@gracker/smartperfetto 1.0.15 → 1.0.17
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/agents/base/baseAgent.d.ts.map +1 -1
- package/dist/agent/agents/base/baseAgent.js +5 -1
- package/dist/agent/agents/base/baseAgent.js.map +1 -1
- package/dist/agent/context/enhancedSessionContext.d.ts +5 -0
- package/dist/agent/context/enhancedSessionContext.d.ts.map +1 -1
- package/dist/agent/context/enhancedSessionContext.js +13 -0
- package/dist/agent/context/enhancedSessionContext.js.map +1 -1
- package/dist/agent/core/conclusionContract.d.ts +23 -1
- package/dist/agent/core/conclusionContract.d.ts.map +1 -1
- package/dist/agent/core/conclusionGenerator.d.ts.map +1 -1
- package/dist/agent/core/conclusionGenerator.js +223 -27
- package/dist/agent/core/conclusionGenerator.js.map +1 -1
- package/dist/agent/core/executors/directSkillExecutor.d.ts.map +1 -1
- package/dist/agent/core/executors/directSkillExecutor.js +6 -12
- package/dist/agent/core/executors/directSkillExecutor.js.map +1 -1
- package/dist/agent/core/orchestratorTypes.d.ts +6 -0
- package/dist/agent/core/orchestratorTypes.d.ts.map +1 -1
- package/dist/agent/core/orchestratorTypes.js.map +1 -1
- package/dist/agent/experts/crossDomain/moduleExpertInvoker.d.ts.map +1 -1
- package/dist/agent/experts/crossDomain/moduleExpertInvoker.js +4 -1
- package/dist/agent/experts/crossDomain/moduleExpertInvoker.js.map +1 -1
- package/dist/agent/scene/sceneStage1Runner.d.ts +1 -1
- package/dist/agent/scene/sceneStage1Runner.d.ts.map +1 -1
- package/dist/agent/scene/sceneStage1Runner.js +1 -1
- package/dist/agent/scene/sceneStage1Runner.js.map +1 -1
- package/dist/agent/scene/sceneStoryService.d.ts +1 -1
- package/dist/agent/scene/sceneStoryService.d.ts.map +1 -1
- package/dist/agent/scene/sceneStoryService.js +4 -1
- package/dist/agent/scene/sceneStoryService.js.map +1 -1
- package/dist/agent/types/agentProtocol.d.ts.map +1 -1
- package/dist/agent/types/agentProtocol.js +4 -1
- package/dist/agent/types/agentProtocol.js.map +1 -1
- package/dist/agent/types.d.ts +7 -0
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/agentOpenAI/openAiConfig.d.ts +2 -0
- package/dist/agentOpenAI/openAiConfig.d.ts.map +1 -1
- package/dist/agentOpenAI/openAiConfig.js +3 -0
- package/dist/agentOpenAI/openAiConfig.js.map +1 -1
- package/dist/agentOpenAI/openAiRuntime.d.ts +8 -0
- package/dist/agentOpenAI/openAiRuntime.d.ts.map +1 -1
- package/dist/agentOpenAI/openAiRuntime.js +293 -58
- package/dist/agentOpenAI/openAiRuntime.js.map +1 -1
- package/dist/agentRuntime/runtimeHealth.d.ts +1 -0
- package/dist/agentRuntime/runtimeHealth.d.ts.map +1 -1
- package/dist/agentv3/artifactStore.d.ts +5 -0
- package/dist/agentv3/artifactStore.d.ts.map +1 -1
- package/dist/agentv3/artifactStore.js +3 -0
- package/dist/agentv3/artifactStore.js.map +1 -1
- package/dist/agentv3/claudeMcpServer.d.ts.map +1 -1
- package/dist/agentv3/claudeMcpServer.js +125 -86
- package/dist/agentv3/claudeMcpServer.js.map +1 -1
- package/dist/agentv3/claudeRuntime.d.ts.map +1 -1
- package/dist/agentv3/claudeRuntime.js +147 -65
- package/dist/agentv3/claudeRuntime.js.map +1 -1
- package/dist/agentv3/claudeSseBridge.d.ts +6 -0
- package/dist/agentv3/claudeSseBridge.d.ts.map +1 -1
- package/dist/agentv3/claudeSseBridge.js +1 -0
- package/dist/agentv3/claudeSseBridge.js.map +1 -1
- package/dist/agentv3/sessionStateSnapshot.d.ts +23 -0
- package/dist/agentv3/sessionStateSnapshot.d.ts.map +1 -1
- package/dist/assistant/application/agentAnalyzeSessionService.d.ts +6 -0
- package/dist/assistant/application/agentAnalyzeSessionService.d.ts.map +1 -1
- package/dist/assistant/application/agentAnalyzeSessionService.js +9 -3
- package/dist/assistant/application/agentAnalyzeSessionService.js.map +1 -1
- package/dist/assistant/application/assistantApplicationService.d.ts.map +1 -1
- package/dist/assistant/application/assistantApplicationService.js +3 -1
- package/dist/assistant/application/assistantApplicationService.js.map +1 -1
- package/dist/cli-user/commands/report.js +64 -0
- package/dist/cli-user/commands/report.js.map +1 -1
- package/dist/cli-user/io/paths.d.ts +3 -0
- package/dist/cli-user/io/paths.d.ts.map +1 -1
- package/dist/cli-user/io/paths.js +6 -0
- package/dist/cli-user/io/paths.js.map +1 -1
- package/dist/cli-user/io/sessionStore.d.ts +1 -0
- package/dist/cli-user/io/sessionStore.d.ts.map +1 -1
- package/dist/cli-user/io/sessionStore.js +5 -0
- package/dist/cli-user/io/sessionStore.js.map +1 -1
- package/dist/cli-user/repl/renderer.d.ts +8 -0
- package/dist/cli-user/repl/renderer.d.ts.map +1 -1
- package/dist/cli-user/repl/renderer.js.map +1 -1
- package/dist/cli-user/services/cliAnalyzeService.d.ts +3 -0
- package/dist/cli-user/services/cliAnalyzeService.d.ts.map +1 -1
- package/dist/cli-user/services/cliAnalyzeService.js +103 -1
- package/dist/cli-user/services/cliAnalyzeService.js.map +1 -1
- package/dist/cli-user/services/turnPersistence.d.ts +0 -10
- package/dist/cli-user/services/turnPersistence.d.ts.map +1 -1
- package/dist/cli-user/services/turnPersistence.js +62 -0
- package/dist/cli-user/services/turnPersistence.js.map +1 -1
- package/dist/routes/agentReportRoutes.d.ts +1 -0
- package/dist/routes/agentReportRoutes.d.ts.map +1 -1
- package/dist/routes/agentReportRoutes.js +13 -2
- package/dist/routes/agentReportRoutes.js.map +1 -1
- package/dist/routes/agentResumeRoutes.d.ts.map +1 -1
- package/dist/routes/agentResumeRoutes.js +51 -5
- package/dist/routes/agentResumeRoutes.js.map +1 -1
- package/dist/routes/agentRoutes.d.ts.map +1 -1
- package/dist/routes/agentRoutes.js +524 -130
- package/dist/routes/agentRoutes.js.map +1 -1
- package/dist/scripts/verifyAgentSseScrolling.js +142 -2
- package/dist/scripts/verifyAgentSseScrolling.js.map +1 -1
- package/dist/services/agentEventStore.d.ts.map +1 -1
- package/dist/services/agentEventStore.js +13 -3
- package/dist/services/agentEventStore.js.map +1 -1
- package/dist/services/agentReportData.d.ts +3 -0
- package/dist/services/agentReportData.d.ts.map +1 -1
- package/dist/services/agentReportData.js.map +1 -1
- package/dist/services/agentResultNormalizer.d.ts +15 -3
- package/dist/services/agentResultNormalizer.d.ts.map +1 -1
- package/dist/services/agentResultNormalizer.js +344 -6
- package/dist/services/agentResultNormalizer.js.map +1 -1
- package/dist/services/analysisResultSnapshotPipeline.d.ts +3 -0
- package/dist/services/analysisResultSnapshotPipeline.d.ts.map +1 -1
- package/dist/services/analysisResultSnapshotPipeline.js +3 -0
- package/dist/services/analysisResultSnapshotPipeline.js.map +1 -1
- package/dist/services/analysisResultSnapshotStore.d.ts.map +1 -1
- package/dist/services/analysisResultSnapshotStore.js +34 -2
- package/dist/services/analysisResultSnapshotStore.js.map +1 -1
- package/dist/services/enterpriseSchema.d.ts.map +1 -1
- package/dist/services/enterpriseSchema.js +11 -0
- package/dist/services/enterpriseSchema.js.map +1 -1
- package/dist/services/evidence/evidenceContractBuilder.d.ts +11 -0
- package/dist/services/evidence/evidenceContractBuilder.d.ts.map +1 -0
- package/dist/services/evidence/evidenceContractBuilder.js +546 -0
- package/dist/services/evidence/evidenceContractBuilder.js.map +1 -0
- package/dist/services/finalResultQualityGate.d.ts +18 -0
- package/dist/services/finalResultQualityGate.d.ts.map +1 -0
- package/dist/services/finalResultQualityGate.js +283 -0
- package/dist/services/finalResultQualityGate.js.map +1 -0
- package/dist/services/htmlReportGenerator.d.ts +8 -1
- package/dist/services/htmlReportGenerator.d.ts.map +1 -1
- package/dist/services/htmlReportGenerator.js +129 -42
- package/dist/services/htmlReportGenerator.js.map +1 -1
- package/dist/services/persistAgentSession.d.ts +2 -0
- package/dist/services/persistAgentSession.d.ts.map +1 -1
- package/dist/services/persistAgentSession.js +17 -1
- package/dist/services/persistAgentSession.js.map +1 -1
- package/dist/services/processIdentity/identityContractMapper.d.ts +14 -0
- package/dist/services/processIdentity/identityContractMapper.d.ts.map +1 -0
- package/dist/services/processIdentity/identityContractMapper.js +135 -0
- package/dist/services/processIdentity/identityContractMapper.js.map +1 -0
- package/dist/services/processIdentity/types.d.ts +5 -0
- package/dist/services/processIdentity/types.d.ts.map +1 -1
- package/dist/services/processIdentity/types.js.map +1 -1
- package/dist/services/skillEngine/skillExecutor.d.ts +14 -2
- package/dist/services/skillEngine/skillExecutor.d.ts.map +1 -1
- package/dist/services/skillEngine/skillExecutor.js +133 -13
- package/dist/services/skillEngine/skillExecutor.js.map +1 -1
- package/dist/services/skillEngine/types.d.ts +2 -0
- package/dist/services/skillEngine/types.d.ts.map +1 -1
- package/dist/services/verifier/claimVerificationRunner.d.ts +20 -0
- package/dist/services/verifier/claimVerificationRunner.d.ts.map +1 -0
- package/dist/services/verifier/claimVerificationRunner.js +88 -0
- package/dist/services/verifier/claimVerificationRunner.js.map +1 -0
- package/dist/services/verifier/deterministicClaimVerifier.d.ts +8 -0
- package/dist/services/verifier/deterministicClaimVerifier.d.ts.map +1 -0
- package/dist/services/verifier/deterministicClaimVerifier.js +178 -0
- package/dist/services/verifier/deterministicClaimVerifier.js.map +1 -0
- package/dist/types/claimVerification.d.ts +38 -0
- package/dist/types/claimVerification.d.ts.map +1 -0
- package/dist/types/claimVerification.js +6 -0
- package/dist/types/claimVerification.js.map +1 -0
- package/dist/types/dataContract.d.ts +32 -0
- package/dist/types/dataContract.d.ts.map +1 -1
- package/dist/types/dataContract.js +7 -0
- package/dist/types/dataContract.js.map +1 -1
- package/dist/types/evidenceContract.d.ts +100 -0
- package/dist/types/evidenceContract.d.ts.map +1 -0
- package/dist/types/evidenceContract.js +6 -0
- package/dist/types/evidenceContract.js.map +1 -0
- package/dist/types/identityContract.d.ts +57 -0
- package/dist/types/identityContract.d.ts.map +1 -0
- package/dist/types/identityContract.js +6 -0
- package/dist/types/identityContract.js.map +1 -0
- package/dist/types/multiTraceComparison.d.ts +3 -0
- package/dist/types/multiTraceComparison.d.ts.map +1 -1
- package/package.json +3 -2
- package/skills/atomic/process_identity_resolver.skill.yaml +130 -1
- package/skills/atomic/process_slice_cpu_hotspots.skill.yaml +321 -0
- package/skills/atomic/startup_slow_reasons.skill.yaml +102 -17
- package/skills/composite/startup_analysis.skill.yaml +16 -0
- package/strategies/anr.strategy.md +2 -2
- package/strategies/game.strategy.md +1 -1
- package/strategies/general.strategy.md +1 -1
- package/strategies/prompt-openai-final-report-continuation-en.template.md +12 -0
- package/strategies/prompt-openai-final-report-continuation-zh.template.md +12 -0
- package/strategies/prompt-output-format.template.md +1 -1
- package/strategies/scrolling.strategy.md +1 -0
- package/strategies/startup.strategy.md +4 -1
|
@@ -53,6 +53,7 @@ const htmlReportGenerator_1 = require("../services/htmlReportGenerator");
|
|
|
53
53
|
const agentReportData_1 = require("../services/agentReportData");
|
|
54
54
|
const persistAgentSession_1 = require("../services/persistAgentSession");
|
|
55
55
|
const comparisonAppendixService_1 = require("../services/comparisonAppendixService");
|
|
56
|
+
const finalResultQualityGate_1 = require("../services/finalResultQualityGate");
|
|
56
57
|
const agentResultNormalizer_1 = require("../services/agentResultNormalizer");
|
|
57
58
|
const reportRoutes_1 = require("./reportRoutes");
|
|
58
59
|
const sessionPersistenceService_1 = require("../services/sessionPersistenceService");
|
|
@@ -92,6 +93,7 @@ const analysisRunStore_1 = require("../services/analysisRunStore");
|
|
|
92
93
|
const agentAnalyzeSessionService_1 = require("../assistant/application/agentAnalyzeSessionService");
|
|
93
94
|
const assistantResultContract_1 = require("../assistant/contracts/assistantResultContract");
|
|
94
95
|
const analysisResultSnapshotPipeline_1 = require("../services/analysisResultSnapshotPipeline");
|
|
96
|
+
const claimVerificationRunner_1 = require("../services/verifier/claimVerificationRunner");
|
|
95
97
|
// DataEnvelope types for v2.0 data contract
|
|
96
98
|
const dataContract_1 = require("../types/dataContract");
|
|
97
99
|
const skillExecutor_1 = require("../services/skillEngine/skillExecutor");
|
|
@@ -100,6 +102,7 @@ const feedbackEnricher_1 = require("../agentv3/selfImprove/feedbackEnricher");
|
|
|
100
102
|
const toolNarration_1 = require("../agentv3/toolNarration");
|
|
101
103
|
const analysisPatternMemory_1 = require("../agentv3/analysisPatternMemory");
|
|
102
104
|
const runtimePaths_1 = require("../runtimePaths");
|
|
105
|
+
const COMPLETED_ANALYSIS_SSE_EVENTS_QUALITY_GATE_VERSION = 1;
|
|
103
106
|
const router = express_1.default.Router();
|
|
104
107
|
const REQUEST_ID_HEADER = 'x-request-id';
|
|
105
108
|
const MAX_REQUEST_ID_LENGTH = 128;
|
|
@@ -363,6 +366,61 @@ function persistBufferedAgentEvent(session, event) {
|
|
|
363
366
|
});
|
|
364
367
|
}
|
|
365
368
|
}
|
|
369
|
+
function sanitizePersistedAnalysisCompletedEvent(session, event) {
|
|
370
|
+
if (event.eventType !== 'analysis_completed')
|
|
371
|
+
return event;
|
|
372
|
+
let payload;
|
|
373
|
+
try {
|
|
374
|
+
payload = JSON.parse(event.eventData || '{}');
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
return event;
|
|
378
|
+
}
|
|
379
|
+
const data = payload?.data && typeof payload.data === 'object'
|
|
380
|
+
? payload.data
|
|
381
|
+
: payload;
|
|
382
|
+
const conclusion = typeof data?.conclusion === 'string'
|
|
383
|
+
? data.conclusion
|
|
384
|
+
: typeof data?.answer === 'string'
|
|
385
|
+
? data.answer
|
|
386
|
+
: '';
|
|
387
|
+
if (!conclusion.trim())
|
|
388
|
+
return event;
|
|
389
|
+
const result = {
|
|
390
|
+
sessionId: session.sessionId,
|
|
391
|
+
success: data?.success !== false,
|
|
392
|
+
findings: Array.isArray(data?.findings) ? data.findings : [],
|
|
393
|
+
hypotheses: Array.isArray(data?.hypotheses) ? data.hypotheses : [],
|
|
394
|
+
conclusion,
|
|
395
|
+
confidence: typeof data?.confidence === 'number' ? data.confidence : 0.5,
|
|
396
|
+
rounds: typeof data?.rounds === 'number' ? data.rounds : 1,
|
|
397
|
+
totalDurationMs: typeof data?.totalDurationMs === 'number' ? data.totalDurationMs : 0,
|
|
398
|
+
partial: data?.partial === true ? true : undefined,
|
|
399
|
+
terminationReason: data?.terminationReason,
|
|
400
|
+
terminationMessage: data?.terminationMessage,
|
|
401
|
+
conclusionContract: data?.conclusionContract,
|
|
402
|
+
claimSupport: data?.claimSupport,
|
|
403
|
+
claimVerificationResult: data?.claimVerificationResult,
|
|
404
|
+
identityResolutions: data?.identityResolutions,
|
|
405
|
+
};
|
|
406
|
+
const issue = (0, finalResultQualityGate_1.applyFinalResultQualityGate)({ result, query: session.query });
|
|
407
|
+
if (!issue)
|
|
408
|
+
return event;
|
|
409
|
+
const nextData = {
|
|
410
|
+
...data,
|
|
411
|
+
confidence: result.confidence,
|
|
412
|
+
partial: result.partial,
|
|
413
|
+
terminationReason: result.terminationReason,
|
|
414
|
+
terminationMessage: result.terminationMessage,
|
|
415
|
+
};
|
|
416
|
+
const nextPayload = payload?.data && typeof payload.data === 'object'
|
|
417
|
+
? { ...payload, data: nextData }
|
|
418
|
+
: { ...payload, ...nextData };
|
|
419
|
+
return {
|
|
420
|
+
...event,
|
|
421
|
+
eventData: JSON.stringify(nextPayload),
|
|
422
|
+
};
|
|
423
|
+
}
|
|
366
424
|
function replayPersistedAgentEvents(session, res, lastEventId) {
|
|
367
425
|
const scope = agentEventScopeFromSession(session);
|
|
368
426
|
if (!scope)
|
|
@@ -386,9 +444,10 @@ function replayPersistedAgentEvents(session, res, lastEventId) {
|
|
|
386
444
|
let lastCursor = lastEventId;
|
|
387
445
|
for (const event of events) {
|
|
388
446
|
try {
|
|
447
|
+
const replayEvent = sanitizePersistedAnalysisCompletedEvent(session, event);
|
|
389
448
|
res.write(`id: ${event.cursor}\n`);
|
|
390
|
-
res.write(`event: ${
|
|
391
|
-
res.write(`data: ${
|
|
449
|
+
res.write(`event: ${replayEvent.eventType}\n`);
|
|
450
|
+
res.write(`data: ${replayEvent.eventData}\n\n`);
|
|
392
451
|
replayed++;
|
|
393
452
|
lastCursor = event.cursor;
|
|
394
453
|
if (sessionSseReplay_1.TERMINAL_SSE_EVENT_TYPES.has(event.eventType)) {
|
|
@@ -412,6 +471,52 @@ function sendReplayableSessionEvent(session, res, eventType, payload) {
|
|
|
412
471
|
streamProjector.sendEvent(res, eventType, payload, event.seqId);
|
|
413
472
|
return event.seqId;
|
|
414
473
|
}
|
|
474
|
+
function appendAndPersistReplayableSessionEvent(session, eventType, payload) {
|
|
475
|
+
const event = (0, sessionSseReplay_1.appendReplayableSseEvent)(session, eventType, payload);
|
|
476
|
+
persistBufferedAgentEvent(session, {
|
|
477
|
+
cursor: event.seqId,
|
|
478
|
+
eventType: event.eventType,
|
|
479
|
+
eventData: event.eventData,
|
|
480
|
+
createdAt: Date.now(),
|
|
481
|
+
});
|
|
482
|
+
return event;
|
|
483
|
+
}
|
|
484
|
+
function writeBufferedSessionEvent(res, event) {
|
|
485
|
+
res.write(`id: ${event.seqId}\n`);
|
|
486
|
+
res.write(`event: ${event.eventType}\n`);
|
|
487
|
+
res.write(`data: ${event.eventData}\n\n`);
|
|
488
|
+
}
|
|
489
|
+
function loadPersistedCompletedAnalysisSseEvents(session) {
|
|
490
|
+
const scope = agentEventScopeFromSession(session);
|
|
491
|
+
if (!scope)
|
|
492
|
+
return [];
|
|
493
|
+
const events = (0, agentEventStore_1.listSerializedAgentEventsAfter)(scope, scope.runId, 0)
|
|
494
|
+
.filter(event => event.eventType === 'snapshot_created' ||
|
|
495
|
+
event.eventType === 'analysis_completed' ||
|
|
496
|
+
event.eventType === 'scene_reconstruction_completed' ||
|
|
497
|
+
event.eventType === 'end')
|
|
498
|
+
.map(event => sanitizePersistedAnalysisCompletedEvent(session, event))
|
|
499
|
+
.map(event => ({
|
|
500
|
+
seqId: event.cursor,
|
|
501
|
+
eventType: event.eventType,
|
|
502
|
+
eventData: event.eventData,
|
|
503
|
+
}));
|
|
504
|
+
if (!events.some(event => event.eventType === 'analysis_completed') ||
|
|
505
|
+
!events.some(event => event.eventType === 'end')) {
|
|
506
|
+
return [];
|
|
507
|
+
}
|
|
508
|
+
session.sseEventSeq = Math.max(session.sseEventSeq || 0, ...events.map(event => event.seqId));
|
|
509
|
+
const existing = new Set(session.sseEventBuffer.map(event => `${event.seqId}:${event.eventType}`));
|
|
510
|
+
for (const event of events) {
|
|
511
|
+
const key = `${event.seqId}:${event.eventType}`;
|
|
512
|
+
if (!existing.has(key))
|
|
513
|
+
session.sseEventBuffer.push(event);
|
|
514
|
+
}
|
|
515
|
+
if (session.sseEventBuffer.length > streamProjector_1.SSE_RING_BUFFER_SIZE) {
|
|
516
|
+
session.sseEventBuffer.splice(0, session.sseEventBuffer.length - streamProjector_1.SSE_RING_BUFFER_SIZE);
|
|
517
|
+
}
|
|
518
|
+
return events;
|
|
519
|
+
}
|
|
415
520
|
function resolveSessionContextForReview(sessionId) {
|
|
416
521
|
const activeSession = assistantAppService.getSession(sessionId);
|
|
417
522
|
if (activeSession) {
|
|
@@ -530,12 +635,44 @@ function buildTurnSeverityCounts(turn) {
|
|
|
530
635
|
function toJsonSafe(value) {
|
|
531
636
|
return JSON.parse(JSON.stringify(value, (_key, v) => (typeof v === 'bigint' ? v.toString() : v)));
|
|
532
637
|
}
|
|
638
|
+
function buildDisplayTurnResult(turn) {
|
|
639
|
+
if (!turn.result)
|
|
640
|
+
return turn.result;
|
|
641
|
+
const message = typeof turn.result.message === 'string' ? turn.result.message : '';
|
|
642
|
+
const resultForGate = {
|
|
643
|
+
sessionId: turn.id,
|
|
644
|
+
success: turn.result.success !== false,
|
|
645
|
+
findings: Array.isArray(turn.findings) ? turn.findings : [],
|
|
646
|
+
hypotheses: [],
|
|
647
|
+
conclusion: message,
|
|
648
|
+
confidence: typeof turn.result.confidence === 'number' ? turn.result.confidence : 0.5,
|
|
649
|
+
rounds: 1,
|
|
650
|
+
totalDurationMs: 0,
|
|
651
|
+
partial: turn.result.partial,
|
|
652
|
+
terminationReason: turn.result.terminationReason,
|
|
653
|
+
terminationMessage: turn.result.terminationMessage,
|
|
654
|
+
conclusionContract: turn.result.conclusionContract,
|
|
655
|
+
claimSupport: turn.result.claimSupport,
|
|
656
|
+
claimVerificationResult: turn.result.claimVerificationResult,
|
|
657
|
+
identityResolutions: turn.result.identityResolutions,
|
|
658
|
+
};
|
|
659
|
+
(0, finalResultQualityGate_1.applyFinalResultQualityGate)({ result: resultForGate, query: turn.query });
|
|
660
|
+
return {
|
|
661
|
+
...turn.result,
|
|
662
|
+
message: resultForGate.conclusion,
|
|
663
|
+
confidence: resultForGate.confidence,
|
|
664
|
+
partial: resultForGate.partial,
|
|
665
|
+
terminationReason: resultForGate.terminationReason,
|
|
666
|
+
terminationMessage: resultForGate.terminationMessage,
|
|
667
|
+
};
|
|
668
|
+
}
|
|
533
669
|
function buildTurnSummary(turn) {
|
|
534
|
-
const
|
|
535
|
-
|
|
670
|
+
const displayResult = buildDisplayTurnResult(turn);
|
|
671
|
+
const confidence = typeof displayResult?.confidence === 'number'
|
|
672
|
+
? displayResult.confidence
|
|
536
673
|
: undefined;
|
|
537
|
-
const sanitizedConclusion = typeof
|
|
538
|
-
? normalizeNarrativeForClient(
|
|
674
|
+
const sanitizedConclusion = typeof displayResult?.message === 'string'
|
|
675
|
+
? normalizeNarrativeForClient(displayResult.message)
|
|
539
676
|
: '';
|
|
540
677
|
const conclusionPreview = sanitizedConclusion
|
|
541
678
|
? sanitizedConclusion.replace(/\s+/g, ' ').slice(0, 240)
|
|
@@ -551,7 +688,10 @@ function buildTurnSummary(turn) {
|
|
|
551
688
|
aspects: Array.isArray(turn.intent?.aspects) ? turn.intent.aspects : [],
|
|
552
689
|
},
|
|
553
690
|
completed: !!turn.completed,
|
|
554
|
-
success: typeof
|
|
691
|
+
success: typeof displayResult?.success === 'boolean' ? displayResult.success : null,
|
|
692
|
+
partial: displayResult?.partial === true,
|
|
693
|
+
terminationReason: displayResult?.terminationReason,
|
|
694
|
+
terminationMessage: displayResult?.terminationMessage,
|
|
555
695
|
confidence,
|
|
556
696
|
findingCount: Array.isArray(turn.findings) ? turn.findings.length : 0,
|
|
557
697
|
severityCounts: buildTurnSeverityCounts(turn),
|
|
@@ -560,15 +700,16 @@ function buildTurnSummary(turn) {
|
|
|
560
700
|
}
|
|
561
701
|
function buildTurnDetail(turn) {
|
|
562
702
|
const summary = buildTurnSummary(turn);
|
|
703
|
+
const displayResult = buildDisplayTurnResult(turn);
|
|
563
704
|
return {
|
|
564
705
|
...summary,
|
|
565
706
|
intent: toJsonSafe(turn.intent),
|
|
566
|
-
result:
|
|
707
|
+
result: displayResult
|
|
567
708
|
? toJsonSafe({
|
|
568
|
-
...
|
|
569
|
-
message: typeof
|
|
570
|
-
? normalizeNarrativeForClient(
|
|
571
|
-
:
|
|
709
|
+
...displayResult,
|
|
710
|
+
message: typeof displayResult.message === 'string'
|
|
711
|
+
? normalizeNarrativeForClient(displayResult.message)
|
|
712
|
+
: displayResult.message,
|
|
572
713
|
})
|
|
573
714
|
: null,
|
|
574
715
|
findings: toJsonSafe(turn.findings || []),
|
|
@@ -607,10 +748,38 @@ function buildRecoveredResultFromContext(sessionId, context) {
|
|
|
607
748
|
partial: turn.result.partial,
|
|
608
749
|
terminationReason: turn.result.terminationReason,
|
|
609
750
|
terminationMessage: turn.result.terminationMessage,
|
|
751
|
+
conclusionContract: turn.result.conclusionContract,
|
|
752
|
+
claimSupport: turn.result.claimSupport,
|
|
753
|
+
claimVerificationResult: turn.result.claimVerificationResult,
|
|
754
|
+
identityResolutions: turn.result.identityResolutions,
|
|
610
755
|
};
|
|
611
756
|
}
|
|
757
|
+
function annotateRecoveredResultQuality(sessionId, session, result, query) {
|
|
758
|
+
const issue = (0, finalResultQualityGate_1.applyFinalResultQualityGate)({
|
|
759
|
+
result,
|
|
760
|
+
query: query || session.query,
|
|
761
|
+
});
|
|
762
|
+
if (!issue)
|
|
763
|
+
return;
|
|
764
|
+
const context = enhancedSessionContext_1.sessionContextManager.get(sessionId, session.traceId) ||
|
|
765
|
+
enhancedSessionContext_1.sessionContextManager.get(sessionId);
|
|
766
|
+
context?.annotateLatestCompletedTurn({
|
|
767
|
+
success: result.success,
|
|
768
|
+
findings: result.findings,
|
|
769
|
+
message: result.conclusion,
|
|
770
|
+
confidence: result.confidence,
|
|
771
|
+
partial: result.partial,
|
|
772
|
+
terminationReason: result.terminationReason,
|
|
773
|
+
terminationMessage: result.terminationMessage,
|
|
774
|
+
conclusionContract: result.conclusionContract,
|
|
775
|
+
claimSupport: result.claimSupport,
|
|
776
|
+
claimVerificationResult: result.claimVerificationResult,
|
|
777
|
+
identityResolutions: result.identityResolutions,
|
|
778
|
+
});
|
|
779
|
+
}
|
|
612
780
|
function recoverResultForSessionIfNeeded(sessionId, session) {
|
|
613
781
|
if (session.result) {
|
|
782
|
+
annotateRecoveredResultQuality(sessionId, session, session.result);
|
|
614
783
|
return session.result;
|
|
615
784
|
}
|
|
616
785
|
const resolved = resolveSessionContextForReview(sessionId);
|
|
@@ -627,6 +796,7 @@ function recoverResultForSessionIfNeeded(sessionId, session) {
|
|
|
627
796
|
if (latestTurn?.query) {
|
|
628
797
|
session.query = latestTurn.query;
|
|
629
798
|
}
|
|
799
|
+
annotateRecoveredResultQuality(sessionId, session, recovered, latestTurn?.query);
|
|
630
800
|
return recovered;
|
|
631
801
|
}
|
|
632
802
|
function buildFallbackIntentFromQuery(query) {
|
|
@@ -1146,6 +1316,15 @@ function handleSessionStream(req, res, sessionId) {
|
|
|
1146
1316
|
timestamp: Date.now(),
|
|
1147
1317
|
...buildStreamObservability(session),
|
|
1148
1318
|
});
|
|
1319
|
+
if (lastEventId !== null &&
|
|
1320
|
+
(session.status === 'completed' || session.status === 'quota_exceeded')) {
|
|
1321
|
+
recoverResultForSessionIfNeeded(sessionId, session);
|
|
1322
|
+
if (session.result) {
|
|
1323
|
+
sendAgentDrivenResult(res, session);
|
|
1324
|
+
res.end();
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1149
1328
|
let ringReplayAfter = lastEventId;
|
|
1150
1329
|
if (lastEventId !== null) {
|
|
1151
1330
|
const persistedReplay = replayPersistedAgentEvents(session, res, lastEventId);
|
|
@@ -1180,11 +1359,8 @@ function handleSessionStream(req, res, sessionId) {
|
|
|
1180
1359
|
recoverResultForSessionIfNeeded(sessionId, session);
|
|
1181
1360
|
if (session.result) {
|
|
1182
1361
|
sendAgentDrivenResult(res, session);
|
|
1183
|
-
sendReplayableSessionEvent(session, res, 'end', {
|
|
1184
|
-
timestamp: Date.now(),
|
|
1185
|
-
...buildStreamObservability(session),
|
|
1186
|
-
});
|
|
1187
1362
|
res.end();
|
|
1363
|
+
assistantAppService.removeSseClient(sessionId, res);
|
|
1188
1364
|
return;
|
|
1189
1365
|
}
|
|
1190
1366
|
}
|
|
@@ -1260,22 +1436,41 @@ router.get('/:sessionId/status', (req, res) => {
|
|
|
1260
1436
|
query: session.query,
|
|
1261
1437
|
findings: recoveredResult.findings,
|
|
1262
1438
|
});
|
|
1263
|
-
const conclusionContract = recoveredResult.
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1439
|
+
const conclusionContract = (0, agentResultNormalizer_1.deriveEvidenceBackedConclusionContractForNarrative)(recoveredResult.conclusion, session.dataEnvelopes || [], {
|
|
1440
|
+
existingContract: recoveredResult.conclusionContract,
|
|
1441
|
+
mode: recoveredResult.rounds > 1 ? 'focused_answer' : 'initial_report',
|
|
1442
|
+
sceneId: sceneIdHint,
|
|
1443
|
+
}) ||
|
|
1268
1444
|
undefined;
|
|
1445
|
+
const qualityArtifacts = recoveredResult.claimSupport &&
|
|
1446
|
+
recoveredResult.claimVerificationResult &&
|
|
1447
|
+
recoveredResult.identityResolutions
|
|
1448
|
+
? {
|
|
1449
|
+
claimSupport: recoveredResult.claimSupport,
|
|
1450
|
+
claimVerificationResult: recoveredResult.claimVerificationResult,
|
|
1451
|
+
identityResolutions: recoveredResult.identityResolutions,
|
|
1452
|
+
}
|
|
1453
|
+
: ensureAnalysisQualityArtifacts(session, conclusionContract, recoveredResult);
|
|
1454
|
+
const completedPayload = ensureCompletedAnalysisResultPayload(session);
|
|
1455
|
+
const finalArtifacts = completedPayload?.finalArtifacts;
|
|
1456
|
+
const normalizedCompletedConclusion = completedPayload?.normalizedConclusion || conclusion;
|
|
1457
|
+
const normalizedCompletedContract = completedPayload?.normalizedConclusionContract || conclusionContract;
|
|
1269
1458
|
response.result = {
|
|
1270
|
-
answer:
|
|
1271
|
-
conclusion,
|
|
1272
|
-
conclusionContract,
|
|
1459
|
+
answer: normalizedCompletedConclusion,
|
|
1460
|
+
conclusion: normalizedCompletedConclusion,
|
|
1461
|
+
conclusionContract: normalizedCompletedContract,
|
|
1462
|
+
claimSupport: qualityArtifacts.claimSupport,
|
|
1463
|
+
claimVerificationResult: qualityArtifacts.claimVerificationResult,
|
|
1464
|
+
identityResolutions: qualityArtifacts.identityResolutions,
|
|
1273
1465
|
confidence: recoveredResult.confidence,
|
|
1274
1466
|
totalDurationMs: recoveredResult.totalDurationMs,
|
|
1275
1467
|
rounds: recoveredResult.rounds,
|
|
1276
1468
|
partial: recoveredResult.partial,
|
|
1277
1469
|
terminationReason: recoveredResult.terminationReason,
|
|
1278
1470
|
terminationMessage: recoveredResult.terminationMessage,
|
|
1471
|
+
reportUrl: finalArtifacts?.reportUrl,
|
|
1472
|
+
reportError: finalArtifacts?.reportError,
|
|
1473
|
+
resultSnapshotId: finalArtifacts?.resultSnapshotId,
|
|
1279
1474
|
findings: recoveredResult.findings,
|
|
1280
1475
|
findingsCount: recoveredResult.findings.length,
|
|
1281
1476
|
resultContract,
|
|
@@ -2233,6 +2428,7 @@ async function detectScenesQuick(traceProcessorService, traceId) {
|
|
|
2233
2428
|
normalizeNarrativeForClient,
|
|
2234
2429
|
buildClientFindings,
|
|
2235
2430
|
buildSessionResultContract,
|
|
2431
|
+
getCompletedPayload: ensureCompletedAnalysisResultPayload,
|
|
2236
2432
|
});
|
|
2237
2433
|
// ============================================================================
|
|
2238
2434
|
// Agent-Driven Analysis Helper Functions (Phase 2-4)
|
|
@@ -2311,9 +2507,14 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
|
|
|
2311
2507
|
console.log(`[AgentRoutes.AgentDriven] Received event: ${update.type}`, update.content?.phase);
|
|
2312
2508
|
logger.debug('Stream', `Update: ${update.type}`, update.content);
|
|
2313
2509
|
const normalizedUpdate = augmentConclusionUpdateWithEvidenceIndex(session, normalizeAgentDrivenUpdate(update));
|
|
2314
|
-
//
|
|
2315
|
-
//
|
|
2316
|
-
|
|
2510
|
+
// Final narrative is emitted through analysis_completed after deterministic
|
|
2511
|
+
// evidence/claim verification has run. Suppress early conclusion events so
|
|
2512
|
+
// clients do not render an unverified terminal answer.
|
|
2513
|
+
const shouldBroadcastOriginalUpdate = normalizedUpdate.type !== 'conclusion' &&
|
|
2514
|
+
normalizedUpdate.type !== 'answer_token';
|
|
2515
|
+
if (shouldBroadcastOriginalUpdate) {
|
|
2516
|
+
broadcastToAgentDrivenClients(sessionId, normalizedUpdate);
|
|
2517
|
+
}
|
|
2317
2518
|
// Also derive a conversation_step for the timeline/observability layer.
|
|
2318
2519
|
const conversationStep = buildConversationStepUpdate(session, normalizedUpdate);
|
|
2319
2520
|
if (conversationStep) {
|
|
@@ -2361,7 +2562,7 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
|
|
|
2361
2562
|
// (answer_token, thought, conclusion, etc.) are already broadcast above
|
|
2362
2563
|
// and remapping would cause duplicate delivery to the frontend.
|
|
2363
2564
|
const eventType = mapToAgentDrivenEventType(normalizedUpdate);
|
|
2364
|
-
if (eventType !== normalizedUpdate.type) {
|
|
2565
|
+
if (shouldBroadcastOriginalUpdate && eventType !== normalizedUpdate.type) {
|
|
2365
2566
|
broadcastToAgentDrivenClients(sessionId, {
|
|
2366
2567
|
type: eventType,
|
|
2367
2568
|
content: normalizedUpdate.content,
|
|
@@ -2440,6 +2641,7 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
|
|
|
2440
2641
|
});
|
|
2441
2642
|
console.log('[AgentRoutes.AgentDriven] analyze completed, success:', result.success);
|
|
2442
2643
|
session.result = result;
|
|
2644
|
+
delete session.completedAnalysisFinalArtifacts;
|
|
2443
2645
|
// Accumulate hypotheses across turns (deduplicate by id)
|
|
2444
2646
|
const existingIds = new Set(session.hypotheses.map(h => h.id));
|
|
2445
2647
|
for (const h of result.hypotheses) {
|
|
@@ -2454,10 +2656,6 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
|
|
|
2454
2656
|
}
|
|
2455
2657
|
}
|
|
2456
2658
|
const terminalRunStatus = terminalRunStatusForResult(result);
|
|
2457
|
-
session.status = terminalRunStatus === 'quota_exceeded'
|
|
2458
|
-
? 'quota_exceeded'
|
|
2459
|
-
: result.success ? 'completed' : 'failed';
|
|
2460
|
-
markSessionRunStatus(session, terminalRunStatus);
|
|
2461
2659
|
// Record conclusion in cross-turn history
|
|
2462
2660
|
if (!session.conclusionHistory)
|
|
2463
2661
|
session.conclusionHistory = [];
|
|
@@ -2496,12 +2694,83 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
|
|
|
2496
2694
|
};
|
|
2497
2695
|
}
|
|
2498
2696
|
}
|
|
2697
|
+
if (result.success || result.partial === true) {
|
|
2698
|
+
const sceneIdHint = resolveConclusionSceneIdHint({
|
|
2699
|
+
sessionId,
|
|
2700
|
+
query,
|
|
2701
|
+
findings: result.findings,
|
|
2702
|
+
});
|
|
2703
|
+
const normalizedConclusionContract = ((0, agentResultNormalizer_1.deriveEvidenceBackedConclusionContractForNarrative)(result.conclusion, session.dataEnvelopes || [], {
|
|
2704
|
+
existingContract: result.conclusionContract,
|
|
2705
|
+
mode: result.rounds > 1 ? 'focused_answer' : 'initial_report',
|
|
2706
|
+
sceneId: sceneIdHint,
|
|
2707
|
+
}) ||
|
|
2708
|
+
undefined);
|
|
2709
|
+
if (normalizedConclusionContract) {
|
|
2710
|
+
result.conclusionContract = normalizedConclusionContract;
|
|
2711
|
+
}
|
|
2712
|
+
ensureAnalysisQualityArtifacts(session, normalizedConclusionContract);
|
|
2713
|
+
}
|
|
2714
|
+
const finalQualityIssue = (0, finalResultQualityGate_1.applyFinalResultQualityGate)({ result, query });
|
|
2715
|
+
if (finalQualityIssue) {
|
|
2716
|
+
const message = result.terminationMessage || finalQualityIssue.message;
|
|
2717
|
+
logger.warn('AgentDrivenAnalysis', 'Final result quality gate marked result partial', {
|
|
2718
|
+
code: finalQualityIssue.code,
|
|
2719
|
+
conclusionChars: result.conclusion.length,
|
|
2720
|
+
findingsCount: result.findings.length,
|
|
2721
|
+
hasConclusionContract: !!result.conclusionContract,
|
|
2722
|
+
claimVerifierStatus: result.claimVerificationResult?.status,
|
|
2723
|
+
runId: session.activeRun?.runId,
|
|
2724
|
+
requestId: session.activeRun?.requestId,
|
|
2725
|
+
});
|
|
2726
|
+
const update = {
|
|
2727
|
+
type: 'degraded',
|
|
2728
|
+
content: {
|
|
2729
|
+
module: 'agentRoutes',
|
|
2730
|
+
fallback: 'final_result_quality_gate',
|
|
2731
|
+
code: finalQualityIssue.code,
|
|
2732
|
+
partial: true,
|
|
2733
|
+
message,
|
|
2734
|
+
},
|
|
2735
|
+
timestamp: Date.now(),
|
|
2736
|
+
};
|
|
2737
|
+
broadcastToAgentDrivenClients(sessionId, update);
|
|
2738
|
+
const conversationStep = buildConversationStepUpdate(session, update);
|
|
2739
|
+
if (conversationStep) {
|
|
2740
|
+
appendConversationStep(session, conversationStep);
|
|
2741
|
+
broadcastToAgentDrivenClients(sessionId, conversationStep);
|
|
2742
|
+
}
|
|
2743
|
+
}
|
|
2744
|
+
const currentTurn = session.runSequence || 1;
|
|
2745
|
+
const latestConclusionHistory = session.conclusionHistory?.[session.conclusionHistory.length - 1];
|
|
2746
|
+
if (latestConclusionHistory?.turn === currentTurn) {
|
|
2747
|
+
latestConclusionHistory.confidence = result.confidence ?? latestConclusionHistory.confidence;
|
|
2748
|
+
}
|
|
2749
|
+
enhancedSessionContext_1.sessionContextManager.get(sessionId, traceId)?.annotateLatestCompletedTurn({
|
|
2750
|
+
success: result.success,
|
|
2751
|
+
findings: result.findings,
|
|
2752
|
+
message: result.conclusion,
|
|
2753
|
+
confidence: result.confidence,
|
|
2754
|
+
partial: result.partial,
|
|
2755
|
+
terminationReason: result.terminationReason,
|
|
2756
|
+
terminationMessage: result.terminationMessage,
|
|
2757
|
+
conclusionContract: result.conclusionContract,
|
|
2758
|
+
claimSupport: result.claimSupport,
|
|
2759
|
+
claimVerificationResult: result.claimVerificationResult,
|
|
2760
|
+
identityResolutions: result.identityResolutions,
|
|
2761
|
+
});
|
|
2762
|
+
session.status = terminalRunStatus === 'quota_exceeded'
|
|
2763
|
+
? 'quota_exceeded'
|
|
2764
|
+
: result.success ? 'completed' : 'failed';
|
|
2765
|
+
markSessionRunStatus(session, terminalRunStatus);
|
|
2499
2766
|
// Log completion details
|
|
2500
2767
|
logger.info('AgentDrivenAnalysis', 'Agent-driven analysis completed', {
|
|
2501
2768
|
confidence: result.confidence,
|
|
2502
2769
|
rounds: result.rounds,
|
|
2503
2770
|
findingsCount: result.findings.length,
|
|
2504
2771
|
hypothesesCount: result.hypotheses.length,
|
|
2772
|
+
claimSupportCount: result.claimSupport?.length || 0,
|
|
2773
|
+
claimVerifierStatus: result.claimVerificationResult?.status,
|
|
2505
2774
|
partial: result.partial,
|
|
2506
2775
|
terminationReason: result.terminationReason,
|
|
2507
2776
|
runId: session.activeRun?.runId,
|
|
@@ -2524,14 +2793,11 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
|
|
|
2524
2793
|
// Send final result
|
|
2525
2794
|
const clientCount = session.sseClients.length;
|
|
2526
2795
|
logger.info('AgentRoutes', 'Sending agent-driven result', { clientCount });
|
|
2796
|
+
ensureCompletedAnalysisSseEvents(session);
|
|
2527
2797
|
session.sseClients.forEach((client, index) => {
|
|
2528
2798
|
try {
|
|
2529
2799
|
logger.info('AgentRoutes', `Sending agent-driven result to client ${index + 1}/${clientCount}`);
|
|
2530
2800
|
sendAgentDrivenResult(client, session);
|
|
2531
|
-
sendReplayableSessionEvent(session, client, 'end', {
|
|
2532
|
-
timestamp: Date.now(),
|
|
2533
|
-
...buildStreamObservability(session),
|
|
2534
|
-
});
|
|
2535
2801
|
}
|
|
2536
2802
|
catch (e) {
|
|
2537
2803
|
logger.error('AgentRoutes', `Error sending agent-driven result to client ${index + 1}`, e);
|
|
@@ -3945,7 +4211,7 @@ function normalizeNarrativeForClient(narrative) {
|
|
|
3945
4211
|
}
|
|
3946
4212
|
function conclusionHasEvidenceIndex(conclusion) {
|
|
3947
4213
|
const text = conclusion || '';
|
|
3948
|
-
return /(^|\n)\s*##\s
|
|
4214
|
+
return /(^|\n)\s*##\s*证据(?:表)?索引\b/.test(text);
|
|
3949
4215
|
}
|
|
3950
4216
|
function markdownCell(value, maxLen = 80) {
|
|
3951
4217
|
return String(value ?? '')
|
|
@@ -3954,19 +4220,7 @@ function markdownCell(value, maxLen = 80) {
|
|
|
3954
4220
|
.trim()
|
|
3955
4221
|
.slice(0, maxLen) || '-';
|
|
3956
4222
|
}
|
|
3957
|
-
function
|
|
3958
|
-
const rows = env?.data?.rows;
|
|
3959
|
-
if (Array.isArray(rows))
|
|
3960
|
-
return String(rows.length);
|
|
3961
|
-
const summaryContent = env?.data?.summary?.content;
|
|
3962
|
-
if (typeof summaryContent === 'string') {
|
|
3963
|
-
const matched = summaryContent.match(/Total rows:\s*(\d+)/i);
|
|
3964
|
-
if (matched)
|
|
3965
|
-
return matched[1];
|
|
3966
|
-
}
|
|
3967
|
-
return '-';
|
|
3968
|
-
}
|
|
3969
|
-
function buildConclusionEvidenceIndex(envelopes, maxItems = 8) {
|
|
4223
|
+
function buildConclusionEvidenceIndex(envelopes, maxItems = 3) {
|
|
3970
4224
|
if (!Array.isArray(envelopes) || envelopes.length === 0)
|
|
3971
4225
|
return '';
|
|
3972
4226
|
const seen = new Set();
|
|
@@ -3983,22 +4237,21 @@ function buildConclusionEvidenceIndex(envelopes, maxItems = 8) {
|
|
|
3983
4237
|
if (seen.has(key))
|
|
3984
4238
|
continue;
|
|
3985
4239
|
seen.add(key);
|
|
3986
|
-
const phase = markdownCell(meta.planPhaseTitle || meta.planPhaseId || '-');
|
|
3987
4240
|
const source = markdownCell(meta.source || meta.skillId || 'execute_sql');
|
|
3988
|
-
const evidence = markdownCell(meta.evidenceRefId || meta.sourceToolCallId || '-',
|
|
3989
|
-
candidates.push(
|
|
4241
|
+
const evidence = markdownCell(meta.evidenceRefId || meta.sourceToolCallId || '-', 36);
|
|
4242
|
+
candidates.push({ title, source, evidence });
|
|
3990
4243
|
}
|
|
3991
4244
|
if (candidates.length === 0)
|
|
3992
4245
|
return '';
|
|
3993
4246
|
const rows = candidates.slice(0, maxItems);
|
|
3994
4247
|
const omitted = Math.max(0, candidates.length - rows.length);
|
|
4248
|
+
const summary = rows
|
|
4249
|
+
.map(item => `${item.title}(${item.source} / ${item.evidence})`)
|
|
4250
|
+
.join(';');
|
|
3995
4251
|
return [
|
|
3996
|
-
'##
|
|
4252
|
+
'## 证据索引',
|
|
3997
4253
|
'',
|
|
3998
|
-
|
|
3999
|
-
'|---|---|---|---:|---|',
|
|
4000
|
-
...rows,
|
|
4001
|
-
omitted > 0 ? `| - | 其余 ${omitted} 份证据 | - | - | - |` : '',
|
|
4254
|
+
`关键数据来源:${summary}${omitted > 0 ? `;其余 ${omitted} 份结构化证据见报告数据详情。` : '。'}`,
|
|
4002
4255
|
].filter(Boolean).join('\n');
|
|
4003
4256
|
}
|
|
4004
4257
|
function appendEvidenceIndexIfMissing(conclusion, envelopes) {
|
|
@@ -4030,53 +4283,67 @@ function augmentConclusionUpdateWithEvidenceIndex(session, update) {
|
|
|
4030
4283
|
},
|
|
4031
4284
|
};
|
|
4032
4285
|
}
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
*/
|
|
4036
|
-
function sendAgentDrivenResult(res, session) {
|
|
4037
|
-
const result = session.result;
|
|
4286
|
+
function ensureAnalysisQualityArtifacts(session, conclusionContract, resultOverride) {
|
|
4287
|
+
const result = resultOverride || session.result;
|
|
4038
4288
|
if (!result)
|
|
4039
|
-
return;
|
|
4040
|
-
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
|
|
4289
|
+
return {};
|
|
4290
|
+
if (result.claimSupport &&
|
|
4291
|
+
result.claimVerificationResult &&
|
|
4292
|
+
result.identityResolutions) {
|
|
4293
|
+
session.claimSupport = result.claimSupport;
|
|
4294
|
+
session.claimVerificationResult = result.claimVerificationResult;
|
|
4295
|
+
session.identityResolutions = result.identityResolutions;
|
|
4296
|
+
const context = enhancedSessionContext_1.sessionContextManager.get(session.sessionId, session.traceId);
|
|
4297
|
+
context?.annotateLatestCompletedTurn({
|
|
4298
|
+
conclusionContract,
|
|
4299
|
+
claimSupport: result.claimSupport,
|
|
4300
|
+
claimVerificationResult: result.claimVerificationResult,
|
|
4301
|
+
identityResolutions: result.identityResolutions,
|
|
4052
4302
|
});
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
const
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4303
|
+
return {
|
|
4304
|
+
claimSupport: result.claimSupport,
|
|
4305
|
+
claimVerificationResult: result.claimVerificationResult,
|
|
4306
|
+
identityResolutions: result.identityResolutions,
|
|
4307
|
+
};
|
|
4308
|
+
}
|
|
4309
|
+
const artifacts = (0, claimVerificationRunner_1.runClaimVerification)({
|
|
4310
|
+
conclusionContract,
|
|
4311
|
+
dataEnvelopes: session.dataEnvelopes || [],
|
|
4312
|
+
comparisonReportSection: session.comparisonReportSection,
|
|
4313
|
+
policy: 'record_only',
|
|
4314
|
+
});
|
|
4315
|
+
result.claimSupport = artifacts.claimSupport;
|
|
4316
|
+
result.claimVerificationResult = artifacts.claimVerificationResult;
|
|
4317
|
+
result.identityResolutions = artifacts.identityResolutions;
|
|
4318
|
+
const context = enhancedSessionContext_1.sessionContextManager.get(session.sessionId, session.traceId);
|
|
4319
|
+
context?.annotateLatestCompletedTurn({
|
|
4320
|
+
conclusionContract,
|
|
4321
|
+
claimSupport: artifacts.claimSupport,
|
|
4322
|
+
claimVerificationResult: artifacts.claimVerificationResult,
|
|
4323
|
+
identityResolutions: artifacts.identityResolutions,
|
|
4324
|
+
});
|
|
4325
|
+
session.claimSupport = artifacts.claimSupport;
|
|
4326
|
+
session.claimVerificationResult = artifacts.claimVerificationResult;
|
|
4327
|
+
session.identityResolutions = artifacts.identityResolutions;
|
|
4328
|
+
return {
|
|
4329
|
+
claimSupport: artifacts.claimSupport,
|
|
4330
|
+
claimVerificationResult: artifacts.claimVerificationResult,
|
|
4331
|
+
identityResolutions: artifacts.identityResolutions,
|
|
4332
|
+
};
|
|
4333
|
+
}
|
|
4334
|
+
function ensureCompletedAnalysisFinalArtifacts(session, input) {
|
|
4335
|
+
const cached = session.completedAnalysisFinalArtifacts;
|
|
4336
|
+
if (cached)
|
|
4337
|
+
return cached;
|
|
4338
|
+
const result = input.result;
|
|
4339
|
+
const finalArtifacts = { generatedAt: Date.now() };
|
|
4340
|
+
let reportId;
|
|
4341
|
+
if (!input.hasEvidenceBackedConclusion) {
|
|
4342
|
+
finalArtifacts.reportError = `analysis did not complete successfully (${result.terminationReason || 'failed'})`;
|
|
4078
4343
|
}
|
|
4079
4344
|
else {
|
|
4345
|
+
let reportLease = null;
|
|
4346
|
+
reportId = `agent-report-${session.sessionId}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
4080
4347
|
try {
|
|
4081
4348
|
if (enterpriseLeasesEnabled()) {
|
|
4082
4349
|
const scope = leaseScopeFromSession(session);
|
|
@@ -4100,18 +4367,15 @@ function sendAgentDrivenResult(res, session) {
|
|
|
4100
4367
|
}
|
|
4101
4368
|
}
|
|
4102
4369
|
const generator = (0, htmlReportGenerator_1.getHTMLReportGenerator)();
|
|
4103
|
-
// Report assembly (cumulative findings dedup, empty-conclusion fallback,
|
|
4104
|
-
// snapshot-first analysisNotes/Plan/Flags) lives in the shared builder so
|
|
4105
|
-
// the CLI path produces identical output.
|
|
4106
4370
|
const reportData = (0, agentReportData_1.buildAgentDrivenReportData)({
|
|
4107
4371
|
session,
|
|
4108
|
-
result: resultForClient,
|
|
4372
|
+
result: input.resultForClient,
|
|
4109
4373
|
});
|
|
4110
4374
|
console.log(`[AgentRoutes] Generating HTML report, data keys:`, {
|
|
4111
4375
|
hasResult: !!result,
|
|
4112
|
-
conclusionLength: normalizedConclusion?.length || 0,
|
|
4113
|
-
conclusionPreview: (normalizedConclusion || '').substring(0, 100),
|
|
4114
|
-
hasConclusionContract: !!normalizedConclusionContract,
|
|
4376
|
+
conclusionLength: input.normalizedConclusion?.length || 0,
|
|
4377
|
+
conclusionPreview: (input.normalizedConclusion || '').substring(0, 100),
|
|
4378
|
+
hasConclusionContract: !!input.normalizedConclusionContract,
|
|
4115
4379
|
findingsCount: result.findings?.length || 0,
|
|
4116
4380
|
hypothesesCount: session.hypotheses?.length || 0,
|
|
4117
4381
|
dialogueCount: session.agentDialogue?.length || 0,
|
|
@@ -4123,9 +4387,10 @@ function sendAgentDrivenResult(res, session) {
|
|
|
4123
4387
|
snapshotNotes: session._lastSnapshot?.analysisNotes?.length ?? 'n/a',
|
|
4124
4388
|
snapshotPlan: !!session._lastSnapshot?.analysisPlan,
|
|
4125
4389
|
snapshotFlags: session._lastSnapshot?.uncertaintyFlags?.length ?? 'n/a',
|
|
4390
|
+
claimSupportCount: input.qualityArtifacts.claimSupport?.length || 0,
|
|
4391
|
+
claimVerifierStatus: input.qualityArtifacts.claimVerificationResult?.status,
|
|
4126
4392
|
});
|
|
4127
4393
|
const html = generator.generateAgentDrivenHTML(reportData);
|
|
4128
|
-
// Store report
|
|
4129
4394
|
(0, reportRoutes_1.persistReport)(reportId, {
|
|
4130
4395
|
html,
|
|
4131
4396
|
generatedAt: Date.now(),
|
|
@@ -4137,13 +4402,15 @@ function sendAgentDrivenResult(res, session) {
|
|
|
4137
4402
|
userId: session.userId,
|
|
4138
4403
|
visibility: 'private',
|
|
4139
4404
|
});
|
|
4140
|
-
|
|
4405
|
+
finalArtifacts.reportId = reportId;
|
|
4406
|
+
finalArtifacts.reportUrl = `/api/reports/${reportId}`;
|
|
4141
4407
|
console.log(`[AgentRoutes] Generated agent-driven HTML report: ${reportId} (${html.length} bytes)`);
|
|
4142
4408
|
}
|
|
4143
4409
|
catch (error) {
|
|
4144
|
-
|
|
4410
|
+
reportId = undefined;
|
|
4411
|
+
finalArtifacts.reportError = error.message || 'Unknown error';
|
|
4145
4412
|
console.error('[AgentRoutes] Failed to generate agent-driven HTML report:', {
|
|
4146
|
-
error: reportError,
|
|
4413
|
+
error: finalArtifacts.reportError,
|
|
4147
4414
|
stack: error.stack?.split('\n').slice(0, 5).join('\n'),
|
|
4148
4415
|
resultConclusion: result?.conclusion ? `${result.conclusion.length} chars` : 'EMPTY/NULL',
|
|
4149
4416
|
resultConfidence: result?.confidence,
|
|
@@ -4155,7 +4422,7 @@ function sendAgentDrivenResult(res, session) {
|
|
|
4155
4422
|
const scope = leaseScopeFromSession(session);
|
|
4156
4423
|
if (scope) {
|
|
4157
4424
|
try {
|
|
4158
|
-
(0, traceProcessorLeaseStore_1.getTraceProcessorLeaseStore)().releaseHolder(scope, reportLease.id, 'report_generation', reportId);
|
|
4425
|
+
(0, traceProcessorLeaseStore_1.getTraceProcessorLeaseStore)().releaseHolder(scope, reportLease.id, 'report_generation', finalArtifacts.reportId || reportId || 'report_generation');
|
|
4159
4426
|
}
|
|
4160
4427
|
catch (releaseError) {
|
|
4161
4428
|
console.warn(`[AgentRoutes] Failed to release report_generation lease ${reportLease.id}: ${releaseError.message}`);
|
|
@@ -4164,7 +4431,7 @@ function sendAgentDrivenResult(res, session) {
|
|
|
4164
4431
|
}
|
|
4165
4432
|
}
|
|
4166
4433
|
}
|
|
4167
|
-
if (hasEvidenceBackedConclusion) {
|
|
4434
|
+
if (input.hasEvidenceBackedConclusion) {
|
|
4168
4435
|
try {
|
|
4169
4436
|
const resultSnapshot = (0, analysisResultSnapshotPipeline_1.persistCompletedAnalysisResultSnapshot)({
|
|
4170
4437
|
tenantId: session.tenantId,
|
|
@@ -4173,20 +4440,23 @@ function sendAgentDrivenResult(res, session) {
|
|
|
4173
4440
|
traceId: session.traceId,
|
|
4174
4441
|
sessionId: session.sessionId,
|
|
4175
4442
|
runId: session.lastRun?.runId || session.activeRun?.runId,
|
|
4176
|
-
reportId:
|
|
4443
|
+
reportId: finalArtifacts.reportId,
|
|
4177
4444
|
query: session.query,
|
|
4178
4445
|
traceLabel: session.traceId,
|
|
4179
|
-
conclusion: normalizedConclusion,
|
|
4180
|
-
conclusionContract: normalizedConclusionContract,
|
|
4446
|
+
conclusion: input.normalizedConclusion,
|
|
4447
|
+
conclusionContract: input.normalizedConclusionContract,
|
|
4448
|
+
claimSupport: input.qualityArtifacts.claimSupport,
|
|
4449
|
+
claimVerificationResult: input.qualityArtifacts.claimVerificationResult,
|
|
4450
|
+
identityResolutions: input.qualityArtifacts.identityResolutions,
|
|
4181
4451
|
confidence: result.confidence,
|
|
4182
4452
|
partial: result.partial,
|
|
4183
4453
|
terminationReason: result.terminationReason,
|
|
4184
4454
|
terminationMessage: result.terminationMessage,
|
|
4185
4455
|
dataEnvelopes: session.dataEnvelopes,
|
|
4186
4456
|
});
|
|
4187
|
-
resultSnapshotId = resultSnapshot?.id;
|
|
4457
|
+
finalArtifacts.resultSnapshotId = resultSnapshot?.id;
|
|
4188
4458
|
if (resultSnapshot) {
|
|
4189
|
-
resultSnapshotEventData = {
|
|
4459
|
+
finalArtifacts.resultSnapshotEventData = {
|
|
4190
4460
|
snapshotId: resultSnapshot.id,
|
|
4191
4461
|
status: resultSnapshot.status,
|
|
4192
4462
|
sceneType: resultSnapshot.sceneType,
|
|
@@ -4209,24 +4479,134 @@ function sendAgentDrivenResult(res, session) {
|
|
|
4209
4479
|
});
|
|
4210
4480
|
}
|
|
4211
4481
|
}
|
|
4212
|
-
|
|
4213
|
-
|
|
4482
|
+
session.completedAnalysisFinalArtifacts = finalArtifacts;
|
|
4483
|
+
return finalArtifacts;
|
|
4484
|
+
}
|
|
4485
|
+
function ensureCompletedAnalysisResultPayload(session) {
|
|
4486
|
+
const result = session.result;
|
|
4487
|
+
if (!result)
|
|
4488
|
+
return undefined;
|
|
4489
|
+
const replayOnlyScene = isSceneReplayOnlyQuery(session.query);
|
|
4490
|
+
const hasEvidenceBackedConclusion = result.success || result.partial === true;
|
|
4491
|
+
const normalizedConclusion = replayOnlyScene
|
|
4492
|
+
? buildSceneReplayNarrative(session.scenes || [])
|
|
4493
|
+
: hasEvidenceBackedConclusion ? appendEvidenceIndexIfMissing(normalizeNarrativeForClient(result.conclusion), session.dataEnvelopes || []) : normalizeNarrativeForClient(result.conclusion);
|
|
4494
|
+
const sceneIdHint = replayOnlyScene
|
|
4495
|
+
? undefined
|
|
4496
|
+
: resolveConclusionSceneIdHint({
|
|
4497
|
+
sessionId: session.sessionId,
|
|
4498
|
+
query: session.query,
|
|
4499
|
+
findings: result.findings,
|
|
4500
|
+
});
|
|
4501
|
+
const normalizedConclusionContract = replayOnlyScene
|
|
4502
|
+
? undefined
|
|
4503
|
+
: hasEvidenceBackedConclusion ? ((0, agentResultNormalizer_1.deriveEvidenceBackedConclusionContractForNarrative)(result.conclusion, session.dataEnvelopes || [], {
|
|
4504
|
+
existingContract: result.conclusionContract,
|
|
4505
|
+
mode: result.rounds > 1 ? 'focused_answer' : 'initial_report',
|
|
4506
|
+
sceneId: sceneIdHint,
|
|
4507
|
+
}) ||
|
|
4508
|
+
undefined) : undefined;
|
|
4509
|
+
const qualityArtifacts = hasEvidenceBackedConclusion && !replayOnlyScene
|
|
4510
|
+
? ensureAnalysisQualityArtifacts(session, normalizedConclusionContract)
|
|
4511
|
+
: {};
|
|
4512
|
+
if (normalizedConclusionContract) {
|
|
4513
|
+
result.conclusionContract = normalizedConclusionContract;
|
|
4514
|
+
}
|
|
4515
|
+
if (!replayOnlyScene) {
|
|
4516
|
+
const readPathQualityIssue = (0, finalResultQualityGate_1.applyFinalResultQualityGate)({ result, query: session.query });
|
|
4517
|
+
if (readPathQualityIssue) {
|
|
4518
|
+
enhancedSessionContext_1.sessionContextManager.get(session.sessionId, session.traceId)?.annotateLatestCompletedTurn({
|
|
4519
|
+
success: result.success,
|
|
4520
|
+
findings: result.findings,
|
|
4521
|
+
message: result.conclusion,
|
|
4522
|
+
confidence: result.confidence,
|
|
4523
|
+
partial: result.partial,
|
|
4524
|
+
terminationReason: result.terminationReason,
|
|
4525
|
+
terminationMessage: result.terminationMessage,
|
|
4526
|
+
conclusionContract: result.conclusionContract,
|
|
4527
|
+
claimSupport: result.claimSupport,
|
|
4528
|
+
claimVerificationResult: result.claimVerificationResult,
|
|
4529
|
+
identityResolutions: result.identityResolutions,
|
|
4530
|
+
});
|
|
4531
|
+
}
|
|
4532
|
+
}
|
|
4533
|
+
const resultForClient = normalizedConclusion === result.conclusion &&
|
|
4534
|
+
normalizedConclusionContract === result.conclusionContract &&
|
|
4535
|
+
qualityArtifacts.claimSupport === result.claimSupport &&
|
|
4536
|
+
qualityArtifacts.claimVerificationResult === result.claimVerificationResult &&
|
|
4537
|
+
qualityArtifacts.identityResolutions === result.identityResolutions
|
|
4538
|
+
? result
|
|
4539
|
+
: {
|
|
4540
|
+
...result,
|
|
4541
|
+
conclusion: normalizedConclusion,
|
|
4542
|
+
conclusionContract: normalizedConclusionContract,
|
|
4543
|
+
...qualityArtifacts,
|
|
4544
|
+
};
|
|
4545
|
+
const clientFindings = replayOnlyScene ? [] : buildClientFindings(result.findings, session.scenes || []);
|
|
4546
|
+
const resultContract = buildSessionResultContract(session, clientFindings);
|
|
4547
|
+
const finalArtifacts = ensureCompletedAnalysisFinalArtifacts(session, {
|
|
4548
|
+
result,
|
|
4549
|
+
hasEvidenceBackedConclusion,
|
|
4550
|
+
normalizedConclusion,
|
|
4551
|
+
normalizedConclusionContract,
|
|
4552
|
+
qualityArtifacts,
|
|
4553
|
+
resultForClient: resultForClient,
|
|
4554
|
+
});
|
|
4555
|
+
return {
|
|
4556
|
+
result,
|
|
4557
|
+
replayOnlyScene,
|
|
4558
|
+
normalizedConclusion,
|
|
4559
|
+
normalizedConclusionContract,
|
|
4560
|
+
qualityArtifacts,
|
|
4561
|
+
clientFindings,
|
|
4562
|
+
resultContract,
|
|
4563
|
+
finalArtifacts,
|
|
4564
|
+
};
|
|
4565
|
+
}
|
|
4566
|
+
/**
|
|
4567
|
+
* Send agent-driven analysis result to SSE client
|
|
4568
|
+
*/
|
|
4569
|
+
function ensureCompletedAnalysisSseEvents(session) {
|
|
4570
|
+
const cached = session.completedAnalysisSseEvents;
|
|
4571
|
+
if (cached?.length &&
|
|
4572
|
+
session.completedAnalysisSseEventsQualityGateVersion ===
|
|
4573
|
+
COMPLETED_ANALYSIS_SSE_EVENTS_QUALITY_GATE_VERSION) {
|
|
4574
|
+
return cached;
|
|
4575
|
+
}
|
|
4576
|
+
const completedPayload = ensureCompletedAnalysisResultPayload(session);
|
|
4577
|
+
if (!completedPayload) {
|
|
4578
|
+
const persisted = loadPersistedCompletedAnalysisSseEvents(session);
|
|
4579
|
+
if (persisted.length > 0) {
|
|
4580
|
+
session.completedAnalysisSseEvents = persisted;
|
|
4581
|
+
delete session.completedAnalysisSseEventsQualityGateVersion;
|
|
4582
|
+
return persisted;
|
|
4583
|
+
}
|
|
4584
|
+
return [];
|
|
4585
|
+
}
|
|
4586
|
+
const { result, normalizedConclusion, normalizedConclusionContract, qualityArtifacts, clientFindings, resultContract, finalArtifacts, } = completedPayload;
|
|
4587
|
+
const observability = buildStreamObservability(session);
|
|
4588
|
+
const events = [];
|
|
4589
|
+
if (finalArtifacts.resultSnapshotEventData) {
|
|
4590
|
+
events.push(appendAndPersistReplayableSessionEvent(session, 'snapshot_created', {
|
|
4214
4591
|
type: 'snapshot_created',
|
|
4215
4592
|
architecture: 'agent-driven',
|
|
4216
4593
|
...observability,
|
|
4217
|
-
data: resultSnapshotEventData,
|
|
4594
|
+
data: finalArtifacts.resultSnapshotEventData,
|
|
4218
4595
|
timestamp: Date.now(),
|
|
4219
|
-
});
|
|
4596
|
+
}));
|
|
4220
4597
|
}
|
|
4221
4598
|
// Send analysis_completed event with full result. Keep it replayable so a
|
|
4222
4599
|
// reconnect between conclusion and report generation can recover reportUrl.
|
|
4223
|
-
|
|
4600
|
+
events.push(appendAndPersistReplayableSessionEvent(session, 'analysis_completed', {
|
|
4224
4601
|
type: 'analysis_completed',
|
|
4225
4602
|
architecture: 'agent-driven',
|
|
4226
4603
|
...observability,
|
|
4227
4604
|
data: {
|
|
4228
4605
|
conclusion: normalizedConclusion,
|
|
4229
4606
|
conclusionContract: normalizedConclusionContract,
|
|
4607
|
+
claimSupport: qualityArtifacts.claimSupport,
|
|
4608
|
+
claimVerificationResult: qualityArtifacts.claimVerificationResult,
|
|
4609
|
+
identityResolutions: qualityArtifacts.identityResolutions,
|
|
4230
4610
|
confidence: result.confidence,
|
|
4231
4611
|
rounds: result.rounds,
|
|
4232
4612
|
totalDurationMs: result.totalDurationMs,
|
|
@@ -4246,8 +4626,8 @@ function sendAgentDrivenResult(res, session) {
|
|
|
4246
4626
|
agentDialogueCount: session.agentDialogue.length,
|
|
4247
4627
|
conversationTimelineCount: session.conversationSteps.length,
|
|
4248
4628
|
conversationTimeline: session.conversationSteps,
|
|
4249
|
-
reportUrl,
|
|
4250
|
-
reportError,
|
|
4629
|
+
reportUrl: finalArtifacts.reportUrl,
|
|
4630
|
+
reportError: finalArtifacts.reportError,
|
|
4251
4631
|
comparisonReportSection: session.comparisonReportSection
|
|
4252
4632
|
? {
|
|
4253
4633
|
source: session.comparisonReportSection.source,
|
|
@@ -4257,14 +4637,15 @@ function sendAgentDrivenResult(res, session) {
|
|
|
4257
4637
|
evidencePack: session.comparisonReportSection.evidencePack,
|
|
4258
4638
|
}
|
|
4259
4639
|
: undefined,
|
|
4260
|
-
resultSnapshotId,
|
|
4640
|
+
resultSnapshotId: finalArtifacts.resultSnapshotId,
|
|
4261
4641
|
observability,
|
|
4642
|
+
terminalRunStatus: session.status === 'quota_exceeded' ? 'quota_exceeded' : 'completed',
|
|
4262
4643
|
},
|
|
4263
4644
|
timestamp: Date.now(),
|
|
4264
|
-
});
|
|
4645
|
+
}));
|
|
4265
4646
|
// Backward-compatible scene reconstruction payload (used by the legacy /scene-reconstruct clients).
|
|
4266
4647
|
if ((session.scenes?.length || 0) > 0 || (session.trackEvents?.length || 0) > 0) {
|
|
4267
|
-
|
|
4648
|
+
events.push(appendAndPersistReplayableSessionEvent(session, 'scene_reconstruction_completed', {
|
|
4268
4649
|
type: 'scene_reconstruction_completed',
|
|
4269
4650
|
...observability,
|
|
4270
4651
|
data: {
|
|
@@ -4292,7 +4673,20 @@ function sendAgentDrivenResult(res, session) {
|
|
|
4292
4673
|
observability,
|
|
4293
4674
|
},
|
|
4294
4675
|
timestamp: Date.now(),
|
|
4295
|
-
});
|
|
4676
|
+
}));
|
|
4677
|
+
}
|
|
4678
|
+
events.push(appendAndPersistReplayableSessionEvent(session, 'end', {
|
|
4679
|
+
timestamp: Date.now(),
|
|
4680
|
+
...observability,
|
|
4681
|
+
}));
|
|
4682
|
+
session.completedAnalysisSseEvents = events;
|
|
4683
|
+
session.completedAnalysisSseEventsQualityGateVersion =
|
|
4684
|
+
COMPLETED_ANALYSIS_SSE_EVENTS_QUALITY_GATE_VERSION;
|
|
4685
|
+
return events;
|
|
4686
|
+
}
|
|
4687
|
+
function sendAgentDrivenResult(res, session) {
|
|
4688
|
+
for (const event of ensureCompletedAnalysisSseEvents(session)) {
|
|
4689
|
+
writeBufferedSessionEvent(res, event);
|
|
4296
4690
|
}
|
|
4297
4691
|
}
|
|
4298
4692
|
(0, agentLogsRoutes_1.registerAgentLogsRoutes)(router);
|