chore: bump version to 2.80.27 and update core features

This commit is contained in:
g1nation
2026-05-09 01:16:12 +09:00
parent 5ffb472d22
commit 3220a126fd
41 changed files with 4457 additions and 72 deletions
+50 -1
View File
@@ -9,6 +9,12 @@ import {
} from './utils';
import { getConfig } from './config';
import { IAIService, IBrainService, AIService, BrainService } from './core/services';
import {
ISkillInjectionService,
FileSystemSkillInjectionService,
SkillInjectionError,
} from './skills/skillInjectionService';
import { resolveAgentSkillsDir } from './lib/paths';
export interface BridgeInterface {
injectSystemMessage(msg: string): void;
@@ -27,15 +33,25 @@ export class BridgeServer {
private server: http.Server | null = null;
private aiService: IAIService;
private brainService: IBrainService;
private skillService: ISkillInjectionService;
constructor(
private provider: BridgeInterface,
aiService?: IAIService,
brainService?: IBrainService
brainService?: IBrainService,
skillService?: ISkillInjectionService
) {
// 의존성 주입 (DIP): 기본값 제공 및 외부 주입 허용
this.aiService = aiService || new AIService();
this.brainService = brainService || new BrainService();
this.skillService = skillService || new FileSystemSkillInjectionService({
resolveSkillsDir: resolveAgentSkillsDir,
onInjected: (result, req) => {
this.provider.injectSystemMessage(
`**[Skill]** Injected agent skill: ${req.displayName || result.safeName}`
);
},
});
}
public start(port: number = 4825) {
@@ -64,6 +80,8 @@ export class BridgeServer {
this.processEvaluateHistory(res);
} else if (method === 'POST' && url === '/api/brain-inject') {
this.handlePost(req, res, this.processBrainInject.bind(this));
} else if (method === 'POST' && url === '/api/skill-inject') {
this.handlePost(req, res, this.processSkillInject.bind(this));
} else {
res.writeHead(404);
res.end();
@@ -175,4 +193,35 @@ export class BridgeServer {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ success: true, rawOutput: result }));
}
/**
* Inject an agent skill (markdown-only — see SkillInjectionService doc) from
* an external tool. Routing-only: validation, file IO, and telemetry live in
* the service.
*/
private async processSkillInject(data: any, res: http.ServerResponse) {
try {
const result = await this.skillService.inject({
name: data?.name,
content: data?.content ?? data?.markdown,
displayName: data?.displayName,
description: data?.description,
source: data?.source,
});
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({
success: true,
safeName: result.safeName,
filePath: result.filePath,
}));
} catch (e: any) {
const status = e instanceof SkillInjectionError && (e.code === 'INVALID_NAME' || e.code === 'EMPTY_CONTENT')
? 400
: 500;
const code = e instanceof SkillInjectionError ? e.code : 'UNKNOWN';
logError('Skill inject endpoint failed.', { code, error: e?.message ?? String(e) });
res.writeHead(status, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: e?.message ?? String(e), code }));
}
}
}