[Architecture] G1nation V2 Refactor

This commit is contained in:
2026-04-24 18:23:21 +09:00
parent 48f41e98c2
commit 0e20dff154
5 changed files with 895 additions and 2103 deletions
+119
View File
@@ -0,0 +1,119 @@
import * as vscode from 'vscode';
import * as path from 'path';
import * as os from 'os';
export const EXCLUDED_DIRS = new Set([
'node_modules', '.git', '.vscode', 'out', 'dist', 'build',
'.next', '.cache', '__pycache__', '.DS_Store', 'coverage',
'.turbo', '.nuxt', '.output', 'vendor', 'target'
]);
export const MAX_CONTEXT_SIZE = 12_000;
export const MAX_AUTO_AGENT_STEPS = 50;
export function getConfig() {
const cfg = vscode.workspace.getConfiguration('g1nation');
return {
ollamaUrl: cfg.get<string>('ollamaUrl', 'http://127.0.0.1:11434'),
defaultModel: cfg.get<string>('defaultModel', 'gemma4:e2b'),
maxTreeFiles: 200,
timeout: cfg.get<number>('requestTimeout', 300) * 1000,
localBrainPath: cfg.get<string>('localBrainPath', '')
};
}
export function shouldAutoPushBrain(): boolean {
const cfg = vscode.workspace.getConfiguration('g1nation');
return cfg.get<boolean>('autoPushBrain', false);
}
export function getSecondBrainRepo(): string {
const cfg = vscode.workspace.getConfiguration('g1nation');
return cfg.get<string>('secondBrainRepo', '');
}
export function _getBrainDir(): string {
const { localBrainPath } = getConfig();
if (localBrainPath && localBrainPath.trim() !== '') {
if (localBrainPath.startsWith('~/')) {
return path.join(os.homedir(), localBrainPath.substring(2));
}
return localBrainPath.trim();
}
return path.join(os.homedir(), '.g1nation-brain');
}
export function _isBrainDirExplicitlySet(): boolean {
const { localBrainPath } = getConfig();
return !!(localBrainPath && localBrainPath.trim() !== '');
}
export function isTextAttachment(fileName: string, mimeType: string): boolean {
const lower = fileName.toLowerCase();
const textExtensions = [
'.txt', '.md', '.csv', '.json', '.js', '.ts', '.jsx', '.tsx',
'.html', '.css', '.py', '.java', '.rs', '.go', '.yaml', '.yml',
'.xml', '.toml', '.sql', '.sh'
];
return mimeType.startsWith('text/')
|| mimeType === 'application/json'
|| textExtensions.some((ext) => lower.endsWith(ext));
}
export function findBrainFiles(dir: string): string[] {
let results: string[] = [];
if (!fs.existsSync(dir)) return results;
const list = fs.readdirSync(dir);
list.forEach((file) => {
const filePath = path.join(dir, file);
const stat = fs.statSync(filePath);
if (stat && stat.isDirectory()) {
if (!EXCLUDED_DIRS.has(file)) {
results = results.concat(findBrainFiles(filePath));
}
} else if (file.endsWith('.md')) {
results.push(filePath);
}
});
return results;
}
export const SYSTEM_PROMPT = `You are "G1nation", a premium agentic AI coding assistant running 100% offline on the user's machine.
You are DIRECTLY CONNECTED to the user's local file system and terminal. You MUST use the action tags below to create, edit, delete, read files and run commands. DO NOT just show code - ALWAYS wrap it in the appropriate action tag so it gets executed.
You have EIGHT powerful agent actions:
[ACTION 1: CREATE NEW FILES]
<create_file path="relative/path/file.ext">
file content here
</create_file>
[ACTION 2: EDIT EXISTING FILES]
<edit_file path="relative/path/file.ext">
<find>exact text to find</find>
<replace>replacement text</replace>
</edit_file>
[ACTION 3: DELETE FILES]
<delete_file path="relative/path/file.ext"/>
[ACTION 4: READ FILES]
<read_file path="relative/path/file.ext"/>
[ACTION 5: LIST DIRECTORY]
<list_files path="relative/path/to/dir"/>
[ACTION 6: RUN TERMINAL COMMANDS]
<run_command>npm install express</run_command>
[ACTION 7: READ USER'S SECOND BRAIN]
<read_brain>filename.md</read_brain>
[ACTION 8: READ WEBSITES & SEARCH INTERNET]
<read_url>https://html.duckduckgo.com/html/?q=YOUR+SEARCH+QUERY</read_url>
CRITICAL RULES:
1. ALWAYS respond in the same language the user uses.
2. You MUST use action tags for any file/terminal operations.
3. Be concise and professional.
4. File paths are RELATIVE to the workspace.`;