Version 2.38.0 Release: Sync logic and knowledge categorization
This commit is contained in:
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "g1nation",
|
"name": "g1nation",
|
||||||
"version": "2.34.1",
|
"version": "2.36.9",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "g1nation",
|
"name": "g1nation",
|
||||||
"version": "2.34.1",
|
"version": "2.36.9",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"marked": "^18.0.2"
|
"marked": "^18.0.2"
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
"name": "g1nation",
|
"name": "g1nation",
|
||||||
"displayName": "G1nation",
|
"displayName": "G1nation",
|
||||||
"description": "High-performance autonomous local AI coding agent for VS Code. Features vectorized inference, asynchronous task management, and 100% offline processing.",
|
"description": "High-performance autonomous local AI coding agent for VS Code. Features vectorized inference, asynchronous task management, and 100% offline processing.",
|
||||||
"version": "2.36.9",
|
"version": "2.38.0",
|
||||||
"publisher": "connectailab",
|
"publisher": "connectailab",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"icon": "assets/icon.png",
|
"icon": "assets/icon.png",
|
||||||
|
|||||||
+24
-31
@@ -3,11 +3,9 @@ import * as path from 'path';
|
|||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
// axios removed
|
// axios removed
|
||||||
import {
|
import {
|
||||||
_getBrainDir,
|
|
||||||
findBrainFiles,
|
findBrainFiles,
|
||||||
getSystemPrompt,
|
getSystemPrompt,
|
||||||
shouldAutoPushBrain,
|
shouldAutoPushBrain,
|
||||||
getSecondBrainRepo,
|
|
||||||
buildApiUrl,
|
buildApiUrl,
|
||||||
getActiveBrainProfile,
|
getActiveBrainProfile,
|
||||||
logError,
|
logError,
|
||||||
@@ -15,7 +13,7 @@ import {
|
|||||||
resolveEngine,
|
resolveEngine,
|
||||||
summarizeText
|
summarizeText
|
||||||
} from './utils';
|
} from './utils';
|
||||||
import { getConfig, EXCLUDED_DIRS } from './config';
|
import { BrainProfile, getConfig, EXCLUDED_DIRS } from './config';
|
||||||
import { validatePath, sanitizeCommand } from './security';
|
import { validatePath, sanitizeCommand } from './security';
|
||||||
import { TransactionManager } from './core/transaction';
|
import { TransactionManager } from './core/transaction';
|
||||||
import { SessionManager } from './core/session';
|
import { SessionManager } from './core/session';
|
||||||
@@ -192,7 +190,8 @@ export class AgentExecutor {
|
|||||||
negativePrompt?: string,
|
negativePrompt?: string,
|
||||||
designerContext?: string,
|
designerContext?: string,
|
||||||
secondBrainTraceEnabled?: boolean,
|
secondBrainTraceEnabled?: boolean,
|
||||||
secondBrainTraceDebug?: boolean
|
secondBrainTraceDebug?: boolean,
|
||||||
|
brainProfileId?: string
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
const {
|
const {
|
||||||
@@ -241,7 +240,9 @@ export class AgentExecutor {
|
|||||||
|
|
||||||
let contextBlock = '';
|
let contextBlock = '';
|
||||||
const config = getConfig();
|
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);
|
const brainFiles = findBrainFiles(activeBrain.localBrainPath);
|
||||||
let secondBrainTrace: SecondBrainTrace | null = null;
|
let secondBrainTrace: SecondBrainTrace | null = null;
|
||||||
if (options.secondBrainTraceEnabled && prompt && loopDepth === 0) {
|
if (options.secondBrainTraceEnabled && prompt && loopDepth === 0) {
|
||||||
@@ -329,7 +330,7 @@ export class AgentExecutor {
|
|||||||
const secondBrainTraceCtx = secondBrainTrace
|
const secondBrainTraceCtx = secondBrainTrace
|
||||||
? `\n\n${renderSecondBrainTraceContext(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 fullSystemPrompt = `${agentSkillCtx}\n\n${systemPrompt}${internetCtx}${memoryCtx}${designerCtx}${secondBrainTraceCtx}\n\n[CONTEXT]\n${brainContext}\n${contextBlock}${negativeCtx}`;
|
||||||
const messagesForRequest: ChatMessage[] = [
|
const messagesForRequest: ChatMessage[] = [
|
||||||
@@ -431,7 +432,7 @@ export class AgentExecutor {
|
|||||||
this.chatHistory.push(assistantMessage);
|
this.chatHistory.push(assistantMessage);
|
||||||
|
|
||||||
this.statusBarManager.updateStatus(AgentStatus.Executing);
|
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) {
|
if (!assistantContent.trim() && report.length === 0) {
|
||||||
this.chatHistory.pop();
|
this.chatHistory.pop();
|
||||||
logError('Model returned an empty response without actions.', { model: actualModel, engine, apiUrl, loopDepth });
|
logError('Model returned an empty response without actions.', { model: actualModel, engine, apiUrl, loopDepth });
|
||||||
@@ -511,7 +512,10 @@ export class AgentExecutor {
|
|||||||
try {
|
try {
|
||||||
let brainContext = 'No specific context available';
|
let brainContext = 'No specific context available';
|
||||||
try {
|
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);
|
const brainFiles = findBrainFiles(activeBrain.localBrainPath);
|
||||||
brainContext = `Brain: ${activeBrain.name}, Files: ${brainFiles.length}`;
|
brainContext = `Brain: ${activeBrain.name}, Files: ${brainFiles.length}`;
|
||||||
} catch (ctxErr) {
|
} catch (ctxErr) {
|
||||||
@@ -826,7 +830,7 @@ export class AgentExecutor {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildMemoryContext(currentPrompt: string): string {
|
private buildMemoryContext(currentPrompt: string, activeBrain: BrainProfile): string {
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
if (!config.memoryEnabled) return '';
|
if (!config.memoryEnabled) return '';
|
||||||
|
|
||||||
@@ -848,7 +852,7 @@ export class AgentExecutor {
|
|||||||
})
|
})
|
||||||
.join('\n');
|
.join('\n');
|
||||||
|
|
||||||
const longTerm = this.findRelevantBrainMemory(currentPrompt, config.memoryLongTermFiles);
|
const longTerm = this.findRelevantBrainMemory(currentPrompt, config.memoryLongTermFiles, activeBrain);
|
||||||
const sections = [
|
const sections = [
|
||||||
shortTerm ? `### Short-Term Memory\n${shortTerm}` : '',
|
shortTerm ? `### Short-Term Memory\n${shortTerm}` : '',
|
||||||
mediumTerm ? `### Medium-Term Memory\n${mediumTerm}` : '',
|
mediumTerm ? `### Medium-Term Memory\n${mediumTerm}` : '',
|
||||||
@@ -865,11 +869,10 @@ export class AgentExecutor {
|
|||||||
].join('\n');
|
].join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
private findRelevantBrainMemory(currentPrompt: string, limit: number): string {
|
private findRelevantBrainMemory(currentPrompt: string, limit: number, activeBrain: BrainProfile): string {
|
||||||
if (limit <= 0) return '';
|
if (limit <= 0) return '';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const activeBrain = getActiveBrainProfile();
|
|
||||||
const files = findBrainFiles(activeBrain.localBrainPath);
|
const files = findBrainFiles(activeBrain.localBrainPath);
|
||||||
const terms = currentPrompt
|
const terms = currentPrompt
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
@@ -1043,9 +1046,10 @@ export class AgentExecutor {
|
|||||||
return candidates;
|
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[] = [];
|
const report: string[] = [];
|
||||||
let brainModified = false;
|
let brainModified = false;
|
||||||
|
const activeBrainDir = activeBrain.localBrainPath;
|
||||||
let firstCreatedFile: string | undefined;
|
let firstCreatedFile: string | undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -1066,7 +1070,7 @@ export class AgentExecutor {
|
|||||||
|
|
||||||
report.push(`✅ Created: ${relPath}`);
|
report.push(`✅ Created: ${relPath}`);
|
||||||
if (!firstCreatedFile) firstCreatedFile = absPath;
|
if (!firstCreatedFile) firstCreatedFile = absPath;
|
||||||
if (absPath.startsWith(_getBrainDir())) brainModified = true;
|
if (absPath.startsWith(activeBrainDir)) brainModified = true;
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
throw new FileSystemError(`Failed to create file ${relPath}: ${err.message}`, relPath, err);
|
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');
|
fs.writeFileSync(absPath, editContent, 'utf-8');
|
||||||
report.push(`📝 Updated (Full): ${relPath}`);
|
report.push(`📝 Updated (Full): ${relPath}`);
|
||||||
}
|
}
|
||||||
if (absPath.startsWith(_getBrainDir())) brainModified = true;
|
if (absPath.startsWith(activeBrainDir)) brainModified = true;
|
||||||
} else {
|
} else {
|
||||||
report.push(`❌ File not found: ${relPath}`);
|
report.push(`❌ File not found: ${relPath}`);
|
||||||
}
|
}
|
||||||
@@ -1184,7 +1188,7 @@ export class AgentExecutor {
|
|||||||
while ((match = listBrainRegex.exec(aiMessage)) !== null) {
|
while ((match = listBrainRegex.exec(aiMessage)) !== null) {
|
||||||
const relPath = match[1].trim() || '.';
|
const relPath = match[1].trim() || '.';
|
||||||
try {
|
try {
|
||||||
const brainDir = _getBrainDir();
|
const brainDir = activeBrainDir;
|
||||||
const absPath = path.join(brainDir, relPath);
|
const absPath = path.join(brainDir, relPath);
|
||||||
if (fs.existsSync(absPath) && fs.statSync(absPath).isDirectory()) {
|
if (fs.existsSync(absPath) && fs.statSync(absPath).isDirectory()) {
|
||||||
const entries = fs.readdirSync(absPath, { withFileTypes: true });
|
const entries = fs.readdirSync(absPath, { withFileTypes: true });
|
||||||
@@ -1209,7 +1213,7 @@ export class AgentExecutor {
|
|||||||
while ((match = brainRegex.exec(aiMessage)) !== null) {
|
while ((match = brainRegex.exec(aiMessage)) !== null) {
|
||||||
const fileName = match[1].trim();
|
const fileName = match[1].trim();
|
||||||
try {
|
try {
|
||||||
const brainDir = _getBrainDir();
|
const brainDir = activeBrainDir;
|
||||||
const files = findBrainFiles(brainDir);
|
const files = findBrainFiles(brainDir);
|
||||||
const targetFile = files.find((f: string) => path.basename(f) === fileName || f.endsWith(fileName));
|
const targetFile = files.find((f: string) => path.basename(f) === fileName || f.endsWith(fileName));
|
||||||
|
|
||||||
@@ -1242,8 +1246,8 @@ export class AgentExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Brain Sync Logic
|
// Brain Sync Logic
|
||||||
if (brainModified && shouldAutoPushBrain() && getSecondBrainRepo()) {
|
if (brainModified && shouldAutoPushBrain() && activeBrain.secondBrainRepo) {
|
||||||
this.syncBrain();
|
this.syncBrain(activeBrainDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
@@ -1262,22 +1266,11 @@ export class AgentExecutor {
|
|||||||
// We return the report with the failure message instead of throwing
|
// We return the report with the failure message instead of throwing
|
||||||
// so the agent can see the failure and decide what to do next
|
// 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;
|
return report;
|
||||||
}
|
}
|
||||||
|
|
||||||
private syncBrain() {
|
private syncBrain(brainDir: string) {
|
||||||
try {
|
try {
|
||||||
const brainDir = _getBrainDir();
|
|
||||||
const { execSync } = require('child_process');
|
const { execSync } = require('child_process');
|
||||||
execSync(`git add .`, { cwd: brainDir });
|
execSync(`git add .`, { cwd: brainDir });
|
||||||
execSync(`git commit -m "[G1nation] Knowledge Update"`, { cwd: brainDir });
|
execSync(`git commit -m "[G1nation] Knowledge Update"`, { cwd: brainDir });
|
||||||
|
|||||||
@@ -1649,9 +1649,12 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
private async _handlePrompt(data: any) {
|
private async _handlePrompt(data: any) {
|
||||||
if (!this._view) return;
|
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._currentNegativePrompt = negativePrompt || '';
|
||||||
this._currentSessionBrainId = getActiveBrainProfile().id;
|
const selectedBrainId = typeof brainProfileId === 'string' && brainProfileId && brainProfileId !== 'new'
|
||||||
|
? brainProfileId
|
||||||
|
: getActiveBrainProfile().id;
|
||||||
|
this._currentSessionBrainId = selectedBrainId;
|
||||||
|
|
||||||
let agentSkillContext = undefined;
|
let agentSkillContext = undefined;
|
||||||
if (agentFile && fs.existsSync(agentFile)) {
|
if (agentFile && fs.existsSync(agentFile)) {
|
||||||
@@ -1668,7 +1671,8 @@ export class SidebarChatProvider implements vscode.WebviewViewProvider, BridgeIn
|
|||||||
negativePrompt,
|
negativePrompt,
|
||||||
designerContext,
|
designerContext,
|
||||||
secondBrainTraceEnabled: secondBrainTrace !== false,
|
secondBrainTraceEnabled: secondBrainTrace !== false,
|
||||||
secondBrainTraceDebug: !!secondBrainTraceDebug
|
secondBrainTraceDebug: !!secondBrainTraceDebug,
|
||||||
|
brainProfileId: selectedBrainId
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
logError('Prompt handling failed in sidebar provider.', { error: error?.message || String(error), promptPreview: summarizeText(value || '', 200) });
|
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,
|
internet: internetEnabled,
|
||||||
files: pendingFiles.length > 0 ? pendingFiles : undefined,
|
files: pendingFiles.length > 0 ? pendingFiles : undefined,
|
||||||
agentFile: agentSel.value === 'none' ? undefined : agentSel.value,
|
agentFile: agentSel.value === 'none' ? undefined : agentSel.value,
|
||||||
|
brainProfileId: brainSel.value && brainSel.value !== 'new' ? brainSel.value : undefined,
|
||||||
negativePrompt: negativePrompt.value.trim() || undefined,
|
negativePrompt: negativePrompt.value.trim() || undefined,
|
||||||
designerGuard: designerGuardEnabled,
|
designerGuard: designerGuardEnabled,
|
||||||
secondBrainTrace: secondBrainTraceEnabled,
|
secondBrainTrace: secondBrainTraceEnabled,
|
||||||
|
|||||||
Reference in New Issue
Block a user