v2.2.256: 코어 채팅 큰 입력 청킹·통합 + 실제 컨텍스트 창 정렬 + 모델 핸들 race 수정

큰 입력 시 "Failed to acquire LM Studio model handle … Operation canceled"
로 턴 전체가 죽던 문제를 3계층으로 해결. 일반 채팅(코어 경로)은 그동안
단일 예산 호출이라 약한 모델·큰 입력에서 무너졌다 — 그 갭을 메움.

- 핸들 race 수정: getModelHandle 을 재시도 루프 안으로 이동. 취소/죽은-핸들
  류 에러는 SDK 재생성 후 1회 자동 재시도(실제 사용자 취소는 존중). 라이프
  사이클의 동시 로드가 abort 되며 SDK 가 coalesce 한 JIT 조회까지 죽던 것.
- Phase 1 실제 창 정렬: llm.getContextLength()(캐시)로 실측 창에 예산 클램프.
  설정값보다 작은 창으로 로드된 경우 서버 truncation/빈 답변 차단. 배지에 표시.
- Phase 2 코어 Map-Reduce: 단일 입력이 (유효 창 × ratio) 초과 시 청크→질의
  인지형 추출→통합. 부분/전체 폴백, 무관 시 정직 신호. 동시성 기본 2.
- Phase 3 메타 노출: 진행/결과 배지 표시, [조각 k] 출처 옵트인.

신규 설정 5종. /meet·/review 전용 경로는 불변. 테스트 +25건, 전체 684 통과.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-19 18:05:44 +09:00
parent 6adbc2a6fa
commit 76d5fedfb5
13 changed files with 883 additions and 19 deletions
+16
View File
@@ -40,6 +40,17 @@ export interface IAgentConfig {
autoCompactHistory: boolean;
/** 작은 모델(≤4B) 감지 시 예산 계산에 쓸 유효 context window 상한. 0 = 비활성화. */
smallModelContextCap: number;
// ─── 큰 입력 Map-Reduce (긴 회의록/리서치 덤프 청킹·통합) ───
/** 단일 사용자 입력이 창을 넘으면 청크→추출→통합으로 처리. 끄면 기존 단발 경로(잘릴 수 있음). */
largeInputMapReduce: boolean;
/** 단일 입력 토큰이 (유효 창 × 이 비율)을 넘으면 map-reduce 발동. 기본 0.6. */
mapReduceTriggerRatio: number;
/** 청크 추출 동시성. 로컬 단일 GPU 보호용으로 낮게. 기본 2. */
mapReduceConcurrency: number;
/** 추출 합본이 창을 넘을 때 계층적 통합 최대 깊이. 기본 3. */
mapReduceMaxDepth: number;
/** 최종 답변에 `[조각 k]` 출처 태그를 노출. 기본 false. */
mapReduceShowProvenance: boolean;
// ─── 응답 복구 (Thought Quarantine / Auto-Continuation) ───
/** 답변이 출력 토큰 한계에 걸리면 사용자 개입 없이 내부적으로 이어서 생성. */
autoContinueOnOutputLimit: boolean;
@@ -500,6 +511,11 @@ export function getConfig(): IAgentConfig {
})(),
autoCompactHistory: cfg.get<boolean>('autoCompactHistory', true),
smallModelContextCap: Math.max(0, cfg.get<number>('smallModelContextCap', 0)),
largeInputMapReduce: cfg.get<boolean>('largeInputMapReduce', true),
mapReduceTriggerRatio: Math.min(0.95, Math.max(0.3, cfg.get<number>('mapReduceTriggerRatio', 0.6))),
mapReduceConcurrency: Math.min(8, Math.max(1, cfg.get<number>('mapReduceConcurrency', 2))),
mapReduceMaxDepth: Math.min(6, Math.max(1, cfg.get<number>('mapReduceMaxDepth', 3))),
mapReduceShowProvenance: cfg.get<boolean>('mapReduceShowProvenance', false),
autoContinueOnOutputLimit: cfg.get<boolean>('autoContinueOnOutputLimit', true),
maxAutoContinuations: Math.max(0, Math.min(10, cfg.get<number>('maxAutoContinuations', 4))),
finalOnlyRetryOnThoughtLeak: cfg.get<boolean>('finalOnlyRetryOnThoughtLeak', true),