diff --git a/package-lock.json b/package-lock.json index 12679a9..a5a98a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "astra", - "version": "2.2.226", + "version": "2.2.227", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "astra", - "version": "2.2.226", + "version": "2.2.227", "license": "MIT", "dependencies": { "@lmstudio/sdk": "^1.5.0", diff --git a/package.json b/package.json index 1b8c662..df2405e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "astra", "displayName": "Astra", "description": "The personal intelligence layer for Antigravity and VS Code. A private cognitive partner for deep project context, memory, and proactive strategic decision-making.", - "version": "2.2.226", + "version": "2.2.227", "publisher": "g1nation", "license": "MIT", "icon": "assets/icon.png", diff --git a/src/agent.ts b/src/agent.ts index 5a369a8..9b506e7 100644 --- a/src/agent.ts +++ b/src/agent.ts @@ -543,7 +543,11 @@ export class AgentExecutor { // 이미 있는 기능을 신규 제안하던 구식화 버그(3회 재발)의 마지막 구멍 봉쇄. if (prompt && loopDepth === 0 && !isCasualConversation && activeBrain?.localBrainPath && isSelfAssessRequest(prompt)) { try { - contextBlock += `\n\n${buildSelfAssessContext(activeBrain.localBrainPath)}`; + const selfAssessBlock = buildSelfAssessContext(activeBrain.localBrainPath); + contextBlock += `\n\n${selfAssessBlock}`; + // 성공 로그 필수 — "주입이 됐는데 모델이 무시" vs "주입 자체가 안 됨"을 + // 구분 못 해 같은 버그를 3번 쫓았다. 실패 모드는 관측 가능해야 한다. + logInfo('자기 평가 인벤토리 주입.', { chars: selfAssessBlock.length, promptPreview: prompt.slice(0, 60) }); } catch (e: any) { logError('자기 평가 컨텍스트 주입 실패 (계속 진행).', { error: e?.message ?? String(e) }); } diff --git a/src/extension/featureInventory.ts b/src/extension/featureInventory.ts index 071ad71..a156809 100644 --- a/src/extension/featureInventory.ts +++ b/src/extension/featureInventory.ts @@ -31,6 +31,22 @@ const HOOK_DESCRIPTIONS: Record = { 'critic-loop': '문제 신호(요소 누락/저확신/근거 약함+단정) 턴만 Critic LLM 검수 1회', }; +/** + * 학술/일반 개념 명칭 ↔ ASTRA 구현 매핑. 자기 개선 제안에서 모델이 학술 명칭 + * ("CoVe 도입하라")으로 제안할 때 설정 키(coveEnabled)와 같은 것임을 모르는 + * 이름 매핑 갭을 막는다. 코드와 함께 배포되므로 릴리스마다 자동 최신화. + */ +const CONCEPT_MAP: Array<[concept: string, impl: string]> = [ + ['CoVe / Chain-of-Verification / Self-Critique', '구현됨 — coveEnabled(답변 전 그라운딩 체크리스트) + critic-loop 훅(문제 신호 턴 LLM 검수) + citationTrace(출처 역추적)'], + ['지식 노후 점검 자동화 / Automated Decay Audit', '구현됨 — 주간 성장 사이클이 매주 자동 실행 (decay-report.md)'], + ['지식 충돌 감지/해결 / Conflict Resolver', '구현됨 — 검색 시점 [CONFLICT WARNING] + 일일 충돌 스캔 + 신뢰도(trust·confidence·최신성) 비교 우선 권고. 최종 결정만 사람'], + ['피드백 태깅 / 오류 분류 / Feedback Tagging', '구현됨 — Correction Loop가 사용자 정정을 자동 분류(사실오류/근거누락/맥락누락/추론오류/지시불이행/형식오류)해 레슨+회귀 케이스로 저장'], + ['멀티스텝 플래닝 / Multi-Step Planning / CoT 강제', '구현됨 — multiAgentEnabled(Planner→Researcher→Writer, 기본 OFF) + 1인 기업 모드 디스패처'], + ['골든셋 자동 평가 / Regression Test', '구현됨 — 주간 사이클 자동 평가 + 직전 대비 회귀 경보(regression-alert.md) + 정정 회귀 재검사'], + ['Sleep-time / 유휴 시간 학습', '구현됨 — 일일 지식 사전 소화 (Digests/)'], + ['확신도 게이팅 / 환각 방지 표명', '구현됨 — [GROUNDING] 강함/보통/약함 + 약함 시 표명 강제 + 학습큐 자동 등록'], +]; + function stripMd(s: string): string { return (s || '').replace(/\*\*|`|\[|\]/g, '').replace(/\s+/g, ' ').trim(); } @@ -68,6 +84,10 @@ export function buildInventoryMarkdown(pkg: any, nowIso: string): string { `## 답변 후 자동 검증 훅 (${POST_ANSWER_HOOKS.length}단계 — 매 답변 후 실행)`, ...POST_ANSWER_HOOKS.map(h => `- \`${h.id}\` — ${HOOK_DESCRIPTIONS[h.id] || '(설명 미등록 — 코드 참조)'}`), '', + '## ⚠️ 개선 제안 전 필독 — 학술 개념 ↔ 구현 매핑', + '아래 개념들은 명칭이 달라도 **이미 구현되어 있다**. 이들을 "도입/추가하라"고 제안하면 오답이다:', + ...CONCEPT_MAP.map(([concept, impl]) => `- **${concept}**: ${impl}`), + '', ]; return lines.join('\n'); } diff --git a/src/lib/contextBuilders/selfAssessContext.ts b/src/lib/contextBuilders/selfAssessContext.ts index f6d1c49..228c5a3 100644 --- a/src/lib/contextBuilders/selfAssessContext.ts +++ b/src/lib/contextBuilders/selfAssessContext.ts @@ -16,16 +16,17 @@ import * as path from 'path'; import { INVENTORY_FILE } from '../../extension/featureInventory'; const IMPROVE_RE = /(개선|고도화|발전|보완|제안|평가|분석|방향|방법|아이디어|로드맵|업그레이드|날카롭|강화)/i; -const SELF_RE = /(기능|역량|능력|아키텍처|구조|시스템|self.?evolv|자기\s*진화|자기\s*개선|아스트라|astra|너(가|의|는)?|네가)/i; +const SELF_RE = /(기능|역량|능력|아키텍처|구조|시스템|self.?evolv|자기\s*진화|자기\s*개선|아스트라|astra|connectai|프로젝트|업무\s*능력|너(가|의|는)?|네가)/i; const CAPABILITY_RE = /(무슨|어떤|할\s*수\s*있는)\s*(기능|일|것)|기능\s*(목록|리스트)|capabilit/i; /** * 자기 평가·개선·기능 질의인지. 오탐 비용이 낮으므로(인벤토리 ~3KB 추가 주입뿐) - * 누락(또 구식 제안)보다 과잉 감지를 택한다. + * 누락(또 구식 제안)보다 과잉 감지를 택한다. 길이 상한 1500 — 사용자의 개선 요청은 + * 배경 설명이 붙어 길어지는 경우가 많다 (600 으로는 실사용 질문을 놓침). */ export function isSelfAssessRequest(prompt: string): boolean { const p = (prompt || '').trim(); - if (!p || p.length > 600) return false; + if (!p || p.length > 1500) return false; return CAPABILITY_RE.test(p) || (IMPROVE_RE.test(p) && SELF_RE.test(p)); } @@ -49,9 +50,11 @@ export function buildSelfAssessContext(brainPath: string): string { return [ header, '자기 기능 평가·개선 제안 시 반드시 아래 인벤토리와 대조하라:', - '- 아래에 **이미 있는 기능을 신규 제안하지 마라.**', + '- 아래에 **이미 있는 기능을 신규 제안하지 마라.** 특히 "개선 제안 전 필독" 섹션의 개념들(CoVe·노후 점검 자동화·충돌 해결·피드백 태깅 등)은 명칭이 달라도 이미 구현돼 있다 — 이를 "도입하라"고 제안하면 그 답변은 오답이다.', '- 제안은 "현재 X가 있고, 빠진 증분은 Y" 형태로.', '- 아래에 없는 기능을 있다고 주장하지도 마라.', + '- 직전 대화에서 본인이 했던 제안 목록을 그대로 반복하지 마라 — 이 인벤토리가 그 제안들보다 우선하는 최신 사실이다.', + '- 답변 끝에 "출처: ASTRA 기능 인벤토리 v<버전>" 을 표기하라 (이 블록을 실제로 읽었다는 증거).', '', body, ].join('\n');