@gracker/smartperfetto 1.0.14 → 1.0.16

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.
Files changed (307) hide show
  1. package/.env.example +16 -8
  2. package/dist/agent/agents/base/baseAgent.d.ts.map +1 -1
  3. package/dist/agent/agents/base/baseAgent.js +5 -1
  4. package/dist/agent/agents/base/baseAgent.js.map +1 -1
  5. package/dist/agent/context/enhancedSessionContext.d.ts +5 -0
  6. package/dist/agent/context/enhancedSessionContext.d.ts.map +1 -1
  7. package/dist/agent/context/enhancedSessionContext.js +13 -0
  8. package/dist/agent/context/enhancedSessionContext.js.map +1 -1
  9. package/dist/agent/core/conclusionContract.d.ts +16 -1
  10. package/dist/agent/core/conclusionContract.d.ts.map +1 -1
  11. package/dist/agent/core/conclusionGenerator.d.ts.map +1 -1
  12. package/dist/agent/core/conclusionGenerator.js +90 -7
  13. package/dist/agent/core/conclusionGenerator.js.map +1 -1
  14. package/dist/agent/core/executors/directSkillExecutor.d.ts.map +1 -1
  15. package/dist/agent/core/executors/directSkillExecutor.js +6 -12
  16. package/dist/agent/core/executors/directSkillExecutor.js.map +1 -1
  17. package/dist/agent/core/orchestratorTypes.d.ts +16 -0
  18. package/dist/agent/core/orchestratorTypes.d.ts.map +1 -1
  19. package/dist/agent/core/orchestratorTypes.js.map +1 -1
  20. package/dist/agent/experts/crossDomain/moduleExpertInvoker.d.ts.map +1 -1
  21. package/dist/agent/experts/crossDomain/moduleExpertInvoker.js +4 -1
  22. package/dist/agent/experts/crossDomain/moduleExpertInvoker.js.map +1 -1
  23. package/dist/agent/scene/sceneStage1Runner.d.ts +1 -1
  24. package/dist/agent/scene/sceneStage1Runner.d.ts.map +1 -1
  25. package/dist/agent/scene/sceneStage1Runner.js +1 -1
  26. package/dist/agent/scene/sceneStage1Runner.js.map +1 -1
  27. package/dist/agent/scene/sceneStoryService.d.ts +1 -1
  28. package/dist/agent/scene/sceneStoryService.d.ts.map +1 -1
  29. package/dist/agent/scene/sceneStoryService.js +4 -1
  30. package/dist/agent/scene/sceneStoryService.js.map +1 -1
  31. package/dist/agent/types/agentProtocol.d.ts.map +1 -1
  32. package/dist/agent/types/agentProtocol.js +4 -1
  33. package/dist/agent/types/agentProtocol.js.map +1 -1
  34. package/dist/agent/types.d.ts +7 -0
  35. package/dist/agent/types.d.ts.map +1 -1
  36. package/dist/agent/types.js.map +1 -1
  37. package/dist/agentOpenAI/openAiRuntime.d.ts.map +1 -1
  38. package/dist/agentOpenAI/openAiRuntime.js +11 -1
  39. package/dist/agentOpenAI/openAiRuntime.js.map +1 -1
  40. package/dist/agentOpenAI/openAiToolAdapter.d.ts.map +1 -1
  41. package/dist/agentOpenAI/openAiToolAdapter.js +27 -2
  42. package/dist/agentOpenAI/openAiToolAdapter.js.map +1 -1
  43. package/dist/agentv3/artifactStore.d.ts +5 -0
  44. package/dist/agentv3/artifactStore.d.ts.map +1 -1
  45. package/dist/agentv3/artifactStore.js +3 -0
  46. package/dist/agentv3/artifactStore.js.map +1 -1
  47. package/dist/agentv3/claudeMcpServer.d.ts +15 -1
  48. package/dist/agentv3/claudeMcpServer.d.ts.map +1 -1
  49. package/dist/agentv3/claudeMcpServer.js +436 -91
  50. package/dist/agentv3/claudeMcpServer.js.map +1 -1
  51. package/dist/agentv3/claudeRuntime.d.ts.map +1 -1
  52. package/dist/agentv3/claudeRuntime.js +17 -0
  53. package/dist/agentv3/claudeRuntime.js.map +1 -1
  54. package/dist/agentv3/claudeSystemPrompt.d.ts.map +1 -1
  55. package/dist/agentv3/claudeSystemPrompt.js +9 -0
  56. package/dist/agentv3/claudeSystemPrompt.js.map +1 -1
  57. package/dist/agentv3/mcpToolRegistry.d.ts +14 -2
  58. package/dist/agentv3/mcpToolRegistry.d.ts.map +1 -1
  59. package/dist/agentv3/mcpToolRegistry.js +25 -6
  60. package/dist/agentv3/mcpToolRegistry.js.map +1 -1
  61. package/dist/agentv3/sessionStateSnapshot.d.ts +41 -0
  62. package/dist/agentv3/sessionStateSnapshot.d.ts.map +1 -1
  63. package/dist/agentv3/types.d.ts +5 -0
  64. package/dist/agentv3/types.d.ts.map +1 -1
  65. package/dist/agentv3/types.js.map +1 -1
  66. package/dist/assistant/application/agentAnalyzeSessionService.d.ts +6 -0
  67. package/dist/assistant/application/agentAnalyzeSessionService.d.ts.map +1 -1
  68. package/dist/assistant/application/agentAnalyzeSessionService.js +9 -3
  69. package/dist/assistant/application/agentAnalyzeSessionService.js.map +1 -1
  70. package/dist/assistant/application/assistantApplicationService.d.ts.map +1 -1
  71. package/dist/assistant/application/assistantApplicationService.js +3 -1
  72. package/dist/assistant/application/assistantApplicationService.js.map +1 -1
  73. package/dist/cli-user/bin.js +99 -1
  74. package/dist/cli-user/bin.js.map +1 -1
  75. package/dist/cli-user/commands/analyze.d.ts +3 -0
  76. package/dist/cli-user/commands/analyze.d.ts.map +1 -1
  77. package/dist/cli-user/commands/analyze.js +2 -0
  78. package/dist/cli-user/commands/analyze.js.map +1 -1
  79. package/dist/cli-user/commands/codebase.d.ts +29 -0
  80. package/dist/cli-user/commands/codebase.d.ts.map +1 -0
  81. package/dist/cli-user/commands/codebase.js +152 -0
  82. package/dist/cli-user/commands/codebase.js.map +1 -0
  83. package/dist/cli-user/commands/config.d.ts.map +1 -1
  84. package/dist/cli-user/commands/config.js +4 -1
  85. package/dist/cli-user/commands/config.js.map +1 -1
  86. package/dist/cli-user/commands/report.js +64 -0
  87. package/dist/cli-user/commands/report.js.map +1 -1
  88. package/dist/cli-user/io/paths.d.ts +3 -0
  89. package/dist/cli-user/io/paths.d.ts.map +1 -1
  90. package/dist/cli-user/io/paths.js +6 -0
  91. package/dist/cli-user/io/paths.js.map +1 -1
  92. package/dist/cli-user/io/sessionStore.d.ts +1 -0
  93. package/dist/cli-user/io/sessionStore.d.ts.map +1 -1
  94. package/dist/cli-user/io/sessionStore.js +5 -0
  95. package/dist/cli-user/io/sessionStore.js.map +1 -1
  96. package/dist/cli-user/repl/renderer.d.ts +8 -0
  97. package/dist/cli-user/repl/renderer.d.ts.map +1 -1
  98. package/dist/cli-user/repl/renderer.js.map +1 -1
  99. package/dist/cli-user/services/cliAnalyzeService.d.ts +6 -0
  100. package/dist/cli-user/services/cliAnalyzeService.d.ts.map +1 -1
  101. package/dist/cli-user/services/cliAnalyzeService.js +183 -29
  102. package/dist/cli-user/services/cliAnalyzeService.js.map +1 -1
  103. package/dist/cli-user/services/turnPersistence.d.ts +0 -10
  104. package/dist/cli-user/services/turnPersistence.d.ts.map +1 -1
  105. package/dist/cli-user/services/turnPersistence.js +62 -0
  106. package/dist/cli-user/services/turnPersistence.js.map +1 -1
  107. package/dist/cli-user/services/turnRunner.d.ts +3 -0
  108. package/dist/cli-user/services/turnRunner.d.ts.map +1 -1
  109. package/dist/cli-user/services/turnRunner.js +6 -0
  110. package/dist/cli-user/services/turnRunner.js.map +1 -1
  111. package/dist/cli-user/types.d.ts +5 -0
  112. package/dist/cli-user/types.d.ts.map +1 -1
  113. package/dist/routes/agentReportRoutes.d.ts +1 -0
  114. package/dist/routes/agentReportRoutes.d.ts.map +1 -1
  115. package/dist/routes/agentReportRoutes.js +13 -2
  116. package/dist/routes/agentReportRoutes.js.map +1 -1
  117. package/dist/routes/agentResumeRoutes.d.ts.map +1 -1
  118. package/dist/routes/agentResumeRoutes.js +29 -5
  119. package/dist/routes/agentResumeRoutes.js.map +1 -1
  120. package/dist/routes/agentRoutes.d.ts.map +1 -1
  121. package/dist/routes/agentRoutes.js +297 -91
  122. package/dist/routes/agentRoutes.js.map +1 -1
  123. package/dist/routes/ragAdminRoutes.d.ts +13 -24
  124. package/dist/routes/ragAdminRoutes.d.ts.map +1 -1
  125. package/dist/routes/ragAdminRoutes.js +266 -11
  126. package/dist/routes/ragAdminRoutes.js.map +1 -1
  127. package/dist/scripts/verifyAgentSseScrolling.js +119 -3
  128. package/dist/scripts/verifyAgentSseScrolling.js.map +1 -1
  129. package/dist/services/agentEventStore.d.ts.map +1 -1
  130. package/dist/services/agentEventStore.js +13 -3
  131. package/dist/services/agentEventStore.js.map +1 -1
  132. package/dist/services/agentReportData.d.ts +3 -0
  133. package/dist/services/agentReportData.d.ts.map +1 -1
  134. package/dist/services/agentReportData.js.map +1 -1
  135. package/dist/services/analysisResultSnapshotPipeline.d.ts +3 -0
  136. package/dist/services/analysisResultSnapshotPipeline.d.ts.map +1 -1
  137. package/dist/services/analysisResultSnapshotPipeline.js +3 -0
  138. package/dist/services/analysisResultSnapshotPipeline.js.map +1 -1
  139. package/dist/services/analysisResultSnapshotStore.d.ts.map +1 -1
  140. package/dist/services/analysisResultSnapshotStore.js +34 -2
  141. package/dist/services/analysisResultSnapshotStore.js.map +1 -1
  142. package/dist/services/aospKnowledgeIngester.d.ts +7 -0
  143. package/dist/services/aospKnowledgeIngester.d.ts.map +1 -1
  144. package/dist/services/aospKnowledgeIngester.js +19 -7
  145. package/dist/services/aospKnowledgeIngester.js.map +1 -1
  146. package/dist/services/auth/codebaseScopes.d.ts +6 -0
  147. package/dist/services/auth/codebaseScopes.d.ts.map +1 -0
  148. package/dist/services/auth/codebaseScopes.js +23 -0
  149. package/dist/services/auth/codebaseScopes.js.map +1 -0
  150. package/dist/services/codebase/codeAwareFeature.d.ts +4 -0
  151. package/dist/services/codebase/codeAwareFeature.d.ts.map +1 -0
  152. package/dist/services/codebase/codeAwareFeature.js +18 -0
  153. package/dist/services/codebase/codeAwareFeature.js.map +1 -0
  154. package/dist/services/codebase/codeLookupLedger.d.ts +37 -0
  155. package/dist/services/codebase/codeLookupLedger.d.ts.map +1 -0
  156. package/dist/services/codebase/codeLookupLedger.js +126 -0
  157. package/dist/services/codebase/codeLookupLedger.js.map +1 -0
  158. package/dist/services/codebase/codebaseRegistry.d.ts +76 -0
  159. package/dist/services/codebase/codebaseRegistry.d.ts.map +1 -0
  160. package/dist/services/codebase/codebaseRegistry.js +164 -0
  161. package/dist/services/codebase/codebaseRegistry.js.map +1 -0
  162. package/dist/services/codebase/defaultCodebaseServices.d.ts +5 -0
  163. package/dist/services/codebase/defaultCodebaseServices.d.ts.map +1 -0
  164. package/dist/services/codebase/defaultCodebaseServices.js +21 -0
  165. package/dist/services/codebase/defaultCodebaseServices.js.map +1 -0
  166. package/dist/services/codebase/patchProposer.d.ts +44 -0
  167. package/dist/services/codebase/patchProposer.d.ts.map +1 -0
  168. package/dist/services/codebase/patchProposer.js +163 -0
  169. package/dist/services/codebase/patchProposer.js.map +1 -0
  170. package/dist/services/codebase/pathSecurityGate.d.ts +33 -0
  171. package/dist/services/codebase/pathSecurityGate.d.ts.map +1 -0
  172. package/dist/services/codebase/pathSecurityGate.js +214 -0
  173. package/dist/services/codebase/pathSecurityGate.js.map +1 -0
  174. package/dist/services/enterpriseSchema.d.ts.map +1 -1
  175. package/dist/services/enterpriseSchema.js +11 -0
  176. package/dist/services/enterpriseSchema.js.map +1 -1
  177. package/dist/services/evidence/evidenceContractBuilder.d.ts +11 -0
  178. package/dist/services/evidence/evidenceContractBuilder.d.ts.map +1 -0
  179. package/dist/services/evidence/evidenceContractBuilder.js +530 -0
  180. package/dist/services/evidence/evidenceContractBuilder.js.map +1 -0
  181. package/dist/services/htmlReportGenerator.d.ts +9 -0
  182. package/dist/services/htmlReportGenerator.d.ts.map +1 -1
  183. package/dist/services/htmlReportGenerator.js +133 -0
  184. package/dist/services/htmlReportGenerator.js.map +1 -1
  185. package/dist/services/persistAgentSession.d.ts.map +1 -1
  186. package/dist/services/persistAgentSession.js +24 -0
  187. package/dist/services/persistAgentSession.js.map +1 -1
  188. package/dist/services/processIdentity/identityContractMapper.d.ts +14 -0
  189. package/dist/services/processIdentity/identityContractMapper.d.ts.map +1 -0
  190. package/dist/services/processIdentity/identityContractMapper.js +135 -0
  191. package/dist/services/processIdentity/identityContractMapper.js.map +1 -0
  192. package/dist/services/processIdentity/types.d.ts +5 -0
  193. package/dist/services/processIdentity/types.d.ts.map +1 -1
  194. package/dist/services/processIdentity/types.js.map +1 -1
  195. package/dist/services/rag/aospSourceIngester.d.ts +26 -0
  196. package/dist/services/rag/aospSourceIngester.d.ts.map +1 -0
  197. package/dist/services/rag/aospSourceIngester.js +143 -0
  198. package/dist/services/rag/aospSourceIngester.js.map +1 -0
  199. package/dist/services/rag/appSourceIngester.d.ts +37 -0
  200. package/dist/services/rag/appSourceIngester.d.ts.map +1 -0
  201. package/dist/services/rag/appSourceIngester.js +165 -0
  202. package/dist/services/rag/appSourceIngester.js.map +1 -0
  203. package/dist/services/rag/baseIngester.d.ts +18 -0
  204. package/dist/services/rag/baseIngester.d.ts.map +1 -0
  205. package/dist/services/rag/baseIngester.js +197 -0
  206. package/dist/services/rag/baseIngester.js.map +1 -0
  207. package/dist/services/rag/kernelSourceIngester.d.ts +35 -0
  208. package/dist/services/rag/kernelSourceIngester.d.ts.map +1 -0
  209. package/dist/services/rag/kernelSourceIngester.js +170 -0
  210. package/dist/services/rag/kernelSourceIngester.js.map +1 -0
  211. package/dist/services/rag/lookupResponseFilter.d.ts +42 -0
  212. package/dist/services/rag/lookupResponseFilter.d.ts.map +1 -0
  213. package/dist/services/rag/lookupResponseFilter.js +192 -0
  214. package/dist/services/rag/lookupResponseFilter.js.map +1 -0
  215. package/dist/services/rag/sessionToolResultRegistry.d.ts +25 -0
  216. package/dist/services/rag/sessionToolResultRegistry.d.ts.map +1 -0
  217. package/dist/services/rag/sessionToolResultRegistry.js +57 -0
  218. package/dist/services/rag/sessionToolResultRegistry.js.map +1 -0
  219. package/dist/services/rag/toolResultProjectionFilter.d.ts +18 -0
  220. package/dist/services/rag/toolResultProjectionFilter.d.ts.map +1 -0
  221. package/dist/services/rag/toolResultProjectionFilter.js +33 -0
  222. package/dist/services/rag/toolResultProjectionFilter.js.map +1 -0
  223. package/dist/services/ragStore.d.ts +8 -0
  224. package/dist/services/ragStore.d.ts.map +1 -1
  225. package/dist/services/ragStore.js +77 -8
  226. package/dist/services/ragStore.js.map +1 -1
  227. package/dist/services/rbac.d.ts +1 -1
  228. package/dist/services/rbac.d.ts.map +1 -1
  229. package/dist/services/rbac.js +6 -0
  230. package/dist/services/rbac.js.map +1 -1
  231. package/dist/services/security/codeAwareOutputRegistry.d.ts +6 -0
  232. package/dist/services/security/codeAwareOutputRegistry.d.ts.map +1 -0
  233. package/dist/services/security/codeAwareOutputRegistry.js +55 -0
  234. package/dist/services/security/codeAwareOutputRegistry.js.map +1 -0
  235. package/dist/services/security/llmEchoOutputFilter.d.ts +49 -0
  236. package/dist/services/security/llmEchoOutputFilter.d.ts.map +1 -0
  237. package/dist/services/security/llmEchoOutputFilter.js +133 -0
  238. package/dist/services/security/llmEchoOutputFilter.js.map +1 -0
  239. package/dist/services/security/secretPatterns.d.ts +6 -0
  240. package/dist/services/security/secretPatterns.d.ts.map +1 -0
  241. package/dist/services/security/secretPatterns.js +23 -0
  242. package/dist/services/security/secretPatterns.js.map +1 -0
  243. package/dist/services/skillEngine/skillExecutor.d.ts +14 -2
  244. package/dist/services/skillEngine/skillExecutor.d.ts.map +1 -1
  245. package/dist/services/skillEngine/skillExecutor.js +133 -13
  246. package/dist/services/skillEngine/skillExecutor.js.map +1 -1
  247. package/dist/services/skillEngine/types.d.ts +2 -0
  248. package/dist/services/skillEngine/types.d.ts.map +1 -1
  249. package/dist/services/symbol/breakpadSymParser.d.ts +19 -0
  250. package/dist/services/symbol/breakpadSymParser.d.ts.map +1 -0
  251. package/dist/services/symbol/breakpadSymParser.js +40 -0
  252. package/dist/services/symbol/breakpadSymParser.js.map +1 -0
  253. package/dist/services/symbol/kallsymsParser.d.ts +12 -0
  254. package/dist/services/symbol/kallsymsParser.d.ts.map +1 -0
  255. package/dist/services/symbol/kallsymsParser.js +41 -0
  256. package/dist/services/symbol/kallsymsParser.js.map +1 -0
  257. package/dist/services/symbol/r8MappingParser.d.ts +40 -0
  258. package/dist/services/symbol/r8MappingParser.d.ts.map +1 -0
  259. package/dist/services/symbol/r8MappingParser.js +99 -0
  260. package/dist/services/symbol/r8MappingParser.js.map +1 -0
  261. package/dist/services/symbol/symbolResolver.d.ts +59 -0
  262. package/dist/services/symbol/symbolResolver.d.ts.map +1 -0
  263. package/dist/services/symbol/symbolResolver.js +147 -0
  264. package/dist/services/symbol/symbolResolver.js.map +1 -0
  265. package/dist/services/symbol/traceSymbolContext.d.ts +14 -0
  266. package/dist/services/symbol/traceSymbolContext.d.ts.map +1 -0
  267. package/dist/services/symbol/traceSymbolContext.js +45 -0
  268. package/dist/services/symbol/traceSymbolContext.js.map +1 -0
  269. package/dist/services/verifier/claimVerificationRunner.d.ts +20 -0
  270. package/dist/services/verifier/claimVerificationRunner.d.ts.map +1 -0
  271. package/dist/services/verifier/claimVerificationRunner.js +88 -0
  272. package/dist/services/verifier/claimVerificationRunner.js.map +1 -0
  273. package/dist/services/verifier/deterministicClaimVerifier.d.ts +8 -0
  274. package/dist/services/verifier/deterministicClaimVerifier.d.ts.map +1 -0
  275. package/dist/services/verifier/deterministicClaimVerifier.js +178 -0
  276. package/dist/services/verifier/deterministicClaimVerifier.js.map +1 -0
  277. package/dist/types/claimVerification.d.ts +38 -0
  278. package/dist/types/claimVerification.d.ts.map +1 -0
  279. package/dist/types/claimVerification.js +6 -0
  280. package/dist/types/claimVerification.js.map +1 -0
  281. package/dist/types/dataContract.d.ts +30 -0
  282. package/dist/types/dataContract.d.ts.map +1 -1
  283. package/dist/types/dataContract.js +7 -0
  284. package/dist/types/dataContract.js.map +1 -1
  285. package/dist/types/evidenceContract.d.ts +100 -0
  286. package/dist/types/evidenceContract.d.ts.map +1 -0
  287. package/dist/types/evidenceContract.js +6 -0
  288. package/dist/types/evidenceContract.js.map +1 -0
  289. package/dist/types/identityContract.d.ts +57 -0
  290. package/dist/types/identityContract.d.ts.map +1 -0
  291. package/dist/types/identityContract.js +6 -0
  292. package/dist/types/identityContract.js.map +1 -0
  293. package/dist/types/multiTraceComparison.d.ts +3 -0
  294. package/dist/types/multiTraceComparison.d.ts.map +1 -1
  295. package/dist/types/sparkContracts.d.ts +31 -3
  296. package/dist/types/sparkContracts.d.ts.map +1 -1
  297. package/dist/types/sparkContracts.js.map +1 -1
  298. package/package.json +8 -1
  299. package/skills/atomic/process_identity_resolver.skill.yaml +130 -1
  300. package/skills/atomic/process_slice_cpu_hotspots.skill.yaml +321 -0
  301. package/skills/composite/code_pinpoint.skill.yaml +111 -0
  302. package/strategies/anr.strategy.md +2 -2
  303. package/strategies/code-aware.template.md +37 -0
  304. package/strategies/game.strategy.md +1 -1
  305. package/strategies/general.strategy.md +1 -1
  306. package/strategies/prompt-methodology.template.md +2 -0
  307. package/strategies/scrolling.strategy.md +1 -0
