[P-Reinforce] Fix encoding, rebuild agent engine, and optimize looping

This commit is contained in:
2026-04-24 18:10:13 +09:00
parent b17bbf3bd7
commit 48f41e98c2
4 changed files with 911 additions and 936 deletions
+101
View File
@@ -0,0 +1,101 @@
/**
* ============================================================
* Centralized Configuration (중앙 집중식 설정 관리)
*
* 모든 환경 설정(모델 이름, API 엔드포인트, 타임아웃, 보안 정책 등)
* 을 한 곳에서 관리합니다. Single Source of Truth 원칙 적용.
* ============================================================
*/
import * as vscode from 'vscode';
import * as os from 'os';
import * as path from 'path';
// ─── VS Code 설정에서 읽어오는 값 ───
export function getConfig(): IAgentConfig {
const cfg = vscode.workspace.getConfiguration('g1nation');
return {
ollamaBase: cfg.get<string>('ollamaUrl', 'http://127.0.0.1:11434'),
defaultModel: cfg.get<string>('defaultModel', 'gemma4:e2b'),
maxTreeFiles: cfg.get<number>('maxTreeFiles', 200),
timeout: cfg.get<number>('requestTimeout', 300) * 1000,
localBrainPath: cfg.get<string>('localBrainPath', '')
};
}
// ─── 에이전트 설정 인터페이스 ───
export interface IAgentConfig {
ollamaBase: string;
defaultModel: string;
maxTreeFiles: number;
timeout: number;
localBrainPath: string;
}
// ─── 두뇌 폴더 경로 유틸리티 ───
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() !== '');
}
// ─── 보안 정책 (Security Policy) ───
export const SECURITY_POLICY = {
// 허용된 터미널 명령어 프리픽스 (Whitelist)
allowedCommandPrefixes: [
'npm', 'yarn', 'pnpm', 'npx',
'node', 'ts-node',
'git',
'python', 'python3', 'pip', 'pip3',
'docker', 'docker-compose',
'ls', 'dir', 'cat', 'type',
'echo', 'print',
'cargo', 'go', 'rustc',
'java', 'javac', 'mvn', 'gradle',
'flutter', 'dart', 'pub',
'webpack', 'vite', 'esbuild', 'parcel',
'jest', 'mocha', 'vitest', 'cypress',
'tsc', 'vue-tsc',
],
// 절대 실행 금지 명령어 (Blacklist)
forbiddenCommands: [
'rm -rf', 'rm-rf', 'del /f', 'format',
'mkfs', 'dd if=', ':(){ :|:& };:',
'wget http', 'curl http', 'sudo',
'chmod 777', 'chown root',
],
// 민감한 파일 패턴 (파일 생성/수정 시 경고)
sensitiveFilePatterns: [
'.env', '.env.*',
'id_rsa', 'id_ed25519',
'.gitconfig', '.npmrc', '.pypirc',
'credentials.json', 'service-account.json',
],
// 파일 생성 시 최대 크기 (bytes)
maxFileSize: 10 * 1024 * 1024, // 10MB
// 맥락 파일 최대 개수
maxContextFiles: 200,
};
// ─── 시스템 프롬프트 상수 ───
export const MAX_CONTEXT_SIZE = 12_000;
export const EXCLUDED_DIRS = new Set([
'node_modules', '.git', '.vscode', 'out', 'dist', 'build',
'.next', '.cache', '__pycache__', '.DS_Store', 'coverage',
'.turbo', '.nuxt', '.output', 'vendor', 'target'
]);
+668 -903
View File
File diff suppressed because it is too large Load Diff
+100
View File
@@ -0,0 +1,100 @@
/**
* ============================================================
* Service Interfaces (서비스 인터페이스 정의)
*
* 각 서비스(Agent, Brain, FileSystem 등)의 추상화 인터페이스를 정의합니다.
* 의존성 주입(DI)과 단위 테스트를 위해 필수적입니다.
* ============================================================
*/
import * as vscode from 'vscode';
// ─── 에이전트 서비스 인터페이스 ───
export interface IAgentService {
/**
* LLM에 프롬프트를 보내고 스트리밍 응답을 가져옴
*/
chat(prompt: string, context: string, model?: string): Promise<AsyncGenerator<string>>;
/**
* 터미널 명령어 실행 (보안 정책 적용)
*/
runCommand(command: string): Promise<{ stdout: string; stderr: string }>;
}
// ─── 파일 시스템 서비스 인터페이스 ───
export interface IFileSystemService {
/**
* 파일 생성
*/
createFile(filePath: string, content: string): Promise<void>;
/**
* 파일 읽기
*/
readFile(filePath: string): Promise<string>;
/**
* 파일 수정
*/
editFile(filePath: string, find: string, replace: string): Promise<void>;
/**
* 파일 삭제
*/
deleteFile(filePath: string): Promise<void>;
/**
* 디렉토리 목록 조회
*/
listDirectory(dirPath: string): Promise<string[]>;
}
// ─── 두뇌 서비스 인터페이스 ───
export interface IBrainService {
/**
* 두뇌 폴더 경로 가져오기
*/
getBrainDir(): string;
/**
* 두뇌 폴더가 명시적으로 설정되었는지 확인
*/
isBrainDirExplicitlySet(): boolean;
/**
* 두뇌 폴더 내 파일 목록 조회
*/
getBrainFiles(): Promise<string[]>;
/**
* 두뇌 파일 내용 읽기
*/
readBrainFile(fileName: string): Promise<string>;
}
// ─── 웹뷰 서비스 인터페이스 ───
export interface IWebviewService {
/**
* 웹뷰에 메시지 전송
*/
postMessage(message: any): void;
/**
* 웹뷰에서 메시지 수신 핸들러 등록
*/
onDidReceiveMessage(callback: (message: any) => void): vscode.Disposable;
}
// ─── HTTP 서비스 인터페이스 ───
export interface IHttpService {
/**
* HTTP GET 요청
*/
get(url: string, options?: any): Promise<any>;
/**
* HTTP POST 요청
*/
post(url: string, data: any, options?: any): Promise<any>;
}