@maudecode/talaria-web 1.16.1 → 1.18.0

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 (445) hide show
  1. package/_release.json +8 -8
  2. package/dist/api/auth-raw.d.ts +1 -1
  3. package/dist/api/auth-raw.js +4 -4
  4. package/dist/api/auth-raw.js.map +1 -1
  5. package/dist/api/automation-raw.d.ts +6 -0
  6. package/dist/api/automation-raw.js +59 -9
  7. package/dist/api/automation-raw.js.map +1 -1
  8. package/dist/api/automation-router.d.ts +163 -10
  9. package/dist/api/automation-router.js +25 -8
  10. package/dist/api/automation-router.js.map +1 -1
  11. package/dist/api/chat-router.d.ts +700 -15
  12. package/dist/api/chat-router.js +74 -55
  13. package/dist/api/chat-router.js.map +1 -1
  14. package/dist/api/git-router.d.ts +47 -2
  15. package/dist/api/git-router.js +31 -22
  16. package/dist/api/git-router.js.map +1 -1
  17. package/dist/api/raw-routes.d.ts +14 -0
  18. package/dist/api/raw-routes.js +277 -36
  19. package/dist/api/raw-routes.js.map +1 -1
  20. package/dist/api/router.d.ts +10 -0
  21. package/dist/api/router.js +10 -8
  22. package/dist/api/router.js.map +1 -1
  23. package/dist/api/sessions-router.d.ts +1710 -73
  24. package/dist/api/sessions-router.js +164 -10
  25. package/dist/api/sessions-router.js.map +1 -1
  26. package/dist/api/settings-router.d.ts +132 -2
  27. package/dist/api/settings-router.js +15 -5
  28. package/dist/api/settings-router.js.map +1 -1
  29. package/dist/api/sse-routes.d.ts +16 -3
  30. package/dist/api/sse-routes.js +194 -67
  31. package/dist/api/sse-routes.js.map +1 -1
  32. package/dist/api/tools-raw.js +12 -25
  33. package/dist/api/tools-raw.js.map +1 -1
  34. package/dist/api/tools-router.d.ts +425 -19
  35. package/dist/api/tools-router.js +157 -26
  36. package/dist/api/tools-router.js.map +1 -1
  37. package/dist/app.d.ts +0 -9377
  38. package/dist/app.js +42 -17
  39. package/dist/app.js.map +1 -1
  40. package/dist/auth/gate.js +8 -2
  41. package/dist/auth/gate.js.map +1 -1
  42. package/dist/auth/oidc.d.ts +5 -2
  43. package/dist/auth/oidc.js +8 -7
  44. package/dist/auth/oidc.js.map +1 -1
  45. package/dist/bin/talaria-web.js +1 -1
  46. package/dist/bin/talaria-web.js.map +1 -1
  47. package/dist/cli/dotenv.js +1 -0
  48. package/dist/cli/dotenv.js.map +1 -1
  49. package/dist/config/agent-config.d.ts +2 -0
  50. package/dist/config/agent-config.js +12 -2
  51. package/dist/config/agent-config.js.map +1 -1
  52. package/dist/config.d.ts +2 -0
  53. package/dist/config.js +5 -1
  54. package/dist/config.js.map +1 -1
  55. package/dist/http/context.d.ts +20 -3
  56. package/dist/http/context.js +41 -8
  57. package/dist/http/context.js.map +1 -1
  58. package/dist/http/csp.d.ts +2 -1
  59. package/dist/http/csp.js +3 -2
  60. package/dist/http/csp.js.map +1 -1
  61. package/dist/onboarding.js +4 -0
  62. package/dist/onboarding.js.map +1 -1
  63. package/dist/profiles/profiles.d.ts +10 -0
  64. package/dist/profiles/profiles.js +40 -2
  65. package/dist/profiles/profiles.js.map +1 -1
  66. package/dist/providers/catalog.d.ts +101 -8
  67. package/dist/providers/catalog.js +463 -123
  68. package/dist/providers/catalog.js.map +1 -1
  69. package/dist/raster-image.d.ts +7 -0
  70. package/dist/raster-image.js +267 -0
  71. package/dist/raster-image.js.map +1 -0
  72. package/dist/redact.d.ts +1 -0
  73. package/dist/redact.js +354 -44
  74. package/dist/redact.js.map +1 -1
  75. package/dist/runtime.js +111 -27
  76. package/dist/runtime.js.map +1 -1
  77. package/dist/server.js +5 -0
  78. package/dist/server.js.map +1 -1
  79. package/dist/sessions/anchor.d.ts +2 -0
  80. package/dist/sessions/anchor.js +8 -3
  81. package/dist/sessions/anchor.js.map +1 -1
  82. package/dist/sessions/background-tasks.d.ts +2 -9
  83. package/dist/sessions/background-tasks.js +2 -12
  84. package/dist/sessions/background-tasks.js.map +1 -1
  85. package/dist/sessions/claude-code.d.ts +19 -0
  86. package/dist/sessions/claude-code.js +250 -0
  87. package/dist/sessions/claude-code.js.map +1 -0
  88. package/dist/sessions/cli-sessions.d.ts +15 -4
  89. package/dist/sessions/cli-sessions.js +120 -29
  90. package/dist/sessions/cli-sessions.js.map +1 -1
  91. package/dist/sessions/completions.d.ts +61 -9
  92. package/dist/sessions/completions.js +282 -34
  93. package/dist/sessions/completions.js.map +1 -1
  94. package/dist/sessions/compress.d.ts +14 -1
  95. package/dist/sessions/compress.js +52 -11
  96. package/dist/sessions/compress.js.map +1 -1
  97. package/dist/sessions/export.d.ts +5 -0
  98. package/dist/sessions/export.js +30 -0
  99. package/dist/sessions/export.js.map +1 -1
  100. package/dist/sessions/gateway-watcher.d.ts +7 -3
  101. package/dist/sessions/gateway-watcher.js +31 -19
  102. package/dist/sessions/gateway-watcher.js.map +1 -1
  103. package/dist/sessions/handoff.d.ts +32 -0
  104. package/dist/sessions/handoff.js +114 -0
  105. package/dist/sessions/handoff.js.map +1 -0
  106. package/dist/sessions/journal.d.ts +8 -0
  107. package/dist/sessions/journal.js +44 -10
  108. package/dist/sessions/journal.js.map +1 -1
  109. package/dist/sessions/list.d.ts +13 -3
  110. package/dist/sessions/list.js +46 -15
  111. package/dist/sessions/list.js.map +1 -1
  112. package/dist/sessions/merge.d.ts +53 -5
  113. package/dist/sessions/merge.js +219 -23
  114. package/dist/sessions/merge.js.map +1 -1
  115. package/dist/sessions/recovery.d.ts +22 -0
  116. package/dist/sessions/recovery.js +506 -0
  117. package/dist/sessions/recovery.js.map +1 -0
  118. package/dist/sessions/relay.d.ts +21 -2
  119. package/dist/sessions/relay.js +156 -11
  120. package/dist/sessions/relay.js.map +1 -1
  121. package/dist/sessions/service.d.ts +152 -8
  122. package/dist/sessions/service.js +640 -72
  123. package/dist/sessions/service.js.map +1 -1
  124. package/dist/sessions/session.d.ts +17 -1
  125. package/dist/sessions/session.js +63 -4
  126. package/dist/sessions/session.js.map +1 -1
  127. package/dist/sessions/state-db-worker.d.ts +1 -0
  128. package/dist/sessions/state-db-worker.js +33 -0
  129. package/dist/sessions/state-db-worker.js.map +1 -0
  130. package/dist/sessions/state-db.d.ts +87 -4
  131. package/dist/sessions/state-db.js +417 -8
  132. package/dist/sessions/state-db.js.map +1 -1
  133. package/dist/sessions/store.d.ts +7 -0
  134. package/dist/sessions/store.js +36 -22
  135. package/dist/sessions/store.js.map +1 -1
  136. package/dist/sessions/streams.d.ts +10 -0
  137. package/dist/sessions/streams.js +14 -3
  138. package/dist/sessions/streams.js.map +1 -1
  139. package/dist/sessions/titles.d.ts +2 -0
  140. package/dist/sessions/titles.js +4 -0
  141. package/dist/sessions/titles.js.map +1 -1
  142. package/dist/sessions/todo.d.ts +6 -1
  143. package/dist/sessions/todo.js +11 -4
  144. package/dist/sessions/todo.js.map +1 -1
  145. package/dist/sessions/tool-display.d.ts +12 -1
  146. package/dist/sessions/tool-display.js +50 -1
  147. package/dist/sessions/tool-display.js.map +1 -1
  148. package/dist/sessions/turn-context.d.ts +1 -1
  149. package/dist/sessions/turn-context.js +11 -7
  150. package/dist/sessions/turn-context.js.map +1 -1
  151. package/dist/sessions/turn.d.ts +67 -11
  152. package/dist/sessions/turn.js +413 -111
  153. package/dist/sessions/turn.js.map +1 -1
  154. package/dist/sessions/wakeup-pause.d.ts +59 -0
  155. package/dist/sessions/wakeup-pause.js +181 -0
  156. package/dist/sessions/wakeup-pause.js.map +1 -0
  157. package/dist/settings.d.ts +20 -2
  158. package/dist/settings.js +45 -9
  159. package/dist/settings.js.map +1 -1
  160. package/dist/sidecar/fake.d.ts +4 -4
  161. package/dist/sidecar/fake.js +5 -2
  162. package/dist/sidecar/fake.js.map +1 -1
  163. package/dist/spa.js +2 -1
  164. package/dist/spa.js.map +1 -1
  165. package/dist/startup.d.ts +13 -5
  166. package/dist/startup.js +48 -0
  167. package/dist/startup.js.map +1 -1
  168. package/dist/test/harness.js +2 -0
  169. package/dist/test/harness.js.map +1 -1
  170. package/dist/test/ts-worker-hooks.d.ts +1 -0
  171. package/dist/test/ts-worker-hooks.js +24 -0
  172. package/dist/test/ts-worker-hooks.js.map +1 -0
  173. package/dist/text/diff.d.ts +9 -14
  174. package/dist/text/diff.js +74 -108
  175. package/dist/text/diff.js.map +1 -1
  176. package/dist/tools/crons.js +45 -8
  177. package/dist/tools/crons.js.map +1 -1
  178. package/dist/tools/dashboard-plugins.d.ts +53 -0
  179. package/dist/tools/dashboard-plugins.js +188 -0
  180. package/dist/tools/dashboard-plugins.js.map +1 -0
  181. package/dist/tools/extensions.d.ts +13 -1
  182. package/dist/tools/extensions.js +132 -60
  183. package/dist/tools/extensions.js.map +1 -1
  184. package/dist/tools/health.d.ts +32 -0
  185. package/dist/tools/health.js +111 -19
  186. package/dist/tools/health.js.map +1 -1
  187. package/dist/tools/insights.d.ts +8 -2
  188. package/dist/tools/insights.js +18 -2
  189. package/dist/tools/insights.js.map +1 -1
  190. package/dist/tools/kanban.d.ts +41 -1
  191. package/dist/tools/kanban.js +113 -2
  192. package/dist/tools/kanban.js.map +1 -1
  193. package/dist/tools/mcp.d.ts +15 -1
  194. package/dist/tools/mcp.js +99 -5
  195. package/dist/tools/mcp.js.map +1 -1
  196. package/dist/tools/project-os.d.ts +11 -0
  197. package/dist/tools/project-os.js +267 -0
  198. package/dist/tools/project-os.js.map +1 -0
  199. package/dist/tools/skills.d.ts +5 -1
  200. package/dist/tools/skills.js +5 -3
  201. package/dist/tools/skills.js.map +1 -1
  202. package/dist/tools/terminal.d.ts +1 -0
  203. package/dist/tools/terminal.js +1 -1
  204. package/dist/tools/terminal.js.map +1 -1
  205. package/dist/tools/updates.d.ts +33 -8
  206. package/dist/tools/updates.js +236 -57
  207. package/dist/tools/updates.js.map +1 -1
  208. package/dist/tools/wiki.d.ts +68 -0
  209. package/dist/tools/wiki.js +413 -0
  210. package/dist/tools/wiki.js.map +1 -0
  211. package/dist/workspace/escape.d.ts +61 -0
  212. package/dist/workspace/escape.js +149 -0
  213. package/dist/workspace/escape.js.map +1 -0
  214. package/dist/workspace/extract.d.ts +22 -0
  215. package/dist/workspace/extract.js +308 -0
  216. package/dist/workspace/extract.js.map +1 -0
  217. package/dist/workspace/fs.d.ts +19 -3
  218. package/dist/workspace/fs.js +96 -23
  219. package/dist/workspace/fs.js.map +1 -1
  220. package/dist/workspace/git.d.ts +18 -0
  221. package/dist/workspace/git.js +38 -25
  222. package/dist/workspace/git.js.map +1 -1
  223. package/dist/workspace/media.d.ts +4 -4
  224. package/dist/workspace/media.js +18 -45
  225. package/dist/workspace/media.js.map +1 -1
  226. package/dist/workspace/preview.d.ts +28 -0
  227. package/dist/workspace/preview.js +110 -0
  228. package/dist/workspace/preview.js.map +1 -0
  229. package/dist/workspace/rollback.d.ts +36 -21
  230. package/dist/workspace/rollback.js +179 -270
  231. package/dist/workspace/rollback.js.map +1 -1
  232. package/dist/workspace/unzip.js +4 -1
  233. package/dist/workspace/unzip.js.map +1 -1
  234. package/dist/workspace/upload.d.ts +9 -4
  235. package/dist/workspace/upload.js +9 -3
  236. package/dist/workspace/upload.js.map +1 -1
  237. package/dist/workspace/worktrees.d.ts +2 -1
  238. package/dist/workspace/worktrees.js +14 -15
  239. package/dist/workspace/worktrees.js.map +1 -1
  240. package/package.json +4 -2
  241. package/sidecar/agent_dependency.json +4 -4
  242. package/sidecar/scripts/replay_sidecar.py +25 -1
  243. package/sidecar/talaria_sidecar/__init__.py +1 -1
  244. package/sidecar/talaria_sidecar/__main__.py +7 -1
  245. package/sidecar/talaria_sidecar/home.py +52 -2
  246. package/sidecar/talaria_sidecar/methods/__init__.py +2 -2
  247. package/sidecar/talaria_sidecar/methods/aux.py +39 -5
  248. package/sidecar/talaria_sidecar/methods/chat.py +431 -43
  249. package/sidecar/talaria_sidecar/methods/checkpoints.py +89 -0
  250. package/sidecar/talaria_sidecar/methods/commands.py +96 -2
  251. package/sidecar/talaria_sidecar/methods/cron.py +39 -8
  252. package/sidecar/talaria_sidecar/methods/gateway.py +32 -15
  253. package/sidecar/talaria_sidecar/methods/kanban.py +140 -19
  254. package/sidecar/talaria_sidecar/methods/mcp.py +1 -1
  255. package/sidecar/talaria_sidecar/methods/process.py +115 -2
  256. package/sidecar/talaria_sidecar/methods/profiles.py +84 -8
  257. package/sidecar/talaria_sidecar/methods/providers.py +27 -8
  258. package/sidecar/talaria_sidecar/methods/runtime.py +3 -0
  259. package/sidecar/talaria_sidecar/methods/state_db.py +39 -5
  260. package/sidecar/talaria_sidecar/methods/text.py +17 -1
  261. package/sidecar/talaria_sidecar/methods/usage.py +257 -4
  262. package/sidecar/talaria_sidecar/runtime.py +17 -1
  263. package/static/dist/FILES.txt +127 -125
  264. package/static/dist/assets/AppShell-g3bkgnvt.js +1 -0
  265. package/static/dist/assets/ChatPage-oo7bdan6.js +25 -0
  266. package/static/dist/assets/Dialog-g355qxhp.js +1 -0
  267. package/static/dist/assets/ExtensionRoute-i2y9fvjm.js +1 -0
  268. package/static/dist/assets/HubRoute-lmkrbw47.js +2 -0
  269. package/static/dist/assets/{Markdown-jqrx5es0.js → Markdown-j4kut4j2.js} +125 -125
  270. package/static/dist/assets/RightPanel-ohlsdzfl.js +1 -0
  271. package/static/dist/assets/Select-kddq75qc.js +1 -0
  272. package/static/dist/assets/SessionListPanel-lu3oy0hw.js +1 -0
  273. package/static/dist/assets/SettingsLayout-o9bv4mgb.js +1 -0
  274. package/static/dist/assets/States-eq6fe29m.js +1 -0
  275. package/static/dist/assets/Toaster-pc247u9f.js +1 -0
  276. package/static/dist/assets/_app-f8n1i0m1.js +1 -0
  277. package/static/dist/assets/_app.ext._extensionId-gfbzpoou.js +1 -0
  278. package/static/dist/assets/_app.index-bzzv80hk.js +1 -0
  279. package/static/dist/assets/_app.insights-dzixbryi.js +1 -0
  280. package/static/dist/assets/_app.kanban-c6hep2us.js +1 -0
  281. package/static/dist/assets/_app.logs-i69qds98.js +1 -0
  282. package/static/dist/assets/_app.memory-kl4vf0gd.js +1 -0
  283. package/static/dist/assets/_app.profiles-b8zinmyp.js +1 -0
  284. package/static/dist/assets/{_app.session._sessionId-hh27wwu2.js → _app.session._sessionId-fn1bhde6.js} +1 -1
  285. package/static/dist/assets/_app.settings-cg8plwmf.js +1 -0
  286. package/static/dist/assets/_app.settings._section-bkwbi9zn.js +3 -0
  287. package/static/dist/assets/_app.skills-cs47sbvs.js +1 -0
  288. package/static/dist/assets/_app.tasks-dwvk64tc.js +1 -0
  289. package/static/dist/assets/_app.todos-c8xjm8p3.js +1 -0
  290. package/static/dist/assets/_app.workspaces-ehvd1gds.js +1 -0
  291. package/static/dist/assets/{abnfDiagram-VCTEODGH-oity9y4o.js → abnfDiagram-VCTEODGH-c8kdixke.js} +1 -1
  292. package/static/dist/assets/architecture-7GRP2DOG-6crvnylg.js +1 -0
  293. package/static/dist/assets/{architectureDiagram-5GKGNRK7-ceaepnyr.js → architectureDiagram-5GKGNRK7-cku06x1p.js} +1 -1
  294. package/static/dist/assets/{back-eu64w89w.js → back-h7aun7ew.js} +1 -1
  295. package/static/dist/assets/{blockDiagram-I7D4REHJ-n79st4pj.js → blockDiagram-I7D4REHJ-jzthp1wa.js} +1 -1
  296. package/static/dist/assets/{c4Diagram-7LVT6UL2-mi73akzk.js → c4Diagram-7LVT6UL2-mwr67mt8.js} +1 -1
  297. package/static/dist/assets/{cancel-mzvkdjg8.js → cancel-fhi0vcnu.js} +1 -1
  298. package/static/dist/assets/channel-b2zo73z1.js +1 -0
  299. package/static/dist/assets/{chunk-4HAMMTFA-laat0g1q.js → chunk-4HAMMTFA-gpq1y228.js} +1 -1
  300. package/static/dist/assets/{chunk-75Z2AOVW-0psy1tr2.js → chunk-75Z2AOVW-ktje58c4.js} +1 -1
  301. package/static/dist/assets/{chunk-DU6HZSFF-lw8uox8x.js → chunk-DU6HZSFF-ofajdixh.js} +3 -3
  302. package/static/dist/assets/{chunk-F27PBJKO-erassib3.js → chunk-F27PBJKO-cmev85ti.js} +1 -1
  303. package/static/dist/assets/{chunk-GMAD6QVW-fz7rx619.js → chunk-GMAD6QVW-htjgt22y.js} +1 -1
  304. package/static/dist/assets/{chunk-GVQU2GXP-gdb0epb2.js → chunk-GVQU2GXP-qndvoxl7.js} +1 -1
  305. package/static/dist/assets/{chunk-IMKFNOWR-ea8t26qw.js → chunk-IMKFNOWR-e5bkd5q6.js} +1 -1
  306. package/static/dist/assets/{chunk-L3NEJ4N5-mb1gu9kz.js → chunk-L3NEJ4N5-mj1155r6.js} +1 -1
  307. package/static/dist/assets/{chunk-OSK3NFVY-eovmccvy.js → chunk-OSK3NFVY-e7gkikcw.js} +1 -1
  308. package/static/dist/assets/{chunk-P2QGCYS3-bo55zjo5.js → chunk-P2QGCYS3-f7t54xfm.js} +1 -1
  309. package/static/dist/assets/{chunk-POPQ4Y6H-ja7ohe4h.js → chunk-POPQ4Y6H-i927v9oa.js} +1 -1
  310. package/static/dist/assets/{chunk-PWAF6VOD-e30g9nus.js → chunk-PWAF6VOD-m84lmnyt.js} +1 -1
  311. package/static/dist/assets/{chunk-SHT3W25Y-gbb798f7.js → chunk-SHT3W25Y-mi0tlcu9.js} +1 -1
  312. package/static/dist/assets/{chunk-SVP7TREG-h2iw8urm.js → chunk-SVP7TREG-dnau702j.js} +1 -1
  313. package/static/dist/assets/{chunk-TICWLB2K-fd2cottz.js → chunk-TICWLB2K-edem1gkg.js} +1 -1
  314. package/static/dist/assets/classDiagram-ZZMXUADV-oe99st8x.js +1 -0
  315. package/static/dist/assets/classDiagram-v2-VYDZK3BY-oe99st8x.js +1 -0
  316. package/static/dist/assets/{copied-h65fc3cx.js → copied-hcplv46p.js} +1 -1
  317. package/static/dist/assets/copy-magtofyp.js +1 -0
  318. package/static/dist/assets/{cynefin-OW5HDTMX-lbltyl5j.js → cynefin-OW5HDTMX-siqlulkl.js} +1 -1
  319. package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-lxhsqq4a.js → cynefinDiagram-5FMLGOSQ-i648tah9.js} +1 -1
  320. package/static/dist/assets/{dagre-GXQ25YYZ-gn4nnaln.js → dagre-GXQ25YYZ-mwn6uc17.js} +1 -1
  321. package/static/dist/assets/{diagram-S7CK7UJ4-pa3ij6q7.js → diagram-S7CK7UJ4-l8abxaes.js} +1 -1
  322. package/static/dist/assets/{diagram-UQ7AKVKN-zbipyz57.js → diagram-UQ7AKVKN-mekq7zgq.js} +1 -1
  323. package/static/dist/assets/{diagram-VSXAHHWV-d1kbpzgf.js → diagram-VSXAHHWV-fnky6lvc.js} +1 -1
  324. package/static/dist/assets/{diagram-VX7I27RA-i3ty14xl.js → diagram-VX7I27RA-xe6r5qfw.js} +1 -1
  325. package/static/dist/assets/{diagram-Z3DM3KII-m8xefqa7.js → diagram-Z3DM3KII-nq07dg7k.js} +1 -1
  326. package/static/dist/assets/{ebnfDiagram-PWID7BFC-nz7wj05l.js → ebnfDiagram-PWID7BFC-c62ipm3g.js} +1 -1
  327. package/static/dist/assets/endpoints-klbxod4t.js +64 -0
  328. package/static/dist/assets/{erDiagram-RLTQ6QDP-fa41ib83.js → erDiagram-RLTQ6QDP-h39kmnzy.js} +1 -1
  329. package/static/dist/assets/eventmodeling-NTZA5JFV-obfede4u.js +1 -0
  330. package/static/dist/assets/flowDiagram-HODETNUW-kdpsp1je.js +1 -0
  331. package/static/dist/assets/{ganttDiagram-EL5Y4UJY-n7zq01qu.js → ganttDiagram-EL5Y4UJY-ngbsyp37.js} +1 -1
  332. package/static/dist/assets/{gitGraph-4MIJSDKK-c89emb07.js → gitGraph-4MIJSDKK-fr2i7caa.js} +1 -1
  333. package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-cz7cgr6w.js → gitGraphDiagram-WWUBYQGX-eravdti4.js} +1 -1
  334. package/static/dist/assets/{highlighted-body-KPVGNVTW-d9bapmni.js → highlighted-body-KPVGNVTW-jwpop9p8.js} +1 -1
  335. package/static/dist/assets/host-i828xuo7.js +1 -0
  336. package/static/dist/assets/index-eh8zilnv.css +2 -0
  337. package/static/dist/assets/index-r648f4o1.js +11 -0
  338. package/static/dist/assets/{info-A6RAGUB7-ndddhhhh.js → info-A6RAGUB7-h11x0dxo.js} +1 -1
  339. package/static/dist/assets/{infoDiagram-27XIBGKW-ccxigcpf.js → infoDiagram-27XIBGKW-dfh47dw9.js} +1 -1
  340. package/static/dist/assets/{ishikawaDiagram-5VMMS53U-le0z9vtc.js → ishikawaDiagram-5VMMS53U-i6ypq351.js} +1 -1
  341. package/static/dist/assets/{journeyDiagram-3NMN7TZE-ivsmb26o.js → journeyDiagram-3NMN7TZE-lduf1z95.js} +1 -1
  342. package/static/dist/assets/{kanban-definition-UXKFOSKX-h6n2awt0.js → kanban-definition-UXKFOSKX-e18bu4pg.js} +1 -1
  343. package/static/dist/assets/lazyRouteComponent-e1y4t2i9.js +1 -0
  344. package/static/dist/assets/{line-dmzlfe0u.js → line-meizqsvn.js} +1 -1
  345. package/static/dist/assets/link-oot2yn73.js +1 -0
  346. package/static/dist/assets/login-gu28l9ou.js +1 -0
  347. package/static/dist/assets/mermaid-HWGCJPDP-mtwrj8fn.js +1 -0
  348. package/static/dist/assets/{mermaid-parser.core-gwyd5bnq.js → mermaid-parser.core-ntne45i9.js} +3 -3
  349. package/static/dist/assets/{mindmap-definition-YA3MSWOX-l68gg5h7.js → mindmap-definition-YA3MSWOX-27b26eok.js} +1 -1
  350. package/static/dist/assets/onboarding-lkphzu1s.js +1 -0
  351. package/static/dist/assets/onboarding_model_label-ftpjdwqk.js +1 -0
  352. package/static/dist/assets/{packet-AYTQ26CC-gpv06065.js → packet-AYTQ26CC-l6jdka8p.js} +1 -1
  353. package/static/dist/assets/{pegDiagram-XKGWAZYB-e52vs23u.js → pegDiagram-XKGWAZYB-g1er3bxj.js} +1 -1
  354. package/static/dist/assets/{pie-WAS4IAKB-l6m7nz5s.js → pie-WAS4IAKB-i0ylcrt9.js} +1 -1
  355. package/static/dist/assets/{pieDiagram-E7YTZNPT-b4is36bq.js → pieDiagram-E7YTZNPT-fbz1e55z.js} +1 -1
  356. package/static/dist/assets/{quadrantDiagram-AXDQQJYC-m8vt2788.js → quadrantDiagram-AXDQQJYC-hhue7d8o.js} +1 -1
  357. package/static/dist/assets/{radar-RG4KPBEZ-nxbrhiov.js → radar-RG4KPBEZ-f9b70aa4.js} +1 -1
  358. package/static/dist/assets/{railroad-74A4TZTK-222mu9hi.js → railroad-74A4TZTK-lgsuoeda.js} +1 -1
  359. package/static/dist/assets/railroad-abnf-HS5TGJTU-nf9d6pdx.js +1 -0
  360. package/static/dist/assets/railroad-ebnf-LZEXJU2U-f7ummkt5.js +1 -0
  361. package/static/dist/assets/railroad-peg-WCYAUIDC-oczq5tqs.js +1 -0
  362. package/static/dist/assets/{railroadDiagram-O6MQD6OU-o8lldfzv.js → railroadDiagram-O6MQD6OU-eqpy9fnz.js} +1 -1
  363. package/static/dist/assets/refresh-abtu93ke.js +1 -0
  364. package/static/dist/assets/refresh-cw-hlwb02qv.js +1 -0
  365. package/static/dist/assets/{requirementDiagram-BXWQKSXE-ovyq38kv.js → requirementDiagram-BXWQKSXE-ogf6puhi.js} +1 -1
  366. package/static/dist/assets/{sankeyDiagram-P5KCCOFB-ou7lznor.js → sankeyDiagram-P5KCCOFB-fqb8xcjf.js} +1 -1
  367. package/static/dist/assets/{saved-bazmcup9.js → saved-girnabkf.js} +1 -1
  368. package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-ovckdzf2.js → sequenceDiagram-WJ2MYXX4-dlcz6qjz.js} +1 -1
  369. package/static/dist/assets/{settings_section_extensions_title-ertwwhlx.js → settings_section_extensions_title-h14cwk6f.js} +1 -1
  370. package/static/dist/assets/share._token-kl0r7ido.js +2 -0
  371. package/static/dist/assets/sliders-horizontal-n1zm34qq.js +1 -0
  372. package/static/dist/assets/sse-iwku0sjo.js +1 -0
  373. package/static/dist/assets/{stateDiagram-D77RDMKH-fcrexkkv.js → stateDiagram-D77RDMKH-fyoznpcs.js} +1 -1
  374. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-ixhx8r46.js +1 -0
  375. package/static/dist/assets/{swimlanes-42K2YHIH-f7usu8fw.js → swimlanes-42K2YHIH-oefldhfy.js} +1 -1
  376. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-h9ersk2e.js +8 -0
  377. package/static/dist/assets/{timeline-definition-24CTP7MA-gp1hvz9f.js → timeline-definition-24CTP7MA-b1vl2zil.js} +1 -1
  378. package/static/dist/assets/todoStore-jjr5yr78.js +1 -0
  379. package/static/dist/assets/{treeView-Q6P3EWNA-gb9gf11u.js → treeView-Q6P3EWNA-f7hcci5o.js} +1 -1
  380. package/static/dist/assets/{treemap-WGGIJYW6-nuvfnvvi.js → treemap-WGGIJYW6-nl85071a.js} +1 -1
  381. package/static/dist/assets/units-kgxzxfhi.js +1 -0
  382. package/static/dist/assets/{untitled-htelhc68.js → untitled-cikfjntn.js} +1 -1
  383. package/static/dist/assets/{useForm-h2t0u14e.js → useForm-kqoqg0k9.js} +1 -1
  384. package/static/dist/assets/useLocale-o59tbiea.js +1 -0
  385. package/static/dist/assets/{useParams-dqd64jv7.js → useParams-b4dq6n4q.js} +1 -1
  386. package/static/dist/assets/{useSearch-j30pvsy7.js → useSearch-ipfmv3he.js} +1 -1
  387. package/static/dist/assets/{vennDiagram-4TSXK5OY-fzchbzaj.js → vennDiagram-4TSXK5OY-h5hzbk0n.js} +1 -1
  388. package/static/dist/assets/{wardley-WFR3VGLG-m47mhfbh.js → wardley-WFR3VGLG-jftvpm3e.js} +1 -1
  389. package/static/dist/assets/{wardleyDiagram-VM6X3IG4-odg6ct1z.js → wardleyDiagram-VM6X3IG4-hedh85ge.js} +1 -1
  390. package/static/dist/assets/{xychartDiagram-S5SC5T6Z-mrhms5um.js → xychartDiagram-S5SC5T6Z-e49523ab.js} +1 -1
  391. package/static/dist/index.html +1 -1
  392. package/static/dist/sw.js +2 -2
  393. package/static/dist/assets/AppShell-ef3bhu32.js +0 -1
  394. package/static/dist/assets/Button-nx37f4u1.js +0 -1
  395. package/static/dist/assets/ChatPage-cdcpykcg.js +0 -25
  396. package/static/dist/assets/Dialog-mec42hvb.js +0 -1
  397. package/static/dist/assets/HubRoute-ecb65zpr.js +0 -2
  398. package/static/dist/assets/RightPanel-d1lgvk4s.js +0 -1
  399. package/static/dist/assets/Select-h4ivl9qf.js +0 -1
  400. package/static/dist/assets/SessionListPanel-ewib046b.js +0 -1
  401. package/static/dist/assets/SettingsLayout-lx654cup.js +0 -1
  402. package/static/dist/assets/States-ehsb6lzo.js +0 -1
  403. package/static/dist/assets/Toaster-mch1pa3t.js +0 -1
  404. package/static/dist/assets/_app-m8d961ef.js +0 -1
  405. package/static/dist/assets/_app.ext._extensionId-mp33hbzi.js +0 -1
  406. package/static/dist/assets/_app.index-dk6zp7e0.js +0 -1
  407. package/static/dist/assets/_app.insights-jt2fk4i1.js +0 -1
  408. package/static/dist/assets/_app.kanban-if4pubeu.js +0 -1
  409. package/static/dist/assets/_app.logs-mfaw9m6g.js +0 -1
  410. package/static/dist/assets/_app.memory-h3eaarb6.js +0 -1
  411. package/static/dist/assets/_app.profiles-ienktovs.js +0 -1
  412. package/static/dist/assets/_app.settings-dpoe0bzf.js +0 -1
  413. package/static/dist/assets/_app.settings._section-l468ynag.js +0 -3
  414. package/static/dist/assets/_app.skills-kcbncc8i.js +0 -1
  415. package/static/dist/assets/_app.tasks-occdrqhw.js +0 -2
  416. package/static/dist/assets/_app.todos-nnke2rcc.js +0 -1
  417. package/static/dist/assets/_app.workspaces-cdlatvwj.js +0 -1
  418. package/static/dist/assets/architecture-7GRP2DOG-hj11333z.js +0 -1
  419. package/static/dist/assets/channel-mbvmf2vv.js +0 -1
  420. package/static/dist/assets/classDiagram-ZZMXUADV-o8r05k0n.js +0 -1
  421. package/static/dist/assets/classDiagram-v2-VYDZK3BY-o8r05k0n.js +0 -1
  422. package/static/dist/assets/copy-e6977uwq.js +0 -1
  423. package/static/dist/assets/endpoints-k7yf25m0.js +0 -64
  424. package/static/dist/assets/eventmodeling-NTZA5JFV-kpbq09bx.js +0 -1
  425. package/static/dist/assets/flowDiagram-HODETNUW-lcz0kx14.js +0 -1
  426. package/static/dist/assets/index-h00usru2.js +0 -11
  427. package/static/dist/assets/index-n73ijkv2.css +0 -2
  428. package/static/dist/assets/lazyRouteComponent-m1rtyk4t.js +0 -1
  429. package/static/dist/assets/link-budeg5t9.js +0 -1
  430. package/static/dist/assets/login-kjhasvp8.js +0 -1
  431. package/static/dist/assets/matchContext-f8oy3lo7.js +0 -1
  432. package/static/dist/assets/mermaid-HWGCJPDP-jb5d211j.js +0 -1
  433. package/static/dist/assets/onboarding-cdfrk0pj.js +0 -1
  434. package/static/dist/assets/railroad-abnf-HS5TGJTU-kdvgl6x8.js +0 -1
  435. package/static/dist/assets/railroad-ebnf-LZEXJU2U-itiqslby.js +0 -1
  436. package/static/dist/assets/railroad-peg-WCYAUIDC-go7kov78.js +0 -1
  437. package/static/dist/assets/refresh-cw-kbcje1uy.js +0 -1
  438. package/static/dist/assets/search-jen74z4u.js +0 -1
  439. package/static/dist/assets/share._token-dan9hgvj.js +0 -2
  440. package/static/dist/assets/sliders-horizontal-f9cb3lh3.js +0 -1
  441. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-lcfraua2.js +0 -1
  442. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-ogmanni0.js +0 -8
  443. package/static/dist/assets/todoStore-eqtid4r4.js +0 -1
  444. package/static/dist/assets/useLocale-hcsb84pj.js +0 -1
  445. package/static/dist/assets/useNavigate-nwy70ztj.js +0 -1
