0a97324f1b
R56–R59: agent.ts 2731→1529줄 god-file 분해 (25 modules) · attrParsers + LLM 메서드 8개 (callNonStreaming, streamChatOnce 등) · executeActions 415줄 → 8 handler 그룹 (file/run/list/brain/calendar/sheets/tasks) · handlePrompt 1100줄 → 7 phase 모듈 (system prompt + budget + autoContinue 등) R50–R55: extension.ts 1145→349줄 (telegram/settings/provider commands 분리) Stocks feature 신규: /stocks slash command (v2.2.152~158) · .astra/stocks.json 저장소 + Yahoo Finance 현재가 갱신 · 8 키워드 필터 (ROE/성장성/유동성/수익성/영업효율/기술력/안정성/PBR) · Naver 시가총액 페이지 JSON API (m.stock.naver.com) 발굴 · LLM Top 5 매력도 분석 + Telegram 자동 보고서 · KST 09:00/15:00 watcher 자동 모니터링 대화 연속성 (v2.2.150~157): · [PRIOR TURN CONCLUSION] block 으로 직전 결론 anchor · thin follow-up 분류 → boilerplate 헤더 suppression · slash 명령 결과 chatHistory mirror (capture wrapper) · echo/parrot 금지 system prompt rule 기타: /stocks 슬래시 자동완성 dropdown UI, Naver JSON API 전환 (cheerio 제거) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
70 lines
2.7 KiB
TypeScript
70 lines
2.7 KiB
TypeScript
import { ChunkedWriter, PersonaOverrides } from './factory';
|
|
import { AgentEngine, PipelineStage, AgentExecuteOptions } from '../lib/engine';
|
|
import { getConfig } from '../config';
|
|
|
|
/**
|
|
* Multi-agent 워크플로우를 외부에 노출하는 얇은 매니저.
|
|
*
|
|
* 예전엔 planner / researcher / reflector / writer / synthesizer 5개 persona 를
|
|
* 줄세웠지만, 각 hop 마다 컨텍스트가 누적되고 원본 본문이 추상화로 손실돼
|
|
* 사용자가 본문 분석을 요청해도 "분석 방법론" 만 만들어내는 사고가 있었음.
|
|
*
|
|
* 현재 흐름: 단일 ChunkedWriter 가 outline → section[N] → polish 세 역할을
|
|
* 같은 모델에서 번갈아 수행 → 각 호출은 작고(컨텍스트 폭증 없음), 본문은
|
|
* 매 호출에 직접 전달돼 손실 없음.
|
|
*/
|
|
export class AgentWorkflowManager {
|
|
public static async runStrictWorkflow(
|
|
prompt: string,
|
|
modelName: string,
|
|
brainContext: string,
|
|
signal: AbortSignal,
|
|
onProgress: (step: string, message: string) => void
|
|
): Promise<string> {
|
|
// 사용자 config 의 polish persona override 가 있으면 ChunkedWriter 에 주입.
|
|
// 비어 있으면 기본 polish persona 사용.
|
|
const cfg = getConfig();
|
|
const overrides: PersonaOverrides | undefined = cfg.polishPersonaOverride
|
|
? { polish: cfg.polishPersonaOverride }
|
|
: undefined;
|
|
const writer = new ChunkedWriter(modelName, overrides);
|
|
const engine = new AgentEngine(writer);
|
|
const missionId = `mission_${Date.now()}`;
|
|
|
|
const runOptions: AgentExecuteOptions = {
|
|
config: { model: modelName },
|
|
};
|
|
|
|
try {
|
|
return await engine.runMission(
|
|
missionId,
|
|
prompt,
|
|
brainContext,
|
|
signal,
|
|
(stage: PipelineStage, message: string) => {
|
|
onProgress(this.mapStageToUI(stage), message);
|
|
},
|
|
runOptions
|
|
);
|
|
} catch (error: any) {
|
|
if (error.name === 'AbortError' || error.message.includes('cancelled')) {
|
|
throw error;
|
|
}
|
|
throw new Error(`[Workflow Manager] ${error.message}`);
|
|
}
|
|
}
|
|
|
|
private static mapStageToUI(stage: PipelineStage): string {
|
|
const maps: Record<PipelineStage, string> = {
|
|
idle: '대기',
|
|
outline: '① 구조 잡기',
|
|
section: '② 본문 작성',
|
|
polish: '③ 최종 다듬기',
|
|
direct: '⚡ 즉답',
|
|
completed: '완료',
|
|
error: '오류',
|
|
};
|
|
return maps[stage] || '진행 중';
|
|
}
|
|
}
|