diff --git a/.astra/tests/stress/.astra/cache/259a37934ead3910a8722b82054d46d2ca2057b05c488be1dcf439166ac5a9a1.json b/.astra/tests/stress/.astra/cache/259a37934ead3910a8722b82054d46d2ca2057b05c488be1dcf439166ac5a9a1.json index de5fadd..93a10d5 100644 --- a/.astra/tests/stress/.astra/cache/259a37934ead3910a8722b82054d46d2ca2057b05c488be1dcf439166ac5a9a1.json +++ b/.astra/tests/stress/.astra/cache/259a37934ead3910a8722b82054d46d2ca2057b05c488be1dcf439166ac5a9a1.json @@ -1,5 +1,5 @@ { "result": "Final report with inconsistencies. This should be long enough to pass validation.", - "createdAt": 1778129530764, + "createdAt": 1778130178728, "modelVersion": "unknown" } \ No newline at end of file diff --git a/.astra/tests/stress/.astra/cache/65775be352df43297b63c7af59c9f4f39d2bc368f77456c37b5eef9a94a66b5c.json b/.astra/tests/stress/.astra/cache/65775be352df43297b63c7af59c9f4f39d2bc368f77456c37b5eef9a94a66b5c.json index 3f94a0d..eb6a9a6 100644 --- a/.astra/tests/stress/.astra/cache/65775be352df43297b63c7af59c9f4f39d2bc368f77456c37b5eef9a94a66b5c.json +++ b/.astra/tests/stress/.astra/cache/65775be352df43297b63c7af59c9f4f39d2bc368f77456c37b5eef9a94a66b5c.json @@ -1,5 +1,5 @@ { "result": "[CONFLICT WARNING] 성능이 200% 증가했습니다. vs 그러나 동시에 50% 감소했습니다. 최적화와 성능 저하가 동시에 발견됨.", - "createdAt": 1778129530762, + "createdAt": 1778130178726, "modelVersion": "unknown" } \ No newline at end of file diff --git a/.astra/tests/stress/.astra/cache/6894d26c5b0a55d25d756a473225c7a44d7661af673b24e3f49551a7a2e50280.json b/.astra/tests/stress/.astra/cache/6894d26c5b0a55d25d756a473225c7a44d7661af673b24e3f49551a7a2e50280.json index 6d5317b..72bd7d1 100644 --- a/.astra/tests/stress/.astra/cache/6894d26c5b0a55d25d756a473225c7a44d7661af673b24e3f49551a7a2e50280.json +++ b/.astra/tests/stress/.astra/cache/6894d26c5b0a55d25d756a473225c7a44d7661af673b24e3f49551a7a2e50280.json @@ -1,5 +1,5 @@ { "result": "Detailed Execution Plan: 1. Research 2. Analyze 3. Write report with high quality.", - "createdAt": 1778129530759, + "createdAt": 1778130178723, "modelVersion": "unknown" } \ No newline at end of file diff --git a/.astra/tests/stress/.astra/cache/88cb61499f88ed38165b64bd3e8adc543795e4b427b64540a49c9ab27c7fe213.json b/.astra/tests/stress/.astra/cache/88cb61499f88ed38165b64bd3e8adc543795e4b427b64540a49c9ab27c7fe213.json index a772dc8..d383bda 100644 --- a/.astra/tests/stress/.astra/cache/88cb61499f88ed38165b64bd3e8adc543795e4b427b64540a49c9ab27c7fe213.json +++ b/.astra/tests/stress/.astra/cache/88cb61499f88ed38165b64bd3e8adc543795e4b427b64540a49c9ab27c7fe213.json @@ -1,5 +1,5 @@ { - "result": "---\nid: stress_conflict_1778129530743\ndate: 2026-05-07T04:52:10.766Z\ntype: knowledge_artifact\nstandard: P-Reinforce v3.0\ntags: [automated, connect_ai, brain_sync]\n---\n\n## 📌 Brief Summary\nFinal report with inconsistencies. This should be long enough to pass validation.\n\nFinal report with inconsistencies. This should be long enough to pass validation.\n\n---\n## 💡 Astra의 선제적 제안 (Proactive Next Actions)\nFinal report with inconsistencies. This should be long enough to pass validation.\n---\n## 🛡️ Reliability & Audit Summary\n> [!NOTE]\n> 이 문서는 ConnectAI의 **Intelligent Resilience** 엔진에 의해 검증 및 정제되었습니다.\n\n| Metric | Value | Status |\n| :--- | :--- | :--- |\n| **Conflict Risk** | `60/100` | ⚠️ Medium |\n| **Fallbacks Used** | `0` | ✅ None |\n| **Auto Retries** | `0` | ✅ Stable |\n| **Deduplication** | `0` | Standard |\n| **Processing Time** | `0.0s` | ✅ Fast |\n\n### 🔍 Decision Audit Trail\n- **[PLANNER]** 전략 수립 중... (15ms)\n- **[RESEARCHER]** 핵심 정보 수집 및 분석 중... (3ms)\n- **[WRITER]** 최종 리포트 작성 및 편집 중... (2ms)\n", - "createdAt": 1778129530766, + "result": "---\nid: stress_conflict_1778130178706\ndate: 2026-05-07T05:02:58.729Z\ntype: knowledge_artifact\nstandard: P-Reinforce v3.0\ntags: [automated, connect_ai, brain_sync]\n---\n\n## 📌 Brief Summary\nFinal report with inconsistencies. This should be long enough to pass validation.\n\nFinal report with inconsistencies. This should be long enough to pass validation.\n\n---\n## 💡 Astra의 선제적 제안 (Proactive Next Actions)\nFinal report with inconsistencies. This should be long enough to pass validation.\n---\n## 🛡️ Reliability & Audit Summary\n> [!NOTE]\n> 이 문서는 ConnectAI의 **Intelligent Resilience** 엔진에 의해 검증 및 정제되었습니다.\n\n| Metric | Value | Status |\n| :--- | :--- | :--- |\n| **Conflict Risk** | `60/100` | ⚠️ Medium |\n| **Fallbacks Used** | `0` | ✅ None |\n| **Auto Retries** | `0` | ✅ Stable |\n| **Deduplication** | `0` | Standard |\n| **Processing Time** | `0.0s` | ✅ Fast |\n\n### 🔍 Decision Audit Trail\n- **[PLANNER]** 전략 수립 중... (16ms)\n- **[RESEARCHER]** 핵심 정보 수집 및 분석 중... (3ms)\n- **[WRITER]** 최종 리포트 작성 및 편집 중... (2ms)\n", + "createdAt": 1778130178730, "modelVersion": "unknown" } \ No newline at end of file diff --git a/.astra/tests/stress/.astra/missions/stress_conflict_1778129530743.json b/.astra/tests/stress/.astra/missions/stress_conflict_1778130178706.json similarity index 82% rename from .astra/tests/stress/.astra/missions/stress_conflict_1778129530743.json rename to .astra/tests/stress/.astra/missions/stress_conflict_1778130178706.json index 18c7704..6938e32 100644 --- a/.astra/tests/stress/.astra/missions/stress_conflict_1778129530743.json +++ b/.astra/tests/stress/.astra/missions/stress_conflict_1778130178706.json @@ -1,8 +1,8 @@ { - "missionId": "stress_conflict_1778129530743", + "missionId": "stress_conflict_1778130178706", "status": "completed", - "startTime": "2026-05-07T04:52:10.743Z", - "totalElapsedMs": 24, + "startTime": "2026-05-07T05:02:58.706Z", + "totalElapsedMs": 25, "results": { "planner": "Detailed Execution Plan: 1. Research 2. Analyze 3. Write report with high quality.", "researcher": "[CONFLICT WARNING] 성능이 200% 증가했습니다. vs 그러나 동시에 50% 감소했습니다. 최적화와 성능 저하가 동시에 발견됨.", @@ -16,30 +16,30 @@ { "from": "idle", "to": "planner", - "durationMs": 15, + "durationMs": 16, "message": "전략 수립 중...", - "ts": "2026-05-07T04:52:10.758Z" + "ts": "2026-05-07T05:02:58.722Z" }, { "from": "planner", "to": "researcher", "durationMs": 3, "message": "핵심 정보 수집 및 분석 중...", - "ts": "2026-05-07T04:52:10.761Z" + "ts": "2026-05-07T05:02:58.725Z" }, { "from": "researcher", "to": "writer", "durationMs": 2, "message": "최종 리포트 작성 및 편집 중...", - "ts": "2026-05-07T04:52:10.763Z" + "ts": "2026-05-07T05:02:58.727Z" }, { "from": "writer", "to": "completed", "durationMs": 4, "message": "미션 완료", - "ts": "2026-05-07T04:52:10.767Z" + "ts": "2026-05-07T05:02:58.731Z" } ], "resilienceMetrics": { diff --git a/package.json b/package.json index 771f02a..3650914 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.80.9", + "version": "2.80.11", "publisher": "g1nation", "license": "MIT", "icon": "assets/icon.png", diff --git a/src/agent.ts b/src/agent.ts index 4be309f..7fba46b 100644 --- a/src/agent.ts +++ b/src/agent.ts @@ -526,7 +526,28 @@ export class AgentExecutor { logInfo('Generation aborted by user.'); } else { logError('Stream reading error.', { engine, apiUrl, error: err?.message || String(err) }); - this.webview?.postMessage({ type: 'error', value: `Connection lost: ${err.message}` }); + // LM Studio llama.cpp n_keep > n_ctx 에러 감지 + const errMsg = String(err?.message || err || ''); + const nCtxMatch = errMsg.match(/n_keep\s*:\s*(\d+)\s*>=?\s*n_ctx\s*:\s*(\d+)/); + if (nCtxMatch) { + const nKeep = nCtxMatch[1]; + const nCtx = nCtxMatch[2]; + this.webview?.postMessage({ + type: 'error', + value: [ + `Connection lost: AI Engine Error (LM Studio)`, + `시스템 프롬프트 토큰(${nKeep})이 실제 KV 캐시(${nCtx})보다 큽니다.`, + '', + '**원인:** LM Studio가 GPU 메모리 부족으로 컨텍스트 창을 축소했습니다.', + '**해결 방법 (LM Studio 재설정):**', + `1. LM Studio → 모델 설정 → GPU Offload 레이어를 줄여보세요 (현재 설정보다 낮게)`, + `2. 모델을 언로드 후 재로드하세요`, + `3. 다른 앱이 GPU 메모리를 점유하고 있다면 종료 후 재시도`, + ].join('\n') + }); + } else { + this.webview?.postMessage({ type: 'error', value: `Connection lost: ${err.message}` }); + } } } @@ -2020,40 +2041,26 @@ export class AgentExecutor { for (const candidateModel of modelCandidates) { for (const variant of messageVariants) { - // LM Studio: context_length를 명시적으로 제한하여 컨텍스트 초과 방지 - // 총 메시지 토큰 추정: 문자 수 / 4 (rough estimate) const totalChars = variant.messages.reduce((acc, m) => acc + String(m.content || '').length, 0); const estimatedTokens = Math.ceil(totalChars / 4); - // LM Studio 소형 모델(4B~8B)은 4096~8192 context 제한 - // 컨텍스트 초과 시 max_tokens을 줄여서 모델이 응답할 공간 확보 - const lmStudioMaxTokens = Math.max(512, Math.min(4096, 8192 - estimatedTokens)); const streamBody = { model: candidateModel, messages: variant.messages, stream: true, ...(engine === 'lmstudio' - ? { - max_tokens: lmStudioMaxTokens, - temperature, - // LM Studio: context_length로 컨텍스트 창 명시 설정 - context_length: 8192 - } + ? { max_tokens: 4096, temperature } : { options: { num_ctx: 32768, num_predict: 4096, temperature } }), }; - if (engine === 'lmstudio' && estimatedTokens > 6000) { - logError('LM Studio context may be too large for small models.', { estimatedTokens, lmStudioMaxTokens, model: candidateModel }); - } + logInfo('AI streaming request started.', { + engine, apiUrl, model: candidateModel, + variant: variant.name, + messageCount: variant.messages.length, + estimatedTokens, + roles: variant.messages.map(message => message.role), + firstUserPreview: summarizeText(String(variant.messages.find(message => message.role === 'user')?.content || ''), 300) + }); try { - logInfo('AI streaming request started.', { - engine, - apiUrl, - model: candidateModel, - variant: variant.name, - messageCount: variant.messages.length, - roles: variant.messages.map(message => message.role), - firstUserPreview: summarizeText(String(variant.messages.find(message => message.role === 'user')?.content || ''), 300) - }); const response = await fetch(apiUrl, { method: 'POST', headers: {