feat: v2.2.3 - Stability, Self-Reflector & Intent Alignment

- 버전 2.2.3 상향 및 PATCHNOTES.md 업데이트

- [신규] src/features/selfReflector/ - 성찰 실행/검증/프롬프트 모듈 추가

- [신규] intentAlignment.ts, intentClassifier.ts - 의도 정렬 시스템 추가

- [신규] pixelOfficeState.ts - 픽셀 오피스 상태 관리 추가

- sidebarProvider, dispatcher, chatHandlers 핵심 로직 최적화

- astra-2.2.3.vsix 패키지 생성 완료 (298 tests PASS)
This commit is contained in:
2026-05-15 14:16:14 +09:00
parent ed7e497194
commit 72412450c3
33 changed files with 4964 additions and 125 deletions
+41 -37
View File
@@ -1,22 +1,23 @@
/**
* Knowledge Mix — controls how much the assistant leans on Second Brain
* evidence vs. the model's own general knowledge for a given query.
* Knowledge Mix — model 지식 vs Second Brain 지식의 *상대 비율*을 LLM에게
* 전달하는 정책 레이어.
*
* The single integer "secondBrainWeight" (0100) drives three things:
* ── 정책 v2 (상대값+상대값=상대값) ──────────────────────────────────────
* weight는 0~100 정수이지만 *상대 비율*로만 해석한다. 즉 "70"은 "100% 중
* 70%"라는 상대 표현이고, 시스템이 도중에 *절대 정수*(예: brain 파일 N개)
* 로 변환하지 않는다. 절대 변환은 v1의 핵심 약점이었다 — 사용자가 입력한
* 상대적 의미가 brain 파일 개수라는 절대 정수로 펴지면서 LLM이 받는
* 비율 정보와 retrieve된 실제 양이 따로 놀았다.
*
* 1. RAG chunk budget — how many brain files we feed the model.
* 2. Retrieval ratio — what fraction of the context budget RAG can claim.
* 3. Prompt policy — natural-language instruction injected into the
* system prompt telling the model how to balance
* its own knowledge against the evidence shown.
* v2에서 weight가 *실제로* 영향을 미치는 곳은 단 한 군데:
* - `buildKnowledgeMixPolicy` — LLM 시스템 프롬프트에 "model X% / brain Y%"
* 자연어 정책을 삽입. 비율 그 자체만 모델에게 전달.
*
* Per-agent overrides (AgentKnowledgeEntry.secondBrainWeight) win over the
* global config (g1nation.knowledgeMix.secondBrainWeight). Both fall back to
* the default `DEFAULT_WEIGHT` (balanced) when nothing is set.
* 절대값 측면(brain 파일 개수, context 예산 비율)은 사용자 설정
* (`memoryLongTermFiles`)을 그대로 사용. 두 극단값(weight=0, weight=100)만
* 안전 차원에서 절대 의미를 유지 — 0이면 0개·5% 예산, 100이면 50% 예산.
*
* Keeping this module isolated and pure makes it trivial to unit-test the
* mapping curve and to extend it later (e.g. add a "creative" axis) without
* touching retrieval or prompt assembly.
* 우선순위: per-agent override → global config → DEFAULT_WEIGHT(50).
*/
import { getConfig } from '../config';
import { getOrCreateAgentEntry } from '../skills/agentKnowledgeMap';
@@ -73,42 +74,45 @@ function _clamp(n: number): number {
}
/**
* Map a weight to the maximum number of brain files (long-term memory) the
* retriever is allowed to consider for this turn.
* Brain 파일 *최대 개수*를 결정.
*
* Curve was chosen so that:
* - 0 fully disables brain-file retrieval (model-only mode).
* - 50 maps to roughly the existing default (`memoryLongTermFiles`), so
* behaviour without any per-agent setting matches the status quo.
* - 100 pushes the cap toward `selectWithinBudget`'s hard ceiling (12).
* Knowledge Mix v2 정책 (상대값+상대값=상대값):
* weight는 LLM에게 *얼마나 신뢰할지*를 전달하는 상대 비율일 뿐, brain 파일
* *개수 자체*를 좌우하지 않는다. 사용자가 명시적으로 설정한
* `memoryLongTermFiles`(=`configuredLimit`)를 그대로 사용.
*
* The configured `memoryLongTermFiles` is treated as the "balanced" baseline:
* it's scaled up at high weights and damped at low weights.
* weight가 의미를 가지는 극단값 두 가지만 절대 의미를 유지한다:
* - weight=0 → 0개 (사용자가 명시적으로 "brain 사용 안 함" 선언)
* - 그 외 → configuredLimit 그대로
*
* 이전 v1은 weight=70이면 8개, weight=30이면 4개 식으로 절대 정수 변환을 했고
* 이게 "사용자가 의도한 70%라는 상대 비율"의 의미를 도중에 잃게 만드는
* 원인이었다. 비율 표현은 `buildKnowledgeMixPolicy`가 LLM에게 자연어로
* 전달하는 역할 하나만 맡는다.
*/
export function mapWeightToBrainFileLimit(weight: number, configuredLimit: number): number {
const w = _clamp(weight);
if (w === 0) return 0;
const baseline = Math.max(1, configuredLimit || 6);
// Linear interpolation:
// w=0 → 0
// w=25 → baseline * 0.5
// w=50 → baseline
// w=75 → baseline * 1.5
// w=100 → baseline * 2 (capped at 12 elsewhere)
const scaled = Math.round((w / 50) * baseline);
// Honour the orchestrator's hard cap (12) so we never blow the budget.
return Math.max(0, Math.min(12, scaled));
// 안전 상한 12는 그대로 — context budget 폭주 방지. 그 외엔 사용자 설정 그대로.
return Math.max(0, Math.min(12, baseline));
}
/**
* Map a weight to the retrieval ratio (fraction of the context-budget that
* RAG can claim). Lower weights mean RAG gets a smaller slice and leaves more
* room for conversation history / system prompt.
* Brain retrieval에 할당할 context-budget 비율.
*
* Knowledge Mix v2 정책: weight와 *분리*. budget 분배는 시스템 안정성에 관한
* 절대 결정이지 사용자가 입력한 상대 비율이 직접 좌우할 일이 아니다. 다만
* 두 극단값에서만 의미를 유지:
* - weight=0 → 0.05 (검색 자체가 비활성화되어도 다른 컨텍스트는 살림)
* - weight=100 → 0.50 (brain이 거의 유일한 근거일 때 더 큰 슬라이스)
* - 그 외 → 0.40 (균형 baseline)
*/
export function mapWeightToRetrievalRatio(weight: number): number {
const w = _clamp(weight);
// 0 → 0.05 (still room for tiny lessons block), 50 → 0.40 (status quo), 100 → 0.60.
return Math.max(0.05, Math.min(0.6, 0.05 + (w / 100) * 0.55));
if (w === 0) return 0.05;
if (w === 100) return 0.5;
return 0.4;
}
/**