@tea-agent/loop-agent 0.44.0-next.1 → 0.44.0-next.11

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 (245) hide show
  1. package/CHANGELOG.md +379 -416
  2. package/dist/application/evaluation/budget.js +21 -0
  3. package/dist/application/evaluation/corpus-hash.js +10 -15
  4. package/dist/application/evaluation/corpus.js +2 -1
  5. package/dist/application/evaluation/frontend-browser-acceptance.js +77 -0
  6. package/dist/application/evaluation/frontend-corpus-browser-acceptance.js +175 -0
  7. package/dist/application/evaluation/frontend-gateway-evidence.js +226 -0
  8. package/dist/application/evaluation/frontend-pair-registration.js +143 -0
  9. package/dist/application/evaluation/frontend-paired-summary.js +150 -0
  10. package/dist/application/evaluation/frontend-run-observation.js +144 -0
  11. package/dist/application/evaluation/frontend-shared-evidence.js +105 -0
  12. package/dist/application/evaluation/types.js +45 -12
  13. package/dist/application/task-lifecycle/observe.js +26 -1
  14. package/dist/build-stamp.json +3 -3
  15. package/dist/cli/command-definitions.js +11 -0
  16. package/dist/cli/program.js +4 -0
  17. package/dist/commands/task-advance.js +3 -5
  18. package/dist/commands/task-source-prepare.js +13 -1
  19. package/dist/executors/dag-pi/guards.js +4 -0
  20. package/dist/executors/dag-pi/model-config.js +30 -0
  21. package/dist/executors/dag-pi/plan/fact-adoption.js +55 -0
  22. package/dist/{workflows/dag/frontend-plan-completeness.js → executors/dag-pi/plan/facts.js} +22 -28
  23. package/dist/executors/dag-pi/plan/finalize-tools.js +259 -0
  24. package/dist/executors/dag-pi/plan/ledger-contract.js +55 -0
  25. package/dist/executors/dag-pi/plan/record-tools.js +861 -0
  26. package/dist/executors/dag-pi/plan/schema.js +129 -0
  27. package/dist/executors/dag-pi/plan/session.js +1 -0
  28. package/dist/executors/dag-pi/plan/tool-helpers.js +16 -0
  29. package/dist/executors/dag-pi/sessions/index.js +6 -0
  30. package/dist/executors/dag-pi/sessions/plan-batches.js +280 -0
  31. package/dist/executors/dag-pi/sessions/plan-prompts.js +367 -0
  32. package/dist/executors/dag-pi/sessions/scout-parallel.js +197 -0
  33. package/dist/executors/dag-pi/sessions/segmented-plan.js +1184 -0
  34. package/dist/executors/dag-pi/sessions/writer-evidence.js +60 -0
  35. package/dist/executors/dag-pi/tools/contract-tools.js +515 -0
  36. package/dist/executors/dag-pi/tools/design-terminal-tools.js +159 -0
  37. package/dist/executors/dag-pi/tools/plan-decision-tools.js +529 -0
  38. package/dist/executors/dag-pi/tools/review-terminal-tools.js +159 -0
  39. package/dist/executors/dag-pi/tools/scout-evidence-tools.js +270 -0
  40. package/dist/executors/dag-pi-executor.js +733 -5782
  41. package/dist/executors/pi-executor.js +6 -1
  42. package/dist/executors/pi-sdk-executor.js +112 -19
  43. package/dist/executors/shell-executor.js +88 -12
  44. package/dist/executors/shell-presets.js +1 -1
  45. package/dist/executors/shell-write-guard.js +26 -3
  46. package/dist/infrastructure/console/operation-store.js +48 -14
  47. package/dist/infrastructure/evaluation/corpus-store.js +37 -12
  48. package/dist/shared/file-identity.js +23 -0
  49. package/dist/shared/git-workspace-status.js +482 -0
  50. package/dist/shared/operator/capabilities.js +10 -5
  51. package/dist/shared/path-safety.js +2 -2
  52. package/dist/shared/wizard-local-telemetry.js +51 -0
  53. package/dist/task/config-types.js +22 -8
  54. package/dist/task/contract/project.js +13 -0
  55. package/dist/task/contract/schema.js +2 -7
  56. package/dist/task/frontend-preflight.js +1 -1
  57. package/dist/task/source-prepare/parse-intent.js +124 -5
  58. package/dist/task/source-prepare/prepare.js +6 -1
  59. package/dist/task/source-prepare/semantic-intake.js +18 -3
  60. package/dist/task/source-prepare/source-execution.js +65 -0
  61. package/dist/task/source-prepare/source-fidelity-pi.js +22 -9
  62. package/dist/task/source-prepare/source-provider-budget.js +290 -0
  63. package/dist/worker/console/chat/assistant-content.js +5 -34
  64. package/dist/worker/console/chat/chat-event-store.js +62 -10
  65. package/dist/worker/console/chat/context-insights.js +723 -0
  66. package/dist/worker/console/chat/conversation-nodes.js +383 -0
  67. package/dist/worker/console/chat/db-connections.js +854 -0
  68. package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +1 -1
  69. package/dist/worker/console/chat/pi-runtime/custom-tools/sql-tools.js +655 -0
  70. package/dist/worker/console/chat/pi-runtime.js +445 -36
  71. package/dist/worker/console/chat/provider-error.js +0 -12
  72. package/dist/worker/console/chat/repo-browser.js +52 -4
  73. package/dist/worker/console/chat/routes.js +577 -72
  74. package/dist/worker/console/chat/sdd-data-alignment.js +8 -31
  75. package/dist/worker/console/chat/session-store.js +147 -19
  76. package/dist/worker/console/chat/shortcuts.js +7 -0
  77. package/dist/worker/console/chat/timeline-message-order.js +22 -0
  78. package/dist/worker/console/chat/tools.js +34 -0
  79. package/dist/worker/console/chat/turn-process.js +237 -66
  80. package/dist/worker/console/chat/user-turn-outline.js +19 -0
  81. package/dist/worker/console/console-update-runtime.js +2 -2
  82. package/dist/worker/console/dag-confirmation.js +3 -0
  83. package/dist/worker/console/dag-execution-receipt.js +3 -0
  84. package/dist/worker/console/operator-actions.js +32 -3
  85. package/dist/worker/console/operator-user-error.js +28 -1
  86. package/dist/worker/console/pi-readiness.js +4 -4
  87. package/dist/worker/console/prd-intake-bridge.js +5 -12
  88. package/dist/worker/console/recovery-cta.js +14 -14
  89. package/dist/worker/console/server.js +5 -1
  90. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-8-j6y-sd.js → abnfDiagram-N423BO3Z-r1NAPU_5.js} +1 -1
  91. package/dist/worker/console/static/assets/{arc-eoQiMvuk.js → arc-dT5T4sVL.js} +1 -1
  92. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-C4A3uMcI.js → architectureDiagram-T3A2C74G-CP_cOq46.js} +1 -1
  93. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-D4zD2F-Q.js → blockDiagram-VBNYF7ZC-sToEZxEf.js} +1 -1
  94. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-j1RkJziL.js → c4Diagram-5PPSVZJV-DSxwwi2m.js} +1 -1
  95. package/dist/worker/console/static/assets/channel-CyBY_yGk.js +1 -0
  96. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-YBHmhik1.js → chunk-2GRJ4B5K-B9fh0IkF.js} +1 -1
  97. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-COfWyo9P.js → chunk-2Q5K7J3B-CAUNl-A6.js} +1 -1
  98. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-I99OUkHY.js → chunk-5RXB4S5H-BomeqbNX.js} +1 -1
  99. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-XKxoJNJ4.js → chunk-5VM5RSS4-BNAuTOLE.js} +1 -1
  100. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DLT_cYx1.js → chunk-6Q2QTUOP-DfzjRD5y.js} +1 -1
  101. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-CxcKZ9mV.js → chunk-GF5L2VYU-C3uE-yc2.js} +1 -1
  102. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-V1EqXdjY.js → chunk-JWPE2WC7-C3sQMMYr.js} +1 -1
  103. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-DebTtdFp.js → chunk-KBJHAD2P-D_AtEYQL.js} +1 -1
  104. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-B-ivNRDf.js → chunk-RYQCIY6F-DW4TwhKv.js} +1 -1
  105. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-DC_Ds11b.js → chunk-XXDRQBXY-CTQDmJcp.js} +1 -1
  106. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-D5lN4E_E.js +1 -0
  107. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-D5lN4E_E.js +1 -0
  108. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-sWEqKwIb.js → cose-bilkent-JH36ORCC-iMqPuBsL.js} +1 -1
  109. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BXa_dcu4.js → cynefin-VYW2F7L2-DktIuDWs.js} +1 -1
  110. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-C-Mle84F.js → cynefinDiagram-MW4NZA55-BgVnjyEs.js} +1 -1
  111. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-CXPDBITe.js → dagre-VZM6K2ZE-CR25E4bu.js} +1 -1
  112. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CC-WJQfa.js → diagram-7IWD3JNH-CPM2h5HY.js} +1 -1
  113. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-CDAV5Vs4.js → diagram-B4RE2ZJO-DqF0x2g1.js} +1 -1
  114. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-CmFiAcNz.js → diagram-LBJQPF4R-G8BYp2eb.js} +1 -1
  115. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-DPBZHuyn.js → diagram-Q27KOJAE-BbC4kT_D.js} +1 -1
  116. package/dist/worker/console/static/assets/{diagram-UB23O5K3-jUlm_Ds3.js → diagram-UB23O5K3-CKZwZ-G5.js} +1 -1
  117. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-DWhQ3mfY.js → ebnfDiagram-BXEA7PRR-kJDmheia.js} +1 -1
  118. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-Tr2gMqet.js → erDiagram-JOGREHBK-DFTVHyxB.js} +1 -1
  119. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-DJjVQHPA.js → flowDiagram-UKHOOZJN-BqdN5_os.js} +1 -1
  120. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-D74dQ4u0.js → ganttDiagram-PKOTCBZU-SYDjVakh.js} +1 -1
  121. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-DwW0tZ0X.js → gitGraphDiagram-DS77QQ5N-Bf8bNpGA.js} +1 -1
  122. package/dist/worker/console/static/assets/index-B28Onmfy.css +1 -0
  123. package/dist/worker/console/static/assets/index-CTMZsDmh.js +486 -0
  124. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-ILCbxJyb.js → infoDiagram-6WML65LV-DIeAmJ45.js} +1 -1
  125. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-DeuWBQ89.js → ishikawaDiagram-WSZJBQD7-oikqUAlo.js} +1 -1
  126. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-CF5ih8Fk.js → journeyDiagram-NVQOT4AX-mKEF_xYT.js} +1 -1
  127. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-C7yOSuRO.js → kanban-definition-27J2QSJJ-BdWJHPnN.js} +1 -1
  128. package/dist/worker/console/static/assets/{linear-BDZ9riWi.js → linear-DGRlieMH.js} +1 -1
  129. package/dist/worker/console/static/assets/{mermaid.core-7pKqYtpZ.js → mermaid.core-4P9yPC9c.js} +5 -5
  130. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-LeJDybSU.js → mindmap-definition-FAOFIHXS-5PTSkos6.js} +1 -1
  131. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-BJvT3pMD.js → pegDiagram-VL7TDLO6-DONIFpG5.js} +1 -1
  132. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-_rGqpMan.js → pieDiagram-7S7Q4E2Y-D_Z4S70M.js} +1 -1
  133. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-DPcSv5aA.js → quadrantDiagram-CIZ2JOQS-CAsjh8iY.js} +1 -1
  134. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-Drxx4hkJ.js → railroadDiagram-AXF67PYL-Cx4Dd6ac.js} +1 -1
  135. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-BCTUdU4z.js → requirementDiagram-LRYGKXZP-cQb7mwyH.js} +1 -1
  136. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-B6wzbZmB.js → sankeyDiagram-W5VNT64P-Cd-DhUdf.js} +1 -1
  137. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BGt8d3QQ.js → sequenceDiagram-SI44F4Z6-AlKYRgIk.js} +1 -1
  138. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-7nlhJKo7.js → sizeCapture-X5ZJPWSS-CUy_ET4e.js} +1 -1
  139. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-Cv2stqMA.js → stateDiagram-OKZ733FA-CTuVe6Sa.js} +1 -1
  140. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BsWhs8O7.js +1 -0
  141. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-qDAo4Yc1.js → swimlanes-SLNWSIFB-ChFLJb-v.js} +2 -2
  142. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-CJcioYGH.js +8 -0
  143. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CKbDNKTr.js → timeline-definition-Z64GVDOM-DZZeiAPr.js} +1 -1
  144. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-DI-9EHic.js → vennDiagram-T6HMQDX7-t4O91cZU.js} +1 -1
  145. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-BrzzRDpX.js → wardleyDiagram-T6FBY63Y-CV5qGHZu.js} +1 -1
  146. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-BclH5hGh.js → xychartDiagram-ELKLHX3M-DyXbytUI.js} +1 -1
  147. package/dist/worker/console/static/index.html +2 -2
  148. package/dist/worker/console/static-src/app/console-types.js +9 -1
  149. package/dist/worker/console/static-src/operator-chat/animation-frame-batcher.js +38 -0
  150. package/dist/worker/console/static-src/operator-chat/chat-link.js +20 -0
  151. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +186 -5
  152. package/dist/worker/console/static-src/operator-chat/chat-stream-continuity.js +101 -0
  153. package/dist/worker/console/static-src/operator-chat/compaction-message.js +18 -3
  154. package/dist/worker/console/static-src/operator-chat/context-insights-store.js +64 -0
  155. package/dist/worker/console/static-src/operator-chat/details-rail-surfaces.js +98 -0
  156. package/dist/worker/console/static-src/operator-chat/file-palette-nav.js +81 -0
  157. package/dist/worker/console/static-src/operator-chat/pending-user-message.js +17 -3
  158. package/dist/worker/console/static-src/operator-chat/process-label.js +27 -5
  159. package/dist/worker/console/static-src/operator-chat/tools-catalog.js +16 -7
  160. package/dist/worker/console/static-src/operator-chat/transcript-mode.js +21 -0
  161. package/dist/worker/console/static-src/operator-chat/turn-group-equality.js +4 -1
  162. package/dist/worker/console/static-src/operator-chat/turn-process-disclosure.js +13 -5
  163. package/dist/worker/console/static-src/operator-chat/turn-state-projection.js +166 -0
  164. package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +56 -2
  165. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +211 -40
  166. package/dist/worker/console/static-src/operator-chat/useChatStream.js +124 -27
  167. package/dist/worker/console/static-src/operator-chat/useChatThread.js +88 -20
  168. package/dist/worker/console/static-src/operator-chat/useComposer.js +80 -6
  169. package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +13 -3
  170. package/dist/worker/console/static-src/operator-chat/useRuntimeControls.js +36 -17
  171. package/dist/worker/console/static-src/operator-chat/useRuntimeSnapshot.js +18 -0
  172. package/dist/worker/console/static-src/operator-chat/useWorkspaceBrowserGate.js +4 -0
  173. package/dist/worker/console/static-src/shell/console-update-reload.js +1 -1
  174. package/dist/worker/console/workspace-context.js +2 -0
  175. package/dist/worker/console/workspace-initialization.js +3 -3
  176. package/dist/worker/observability/read-model.js +23 -2
  177. package/dist/worker/observe/node-context-insights.js +479 -0
  178. package/dist/worker/observe/static/console-theme.css +174 -0
  179. package/dist/worker/observe/static/console-theme.js +36 -0
  180. package/dist/worker/observe/static/operator-chrome.css +85 -0
  181. package/dist/worker/observe/static/operator-chrome.js +51 -0
  182. package/dist/worker/scheduler/scheduled-goal-dispatch.js +3 -2
  183. package/dist/worker/scheduler/scheduled-goal-evidence.js +66 -3
  184. package/dist/worker/scheduler/scheduled-goal-store.js +10 -0
  185. package/dist/workflows/dag/budget-enforcement.js +31 -2
  186. package/dist/workflows/dag/checkpoint.js +686 -0
  187. package/dist/workflows/dag/frontend-closeout.js +3 -1
  188. package/dist/workflows/dag/frontend-contract-facts.js +11 -8
  189. package/dist/workflows/dag/frontend-design-policy.js +6 -6
  190. package/dist/workflows/dag/frontend-durable-tools.js +90 -70
  191. package/dist/workflows/dag/frontend-implementation-contract.js +146 -57
  192. package/dist/workflows/dag/frontend-plan-canary.js +66 -16
  193. package/dist/workflows/dag/frontend-plan-decision-contract.js +13 -21
  194. package/dist/workflows/dag/frontend-plan-progress.js +92 -0
  195. package/dist/workflows/dag/frontend-recovery-plan.js +10 -5
  196. package/dist/workflows/dag/frontend-recovery-run.js +51 -46
  197. package/dist/workflows/dag/frontend-repair-assertions.js +36 -0
  198. package/dist/workflows/dag/frontend-review-context.js +29 -1
  199. package/dist/workflows/dag/frontend-review-scopes.js +92 -2
  200. package/dist/workflows/dag/frontend-risk.js +8 -3
  201. package/dist/workflows/dag/frontend-root-observation.js +261 -0
  202. package/dist/workflows/dag/frontend-session-budget.js +52 -39
  203. package/dist/workflows/dag/frontend-session-context.js +10 -0
  204. package/dist/workflows/dag/frontend-test-execution-evidence.js +206 -48
  205. package/dist/workflows/dag/frontend-typed-event-store.js +11 -1
  206. package/dist/workflows/dag/frontend-verification-trace.js +6 -0
  207. package/dist/workflows/dag/frontend-writer-admission.js +3 -1
  208. package/dist/workflows/dag/hybrid/sources.js +1812 -0
  209. package/dist/workflows/dag/hybrid/templates/backend-test.js +1807 -0
  210. package/dist/workflows/dag/hybrid/templates/frontend-test.js +702 -0
  211. package/dist/workflows/dag/hybrid/templates/frontend.js +1529 -0
  212. package/dist/workflows/dag/hybrid/templates/index.js +8 -0
  213. package/dist/workflows/dag/hybrid/templates/kg-bootstrap.js +449 -0
  214. package/dist/workflows/dag/hybrid/templates/knowledge-sync.js +495 -0
  215. package/dist/workflows/dag/hybrid/templates/shared.js +101 -0
  216. package/dist/workflows/dag/hybrid/templates/standard.js +265 -0
  217. package/dist/workflows/dag/hybrid/types.js +32 -0
  218. package/dist/workflows/dag/init-hybrid.js +57 -7106
  219. package/dist/workflows/dag/node-execution.js +11 -11
  220. package/dist/workflows/dag/output-protocol.js +1 -0
  221. package/dist/workflows/dag/rerun-feedback.js +35 -4
  222. package/dist/workflows/dag/rerun-task.js +62 -66
  223. package/dist/workflows/dag/runner.js +38 -1159
  224. package/dist/workflows/dag/terminal-status.js +502 -0
  225. package/dist/workflows/dag/types.js +15 -8
  226. package/dist/workflows/loop/benchmark.js +11 -8
  227. package/docs/README.md +1 -1
  228. package/docs/architecture/dag-execution.md +1 -1
  229. package/docs/architecture/runtime-boundaries.md +1 -1
  230. package/docs/governance/harness-methodology-verification.md +11 -0
  231. package/docs/templates/backend-test-dag.json +5 -4
  232. package/docs/templates/frontend-implementation-contract.schema.json +31 -11
  233. package/package.json +6 -4
  234. package/skills/frontend-design-review/SKILL.md +8 -11
  235. package/skills/frontend-design-review/references/review-checklist.md +3 -4
  236. package/skills/frontend-review/SKILL.md +5 -1
  237. package/skills/loop-agent/references/command-reference.md +8 -0
  238. package/skills/loop-agent/references/hybrid-dag.md +1 -1
  239. package/dist/worker/console/static/assets/channel-ChE7y-cx.js +0 -1
  240. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-C01TCf2X.js +0 -1
  241. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-C01TCf2X.js +0 -1
  242. package/dist/worker/console/static/assets/index-BWkIfcrK.css +0 -1
  243. package/dist/worker/console/static/assets/index-Cdkvw_H6.js +0 -469
  244. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DC7V5vcq.js +0 -1
  245. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Bwy4QUTO.js +0 -8
