feat: v2.2.74 → v2.2.82 — chunked writer + 코드 리뷰 패치 + /youtube 확장
주요 변경: [chunked writer 아키텍처 (v2.2.74~v2.2.75)] - 5-stage 다중 에이전트(planner/researcher/reflector/writer/synthesizer) 파이프라인 제거 → 단일 ChunkedWriter 의 outline → section[N] → polish 3-step 으로 교체. 본문 분석에서 추상화 손실 / 토큰 폭증 문제 해소 - 답변 길이 자동 분기: 짧은 prompt 는 fast-path direct 1회 호출, 본문 분석은 chunked. outline 빈 배열도 direct 폴백 [코드 리뷰 9개 항목 일괄 패치 (v2.2.76)] - /research polling hang 방어 (heartbeat + status 정규화 + 연속 실패 abort) - 회사 모드 dispatcher abort 신호를 AIService.chat 까지 전달 - bridgeFetch 에 onHeartbeat 콜백 도입 (slow endpoint 사용자 친화적) - dead code 정리: reflectionPersister.ts 제거 + enableReflection 등 좀비 config 키 - parseOutline 의 empty vs fallback reason 명시적 분리 - chatHandlers 의 회사 모드 케이스 ~325줄을 src/sidebar/companyHandlers.ts 로 분리 - Intent Alignment 라운드 한도 도달 시 smart 모드 자동 진행 - LM Studio doSwitch unload 실패 시 currentModel 정리 + load 강행 - retrieval informationDensity → queryCoverage 정합화 [/youtube 채널 지원 (v2.2.77~v2.2.82)] - 채널/플레이리스트 URL 자동 감지 + n:N 으로 영상 개수 지정 (최대 50) - 채널 루트 URL 에 /videos 탭 자동 append (yt-dlp enumeration 정상화) - 영상별 순차 처리 (queue 패턴) + i/N 진행 표시 + 마지막 통계 요약 - mode:info / mode:benchmark / mode:both 분석 모드 분기 - info: 영상 내용을 지식 카드로 추출 (튜토리얼·강의·뉴스용) - benchmark: 4-렌즈 대본 역기획서 (콘텐츠 제작 벤치마크용) - both: 둘 다 (기본) - bare keyword 도 허용: /youtube <url> n:1 info - bridge 에러 메시지 [object Object] 깨짐 수정 (구조화 에러 추출) - "패키지 없음" 등 환경 의존성 에러에 자동 가이드 첨부 [Astra: Setup Datacollect Dependencies 명령 추가 (v2.2.80)] - Python 자동 감지 + yt-dlp / youtube-transcript-api 자동 설치 - macOS PEP 668 환경 자동 폴백 (--user --break-system-packages) - /youtube 등에서 패키지 미설치 감지 시 "Install Now" 버튼 notification [테스트] - tests/agentEngine.test.ts 를 chunked flow 에 맞춰 전체 재작성 - tests/resilience_stress.test.ts Scenario B/D 를 role-aware mock 으로 갱신 - 399/399 통과 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,18 @@
|
||||
import { PlannerAgent, ResearcherAgent, ReflectorAgent, WriterAgent, SynthesizerAgent } from './factory';
|
||||
import { ChunkedWriter } 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,
|
||||
@@ -13,21 +20,12 @@ export class AgentWorkflowManager {
|
||||
signal: AbortSignal,
|
||||
onProgress: (step: string, message: string) => void
|
||||
): Promise<string> {
|
||||
const planner = new PlannerAgent(modelName);
|
||||
const researcher = new ResearcherAgent(modelName);
|
||||
const writer = new WriterAgent(modelName);
|
||||
// [Self-Reflection] 설정으로 비활성화하지 않은 경우에만 Reflector를 주입.
|
||||
const cfg = getConfig();
|
||||
const enableReflection = cfg.enableReflection !== false;
|
||||
const reflector = enableReflection ? new ReflectorAgent(modelName) : undefined;
|
||||
// [5-stage pipeline] 최종 합성 단계. 설정으로 끄지 않은 한 항상 주입.
|
||||
const enableSynth = cfg.workflowSynthesizerEnabled !== false;
|
||||
const synthesizer = enableSynth ? new SynthesizerAgent(modelName) : undefined;
|
||||
const engine = new AgentEngine(planner, researcher, writer, reflector, synthesizer);
|
||||
const writer = new ChunkedWriter(modelName);
|
||||
const engine = new AgentEngine(writer);
|
||||
const missionId = `mission_${Date.now()}`;
|
||||
|
||||
const runOptions: AgentExecuteOptions = {
|
||||
config: { enableReflection }
|
||||
config: { model: modelName },
|
||||
};
|
||||
|
||||
try {
|
||||
@@ -50,16 +48,14 @@ export class AgentWorkflowManager {
|
||||
}
|
||||
|
||||
private static mapStageToUI(stage: PipelineStage): string {
|
||||
// 사용자가 보는 라벨은 한국어 + 단계 번호로 통일. 5단계 파이프라인이 명확하게 드러나도록.
|
||||
const maps: Record<PipelineStage, string> = {
|
||||
idle: '대기',
|
||||
planner: '① 계획',
|
||||
researcher: '② 자료 수집',
|
||||
reflector: '③ 자기 검증',
|
||||
writer: '④ 초안 작성',
|
||||
synthesizer: '⑤ 최종 정리',
|
||||
outline: '① 구조 잡기',
|
||||
section: '② 본문 작성',
|
||||
polish: '③ 최종 다듬기',
|
||||
direct: '⚡ 즉답',
|
||||
completed: '완료',
|
||||
error: '오류'
|
||||
error: '오류',
|
||||
};
|
||||
return maps[stage] || '진행 중';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user