Version 2.38.0 Release: Sync logic and knowledge categorization

This commit is contained in:
g1nation
2026-05-03 00:23:47 +09:00
parent d5aad75a10
commit d875ba7bc3
4 changed files with 35 additions and 37 deletions
+24 -31
View File
@@ -3,11 +3,9 @@ import * as path from 'path';
import * as fs from 'fs';
// axios removed
import {
_getBrainDir,
findBrainFiles,
getSystemPrompt,
shouldAutoPushBrain,
getSecondBrainRepo,
buildApiUrl,
getActiveBrainProfile,
logError,
@@ -15,7 +13,7 @@ import {
resolveEngine,
summarizeText
} from './utils';
import { getConfig, EXCLUDED_DIRS } from './config';
import { BrainProfile, getConfig, EXCLUDED_DIRS } from './config';
import { validatePath, sanitizeCommand } from './security';
import { TransactionManager } from './core/transaction';
import { SessionManager } from './core/session';
@@ -192,7 +190,8 @@ export class AgentExecutor {
negativePrompt?: string,
designerContext?: string,
secondBrainTraceEnabled?: boolean,
secondBrainTraceDebug?: boolean
secondBrainTraceDebug?: boolean,
brainProfileId?: string
}
) {
const {
@@ -241,7 +240,9 @@ export class AgentExecutor {
let contextBlock = '';
const config = getConfig();
const activeBrain = getActiveBrainProfile();
const activeBrain = options.brainProfileId
? (config.brainProfiles.find((profile) => profile.id === options.brainProfileId) || getActiveBrainProfile())
: getActiveBrainProfile();
const brainFiles = findBrainFiles(activeBrain.localBrainPath);
let secondBrainTrace: SecondBrainTrace | null = null;
if (options.secondBrainTraceEnabled && prompt && loopDepth === 0) {
@@ -329,7 +330,7 @@ export class AgentExecutor {
const secondBrainTraceCtx = secondBrainTrace
? `\n\n${renderSecondBrainTraceContext(secondBrainTrace)}`
: '';
const memoryCtx = this.buildMemoryContext(prompt || '');
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 messagesForRequest: ChatMessage[] = [
@@ -431,7 +432,7 @@ export class AgentExecutor {
this.chatHistory.push(assistantMessage);
this.statusBarManager.updateStatus(AgentStatus.Executing);
const report = await this.executeActions(aiResponseText, rootPath);
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 });
@@ -511,7 +512,10 @@ export class AgentExecutor {
try {
let brainContext = 'No specific context available';
try {
const activeBrain = getActiveBrainProfile();
const config = getConfig();
const activeBrain = options.brainProfileId
? (config.brainProfiles.find((profile) => profile.id === options.brainProfileId) || getActiveBrainProfile())
: getActiveBrainProfile();
const brainFiles = findBrainFiles(activeBrain.localBrainPath);
brainContext = `Brain: ${activeBrain.name}, Files: ${brainFiles.length}`;
} catch (ctxErr) {
@@ -826,7 +830,7 @@ export class AgentExecutor {
});
}
private buildMemoryContext(currentPrompt: string): string {
private buildMemoryContext(currentPrompt: string, activeBrain: BrainProfile): string {
const config = getConfig();
if (!config.memoryEnabled) return '';
@@ -848,7 +852,7 @@ export class AgentExecutor {
})
.join('\n');
const longTerm = this.findRelevantBrainMemory(currentPrompt, config.memoryLongTermFiles);
const longTerm = this.findRelevantBrainMemory(currentPrompt, config.memoryLongTermFiles, activeBrain);
const sections = [
shortTerm ? `### Short-Term Memory\n${shortTerm}` : '',
mediumTerm ? `### Medium-Term Memory\n${mediumTerm}` : '',
@@ -865,11 +869,10 @@ export class AgentExecutor {
].join('\n');
}
private findRelevantBrainMemory(currentPrompt: string, limit: number): string {
private findRelevantBrainMemory(currentPrompt: string, limit: number, activeBrain: BrainProfile): string {
if (limit <= 0) return '';
try {
const activeBrain = getActiveBrainProfile();
const files = findBrainFiles(activeBrain.localBrainPath);
const terms = currentPrompt
.toLowerCase()
@@ -1043,9 +1046,10 @@ export class AgentExecutor {
return candidates;
}
private async executeActions(aiMessage: string, rootPath: string): Promise<string[]> {
private async executeActions(aiMessage: string, rootPath: string, activeBrain: BrainProfile): Promise<string[]> {
const report: string[] = [];
let brainModified = false;
const activeBrainDir = activeBrain.localBrainPath;
let firstCreatedFile: string | undefined;
try {
@@ -1066,7 +1070,7 @@ export class AgentExecutor {
report.push(`✅ Created: ${relPath}`);
if (!firstCreatedFile) firstCreatedFile = absPath;
if (absPath.startsWith(_getBrainDir())) brainModified = true;
if (absPath.startsWith(activeBrainDir)) brainModified = true;
} catch (err: any) {
throw new FileSystemError(`Failed to create file ${relPath}: ${err.message}`, relPath, err);
}
@@ -1099,7 +1103,7 @@ export class AgentExecutor {
fs.writeFileSync(absPath, editContent, 'utf-8');
report.push(`📝 Updated (Full): ${relPath}`);
}
if (absPath.startsWith(_getBrainDir())) brainModified = true;
if (absPath.startsWith(activeBrainDir)) brainModified = true;
} else {
report.push(`❌ File not found: ${relPath}`);
}
@@ -1184,7 +1188,7 @@ export class AgentExecutor {
while ((match = listBrainRegex.exec(aiMessage)) !== null) {
const relPath = match[1].trim() || '.';
try {
const brainDir = _getBrainDir();
const brainDir = activeBrainDir;
const absPath = path.join(brainDir, relPath);
if (fs.existsSync(absPath) && fs.statSync(absPath).isDirectory()) {
const entries = fs.readdirSync(absPath, { withFileTypes: true });
@@ -1209,7 +1213,7 @@ export class AgentExecutor {
while ((match = brainRegex.exec(aiMessage)) !== null) {
const fileName = match[1].trim();
try {
const brainDir = _getBrainDir();
const brainDir = activeBrainDir;
const files = findBrainFiles(brainDir);
const targetFile = files.find((f: string) => path.basename(f) === fileName || f.endsWith(fileName));
@@ -1242,8 +1246,8 @@ export class AgentExecutor {
}
// Brain Sync Logic
if (brainModified && shouldAutoPushBrain() && getSecondBrainRepo()) {
this.syncBrain();
if (brainModified && shouldAutoPushBrain() && activeBrain.secondBrainRepo) {
this.syncBrain(activeBrainDir);
}
const config = getConfig();
@@ -1262,22 +1266,11 @@ export class AgentExecutor {
// We return the report with the failure message instead of throwing
// so the agent can see the failure and decide what to do next
}
if (firstCreatedFile) {
vscode.window.showTextDocument(vscode.Uri.file(firstCreatedFile), { preview: false });
}
// Brain Sync Logic
if (brainModified && shouldAutoPushBrain() && getSecondBrainRepo()) {
this.syncBrain();
}
return report;
}
private syncBrain() {
private syncBrain(brainDir: string) {
try {
const brainDir = _getBrainDir();
const { execSync } = require('child_process');
execSync(`git add .`, { cwd: brainDir });
execSync(`git commit -m "[G1nation] Knowledge Update"`, { cwd: brainDir });
+8 -3
View File
@@ -1649,9 +1649,12 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
private async _handlePrompt(data: any) {
if (!this._view) return;
const { value, model, internet, files, agentFile, negativePrompt, designerGuard, secondBrainTrace, secondBrainTraceDebug } = data;
const { value, model, internet, files, agentFile, negativePrompt, designerGuard, secondBrainTrace, secondBrainTraceDebug, brainProfileId } = data;
this._currentNegativePrompt = negativePrompt || '';
this._currentSessionBrainId = getActiveBrainProfile().id;
const selectedBrainId = typeof brainProfileId === 'string' && brainProfileId && brainProfileId !== 'new'
? brainProfileId
: getActiveBrainProfile().id;
this._currentSessionBrainId = selectedBrainId;
let agentSkillContext = undefined;
if (agentFile && fs.existsSync(agentFile)) {
@@ -1668,7 +1671,8 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
negativePrompt,
designerContext,
secondBrainTraceEnabled: secondBrainTrace !== false,
secondBrainTraceDebug: !!secondBrainTraceDebug
secondBrainTraceDebug: !!secondBrainTraceDebug,
brainProfileId: selectedBrainId
});
} catch (error: any) {
logError('Prompt handling failed in sidebar provider.', { error: error?.message || String(error), promptPreview: summarizeText(value || '', 200) });
@@ -3039,6 +3043,7 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
internet: internetEnabled,
files: pendingFiles.length > 0 ? pendingFiles : undefined,
agentFile: agentSel.value === 'none' ? undefined : agentSel.value,
brainProfileId: brainSel.value && brainSel.value !== 'new' ? brainSel.value : undefined,
negativePrompt: negativePrompt.value.trim() || undefined,
designerGuard: designerGuardEnabled,
secondBrainTrace: secondBrainTraceEnabled,