@gracker/smartperfetto 1.0.19 → 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 +159 -191
- 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 +198 -265
- 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/claudeVerifier.d.ts.map +1 -1
- package/dist/agentv3/claudeVerifier.js +3 -6
- package/dist/agentv3/claudeVerifier.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/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/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/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/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/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 +3 -3
- 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 +3 -1
- package/strategies/prompt-openai-final-report-continuation-zh.template.md +3 -1
- package/strategies/prompt-output-format.template.md +1 -1
- package/strategies/startup.strategy.md +4 -4
|
@@ -27,9 +27,7 @@ const queryComplexityClassifier_1 = require("../agentv3/queryComplexityClassifie
|
|
|
27
27
|
const openAiComplexityClassifier_1 = require("./openAiComplexityClassifier");
|
|
28
28
|
const artifactStore_1 = require("../agentv3/artifactStore");
|
|
29
29
|
const analysisPatternMemory_1 = require("../agentv3/analysisPatternMemory");
|
|
30
|
-
const skillNotesInjector_1 = require("../agentv3/selfImprove/skillNotesInjector");
|
|
31
30
|
const traceCompletenessProber_1 = require("../agentv3/traceCompletenessProber");
|
|
32
|
-
const entityCapture_1 = require("../agent/core/entityCapture");
|
|
33
31
|
const outputLanguage_1 = require("../agentv3/outputLanguage");
|
|
34
32
|
const codeAwareOutputRegistry_1 = require("../services/security/codeAwareOutputRegistry");
|
|
35
33
|
const toolNarration_1 = require("../agentv3/toolNarration");
|
|
@@ -38,29 +36,16 @@ const mimoReasoningCompat_1 = require("./mimoReasoningCompat");
|
|
|
38
36
|
const openAiToolAdapter_1 = require("./openAiToolAdapter");
|
|
39
37
|
const finalResultQualityGate_1 = require("../services/finalResultQualityGate");
|
|
40
38
|
const finalReportContractGate_1 = require("../services/finalReportContractGate");
|
|
41
|
-
const
|
|
39
|
+
const runtimeCommon_1 = require("../agentRuntime/runtimeCommon");
|
|
40
|
+
const OPENAI_SESSION_FRESHNESS_MS = runtimeCommon_1.SDK_SESSION_FRESHNESS_MS;
|
|
42
41
|
const OPENAI_MAX_PLAN_CONTINUATIONS = 3;
|
|
43
|
-
const OPENAI_MAX_FINAL_REPORT_CONTINUATIONS =
|
|
42
|
+
const OPENAI_MAX_FINAL_REPORT_CONTINUATIONS = 4;
|
|
44
43
|
const OPENAI_PLAN_COMPLETE_IDLE_ABORT_MS = 8000;
|
|
45
44
|
function hasAdequateClosedPhaseSummary(phase) {
|
|
46
45
|
if (phase.status !== 'completed' && phase.status !== 'skipped')
|
|
47
46
|
return false;
|
|
48
47
|
return typeof phase.summary === 'string' && phase.summary.trim().length >= claudeMcpServer_1.MIN_PHASE_SUMMARY_CHARS;
|
|
49
48
|
}
|
|
50
|
-
function formatTraceContext(datasets, outputLanguage) {
|
|
51
|
-
if (!datasets || datasets.length === 0)
|
|
52
|
-
return '';
|
|
53
|
-
const parts = datasets.map((d) => {
|
|
54
|
-
const header = `| ${d.columns.join(' | ')} |`;
|
|
55
|
-
const sep = `| ${d.columns.map(() => '---').join(' | ')} |`;
|
|
56
|
-
const rows = d.rows.slice(0, 100).map((r) => `| ${r.map((v) => String(v ?? '-')).join(' | ')} |`);
|
|
57
|
-
const truncNote = d.rows.length > 100
|
|
58
|
-
? (0, outputLanguage_1.localize)(outputLanguage, `\n*(前 100 行,共 ${d.rows.length} 行)*`, `\n*(first 100 rows out of ${d.rows.length})*`)
|
|
59
|
-
: '';
|
|
60
|
-
return `### ${d.label}\n${header}\n${sep}\n${rows.join('\n')}${truncNote}`;
|
|
61
|
-
});
|
|
62
|
-
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')}`);
|
|
63
|
-
}
|
|
64
49
|
function parseJsonObject(value) {
|
|
65
50
|
if (typeof value !== 'string')
|
|
66
51
|
return undefined;
|
|
@@ -72,25 +57,6 @@ function parseJsonObject(value) {
|
|
|
72
57
|
return undefined;
|
|
73
58
|
}
|
|
74
59
|
}
|
|
75
|
-
function providerScopeFromOptions(options) {
|
|
76
|
-
if (!options.tenantId || !options.workspaceId)
|
|
77
|
-
return undefined;
|
|
78
|
-
return {
|
|
79
|
-
tenantId: options.tenantId,
|
|
80
|
-
workspaceId: options.workspaceId,
|
|
81
|
-
userId: options.userId,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
function knowledgeScopeFromOptions(options) {
|
|
85
|
-
if (!options.tenantId || !options.workspaceId)
|
|
86
|
-
return undefined;
|
|
87
|
-
return {
|
|
88
|
-
tenantId: options.tenantId,
|
|
89
|
-
workspaceId: options.workspaceId,
|
|
90
|
-
userId: options.userId,
|
|
91
|
-
sourceRunId: options.runId,
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
60
|
function summarizeToolOutput(value) {
|
|
95
61
|
const text = typeof value === 'string' ? value : JSON.stringify(value);
|
|
96
62
|
if (!text)
|
|
@@ -301,12 +267,54 @@ function chooseOpenAiConclusionText(input) {
|
|
|
301
267
|
}
|
|
302
268
|
return selected;
|
|
303
269
|
}
|
|
270
|
+
function resolveOpenAIRunInput(params) {
|
|
271
|
+
let effectivePrompt = params.effectivePrompt;
|
|
272
|
+
if (params.quickMode) {
|
|
273
|
+
const quickConversationContext = (0, runtimeCommon_1.buildQuickConversationContext)(params.previousTurns, params.config.outputLanguage);
|
|
274
|
+
if (quickConversationContext) {
|
|
275
|
+
effectivePrompt = `${quickConversationContext}\n\n${effectivePrompt}`;
|
|
276
|
+
}
|
|
277
|
+
return {
|
|
278
|
+
input: effectivePrompt,
|
|
279
|
+
effectivePrompt,
|
|
280
|
+
shouldPersistRemoteSession: false,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
const hasFreshSessionEntry = (0, runtimeCommon_1.isFreshRuntimeEntry)(params.sessionEntry, OPENAI_SESSION_FRESHNESS_MS, params.now ?? Date.now());
|
|
284
|
+
const freshSessionEntry = hasFreshSessionEntry ? params.sessionEntry : undefined;
|
|
285
|
+
const usePreviousResponse = params.config.protocol === 'responses'
|
|
286
|
+
&& !!freshSessionEntry?.lastResponseId;
|
|
287
|
+
if (usePreviousResponse) {
|
|
288
|
+
return {
|
|
289
|
+
input: effectivePrompt,
|
|
290
|
+
effectivePrompt,
|
|
291
|
+
previousResponseId: freshSessionEntry.lastResponseId,
|
|
292
|
+
shouldPersistRemoteSession: true,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
if (freshSessionEntry?.history) {
|
|
296
|
+
return {
|
|
297
|
+
input: [
|
|
298
|
+
...freshSessionEntry.history,
|
|
299
|
+
{ role: 'user', content: effectivePrompt },
|
|
300
|
+
],
|
|
301
|
+
effectivePrompt,
|
|
302
|
+
shouldPersistRemoteSession: true,
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
input: effectivePrompt,
|
|
307
|
+
effectivePrompt,
|
|
308
|
+
shouldPersistRemoteSession: true,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
304
311
|
exports.__testing = {
|
|
305
312
|
isMissingOpenAIPreviousResponseError,
|
|
306
313
|
readCompletedStreamFinalOutput,
|
|
307
314
|
sanitizeOpenAiConclusionText,
|
|
308
315
|
chooseOpenAiConclusionText,
|
|
309
316
|
selectOpenAiRecoveryAnswer,
|
|
317
|
+
resolveOpenAIRunInput,
|
|
310
318
|
isRecoverableOpenAIStreamTermination,
|
|
311
319
|
compactProviderErrorMessage,
|
|
312
320
|
};
|
|
@@ -327,11 +335,11 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
327
335
|
this.traceProcessorService = traceProcessorService;
|
|
328
336
|
}
|
|
329
337
|
buildSessionMapKey(sessionId, referenceTraceId) {
|
|
330
|
-
return
|
|
338
|
+
return (0, runtimeCommon_1.buildRuntimeSessionMapKey)(sessionId, referenceTraceId);
|
|
331
339
|
}
|
|
332
340
|
getSdkSessionId(sessionId, referenceTraceId) {
|
|
333
341
|
const entry = this.sessionMap.get(this.buildSessionMapKey(sessionId, referenceTraceId));
|
|
334
|
-
return
|
|
342
|
+
return (0, runtimeCommon_1.isFreshRuntimeEntry)(entry, OPENAI_SESSION_FRESHNESS_MS)
|
|
335
343
|
? entry.lastResponseId
|
|
336
344
|
: undefined;
|
|
337
345
|
}
|
|
@@ -344,7 +352,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
344
352
|
});
|
|
345
353
|
}
|
|
346
354
|
restoreArchitectureCache(traceId, architecture) {
|
|
347
|
-
this.architectureCache
|
|
355
|
+
(0, runtimeCommon_1.setLruCacheEntry)(this.architectureCache, traceId, architecture);
|
|
348
356
|
}
|
|
349
357
|
forgetOpenAILastResponseId(sessionMapKey, reason) {
|
|
350
358
|
const existing = this.sessionMap.get(sessionMapKey);
|
|
@@ -394,7 +402,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
394
402
|
const startTime = Date.now();
|
|
395
403
|
let accumulatedAnswer = '';
|
|
396
404
|
let rounds = 0;
|
|
397
|
-
const config = (0, openAiConfig_1.loadOpenAIConfig)(options.providerId,
|
|
405
|
+
const config = (0, openAiConfig_1.loadOpenAIConfig)(options.providerId, (0, runtimeCommon_1.providerScopeFromAnalysisOptions)(options));
|
|
398
406
|
const sceneType = (0, sceneClassifier_1.classifyScene)(query);
|
|
399
407
|
const quickMode = await this.classifyModeForRequest(query, sessionId, traceId, options, sceneType, config);
|
|
400
408
|
try {
|
|
@@ -403,22 +411,17 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
403
411
|
sceneType,
|
|
404
412
|
lightweight: quickMode,
|
|
405
413
|
});
|
|
406
|
-
const promptPrefix = formatTraceContext(options.traceContext, config.outputLanguage);
|
|
414
|
+
const promptPrefix = (0, runtimeCommon_1.formatTraceContext)(options.traceContext, config.outputLanguage);
|
|
407
415
|
const effectivePrompt = promptPrefix ? `${promptPrefix}\n\n${query}` : query;
|
|
408
416
|
const sessionEntry = this.sessionMap.get(context.sessionMapKey);
|
|
409
|
-
const
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
? [
|
|
418
|
-
...sessionEntry.history,
|
|
419
|
-
{ role: 'user', content: effectivePrompt },
|
|
420
|
-
]
|
|
421
|
-
: effectivePrompt;
|
|
417
|
+
const runInput = resolveOpenAIRunInput({
|
|
418
|
+
quickMode,
|
|
419
|
+
config,
|
|
420
|
+
sessionEntry,
|
|
421
|
+
effectivePrompt,
|
|
422
|
+
previousTurns: context.previousTurns,
|
|
423
|
+
});
|
|
424
|
+
const input = runInput.input;
|
|
422
425
|
(0, agents_1.setTracingDisabled)(true);
|
|
423
426
|
const provider = (0, mimoReasoningCompat_1.shouldUseMimoReasoningContentCompat)(config)
|
|
424
427
|
? new agents_1.OpenAIProvider({
|
|
@@ -465,13 +468,13 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
465
468
|
type: 'progress',
|
|
466
469
|
content: {
|
|
467
470
|
phase: 'answering',
|
|
468
|
-
message: (0, outputLanguage_1.localize)(config.outputLanguage, `
|
|
471
|
+
message: (0, outputLanguage_1.localize)(config.outputLanguage, `AI 分析引擎分析中 (${agent.model})...`, `AI analysis engine is running (${agent.model})...`),
|
|
469
472
|
runtime: 'openai-agents-sdk',
|
|
470
473
|
model: agent.model,
|
|
471
474
|
},
|
|
472
475
|
timestamp: Date.now(),
|
|
473
476
|
});
|
|
474
|
-
let currentPreviousResponseId =
|
|
477
|
+
let currentPreviousResponseId = runInput.previousResponseId;
|
|
475
478
|
try {
|
|
476
479
|
let currentInput = input;
|
|
477
480
|
let conclusion = '';
|
|
@@ -528,7 +531,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
528
531
|
type: 'progress',
|
|
529
532
|
content: {
|
|
530
533
|
phase: 'concluding',
|
|
531
|
-
message: (0, outputLanguage_1.localize)(config.outputLanguage, '
|
|
534
|
+
message: (0, outputLanguage_1.localize)(config.outputLanguage, '分析阶段已完成,正在整理最终报告。', 'Analysis phases are complete; preparing the final report.'),
|
|
532
535
|
},
|
|
533
536
|
timestamp: Date.now(),
|
|
534
537
|
});
|
|
@@ -685,7 +688,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
685
688
|
(0, finalResultQualityGate_1.looksLikePhaseSummaryFallback)(conclusion)) &&
|
|
686
689
|
!partial) {
|
|
687
690
|
partial = true;
|
|
688
|
-
terminationMessage = (0, outputLanguage_1.localize)(config.outputLanguage, '
|
|
691
|
+
terminationMessage = (0, outputLanguage_1.localize)(config.outputLanguage, '分析阶段已完成,但模型没有输出独立最终报告;已使用阶段摘要兜底,结果信息密度可能不足。', 'Analysis phases completed, but the model did not produce an independent final report; falling back to phase summaries, which may be less informative.');
|
|
689
692
|
this.emitUpdate({
|
|
690
693
|
type: 'degraded',
|
|
691
694
|
content: {
|
|
@@ -727,12 +730,14 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
727
730
|
timestamp: Date.now(),
|
|
728
731
|
});
|
|
729
732
|
}
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
733
|
+
if (runInput.shouldPersistRemoteSession) {
|
|
734
|
+
this.sessionMap.set(context.sessionMapKey, {
|
|
735
|
+
history: finalHistory,
|
|
736
|
+
lastResponseId: finalLastResponseId,
|
|
737
|
+
runState: finalRunState,
|
|
738
|
+
updatedAt: Date.now(),
|
|
739
|
+
});
|
|
740
|
+
}
|
|
736
741
|
this.recordTurn({
|
|
737
742
|
query,
|
|
738
743
|
sessionId,
|
|
@@ -769,33 +774,18 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
769
774
|
});
|
|
770
775
|
}
|
|
771
776
|
else if (error instanceof agents_1.MaxTurnsExceededError) {
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
this.emitUpdate({
|
|
776
|
-
type: 'degraded',
|
|
777
|
-
content: {
|
|
778
|
-
module: 'openAiRuntime',
|
|
779
|
-
fallback: 'partial_result_after_max_turns',
|
|
780
|
-
partial: true,
|
|
781
|
-
terminationReason: 'max_turns',
|
|
782
|
-
message: (0, outputLanguage_1.localize)(config.outputLanguage, 'OpenAI 分析达到轮次上限,结果可能不完整', 'OpenAI analysis reached the turn limit; result may be incomplete'),
|
|
783
|
-
},
|
|
784
|
-
timestamp: Date.now(),
|
|
785
|
-
});
|
|
786
|
-
return {
|
|
777
|
+
return this.recordMaxTurnsPartialResult({
|
|
778
|
+
error,
|
|
779
|
+
query,
|
|
787
780
|
sessionId,
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
confidence,
|
|
781
|
+
outputLanguage: config.outputLanguage,
|
|
782
|
+
accumulatedAnswer,
|
|
783
|
+
context,
|
|
784
|
+
startTime,
|
|
793
785
|
rounds,
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
terminationMessage: error.message,
|
|
798
|
-
};
|
|
786
|
+
quickMode,
|
|
787
|
+
codeAwareMode: options.codeAwareMode,
|
|
788
|
+
});
|
|
799
789
|
}
|
|
800
790
|
const recoverablePartial = this.recoverPartialResultAfterStreamTermination({
|
|
801
791
|
error,
|
|
@@ -807,6 +797,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
807
797
|
query,
|
|
808
798
|
startTime,
|
|
809
799
|
rounds,
|
|
800
|
+
codeAwareMode: options.codeAwareMode,
|
|
810
801
|
});
|
|
811
802
|
if (recoverablePartial) {
|
|
812
803
|
return recoverablePartial;
|
|
@@ -818,7 +809,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
818
809
|
const message = compactProviderErrorMessage(error);
|
|
819
810
|
this.emitUpdate({
|
|
820
811
|
type: 'error',
|
|
821
|
-
content: { message: `
|
|
812
|
+
content: { message: `AI analysis failed: ${message}` },
|
|
822
813
|
timestamp: Date.now(),
|
|
823
814
|
});
|
|
824
815
|
return {
|
|
@@ -826,7 +817,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
826
817
|
success: false,
|
|
827
818
|
findings: [],
|
|
828
819
|
hypotheses: [],
|
|
829
|
-
conclusion: (0, outputLanguage_1.localize)(config.outputLanguage, `
|
|
820
|
+
conclusion: (0, outputLanguage_1.localize)(config.outputLanguage, `AI 分析失败:${message}`, `AI analysis failed: ${message}`),
|
|
830
821
|
confidence: 0,
|
|
831
822
|
rounds,
|
|
832
823
|
totalDurationMs: Date.now() - startTime,
|
|
@@ -869,7 +860,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
869
860
|
const planState = this.sessionPlans.get(sessionId);
|
|
870
861
|
const artifactStore = this.artifactStores.get(sessionId);
|
|
871
862
|
const sessionEntry = this.sessionMap.get(this.buildSessionMapKey(sessionId, sessionFields.referenceTraceId));
|
|
872
|
-
const freshSessionEntry =
|
|
863
|
+
const freshSessionEntry = (0, runtimeCommon_1.isFreshRuntimeEntry)(sessionEntry, OPENAI_SESSION_FRESHNESS_MS)
|
|
873
864
|
? sessionEntry
|
|
874
865
|
: undefined;
|
|
875
866
|
return {
|
|
@@ -990,12 +981,10 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
990
981
|
uncertaintyFlags.splice(0);
|
|
991
982
|
let sqlErrors = this.sessionSqlErrors.get(sessionId);
|
|
992
983
|
if (!sqlErrors) {
|
|
993
|
-
sqlErrors = (0, claudeMcpServer_1.loadLearnedSqlFixPairs)(5,
|
|
984
|
+
sqlErrors = (0, claudeMcpServer_1.loadLearnedSqlFixPairs)(5, (0, runtimeCommon_1.knowledgeScopeFromAnalysisOptions)(options));
|
|
994
985
|
this.sessionSqlErrors.set(sessionId, sqlErrors);
|
|
995
986
|
}
|
|
996
|
-
const skillNotesBudget =
|
|
997
|
-
? new skillNotesInjector_1.SkillNotesBudget({ mode: 'full' })
|
|
998
|
-
: undefined;
|
|
987
|
+
const skillNotesBudget = (0, runtimeCommon_1.createRuntimeSkillNotesBudget)(lightweight);
|
|
999
988
|
const { allowedTools, toolDefinitions } = (0, claudeMcpServer_1.createClaudeMcpServer)({
|
|
1000
989
|
sessionId,
|
|
1001
990
|
traceId,
|
|
@@ -1023,7 +1012,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
1023
1012
|
lightweight,
|
|
1024
1013
|
skillNotesBudget,
|
|
1025
1014
|
outputLanguage: config.outputLanguage,
|
|
1026
|
-
knowledgeScope:
|
|
1015
|
+
knowledgeScope: (0, runtimeCommon_1.knowledgeScopeFromAnalysisOptions)(options),
|
|
1027
1016
|
codeAwareMode: options.codeAwareMode,
|
|
1028
1017
|
codebaseIds: options.codebaseIds,
|
|
1029
1018
|
});
|
|
@@ -1045,6 +1034,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
1045
1034
|
.filter((e) => e.fixedSql)
|
|
1046
1035
|
.slice(-3)
|
|
1047
1036
|
.map((e) => ({ errorSql: e.errorSql, errorMessage: e.errorMessage, fixedSql: e.fixedSql }));
|
|
1037
|
+
const traceInfo = this.traceProcessorService.getTrace(traceId);
|
|
1048
1038
|
const systemPrompt = lightweight
|
|
1049
1039
|
? (0, claudeSystemPrompt_1.buildQuickSystemPrompt)({
|
|
1050
1040
|
architecture,
|
|
@@ -1075,6 +1065,8 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
1075
1065
|
selectionContext: options.selectionContext,
|
|
1076
1066
|
comparison: comparisonContext,
|
|
1077
1067
|
traceCompleteness,
|
|
1068
|
+
traceOs: traceInfo?.traceOs,
|
|
1069
|
+
traceFormat: traceInfo?.traceFormat,
|
|
1078
1070
|
outputLanguage: config.outputLanguage,
|
|
1079
1071
|
codeAwareMode: options.codeAwareMode,
|
|
1080
1072
|
codebaseIds: options.codebaseIds,
|
|
@@ -1092,7 +1084,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
1092
1084
|
};
|
|
1093
1085
|
}
|
|
1094
1086
|
async detectArchitecture(traceId, packageName) {
|
|
1095
|
-
const cached = this.architectureCache
|
|
1087
|
+
const cached = (0, runtimeCommon_1.getLruCacheEntry)(this.architectureCache, traceId);
|
|
1096
1088
|
if (cached)
|
|
1097
1089
|
return cached;
|
|
1098
1090
|
try {
|
|
@@ -1103,7 +1095,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
1103
1095
|
packageName,
|
|
1104
1096
|
});
|
|
1105
1097
|
if (architecture) {
|
|
1106
|
-
this.architectureCache
|
|
1098
|
+
(0, runtimeCommon_1.setLruCacheEntry)(this.architectureCache, traceId, architecture);
|
|
1107
1099
|
this.emitUpdate({ type: 'architecture_detected', content: { architecture }, timestamp: Date.now() });
|
|
1108
1100
|
}
|
|
1109
1101
|
return architecture;
|
|
@@ -1161,15 +1153,16 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
1161
1153
|
};
|
|
1162
1154
|
}
|
|
1163
1155
|
async detectVendor(traceId) {
|
|
1164
|
-
const cached = this.vendorCache
|
|
1156
|
+
const cached = (0, runtimeCommon_1.getLruCacheEntry)(this.vendorCache, traceId);
|
|
1165
1157
|
if (cached)
|
|
1166
1158
|
return cached;
|
|
1167
1159
|
try {
|
|
1168
1160
|
const adapter = (0, skillAnalysisAdapter_1.getSkillAnalysisAdapter)(this.traceProcessorService);
|
|
1169
1161
|
await adapter.ensureInitialized();
|
|
1170
1162
|
const result = await adapter.detectVendor(traceId);
|
|
1171
|
-
if (result.vendor && result.vendor !== 'aosp')
|
|
1172
|
-
this.vendorCache
|
|
1163
|
+
if (result.vendor && result.vendor !== 'aosp') {
|
|
1164
|
+
(0, runtimeCommon_1.setLruCacheEntry)(this.vendorCache, traceId, result.vendor);
|
|
1165
|
+
}
|
|
1173
1166
|
return result.vendor;
|
|
1174
1167
|
}
|
|
1175
1168
|
catch (error) {
|
|
@@ -1178,12 +1171,12 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
1178
1171
|
}
|
|
1179
1172
|
}
|
|
1180
1173
|
async detectCompleteness(traceId, architecture) {
|
|
1181
|
-
const cached = this.completenessCache
|
|
1174
|
+
const cached = (0, runtimeCommon_1.getLruCacheEntry)(this.completenessCache, traceId);
|
|
1182
1175
|
if (cached)
|
|
1183
1176
|
return cached;
|
|
1184
1177
|
try {
|
|
1185
1178
|
const completeness = await (0, traceCompletenessProber_1.probeTraceCompleteness)(this.traceProcessorService, traceId, architecture?.type);
|
|
1186
|
-
this.completenessCache
|
|
1179
|
+
(0, runtimeCommon_1.setLruCacheEntry)(this.completenessCache, traceId, completeness);
|
|
1187
1180
|
return completeness;
|
|
1188
1181
|
}
|
|
1189
1182
|
catch (error) {
|
|
@@ -1289,7 +1282,7 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
1289
1282
|
return template;
|
|
1290
1283
|
}
|
|
1291
1284
|
formatPlanCompleteReportContinuationMessage(outputLanguage) {
|
|
1292
|
-
return (0, outputLanguage_1.localize)(outputLanguage, '
|
|
1285
|
+
return (0, outputLanguage_1.localize)(outputLanguage, '最终报告仍需补齐,继续整理完整结论。', 'The final report still needs completion; continuing to assemble the full conclusion.');
|
|
1293
1286
|
}
|
|
1294
1287
|
buildCompletedPlanFallbackConclusion(sessionId, quickMode, outputLanguage) {
|
|
1295
1288
|
if (quickMode)
|
|
@@ -1404,7 +1397,9 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
1404
1397
|
let conclusion = planStatus.complete
|
|
1405
1398
|
? conclusionBase
|
|
1406
1399
|
: this.withIncompletePlanWarning(conclusionBase, planStatus, params.outputLanguage);
|
|
1407
|
-
|
|
1400
|
+
if (params.codeAwareMode && params.codeAwareMode !== 'off') {
|
|
1401
|
+
conclusion = (0, codeAwareOutputRegistry_1.sanitizeCodeAwareText)(params.sessionId, conclusion);
|
|
1402
|
+
}
|
|
1408
1403
|
const findings = (0, claudeFindingExtractor_1.extractFindingsFromText)(conclusion);
|
|
1409
1404
|
const confidence = Math.min(0.55, this.estimateConfidence(findings, conclusion));
|
|
1410
1405
|
const terminationReason = planStatus.complete ? 'timeout' : 'plan_incomplete';
|
|
@@ -1464,12 +1459,63 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
1464
1459
|
terminationMessage,
|
|
1465
1460
|
};
|
|
1466
1461
|
}
|
|
1462
|
+
recordMaxTurnsPartialResult(params) {
|
|
1463
|
+
let partialConclusion = params.accumulatedAnswer || (0, outputLanguage_1.localize)(params.outputLanguage, '分析达到轮次上限,尚未形成完整结论。', 'The analysis reached the turn limit before a complete conclusion was produced.');
|
|
1464
|
+
if (params.codeAwareMode && params.codeAwareMode !== 'off') {
|
|
1465
|
+
partialConclusion = (0, codeAwareOutputRegistry_1.sanitizeCodeAwareText)(params.sessionId, partialConclusion);
|
|
1466
|
+
}
|
|
1467
|
+
const findings = (0, claudeFindingExtractor_1.extractFindingsFromText)(partialConclusion);
|
|
1468
|
+
const confidence = Math.min(0.55, this.estimateConfidence(findings, partialConclusion));
|
|
1469
|
+
const result = {
|
|
1470
|
+
sessionId: params.sessionId,
|
|
1471
|
+
success: true,
|
|
1472
|
+
findings,
|
|
1473
|
+
hypotheses: params.context.hypotheses.map(h => this.toProtocolHypothesis(h)),
|
|
1474
|
+
conclusion: partialConclusion,
|
|
1475
|
+
confidence,
|
|
1476
|
+
rounds: params.rounds,
|
|
1477
|
+
totalDurationMs: Date.now() - params.startTime,
|
|
1478
|
+
partial: true,
|
|
1479
|
+
terminationReason: 'max_turns',
|
|
1480
|
+
terminationMessage: params.error.message,
|
|
1481
|
+
};
|
|
1482
|
+
this.emitUpdate({
|
|
1483
|
+
type: 'degraded',
|
|
1484
|
+
content: {
|
|
1485
|
+
module: 'openAiRuntime',
|
|
1486
|
+
fallback: 'partial_result_after_max_turns',
|
|
1487
|
+
partial: true,
|
|
1488
|
+
terminationReason: 'max_turns',
|
|
1489
|
+
message: (0, outputLanguage_1.localize)(params.outputLanguage, 'OpenAI 分析达到轮次上限,结果可能不完整', 'OpenAI analysis reached the turn limit; result may be incomplete'),
|
|
1490
|
+
},
|
|
1491
|
+
timestamp: Date.now(),
|
|
1492
|
+
});
|
|
1493
|
+
this.recordTurn({
|
|
1494
|
+
query: params.query,
|
|
1495
|
+
sessionId: params.sessionId,
|
|
1496
|
+
result,
|
|
1497
|
+
sessionContext: params.context.sessionContext,
|
|
1498
|
+
previousTurnCount: params.context.previousTurns.length,
|
|
1499
|
+
quickMode: params.quickMode,
|
|
1500
|
+
});
|
|
1501
|
+
this.emitUpdate({
|
|
1502
|
+
type: 'conclusion',
|
|
1503
|
+
content: { conclusion: result.conclusion, durationMs: Date.now() - params.startTime, turns: params.rounds },
|
|
1504
|
+
timestamp: Date.now(),
|
|
1505
|
+
});
|
|
1506
|
+
this.emitUpdate({
|
|
1507
|
+
type: 'answer_token',
|
|
1508
|
+
content: { done: true, totalChars: result.conclusion.length },
|
|
1509
|
+
timestamp: Date.now(),
|
|
1510
|
+
});
|
|
1511
|
+
return result;
|
|
1512
|
+
}
|
|
1467
1513
|
formatPlanContinuationMessage(status, outputLanguage) {
|
|
1468
1514
|
if (!status.hasPlan) {
|
|
1469
|
-
return (0, outputLanguage_1.localize)(outputLanguage, '
|
|
1515
|
+
return (0, outputLanguage_1.localize)(outputLanguage, '继续建立分析计划并补齐必要证据...', 'Continuing by creating the analysis plan and collecting required evidence...');
|
|
1470
1516
|
}
|
|
1471
1517
|
const phaseNames = status.pendingPhases.map(p => p.name || p.id).slice(0, 3).join('、');
|
|
1472
|
-
return (0, outputLanguage_1.localize)(outputLanguage,
|
|
1518
|
+
return (0, outputLanguage_1.localize)(outputLanguage, `继续补齐剩余分析阶段:${phaseNames}`, `Continuing the remaining analysis phases: ${phaseNames}`);
|
|
1473
1519
|
}
|
|
1474
1520
|
formatIncompletePlanMessage(status, outputLanguage) {
|
|
1475
1521
|
if (!status.hasPlan) {
|
|
@@ -1593,94 +1639,16 @@ class OpenAIRuntime extends events_1.EventEmitter {
|
|
|
1593
1639
|
});
|
|
1594
1640
|
}
|
|
1595
1641
|
captureEntitiesFromSkillDisplayResults(displayResults, entityStore) {
|
|
1596
|
-
|
|
1597
|
-
const data = {};
|
|
1598
|
-
for (const dr of displayResults) {
|
|
1599
|
-
if (dr.stepId && dr.data)
|
|
1600
|
-
data[dr.stepId] = dr.data;
|
|
1601
|
-
}
|
|
1602
|
-
const captured = (0, entityCapture_1.captureEntitiesFromResponses)([{
|
|
1603
|
-
agentId: 'openai-agent',
|
|
1604
|
-
success: true,
|
|
1605
|
-
toolResults: [{ toolName: 'invoke_skill', data }],
|
|
1606
|
-
}]);
|
|
1607
|
-
(0, entityCapture_1.applyCapturedEntities)(entityStore, captured);
|
|
1608
|
-
}
|
|
1609
|
-
catch (error) {
|
|
1610
|
-
console.warn('[OpenAIRuntime] Entity capture failed:', error.message);
|
|
1611
|
-
}
|
|
1642
|
+
(0, runtimeCommon_1.captureSkillDisplayEntities)(displayResults, entityStore, 'openai-agent');
|
|
1612
1643
|
}
|
|
1613
1644
|
collectPreviousFindings(sessionContext, maxTurns = 3) {
|
|
1614
|
-
|
|
1615
|
-
const turns = sessionContext.getAllTurns?.() || [];
|
|
1616
|
-
return turns.slice(-maxTurns).flatMap((turn) => turn.findings || []).slice(0, 5);
|
|
1617
|
-
}
|
|
1618
|
-
catch {
|
|
1619
|
-
return [];
|
|
1620
|
-
}
|
|
1645
|
+
return (0, runtimeCommon_1.collectRecentFindings)(sessionContext, { maxTurns, maxFindings: 5 });
|
|
1621
1646
|
}
|
|
1622
1647
|
buildEntityContext(entityStore) {
|
|
1623
|
-
|
|
1624
|
-
const lines = [];
|
|
1625
|
-
const frames = entityStore.getAllFrames?.() || [];
|
|
1626
|
-
if (frames.length > 0) {
|
|
1627
|
-
lines.push(`**帧 (${frames.length})**:`);
|
|
1628
|
-
for (const f of frames.slice(0, 15)) {
|
|
1629
|
-
const parts = [`frame_id=${f.frame_id}`];
|
|
1630
|
-
if (f.start_ts)
|
|
1631
|
-
parts.push(`ts=${f.start_ts}`);
|
|
1632
|
-
if (f.jank_type)
|
|
1633
|
-
parts.push(`jank=${f.jank_type}`);
|
|
1634
|
-
if (f.dur_ms)
|
|
1635
|
-
parts.push(`dur=${f.dur_ms}ms`);
|
|
1636
|
-
if (f.process_name)
|
|
1637
|
-
parts.push(`proc=${f.process_name}`);
|
|
1638
|
-
lines.push(`- ${parts.join(', ')}`);
|
|
1639
|
-
}
|
|
1640
|
-
}
|
|
1641
|
-
const sessions = entityStore.getAllSessions?.() || [];
|
|
1642
|
-
if (sessions.length > 0) {
|
|
1643
|
-
lines.push(`**滑动会话 (${sessions.length})**:`);
|
|
1644
|
-
for (const s of sessions.slice(0, 8)) {
|
|
1645
|
-
const parts = [`session_id=${s.session_id}`];
|
|
1646
|
-
if (s.start_ts)
|
|
1647
|
-
parts.push(`ts=${s.start_ts}`);
|
|
1648
|
-
if (s.jank_count)
|
|
1649
|
-
parts.push(`janks=${s.jank_count}`);
|
|
1650
|
-
if (s.process_name)
|
|
1651
|
-
parts.push(`proc=${s.process_name}`);
|
|
1652
|
-
lines.push(`- ${parts.join(', ')}`);
|
|
1653
|
-
}
|
|
1654
|
-
}
|
|
1655
|
-
return lines.length > 0 ? lines.join('\n') : undefined;
|
|
1656
|
-
}
|
|
1657
|
-
catch {
|
|
1658
|
-
return undefined;
|
|
1659
|
-
}
|
|
1648
|
+
return (0, runtimeCommon_1.buildEntityContext)(entityStore);
|
|
1660
1649
|
}
|
|
1661
1650
|
toProtocolHypothesis(h) {
|
|
1662
|
-
|
|
1663
|
-
formed: 'proposed',
|
|
1664
|
-
confirmed: 'confirmed',
|
|
1665
|
-
rejected: 'rejected',
|
|
1666
|
-
};
|
|
1667
|
-
const confidenceMap = { formed: 0.5, confirmed: 0.85, rejected: 0.1 };
|
|
1668
|
-
return {
|
|
1669
|
-
id: h.id,
|
|
1670
|
-
description: h.statement,
|
|
1671
|
-
status: statusMap[h.status] || 'proposed',
|
|
1672
|
-
confidence: confidenceMap[h.status] ?? 0.5,
|
|
1673
|
-
supportingEvidence: h.evidence && h.status === 'confirmed'
|
|
1674
|
-
? [{ id: `${h.id}-ev`, type: 'observation', description: h.evidence, source: 'openai', strength: 0.8 }]
|
|
1675
|
-
: [],
|
|
1676
|
-
contradictingEvidence: h.evidence && h.status === 'rejected'
|
|
1677
|
-
? [{ id: `${h.id}-ev`, type: 'observation', description: h.evidence, source: 'openai', strength: 0.8 }]
|
|
1678
|
-
: [],
|
|
1679
|
-
proposedBy: 'openai',
|
|
1680
|
-
relevantAgents: ['openai'],
|
|
1681
|
-
createdAt: h.formedAt,
|
|
1682
|
-
updatedAt: h.resolvedAt || h.formedAt,
|
|
1683
|
-
};
|
|
1651
|
+
return (0, runtimeCommon_1.toProtocolHypothesis)(h, 'openai');
|
|
1684
1652
|
}
|
|
1685
1653
|
emitUpdate(update) {
|
|
1686
1654
|
this.emit('update', update);
|