Version 2.39.0 Release: Second Brain Inventory and empty response fix
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@
|
||||
"name": "g1nation",
|
||||
"displayName": "G1nation",
|
||||
"description": "High-performance autonomous local AI coding agent for VS Code. Features vectorized inference, asynchronous task management, and 100% offline processing.",
|
||||
"version": "2.38.0",
|
||||
"version": "2.39.0",
|
||||
"publisher": "connectailab",
|
||||
"license": "MIT",
|
||||
"icon": "assets/icon.png",
|
||||
|
||||
+48
-5
@@ -264,6 +264,9 @@ export class AgentExecutor {
|
||||
activeBrain.description ? `Description: ${activeBrain.description}` : '',
|
||||
brainPreview ? `Available file examples:\n${brainPreview}` : 'Files: none found'
|
||||
].filter(Boolean).join('\n');
|
||||
const brainInventoryCtx = prompt && this.isSecondBrainInventoryRequest(prompt)
|
||||
? `\n\n${this.buildSecondBrainInventoryContext(activeBrain, brainFiles)}`
|
||||
: '';
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (editor && editor.document.uri.scheme === 'file') {
|
||||
const text = editor.document.getText();
|
||||
@@ -332,7 +335,7 @@ export class AgentExecutor {
|
||||
: '';
|
||||
const memoryCtx = this.buildMemoryContext(prompt || '', activeBrain);
|
||||
|
||||
const fullSystemPrompt = `${agentSkillCtx}\n\n${systemPrompt}${internetCtx}${memoryCtx}${designerCtx}${secondBrainTraceCtx}\n\n[CONTEXT]\n${brainContext}\n${contextBlock}${negativeCtx}`;
|
||||
const fullSystemPrompt = `${agentSkillCtx}\n\n${systemPrompt}${internetCtx}${memoryCtx}${designerCtx}${secondBrainTraceCtx}\n\n[CONTEXT]\n${brainContext}${brainInventoryCtx}\n${contextBlock}${negativeCtx}`;
|
||||
const messagesForRequest: ChatMessage[] = [
|
||||
{ role: 'system', content: fullSystemPrompt, internal: true },
|
||||
...reqMessages
|
||||
@@ -428,13 +431,10 @@ export class AgentExecutor {
|
||||
? renderSecondBrainTraceMarkdown(secondBrainTrace, !!options.secondBrainTraceDebug)
|
||||
: '';
|
||||
const finalAssistantContent = traceMarkdown ? `${assistantContent}\n${traceMarkdown}` : assistantContent;
|
||||
const assistantMessage: ChatMessage = { role: 'assistant', content: finalAssistantContent, internal: false, rationale };
|
||||
this.chatHistory.push(assistantMessage);
|
||||
|
||||
|
||||
this.statusBarManager.updateStatus(AgentStatus.Executing);
|
||||
const report = await this.executeActions(aiResponseText, rootPath, activeBrain);
|
||||
if (!assistantContent.trim() && report.length === 0) {
|
||||
this.chatHistory.pop();
|
||||
logError('Model returned an empty response without actions.', { model: actualModel, engine, apiUrl, loopDepth });
|
||||
this.webview.postMessage({
|
||||
type: 'error',
|
||||
@@ -476,6 +476,8 @@ export class AgentExecutor {
|
||||
return;
|
||||
}
|
||||
|
||||
const assistantMessage: ChatMessage = { role: 'assistant', content: finalAssistantContent, internal: false, rationale };
|
||||
this.chatHistory.push(assistantMessage);
|
||||
this.emitHistoryChanged();
|
||||
this.statusBarManager.updateStatus(AgentStatus.Success);
|
||||
this.webview.postMessage({ type: 'streamChunk', value: finalAssistantContent });
|
||||
@@ -613,6 +615,47 @@ export class AgentExecutor {
|
||||
return /(second brain|2nd brain|제2뇌|브레인|brain|기억|기록|노트|문서|참고해서|사용해서|검색해서|근거|출처)/i.test(prompt);
|
||||
}
|
||||
|
||||
private isSecondBrainInventoryRequest(prompt: string): boolean {
|
||||
const normalized = prompt.toLowerCase();
|
||||
const asksBrain = /(second brain|2nd brain|제2뇌|브레인|brain)/i.test(normalized);
|
||||
const asksOverview = /(평가|분석|강점|약점|부족|무엇을 할 수|활용|전체|연결된|현재|inside|overview|inventory|strength|weakness)/i.test(normalized);
|
||||
return asksBrain && asksOverview;
|
||||
}
|
||||
|
||||
private buildSecondBrainInventoryContext(activeBrain: BrainProfile, brainFiles: string[]): string {
|
||||
const relativeFiles = brainFiles.map((file) => path.relative(activeBrain.localBrainPath, file));
|
||||
const directoryCounts = new Map<string, number>();
|
||||
for (const rel of relativeFiles) {
|
||||
const topDir = rel.includes(path.sep) ? rel.split(path.sep)[0] : '(root)';
|
||||
directoryCounts.set(topDir, (directoryCounts.get(topDir) || 0) + 1);
|
||||
}
|
||||
|
||||
const topDirectories = [...directoryCounts.entries()]
|
||||
.sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
|
||||
.slice(0, 12)
|
||||
.map(([dir, count]) => `- ${dir}: ${count} markdown files`)
|
||||
.join('\n');
|
||||
|
||||
const samples = relativeFiles
|
||||
.slice(0, 40)
|
||||
.map((file) => `- ${file}`)
|
||||
.join('\n');
|
||||
|
||||
return [
|
||||
'[SECOND BRAIN INVENTORY]',
|
||||
'The user is asking about the currently selected Second Brain as a knowledge base. Use this inventory as direct evidence.',
|
||||
`Selected brain name: ${activeBrain.name}`,
|
||||
`Selected brain path: ${activeBrain.localBrainPath}`,
|
||||
`Markdown file count: ${brainFiles.length}`,
|
||||
brainFiles.length > 0
|
||||
? 'Do not say the Second Brain has no data, no files, or cannot be evaluated because files were not provided.'
|
||||
: 'No Markdown files were found in the selected Second Brain path.',
|
||||
topDirectories ? `Top-level distribution:\n${topDirectories}` : 'Top-level distribution: none',
|
||||
samples ? `Sample files:\n${samples}` : 'Sample files: none',
|
||||
'For strengths and weaknesses, infer from the inventory and selected note excerpts. Mark broad conclusions as inference when they are not directly proven.'
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
private isStaleRun(runId: number): boolean {
|
||||
return runId !== this.activeRunId;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user