@@ -3,11 +3,12 @@
3
3
  * `_merge_display_messages_after_agent_result`, `_message_identity`,
4
4
  * `_extract_tool_calls_from_messages`, `_build_partial_message`).
5
5
  */
6
- import { buildActiveTurnToken } from '../redact.js';
6
+ import { buildActiveTurnToken, completedToolIndex } from '../redact.js';
7
+ import { RunJournal } from './journal.js';
7
8
  import { str } from '../util.js';
8
- import { stripAttachedFilesMarker } from './session.js';
9
- export const WORKSPACE_PREFIX_RE = /^\s*\[Workspace::v1:\s*(?:\\.|[^\]\\])+\]\s*/;
10
- const LEGACY_WORKSPACE_PREFIX_RE = /^\s*\[Workspace:[^\]]+\]\s*/;
9
+ import { stripAttachedFilesMarker, stripWorkspacePrefix } from './session.js';
10
+ export { WORKSPACE_PREFIX_RE, stripWorkspacePrefix } from './session.js';
11
+ import { decidedEditDiff, toolEditDiff, toolName } from './tool-display.js';
11
12
  const TOOL_RESULT_SNIPPET_MAX = 4000;
12
13
  // Python `_TOOL_ARG_CONTENT_KEYS`: file bodies, commands, and patch text keep up to the content cap; incidental args cut at 120.
