@gracker/smartperfetto 1.0.20 → 1.0.21
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/config/domainManifest.d.ts +5 -3
- package/dist/agent/config/domainManifest.d.ts.map +1 -1
- package/dist/agent/config/domainManifest.js +120 -5
- package/dist/agent/config/domainManifest.js.map +1 -1
- package/dist/agent/core/orchestratorTypes.d.ts +5 -0
- package/dist/agent/core/orchestratorTypes.d.ts.map +1 -1
- package/dist/agent/core/orchestratorTypes.js.map +1 -1
- package/dist/agent/scene/buildSmartChatReport.d.ts +13 -0
- package/dist/agent/scene/buildSmartChatReport.d.ts.map +1 -0
- package/dist/agent/scene/buildSmartChatReport.js +333 -0
- package/dist/agent/scene/buildSmartChatReport.js.map +1 -0
- package/dist/agent/scene/sceneAnalysisJobRunner.d.ts +8 -4
- package/dist/agent/scene/sceneAnalysisJobRunner.d.ts.map +1 -1
- package/dist/agent/scene/sceneAnalysisJobRunner.js +78 -3
- package/dist/agent/scene/sceneAnalysisJobRunner.js.map +1 -1
- package/dist/agent/scene/sceneIntervalBuilder.d.ts +14 -5
- package/dist/agent/scene/sceneIntervalBuilder.d.ts.map +1 -1
- package/dist/agent/scene/sceneIntervalBuilder.js +578 -1
- package/dist/agent/scene/sceneIntervalBuilder.js.map +1 -1
- package/dist/agent/scene/sceneStage1Verifier.d.ts +8 -0
- package/dist/agent/scene/sceneStage1Verifier.d.ts.map +1 -0
- package/dist/agent/scene/sceneStage1Verifier.js +245 -0
- package/dist/agent/scene/sceneStage1Verifier.js.map +1 -0
- package/dist/agent/scene/sceneStoryService.d.ts +20 -2
- package/dist/agent/scene/sceneStoryService.d.ts.map +1 -1
- package/dist/agent/scene/sceneStoryService.js +238 -25
- package/dist/agent/scene/sceneStoryService.js.map +1 -1
- package/dist/agent/scene/smartCancelBridge.d.ts +13 -0
- package/dist/agent/scene/smartCancelBridge.d.ts.map +1 -0
- package/dist/agent/scene/smartCancelBridge.js +44 -0
- package/dist/agent/scene/smartCancelBridge.js.map +1 -0
- package/dist/agent/scene/smartDeepDiveDispatch.d.ts +15 -0
- package/dist/agent/scene/smartDeepDiveDispatch.d.ts.map +1 -0
- package/dist/agent/scene/smartDeepDiveDispatch.js +170 -0
- package/dist/agent/scene/smartDeepDiveDispatch.js.map +1 -0
- package/dist/agent/scene/types.d.ts +97 -6
- package/dist/agent/scene/types.d.ts.map +1 -1
- package/dist/agent/types.d.ts +1 -1
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js.map +1 -1
- package/dist/agentv3/strategyLoader.d.ts +3 -0
- package/dist/agentv3/strategyLoader.d.ts.map +1 -1
- package/dist/agentv3/strategyLoader.js +17 -4
- package/dist/agentv3/strategyLoader.js.map +1 -1
- package/dist/config/index.d.ts +12 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +6 -0
- package/dist/config/index.js.map +1 -1
- package/dist/routes/agent/finalizeAgentDrivenSession.d.ts +67 -0
- package/dist/routes/agent/finalizeAgentDrivenSession.d.ts.map +1 -0
- package/dist/routes/agent/finalizeAgentDrivenSession.js +103 -0
- package/dist/routes/agent/finalizeAgentDrivenSession.js.map +1 -0
- package/dist/routes/agent/normalizeAnalyzeOptions.d.ts +42 -0
- package/dist/routes/agent/normalizeAnalyzeOptions.d.ts.map +1 -0
- package/dist/routes/agent/normalizeAnalyzeOptions.js +185 -0
- package/dist/routes/agent/normalizeAnalyzeOptions.js.map +1 -0
- package/dist/routes/agentRoutes.d.ts.map +1 -1
- package/dist/routes/agentRoutes.js +285 -125
- package/dist/routes/agentRoutes.js.map +1 -1
- package/dist/scripts/verifyAgentSseScrolling.js +131 -8
- package/dist/scripts/verifyAgentSseScrolling.js.map +1 -1
- package/dist/services/sceneReport/sceneJobArtifactStore.d.ts +22 -0
- package/dist/services/sceneReport/sceneJobArtifactStore.d.ts.map +1 -0
- package/dist/services/sceneReport/sceneJobArtifactStore.js +65 -0
- package/dist/services/sceneReport/sceneJobArtifactStore.js.map +1 -0
- package/dist/services/sceneReport/sceneReportMemoryCache.d.ts +5 -3
- package/dist/services/sceneReport/sceneReportMemoryCache.d.ts.map +1 -1
- package/dist/services/sceneReport/sceneReportMemoryCache.js +15 -10
- package/dist/services/sceneReport/sceneReportMemoryCache.js.map +1 -1
- package/dist/services/sceneReport/sceneReportStore.d.ts +9 -4
- package/dist/services/sceneReport/sceneReportStore.d.ts.map +1 -1
- package/dist/services/sceneReport/sceneReportStore.js +27 -7
- package/dist/services/sceneReport/sceneReportStore.js.map +1 -1
- package/dist/services/traceProcessor/sqlSemaphore.d.ts +16 -0
- package/dist/services/traceProcessor/sqlSemaphore.d.ts.map +1 -0
- package/dist/services/traceProcessor/sqlSemaphore.js +63 -0
- package/dist/services/traceProcessor/sqlSemaphore.js.map +1 -0
- package/dist/types/dataContract.d.ts +1 -1
- package/dist/types/dataContract.d.ts.map +1 -1
- package/dist/types/dataContract.js +2 -0
- package/dist/types/dataContract.js.map +1 -1
- package/package.json +1 -1
- package/skills/README.md +13 -5
- package/skills/composite/device_state_snapshot.skill.yaml +204 -0
- package/skills/composite/scene_reconstruction.skill.yaml +5 -1
- package/strategies/scene-reconstruction-verifier.template.md +18 -0
- package/strategies/scrolling.strategy.md +5 -1
- package/strategies/smart.strategy.md +53 -0
- package/skills/atomic/device_state_snapshot.skill.yaml +0 -171
|
@@ -68,8 +68,12 @@ const conclusionSceneTemplates_1 = require("../agent/core/conclusionSceneTemplat
|
|
|
68
68
|
const analysisNarrative_1 = require("../utils/analysisNarrative");
|
|
69
69
|
const agentSceneReconstructRoutes_1 = require("./agentSceneReconstructRoutes");
|
|
70
70
|
const sceneStoryService_1 = require("../agent/scene/sceneStoryService");
|
|
71
|
+
const buildSmartChatReport_1 = require("../agent/scene/buildSmartChatReport");
|
|
72
|
+
const smartDeepDiveDispatch_1 = require("../agent/scene/smartDeepDiveDispatch");
|
|
73
|
+
const smartCancelBridge_1 = require("../agent/scene/smartCancelBridge");
|
|
71
74
|
const sceneReportStore_1 = require("../services/sceneReport/sceneReportStore");
|
|
72
75
|
const sceneReportMemoryCache_1 = require("../services/sceneReport/sceneReportMemoryCache");
|
|
76
|
+
const sceneJobArtifactStore_1 = require("../services/sceneReport/sceneJobArtifactStore");
|
|
73
77
|
const traceHash_1 = require("../agent/scene/traceHash");
|
|
74
78
|
const sceneTraceDurationProbe_1 = require("../agent/scene/sceneTraceDurationProbe");
|
|
75
79
|
const config_1 = require("../config");
|
|
@@ -85,6 +89,8 @@ const agentReportRoutes_1 = require("./agentReportRoutes");
|
|
|
85
89
|
const agentResumeRoutes_1 = require("./agentResumeRoutes");
|
|
86
90
|
const agentSessionCatalogRoutes_1 = require("./agentSessionCatalogRoutes");
|
|
87
91
|
const agentTeachingRoutes_1 = require("./agentTeachingRoutes");
|
|
92
|
+
const normalizeAnalyzeOptions_1 = require("./agent/normalizeAnalyzeOptions");
|
|
93
|
+
const finalizeAgentDrivenSession_1 = require("./agent/finalizeAgentDrivenSession");
|
|
88
94
|
const assistantApplicationService_1 = require("../assistant/application/assistantApplicationService");
|
|
89
95
|
const streamProjector_1 = require("../assistant/stream/streamProjector");
|
|
90
96
|
const sessionSseReplay_1 = require("../assistant/stream/sessionSseReplay");
|
|
@@ -271,6 +277,7 @@ router.use((req, res, next) => {
|
|
|
271
277
|
router.use(auth_1.authenticate);
|
|
272
278
|
const assistantAppService = new assistantApplicationService_1.AssistantApplicationService();
|
|
273
279
|
const streamProjector = new streamProjector_1.StreamProjector();
|
|
280
|
+
const smartCancelBridge = new smartCancelBridge_1.SmartCancelBridge();
|
|
274
281
|
function agentEventScopeFromSession(session) {
|
|
275
282
|
const run = session.activeRun || session.lastRun;
|
|
276
283
|
if (!(0, config_1.resolveFeatureConfig)().enterprise ||
|
|
@@ -903,7 +910,7 @@ async function handleAnalyzeRequest(req, res, requestedSessionIdOverride) {
|
|
|
903
910
|
try {
|
|
904
911
|
const requestId = getRequestId(req);
|
|
905
912
|
const requestContext = (0, auth_1.requireRequestContext)(req);
|
|
906
|
-
const { traceId, query, sessionId: bodyRequestedSessionId, options = {}, selectionContext: rawSelectionContext, referenceTraceId, traceContext: rawTraceContext, providerId, } = req.body;
|
|
913
|
+
const { traceId, query, sessionId: bodyRequestedSessionId, options: rawOptions = {}, selectionContext: rawSelectionContext, referenceTraceId, traceContext: rawTraceContext, providerId, } = req.body;
|
|
907
914
|
const requestedSessionId = requestedSessionIdOverride || bodyRequestedSessionId;
|
|
908
915
|
if (!(0, rbac_1.hasRbacPermission)(requestContext, 'agent:run')) {
|
|
909
916
|
(0, rbac_1.sendForbidden)(res, 'Starting analysis requires agent:run permission');
|
|
@@ -937,6 +944,24 @@ async function handleAnalyzeRequest(req, res, requestedSessionIdOverride) {
|
|
|
937
944
|
});
|
|
938
945
|
return;
|
|
939
946
|
}
|
|
947
|
+
let options;
|
|
948
|
+
try {
|
|
949
|
+
options = (0, normalizeAnalyzeOptions_1.normalizeAnalyzeOptions)(rawOptions, {
|
|
950
|
+
endpoint: requestedSessionIdOverride ? '/sessions/:id/runs' : '/analyze',
|
|
951
|
+
hasReferenceTraceId: !!referenceTraceId,
|
|
952
|
+
});
|
|
953
|
+
}
|
|
954
|
+
catch (error) {
|
|
955
|
+
if (error instanceof normalizeAnalyzeOptions_1.AnalyzeOptionsError) {
|
|
956
|
+
res.status(error.httpStatus).json({
|
|
957
|
+
success: false,
|
|
958
|
+
error: error.message,
|
|
959
|
+
code: error.code,
|
|
960
|
+
});
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
963
|
+
throw error;
|
|
964
|
+
}
|
|
940
965
|
if (requestedSessionId && !requestedSessionIsVisible(requestedSessionId, requestContext)) {
|
|
941
966
|
(0, resourceOwnership_1.sendResourceNotFound)(res, 'Session not found');
|
|
942
967
|
return;
|
|
@@ -1080,6 +1105,49 @@ async function handleAnalyzeRequest(req, res, requestedSessionIdOverride) {
|
|
|
1080
1105
|
runId: runContext.runId,
|
|
1081
1106
|
runSequence: runContext.sequence,
|
|
1082
1107
|
});
|
|
1108
|
+
if (options.preset === 'smart') {
|
|
1109
|
+
runSmartAnalysis(sessionId, query, traceId, {
|
|
1110
|
+
runContext,
|
|
1111
|
+
traceProcessorService,
|
|
1112
|
+
smartAction: options.smartAction ?? 'preview',
|
|
1113
|
+
smartSelection: options.smartSelection,
|
|
1114
|
+
forceRefresh: options.forceRefresh === true,
|
|
1115
|
+
analysisMode: options.analysisMode,
|
|
1116
|
+
blockedStrategyIds,
|
|
1117
|
+
owner: (0, resourceOwnership_1.ownerFieldsFromContext)(requestContext),
|
|
1118
|
+
}).catch((error) => {
|
|
1119
|
+
const session = assistantAppService.getSession(sessionId);
|
|
1120
|
+
if (session) {
|
|
1121
|
+
session.logger.error('AgentRoutes', 'Smart analysis failed', error);
|
|
1122
|
+
session.status = 'failed';
|
|
1123
|
+
session.error = error.message;
|
|
1124
|
+
markSessionRunStatus(session, 'failed', error.message);
|
|
1125
|
+
broadcastToAgentDrivenClients(sessionId, {
|
|
1126
|
+
type: 'error',
|
|
1127
|
+
content: { message: error.message, error: error.message },
|
|
1128
|
+
timestamp: Date.now(),
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1132
|
+
res.json({
|
|
1133
|
+
success: true,
|
|
1134
|
+
sessionId,
|
|
1135
|
+
message: isNewSession ? 'Smart analysis started' : 'Smart analysis started',
|
|
1136
|
+
isNewSession,
|
|
1137
|
+
providerSnapshotChanged: preparedSession?.providerSnapshotChanged || undefined,
|
|
1138
|
+
architecture: 'agent-driven',
|
|
1139
|
+
preset: 'smart',
|
|
1140
|
+
runId: runContext.runId,
|
|
1141
|
+
requestId: runContext.requestId,
|
|
1142
|
+
runSequence: runContext.sequence,
|
|
1143
|
+
observability: {
|
|
1144
|
+
runId: runContext.runId,
|
|
1145
|
+
requestId: runContext.requestId,
|
|
1146
|
+
runSequence: runContext.sequence,
|
|
1147
|
+
},
|
|
1148
|
+
});
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1083
1151
|
let agentRunLease = null;
|
|
1084
1152
|
let referenceAgentRunLease = null;
|
|
1085
1153
|
let agentRunLeaseDecision = null;
|
|
@@ -1840,6 +1908,10 @@ router.post('/:sessionId/cancel', (req, res) => {
|
|
|
1840
1908
|
return;
|
|
1841
1909
|
// Mark session as failed/cancelled
|
|
1842
1910
|
if (session.status === 'running' || session.status === 'pending') {
|
|
1911
|
+
const smartCancelled = smartCancelBridge.cancel(sessionId);
|
|
1912
|
+
if (smartCancelled)
|
|
1913
|
+
smartCancelBridge.tryClaimTerminal(sessionId);
|
|
1914
|
+
const sceneCancelled = sceneStoryService.cancel(sessionId);
|
|
1843
1915
|
session.status = 'failed';
|
|
1844
1916
|
session.error = 'Cancelled by user';
|
|
1845
1917
|
markSessionRunStatus(session, 'failed', 'Cancelled by user');
|
|
@@ -1857,7 +1929,11 @@ router.post('/:sessionId/cancel', (req, res) => {
|
|
|
1857
1929
|
catch { /* client may already be closed */ }
|
|
1858
1930
|
}
|
|
1859
1931
|
session.sseClients = [];
|
|
1860
|
-
session.logger.info('AgentRoutes', 'Session cancelled by user', {
|
|
1932
|
+
session.logger.info('AgentRoutes', 'Session cancelled by user', {
|
|
1933
|
+
sessionId,
|
|
1934
|
+
smartCancelled,
|
|
1935
|
+
sceneCancelled,
|
|
1936
|
+
});
|
|
1861
1937
|
}
|
|
1862
1938
|
return res.json({ success: true, sessionId, status: session.status });
|
|
1863
1939
|
});
|
|
@@ -2000,6 +2076,7 @@ router.get('/:sessionId/focus', (req, res) => {
|
|
|
2000
2076
|
// traces (no content hash, so they live for the lifetime of the backend).
|
|
2001
2077
|
const sceneReportStore = new sceneReportStore_1.FileSystemSceneReportStore(config_1.sceneStoryConfig.reportDir);
|
|
2002
2078
|
const sceneReportMemoryCache = new sceneReportMemoryCache_1.SceneReportMemoryCache(config_1.sceneStoryConfig.memoryCacheMaxSize);
|
|
2079
|
+
const sceneJobArtifactStore = new sceneJobArtifactStore_1.FileSystemSceneJobArtifactStore(config_1.sceneStoryConfig.jobArtifactDir);
|
|
2003
2080
|
// Singleton — sceneStoryService holds per-session JobRunner state for cancel
|
|
2004
2081
|
// lookup, so it must outlive a single request. SkillExecutor is still created
|
|
2005
2082
|
// per-request inside the route handler.
|
|
@@ -2008,6 +2085,7 @@ const sceneStoryService = new sceneStoryService_1.SceneStoryService({
|
|
|
2008
2085
|
getSession: (id) => assistantAppService.getSession(id),
|
|
2009
2086
|
reportStore: sceneReportStore,
|
|
2010
2087
|
memoryCache: sceneReportMemoryCache,
|
|
2088
|
+
jobArtifactStore: sceneJobArtifactStore,
|
|
2011
2089
|
computeHash: (traceId) => (0, traceHash_1.computeTraceContentHash)((0, traceProcessorService_1.getTraceProcessorService)(), traceId),
|
|
2012
2090
|
probeDuration: (traceId) => (0, sceneTraceDurationProbe_1.probeTraceDuration)((0, traceProcessorService_1.getTraceProcessorService)(), traceId),
|
|
2013
2091
|
});
|
|
@@ -2043,6 +2121,196 @@ const SCENE_EXTRACTION_STEP_IDS = new Set([
|
|
|
2043
2121
|
'jank_events',
|
|
2044
2122
|
'clean_timeline',
|
|
2045
2123
|
]);
|
|
2124
|
+
async function runSmartAnalysis(sessionId, query, traceId, options) {
|
|
2125
|
+
const session = assistantAppService.getSession(sessionId);
|
|
2126
|
+
if (!session)
|
|
2127
|
+
return;
|
|
2128
|
+
const startedAt = Date.now();
|
|
2129
|
+
session.activeRun = {
|
|
2130
|
+
...options.runContext,
|
|
2131
|
+
query,
|
|
2132
|
+
status: 'running',
|
|
2133
|
+
startedAt: options.runContext.startedAt || startedAt,
|
|
2134
|
+
};
|
|
2135
|
+
session.lastRun = { ...session.activeRun };
|
|
2136
|
+
session.status = 'running';
|
|
2137
|
+
session.lastActivityAt = Date.now();
|
|
2138
|
+
persistSessionRunState(session, 'running');
|
|
2139
|
+
const runHeartbeatInterval = startSessionRunHeartbeat(session);
|
|
2140
|
+
const cancelToken = smartCancelBridge.create(sessionId);
|
|
2141
|
+
let dispatchedToAgentDeepDive = false;
|
|
2142
|
+
session.logger.info('SmartAnalysis', 'Starting smart analysis', {
|
|
2143
|
+
query,
|
|
2144
|
+
traceId,
|
|
2145
|
+
smartAction: options.smartAction,
|
|
2146
|
+
smartSelection: options.smartSelection,
|
|
2147
|
+
runId: session.activeRun?.runId,
|
|
2148
|
+
requestId: session.activeRun?.requestId,
|
|
2149
|
+
});
|
|
2150
|
+
try {
|
|
2151
|
+
await (0, skillLoader_1.ensureSkillRegistryInitialized)();
|
|
2152
|
+
const skillExecutor = new skillExecutor_1.SkillExecutor(options.traceProcessorService);
|
|
2153
|
+
skillExecutor.registerSkills(skillLoader_1.skillRegistry.getAllSkills());
|
|
2154
|
+
let report = null;
|
|
2155
|
+
if (options.smartAction === 'analyze') {
|
|
2156
|
+
report = await resolveSmartPreviewReportForSelection({
|
|
2157
|
+
session,
|
|
2158
|
+
selection: options.smartSelection,
|
|
2159
|
+
traceId,
|
|
2160
|
+
owner: options.owner,
|
|
2161
|
+
});
|
|
2162
|
+
}
|
|
2163
|
+
if (!report) {
|
|
2164
|
+
report = await sceneStoryService.start({
|
|
2165
|
+
sessionId,
|
|
2166
|
+
traceId,
|
|
2167
|
+
skillExecutor,
|
|
2168
|
+
owner: options.owner,
|
|
2169
|
+
options: {
|
|
2170
|
+
routeProfile: 'smart',
|
|
2171
|
+
previewOnly: true,
|
|
2172
|
+
forceRefresh: options.smartAction === 'preview'
|
|
2173
|
+
? true
|
|
2174
|
+
: options.forceRefresh,
|
|
2175
|
+
cancelToken,
|
|
2176
|
+
},
|
|
2177
|
+
});
|
|
2178
|
+
}
|
|
2179
|
+
if (!report) {
|
|
2180
|
+
throw new Error(session.error || 'Smart analysis failed before report finalization');
|
|
2181
|
+
}
|
|
2182
|
+
if (options.smartAction === 'preview') {
|
|
2183
|
+
const result = (0, buildSmartChatReport_1.buildSmartSceneSelectionReport)({
|
|
2184
|
+
sessionId,
|
|
2185
|
+
report,
|
|
2186
|
+
totalDurationMs: Date.now() - startedAt,
|
|
2187
|
+
});
|
|
2188
|
+
if (!smartCancelBridge.tryClaimTerminal(sessionId)) {
|
|
2189
|
+
session.logger.warn('SmartAnalysis', 'Skipping late smart preview terminal', {
|
|
2190
|
+
sessionId,
|
|
2191
|
+
runId: session.activeRun?.runId,
|
|
2192
|
+
});
|
|
2193
|
+
return;
|
|
2194
|
+
}
|
|
2195
|
+
completeAgentDrivenSessionWithResult({
|
|
2196
|
+
sessionId,
|
|
2197
|
+
query,
|
|
2198
|
+
traceId,
|
|
2199
|
+
session,
|
|
2200
|
+
result,
|
|
2201
|
+
logComponent: 'SmartAnalysis',
|
|
2202
|
+
});
|
|
2203
|
+
return;
|
|
2204
|
+
}
|
|
2205
|
+
const dispatch = (0, smartDeepDiveDispatch_1.buildSmartDeepDiveDispatch)({
|
|
2206
|
+
report,
|
|
2207
|
+
selection: options.smartSelection ?? { scope: 'all' },
|
|
2208
|
+
});
|
|
2209
|
+
if (!dispatch) {
|
|
2210
|
+
throw new Error('所选范围没有匹配到可深钻场景,请返回场景盘点后重新选择。');
|
|
2211
|
+
}
|
|
2212
|
+
session.logger.info('SmartAnalysis', 'Dispatching smart selection to agent deep dive', {
|
|
2213
|
+
query: dispatch.query,
|
|
2214
|
+
selectedSceneCount: dispatch.selectedScenes.length,
|
|
2215
|
+
packageName: dispatch.packageName,
|
|
2216
|
+
previewReportId: report.reportId,
|
|
2217
|
+
runId: session.activeRun?.runId,
|
|
2218
|
+
requestId: session.activeRun?.requestId,
|
|
2219
|
+
});
|
|
2220
|
+
broadcastToAgentDrivenClients(sessionId, {
|
|
2221
|
+
type: 'progress',
|
|
2222
|
+
content: {
|
|
2223
|
+
phase: 'smart_deep_dive_dispatch',
|
|
2224
|
+
message: `已选中 ${dispatch.selectedScenes.length} 个场景,进入详细分析`,
|
|
2225
|
+
},
|
|
2226
|
+
timestamp: Date.now(),
|
|
2227
|
+
});
|
|
2228
|
+
dispatchedToAgentDeepDive = true;
|
|
2229
|
+
await runAgentDrivenAnalysis(sessionId, dispatch.query, traceId, {
|
|
2230
|
+
traceProcessorService: options.traceProcessorService,
|
|
2231
|
+
runContext: options.runContext,
|
|
2232
|
+
blockedStrategyIds: options.blockedStrategyIds,
|
|
2233
|
+
selectionContext: dispatch.selectionContext,
|
|
2234
|
+
traceContext: dispatch.traceContext,
|
|
2235
|
+
packageName: dispatch.packageName,
|
|
2236
|
+
analysisMode: resolveSmartDeepDiveAnalysisMode(options.analysisMode),
|
|
2237
|
+
generateTracks: false,
|
|
2238
|
+
});
|
|
2239
|
+
}
|
|
2240
|
+
catch (error) {
|
|
2241
|
+
session.status = 'failed';
|
|
2242
|
+
session.error = error.message || String(error);
|
|
2243
|
+
markSessionRunStatus(session, 'failed', session.error);
|
|
2244
|
+
session.logger.error('SmartAnalysis', 'Smart analysis failed', error);
|
|
2245
|
+
if (!dispatchedToAgentDeepDive && smartCancelBridge.tryClaimTerminal(sessionId)) {
|
|
2246
|
+
broadcastToAgentDrivenClients(sessionId, {
|
|
2247
|
+
type: 'error',
|
|
2248
|
+
content: { message: session.error, error: session.error },
|
|
2249
|
+
timestamp: Date.now(),
|
|
2250
|
+
});
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
finally {
|
|
2254
|
+
smartCancelBridge.release(sessionId);
|
|
2255
|
+
if (runHeartbeatInterval) {
|
|
2256
|
+
clearInterval(runHeartbeatInterval);
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
function resolveSmartDeepDiveAnalysisMode(mode) {
|
|
2261
|
+
return mode === 'fast' ? 'fast' : 'full';
|
|
2262
|
+
}
|
|
2263
|
+
async function resolveSmartPreviewReportForSelection(input) {
|
|
2264
|
+
const requestedReportId = input.selection?.reportId || input.selection?.sceneSnapshotId;
|
|
2265
|
+
const sessionReport = input.session.sceneStoryReport;
|
|
2266
|
+
if (isUsableSmartPreviewReport(sessionReport, input.traceId, input.owner, requestedReportId)) {
|
|
2267
|
+
return sessionReport;
|
|
2268
|
+
}
|
|
2269
|
+
if (!requestedReportId)
|
|
2270
|
+
return null;
|
|
2271
|
+
const persisted = await sceneStoryService.getReport(requestedReportId);
|
|
2272
|
+
if (isUsableSmartPreviewReport(persisted, input.traceId, input.owner, requestedReportId)) {
|
|
2273
|
+
return persisted;
|
|
2274
|
+
}
|
|
2275
|
+
return null;
|
|
2276
|
+
}
|
|
2277
|
+
function isUsableSmartPreviewReport(report, traceId, owner, requestedReportId) {
|
|
2278
|
+
if (!report)
|
|
2279
|
+
return false;
|
|
2280
|
+
if (requestedReportId && report.reportId !== requestedReportId)
|
|
2281
|
+
return false;
|
|
2282
|
+
if (report.traceId !== traceId)
|
|
2283
|
+
return false;
|
|
2284
|
+
return (0, resourceOwnership_1.ownersMatch)(report, owner);
|
|
2285
|
+
}
|
|
2286
|
+
function completeAgentDrivenSessionWithResult(input) {
|
|
2287
|
+
(0, finalizeAgentDrivenSession_1.finalizeAgentDrivenSession)(input, {
|
|
2288
|
+
applyFinalResultQualityGate: finalResultQualityGate_1.applyFinalResultQualityGate,
|
|
2289
|
+
broadcast: broadcastToAgentDrivenClients,
|
|
2290
|
+
buildConversationStepUpdate,
|
|
2291
|
+
appendConversationStep,
|
|
2292
|
+
annotateLatestCompletedTurn: (sessionId, traceId, result) => {
|
|
2293
|
+
enhancedSessionContext_1.sessionContextManager.get(sessionId, traceId)?.annotateLatestCompletedTurn({
|
|
2294
|
+
success: result.success,
|
|
2295
|
+
findings: result.findings,
|
|
2296
|
+
message: result.conclusion,
|
|
2297
|
+
confidence: result.confidence,
|
|
2298
|
+
partial: result.partial,
|
|
2299
|
+
terminationReason: result.terminationReason,
|
|
2300
|
+
terminationMessage: result.terminationMessage,
|
|
2301
|
+
conclusionContract: result.conclusionContract,
|
|
2302
|
+
claimSupport: result.claimSupport,
|
|
2303
|
+
claimVerificationResult: result.claimVerificationResult,
|
|
2304
|
+
identityResolutions: result.identityResolutions,
|
|
2305
|
+
});
|
|
2306
|
+
},
|
|
2307
|
+
terminalRunStatusForResult,
|
|
2308
|
+
markSessionRunStatus,
|
|
2309
|
+
persistAgentTurn: persistAgentSession_1.persistAgentTurn,
|
|
2310
|
+
ensureCompletedAnalysisSseEvents,
|
|
2311
|
+
sendAgentDrivenResult,
|
|
2312
|
+
});
|
|
2313
|
+
}
|
|
2046
2314
|
function objectRowsToEnvelopePayload(rows) {
|
|
2047
2315
|
if (!Array.isArray(rows) || rows.length === 0) {
|
|
2048
2316
|
return { columns: [], rows: [] };
|
|
@@ -2640,33 +2908,6 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
|
|
|
2640
2908
|
return runWithTraceProcessorLease(analyze);
|
|
2641
2909
|
});
|
|
2642
2910
|
console.log('[AgentRoutes.AgentDriven] analyze completed, success:', result.success);
|
|
2643
|
-
session.result = result;
|
|
2644
|
-
delete session.completedAnalysisFinalArtifacts;
|
|
2645
|
-
// Accumulate hypotheses across turns (deduplicate by id)
|
|
2646
|
-
const existingIds = new Set(session.hypotheses.map(h => h.id));
|
|
2647
|
-
for (const h of result.hypotheses) {
|
|
2648
|
-
if (!existingIds.has(h.id)) {
|
|
2649
|
-
session.hypotheses.push(h);
|
|
2650
|
-
}
|
|
2651
|
-
else {
|
|
2652
|
-
// Update existing hypothesis with latest status
|
|
2653
|
-
const idx = session.hypotheses.findIndex(eh => eh.id === h.id);
|
|
2654
|
-
if (idx >= 0)
|
|
2655
|
-
session.hypotheses[idx] = h;
|
|
2656
|
-
}
|
|
2657
|
-
}
|
|
2658
|
-
const terminalRunStatus = terminalRunStatusForResult(result);
|
|
2659
|
-
// Record conclusion in cross-turn history
|
|
2660
|
-
if (!session.conclusionHistory)
|
|
2661
|
-
session.conclusionHistory = [];
|
|
2662
|
-
if (result.conclusion) {
|
|
2663
|
-
session.conclusionHistory.push({
|
|
2664
|
-
turn: session.runSequence || 1,
|
|
2665
|
-
conclusion: result.conclusion,
|
|
2666
|
-
confidence: result.confidence ?? 0,
|
|
2667
|
-
timestamp: Date.now(),
|
|
2668
|
-
});
|
|
2669
|
-
}
|
|
2670
2911
|
// Ensure trackEvents/scenes are computed for completed sessions (even without SSE clients)
|
|
2671
2912
|
if (shouldGenerateTracks) {
|
|
2672
2913
|
updateSceneReconstructionArtifactsFromEnvelopes(session, session.dataEnvelopes);
|
|
@@ -2709,101 +2950,16 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
|
|
|
2709
2950
|
if (normalizedConclusionContract) {
|
|
2710
2951
|
result.conclusionContract = normalizedConclusionContract;
|
|
2711
2952
|
}
|
|
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
|
-
}
|
|
2953
|
+
ensureAnalysisQualityArtifacts(session, normalizedConclusionContract, result);
|
|
2743
2954
|
}
|
|
2744
|
-
|
|
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);
|
|
2766
|
-
// Log completion details
|
|
2767
|
-
logger.info('AgentDrivenAnalysis', 'Agent-driven analysis completed', {
|
|
2768
|
-
confidence: result.confidence,
|
|
2769
|
-
rounds: result.rounds,
|
|
2770
|
-
findingsCount: result.findings.length,
|
|
2771
|
-
hypothesesCount: result.hypotheses.length,
|
|
2772
|
-
claimSupportCount: result.claimSupport?.length || 0,
|
|
2773
|
-
claimVerifierStatus: result.claimVerificationResult?.status,
|
|
2774
|
-
partial: result.partial,
|
|
2775
|
-
terminationReason: result.terminationReason,
|
|
2776
|
-
runId: session.activeRun?.runId,
|
|
2777
|
-
requestId: session.activeRun?.requestId,
|
|
2778
|
-
runSequence: session.activeRun?.sequence,
|
|
2779
|
-
});
|
|
2780
|
-
// Persist session state via shared helper — see services/persistAgentSession.ts.
|
|
2781
|
-
// CLI's cliAnalyzeService routes through the same function.
|
|
2782
|
-
(0, persistAgentSession_1.persistAgentTurn)({
|
|
2783
|
-
session,
|
|
2955
|
+
completeAgentDrivenSessionWithResult({
|
|
2784
2956
|
sessionId,
|
|
2785
|
-
traceId,
|
|
2786
2957
|
query,
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
// on 'AgentDrivenAnalysis' keep matching persist-related events.
|
|
2958
|
+
traceId,
|
|
2959
|
+
session,
|
|
2960
|
+
result,
|
|
2791
2961
|
logComponent: 'AgentDrivenAnalysis',
|
|
2792
2962
|
});
|
|
2793
|
-
// Send final result
|
|
2794
|
-
const clientCount = session.sseClients.length;
|
|
2795
|
-
logger.info('AgentRoutes', 'Sending agent-driven result', { clientCount });
|
|
2796
|
-
ensureCompletedAnalysisSseEvents(session);
|
|
2797
|
-
session.sseClients.forEach((client, index) => {
|
|
2798
|
-
try {
|
|
2799
|
-
logger.info('AgentRoutes', `Sending agent-driven result to client ${index + 1}/${clientCount}`);
|
|
2800
|
-
sendAgentDrivenResult(client, session);
|
|
2801
|
-
}
|
|
2802
|
-
catch (e) {
|
|
2803
|
-
logger.error('AgentRoutes', `Error sending agent-driven result to client ${index + 1}`, e);
|
|
2804
|
-
}
|
|
2805
|
-
});
|
|
2806
|
-
logger.close();
|
|
2807
2963
|
}
|
|
2808
2964
|
catch (error) {
|
|
2809
2965
|
session.status = 'failed';
|
|
@@ -4488,6 +4644,7 @@ function ensureCompletedAnalysisResultPayload(session) {
|
|
|
4488
4644
|
return undefined;
|
|
4489
4645
|
const replayOnlyScene = isSceneReplayOnlyQuery(session.query);
|
|
4490
4646
|
const hasEvidenceBackedConclusion = result.success || result.partial === true;
|
|
4647
|
+
const isSmartResult = result.conclusionContract?.metadata?.sceneId === 'smart';
|
|
4491
4648
|
const normalizedConclusion = replayOnlyScene
|
|
4492
4649
|
? buildSceneReplayNarrative(session.scenes || [])
|
|
4493
4650
|
: hasEvidenceBackedConclusion ? appendEvidenceIndexIfMissing(normalizeNarrativeForClient(result.conclusion), session.dataEnvelopes || []) : normalizeNarrativeForClient(result.conclusion);
|
|
@@ -4500,12 +4657,14 @@ function ensureCompletedAnalysisResultPayload(session) {
|
|
|
4500
4657
|
});
|
|
4501
4658
|
const normalizedConclusionContract = replayOnlyScene
|
|
4502
4659
|
? undefined
|
|
4503
|
-
:
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4660
|
+
: isSmartResult
|
|
4661
|
+
? result.conclusionContract
|
|
4662
|
+
: hasEvidenceBackedConclusion ? ((0, agentResultNormalizer_1.deriveEvidenceBackedConclusionContractForNarrative)(result.conclusion, session.dataEnvelopes || [], {
|
|
4663
|
+
existingContract: result.conclusionContract,
|
|
4664
|
+
mode: result.rounds > 1 ? 'focused_answer' : 'initial_report',
|
|
4665
|
+
sceneId: sceneIdHint,
|
|
4666
|
+
}) ||
|
|
4667
|
+
undefined) : undefined;
|
|
4509
4668
|
const qualityArtifacts = hasEvidenceBackedConclusion && !replayOnlyScene
|
|
4510
4669
|
? ensureAnalysisQualityArtifacts(session, normalizedConclusionContract)
|
|
4511
4670
|
: {};
|
|
@@ -4613,6 +4772,7 @@ function ensureCompletedAnalysisSseEvents(session) {
|
|
|
4613
4772
|
partial: result.partial,
|
|
4614
4773
|
terminationReason: result.terminationReason,
|
|
4615
4774
|
terminationMessage: result.terminationMessage,
|
|
4775
|
+
smartScenePreview: result.smartScenePreview,
|
|
4616
4776
|
findings: clientFindings,
|
|
4617
4777
|
resultContract,
|
|
4618
4778
|
hypotheses: result.hypotheses.map((h) => ({
|