@@ -0,0 +1,383 @@
1
+ function finiteStep(data) {
2
+ return typeof data.step === "number" && Number.isSafeInteger(data.step) && data.step >= 0
3
+ ? data.step
4
+ : undefined;
5
+ }
6
+ function locationFor(event, step = finiteStep(event.data)) {
7
+ return step === undefined
8
+ ? { kind: "turn", turnId: event.turnId }
9
+ : { kind: "step", turnId: event.turnId, step };
10
+ }
11
+ function status(value) {
12
+ return value === "scheduled" ||
13
+ value === "started" ||
14
+ value === "cancelled" ||
15
+ value === "running" ||
16
+ value === "completed" ||
17
+ value === "failed" ||
18
+ value === "interrupted"
19
+ ? value
20
+ : undefined;
21
+ }
22
+ function positiveInteger(value) {
23
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0
24
+ ? value
25
+ : undefined;
26
+ }
27
+ function nonNegativeNumber(value) {
28
+ return typeof value === "number" && Number.isFinite(value) && value >= 0
29
+ ? value
30
+ : undefined;
31
+ }
32
+ function nonEmptyString(value) {
33
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
34
+ }
35
+ function unknownRetryNode(event, base) {
36
+ return {
37
+ ...base,
38
+ key: `unknown:${event.eventId}`,
39
+ kind: "unknown",
40
+ location: locationFor(event),
41
+ data: {
42
+ eventType: "model_retry",
43
+ preview: "Incomplete model retry lifecycle event",
44
+ },
45
+ };
46
+ }
47
+ function retryStateFromEvent(data) {
48
+ if (data.state === "scheduled")
49
+ return "scheduled";
50
+ return data.success === false || data.state === "failed"
51
+ ? "cancelled"
52
+ : "started";
53
+ }
54
+ function isRetryAttempt(value) {
55
+ if (!value || typeof value !== "object" || Array.isArray(value))
56
+ return false;
57
+ const attempt = value;
58
+ return (positiveInteger(attempt.attempt) !== undefined &&
59
+ positiveInteger(attempt.maxAttempts) !== undefined &&
60
+ nonNegativeNumber(attempt.delayMs) !== undefined &&
61
+ nonEmptyString(attempt.errorMessage) !== undefined &&
62
+ (attempt.state === "scheduled" ||
63
+ attempt.state === "started" ||
64
+ attempt.state === "cancelled") &&
65
+ typeof attempt.seq === "number" &&
66
+ typeof attempt.at === "number");
67
+ }
68
+ /** Read the current complete attempt from a projected retry-chain node. */
69
+ export function modelRetryCurrent(node) {
70
+ if (node.kind !== "retry")
71
+ return undefined;
72
+ return isRetryAttempt(node.data.current) ? node.data.current : undefined;
73
+ }
74
+ function modelRetryAttempts(node) {
75
+ return Array.isArray(node.data.attempts)
76
+ ? node.data.attempts.filter(isRetryAttempt)
77
+ : [];
78
+ }
79
+ function retryUpdate(node) {
80
+ const value = node.data.retryUpdate;
81
+ if (!value || typeof value !== "object" || Array.isArray(value))
82
+ return undefined;
83
+ const candidate = value;
84
+ if (positiveInteger(candidate.attempt) === undefined ||
85
+ (candidate.state !== "started" && candidate.state !== "cancelled"))
86
+ return undefined;
87
+ return candidate;
88
+ }
89
+ /** Convert one already-redacted durable event into a stable UI node. */
90
+ export function conversationNodeFromEvent(event) {
91
+ const at = Date.parse(event.at);
92
+ const base = {
93
+ anchorSeq: event.seq,
94
+ updatedSeq: event.seq,
95
+ at: Number.isFinite(at) ? at : 0,
96
+ data: event.data,
97
+ };
98
+ const step = finiteStep(event.data);
99
+ switch (event.kind) {
100
+ case "step_start":
101
+ case "step_end": {
102
+ if (step === undefined)
103
+ return undefined;
104
+ const outcome = status(event.data.outcome);
105
+ return {
106
+ ...base,
107
+ key: `step:${event.turnId}:${step}`,
108
+ kind: "step",
109
+ location: { kind: "step", turnId: event.turnId, step },
110
+ status: event.kind === "step_start" ? "running" : (outcome ?? "completed"),
111
+ };
112
+ }
113
+ case "model_retry": {
114
+ const attempt = positiveInteger(event.data.attempt);
115
+ if (attempt === undefined)
116
+ return unknownRetryNode(event, base);
117
+ const retryState = retryStateFromEvent(event.data);
118
+ const key = `retry:${event.turnId}:${step ?? 0}`;
119
+ if (retryState !== "scheduled") {
120
+ return {
121
+ ...base,
122
+ key,
123
+ kind: "retry",
124
+ location: locationFor(event),
125
+ status: retryState,
126
+ data: {
127
+ retryUpdate: {
128
+ attempt,
129
+ state: retryState,
130
+ seq: event.seq,
131
+ at: base.at,
132
+ },
133
+ },
134
+ };
135
+ }
136
+ const maxAttempts = positiveInteger(event.data.maxAttempts);
137
+ const delayMs = nonNegativeNumber(event.data.delayMs);
138
+ const errorMessage = nonEmptyString(event.data.errorMessage);
139
+ if (maxAttempts === undefined || delayMs === undefined || !errorMessage) {
140
+ return unknownRetryNode(event, base);
141
+ }
142
+ const current = {
143
+ attempt,
144
+ maxAttempts,
145
+ delayMs,
146
+ errorMessage,
147
+ state: "scheduled",
148
+ seq: event.seq,
149
+ at: base.at,
150
+ };
151
+ return {
152
+ ...base,
153
+ key,
154
+ kind: "retry",
155
+ location: locationFor(event),
156
+ status: "scheduled",
157
+ data: { attempts: [current], current },
158
+ };
159
+ }
160
+ case "turn_error":
161
+ return {
162
+ ...base,
163
+ key: `turn-error:${event.turnId}`,
164
+ kind: "turn-error",
165
+ location: locationFor(event),
166
+ status: "failed",
167
+ };
168
+ case "turn_max_tokens":
169
+ return {
170
+ ...base,
171
+ key: `max-tokens:${event.turnId}:${step ?? 0}`,
172
+ kind: "max-tokens",
173
+ location: locationFor(event),
174
+ status: "completed",
175
+ };
176
+ case "request_context": {
177
+ const requestId = typeof event.data.requestId === "string" && event.data.requestId
178
+ ? event.data.requestId
179
+ : event.eventId;
180
+ return {
181
+ ...base,
182
+ key: `request:${requestId}`,
183
+ kind: "request",
184
+ location: locationFor(event),
185
+ status: "completed",
186
+ };
187
+ }
188
+ case "command": {
189
+ const commandId = typeof event.data.commandId === "string" && event.data.commandId
190
+ ? event.data.commandId
191
+ : event.eventId;
192
+ return {
193
+ ...base,
194
+ key: `command:${commandId}`,
195
+ kind: "command",
196
+ location: { kind: "turn", turnId: event.turnId },
197
+ status: status(event.data.outcome) ?? "completed",
198
+ };
199
+ }
200
+ case "unknown":
201
+ return {
202
+ ...base,
203
+ key: `unknown:${event.eventId}`,
204
+ kind: "unknown",
205
+ location: locationFor(event),
206
+ };
207
+ }
208
+ }
209
+ export function conversationNodesFromEvents(events) {
210
+ let nodes = [];
211
+ for (const event of events) {
212
+ const node = conversationNodeFromEvent(event);
213
+ if (node)
214
+ nodes = upsertConversationNode(nodes, node);
215
+ }
216
+ return nodes;
217
+ }
218
+ /** Keyed upsert that preserves the first structural anchor and location. */
219
+ export function upsertConversationNode(nodes, next) {
220
+ if (next.kind === "retry")
221
+ return upsertRetryNode(nodes, next);
222
+ const merged = upsertBase(nodes, next);
223
+ if (next.kind === "step" && next.location.kind === "step") {
224
+ const { step: nextStep, turnId } = next.location;
225
+ if (next.status === "running") {
226
+ return transitionScheduledRetries(merged, (node) => node.location.kind === "step" &&
227
+ node.location.turnId === turnId &&
228
+ node.location.step < nextStep, "started", next.updatedSeq);
229
+ }
230
+ return transitionScheduledRetries(merged, (node) => node.location.kind === "step" &&
231
+ node.location.turnId === turnId &&
232
+ node.location.step === nextStep &&
233
+ node.anchorSeq < next.updatedSeq, "cancelled", next.updatedSeq);
234
+ }
235
+ if (next.kind === "turn-error") {
236
+ return transitionScheduledRetries(merged, (node) => node.location.kind !== "session" &&
237
+ next.location.kind !== "session" &&
238
+ node.location.turnId === next.location.turnId, "cancelled", next.updatedSeq);
239
+ }
240
+ return merged;
241
+ }
242
+ function upsertBase(nodes, next) {
243
+ const index = nodes.findIndex((node) => node.key === next.key);
244
+ if (index < 0) {
245
+ return [...nodes, next].sort((left, right) => left.anchorSeq - right.anchorSeq || left.key.localeCompare(right.key));
246
+ }
247
+ const previous = nodes[index];
248
+ if (next.updatedSeq < previous.updatedSeq)
249
+ return [...nodes];
250
+ const merged = {
251
+ ...previous,
252
+ ...next,
253
+ anchorSeq: previous.anchorSeq,
254
+ at: previous.at,
255
+ location: previous.location,
256
+ data: { ...previous.data, ...next.data },
257
+ };
258
+ const result = [...nodes];
259
+ result[index] = merged;
260
+ return result;
261
+ }
262
+ function retryTurnId(node) {
263
+ return node.location.kind === "session" ? undefined : node.location.turnId;
264
+ }
265
+ function retryCandidateIndex(nodes, next) {
266
+ const exact = nodes.findIndex((node) => node.key === next.key);
267
+ if (exact >= 0)
268
+ return exact;
269
+ const update = retryUpdate(next);
270
+ const nextCurrent = modelRetryCurrent(next);
271
+ const attempt = update?.attempt ?? nextCurrent?.attempt;
272
+ const turnId = retryTurnId(next);
273
+ if (attempt === undefined || !turnId)
274
+ return -1;
275
+ for (let index = nodes.length - 1; index >= 0; index -= 1) {
276
+ const candidate = nodes[index];
277
+ const current = modelRetryCurrent(candidate);
278
+ if (candidate.kind !== "retry" || retryTurnId(candidate) !== turnId || !current)
279
+ continue;
280
+ if (current.attempt === attempt)
281
+ return index;
282
+ if (nextCurrent?.state === "scheduled" && current.attempt + 1 === attempt)
283
+ return index;
284
+ }
285
+ return -1;
286
+ }
287
+ function upsertRetryNode(nodes, next) {
288
+ const index = retryCandidateIndex(nodes, next);
289
+ const nextCurrent = modelRetryCurrent(next);
290
+ const update = retryUpdate(next);
291
+ if (index < 0) {
292
+ if (nextCurrent)
293
+ return upsertBase(nodes, next);
294
+ return upsertBase(nodes, {
295
+ ...next,
296
+ key: `unknown:${next.key}:${next.updatedSeq}`,
297
+ kind: "unknown",
298
+ status: undefined,
299
+ data: {
300
+ eventType: "model_retry",
301
+ preview: "Orphan model retry lifecycle update",
302
+ },
303
+ });
304
+ }
305
+ const previous = nodes[index];
306
+ if (next.updatedSeq < previous.updatedSeq)
307
+ return [...nodes];
308
+ let attempts = modelRetryAttempts(previous);
309
+ if (nextCurrent) {
310
+ attempts = attempts.map((attempt) => attempt.state === "scheduled" && attempt.attempt < nextCurrent.attempt
311
+ ? { ...attempt, state: "started" }
312
+ : attempt);
313
+ const existing = attempts.findIndex((attempt) => attempt.attempt === nextCurrent.attempt);
314
+ if (existing >= 0)
315
+ attempts[existing] = { ...attempts[existing], ...nextCurrent };
316
+ else
317
+ attempts = [...attempts, nextCurrent];
318
+ }
319
+ else if (update) {
320
+ attempts = attempts.map((attempt) => attempt.attempt === update.attempt
321
+ ? { ...attempt, state: update.state }
322
+ : attempt);
323
+ }
324
+ const current = attempts.at(-1);
325
+ if (!current)
326
+ return [...nodes];
327
+ const result = [...nodes];
328
+ result[index] = {
329
+ ...previous,
330
+ updatedSeq: next.updatedSeq,
331
+ status: current.state,
332
+ data: { attempts, current },
333
+ };
334
+ return result;
335
+ }
336
+ function transitionScheduledRetries(nodes, predicate, state, updatedSeq) {
337
+ return nodes.map((node) => {
338
+ const current = modelRetryCurrent(node);
339
+ if (node.kind !== "retry" || current?.state !== "scheduled" || !predicate(node)) {
340
+ return node;
341
+ }
342
+ const attempts = modelRetryAttempts(node).map((attempt) => attempt.attempt === current.attempt
343
+ ? { ...attempt, state }
344
+ : attempt);
345
+ const nextCurrent = attempts.at(-1);
346
+ return {
347
+ ...node,
348
+ updatedSeq: Math.max(node.updatedSeq, updatedSeq),
349
+ status: state,
350
+ data: { attempts, current: nextCurrent },
351
+ };
352
+ });
353
+ }
354
+ /** Resolve explicit parent links only. Cycles and excessive chains fail flat. */
355
+ export function toolNestingDepths(tools, maxDepth = 32) {
356
+ const byId = new Map(tools.map((tool) => [tool.id, tool]));
357
+ const depths = new Map();
358
+ const cyclic = new Set();
359
+ const resolve = (id, path) => {
360
+ const cached = depths.get(id);
361
+ if (cached !== undefined)
362
+ return cached;
363
+ const cycleAt = path.indexOf(id);
364
+ if (cycleAt >= 0) {
365
+ for (const key of path.slice(cycleAt))
366
+ cyclic.add(key);
367
+ return 0;
368
+ }
369
+ if (path.length >= maxDepth)
370
+ return 0;
371
+ const tool = byId.get(id);
372
+ const parent = tool?.parentToolCallId;
373
+ if (!parent || !byId.has(parent) || parent === id)
374
+ return 0;
375
+ const depth = Math.min(maxDepth, resolve(parent, [...path, id]) + 1);
376
+ return cyclic.has(id) ? 0 : depth;
377
+ };
378
+ for (const tool of tools)
379
+ depths.set(tool.id, resolve(tool.id, []));
380
+ for (const id of cyclic)
381
+ depths.set(id, 0);
382
+ return depths;
383
+ }