13
14
  export const TOOL_ARG_CONTENT_KEYS = new Set(['command', 'cmd', 'script', 'code', 'patch', 'diff', 'old_string', 'new_string', 'content', 'path', 'file_path']);
@@ -16,16 +17,6 @@ export const isDict = (v) => Boolean(v) && typeof v === 'object' && !Array.isArr
16
17
  export function escapeWorkspacePrefixPath(path) {
17
18
  return path.replace(/\\/g, '\\\\').replace(/]/g, '\\]');
18
19
  }
19
- export function workspaceContextPrefix(path) {
20
- return `[Workspace::v1: ${escapeWorkspacePrefixPath(path)}]\n`;
21
- }
22
- export function stripWorkspacePrefix(text, includeLegacy = false) {
23
- const value = str(text);
24
- let stripped = value.replace(WORKSPACE_PREFIX_RE, '');
25
- if (includeLegacy && stripped === value)
26
- stripped = value.replace(LEGACY_WORKSPACE_PREFIX_RE, '');
27
- return stripped.trim();
28
- }
29
20
  /** Python `_message_text`: flatten string or multimodal content to text. */
30
21
  export function isReasoningBlock(part) {
31
22
  return part.type === 'reasoning' || part.type === 'thinking';
@@ -55,7 +46,7 @@ export function messageText(content) {
55
46
  }
56
47
  return str(content);
57
48
  }
