@gracker/smartperfetto 1.0.18 → 1.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/core/conclusionContract.d.ts +1 -0
- package/dist/agent/core/conclusionContract.d.ts.map +1 -1
- package/dist/agent/tools/frameAnalyzer.d.ts.map +1 -1
- package/dist/agent/tools/frameAnalyzer.js +1 -0
- package/dist/agent/tools/frameAnalyzer.js.map +1 -1
- package/dist/agentOpenAI/openAiRuntime.d.ts +24 -0
- package/dist/agentOpenAI/openAiRuntime.d.ts.map +1 -1
- package/dist/agentOpenAI/openAiRuntime.js +171 -195
- package/dist/agentOpenAI/openAiRuntime.js.map +1 -1
- package/dist/agentRuntime/index.d.ts +1 -0
- package/dist/agentRuntime/index.d.ts.map +1 -1
- package/dist/agentRuntime/index.js +16 -1
- package/dist/agentRuntime/index.js.map +1 -1
- package/dist/agentRuntime/runtimeCommon.d.ts +34 -0
- package/dist/agentRuntime/runtimeCommon.d.ts.map +1 -0
- package/dist/agentRuntime/runtimeCommon.js +231 -0
- package/dist/agentRuntime/runtimeCommon.js.map +1 -0
- package/dist/agentv3/claudeConfig.d.ts +6 -2
- package/dist/agentv3/claudeConfig.d.ts.map +1 -1
- package/dist/agentv3/claudeConfig.js +50 -48
- package/dist/agentv3/claudeConfig.js.map +1 -1
- package/dist/agentv3/claudeMcpServer.d.ts.map +1 -1
- package/dist/agentv3/claudeMcpServer.js +74 -66
- package/dist/agentv3/claudeMcpServer.js.map +1 -1
- package/dist/agentv3/claudeRuntime.d.ts +18 -2
- package/dist/agentv3/claudeRuntime.d.ts.map +1 -1
- package/dist/agentv3/claudeRuntime.js +201 -268
- package/dist/agentv3/claudeRuntime.js.map +1 -1
- package/dist/agentv3/claudeSseBridge.js +1 -1
- package/dist/agentv3/claudeSseBridge.js.map +1 -1
- package/dist/agentv3/claudeSystemPrompt.d.ts.map +1 -1
- package/dist/agentv3/claudeSystemPrompt.js +14 -1
- package/dist/agentv3/claudeSystemPrompt.js.map +1 -1
- package/dist/agentv3/claudeVerifier.d.ts +1 -1
- package/dist/agentv3/claudeVerifier.d.ts.map +1 -1
- package/dist/agentv3/claudeVerifier.js +42 -19
- package/dist/agentv3/claudeVerifier.js.map +1 -1
- package/dist/agentv3/strategyLoader.d.ts +28 -0
- package/dist/agentv3/strategyLoader.d.ts.map +1 -1
- package/dist/agentv3/strategyLoader.js +35 -0
- package/dist/agentv3/strategyLoader.js.map +1 -1
- package/dist/cli/commands/validate.d.ts.map +1 -1
- package/dist/cli/commands/validate.js +120 -10
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli-user/bin.js +83 -2
- package/dist/cli-user/bin.js.map +1 -1
- package/dist/cli-user/commands/analyze.d.ts +2 -0
- package/dist/cli-user/commands/analyze.d.ts.map +1 -1
- package/dist/cli-user/commands/analyze.js +1 -0
- package/dist/cli-user/commands/analyze.js.map +1 -1
- package/dist/cli-user/commands/capture.d.ts +37 -2
- package/dist/cli-user/commands/capture.d.ts.map +1 -1
- package/dist/cli-user/commands/capture.js +184 -95
- package/dist/cli-user/commands/capture.js.map +1 -1
- package/dist/cli-user/commands/codebase.js +4 -4
- package/dist/cli-user/commands/codebase.js.map +1 -1
- package/dist/cli-user/commands/compare.d.ts +2 -0
- package/dist/cli-user/commands/compare.d.ts.map +1 -1
- package/dist/cli-user/commands/compare.js +1 -0
- package/dist/cli-user/commands/compare.js.map +1 -1
- package/dist/cli-user/commands/doctor.js +4 -0
- package/dist/cli-user/commands/doctor.js.map +1 -1
- package/dist/cli-user/services/androidCapture.d.ts +59 -0
- package/dist/cli-user/services/androidCapture.d.ts.map +1 -0
- package/dist/cli-user/services/androidCapture.js +375 -0
- package/dist/cli-user/services/androidCapture.js.map +1 -0
- package/dist/cli-user/services/captureConfig.d.ts +38 -0
- package/dist/cli-user/services/captureConfig.d.ts.map +1 -0
- package/dist/cli-user/services/captureConfig.js +434 -0
- package/dist/cli-user/services/captureConfig.js.map +1 -0
- package/dist/cli-user/services/captureTools.d.ts +11 -0
- package/dist/cli-user/services/captureTools.d.ts.map +1 -0
- package/dist/cli-user/services/captureTools.js +247 -0
- package/dist/cli-user/services/captureTools.js.map +1 -0
- package/dist/cli-user/services/cliAnalyzeService.d.ts +2 -0
- package/dist/cli-user/services/cliAnalyzeService.d.ts.map +1 -1
- package/dist/cli-user/services/cliAnalyzeService.js +1 -0
- package/dist/cli-user/services/cliAnalyzeService.js.map +1 -1
- package/dist/cli-user/services/runtimeGuard.d.ts +10 -0
- package/dist/cli-user/services/runtimeGuard.d.ts.map +1 -1
- package/dist/cli-user/services/runtimeGuard.js +48 -0
- package/dist/cli-user/services/runtimeGuard.js.map +1 -1
- package/dist/cli-user/services/turnRunner.d.ts +3 -0
- package/dist/cli-user/services/turnRunner.d.ts.map +1 -1
- package/dist/cli-user/services/turnRunner.js +4 -0
- package/dist/cli-user/services/turnRunner.js.map +1 -1
- package/dist/cli-user/types.d.ts +57 -0
- package/dist/cli-user/types.d.ts.map +1 -1
- package/dist/perfetto-recording-tools-pin.env +24 -0
- package/dist/routes/ragAdminRoutes.js +7 -7
- package/dist/routes/ragAdminRoutes.js.map +1 -1
- package/dist/services/agentResultNormalizer.d.ts.map +1 -1
- package/dist/services/agentResultNormalizer.js +32 -4
- package/dist/services/agentResultNormalizer.js.map +1 -1
- package/dist/services/codebase/pathSecurityGate.d.ts +2 -2
- package/dist/services/codebase/pathSecurityGate.d.ts.map +1 -1
- package/dist/services/codebase/pathSecurityGate.js +33 -9
- package/dist/services/codebase/pathSecurityGate.js.map +1 -1
- package/dist/services/evidence/evidenceContractBuilder.d.ts.map +1 -1
- package/dist/services/evidence/evidenceContractBuilder.js +17 -3
- package/dist/services/evidence/evidenceContractBuilder.js.map +1 -1
- package/dist/services/finalReportContractGate.d.ts +13 -0
- package/dist/services/finalReportContractGate.d.ts.map +1 -0
- package/dist/services/finalReportContractGate.js +48 -0
- package/dist/services/finalReportContractGate.js.map +1 -0
- package/dist/services/finalResultQualityGate.d.ts +3 -1
- package/dist/services/finalResultQualityGate.d.ts.map +1 -1
- package/dist/services/finalResultQualityGate.js +18 -1
- package/dist/services/finalResultQualityGate.js.map +1 -1
- package/dist/services/htmlReportGenerator.d.ts +12 -0
- package/dist/services/htmlReportGenerator.d.ts.map +1 -1
- package/dist/services/htmlReportGenerator.js +286 -33
- package/dist/services/htmlReportGenerator.js.map +1 -1
- package/dist/services/perfettoSqlSkill.d.ts.map +1 -1
- package/dist/services/perfettoSqlSkill.js +1 -0
- package/dist/services/perfettoSqlSkill.js.map +1 -1
- package/dist/services/providerManager/connectionTester.d.ts.map +1 -1
- package/dist/services/providerManager/connectionTester.js +4 -68
- package/dist/services/providerManager/connectionTester.js.map +1 -1
- package/dist/services/providerManager/index.d.ts +1 -0
- package/dist/services/providerManager/index.d.ts.map +1 -1
- package/dist/services/providerManager/index.js +8 -1
- package/dist/services/providerManager/index.js.map +1 -1
- package/dist/services/providerManager/providerService.d.ts.map +1 -1
- package/dist/services/providerManager/providerService.js +37 -106
- package/dist/services/providerManager/providerService.js.map +1 -1
- package/dist/services/providerManager/providerSnapshot.d.ts.map +1 -1
- package/dist/services/providerManager/providerSnapshot.js +13 -12
- package/dist/services/providerManager/providerSnapshot.js.map +1 -1
- package/dist/services/providerManager/runtimeCapabilities.d.ts +9 -0
- package/dist/services/providerManager/runtimeCapabilities.d.ts.map +1 -0
- package/dist/services/providerManager/runtimeCapabilities.js +105 -0
- package/dist/services/providerManager/runtimeCapabilities.js.map +1 -0
- package/dist/services/rag/aospSourceIngester.d.ts +1 -1
- package/dist/services/rag/aospSourceIngester.d.ts.map +1 -1
- package/dist/services/rag/aospSourceIngester.js +6 -4
- package/dist/services/rag/aospSourceIngester.js.map +1 -1
- package/dist/services/rag/appSourceIngester.d.ts +1 -1
- package/dist/services/rag/appSourceIngester.d.ts.map +1 -1
- package/dist/services/rag/appSourceIngester.js +6 -4
- package/dist/services/rag/appSourceIngester.js.map +1 -1
- package/dist/services/rag/kernelSourceIngester.d.ts +1 -1
- package/dist/services/rag/kernelSourceIngester.d.ts.map +1 -1
- package/dist/services/rag/kernelSourceIngester.js +6 -4
- package/dist/services/rag/kernelSourceIngester.js.map +1 -1
- package/dist/services/ragStore.d.ts +2 -0
- package/dist/services/ragStore.d.ts.map +1 -1
- package/dist/services/ragStore.js +6 -1
- package/dist/services/ragStore.js.map +1 -1
- package/dist/services/skillEngine/skillExecutor.d.ts +1 -0
- package/dist/services/skillEngine/skillExecutor.d.ts.map +1 -1
- package/dist/services/skillEngine/skillExecutor.js +64 -12
- package/dist/services/skillEngine/skillExecutor.js.map +1 -1
- package/package.json +5 -5
- package/prebuilts/android-platform-tools/README.md +13 -0
- package/prebuilts/perfetto-recording-tools/README.md +17 -0
- package/skills/atomic/cpu_topology_detection.skill.yaml +105 -159
- package/skills/atomic/cpu_topology_view.skill.yaml +2 -0
- package/strategies/prompt-openai-final-report-continuation-en.template.md +5 -1
- package/strategies/prompt-openai-final-report-continuation-zh.template.md +5 -1
- package/strategies/prompt-output-format.template.md +1 -1
- package/strategies/scrolling.strategy.md +22 -0
- package/strategies/startup.strategy.md +27 -1
|
@@ -65,18 +65,10 @@ const contextTokenMeter_1 = require("./contextTokenMeter");
|
|
|
65
65
|
const agentMetrics_1 = require("./agentMetrics");
|
|
66
66
|
const analysisPatternMemory_1 = require("./analysisPatternMemory");
|
|
67
67
|
const codeAwareOutputRegistry_1 = require("../services/security/codeAwareOutputRegistry");
|
|
68
|
-
const skillNotesInjector_1 = require("./selfImprove/skillNotesInjector");
|
|
69
68
|
const strategyFingerprint_1 = require("./selfImprove/strategyFingerprint");
|
|
70
69
|
const claudeVerifier_1 = require("./claudeVerifier");
|
|
71
70
|
const runtimePaths_1 = require("../runtimePaths");
|
|
72
71
|
const finalResultQualityGate_1 = require("../services/finalResultQualityGate");
|
|
73
|
-
function parseQuickBudgetEnv() {
|
|
74
|
-
const v = process.env.SELF_IMPROVE_QUICK_NOTES_BUDGET;
|
|
75
|
-
if (!v)
|
|
76
|
-
return undefined;
|
|
77
|
-
const n = Number.parseInt(v, 10);
|
|
78
|
-
return Number.isFinite(n) && n >= 0 ? n : undefined;
|
|
79
|
-
}
|
|
80
72
|
function parseLeadingJsonObject(text) {
|
|
81
73
|
let depth = 0;
|
|
82
74
|
let inString = false;
|
|
@@ -142,7 +134,7 @@ function extractPlanPhaseIdFromToolResult(resultStr) {
|
|
|
142
134
|
return undefined;
|
|
143
135
|
}
|
|
144
136
|
function looksLikeProcessNarration(text) {
|
|
145
|
-
return /(
|
|
137
|
+
return /(?:我来|我需要|我将|接下来|先重新|重新读取|继续调用|首先.*提交|计划已提交|工具|tool|let me|i need to|i will|next i)/i
|
|
146
138
|
.test(text.slice(0, 500));
|
|
147
139
|
}
|
|
148
140
|
function correctionResultLooksUsable(text) {
|
|
@@ -156,16 +148,116 @@ function correctionResultLooksUsable(text) {
|
|
|
156
148
|
return false;
|
|
157
149
|
return hasFinalReportMarker || !(0, claudeVerifier_1.isConclusionIncomplete)(trimmed);
|
|
158
150
|
}
|
|
151
|
+
function findDeliverableReportHeadingIndex(text) {
|
|
152
|
+
const match = text.match(/(?:^|\n)\s{0,3}(?:#{1,3}\s*)?(?:(?:[^\n#]{0,40})?分析报告|综合结论|关键结论|最终结论|最终报告|根因分析|Final Conclusion|Final Report|Analysis Report|Root Cause)(?=\s|[::。.!!?\n]|$)/i);
|
|
153
|
+
return match?.index ?? -1;
|
|
154
|
+
}
|
|
155
|
+
function stripLeadingProcessNarrationBeforeSection(text) {
|
|
156
|
+
const trimmed = text.trim();
|
|
157
|
+
if (!trimmed)
|
|
158
|
+
return '';
|
|
159
|
+
const reportHeadingMatch = trimmed.match(/^\s{0,3}#{1,3}\s*[^\n]*(?:分析报告|最终报告|Final Report|Analysis Report)[^\n]*\n+/i);
|
|
160
|
+
const heading = reportHeadingMatch ? reportHeadingMatch[0].trimEnd() : '';
|
|
161
|
+
const body = reportHeadingMatch
|
|
162
|
+
? trimmed.slice(reportHeadingMatch[0].length).trimStart()
|
|
163
|
+
: trimmed;
|
|
164
|
+
const sectionMatch = /(?:^|\n)\s{0,3}#{1,4}\s+\S/.exec(body);
|
|
165
|
+
if (!sectionMatch || sectionMatch.index === undefined || sectionMatch.index <= 0) {
|
|
166
|
+
return trimmed;
|
|
167
|
+
}
|
|
168
|
+
const prefix = body.slice(0, sectionMatch.index).trim();
|
|
169
|
+
const prefixIsProcessNarration = looksLikeProcessNarration(prefix) ||
|
|
170
|
+
(0, finalResultQualityGate_1.looksLikeProcessNarrationConclusion)(prefix) ||
|
|
171
|
+
/(?:我来分析|计划已提交|开始\s*Phase|进入\s*Phase|Phase\s*\d+|所有假设已解决|完整结构化报告|修正重试|验证发现|update_plan_phase|resolve_hypothesis)/i.test(prefix);
|
|
172
|
+
if (!prefixIsProcessNarration)
|
|
173
|
+
return trimmed;
|
|
174
|
+
const reportBody = body.slice(sectionMatch.index).trimStart();
|
|
175
|
+
return heading ? `${heading}\n\n${reportBody}` : reportBody;
|
|
176
|
+
}
|
|
177
|
+
function sanitizeClaudeConclusionText(text) {
|
|
178
|
+
const trimmed = text.trim();
|
|
179
|
+
if (!trimmed)
|
|
180
|
+
return '';
|
|
181
|
+
const singleLineCleaned = trimmed
|
|
182
|
+
.replace(/^(?:完成综合结论输出|完整结构化报告已(?:输出|生成))[。::\s]*/i, '')
|
|
183
|
+
.replace(/^所有假设已解决[。;;,\s]*(?:现在)?输出完整结构化报告[。::\s-]*/i, '')
|
|
184
|
+
.replace(/^所有(?:深钻)?数据已收集完毕[。;;,\s]*(?:现在)?输出(?:综合结论|最终报告|完整结构化报告)[。::\s-]*/i, '')
|
|
185
|
+
.trim();
|
|
186
|
+
const processIntroCleaned = stripLeadingProcessNarrationBeforeSection(singleLineCleaned);
|
|
187
|
+
if (processIntroCleaned !== trimmed)
|
|
188
|
+
return processIntroCleaned;
|
|
189
|
+
const headingIndex = findDeliverableReportHeadingIndex(trimmed);
|
|
190
|
+
if (headingIndex <= 0 || !(0, finalResultQualityGate_1.hasDeliverableFinalReportHeading)(trimmed.slice(headingIndex))) {
|
|
191
|
+
return trimmed;
|
|
192
|
+
}
|
|
193
|
+
const prefix = trimmed.slice(0, headingIndex).trim();
|
|
194
|
+
const prefixIsProcessNarration = looksLikeProcessNarration(prefix) ||
|
|
195
|
+
(0, finalResultQualityGate_1.looksLikeProcessNarrationConclusion)(prefix) ||
|
|
196
|
+
/(?:我来分析|计划已提交|开始\s*Phase|进入\s*Phase|Phase\s*\d+|所有假设已解决|完整结构化报告|修正重试|验证发现|update_plan_phase|resolve_hypothesis)/i.test(prefix);
|
|
197
|
+
if (!prefixIsProcessNarration)
|
|
198
|
+
return trimmed;
|
|
199
|
+
return trimmed.slice(headingIndex).trim();
|
|
200
|
+
}
|
|
201
|
+
function reportHeadingForScene(sceneType, outputLanguage) {
|
|
202
|
+
const zh = outputLanguage !== 'en';
|
|
203
|
+
switch (sceneType) {
|
|
204
|
+
case 'startup':
|
|
205
|
+
return zh ? '# 启动性能分析报告' : '# Startup Performance Analysis Report';
|
|
206
|
+
case 'scrolling':
|
|
207
|
+
return zh ? '# 滑动性能分析报告' : '# Scrolling Performance Analysis Report';
|
|
208
|
+
case 'anr':
|
|
209
|
+
return zh ? '# ANR 分析报告' : '# ANR Analysis Report';
|
|
210
|
+
default:
|
|
211
|
+
return zh ? '# 性能分析报告' : '# Performance Analysis Report';
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function looksLikeStructuredDeliverableReport(text) {
|
|
215
|
+
const trimmed = text.trim();
|
|
216
|
+
const headingCount = (trimmed.match(/(^|\n)\s{0,3}#{1,3}\s+\S/g) || []).length;
|
|
217
|
+
if (headingCount < 2)
|
|
218
|
+
return false;
|
|
219
|
+
return /(?:evidence_ref_id|source_ref|art-\d+|data:art-\d+|data:skill:|##?\s*(?:概览|关键发现|根因|优化建议|Recommendations|Evidence))/i.test(trimmed);
|
|
220
|
+
}
|
|
221
|
+
function ensureClaudeFinalReportHeading(text, sceneType, outputLanguage) {
|
|
222
|
+
const trimmed = sanitizeClaudeConclusionText(text);
|
|
223
|
+
if (!trimmed || (0, finalResultQualityGate_1.hasDeliverableFinalReportHeading)(trimmed))
|
|
224
|
+
return trimmed;
|
|
225
|
+
if (!looksLikeStructuredDeliverableReport(trimmed))
|
|
226
|
+
return trimmed;
|
|
227
|
+
return `${reportHeadingForScene(sceneType, outputLanguage)}\n\n${trimmed}`;
|
|
228
|
+
}
|
|
229
|
+
function shouldMarkCorrectionTimeoutPartial(input) {
|
|
230
|
+
if (correctionResultLooksUsable(sanitizeClaudeConclusionText(input.correctedResult))) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
return !correctionResultLooksUsable(sanitizeClaudeConclusionText(input.existingConclusion));
|
|
234
|
+
}
|
|
235
|
+
function chooseClaudeConclusionText(input) {
|
|
236
|
+
const finalResult = sanitizeClaudeConclusionText(input.finalResult);
|
|
237
|
+
const accumulatedAnswer = sanitizeClaudeConclusionText(input.accumulatedAnswer);
|
|
238
|
+
if (!finalResult)
|
|
239
|
+
return accumulatedAnswer;
|
|
240
|
+
if (!accumulatedAnswer)
|
|
241
|
+
return finalResult;
|
|
242
|
+
if ((0, claudeVerifier_1.isConclusionIncomplete)(finalResult) &&
|
|
243
|
+
accumulatedAnswer.length > finalResult.length &&
|
|
244
|
+
(0, finalResultQualityGate_1.hasDeliverableFinalReportHeading)(accumulatedAnswer)) {
|
|
245
|
+
return accumulatedAnswer;
|
|
246
|
+
}
|
|
247
|
+
if (!(0, finalResultQualityGate_1.hasDeliverableFinalReportHeading)(finalResult) &&
|
|
248
|
+
(0, finalResultQualityGate_1.hasDeliverableFinalReportHeading)(accumulatedAnswer)) {
|
|
249
|
+
return accumulatedAnswer;
|
|
250
|
+
}
|
|
251
|
+
return finalResult;
|
|
252
|
+
}
|
|
159
253
|
const traceCompletenessProber_1 = require("./traceCompletenessProber");
|
|
160
|
-
const entityCapture_1 = require("../agent/core/entityCapture");
|
|
161
254
|
const outputLanguage_1 = require("./outputLanguage");
|
|
162
255
|
const runtimeSnapshotStore_1 = require("../services/runtimeSnapshotStore");
|
|
163
256
|
const enterpriseMigration_1 = require("../services/enterpriseMigration");
|
|
257
|
+
const runtimeCommon_1 = require("../agentRuntime/runtimeCommon");
|
|
164
258
|
const SESSION_MAP_FILE = (0, runtimePaths_1.backendLogPath)('claude_session_map.json');
|
|
165
259
|
/** Max age for session map entries before pruning (24 hours). */
|
|
166
260
|
const SESSION_MAP_MAX_AGE_MS = 24 * 60 * 60 * 1000;
|
|
167
|
-
/** Claude SDK sessions expire server-side after roughly 4 hours. */
|
|
168
|
-
const SDK_SESSION_FRESHNESS_MS = 4 * 60 * 60 * 1000;
|
|
169
261
|
function enterpriseSessionMapDbWritesEnabled() {
|
|
170
262
|
return (0, enterpriseMigration_1.enterpriseDbWritesEnabled)();
|
|
171
263
|
}
|
|
@@ -213,25 +305,6 @@ function loadSessionMapForCurrentMode() {
|
|
|
213
305
|
}
|
|
214
306
|
return new Map();
|
|
215
307
|
}
|
|
216
|
-
function providerScopeFromOptions(options) {
|
|
217
|
-
if (!options.tenantId || !options.workspaceId)
|
|
218
|
-
return undefined;
|
|
219
|
-
return {
|
|
220
|
-
tenantId: options.tenantId,
|
|
221
|
-
workspaceId: options.workspaceId,
|
|
222
|
-
userId: options.userId,
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
function knowledgeScopeFromOptions(options) {
|
|
226
|
-
if (!options.tenantId || !options.workspaceId)
|
|
227
|
-
return undefined;
|
|
228
|
-
return {
|
|
229
|
-
tenantId: options.tenantId,
|
|
230
|
-
workspaceId: options.workspaceId,
|
|
231
|
-
userId: options.userId,
|
|
232
|
-
sourceRunId: options.runId,
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
308
|
/**
|
|
236
309
|
* Debounce timer for session map persistence — avoids blocking event loop on every SDK message.
|
|
237
310
|
* P2-1: Use a Map keyed by the Map reference to support multiple ClaudeRuntime instances.
|
|
@@ -272,24 +345,6 @@ function savePersistedSessionMapSync(map) {
|
|
|
272
345
|
// The old logs/session_notes/ directory is no longer written to.
|
|
273
346
|
// P2-G1: ALLOWED_TOOLS is now auto-derived from createClaudeMcpServer() return value.
|
|
274
347
|
// No longer hardcoded — adding a new MCP tool automatically includes it.
|
|
275
|
-
/**
|
|
276
|
-
* Format pre-queried trace datasets as Markdown tables to prepend to the AI prompt.
|
|
277
|
-
* Mirrors smartperfetto's approach: data is ready upfront so the AI skips basic SQL turns.
|
|
278
|
-
*/
|
|
279
|
-
function formatTraceContext(datasets, outputLanguage = outputLanguage_1.DEFAULT_OUTPUT_LANGUAGE) {
|
|
280
|
-
if (!datasets || datasets.length === 0)
|
|
281
|
-
return '';
|
|
282
|
-
const parts = datasets.map((d) => {
|
|
283
|
-
const header = `| ${d.columns.join(' | ')} |`;
|
|
284
|
-
const sep = `| ${d.columns.map(() => '---').join(' | ')} |`;
|
|
285
|
-
const rows = d.rows.slice(0, 100).map((r) => `| ${r.map((v) => String(v ?? '—')).join(' | ')} |`);
|
|
286
|
-
const truncNote = d.rows.length > 100
|
|
287
|
-
? (0, outputLanguage_1.localize)(outputLanguage, `\n*(前 100 行,共 ${d.rows.length} 行)*`, `\n*(first 100 rows out of ${d.rows.length})*`)
|
|
288
|
-
: '';
|
|
289
|
-
return `### ${d.label}\n${header}\n${sep}\n${rows.join('\n')}${truncNote}`;
|
|
290
|
-
});
|
|
291
|
-
return (0, outputLanguage_1.localize)(outputLanguage, `## 前端预查询 Trace 数据\n\n以下数据已由前端查询完毕,直接使用,无需重复 SQL 查询:\n\n${parts.join('\n\n')}`, `## Frontend Pre-queried Trace Data\n\nThe frontend has already queried the following data. Use it directly; do not repeat the same SQL query.\n\n${parts.join('\n\n')}`);
|
|
292
|
-
}
|
|
293
348
|
/** Check if an error is retryable (API overload/server errors). */
|
|
294
349
|
function isRetryableError(err) {
|
|
295
350
|
const msg = err.message || '';
|
|
@@ -331,44 +386,18 @@ function isMissingSdkConversationError(message) {
|
|
|
331
386
|
function isFreshFullSdkSessionEntry(entry, now = Date.now()) {
|
|
332
387
|
return !!entry
|
|
333
388
|
&& entry.mode === 'full'
|
|
334
|
-
&&
|
|
335
|
-
}
|
|
336
|
-
function compactForPrompt(value, maxChars) {
|
|
337
|
-
const text = String(value ?? '').replace(/\s+/g, ' ').trim();
|
|
338
|
-
if (text.length <= maxChars)
|
|
339
|
-
return text;
|
|
340
|
-
return `${text.slice(0, Math.max(0, maxChars - 1))}...`;
|
|
341
|
-
}
|
|
342
|
-
function buildQuickConversationContext(previousTurns, outputLanguage = outputLanguage_1.DEFAULT_OUTPUT_LANGUAGE) {
|
|
343
|
-
const turns = previousTurns.filter(turn => turn.completed).slice(-3);
|
|
344
|
-
if (turns.length === 0)
|
|
345
|
-
return undefined;
|
|
346
|
-
const lines = [
|
|
347
|
-
(0, outputLanguage_1.localize)(outputLanguage, '## 最近对话上下文\n\n以下是 SmartPerfetto 本地保存的最近问答,用于理解“继续/刚才/这个”等指代;不要把它当作当前问题的新证据。', '## Recent Conversation Context\n\nThe following recent SmartPerfetto turns are local context for references like "continue", "earlier", or "this"; do not treat them as new evidence for the current question.'),
|
|
348
|
-
];
|
|
349
|
-
for (const turn of turns) {
|
|
350
|
-
const query = compactForPrompt(turn.query, 220);
|
|
351
|
-
const answer = compactForPrompt(turn.result?.message || '', 700);
|
|
352
|
-
const findings = turn.findings
|
|
353
|
-
.slice(0, 3)
|
|
354
|
-
.map(f => `[${f.severity}] ${compactForPrompt(f.title, 160)}`)
|
|
355
|
-
.filter(Boolean);
|
|
356
|
-
lines.push(`### Turn ${turn.turnIndex + 1}`);
|
|
357
|
-
lines.push(`- ${(0, outputLanguage_1.localize)(outputLanguage, '用户', 'User')}: ${query}`);
|
|
358
|
-
if (answer) {
|
|
359
|
-
lines.push(`- ${(0, outputLanguage_1.localize)(outputLanguage, '上轮回答', 'Previous answer')}: ${answer}`);
|
|
360
|
-
}
|
|
361
|
-
if (findings.length > 0) {
|
|
362
|
-
lines.push(`- ${(0, outputLanguage_1.localize)(outputLanguage, '上轮发现', 'Previous findings')}: ${findings.join('; ')}`);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
return lines.join('\n');
|
|
389
|
+
&& (0, runtimeCommon_1.isFreshRuntimeEntry)(entry, runtimeCommon_1.SDK_SESSION_FRESHNESS_MS, now);
|
|
366
390
|
}
|
|
367
391
|
exports.__testing = {
|
|
368
392
|
getSdkResultErrorMessage,
|
|
369
393
|
isMissingSdkConversationError,
|
|
370
394
|
isFreshFullSdkSessionEntry,
|
|
371
|
-
buildQuickConversationContext,
|
|
395
|
+
buildQuickConversationContext: runtimeCommon_1.buildQuickConversationContext,
|
|
396
|
+
correctionResultLooksUsable,
|
|
397
|
+
chooseClaudeConclusionText,
|
|
398
|
+
ensureClaudeFinalReportHeading,
|
|
399
|
+
sanitizeClaudeConclusionText,
|
|
400
|
+
shouldMarkCorrectionTimeoutPartial,
|
|
372
401
|
};
|
|
373
402
|
/** Sleep for the given milliseconds. */
|
|
374
403
|
function sleep(ms) {
|
|
@@ -491,7 +520,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
491
520
|
}
|
|
492
521
|
/** Restore a cached architecture detection result (e.g., from session persistence). */
|
|
493
522
|
restoreArchitectureCache(traceId, architecture) {
|
|
494
|
-
this.architectureCache
|
|
523
|
+
(0, runtimeCommon_1.setLruCacheEntry)(this.architectureCache, traceId, architecture);
|
|
495
524
|
}
|
|
496
525
|
/** Get cached architecture for a traceId (used for persistence). */
|
|
497
526
|
getCachedArchitecture(traceId) {
|
|
@@ -503,7 +532,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
503
532
|
return isFreshFullSdkSessionEntry(entry) ? entry.sdkSessionId : undefined;
|
|
504
533
|
}
|
|
505
534
|
buildSessionMapKey(sessionId, referenceTraceId) {
|
|
506
|
-
return
|
|
535
|
+
return (0, runtimeCommon_1.buildRuntimeSessionMapKey)(sessionId, referenceTraceId);
|
|
507
536
|
}
|
|
508
537
|
persistSessionMapEntry(sessionId, traceId, sessionMapKey, entry, options) {
|
|
509
538
|
if (legacySessionMapWritesEnabled()) {
|
|
@@ -541,7 +570,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
541
570
|
}
|
|
542
571
|
if (enterpriseSessionMapDbWritesEnabled()) {
|
|
543
572
|
try {
|
|
544
|
-
(0, runtimeSnapshotStore_1.deleteClaudeSessionMapRuntimeSnapshot)(sessionId, sessionMapKey,
|
|
573
|
+
(0, runtimeSnapshotStore_1.deleteClaudeSessionMapRuntimeSnapshot)(sessionId, sessionMapKey, (0, runtimeCommon_1.providerScopeFromAnalysisOptions)(options));
|
|
545
574
|
}
|
|
546
575
|
catch (err) {
|
|
547
576
|
console.warn('[ClaudeRuntime] Failed to delete stale SDK session map from runtime_snapshots:', err.message);
|
|
@@ -607,7 +636,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
607
636
|
// Distinguish: only full analysis turns trigger multi-turn continuity (not prior quick turns)
|
|
608
637
|
hasPriorFullAnalysis: previousTurns.some(t => t.intent?.complexity !== 'simple'),
|
|
609
638
|
};
|
|
610
|
-
const cachedArch = this.architectureCache
|
|
639
|
+
const cachedArch = (0, runtimeCommon_1.getLruCacheEntry)(this.architectureCache, traceId);
|
|
611
640
|
// Focus detection runs for every path — kick it off once and let the classifier
|
|
612
641
|
// (if needed) share the wait. Explicit 'fast'/'full' skips the classifier entirely.
|
|
613
642
|
const explicitMode = options.analysisMode;
|
|
@@ -615,7 +644,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
615
644
|
console.warn('[ClaudeRuntime] Focus app detection failed (graceful):', err.message);
|
|
616
645
|
return { apps: [], primaryApp: undefined, method: 'none' };
|
|
617
646
|
});
|
|
618
|
-
const providerScope =
|
|
647
|
+
const providerScope = (0, runtimeCommon_1.providerScopeFromAnalysisOptions)(options);
|
|
619
648
|
const runtimeConfig = (0, claudeConfig_1.resolveRuntimeConfig)(this.config, options.providerId, providerScope);
|
|
620
649
|
let queryComplexity;
|
|
621
650
|
let classifierSource;
|
|
@@ -654,6 +683,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
654
683
|
sessionContext,
|
|
655
684
|
previousTurns,
|
|
656
685
|
sceneType,
|
|
686
|
+
runtimeConfig,
|
|
657
687
|
});
|
|
658
688
|
const { handleMessage: bridge, getAccumulatedAnswer } = (0, claudeSseBridge_1.createSseBridge)((update) => {
|
|
659
689
|
this.emitUpdate(update);
|
|
@@ -702,7 +732,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
702
732
|
}
|
|
703
733
|
// Prepend pre-queried trace data so the AI has all context without spending turns on SQL
|
|
704
734
|
if (options.traceContext && options.traceContext.length > 0) {
|
|
705
|
-
const traceSection = formatTraceContext(options.traceContext, this.config.outputLanguage);
|
|
735
|
+
const traceSection = (0, runtimeCommon_1.formatTraceContext)(options.traceContext, this.config.outputLanguage);
|
|
706
736
|
effectivePrompt = `${traceSection}\n\n${effectivePrompt}`;
|
|
707
737
|
}
|
|
708
738
|
const sdkEnv = (0, claudeConfig_1.createSdkEnv)(options.providerId, providerScope);
|
|
@@ -1091,8 +1121,8 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1091
1121
|
terminationMessage = (0, analysisTermination_1.buildMaxTurnsTerminationMessage)({
|
|
1092
1122
|
mode: 'full',
|
|
1093
1123
|
turns: rounds,
|
|
1094
|
-
maxTurns:
|
|
1095
|
-
outputLanguage:
|
|
1124
|
+
maxTurns: runtimeConfig.maxTurns,
|
|
1125
|
+
outputLanguage: runtimeConfig.outputLanguage,
|
|
1096
1126
|
});
|
|
1097
1127
|
}
|
|
1098
1128
|
// Record SDK token usage and prompt cache metrics
|
|
@@ -1181,13 +1211,24 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1181
1211
|
mode: 'full',
|
|
1182
1212
|
});
|
|
1183
1213
|
}
|
|
1184
|
-
//
|
|
1185
|
-
//
|
|
1186
|
-
//
|
|
1187
|
-
|
|
1214
|
+
// Prefer a deliverable streamed report over a short SDK terminal summary.
|
|
1215
|
+
// Some compatible providers put the full report in answer_token chunks but
|
|
1216
|
+
// return only a terse summary in the terminal result.
|
|
1217
|
+
const accumulatedAnswerBeforeVerification = getAccumulatedAnswer();
|
|
1218
|
+
conclusionText = chooseClaudeConclusionText({
|
|
1219
|
+
finalResult: finalResult || '',
|
|
1220
|
+
accumulatedAnswer: accumulatedAnswerBeforeVerification,
|
|
1221
|
+
});
|
|
1222
|
+
conclusionText = ensureClaudeFinalReportHeading(conclusionText, ctx.sceneType, runtimeConfig.outputLanguage);
|
|
1188
1223
|
if (!finalResult && conclusionText) {
|
|
1189
1224
|
console.warn(`[ClaudeRuntime] Session ${sessionId}: SDK result was empty, recovered ${conclusionText.length} chars from streamed answer tokens`);
|
|
1190
1225
|
}
|
|
1226
|
+
else if (finalResult &&
|
|
1227
|
+
conclusionText === sanitizeClaudeConclusionText(accumulatedAnswerBeforeVerification) &&
|
|
1228
|
+
conclusionText !== sanitizeClaudeConclusionText(finalResult)) {
|
|
1229
|
+
console.warn(`[ClaudeRuntime] Session ${sessionId}: SDK result was a short terminal summary ` +
|
|
1230
|
+
`(${finalResult.length} chars), using streamed report (${conclusionText.length} chars) before verification`);
|
|
1231
|
+
}
|
|
1191
1232
|
allFindings.push((0, claudeFindingExtractor_1.extractFindingsFromText)(conclusionText));
|
|
1192
1233
|
let mergedFindings = (0, claudeFindingExtractor_1.mergeFindings)(allFindings);
|
|
1193
1234
|
if (conclusionText.trim() && ctx.analysisPlan.current) {
|
|
@@ -1284,12 +1325,12 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1284
1325
|
type: 'progress',
|
|
1285
1326
|
content: {
|
|
1286
1327
|
phase: 'concluding',
|
|
1287
|
-
message: (0, outputLanguage_1.localize)(this.config.outputLanguage,
|
|
1328
|
+
message: (0, outputLanguage_1.localize)(this.config.outputLanguage, `最终报告仍需补齐,正在自动修正 (${attempt + 1}/${MAX_CORRECTION_ATTEMPTS})...`, `The final report still needs completion; applying automatic correction (${attempt + 1}/${MAX_CORRECTION_ATTEMPTS})...`),
|
|
1288
1329
|
},
|
|
1289
1330
|
timestamp: Date.now(),
|
|
1290
1331
|
});
|
|
1291
1332
|
try {
|
|
1292
|
-
const correctionPrompt = (0, claudeVerifier_1.generateCorrectionPrompt)(allIssues, conclusionText, this.config.outputLanguage);
|
|
1333
|
+
const correctionPrompt = (0, claudeVerifier_1.generateCorrectionPrompt)(allIssues, conclusionText, this.config.outputLanguage, ctx.sceneType);
|
|
1293
1334
|
// When the conclusion is incomplete (just reasoning notes, no structured report),
|
|
1294
1335
|
// the agent ran out of turns before generating a report. Give substantially more
|
|
1295
1336
|
// budget so the correction can produce a complete structured output.
|
|
@@ -1378,11 +1419,15 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1378
1419
|
if (!correctedResult && !correctionTimedOut) {
|
|
1379
1420
|
correctedResult = correctionAnswerBridge.getAccumulatedAnswer();
|
|
1380
1421
|
}
|
|
1422
|
+
correctedResult = ensureClaudeFinalReportHeading(correctedResult, ctx.sceneType, runtimeConfig.outputLanguage);
|
|
1381
1423
|
if (correctionTimedOut) {
|
|
1382
1424
|
console.warn(`[ClaudeRuntime] Correction attempt ${attempt + 1} timed out, using partial result (${correctedResult.length} chars)`);
|
|
1383
|
-
if (
|
|
1425
|
+
if (shouldMarkCorrectionTimeoutPartial({ correctedResult, existingConclusion: conclusionText })) {
|
|
1426
|
+
correctedResult = '';
|
|
1427
|
+
verificationDegradedMessage = (0, outputLanguage_1.localize)(this.config.outputLanguage, '修正重试超时,且当前结论仍不可独立交付;已保留原结论并标记为 partial。', 'Correction retry timed out and the current conclusion is still not independently deliverable; keeping the previous conclusion and marking the result partial.');
|
|
1428
|
+
}
|
|
1429
|
+
else if (!correctionResultLooksUsable(correctedResult)) {
|
|
1384
1430
|
correctedResult = '';
|
|
1385
|
-
verificationDegradedMessage = (0, outputLanguage_1.localize)(this.config.outputLanguage, 'Claude 修正重试超时,且没有产出可独立交付的修正报告;已保留原结论并标记为 partial。', 'Claude correction retry timed out without a deliverable corrected report; keeping the previous conclusion and marking the result partial.');
|
|
1386
1431
|
}
|
|
1387
1432
|
}
|
|
1388
1433
|
// P2-G13: Compare correction quality by finding count and coverage, not text length.
|
|
@@ -1424,27 +1469,28 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1424
1469
|
allFindings.push((0, claudeFindingExtractor_1.extractFindingsFromText)(conclusionText));
|
|
1425
1470
|
mergedFindings = (0, claudeFindingExtractor_1.mergeFindings)(allFindings);
|
|
1426
1471
|
}
|
|
1472
|
+
conclusionText = ensureClaudeFinalReportHeading(conclusionText, ctx.sceneType, runtimeConfig.outputLanguage);
|
|
1427
1473
|
const isPartialResult = terminationReason === analysisTermination_1.MAX_TURNS_TERMINATION_REASON;
|
|
1428
1474
|
if (isPartialResult) {
|
|
1429
1475
|
terminationMessage || (terminationMessage = (0, analysisTermination_1.buildMaxTurnsTerminationMessage)({
|
|
1430
1476
|
mode: 'full',
|
|
1431
1477
|
turns: rounds,
|
|
1432
|
-
maxTurns:
|
|
1433
|
-
outputLanguage:
|
|
1478
|
+
maxTurns: runtimeConfig.maxTurns,
|
|
1479
|
+
outputLanguage: runtimeConfig.outputLanguage,
|
|
1434
1480
|
}));
|
|
1435
1481
|
conclusionText = conclusionText.trim()
|
|
1436
|
-
? (0, analysisTermination_1.prependPartialNotice)(conclusionText, terminationMessage,
|
|
1482
|
+
? (0, analysisTermination_1.prependPartialNotice)(conclusionText, terminationMessage, runtimeConfig.outputLanguage)
|
|
1437
1483
|
: (0, analysisTermination_1.buildMaxTurnsFallbackConclusion)({
|
|
1438
1484
|
mode: 'full',
|
|
1439
1485
|
turns: rounds,
|
|
1440
|
-
maxTurns:
|
|
1441
|
-
outputLanguage:
|
|
1486
|
+
maxTurns: runtimeConfig.maxTurns,
|
|
1487
|
+
outputLanguage: runtimeConfig.outputLanguage,
|
|
1442
1488
|
});
|
|
1443
1489
|
allFindings.push((0, claudeFindingExtractor_1.extractFindingsFromText)(conclusionText));
|
|
1444
1490
|
mergedFindings = (0, claudeFindingExtractor_1.mergeFindings)(allFindings);
|
|
1445
1491
|
failedApproaches.push({
|
|
1446
1492
|
type: 'strategy_failure',
|
|
1447
|
-
approach: `analysis reached ${
|
|
1493
|
+
approach: `analysis reached ${runtimeConfig.maxTurns} full-mode turns`,
|
|
1448
1494
|
reason: 'SDK returned error_max_turns before a normal success result',
|
|
1449
1495
|
});
|
|
1450
1496
|
this.emitUpdate({
|
|
@@ -1457,7 +1503,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1457
1503
|
partial: true,
|
|
1458
1504
|
terminationReason,
|
|
1459
1505
|
turns: rounds,
|
|
1460
|
-
maxTurns:
|
|
1506
|
+
maxTurns: runtimeConfig.maxTurns,
|
|
1461
1507
|
},
|
|
1462
1508
|
timestamp: Date.now(),
|
|
1463
1509
|
});
|
|
@@ -1469,12 +1515,12 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1469
1515
|
? `${terminationMessage}\n\n${verificationDegradedMessage}`
|
|
1470
1516
|
: verificationDegradedMessage;
|
|
1471
1517
|
conclusionText = conclusionText.trim()
|
|
1472
|
-
? (0, analysisTermination_1.prependPartialNotice)(conclusionText, verificationDegradedMessage,
|
|
1518
|
+
? (0, analysisTermination_1.prependPartialNotice)(conclusionText, verificationDegradedMessage, runtimeConfig.outputLanguage)
|
|
1473
1519
|
: (0, analysisTermination_1.buildMaxTurnsFallbackConclusion)({
|
|
1474
1520
|
mode: 'full',
|
|
1475
1521
|
turns: rounds,
|
|
1476
|
-
maxTurns:
|
|
1477
|
-
outputLanguage:
|
|
1522
|
+
maxTurns: runtimeConfig.maxTurns,
|
|
1523
|
+
outputLanguage: runtimeConfig.outputLanguage,
|
|
1478
1524
|
});
|
|
1479
1525
|
mergedFindings = (0, claudeFindingExtractor_1.mergeFindings)([(0, claudeFindingExtractor_1.extractFindingsFromText)(conclusionText)]);
|
|
1480
1526
|
this.emitUpdate({
|
|
@@ -1509,7 +1555,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1509
1555
|
terminationReason,
|
|
1510
1556
|
terminationMessage,
|
|
1511
1557
|
};
|
|
1512
|
-
const gateIssue = (0, finalResultQualityGate_1.applyFinalResultQualityGate)({ result: finalAnalysisResult, query });
|
|
1558
|
+
const gateIssue = (0, finalResultQualityGate_1.applyFinalResultQualityGate)({ result: finalAnalysisResult, query, sceneType });
|
|
1513
1559
|
if (gateIssue) {
|
|
1514
1560
|
this.emitUpdate({
|
|
1515
1561
|
type: 'degraded',
|
|
@@ -1566,7 +1612,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1566
1612
|
sessionId,
|
|
1567
1613
|
turnIndex: ctx.previousTurns.length,
|
|
1568
1614
|
},
|
|
1569
|
-
knowledgeScope:
|
|
1615
|
+
knowledgeScope: (0, runtimeCommon_1.knowledgeScopeFromAnalysisOptions)(options),
|
|
1570
1616
|
};
|
|
1571
1617
|
(0, analysisPatternMemory_1.saveAnalysisPattern)(fullFeatures, insights, sceneType, ctx.architecture?.type, finalAnalysisResult.confidence, patternExtras)
|
|
1572
1618
|
.catch(err => console.warn('[ClaudeRuntime] Pattern save failed:', err.message));
|
|
@@ -1578,7 +1624,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1578
1624
|
sceneType,
|
|
1579
1625
|
architectureType: ctx.architecture?.type,
|
|
1580
1626
|
verifierPassed: true,
|
|
1581
|
-
knowledgeScope:
|
|
1627
|
+
knowledgeScope: (0, runtimeCommon_1.knowledgeScopeFromAnalysisOptions)(options),
|
|
1582
1628
|
}).catch(err => console.warn('[ClaudeRuntime] Quick→full promote failed:', err.message));
|
|
1583
1629
|
}
|
|
1584
1630
|
// Derive sql_error FailedApproach entries from persistent SQL errors
|
|
@@ -1594,7 +1640,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1594
1640
|
// P1: Save negative patterns to long-term memory (fire-and-forget)
|
|
1595
1641
|
if (failedApproaches.length > 0 && fullFeatures.length > 0) {
|
|
1596
1642
|
(0, analysisPatternMemory_1.saveNegativePattern)(fullFeatures, failedApproaches, sceneType, ctx.architecture?.type, {
|
|
1597
|
-
knowledgeScope:
|
|
1643
|
+
knowledgeScope: (0, runtimeCommon_1.knowledgeScopeFromAnalysisOptions)(options),
|
|
1598
1644
|
})
|
|
1599
1645
|
.catch(err => console.warn('[ClaudeRuntime] Negative pattern save failed:', err.message));
|
|
1600
1646
|
}
|
|
@@ -1602,7 +1648,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1602
1648
|
}
|
|
1603
1649
|
catch (error) {
|
|
1604
1650
|
const rawErrorMessage = error.message || 'Unknown error';
|
|
1605
|
-
const errMsg = (0, claudeConfig_1.explainClaudeRuntimeError)(rawErrorMessage, this.config.outputLanguage, (0, claudeConfig_1.getCredentialSourceHint)(options.providerId,
|
|
1651
|
+
const errMsg = (0, claudeConfig_1.explainClaudeRuntimeError)(rawErrorMessage, this.config.outputLanguage, (0, claudeConfig_1.getCredentialSourceHint)(options.providerId, (0, runtimeCommon_1.providerScopeFromAnalysisOptions)(options)));
|
|
1606
1652
|
const quotaExceeded = (0, claudeConfig_1.isClaudeQuotaError)(rawErrorMessage);
|
|
1607
1653
|
console.error('[ClaudeRuntime] Analysis failed:', errMsg);
|
|
1608
1654
|
// P1-3: Preserve partial findings and generate partial conclusion on mid-stream errors
|
|
@@ -1696,13 +1742,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1696
1742
|
packageName: effectivePackageName,
|
|
1697
1743
|
});
|
|
1698
1744
|
if (arch) {
|
|
1699
|
-
this.architectureCache
|
|
1700
|
-
// LRU eviction: match full path's 50-entry cap
|
|
1701
|
-
if (this.architectureCache.size > 50) {
|
|
1702
|
-
const firstKey = this.architectureCache.keys().next().value;
|
|
1703
|
-
if (firstKey)
|
|
1704
|
-
this.architectureCache.delete(firstKey);
|
|
1705
|
-
}
|
|
1745
|
+
(0, runtimeCommon_1.setLruCacheEntry)(this.architectureCache, traceId, arch);
|
|
1706
1746
|
}
|
|
1707
1747
|
return arch;
|
|
1708
1748
|
}
|
|
@@ -1719,12 +1759,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1719
1759
|
const watchdogWarning = { current: null };
|
|
1720
1760
|
// Quick path defaults to no skill-notes injection per §8 of the
|
|
1721
1761
|
// self-improving design. Operators can opt-in via the env override.
|
|
1722
|
-
const quickNotesBudget =
|
|
1723
|
-
? new skillNotesInjector_1.SkillNotesBudget({
|
|
1724
|
-
mode: 'quick',
|
|
1725
|
-
quickOverrideTotal: parseQuickBudgetEnv(),
|
|
1726
|
-
})
|
|
1727
|
-
: undefined;
|
|
1762
|
+
const quickNotesBudget = (0, runtimeCommon_1.createRuntimeSkillNotesBudget)(true);
|
|
1728
1763
|
const { server: mcpServer, allowedTools } = (0, claudeMcpServer_1.createClaudeMcpServer)({
|
|
1729
1764
|
sessionId,
|
|
1730
1765
|
traceId,
|
|
@@ -1737,7 +1772,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1737
1772
|
lightweight: true,
|
|
1738
1773
|
skillNotesBudget: quickNotesBudget,
|
|
1739
1774
|
outputLanguage: this.config.outputLanguage,
|
|
1740
|
-
knowledgeScope:
|
|
1775
|
+
knowledgeScope: (0, runtimeCommon_1.knowledgeScopeFromAnalysisOptions)(options),
|
|
1741
1776
|
codeAwareMode: options.codeAwareMode,
|
|
1742
1777
|
codebaseIds: options.codebaseIds,
|
|
1743
1778
|
});
|
|
@@ -1749,8 +1784,9 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1749
1784
|
selectionContext: options.selectionContext,
|
|
1750
1785
|
outputLanguage: this.config.outputLanguage,
|
|
1751
1786
|
});
|
|
1752
|
-
const providerScope =
|
|
1753
|
-
const
|
|
1787
|
+
const providerScope = (0, runtimeCommon_1.providerScopeFromAnalysisOptions)(options);
|
|
1788
|
+
const sdkEnv = (0, claudeConfig_1.createSdkEnv)(options.providerId, providerScope);
|
|
1789
|
+
const quickConfig = (0, claudeConfig_1.createQuickConfig)((0, claudeConfig_1.resolveRuntimeConfig)(this.config, options.providerId, providerScope), sdkEnv);
|
|
1754
1790
|
const { handleMessage: bridge, getAccumulatedAnswer } = (0, claudeSseBridge_1.createSseBridge)((update) => {
|
|
1755
1791
|
this.emitUpdate(update);
|
|
1756
1792
|
}, this.config.outputLanguage);
|
|
@@ -1762,20 +1798,19 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1762
1798
|
},
|
|
1763
1799
|
timestamp: Date.now(),
|
|
1764
1800
|
});
|
|
1765
|
-
const sdkEnv = (0, claudeConfig_1.createSdkEnv)(options.providerId, providerScope);
|
|
1766
1801
|
// Quick calls intentionally do not resume or persist Claude SDK sessions.
|
|
1767
1802
|
// The SDK's maxTurns budget is tied to the resumed conversation, while
|
|
1768
1803
|
// SmartPerfetto's fast mode budget is a per-question latency guard. Keep
|
|
1769
1804
|
// cross-turn context local and compact so quick cannot exhaust or overwrite
|
|
1770
1805
|
// the full-mode SDK conversation.
|
|
1771
1806
|
let quickPrompt = query;
|
|
1772
|
-
const quickConversationContext = buildQuickConversationContext(previousTurns, this.config.outputLanguage);
|
|
1807
|
+
const quickConversationContext = (0, runtimeCommon_1.buildQuickConversationContext)(previousTurns, this.config.outputLanguage);
|
|
1773
1808
|
if (quickConversationContext) {
|
|
1774
1809
|
quickPrompt = `${quickConversationContext}\n\n${quickPrompt}`;
|
|
1775
1810
|
}
|
|
1776
1811
|
// Prepend pre-queried trace data so the AI skips basic SQL turns in fast mode.
|
|
1777
1812
|
if (options.traceContext && options.traceContext.length > 0) {
|
|
1778
|
-
quickPrompt = `${formatTraceContext(options.traceContext, this.config.outputLanguage)}\n\n${quickPrompt}`;
|
|
1813
|
+
quickPrompt = `${(0, runtimeCommon_1.formatTraceContext)(options.traceContext, this.config.outputLanguage)}\n\n${quickPrompt}`;
|
|
1779
1814
|
}
|
|
1780
1815
|
const { stream, close: closeSdk } = sdkQueryWithRetry({
|
|
1781
1816
|
prompt: quickPrompt,
|
|
@@ -1916,7 +1951,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1916
1951
|
terminationReason,
|
|
1917
1952
|
terminationMessage,
|
|
1918
1953
|
};
|
|
1919
|
-
const quickGateIssue = (0, finalResultQualityGate_1.applyFinalResultQualityGate)({ result: quickResult, query });
|
|
1954
|
+
const quickGateIssue = (0, finalResultQualityGate_1.applyFinalResultQualityGate)({ result: quickResult, query, sceneType });
|
|
1920
1955
|
if (quickGateIssue) {
|
|
1921
1956
|
this.emitUpdate({
|
|
1922
1957
|
type: 'degraded',
|
|
@@ -1966,14 +2001,14 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
1966
2001
|
(0, analysisPatternMemory_1.saveQuickPathPattern)(quickFeatures, insights, sceneType, cachedArch?.type, {
|
|
1967
2002
|
status: 'provisional',
|
|
1968
2003
|
provenance: { sessionId, turnIndex: previousTurns.length },
|
|
1969
|
-
knowledgeScope:
|
|
2004
|
+
knowledgeScope: (0, runtimeCommon_1.knowledgeScopeFromAnalysisOptions)(options),
|
|
1970
2005
|
}).catch(err => console.warn('[ClaudeRuntime] Quick pattern save failed:', err.message));
|
|
1971
2006
|
}
|
|
1972
2007
|
return quickResult;
|
|
1973
2008
|
}
|
|
1974
2009
|
catch (error) {
|
|
1975
2010
|
const rawErrorMessage = error.message || 'Unknown error';
|
|
1976
|
-
const errMsg = (0, claudeConfig_1.explainClaudeRuntimeError)(rawErrorMessage, this.config.outputLanguage, (0, claudeConfig_1.getCredentialSourceHint)(options.providerId,
|
|
2011
|
+
const errMsg = (0, claudeConfig_1.explainClaudeRuntimeError)(rawErrorMessage, this.config.outputLanguage, (0, claudeConfig_1.getCredentialSourceHint)(options.providerId, (0, runtimeCommon_1.providerScopeFromAnalysisOptions)(options)));
|
|
1977
2012
|
const quotaExceeded = (0, claudeConfig_1.isClaudeQuotaError)(rawErrorMessage);
|
|
1978
2013
|
console.error('[ClaudeRuntime] Quick analysis failed:', errMsg);
|
|
1979
2014
|
this.emitUpdate({
|
|
@@ -2135,7 +2170,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2135
2170
|
this.artifactStores.set(sessionId, artifactStore_1.ArtifactStore.fromSnapshot(snapshot.artifacts));
|
|
2136
2171
|
}
|
|
2137
2172
|
if (snapshot.architecture) {
|
|
2138
|
-
this.architectureCache
|
|
2173
|
+
(0, runtimeCommon_1.setLruCacheEntry)(this.architectureCache, traceId, snapshot.architecture);
|
|
2139
2174
|
}
|
|
2140
2175
|
if (snapshot.sdkSessionId && snapshot.sdkSessionMode === 'full') {
|
|
2141
2176
|
this.sessionMap.set(this.buildSessionMapKey(sessionId, snapshot.referenceTraceId), {
|
|
@@ -2147,24 +2182,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2147
2182
|
}
|
|
2148
2183
|
/** P0-1: Convert agentv3 Hypothesis to agentProtocol Hypothesis format for AnalysisResult. */
|
|
2149
2184
|
toProtocolHypothesis(h) {
|
|
2150
|
-
|
|
2151
|
-
formed: 'proposed',
|
|
2152
|
-
confirmed: 'confirmed',
|
|
2153
|
-
rejected: 'rejected',
|
|
2154
|
-
};
|
|
2155
|
-
const confidenceMap = { formed: 0.5, confirmed: 0.85, rejected: 0.1 };
|
|
2156
|
-
return {
|
|
2157
|
-
id: h.id,
|
|
2158
|
-
description: h.statement,
|
|
2159
|
-
status: statusMap[h.status] || 'proposed',
|
|
2160
|
-
confidence: confidenceMap[h.status] ?? 0.5,
|
|
2161
|
-
supportingEvidence: h.evidence && h.status === 'confirmed' ? [{ id: `${h.id}-ev`, type: 'observation', description: h.evidence, source: 'claude', strength: 0.8 }] : [],
|
|
2162
|
-
contradictingEvidence: h.evidence && h.status === 'rejected' ? [{ id: `${h.id}-ev`, type: 'observation', description: h.evidence, source: 'claude', strength: 0.8 }] : [],
|
|
2163
|
-
proposedBy: 'claude',
|
|
2164
|
-
relevantAgents: ['claude'],
|
|
2165
|
-
createdAt: h.formedAt,
|
|
2166
|
-
updatedAt: h.resolvedAt || h.formedAt,
|
|
2167
|
-
};
|
|
2185
|
+
return (0, runtimeCommon_1.toProtocolHypothesis)(h, 'claude');
|
|
2168
2186
|
}
|
|
2169
2187
|
reset() {
|
|
2170
2188
|
this.architectureCache.clear();
|
|
@@ -2187,64 +2205,14 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2187
2205
|
* Caps at 5 findings to prevent unbounded prompt growth.
|
|
2188
2206
|
*/
|
|
2189
2207
|
collectPreviousFindings(sessionContext, maxTurns) {
|
|
2190
|
-
|
|
2191
|
-
let turns = sessionContext.getAllTurns?.() || [];
|
|
2192
|
-
if (maxTurns && maxTurns > 0) {
|
|
2193
|
-
turns = turns.slice(-maxTurns);
|
|
2194
|
-
}
|
|
2195
|
-
return turns.flatMap((turn) => turn.findings || []).slice(-5);
|
|
2196
|
-
}
|
|
2197
|
-
catch {
|
|
2198
|
-
return [];
|
|
2199
|
-
}
|
|
2208
|
+
return (0, runtimeCommon_1.collectRecentFindings)(sessionContext, { maxTurns, maxFindings: 5 });
|
|
2200
2209
|
}
|
|
2201
2210
|
/**
|
|
2202
2211
|
* Build a compact entity context string for the system prompt.
|
|
2203
2212
|
* Gives Claude awareness of known frames/sessions for drill-down resolution.
|
|
2204
2213
|
*/
|
|
2205
2214
|
buildEntityContext(entityStore) {
|
|
2206
|
-
|
|
2207
|
-
const stats = entityStore.getStats();
|
|
2208
|
-
if (stats.totalEntityCount === 0)
|
|
2209
|
-
return undefined;
|
|
2210
|
-
const lines = [];
|
|
2211
|
-
const frames = entityStore.getAllFrames?.() || [];
|
|
2212
|
-
if (frames.length > 0) {
|
|
2213
|
-
lines.push(`**帧 (${frames.length})**:`);
|
|
2214
|
-
for (const f of frames.slice(0, 15)) {
|
|
2215
|
-
const parts = [`frame_id=${f.frame_id}`];
|
|
2216
|
-
if (f.start_ts)
|
|
2217
|
-
parts.push(`ts=${f.start_ts}`);
|
|
2218
|
-
if (f.jank_type)
|
|
2219
|
-
parts.push(`jank=${f.jank_type}`);
|
|
2220
|
-
if (f.dur_ms)
|
|
2221
|
-
parts.push(`dur=${f.dur_ms}ms`);
|
|
2222
|
-
if (f.process_name)
|
|
2223
|
-
parts.push(`proc=${f.process_name}`);
|
|
2224
|
-
lines.push(`- ${parts.join(', ')}`);
|
|
2225
|
-
}
|
|
2226
|
-
if (frames.length > 15)
|
|
2227
|
-
lines.push(`- ...及其他 ${frames.length - 15} 帧`);
|
|
2228
|
-
}
|
|
2229
|
-
const sessions = entityStore.getAllSessions?.() || [];
|
|
2230
|
-
if (sessions.length > 0) {
|
|
2231
|
-
lines.push(`**滑动会话 (${sessions.length})**:`);
|
|
2232
|
-
for (const s of sessions.slice(0, 8)) {
|
|
2233
|
-
const parts = [`session_id=${s.session_id}`];
|
|
2234
|
-
if (s.start_ts)
|
|
2235
|
-
parts.push(`ts=${s.start_ts}`);
|
|
2236
|
-
if (s.jank_count)
|
|
2237
|
-
parts.push(`janks=${s.jank_count}`);
|
|
2238
|
-
if (s.process_name)
|
|
2239
|
-
parts.push(`proc=${s.process_name}`);
|
|
2240
|
-
lines.push(`- ${parts.join(', ')}`);
|
|
2241
|
-
}
|
|
2242
|
-
}
|
|
2243
|
-
return lines.length > 0 ? lines.join('\n') : undefined;
|
|
2244
|
-
}
|
|
2245
|
-
catch {
|
|
2246
|
-
return undefined;
|
|
2247
|
-
}
|
|
2215
|
+
return (0, runtimeCommon_1.buildEntityContext)(entityStore);
|
|
2248
2216
|
}
|
|
2249
2217
|
/**
|
|
2250
2218
|
* Prepare all context needed for a Claude analysis run.
|
|
@@ -2253,6 +2221,9 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2253
2221
|
* into a single cohesive preparation phase.
|
|
2254
2222
|
*/
|
|
2255
2223
|
async prepareAnalysisContext(query, sessionId, traceId, options, precomputed) {
|
|
2224
|
+
const providerScope = (0, runtimeCommon_1.providerScopeFromAnalysisOptions)(options);
|
|
2225
|
+
const runtimeConfig = precomputed?.runtimeConfig
|
|
2226
|
+
?? (0, claudeConfig_1.resolveRuntimeConfig)(this.config, options.providerId, providerScope);
|
|
2256
2227
|
// Phase 0: Selection context logging
|
|
2257
2228
|
if (options.selectionContext) {
|
|
2258
2229
|
const sc = options.selectionContext;
|
|
@@ -2276,7 +2247,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2276
2247
|
type: 'progress',
|
|
2277
2248
|
content: {
|
|
2278
2249
|
phase: 'starting',
|
|
2279
|
-
message: (0, outputLanguage_1.localize)(
|
|
2250
|
+
message: (0, outputLanguage_1.localize)(runtimeConfig.outputLanguage, `检测到焦点应用: ${focusResult.primaryApp} (${focusResult.method})`, `Detected focus app: ${focusResult.primaryApp} (${focusResult.method})`),
|
|
2280
2251
|
},
|
|
2281
2252
|
timestamp: Date.now(),
|
|
2282
2253
|
});
|
|
@@ -2287,13 +2258,8 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2287
2258
|
skillExecutor.registerSkills(skillLoader_1.skillRegistry.getAllSkills());
|
|
2288
2259
|
skillExecutor.setFragmentRegistry(skillLoader_1.skillRegistry.getFragmentCache());
|
|
2289
2260
|
// Phase 2: Architecture detection (LRU cached per traceId)
|
|
2290
|
-
let architecture = this.architectureCache
|
|
2291
|
-
if (architecture) {
|
|
2292
|
-
// LRU touch: delete and re-insert to move to end of Map iteration order
|
|
2293
|
-
this.architectureCache.delete(traceId);
|
|
2294
|
-
this.architectureCache.set(traceId, architecture);
|
|
2295
|
-
}
|
|
2296
|
-
else {
|
|
2261
|
+
let architecture = (0, runtimeCommon_1.getLruCacheEntry)(this.architectureCache, traceId);
|
|
2262
|
+
if (!architecture) {
|
|
2297
2263
|
try {
|
|
2298
2264
|
const detector = (0, architectureDetector_1.createArchitectureDetector)();
|
|
2299
2265
|
architecture = await detector.detect({
|
|
@@ -2302,13 +2268,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2302
2268
|
packageName: effectivePackageName,
|
|
2303
2269
|
});
|
|
2304
2270
|
if (architecture) {
|
|
2305
|
-
this.architectureCache
|
|
2306
|
-
// LRU eviction: remove oldest entry (first key in Map)
|
|
2307
|
-
if (this.architectureCache.size > 50) {
|
|
2308
|
-
const firstKey = this.architectureCache.keys().next().value;
|
|
2309
|
-
if (firstKey)
|
|
2310
|
-
this.architectureCache.delete(firstKey);
|
|
2311
|
-
}
|
|
2271
|
+
(0, runtimeCommon_1.setLruCacheEntry)(this.architectureCache, traceId, architecture);
|
|
2312
2272
|
}
|
|
2313
2273
|
this.emitUpdate({ type: 'architecture_detected', content: { architecture }, timestamp: Date.now() });
|
|
2314
2274
|
}
|
|
@@ -2317,7 +2277,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2317
2277
|
}
|
|
2318
2278
|
}
|
|
2319
2279
|
// Phase 2.5: Vendor detection (LRU cached per traceId, reuses SkillAnalysisAdapter.detectVendor)
|
|
2320
|
-
let detectedVendor = this.vendorCache
|
|
2280
|
+
let detectedVendor = (0, runtimeCommon_1.getLruCacheEntry)(this.vendorCache, traceId) ?? null;
|
|
2321
2281
|
if (!detectedVendor) {
|
|
2322
2282
|
try {
|
|
2323
2283
|
const adapter = (0, skillAnalysisAdapter_1.getSkillAnalysisAdapter)(this.traceProcessorService);
|
|
@@ -2325,13 +2285,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2325
2285
|
const vendorResult = await adapter.detectVendor(traceId);
|
|
2326
2286
|
detectedVendor = vendorResult.vendor;
|
|
2327
2287
|
if (detectedVendor && detectedVendor !== 'aosp') {
|
|
2328
|
-
this.vendorCache
|
|
2329
|
-
// LRU eviction: match architectureCache limit
|
|
2330
|
-
if (this.vendorCache.size > 50) {
|
|
2331
|
-
const firstKey = this.vendorCache.keys().next().value;
|
|
2332
|
-
if (firstKey)
|
|
2333
|
-
this.vendorCache.delete(firstKey);
|
|
2334
|
-
}
|
|
2288
|
+
(0, runtimeCommon_1.setLruCacheEntry)(this.vendorCache, traceId, detectedVendor);
|
|
2335
2289
|
}
|
|
2336
2290
|
}
|
|
2337
2291
|
catch (err) {
|
|
@@ -2347,7 +2301,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2347
2301
|
type: 'progress',
|
|
2348
2302
|
content: {
|
|
2349
2303
|
phase: 'starting',
|
|
2350
|
-
message: (0, outputLanguage_1.localize)(
|
|
2304
|
+
message: (0, outputLanguage_1.localize)(runtimeConfig.outputLanguage, '对比模式:正在检测参考 Trace...', 'Comparison mode: detecting the reference trace...'),
|
|
2351
2305
|
},
|
|
2352
2306
|
timestamp: Date.now(),
|
|
2353
2307
|
});
|
|
@@ -2356,7 +2310,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2356
2310
|
const [refFocusResult, refArchitecture, currentTables, refTables] = await Promise.all([
|
|
2357
2311
|
(0, focusAppDetector_1.detectFocusApps)(this.traceProcessorService, referenceTraceId).catch(() => ({ apps: [], method: 'none', primaryApp: undefined })),
|
|
2358
2312
|
(async () => {
|
|
2359
|
-
let refArch = this.architectureCache
|
|
2313
|
+
let refArch = (0, runtimeCommon_1.getLruCacheEntry)(this.architectureCache, referenceTraceId);
|
|
2360
2314
|
if (!refArch) {
|
|
2361
2315
|
try {
|
|
2362
2316
|
const detector = (0, architectureDetector_1.createArchitectureDetector)();
|
|
@@ -2366,7 +2320,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2366
2320
|
packageName: undefined,
|
|
2367
2321
|
}) ?? undefined;
|
|
2368
2322
|
if (refArch)
|
|
2369
|
-
this.architectureCache
|
|
2323
|
+
(0, runtimeCommon_1.setLruCacheEntry)(this.architectureCache, referenceTraceId, refArch);
|
|
2370
2324
|
}
|
|
2371
2325
|
catch { /* non-fatal */ }
|
|
2372
2326
|
}
|
|
@@ -2405,16 +2359,11 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2405
2359
|
`capDiff=${capabilityDiff ? `cur=${capabilityDiff.currentOnly.length}/ref=${capabilityDiff.referenceOnly.length}` : 'none'}`);
|
|
2406
2360
|
}
|
|
2407
2361
|
// Phase 2.9: Trace data completeness probe (cached per traceId, ~50ms first run)
|
|
2408
|
-
let traceCompleteness = this.completenessCache
|
|
2362
|
+
let traceCompleteness = (0, runtimeCommon_1.getLruCacheEntry)(this.completenessCache, traceId);
|
|
2409
2363
|
if (!traceCompleteness) {
|
|
2410
2364
|
try {
|
|
2411
2365
|
traceCompleteness = await (0, traceCompletenessProber_1.probeTraceCompleteness)(this.traceProcessorService, traceId, architecture?.type);
|
|
2412
|
-
this.completenessCache
|
|
2413
|
-
if (this.completenessCache.size > 50) {
|
|
2414
|
-
const firstKey = this.completenessCache.keys().next().value;
|
|
2415
|
-
if (firstKey)
|
|
2416
|
-
this.completenessCache.delete(firstKey);
|
|
2417
|
-
}
|
|
2366
|
+
(0, runtimeCommon_1.setLruCacheEntry)(this.completenessCache, traceId, traceCompleteness);
|
|
2418
2367
|
}
|
|
2419
2368
|
catch (err) {
|
|
2420
2369
|
console.warn('[ClaudeRuntime] Trace completeness probe failed (non-fatal):', err.message);
|
|
@@ -2445,15 +2394,17 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2445
2394
|
const entityContext = this.buildEntityContext(entityStore);
|
|
2446
2395
|
// Phase 5: Scene classification + effort resolution (reuse precomputed if available)
|
|
2447
2396
|
const sceneType = precomputed?.sceneType ?? (0, sceneClassifier_1.classifyScene)(query);
|
|
2448
|
-
const effectiveEffort = (0, claudeConfig_1.resolveEffort)(
|
|
2397
|
+
const effectiveEffort = (0, claudeConfig_1.resolveEffort)(runtimeConfig, sceneType, {
|
|
2398
|
+
configuredEffortOverridesScene: (0, claudeConfig_1.hasConfiguredClaudeEffortOverride)(options.providerId, providerScope),
|
|
2399
|
+
});
|
|
2449
2400
|
// Phase 5.5: Pattern memory — match similar historical traces (P2-2)
|
|
2450
2401
|
const traceFeatures = (0, analysisPatternMemory_1.extractTraceFeatures)({
|
|
2451
2402
|
architectureType: architecture?.type,
|
|
2452
2403
|
sceneType,
|
|
2453
2404
|
packageName: effectivePackageName,
|
|
2454
2405
|
});
|
|
2455
|
-
const patternContext = (0, analysisPatternMemory_1.buildPatternContextSection)(traceFeatures,
|
|
2456
|
-
const negativePatternContext = (0, analysisPatternMemory_1.buildNegativePatternSection)(traceFeatures,
|
|
2406
|
+
const patternContext = (0, analysisPatternMemory_1.buildPatternContextSection)(traceFeatures, (0, runtimeCommon_1.knowledgeScopeFromAnalysisOptions)(options));
|
|
2407
|
+
const negativePatternContext = (0, analysisPatternMemory_1.buildNegativePatternSection)(traceFeatures, (0, runtimeCommon_1.knowledgeScopeFromAnalysisOptions)(options));
|
|
2457
2408
|
// Phase 6: Session-scoped artifact store + analysis notes
|
|
2458
2409
|
if (!this.artifactStores.has(sessionId)) {
|
|
2459
2410
|
this.artifactStores.set(sessionId, new artifactStore_1.ArtifactStore());
|
|
@@ -2497,14 +2448,12 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2497
2448
|
// Seed new sessions with previously learned fix pairs from disk (cross-session learning)
|
|
2498
2449
|
let sqlErrors = this.sessionSqlErrors.get(sessionId);
|
|
2499
2450
|
if (!sqlErrors) {
|
|
2500
|
-
sqlErrors = (0, claudeMcpServer_1.loadLearnedSqlFixPairs)(5,
|
|
2451
|
+
sqlErrors = (0, claudeMcpServer_1.loadLearnedSqlFixPairs)(5, (0, runtimeCommon_1.knowledgeScopeFromAnalysisOptions)(options));
|
|
2501
2452
|
this.sessionSqlErrors.set(sessionId, sqlErrors);
|
|
2502
2453
|
}
|
|
2503
2454
|
// Phase 8: MCP server with all session-scoped state
|
|
2504
2455
|
// P2-G1: Destructure to get both server and auto-derived allowedTools
|
|
2505
|
-
const fullNotesBudget =
|
|
2506
|
-
? new skillNotesInjector_1.SkillNotesBudget({ mode: 'full' })
|
|
2507
|
-
: undefined;
|
|
2456
|
+
const fullNotesBudget = (0, runtimeCommon_1.createRuntimeSkillNotesBudget)(false);
|
|
2508
2457
|
const { server: mcpServer, allowedTools } = (0, claudeMcpServer_1.createClaudeMcpServer)({
|
|
2509
2458
|
sessionId,
|
|
2510
2459
|
traceId,
|
|
@@ -2530,8 +2479,8 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2530
2479
|
referenceTraceId,
|
|
2531
2480
|
comparisonContext,
|
|
2532
2481
|
skillNotesBudget: fullNotesBudget,
|
|
2533
|
-
outputLanguage:
|
|
2534
|
-
knowledgeScope:
|
|
2482
|
+
outputLanguage: runtimeConfig.outputLanguage,
|
|
2483
|
+
knowledgeScope: (0, runtimeCommon_1.knowledgeScopeFromAnalysisOptions)(options),
|
|
2535
2484
|
codeAwareMode: options.codeAwareMode,
|
|
2536
2485
|
codebaseIds: options.codebaseIds,
|
|
2537
2486
|
});
|
|
@@ -2548,12 +2497,12 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2548
2497
|
}
|
|
2549
2498
|
// Phase 11: Sub-agent definitions (feature-gated)
|
|
2550
2499
|
let agents;
|
|
2551
|
-
if (
|
|
2500
|
+
if (runtimeConfig.enableSubAgents && sceneType !== 'anr') {
|
|
2552
2501
|
agents = (0, claudeAgentDefinitions_1.buildAgentDefinitions)(sceneType, {
|
|
2553
2502
|
architecture,
|
|
2554
2503
|
packageName: effectivePackageName,
|
|
2555
2504
|
allowedTools,
|
|
2556
|
-
subAgentModel:
|
|
2505
|
+
subAgentModel: runtimeConfig.subAgentModel,
|
|
2557
2506
|
});
|
|
2558
2507
|
}
|
|
2559
2508
|
// Phase 12: SQL error-fix pairs for prompt injection
|
|
@@ -2586,7 +2535,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2586
2535
|
traceCompleteness,
|
|
2587
2536
|
traceOs: traceInfo?.traceOs,
|
|
2588
2537
|
traceFormat: traceInfo?.traceFormat,
|
|
2589
|
-
outputLanguage:
|
|
2538
|
+
outputLanguage: runtimeConfig.outputLanguage,
|
|
2590
2539
|
codeAwareMode: options.codeAwareMode,
|
|
2591
2540
|
codebaseIds: options.codebaseIds,
|
|
2592
2541
|
};
|
|
@@ -2617,23 +2566,7 @@ class ClaudeRuntime extends events_1.EventEmitter {
|
|
|
2617
2566
|
}
|
|
2618
2567
|
/** Capture entities from skill displayResults into EntityStore for multi-turn drill-down. */
|
|
2619
2568
|
captureEntitiesFromSkillDisplayResults(displayResults, entityStore) {
|
|
2620
|
-
|
|
2621
|
-
const data = {};
|
|
2622
|
-
for (const dr of displayResults) {
|
|
2623
|
-
if (dr.stepId && dr.data) {
|
|
2624
|
-
data[dr.stepId] = dr.data;
|
|
2625
|
-
}
|
|
2626
|
-
}
|
|
2627
|
-
const captured = (0, entityCapture_1.captureEntitiesFromResponses)([{
|
|
2628
|
-
agentId: 'claude-agent',
|
|
2629
|
-
success: true,
|
|
2630
|
-
toolResults: [{ toolName: 'invoke_skill', data }],
|
|
2631
|
-
}]);
|
|
2632
|
-
(0, entityCapture_1.applyCapturedEntities)(entityStore, captured);
|
|
2633
|
-
}
|
|
2634
|
-
catch (err) {
|
|
2635
|
-
console.warn('[ClaudeRuntime] Entity capture failed:', err.message);
|
|
2636
|
-
}
|
|
2569
|
+
(0, runtimeCommon_1.captureSkillDisplayEntities)(displayResults, entityStore, 'claude-agent');
|
|
2637
2570
|
}
|
|
2638
2571
|
}
|
|
2639
2572
|
exports.ClaudeRuntime = ClaudeRuntime;
|