release: v2.0.1 - Advanced Knowledge Mix & Architectural Intelligence

This commit is contained in:
g1nation
2026-05-13 22:05:39 +09:00
parent c32b17377b
commit e85e11aac6
23 changed files with 1758 additions and 78 deletions
+65 -5
View File
@@ -44,6 +44,13 @@ import { buildLessonChecklistBlock, isQaRegressionFeedback, findUnaddressedCheck
import { embedQuery, embedTexts } from './retrieval/embeddings';
import { backfillBrainEmbeddings } from './retrieval/brainIndex';
import { resolveScopeForAgent } from './skills/agentKnowledgeMap';
import {
resolveKnowledgeMix,
mapWeightToBrainFileLimit,
mapWeightToRetrievalRatio,
buildKnowledgeMixPolicy,
ResolvedKnowledgeMix,
} from './retrieval/knowledgeMix';
import {
extractVisibleFinal,
shouldFinalOnlyRetry,
@@ -202,6 +209,8 @@ export class AgentExecutor {
} | null = null;
/** Lesson card *contents* injected this turn — kept to check the answer against their Prevention Checklists. */
private _lastLessonContents: string[] = [];
/** Resolved Knowledge Mix for the most recent retrieval — surfaced in the scope footer. */
private _lastKnowledgeMix: ResolvedKnowledgeMix | null = null;
private readonly options: AgentExecutorOptions;
@@ -346,6 +355,12 @@ export class AgentExecutor {
agentSkillFile?: string,
negativePrompt?: string,
designerContext?: string,
/**
* Pre-formatted architecture-context block (`[ACTIVE PROJECT ARCHITECTURE CONTEXT]…`)
* built by sidebarProvider from the active project's architecture doc.
* Empty/undefined when project mode is off or auto-attach is disabled.
*/
projectArchitectureContext?: string,
secondBrainTraceEnabled?: boolean,
secondBrainTraceDebug?: boolean,
brainProfileId?: string
@@ -401,6 +416,7 @@ export class AgentExecutor {
// "참조 범위" footer (the exact "안녕 → 🔎 참조: 에피소드기억" bug).
this._lastRetrievalInfo = null;
this._lastLessonContents = [];
this._lastKnowledgeMix = null;
}
// 1. Prepare Context
@@ -520,6 +536,13 @@ export class AgentExecutor {
const designerCtx = options.designerContext
? `\n\n[PROJECT CHRONICLE GUARD]\n${options.designerContext}`
: '';
// Project Architecture context (Feature 2): durable per-project ground truth.
// Already pre-formatted by sidebarProvider with header + markers, so we just
// sandwich it with newlines. Suppressed implicitly because the field is empty
// when project mode is off — no extra check needed here.
const projectArchitectureCtx = options.projectArchitectureContext
? `\n\n${options.projectArchitectureContext}`
: '';
const secondBrainTraceCtx = secondBrainTrace
? `\n\n${renderSecondBrainTraceContext(secondBrainTrace)}`
: '';
@@ -602,8 +625,17 @@ export class AgentExecutor {
const casualCtx = isCasualConversation
? '\n\n[CASUAL CONVERSATION MODE]\nThe user sent a greeting, acknowledgement, or light conversational message. Reply naturally and briefly to the message itself. Do not use Second Brain, memory, project records, reports, references, or analysis unless the user explicitly asks for them.'
: '';
// Knowledge Mix policy: tells the model how strongly to lean on Second Brain
// evidence vs. its own general knowledge for this turn. Suppressed for casual
// chat — pure greetings don't need to be told anything about RAG balance.
const knowledgeMixCtx = (!isCasualConversation && this._lastKnowledgeMix)
? (() => {
const block = buildKnowledgeMixPolicy(this._lastKnowledgeMix);
return block ? `\n\n${block}` : '';
})()
: '';
// memoryCtx(RAG/메모리/lessons)는 [CONTEXT] 안에 — 토큰이 빡빡하면 대화 기록보다 먼저 잘림.
fullSystemPrompt = `${systemPrompt}${internetCtx}${designerCtx}${localProjectKnowledgeCtx}${thinkingPartnerCtx}${astraStanceCtx}${secondBrainTraceCtx}${v4PolicyCtx}${casualCtx}\n\n[CONTEXT]\n${memoryCtx}\n${knowledgeContextForPrompt}\n${contextBlock}\n[/CONTEXT]\n${negativeCtx}`;
fullSystemPrompt = `${systemPrompt}${internetCtx}${designerCtx}${projectArchitectureCtx}${localProjectKnowledgeCtx}${thinkingPartnerCtx}${astraStanceCtx}${secondBrainTraceCtx}${v4PolicyCtx}${knowledgeMixCtx}${casualCtx}\n\n[CONTEXT]\n${memoryCtx}\n${knowledgeContextForPrompt}\n${contextBlock}\n[/CONTEXT]\n${negativeCtx}`;
}
// ──────────────────────────────────────────────────────────────────
// [Context Limit Manager] context length 는 "답변을 그만큼 길게 써도 된다"
@@ -1199,7 +1231,19 @@ export class AgentExecutor {
const unaddressedChecklist = findUnaddressedChecklistItems(finalAssistantContent, this._lastLessonContents);
this.webview.postMessage({
type: 'usedScope',
value: { ...this._lastRetrievalInfo, hasAgentSelected: !!options.agentSkillFile, unaddressedChecklist },
value: {
...this._lastRetrievalInfo,
hasAgentSelected: !!options.agentSkillFile,
unaddressedChecklist,
// Knowledge Mix surfaced under the answer so the user can see what policy ran.
knowledgeMix: this._lastKnowledgeMix
? {
weight: this._lastKnowledgeMix.weight,
source: this._lastKnowledgeMix.source,
agent: this._lastKnowledgeMix.agent,
}
: null,
},
});
}
// Progressive answering: the bubble was filled live with raw tokens
@@ -2441,6 +2485,7 @@ export class AgentExecutor {
const config = getConfig();
this._lastRetrievalInfo = null;
this._lastLessonContents = [];
this._lastKnowledgeMix = null;
if (!config.memoryEnabled) return '';
// Update memory manager config in case settings changed
@@ -2497,6 +2542,15 @@ export class AgentExecutor {
}
}
// Resolve the Knowledge Mix weight for this turn (per-agent → global → default).
// The weight scales how many brain files we feed the retriever and how big a
// slice of the context budget RAG can claim. At weight=50 the numbers below
// equal the legacy defaults, so users who never touch the slider see no change.
const knowledgeMix = resolveKnowledgeMix(agentSkillFile);
this._lastKnowledgeMix = knowledgeMix;
const mixedBrainFileLimit = mapWeightToBrainFileLimit(knowledgeMix.weight, config.memoryLongTermFiles);
const mixedRetrievalRatio = mapWeightToRetrievalRatio(knowledgeMix.weight);
// Use the Unified RAG Pipeline
const result = this.retrievalOrchestrator.retrieve(currentPrompt, {
brain: activeBrain,
@@ -2505,9 +2559,9 @@ export class AgentExecutor {
chatHistory: visibleHistory,
contextBudget: {
totalBudget: scaledTotalBudget,
retrievalRatio: 0.4
retrievalRatio: mixedRetrievalRatio,
},
brainFileLimit: config.memoryLongTermFiles,
brainFileLimit: mixedBrainFileLimit,
scopeFolders: scope.folders,
recentSessions,
mediumTermLimit: config.memoryMediumTermSessions ?? 0,
@@ -3196,7 +3250,13 @@ export class AgentExecutor {
}
if (firstCreatedFile) {
vscode.window.showTextDocument(vscode.Uri.file(firstCreatedFile), { preview: false });
// Always open file results in the editor group (column 2) — the ConnectAI
// sidebar lives in column 3 and we don't want freshly-written files to
// hijack the chat panel.
vscode.window.showTextDocument(vscode.Uri.file(firstCreatedFile), {
preview: false,
viewColumn: vscode.ViewColumn.Two,
});
}
// Brain Sync Logic