58
- export function messageIdentity(msg) {
49
+ export function messageIdentity(msg, textLimit = 500) {
59
50
  if (!isDict(msg))
60
51
  return null;
61
52
  const role = str(msg.role);
@@ -75,7 +66,7 @@ export function messageIdentity(msg) {
75
66
  return null;
76
67
  }
77
68
  const toolCalls = Array.isArray(msg.tool_calls) ? msg.tool_calls : [];
78
- return JSON.stringify([role, text.split(/\s+/).join(' ').trim().slice(0, 500), str(msg.tool_call_id), JSON.stringify(sortKeysDeep(toolCalls))]);
69
+ return JSON.stringify([role, text.split(/\s+/).join(' ').trim().slice(0, textLimit), str(msg.tool_call_id), JSON.stringify(sortKeysDeep(toolCalls))]);
79
70
  }
80
71
  function sortKeysDeep(value) {
81
72
  if (Array.isArray(value))
@@ -226,6 +217,17 @@ export function injectMaxIterationSummaryFallback(messages, finalResponse) {
226
217
  return messages;
227
218
  return [...messages, { role: 'assistant', content: finalResponse, _max_iteration_summary_fallback: true }];
228
219
  }
220
+ /**
221
+ * TAL-537: the user row the Agent appends to ask for that summary is its own prompt, neither shown nor sent back. It is
222
+ * the exhausted turn's last user row; any other row with the same text (one the user typed) stays.
223
+ */
224
+ export function withoutMaxIterationSummaryRequest(messages, request, msgText) {
225
+ const at = messages.findLastIndex((m) => m.role === 'user');
226
+ const row = messages[at];
227
+ if (!request || row?.content !== request || looksLikeCurrentUserTurn(row, msgText))
228
+ return messages;
229
+ return messages.filter((_, i) => i !== at);
230
+ }
229
231
  export function mergeDisplayMessagesAfterAgentResult(previousDisplay, previousContext, resultMessages, msgText, opts = {}) {
230
232
  const display = previousDisplay.filter((m) => !isContextCompressionMarker(m));
231
233
  const seenPartial = new Set();
@@ -670,26 +672,70 @@ export function withToolCallOutcomes(messages, sessionToolCalls, activeTurnId) {
670
672
  if (!calls.length && !records.length)
671
673
  return m;
672
674
  const running = Boolean(activeTurnId) && m._turn_id === activeTurnId;
673
- const resolve = (id, rec, answered) => {
675
+ const resolve = (id, name, rec, answered) => {
674
676
  const reply = id ? replies.get(key(index, id)) : undefined;
675
677
  const outcome = reply ? { ...toolOutcome(reply.content), flagged: reply.is_error } : null;
678
+ // TAL-448: a file edit's change, from its full reply, else the one its live record decided.
679
+ const editDiff = reply ? toolEditDiff(name, reply.content) : decidedEditDiff(rec?.edit_diff);
676
680
  return {
681
+ ...(editDiff ? { edit_diff: editDiff } : {}),
677
682
  done: Boolean(reply) || answered || !running, is_error: outcome ? outcome.flagged || outcome.is_error : rec?.is_error === true,
678
683
  duration: finiteOrNull(rec?.duration), result: outcome ? outcome.result_text : typeof rec?.snippet === 'string' ? rec.snippet : null,
679
684
  result_view: outcome ? outcome.result_view : isDict(rec?.result_view) ? decidedResultView(rec.result_view) : typeof rec?.snippet === 'string' ? toolResultView(rec.snippet) : null,
680
685
  };
681
686
  };
682
687
  const projected = [
683
- ...calls.map((call) => (isDict(call) ? { ...call, ...resolve(callId(call), recorded.get(callId(call)), false) } : call)),
688
+ ...calls.map((call) => (isDict(call) ? { ...call, ...resolve(callId(call), toolName(call), recorded.get(callId(call)), false) } : call)),
684
689
  ...records.map((tc) => ({
685
690
  ...(str(tc.tid) ? { id: str(tc.tid) } : {}), type: 'function', function: { name: str(tc.name), arguments: JSON.stringify(tc.args ?? {}) },
686
691
  // A session-level entry was answered; a live call says whether it completed.
687
- ...resolve(str(tc.tid), tc, typeof tc.done === 'boolean' ? tc.done : true),
692
+ ...resolve(str(tc.tid), tc.name, tc, typeof tc.done === 'boolean' ? tc.done : true),
688
693
  })),
689
694
  ];
690
695
  return { ...m, tool_calls: projected };
691
696
  });
692
697
  }
698
+ /** The prompt text naming every attached file by path after it (TAL-276), so an attachment-only turn still asks something. */
699
+ export function attachedFilesPrompt(text, attachments) {
700
+ const named = attachments.map((att) => (isDict(att) ? str(att.path).trim() : '')).filter(Boolean).map(escapeWorkspacePrefixPath);
701
+ return named.length ? `${text}\n\n[Attached files: ${named.join(', ')}]` : text;
702
+ }
703
+ const TOOL_IMAGE_PART_TYPES = new Set(['image', 'image_url', 'input_image']);
704
+ /**
705
+ * TAL-544, Python `_compact_image_parts_for_persistence`: a settled turn's tool-result images (browser and vision
706
+ * screenshots) become `[screenshot]` text, so saves, loads and later turns stop carrying the base64. A result is a `tool`
707
+ * row or an Anthropic-style `tool_result` block in a user row; the user's own attachments stay.
708
+ */
709
+ export function withoutToolImages(messages) {
710
+ const isImage = (p) => isDict(p) && TOOL_IMAGE_PART_TYPES.has(p.type);
711
+ const hasImage = (parts) => Array.isArray(parts) && parts.some(isImage);
712
+ const compact = (parts) => parts.map((p) => (isImage(p) ? { type: 'text', text: '[screenshot]' } : p));
713
+ const isImageResult = (p) => isDict(p) && p.type === 'tool_result' && hasImage(p.content);
714
+ const out = messages.map((m) => {
715
+ const content = m.content;
716
+ if (m.role === 'tool' && hasImage(content))
717
+ return { ...m, content: compact(content) };
718
+ if (m.role === 'user' && Array.isArray(content) && content.some(isImageResult)) {
719
+ return { ...m, content: content.map((p) => (isImageResult(p) ? { ...p, content: compact(p.content) } : p)) };
720
+ }
721
+ return m;
722
+ });
723
+ // The same array when nothing changed, so a caller can tell whether its rows were rewritten.
724
+ return out.some((m, i) => m !== messages[i]) ? out : messages;
725
+ }
726
+ /** A settled model context without an assistant row repeated back to back, and without tool-result images. */
727
+ export function dedupeContext(messages) {
728
+ const out = [];
729
+ let lastKey = null;
730
+ for (const m of withoutToolImages(messages)) {
731
+ const key = messageIdentity(m);
732
+ if (key !== null && key === lastKey && m.role === 'assistant')
733
+ continue;
734
+ out.push(m);
735
+ lastKey = key;
736
+ }
737
+ return out;
738
+ }
693
739
  /** Python `_build_partial_message`. */
694
740
  export function buildPartialMessage(contentText, reasoningText, toolCalls, now = Date.now() / 1000) {
695
741
  let stripped = '';
@@ -709,6 +755,69 @@ export function buildPartialMessage(contentText, reasoningText, toolCalls, now =
709
755
  msg._partial_tool_calls = [...toolCalls];
710
756
  return msg;
711
757
  }
758
+ /**
759
+ * TAL-536: a dead run's journaled output as partial rows, in order: each row is a stretch of reasoning and prose with the
760
+ * tool calls that followed it, the shape a Stop's snapshot keeps. A run that ended in `done` gets its answer as a settled
761
+ * row: its last prose row, else the one the `done` frame's session carries (an answer that never streamed, like the
762
+ * tool-limit summary). `answered` says the run finished with one.
763
+ */
764
+ export function journalOutputRows(events, turnId) {
765
+ const rows = [];
766
+ const calls = [];
767
+ let text = '';
768
+ let reasoning = '';
769
+ let tools = [];
770
+ let at = 0;
771
+ const flush = () => {
772
+ const row = buildPartialMessage(text, reasoning, tools, at);
773
+ if (row)
774
+ rows.push({ ...row, _turn_id: turnId });
775
+ text = '';
776
+ reasoning = '';
777
+ tools = [];
778
+ };
779
+ for (const e of events) {
780
+ const p = isDict(e.payload) ? e.payload : {};
781
+ if ((e.event === 'token' || e.event === 'reasoning') && tools.length)
782
+ flush();
783
+ if (e.event === 'token')
784
+ text += str(p.text);
785
+ else if (e.event === 'reasoning')
786
+ reasoning += str(p.text);
787
+ else if (e.event === 'tool') {
788
+ const call = { name: p.name, args: p.args ?? {}, tid: str(p.id), done: false };
789
+ calls.push(call);
790
+ tools.push(call);
791
+ }
792
+ else if (e.event === 'tool_complete') {
793
+ // The record is shared with the row that holds it, so a completion after its row closed still lands.
794
+ const call = calls[completedToolIndex(calls, str(p.id), p.name)];
795
+ if (call)
796
+ Object.assign(call, { done: true, snippet: p.preview, is_error: p.is_error === true, duration: p.duration ?? null, ...(isDict(p.result_view) ? { result_view: p.result_view } : {}), ...(isDict(p.edit_diff) ? { edit_diff: p.edit_diff } : {}) });
797
+ }
798
+ else
799
+ continue;
800
+ at = e.created_at || at;
801
+ }
802
+ flush();
803
+ const done = RunJournal.selectAuthoritativeTerminalEvent(events);
804
+ if (done?.event !== 'done')
805
+ return { rows, answered: false };
806
+ // The last row answers only with visible prose and no calls after it (a reasoning-only segment is no answer).
807
+ const last = rows[rows.length - 1];
808
+ if (last && !last._partial_tool_calls && str(last.content)) {
809
+ delete last._partial;
810
+ return { rows, answered: true };
811
+ }
812
+ const settled = isDict(done.payload) && isDict(done.payload.session) && Array.isArray(done.payload.session.messages) ? done.payload.session.messages : [];
813
+ const answer = settled.findLast((m) => isDict(m) && m.role === 'assistant' && m._turn_id === turnId);
814
+ // Its visible prose, from string or structured content, as the scene's final answer reads it.
815
+ const content = answer && !answer._error && !(Array.isArray(answer.tool_calls) && answer.tool_calls.length) ? splitDisplayText(messageText(answer.content))[0] : '';
816
+ if (!content)
817
+ return { rows, answered: false };
818
+ rows.push({ role: 'assistant', content, timestamp: Math.trunc(done.created_at), _turn_id: turnId });
819
+ return { rows, answered: true };
820
+ }
712
821
  const DSML = '(?:\\s*|\\s*DSML\\s*[||]\\s*)?';
713
822
  /** Markdown code (fenced blocks, an unclosed one running to the end, and inline spans): markup written there is literal. */
714
823
  function codeRanges(text) {
@@ -833,6 +942,9 @@ export function normalizeAssistantDisplay(message) {
833
942
  * replay): rows at or before it, and, for a truncation cut, rows after it until the sidecar advances past it (TAL-504).
834
943
  * A compression watermark only covers the compressed rows. Rows past the sidecar tail (a conversation continued from the
835
944
  * CLI) are appended in state.db order.
945
+ * TAL-493: once a boundary or settled turn recorded the highest state.db id it read (`stateDbSeenId`) and the rows carry
946
+ * ids, identity replaces the timestamp rules: rows up to that id are covered, and every newer row not already in the
947
+ * sidecar is appended, even one a writer stamped before the newest local row or the watermark but committed later.
836
948
  * ponytail: the Python identity memo (api_content sidecars, message ids, workspace-prefix normalisation) is not ported;
837
949
  * add it if a mixed WebUI/CLI transcript shows duplicated turns.
838
950
  */
@@ -843,6 +955,31 @@ export function mergeSessionMessagesAppendOnly(sidecar, state, opts = {}) {
843
955
  return sidecar;
844
956
  const ts = (m) => { const n = Number(m.timestamp); return Number.isFinite(n) ? n : null; };
845
957
  const key = (m) => `${String(m.role)}\0${String(ts(m) ?? '')}\0${typeof m.content === 'string' ? m.content : JSON.stringify(m.content ?? null)}`;
958
+ const seenId = opts.stateDbSeenId;
959
+ if (typeof seenId === 'number' && Number.isFinite(seenId) && state.some((m) => stateDbRowId(m) !== null)) {
960
+ // Each local row stands for at most one new state.db row: a persisted copy by its id, any other by its key.
961
+ const localIds = new Set(sidecar.map(stateDbRowId));
962
+ const localKeys = new Map();
963
+ for (const m of sidecar)
964
+ if (stateDbRowId(m) === null)
965
+ localKeys.set(key(m), (localKeys.get(key(m)) ?? 0) + 1);
966
+ const merged = [...sidecar];
967
+ for (const m of state) {
968
+ const id = stateDbRowId(m);
969
+ if (id !== null && localIds.has(id))
970
+ continue;
971
+ // In state.db order, so a covered row matches its own local copy before a newer duplicate can.
972
+ const left = localKeys.get(key(m)) ?? 0;
973
+ if (left > 0) {
974
+ localKeys.set(key(m), left - 1);
975
+ continue;
976
+ }
977
+ if (id === null || id <= seenId)
978
+ continue;
979
+ merged.push(m);
980
+ }
981
+ return merged;
982
+ }
846
983
  if (!sidecar.length) {
847
984
  if (!hasWatermark) {
848
985
  const seen = new Set();
@@ -877,6 +1014,21 @@ export function mergeSessionMessagesAppendOnly(sidecar, state, opts = {}) {
877
1014
  }
878
1015
  return merged;
879
1016
  }
1017
+ /** The state.db row id a row was read with (a compaction copy reads as the row it copies; TAL-709), or null for a database without the column. */
1018
+ function stateDbRowId(m) {
1019
+ const id = m._state_db_row_id;
1020
+ return typeof id === 'number' && Number.isFinite(id) ? id : null;
1021
+ }
1022
+ /** TAL-493: the `state_db_seen_id` after reading `rows`: their highest id, or null when they carry none. */
1023
+ export function stateDbSeenId(rows) {
1024
+ let max = null;
1025
+ for (const m of rows) {
1026
+ const id = stateDbRowId(m);
1027
+ if (id !== null && (max === null || id > max))
1028
+ max = id;
1029
+ }
1030
+ return max;
1031
+ }
880
1032
  /**
881
1033
  * TAL-316: the merged transcript without the running turn's output, which the run journal replays from its start. The turn
882
1034
  * begins at its checkpointed prompt, else at its first stamped row or the first state.db row appended past the sidecar
@@ -1066,7 +1218,8 @@ export function stoppedTurnContext(previousContext, checkpoint, prompt, msgText,
1066
1218
  // A tool result is a `tool` row or an Anthropic-style user row of `tool_result` blocks. A steer the Agent applied is
1067
1219
  // neither a prompt nor a result: the boundary goes after it, and it never makes the turn look unanswered.
1068
1220
  const toolResult = (m) => m?.role === 'tool' || (m?.role === 'user' && Array.isArray(m.content) && m.content.some((part) => isDict(part) && part.type === 'tool_result'));
1069
- const tail = () => sanitizeMessagesForApi(rows.filter((m) => agentSteerText(m) === null)).at(-1);
1221
+ // The next turn's own history projection, so an answer the Agent replays from `api_content` counts.
1222
+ const tail = () => sanitizeMessagesForApi(rows.filter((m) => agentSteerText(m) === null), { preserveApiContent: true }).at(-1);
1070
1223
  if (toolResult(tail()))
1071
1224
  rows.push({ role: 'assistant', content: unsettled || 'Operation interrupted.' });
1072
1225
  else if (unsettled)
@@ -1091,6 +1244,10 @@ export function agentSteerText(m) {
1091
1244
  return inner.trim();
1092
1245
  return m.display_kind === 'steer' ? content.trim() : null;
1093
1246
  }
1247
+ /** The Agent's `api_content` replay sidecar: the exact bytes a user/assistant row was sent as, else undefined. */
1248
+ function apiContent(msg) {
1249
+ return (msg.role === 'user' || msg.role === 'assistant') && typeof msg.api_content === 'string' && msg.api_content ? msg.api_content : undefined;
1250
+ }
1094
1251
  /** Python `_is_reasoning_only_assistant_message`: a display-only Thinking card with no visible reply. */
1095
1252
  function isReasoningOnlyAssistant(msg) {
1096
1253
  if (msg.role !== 'assistant' || (Array.isArray(msg.tool_calls) && msg.tool_calls.length))
@@ -1115,8 +1272,10 @@ function stripOobBlocks(content) {
1115
1272
  * reasoning-only assistants), orphaned tool rows and unanswered tool calls, keeps only API-safe keys, strips consumed
1116
1273
  * out-of-band blocks, and keeps a cancelled (`_recovered`) user prompt only where it separates two assistant turns —
1117
1274
  * otherwise the neighbours fuse cleanly or the prompt is stale, and replaying it would answer it again.
1275
+ * `preserveApiContent` (Python `_sanitize_messages_for_agent`) keeps the Agent's `api_content` replay sidecar on
1276
+ * user/assistant rows and every row's `timestamp` for turn history; compression and other projections strip both.
1118
1277
  */
1119
- export function sanitizeMessagesForApi(messages) {
1278
+ export function sanitizeMessagesForApi(messages, { preserveApiContent = false } = {}) {
1120
1279
  // Calls are OpenAI `tool_calls` or Anthropic-style `tool_use` content blocks; results name them by `tool_call_id`,
1121
1280
  // `tool_use_id`, or a user row's `tool_result` blocks.
1122
1281
  const toolUseIds = (msg) => (Array.isArray(msg.content) ? msg.content.flatMap((part) => (isDict(part) && part.type === 'tool_use' && str(part.id) ? [str(part.id)] : [])) : []);
@@ -1136,7 +1295,9 @@ export function sanitizeMessagesForApi(messages) {
1136
1295
  for (const msg of messages) {
1137
1296
  if (!msg || typeof msg !== 'object')
1138
1297
  continue;
1139
- if (isReasoningOnlyAssistant(msg))
1298
+ // A reasoning-only clean stop the Agent answered from `api_content` is a reply, not a Thinking card.
1299
+ const replay = preserveApiContent ? apiContent(msg) : undefined;
1300
+ if (isReasoningOnlyAssistant(msg) && !replay)
1140
1301
  continue;
1141
1302
  // The Agent already received a steer mid-turn; its persisted row is display-only.
1142
1303
  if (msg._error || isDict(msg._steer))
@@ -1152,6 +1313,12 @@ export function sanitizeMessagesForApi(messages) {
1152
1313
  const sanitized = Object.fromEntries(Object.entries(msg).filter(([k]) => API_SAFE_MSG_KEYS.has(k)));
1153
1314
  if (Array.isArray(sanitized.tool_calls) && !sanitized.tool_calls.length)
1154
1315
  Reflect.deleteProperty(sanitized, 'tool_calls');
1316
+ if (replay)
1317
+ sanitized.api_content = replay;
1318
+ // TAL-681: the Agent re-inserts turn history when it prunes and keys display dedupe on the row timestamp, so turn
1319
+ // history keeps it (persistence-only: the Agent strips it before the provider call).
1320
+ if (preserveApiContent && msg.timestamp != null)
1321
+ sanitized.timestamp = msg.timestamp;
1155
1322
  if (recovered)
1156
1323
  sanitized._recovered = true;
1157
1324
  if ('content' in sanitized)
@@ -1174,7 +1341,7 @@ export function sanitizeMessagesForApi(messages) {
1174
1341
  continue;
1175
1342
  msg = { ...msg, content: parts };
1176
1343
  // Reasoning left behind by a dropped call is not an answer either.
1177
- if (isReasoningOnlyAssistant(msg))
1344
+ if (isReasoningOnlyAssistant(msg) && !apiContent(msg))
1178
1345
  continue;
1179
1346
  }
1180
1347
  if (msg.role === 'assistant' && Array.isArray(msg.tool_calls) && msg.tool_calls.length) {
@@ -1203,4 +1370,33 @@ export function sanitizeMessagesForApi(messages) {
1203
1370
  }
1204
1371
  return final;
1205
1372
  }
1373
+ const isNativeImagePart = (part) => isDict(part) && (part.type === 'image_url' || 'image_url' in part);
1374
+ /** True when any row's content carries a native `image_url` part. */
1375
+ export function hasNativeImages(messages) {
1376
+ return messages.some((msg) => Array.isArray(msg.content) && msg.content.some(isNativeImagePart));
1377
+ }
1378
+ /**
1379
+ * Python `_strip_native_image_parts_from_content` (TAL-545): the history for a turn whose image mode resolved to text.
1380
+ * Native `image_url` parts are dropped and the text kept; a lone text part collapses to its string, as a text-only
1381
+ * provider rejects a replayed image before the Agent's own strip-and-retry guard can recover.
1382
+ */
1383
+ export function withoutNativeImages(messages) {
1384
+ return messages.map((msg) => {
1385
+ if (!Array.isArray(msg.content) || !msg.content.some(isNativeImagePart))
1386
+ return msg;
1387
+ const parts = msg.content.filter((part) => isDict(part) && !isNativeImagePart(part));
1388
+ const content = !parts.length ? '' : parts.length === 1 && parts[0].type === 'text' ? str(parts[0].text) : parts;
1389
+ return { ...msg, content };
1390
+ });
1391
+ }
1392
+ /**
1393
+ * TAL-545: the image-free history is one request's projection, never the session's. The Agent hands the history it got
1394
+ * back ahead of its own rows, so each row it returned exactly as sent (`sent[i]`, stripped from `original[i]`) is swapped
1395
+ * back for the original; a row the Agent rewrote stays its own.
1396
+ */
1397
+ export function withNativeImagesRestored(rows, sent, original) {
1398
+ if (sent === original)
1399
+ return rows;
1400
+ return rows.map((row, i) => (i < sent.length && sent[i] !== original[i] && JSON.stringify(row) === JSON.stringify(sent[i]) ? original[i] : row));
1401
+ }
1206
1402
  //# sourceMappingURL=merge.js.map