@@ -92,6 +92,7 @@ const analysisRunStore_1 = require("../services/analysisRunStore");
92
92
  const agentAnalyzeSessionService_1 = require("../assistant/application/agentAnalyzeSessionService");
93
93
  const assistantResultContract_1 = require("../assistant/contracts/assistantResultContract");
94
94
  const analysisResultSnapshotPipeline_1 = require("../services/analysisResultSnapshotPipeline");
95
+ const claimVerificationRunner_1 = require("../services/verifier/claimVerificationRunner");
95
96
  // DataEnvelope types for v2.0 data contract
96
97
  const dataContract_1 = require("../types/dataContract");
97
98
  const skillExecutor_1 = require("../services/skillEngine/skillExecutor");
@@ -412,6 +413,51 @@ function sendReplayableSessionEvent(session, res, eventType, payload) {
412
413
  streamProjector.sendEvent(res, eventType, payload, event.seqId);
413
414
  return event.seqId;
414
415
  }
416
+ function appendAndPersistReplayableSessionEvent(session, eventType, payload) {
417
+ const event = (0, sessionSseReplay_1.appendReplayableSseEvent)(session, eventType, payload);
418
+ persistBufferedAgentEvent(session, {
419
+ cursor: event.seqId,
420
+ eventType: event.eventType,
421
+ eventData: event.eventData,
422
+ createdAt: Date.now(),
423
+ });
424
+ return event;
425
+ }
426
+ function writeBufferedSessionEvent(res, event) {
427
+ res.write(`id: ${event.seqId}\n`);
428
+ res.write(`event: ${event.eventType}\n`);
429
+ res.write(`data: ${event.eventData}\n\n`);
430
+ }
431
+ function loadPersistedCompletedAnalysisSseEvents(session) {
432
+ const scope = agentEventScopeFromSession(session);
433
+ if (!scope)
434
+ return [];
435
+ const events = (0, agentEventStore_1.listSerializedAgentEventsAfter)(scope, scope.runId, 0)
436
+ .filter(event => event.eventType === 'snapshot_created' ||
437
+ event.eventType === 'analysis_completed' ||
438
+ event.eventType === 'scene_reconstruction_completed' ||
439
+ event.eventType === 'end')
440
+ .map(event => ({
441
+ seqId: event.cursor,
442
+ eventType: event.eventType,
443
+ eventData: event.eventData,
444
+ }));
445
+ if (!events.some(event => event.eventType === 'analysis_completed') ||
446
+ !events.some(event => event.eventType === 'end')) {
447
+ return [];
448
+ }
449
+ session.sseEventSeq = Math.max(session.sseEventSeq || 0, ...events.map(event => event.seqId));
450
+ const existing = new Set(session.sseEventBuffer.map(event => `${event.seqId}:${event.eventType}`));
451
+ for (const event of events) {
452
+ const key = `${event.seqId}:${event.eventType}`;
453
+ if (!existing.has(key))
454
+ session.sseEventBuffer.push(event);
455
+ }
456
+ if (session.sseEventBuffer.length > streamProjector_1.SSE_RING_BUFFER_SIZE) {
457
+ session.sseEventBuffer.splice(0, session.sseEventBuffer.length - streamProjector_1.SSE_RING_BUFFER_SIZE);
458
+ }
459
+ return events;
460
+ }
415
461
  function resolveSessionContextForReview(sessionId) {
416
462
  const activeSession = assistantAppService.getSession(sessionId);
417
463
  if (activeSession) {
@@ -607,6 +653,10 @@ function buildRecoveredResultFromContext(sessionId, context) {
607
653
  partial: turn.result.partial,
608
654
  terminationReason: turn.result.terminationReason,
609
655
  terminationMessage: turn.result.terminationMessage,
656
+ conclusionContract: turn.result.conclusionContract,
657
+ claimSupport: turn.result.claimSupport,
658
+ claimVerificationResult: turn.result.claimVerificationResult,
659
+ identityResolutions: turn.result.identityResolutions,
610
660
  };
611
661
  }
612
662
  function recoverResultForSessionIfNeeded(sessionId, session) {
@@ -902,6 +952,8 @@ async function handleAnalyzeRequest(req, res, requestedSessionIdOverride) {
902
952
  sessionForRun.referenceTraceId = effectiveReferenceTraceId;
903
953
  sessionForRun.comparisonSource = 'raw_trace_pair';
904
954
  }
955
+ sessionForRun.codeAwareMode = options.codeAwareMode;
956
+ sessionForRun.codebaseIds = Array.isArray(options.codebaseIds) ? options.codebaseIds : undefined;
905
957
  const runContext = startSessionRun(sessionForRun, query, requestId);
906
958
  sessionForRun.logger.setMetadata({
907
959
  requestId: runContext.requestId,
@@ -1178,11 +1230,8 @@ function handleSessionStream(req, res, sessionId) {
1178
1230
  recoverResultForSessionIfNeeded(sessionId, session);
1179
1231
  if (session.result) {
1180
1232
  sendAgentDrivenResult(res, session);
1181
- sendReplayableSessionEvent(session, res, 'end', {
1182
- timestamp: Date.now(),
1183
- ...buildStreamObservability(session),
1184
- });
1185
1233
  res.end();
1234
+ assistantAppService.removeSseClient(sessionId, res);
1186
1235
  return;
1187
1236
  }
1188
1237
  }
@@ -1264,16 +1313,35 @@ router.get('/:sessionId/status', (req, res) => {
1264
1313
  sceneId: sceneIdHint,
1265
1314
  }) ||
1266
1315
  undefined;
1316
+ const qualityArtifacts = recoveredResult.claimSupport &&
1317
+ recoveredResult.claimVerificationResult &&
1318
+ recoveredResult.identityResolutions
1319
+ ? {
1320
+ claimSupport: recoveredResult.claimSupport,
1321
+ claimVerificationResult: recoveredResult.claimVerificationResult,
1322
+ identityResolutions: recoveredResult.identityResolutions,
1323
+ }
1324
+ : ensureAnalysisQualityArtifacts(session, conclusionContract, recoveredResult);
1325
+ const completedPayload = ensureCompletedAnalysisResultPayload(session);
1326
+ const finalArtifacts = completedPayload?.finalArtifacts;
1327
+ const normalizedCompletedConclusion = completedPayload?.normalizedConclusion || conclusion;
1328
+ const normalizedCompletedContract = completedPayload?.normalizedConclusionContract || conclusionContract;
1267
1329
  response.result = {
1268
- answer: conclusion,
1269
- conclusion,
1270
- conclusionContract,
1330
+ answer: normalizedCompletedConclusion,
1331
+ conclusion: normalizedCompletedConclusion,
1332
+ conclusionContract: normalizedCompletedContract,
1333
+ claimSupport: qualityArtifacts.claimSupport,
1334
+ claimVerificationResult: qualityArtifacts.claimVerificationResult,
1335
+ identityResolutions: qualityArtifacts.identityResolutions,
1271
1336
  confidence: recoveredResult.confidence,
1272
1337
  totalDurationMs: recoveredResult.totalDurationMs,
1273
1338
  rounds: recoveredResult.rounds,
1274
1339
  partial: recoveredResult.partial,
1275
1340
  terminationReason: recoveredResult.terminationReason,
1276
1341
  terminationMessage: recoveredResult.terminationMessage,
1342
+ reportUrl: finalArtifacts?.reportUrl,
1343
+ reportError: finalArtifacts?.reportError,
1344
+ resultSnapshotId: finalArtifacts?.resultSnapshotId,
1277
1345
  findings: recoveredResult.findings,
1278
1346
  findingsCount: recoveredResult.findings.length,
1279
1347
  resultContract,
@@ -2231,6 +2299,7 @@ async function detectScenesQuick(traceProcessorService, traceId) {
2231
2299
  normalizeNarrativeForClient,
2232
2300
  buildClientFindings,
2233
2301
  buildSessionResultContract,
2302
+ getCompletedPayload: ensureCompletedAnalysisResultPayload,
2234
2303
  });
2235
2304
  // ============================================================================
2236
2305
  // Agent-Driven Analysis Helper Functions (Phase 2-4)
@@ -2309,9 +2378,14 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
2309
2378
  console.log(`[AgentRoutes.AgentDriven] Received event: ${update.type}`, update.content?.phase);
2310
2379
  logger.debug('Stream', `Update: ${update.type}`, update.content);
2311
2380
  const normalizedUpdate = augmentConclusionUpdateWithEvidenceIndex(session, normalizeAgentDrivenUpdate(update));
2312
- // Broadcast the original event so the frontend receives raw events
2313
- // (answer_token, thought, agent_response, conclusion, etc.) for rendering.
2314
- broadcastToAgentDrivenClients(sessionId, normalizedUpdate);
2381
+ // Final narrative is emitted through analysis_completed after deterministic
2382
+ // evidence/claim verification has run. Suppress early conclusion events so
2383
+ // clients do not render an unverified terminal answer.
2384
+ const shouldBroadcastOriginalUpdate = normalizedUpdate.type !== 'conclusion' &&
2385
+ normalizedUpdate.type !== 'answer_token';
2386
+ if (shouldBroadcastOriginalUpdate) {
2387
+ broadcastToAgentDrivenClients(sessionId, normalizedUpdate);
2388
+ }
2315
2389
  // Also derive a conversation_step for the timeline/observability layer.
2316
2390
  const conversationStep = buildConversationStepUpdate(session, normalizedUpdate);
2317
2391
  if (conversationStep) {
@@ -2359,7 +2433,7 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
2359
2433
  // (answer_token, thought, conclusion, etc.) are already broadcast above
2360
2434
  // and remapping would cause duplicate delivery to the frontend.
2361
2435
  const eventType = mapToAgentDrivenEventType(normalizedUpdate);
2362
- if (eventType !== normalizedUpdate.type) {
2436
+ if (shouldBroadcastOriginalUpdate && eventType !== normalizedUpdate.type) {
2363
2437
  broadcastToAgentDrivenClients(sessionId, {
2364
2438
  type: eventType,
2365
2439
  content: normalizedUpdate.content,
@@ -2427,6 +2501,8 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
2427
2501
  traceContext: options.traceContext,
2428
2502
  referenceTraceId: options.referenceTraceId,
2429
2503
  providerId: options.providerId,
2504
+ codeAwareMode: options.codeAwareMode,
2505
+ codebaseIds: Array.isArray(options.codebaseIds) ? options.codebaseIds : undefined,
2430
2506
  tenantId: session.tenantId,
2431
2507
  workspaceId: session.workspaceId,
2432
2508
  userId: session.userId,
@@ -2436,6 +2512,7 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
2436
2512
  });
2437
2513
  console.log('[AgentRoutes.AgentDriven] analyze completed, success:', result.success);
2438
2514
  session.result = result;
2515
+ delete session.completedAnalysisFinalArtifacts;
2439
2516
  // Accumulate hypotheses across turns (deduplicate by id)
2440
2517
  const existingIds = new Set(session.hypotheses.map(h => h.id));
2441
2518
  for (const h of result.hypotheses) {
@@ -2450,10 +2527,6 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
2450
2527
  }
2451
2528
  }
2452
2529
  const terminalRunStatus = terminalRunStatusForResult(result);
2453
- session.status = terminalRunStatus === 'quota_exceeded'
2454
- ? 'quota_exceeded'
2455
- : result.success ? 'completed' : 'failed';
2456
- markSessionRunStatus(session, terminalRunStatus);
2457
2530
  // Record conclusion in cross-turn history
2458
2531
  if (!session.conclusionHistory)
2459
2532
  session.conclusionHistory = [];
@@ -2492,12 +2565,35 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
2492
2565
  };
2493
2566
  }
2494
2567
  }
2568
+ if (result.success || result.partial === true) {
2569
+ const sceneIdHint = resolveConclusionSceneIdHint({
2570
+ sessionId,
2571
+ query,
2572
+ findings: result.findings,
2573
+ });
2574
+ const normalizedConclusionContract = (result.conclusionContract ||
2575
+ (0, agentResultNormalizer_1.deriveConclusionContractForNarrative)(result.conclusion, {
2576
+ mode: result.rounds > 1 ? 'focused_answer' : 'initial_report',
2577
+ sceneId: sceneIdHint,
2578
+ }) ||
2579
+ undefined);
2580
+ if (normalizedConclusionContract) {
2581
+ result.conclusionContract = normalizedConclusionContract;
2582
+ }
2583
+ ensureAnalysisQualityArtifacts(session, normalizedConclusionContract);
2584
+ }
2585
+ session.status = terminalRunStatus === 'quota_exceeded'
2586
+ ? 'quota_exceeded'
2587
+ : result.success ? 'completed' : 'failed';
2588
+ markSessionRunStatus(session, terminalRunStatus);
2495
2589
  // Log completion details
2496
2590
  logger.info('AgentDrivenAnalysis', 'Agent-driven analysis completed', {
2497
2591
  confidence: result.confidence,
2498
2592
  rounds: result.rounds,
2499
2593
  findingsCount: result.findings.length,
2500
2594
  hypothesesCount: result.hypotheses.length,
2595
+ claimSupportCount: result.claimSupport?.length || 0,
2596
+ claimVerifierStatus: result.claimVerificationResult?.status,
2501
2597
  partial: result.partial,
2502
2598
  terminationReason: result.terminationReason,
2503
2599
  runId: session.activeRun?.runId,
@@ -2520,14 +2616,11 @@ async function runAgentDrivenAnalysis(sessionId, query, traceId, options = {}) {
2520
2616
  // Send final result
2521
2617
  const clientCount = session.sseClients.length;
2522
2618
  logger.info('AgentRoutes', 'Sending agent-driven result', { clientCount });
2619
+ ensureCompletedAnalysisSseEvents(session);
2523
2620
  session.sseClients.forEach((client, index) => {
2524
2621
  try {
2525
2622
  logger.info('AgentRoutes', `Sending agent-driven result to client ${index + 1}/${clientCount}`);
2526
2623
  sendAgentDrivenResult(client, session);
2527
- sendReplayableSessionEvent(session, client, 'end', {
2528
- timestamp: Date.now(),
2529
- ...buildStreamObservability(session),
2530
- });
2531
2624
  }
2532
2625
  catch (e) {
2533
2626
  logger.error('AgentRoutes', `Error sending agent-driven result to client ${index + 1}`, e);
@@ -4026,53 +4119,67 @@ function augmentConclusionUpdateWithEvidenceIndex(session, update) {
4026
4119
  },
4027
4120
  };
4028
4121
  }
4029
- /**
4030
- * Send agent-driven analysis result to SSE client
4031
- */
4032
- function sendAgentDrivenResult(res, session) {
4033
- const result = session.result;
4122
+ function ensureAnalysisQualityArtifacts(session, conclusionContract, resultOverride) {
4123
+ const result = resultOverride || session.result;
4034
4124
  if (!result)
4035
- return;
4036
- const observability = buildStreamObservability(session);
4037
- const replayOnlyScene = isSceneReplayOnlyQuery(session.query);
4038
- const hasEvidenceBackedConclusion = result.success || result.partial === true;
4039
- const normalizedConclusion = replayOnlyScene
4040
- ? buildSceneReplayNarrative(session.scenes || [])
4041
- : hasEvidenceBackedConclusion ? appendEvidenceIndexIfMissing(normalizeNarrativeForClient(result.conclusion), session.dataEnvelopes || []) : normalizeNarrativeForClient(result.conclusion);
4042
- const sceneIdHint = replayOnlyScene
4043
- ? undefined
4044
- : resolveConclusionSceneIdHint({
4045
- sessionId: session.sessionId,
4046
- query: session.query,
4047
- findings: result.findings,
4125
+ return {};
4126
+ if (result.claimSupport &&
4127
+ result.claimVerificationResult &&
4128
+ result.identityResolutions) {
4129
+ session.claimSupport = result.claimSupport;
4130
+ session.claimVerificationResult = result.claimVerificationResult;
4131
+ session.identityResolutions = result.identityResolutions;
4132
+ const context = enhancedSessionContext_1.sessionContextManager.get(session.sessionId, session.traceId);
4133
+ context?.annotateLatestCompletedTurn({
4134
+ conclusionContract,
4135
+ claimSupport: result.claimSupport,
4136
+ claimVerificationResult: result.claimVerificationResult,
4137
+ identityResolutions: result.identityResolutions,
4048
4138
  });
4049
- // Fallback: re-derive contract if the orchestrator didn't populate it.
4050
- // Note: mode heuristic uses rounds (available here) as proxy for turnCount
4051
- // (which only the orchestrator knows). Both signal "multi-interaction" analysis.
4052
- const normalizedConclusionContract = replayOnlyScene
4053
- ? undefined
4054
- : hasEvidenceBackedConclusion ? (result.conclusionContract ||
4055
- (0, agentResultNormalizer_1.deriveConclusionContractForNarrative)(result.conclusion, {
4056
- mode: result.rounds > 1 ? 'focused_answer' : 'initial_report',
4057
- sceneId: sceneIdHint,
4058
- }) ||
4059
- undefined) : undefined;
4060
- const resultForClient = normalizedConclusion === result.conclusion && normalizedConclusionContract === result.conclusionContract
4061
- ? result
4062
- : { ...result, conclusion: normalizedConclusion, conclusionContract: normalizedConclusionContract };
4063
- const clientFindings = replayOnlyScene ? [] : buildClientFindings(result.findings, session.scenes || []);
4064
- const resultContract = buildSessionResultContract(session, clientFindings);
4065
- // Generate HTML report
4066
- let reportUrl;
4067
- let reportError;
4068
- const reportId = `agent-report-${session.sessionId}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
4069
- let resultSnapshotId;
4070
- let resultSnapshotEventData;
4071
- let reportLease = null;
4072
- if (!hasEvidenceBackedConclusion) {
4073
- reportError = `analysis did not complete successfully (${result.terminationReason || 'failed'})`;
4139
+ return {
4140
+ claimSupport: result.claimSupport,
4141
+ claimVerificationResult: result.claimVerificationResult,
4142
+ identityResolutions: result.identityResolutions,
4143
+ };
4144
+ }
4145
+ const artifacts = (0, claimVerificationRunner_1.runClaimVerification)({
4146
+ conclusionContract,
4147
+ dataEnvelopes: session.dataEnvelopes || [],
4148
+ comparisonReportSection: session.comparisonReportSection,
4149
+ policy: 'record_only',
4150
+ });
4151
+ result.claimSupport = artifacts.claimSupport;
4152
+ result.claimVerificationResult = artifacts.claimVerificationResult;
4153
+ result.identityResolutions = artifacts.identityResolutions;
4154
+ const context = enhancedSessionContext_1.sessionContextManager.get(session.sessionId, session.traceId);
4155
+ context?.annotateLatestCompletedTurn({
4156
+ conclusionContract,
4157
+ claimSupport: artifacts.claimSupport,
4158
+ claimVerificationResult: artifacts.claimVerificationResult,
4159
+ identityResolutions: artifacts.identityResolutions,
4160
+ });
4161
+ session.claimSupport = artifacts.claimSupport;
4162
+ session.claimVerificationResult = artifacts.claimVerificationResult;
4163
+ session.identityResolutions = artifacts.identityResolutions;
4164
+ return {
4165
+ claimSupport: artifacts.claimSupport,
4166
+ claimVerificationResult: artifacts.claimVerificationResult,
4167
+ identityResolutions: artifacts.identityResolutions,
4168
+ };
4169
+ }
4170
+ function ensureCompletedAnalysisFinalArtifacts(session, input) {
4171
+ const cached = session.completedAnalysisFinalArtifacts;
4172
+ if (cached)
4173
+ return cached;
4174
+ const result = input.result;
4175
+ const finalArtifacts = { generatedAt: Date.now() };
4176
+ let reportId;
4177
+ if (!input.hasEvidenceBackedConclusion) {
4178
+ finalArtifacts.reportError = `analysis did not complete successfully (${result.terminationReason || 'failed'})`;
4074
4179
  }
4075
4180
  else {
4181
+ let reportLease = null;
4182
+ reportId = `agent-report-${session.sessionId}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
4076
4183
  try {
4077
4184
  if (enterpriseLeasesEnabled()) {
4078
4185
  const scope = leaseScopeFromSession(session);
@@ -4096,18 +4203,15 @@ function sendAgentDrivenResult(res, session) {
4096
4203
  }
4097
4204
  }
4098
4205
  const generator = (0, htmlReportGenerator_1.getHTMLReportGenerator)();
4099
- // Report assembly (cumulative findings dedup, empty-conclusion fallback,
4100
- // snapshot-first analysisNotes/Plan/Flags) lives in the shared builder so
4101
- // the CLI path produces identical output.
4102
4206
  const reportData = (0, agentReportData_1.buildAgentDrivenReportData)({
4103
4207
  session,
4104
- result: resultForClient,
4208
+ result: input.resultForClient,
4105
4209
  });
4106
4210
  console.log(`[AgentRoutes] Generating HTML report, data keys:`, {
4107
4211
  hasResult: !!result,
4108
- conclusionLength: normalizedConclusion?.length || 0,
4109
- conclusionPreview: (normalizedConclusion || '').substring(0, 100),
4110
- hasConclusionContract: !!normalizedConclusionContract,
4212
+ conclusionLength: input.normalizedConclusion?.length || 0,
4213
+ conclusionPreview: (input.normalizedConclusion || '').substring(0, 100),
4214
+ hasConclusionContract: !!input.normalizedConclusionContract,
4111
4215
  findingsCount: result.findings?.length || 0,
4112
4216
  hypothesesCount: session.hypotheses?.length || 0,
4113
4217
  dialogueCount: session.agentDialogue?.length || 0,
@@ -4119,9 +4223,10 @@ function sendAgentDrivenResult(res, session) {
4119
4223
  snapshotNotes: session._lastSnapshot?.analysisNotes?.length ?? 'n/a',
4120
4224
  snapshotPlan: !!session._lastSnapshot?.analysisPlan,
4121
4225
  snapshotFlags: session._lastSnapshot?.uncertaintyFlags?.length ?? 'n/a',
4226
+ claimSupportCount: input.qualityArtifacts.claimSupport?.length || 0,
4227
+ claimVerifierStatus: input.qualityArtifacts.claimVerificationResult?.status,
4122
4228
  });
4123
4229
  const html = generator.generateAgentDrivenHTML(reportData);
4124
- // Store report
4125
4230
  (0, reportRoutes_1.persistReport)(reportId, {
4126
4231
  html,
4127
4232
  generatedAt: Date.now(),
@@ -4133,13 +4238,15 @@ function sendAgentDrivenResult(res, session) {
4133
4238
  userId: session.userId,
4134
4239
  visibility: 'private',
4135
4240
  });
4136
- reportUrl = `/api/reports/${reportId}`;
4241
+ finalArtifacts.reportId = reportId;
4242
+ finalArtifacts.reportUrl = `/api/reports/${reportId}`;
4137
4243
  console.log(`[AgentRoutes] Generated agent-driven HTML report: ${reportId} (${html.length} bytes)`);
4138
4244
  }
4139
4245
  catch (error) {
4140
- reportError = error.message || 'Unknown error';
4246
+ reportId = undefined;
4247
+ finalArtifacts.reportError = error.message || 'Unknown error';
4141
4248
  console.error('[AgentRoutes] Failed to generate agent-driven HTML report:', {
4142
- error: reportError,
4249
+ error: finalArtifacts.reportError,
4143
4250
  stack: error.stack?.split('\n').slice(0, 5).join('\n'),
4144
4251
  resultConclusion: result?.conclusion ? `${result.conclusion.length} chars` : 'EMPTY/NULL',
4145
4252
  resultConfidence: result?.confidence,
@@ -4151,7 +4258,7 @@ function sendAgentDrivenResult(res, session) {
4151
4258
  const scope = leaseScopeFromSession(session);
4152
4259
  if (scope) {
4153
4260
  try {
4154
- (0, traceProcessorLeaseStore_1.getTraceProcessorLeaseStore)().releaseHolder(scope, reportLease.id, 'report_generation', reportId);
4261
+ (0, traceProcessorLeaseStore_1.getTraceProcessorLeaseStore)().releaseHolder(scope, reportLease.id, 'report_generation', finalArtifacts.reportId || reportId || 'report_generation');
4155
4262
  }
4156
4263
  catch (releaseError) {
4157
4264
  console.warn(`[AgentRoutes] Failed to release report_generation lease ${reportLease.id}: ${releaseError.message}`);
@@ -4160,7 +4267,7 @@ function sendAgentDrivenResult(res, session) {
4160
4267
  }
4161
4268
  }
4162
4269
  }
4163
- if (hasEvidenceBackedConclusion) {
4270
+ if (input.hasEvidenceBackedConclusion) {
4164
4271
  try {
4165
4272
  const resultSnapshot = (0, analysisResultSnapshotPipeline_1.persistCompletedAnalysisResultSnapshot)({
4166
4273
  tenantId: session.tenantId,
@@ -4169,20 +4276,23 @@ function sendAgentDrivenResult(res, session) {
4169
4276
  traceId: session.traceId,
4170
4277
  sessionId: session.sessionId,
4171
4278
  runId: session.lastRun?.runId || session.activeRun?.runId,
4172
- reportId: reportUrl ? reportId : undefined,
4279
+ reportId: finalArtifacts.reportId,
4173
4280
  query: session.query,
4174
4281
  traceLabel: session.traceId,
4175
- conclusion: normalizedConclusion,
4176
- conclusionContract: normalizedConclusionContract,
4282
+ conclusion: input.normalizedConclusion,
4283
+ conclusionContract: input.normalizedConclusionContract,
4284
+ claimSupport: input.qualityArtifacts.claimSupport,
4285
+ claimVerificationResult: input.qualityArtifacts.claimVerificationResult,
4286
+ identityResolutions: input.qualityArtifacts.identityResolutions,
4177
4287
  confidence: result.confidence,
4178
4288
  partial: result.partial,
4179
4289
  terminationReason: result.terminationReason,
4180
4290
  terminationMessage: result.terminationMessage,
4181
4291
  dataEnvelopes: session.dataEnvelopes,
4182
4292
  });
4183
- resultSnapshotId = resultSnapshot?.id;
4293
+ finalArtifacts.resultSnapshotId = resultSnapshot?.id;
4184
4294
  if (resultSnapshot) {
4185
- resultSnapshotEventData = {
4295
+ finalArtifacts.resultSnapshotEventData = {
4186
4296
  snapshotId: resultSnapshot.id,
4187
4297
  status: resultSnapshot.status,
4188
4298
  sceneType: resultSnapshot.sceneType,
@@ -4205,24 +4315,108 @@ function sendAgentDrivenResult(res, session) {
4205
4315
  });
4206
4316
  }
4207
4317
  }
4208
- if (resultSnapshotEventData) {
4209
- sendReplayableSessionEvent(session, res, 'snapshot_created', {
4318
+ session.completedAnalysisFinalArtifacts = finalArtifacts;
4319
+ return finalArtifacts;
4320
+ }
4321
+ function ensureCompletedAnalysisResultPayload(session) {
4322
+ const result = session.result;
4323
+ if (!result)
4324
+ return undefined;
4325
+ const replayOnlyScene = isSceneReplayOnlyQuery(session.query);
4326
+ const hasEvidenceBackedConclusion = result.success || result.partial === true;
4327
+ const normalizedConclusion = replayOnlyScene
4328
+ ? buildSceneReplayNarrative(session.scenes || [])
4329
+ : hasEvidenceBackedConclusion ? appendEvidenceIndexIfMissing(normalizeNarrativeForClient(result.conclusion), session.dataEnvelopes || []) : normalizeNarrativeForClient(result.conclusion);
4330
+ const sceneIdHint = replayOnlyScene
4331
+ ? undefined
4332
+ : resolveConclusionSceneIdHint({
4333
+ sessionId: session.sessionId,
4334
+ query: session.query,
4335
+ findings: result.findings,
4336
+ });
4337
+ const normalizedConclusionContract = replayOnlyScene
4338
+ ? undefined
4339
+ : hasEvidenceBackedConclusion ? (result.conclusionContract ||
4340
+ (0, agentResultNormalizer_1.deriveConclusionContractForNarrative)(result.conclusion, {
4341
+ mode: result.rounds > 1 ? 'focused_answer' : 'initial_report',
4342
+ sceneId: sceneIdHint,
4343
+ }) ||
4344
+ undefined) : undefined;
4345
+ const qualityArtifacts = hasEvidenceBackedConclusion && !replayOnlyScene
4346
+ ? ensureAnalysisQualityArtifacts(session, normalizedConclusionContract)
4347
+ : {};
4348
+ const resultForClient = normalizedConclusion === result.conclusion &&
4349
+ normalizedConclusionContract === result.conclusionContract &&
4350
+ qualityArtifacts.claimSupport === result.claimSupport &&
4351
+ qualityArtifacts.claimVerificationResult === result.claimVerificationResult &&
4352
+ qualityArtifacts.identityResolutions === result.identityResolutions
4353
+ ? result
4354
+ : {
4355
+ ...result,
4356
+ conclusion: normalizedConclusion,
4357
+ conclusionContract: normalizedConclusionContract,
4358
+ ...qualityArtifacts,
4359
+ };
4360
+ const clientFindings = replayOnlyScene ? [] : buildClientFindings(result.findings, session.scenes || []);
4361
+ const resultContract = buildSessionResultContract(session, clientFindings);
4362
+ const finalArtifacts = ensureCompletedAnalysisFinalArtifacts(session, {
4363
+ result,
4364
+ hasEvidenceBackedConclusion,
4365
+ normalizedConclusion,
4366
+ normalizedConclusionContract,
4367
+ qualityArtifacts,
4368
+ resultForClient: resultForClient,
4369
+ });
4370
+ return {
4371
+ result,
4372
+ replayOnlyScene,
4373
+ normalizedConclusion,
4374
+ normalizedConclusionContract,
4375
+ qualityArtifacts,
4376
+ clientFindings,
4377
+ resultContract,
4378
+ finalArtifacts,
4379
+ };
4380
+ }
4381
+ /**
4382
+ * Send agent-driven analysis result to SSE client
4383
+ */
4384
+ function ensureCompletedAnalysisSseEvents(session) {
4385
+ const cached = session.completedAnalysisSseEvents;
4386
+ if (cached?.length)
4387
+ return cached;
4388
+ const persisted = loadPersistedCompletedAnalysisSseEvents(session);
4389
+ if (persisted.length > 0) {
4390
+ session.completedAnalysisSseEvents = persisted;
4391
+ return persisted;
4392
+ }
4393
+ const completedPayload = ensureCompletedAnalysisResultPayload(session);
4394
+ if (!completedPayload)
4395
+ return [];
4396
+ const { result, normalizedConclusion, normalizedConclusionContract, qualityArtifacts, clientFindings, resultContract, finalArtifacts, } = completedPayload;
4397
+ const observability = buildStreamObservability(session);
4398
+ const events = [];
4399
+ if (finalArtifacts.resultSnapshotEventData) {
4400
+ events.push(appendAndPersistReplayableSessionEvent(session, 'snapshot_created', {
4210
4401
  type: 'snapshot_created',
4211
4402
  architecture: 'agent-driven',
4212
4403
  ...observability,
4213
- data: resultSnapshotEventData,
4404
+ data: finalArtifacts.resultSnapshotEventData,
4214
4405
  timestamp: Date.now(),
4215
- });
4406
+ }));
4216
4407
  }
4217
4408
  // Send analysis_completed event with full result. Keep it replayable so a
4218
4409
  // reconnect between conclusion and report generation can recover reportUrl.
4219
- sendReplayableSessionEvent(session, res, 'analysis_completed', {
4410
+ events.push(appendAndPersistReplayableSessionEvent(session, 'analysis_completed', {
4220
4411
  type: 'analysis_completed',
4221
4412
  architecture: 'agent-driven',
4222
4413
  ...observability,
4223
4414
  data: {
4224
4415
  conclusion: normalizedConclusion,
4225
4416
  conclusionContract: normalizedConclusionContract,
4417
+ claimSupport: qualityArtifacts.claimSupport,
4418
+ claimVerificationResult: qualityArtifacts.claimVerificationResult,
4419
+ identityResolutions: qualityArtifacts.identityResolutions,
4226
4420
  confidence: result.confidence,
4227
4421
  rounds: result.rounds,
4228
4422
  totalDurationMs: result.totalDurationMs,
@@ -4242,8 +4436,8 @@ function sendAgentDrivenResult(res, session) {
4242
4436
  agentDialogueCount: session.agentDialogue.length,
4243
4437
  conversationTimelineCount: session.conversationSteps.length,
4244
4438
  conversationTimeline: session.conversationSteps,
4245
- reportUrl,
4246
- reportError,
4439
+ reportUrl: finalArtifacts.reportUrl,
4440
+ reportError: finalArtifacts.reportError,
4247
4441
  comparisonReportSection: session.comparisonReportSection
4248
4442
  ? {
4249
4443
  source: session.comparisonReportSection.source,
@@ -4253,14 +4447,15 @@ function sendAgentDrivenResult(res, session) {
4253
4447
  evidencePack: session.comparisonReportSection.evidencePack,
4254
4448
  }
4255
4449
  : undefined,
4256
- resultSnapshotId,
4450
+ resultSnapshotId: finalArtifacts.resultSnapshotId,
4257
4451
  observability,
4452
+ terminalRunStatus: session.status === 'quota_exceeded' ? 'quota_exceeded' : 'completed',
4258
4453
  },
4259
4454
  timestamp: Date.now(),
4260
- });
4455
+ }));
4261
4456
  // Backward-compatible scene reconstruction payload (used by the legacy /scene-reconstruct clients).
4262
4457
  if ((session.scenes?.length || 0) > 0 || (session.trackEvents?.length || 0) > 0) {
4263
- sendReplayableSessionEvent(session, res, 'scene_reconstruction_completed', {
4458
+ events.push(appendAndPersistReplayableSessionEvent(session, 'scene_reconstruction_completed', {
4264
4459
  type: 'scene_reconstruction_completed',
4265
4460
  ...observability,
4266
4461
  data: {
@@ -4288,7 +4483,18 @@ function sendAgentDrivenResult(res, session) {
4288
4483
  observability,
4289
4484
  },
4290
4485
  timestamp: Date.now(),
4291
- });
4486
+ }));
4487
+ }
4488
+ events.push(appendAndPersistReplayableSessionEvent(session, 'end', {
4489
+ timestamp: Date.now(),
4490
+ ...observability,
4491
+ }));
4492
+ session.completedAnalysisSseEvents = events;
4493
+ return events;
4494
+ }
4495
+ function sendAgentDrivenResult(res, session) {
4496
+ for (const event of ensureCompletedAnalysisSseEvents(session)) {
4497
+ writeBufferedSessionEvent(res, event);
4292
4498
  }
4293
4499
  }
4294
4500
  (0, agentLogsRoutes_1.registerAgentLogsRoutes)(router);