Version 2.42.0 Release: Autonomous Anti-Blocking Generation for Project Knowledge

This commit is contained in:
g1nation
2026-05-03 00:54:05 +09:00
parent 9403662ba3
commit 1d9c7f203f
3 changed files with 95 additions and 2 deletions
+1 -1
View File
@@ -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.41.0",
"version": "2.42.0",
"publisher": "connectailab",
"license": "MIT",
"icon": "assets/icon.png",
+65 -1
View File
@@ -330,12 +330,15 @@ export class AgentExecutor {
const designerCtx = options.designerContext
? `\n\n[PROJECT CHRONICLE GUARD]\n${options.designerContext}`
: '';
const localProjectKnowledgeCtx = prompt && localPathContext && this.isProjectKnowledgeCreationRequest(prompt)
? `\n\n[LOCAL PROJECT KNOWLEDGE CREATION OVERRIDE]\nThe user gave an accessible local project path and asked to create project knowledge. Do not ask blocking scope questions. Use a sensible default MVP: create or propose a project overview note from the inspected tree and priority file previews. If writing is not explicitly safe, provide the concrete note draft and target path.`
: '';
const secondBrainTraceCtx = secondBrainTrace
? `\n\n${renderSecondBrainTraceContext(secondBrainTrace)}`
: '';
const memoryCtx = this.buildMemoryContext(prompt || '', activeBrain);
const fullSystemPrompt = `${agentSkillCtx}\n\n${systemPrompt}${internetCtx}${memoryCtx}${designerCtx}${secondBrainTraceCtx}\n\n[CONTEXT]\n${brainContext}${brainInventoryCtx}\n${contextBlock}${negativeCtx}`;
const fullSystemPrompt = `${agentSkillCtx}\n\n${systemPrompt}${internetCtx}${memoryCtx}${designerCtx}${localProjectKnowledgeCtx}${secondBrainTraceCtx}\n\n[CONTEXT]\n${brainContext}${brainInventoryCtx}\n${contextBlock}${negativeCtx}`;
const messagesForRequest: ChatMessage[] = [
{ role: 'system', content: fullSystemPrompt, internal: true },
...reqMessages
@@ -430,6 +433,9 @@ export class AgentExecutor {
if (prompt && this.isSecondBrainInventoryRequest(prompt) && brainFiles.length > 0 && this.isNoBrainDataRefusal(assistantContent)) {
assistantContent = this.buildSecondBrainInventoryFallbackAnswer(activeBrain, brainFiles, secondBrainTrace);
}
if (prompt && localPathContext && this.isProjectKnowledgeCreationRequest(prompt) && this.isBlockingProjectKnowledgeAnswer(assistantContent)) {
assistantContent = this.buildProjectKnowledgeFallbackAnswer(localPathContext);
}
const traceMarkdown = secondBrainTrace
? renderSecondBrainTraceMarkdown(secondBrainTrace, !!options.secondBrainTraceDebug)
: '';
@@ -742,6 +748,11 @@ export class AgentExecutor {
&& /\/Volumes\/Data\/project\/Antigravity\/[^\s`"'<>]+/i.test(prompt);
}
private isProjectKnowledgeCreationRequest(prompt: string): boolean {
return /(지식|문서화|문서|정리|기록|위키|저장|만들|생성|knowledge|document|documentation|wiki|summari[sz]e)/i.test(prompt)
&& /\/Volumes\/Data\/project\/Antigravity\/[^\s`"'<>]+/i.test(prompt);
}
private extractLocalProjectPaths(prompt: string): string[] {
const matches = prompt.match(/\/Volumes\/Data\/project\/Antigravity\/[^\s`"'<>]+/gi) || [];
return Array.from(new Set(matches.map((value) => value.replace(/[),.;\]]+$/g, ''))));
@@ -831,6 +842,59 @@ export class AgentExecutor {
].filter(Boolean).join('\n\n');
}
private isBlockingProjectKnowledgeAnswer(content: string): boolean {
return /(블로킹 질문|어떤 기능 영역|어떤 부분.*먼저|어떤 기능이나 아키텍처|구체적인 방향|방향 설정이 필요|명확히 알려주시면|우선적으로 정리|최종 사용 목적|Question reason)/i.test(content);
}
private buildProjectKnowledgeFallbackAnswer(localPathContext: string): string {
const pathMatch = localPathContext.match(/Path:\s*(.+)/);
const projectPath = pathMatch?.[1]?.trim() || '제공된 로컬 프로젝트 경로';
const treeMatch = localPathContext.match(/Scanned tree:\n([\s\S]*?)(?:\nPriority file previews:|$)/);
const treePreview = treeMatch?.[1]?.trim().split('\n').slice(0, 18).join('\n') || '';
const priorityMatches = [...localPathContext.matchAll(/###\s+(.+)/g)].map((match) => match[1].trim()).slice(0, 10);
const priorityText = priorityMatches.length
? priorityMatches.map((file) => `- ${file}`).join('\n')
: '- package.json, src, docs, config 계열 파일을 우선 확인';
return [
'## 간단 요약',
'맞아요. 이 경우에는 추가 질문으로 멈출 필요 없이, 지금 확인된 로컬 프로젝트 구조를 기준으로 기본 프로젝트 지식을 바로 만들면 됩니다.',
'',
'## 기본 지식 생성 방향',
`대상 프로젝트는 \`${projectPath}\`입니다. 우선 MVP 지식은 “프로젝트 개요 + 주요 모듈 + 확인된 근거 파일 + 다음에 깊게 볼 영역” 형태로 만드는 것이 가장 안전합니다.`,
'',
'## 확인된 근거',
priorityText,
'',
treePreview ? `## 확인된 구조 일부\n\`\`\`text\n${treePreview}\n\`\`\`` : '',
'',
'## 바로 만들 지식 초안',
'```markdown',
'# ConnectAI Project Knowledge Overview',
'',
'## Purpose',
'ConnectAI는 VS Code 안에서 로컬 AI 에이전트, Second Brain, 프로젝트 기록, 에이전트 스킬을 연결하는 개발 보조 프로젝트다.',
'',
'## Confirmed Structure',
'- `src/agent.ts`: 에이전트 실행, 로컬 경로 프리플라이트, Second Brain Trace, 액션 실행 흐름의 중심.',
'- `src/sidebarProvider.ts`: Webview UI, 브레인/모델/프로젝트 선택, 프롬프트 전달, 기록 UI를 담당.',
'- `src/features/secondBrainTrace.ts`: Second Brain 검색 결과와 근거 정책을 구성.',
'- `src/features/projectChronicle/`: 프로젝트 기록을 Markdown으로 관리하는 Chronicle 기능.',
'- `src/core/`: 큐, 이벤트, 트랜잭션, 오류 처리 등 실행 안정성 계층.',
'- `tests/`: Second Brain, 로컬 경로 프리플라이트, Chronicle, 보안/트랜잭션 회귀 테스트.',
'',
'## Current Knowledge Gap',
'- 전체 아키텍처는 파일 구조와 일부 프리뷰 기준으로 파악 가능하지만, 세부 동작 지식은 `src/agent.ts`, `src/sidebarProvider.ts`, `secondBrainTrace.ts`, `projectChronicle` 순서로 심화 분석해 보강해야 한다.',
'',
'## Recommended Next Record',
'- `docs/records/ConnectAI/development/YYYY-MM-DD_connectai_project_knowledge_overview.md`',
'```',
'',
'## 다음 액션',
'기본값으로는 위 초안을 프로젝트 지식 1번 문서로 저장하고, 그 다음 `agent.ts` 실행 흐름 지식을 별도 문서로 쪼개는 것이 좋습니다.'
].filter(Boolean).join('\n');
}
private listProjectTree(root: string, current: string, depth: number, maxDepth: number, limit: number): string {
if (limit <= 0 || depth > maxDepth) {
return '';
+29
View File
@@ -84,4 +84,33 @@ describe('local project path preflight', () => {
expect(fixed).not.toContain('핵심 파일이나 구조를 저에게 제공');
expect(fixed).not.toContain('실제 구현 근거 없이는');
});
it('replaces blocking scope questions for local project knowledge creation', () => {
const context: any = {
globalStorageUri: { fsPath: path.join(root, '.storage') },
workspaceState: stateStore(),
globalState: stateStore()
};
const agent = new AgentExecutor(context) as any;
const answer = '## 블로킹 질문\n1. 어떤 기능 영역을 가장 먼저 분석하고 싶으신가요? (Question reason: 범위 조정)';
const localPathContext = [
'Path: /Volumes/Data/project/Antigravity/ConnectAI',
'Access: succeeded',
'Type: directory',
'Scanned tree:',
'src/',
'src/agent.ts',
'Priority file previews:',
'### package.json',
'{"name":"g1nation"}',
'### src/agent.ts',
'export class AgentExecutor {}'
].join('\n');
expect(agent.isBlockingProjectKnowledgeAnswer(answer)).toBe(true);
const fallback = agent.buildProjectKnowledgeFallbackAnswer(localPathContext);
expect(fallback).toContain('추가 질문으로 멈출 필요 없이');
expect(fallback).toContain('ConnectAI Project Knowledge Overview');
expect(fallback).not.toContain('어떤 기능 영역을 가장 먼저');
});
});