@maudecode/talaria-web 1.16.1 → 1.17.2

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 (328) hide show
  1. package/_release.json +4 -4
  2. package/dist/api/automation-raw.js +6 -3
  3. package/dist/api/automation-raw.js.map +1 -1
  4. package/dist/api/automation-router.d.ts +137 -9
  5. package/dist/api/automation-router.js +9 -6
  6. package/dist/api/automation-router.js.map +1 -1
  7. package/dist/api/chat-router.d.ts +51 -0
  8. package/dist/api/chat-router.js +29 -12
  9. package/dist/api/chat-router.js.map +1 -1
  10. package/dist/api/git-router.d.ts +12 -1
  11. package/dist/api/git-router.js +17 -7
  12. package/dist/api/git-router.js.map +1 -1
  13. package/dist/api/raw-routes.d.ts +6 -0
  14. package/dist/api/raw-routes.js +30 -0
  15. package/dist/api/raw-routes.js.map +1 -1
  16. package/dist/api/sessions-router.d.ts +260 -0
  17. package/dist/api/sessions-router.js +30 -2
  18. package/dist/api/sessions-router.js.map +1 -1
  19. package/dist/api/settings-router.d.ts +101 -2
  20. package/dist/api/settings-router.js +7 -2
  21. package/dist/api/settings-router.js.map +1 -1
  22. package/dist/api/sse-routes.d.ts +11 -3
  23. package/dist/api/sse-routes.js +144 -64
  24. package/dist/api/sse-routes.js.map +1 -1
  25. package/dist/api/tools-raw.js +6 -2
  26. package/dist/api/tools-raw.js.map +1 -1
  27. package/dist/api/tools-router.d.ts +73 -8
  28. package/dist/api/tools-router.js +9 -7
  29. package/dist/api/tools-router.js.map +1 -1
  30. package/dist/app.d.ts +0 -9377
  31. package/dist/app.js +7 -2
  32. package/dist/app.js.map +1 -1
  33. package/dist/auth/gate.js +3 -0
  34. package/dist/auth/gate.js.map +1 -1
  35. package/dist/config/agent-config.d.ts +2 -0
  36. package/dist/config/agent-config.js +9 -0
  37. package/dist/config/agent-config.js.map +1 -1
  38. package/dist/http/context.d.ts +3 -0
  39. package/dist/http/context.js +10 -4
  40. package/dist/http/context.js.map +1 -1
  41. package/dist/onboarding.js +4 -0
  42. package/dist/onboarding.js.map +1 -1
  43. package/dist/providers/catalog.d.ts +96 -7
  44. package/dist/providers/catalog.js +434 -113
  45. package/dist/providers/catalog.js.map +1 -1
  46. package/dist/redact.d.ts +1 -0
  47. package/dist/redact.js +27 -4
  48. package/dist/redact.js.map +1 -1
  49. package/dist/runtime.js +27 -9
  50. package/dist/runtime.js.map +1 -1
  51. package/dist/sessions/anchor.d.ts +2 -0
  52. package/dist/sessions/anchor.js +8 -3
  53. package/dist/sessions/anchor.js.map +1 -1
  54. package/dist/sessions/claude-code.d.ts +19 -0
  55. package/dist/sessions/claude-code.js +250 -0
  56. package/dist/sessions/claude-code.js.map +1 -0
  57. package/dist/sessions/completions.d.ts +13 -1
  58. package/dist/sessions/completions.js +63 -11
  59. package/dist/sessions/completions.js.map +1 -1
  60. package/dist/sessions/compress.d.ts +14 -1
  61. package/dist/sessions/compress.js +52 -11
  62. package/dist/sessions/compress.js.map +1 -1
  63. package/dist/sessions/journal.d.ts +8 -0
  64. package/dist/sessions/journal.js +44 -10
  65. package/dist/sessions/journal.js.map +1 -1
  66. package/dist/sessions/list.d.ts +6 -2
  67. package/dist/sessions/list.js +33 -10
  68. package/dist/sessions/list.js.map +1 -1
  69. package/dist/sessions/merge.d.ts +52 -2
  70. package/dist/sessions/merge.js +213 -10
  71. package/dist/sessions/merge.js.map +1 -1
  72. package/dist/sessions/service.d.ts +44 -2
  73. package/dist/sessions/service.js +251 -57
  74. package/dist/sessions/service.js.map +1 -1
  75. package/dist/sessions/session.d.ts +11 -1
  76. package/dist/sessions/session.js +23 -2
  77. package/dist/sessions/session.js.map +1 -1
  78. package/dist/sessions/state-db.d.ts +26 -4
  79. package/dist/sessions/state-db.js +126 -8
  80. package/dist/sessions/state-db.js.map +1 -1
  81. package/dist/sessions/store.js +5 -0
  82. package/dist/sessions/store.js.map +1 -1
  83. package/dist/sessions/streams.d.ts +10 -0
  84. package/dist/sessions/streams.js +14 -3
  85. package/dist/sessions/streams.js.map +1 -1
  86. package/dist/sessions/todo.d.ts +6 -1
  87. package/dist/sessions/todo.js +11 -4
  88. package/dist/sessions/todo.js.map +1 -1
  89. package/dist/sessions/tool-display.d.ts +12 -1
  90. package/dist/sessions/tool-display.js +76 -1
  91. package/dist/sessions/tool-display.js.map +1 -1
  92. package/dist/sessions/turn.d.ts +30 -9
  93. package/dist/sessions/turn.js +247 -78
  94. package/dist/sessions/turn.js.map +1 -1
  95. package/dist/settings.d.ts +20 -2
  96. package/dist/settings.js +40 -2
  97. package/dist/settings.js.map +1 -1
  98. package/dist/sidecar/fake.d.ts +2 -2
  99. package/dist/sidecar/fake.js +5 -2
  100. package/dist/sidecar/fake.js.map +1 -1
  101. package/dist/spa.js +2 -1
  102. package/dist/spa.js.map +1 -1
  103. package/dist/test/harness.js +2 -0
  104. package/dist/test/harness.js.map +1 -1
  105. package/dist/tools/insights.d.ts +8 -2
  106. package/dist/tools/insights.js +18 -2
  107. package/dist/tools/insights.js.map +1 -1
  108. package/dist/tools/kanban.d.ts +41 -1
  109. package/dist/tools/kanban.js +113 -2
  110. package/dist/tools/kanban.js.map +1 -1
  111. package/dist/tools/mcp.d.ts +2 -1
  112. package/dist/tools/mcp.js +11 -5
  113. package/dist/tools/mcp.js.map +1 -1
  114. package/dist/tools/terminal.d.ts +1 -0
  115. package/dist/tools/terminal.js +1 -1
  116. package/dist/tools/terminal.js.map +1 -1
  117. package/dist/tools/updates.d.ts +7 -0
  118. package/dist/tools/updates.js +74 -7
  119. package/dist/tools/updates.js.map +1 -1
  120. package/dist/workspace/fs.d.ts +7 -3
  121. package/dist/workspace/fs.js +5 -1
  122. package/dist/workspace/fs.js.map +1 -1
  123. package/dist/workspace/media.js +2 -0
  124. package/dist/workspace/media.js.map +1 -1
  125. package/dist/workspace/preview.d.ts +28 -0
  126. package/dist/workspace/preview.js +110 -0
  127. package/dist/workspace/preview.js.map +1 -0
  128. package/dist/workspace/rollback.d.ts +5 -4
  129. package/dist/workspace/rollback.js +12 -9
  130. package/dist/workspace/rollback.js.map +1 -1
  131. package/dist/workspace/upload.d.ts +2 -0
  132. package/dist/workspace/upload.js +4 -1
  133. package/dist/workspace/upload.js.map +1 -1
  134. package/package.json +2 -2
  135. package/sidecar/scripts/replay_sidecar.py +1 -1
  136. package/sidecar/talaria_sidecar/__init__.py +1 -1
  137. package/sidecar/talaria_sidecar/__main__.py +7 -1
  138. package/sidecar/talaria_sidecar/home.py +39 -0
  139. package/sidecar/talaria_sidecar/methods/chat.py +422 -38
  140. package/sidecar/talaria_sidecar/methods/commands.py +15 -2
  141. package/sidecar/talaria_sidecar/methods/cron.py +10 -6
  142. package/sidecar/talaria_sidecar/methods/kanban.py +115 -15
  143. package/sidecar/talaria_sidecar/methods/process.py +60 -1
  144. package/sidecar/talaria_sidecar/methods/profiles.py +7 -1
  145. package/sidecar/talaria_sidecar/methods/runtime.py +3 -0
  146. package/sidecar/talaria_sidecar/methods/text.py +17 -1
  147. package/sidecar/talaria_sidecar/methods/usage.py +257 -4
  148. package/static/dist/FILES.txt +126 -125
  149. package/static/dist/assets/AppShell-fb2td9zi.js +1 -0
  150. package/static/dist/assets/ChatPage-cj96kiy9.js +25 -0
  151. package/static/dist/assets/Dialog-kxcg7ard.js +1 -0
  152. package/static/dist/assets/ExtensionRoute-jf7h0754.js +1 -0
  153. package/static/dist/assets/HubRoute-gmanpd5y.js +2 -0
  154. package/static/dist/assets/{Markdown-jqrx5es0.js → Markdown-mdwlvj3w.js} +29 -29
  155. package/static/dist/assets/RightPanel-ftvrjlcp.js +1 -0
  156. package/static/dist/assets/Select-bilaypej.js +1 -0
  157. package/static/dist/assets/SessionListPanel-og8n36qs.js +1 -0
  158. package/static/dist/assets/SettingsLayout-jonjefmj.js +1 -0
  159. package/static/dist/assets/States-nmejrwrm.js +1 -0
  160. package/static/dist/assets/Toaster-nnl8zkt9.js +1 -0
  161. package/static/dist/assets/_app-gdidzd94.js +1 -0
  162. package/static/dist/assets/_app.ext._extensionId-opyh9y0v.js +1 -0
  163. package/static/dist/assets/_app.index-hbarzbjx.js +1 -0
  164. package/static/dist/assets/_app.insights-luywlarz.js +1 -0
  165. package/static/dist/assets/_app.kanban-kincnbr8.js +1 -0
  166. package/static/dist/assets/_app.logs-oi2gr3gs.js +1 -0
  167. package/static/dist/assets/_app.memory-b6jfivt6.js +1 -0
  168. package/static/dist/assets/_app.profiles-lpvixmqp.js +1 -0
  169. package/static/dist/assets/{_app.session._sessionId-hh27wwu2.js → _app.session._sessionId-bfd4h3id.js} +1 -1
  170. package/static/dist/assets/_app.settings-vowx3iq0.js +1 -0
  171. package/static/dist/assets/_app.settings._section-cnntg1tu.js +3 -0
  172. package/static/dist/assets/_app.skills-fb57lpau.js +1 -0
  173. package/static/dist/assets/_app.tasks-eszpx1q7.js +2 -0
  174. package/static/dist/assets/_app.todos-nr05ac6w.js +1 -0
  175. package/static/dist/assets/_app.workspaces-d2luomu6.js +1 -0
  176. package/static/dist/assets/{abnfDiagram-VCTEODGH-oity9y4o.js → abnfDiagram-VCTEODGH-b2x1lqot.js} +1 -1
  177. package/static/dist/assets/architecture-7GRP2DOG-hd0o7bde.js +1 -0
  178. package/static/dist/assets/{architectureDiagram-5GKGNRK7-ceaepnyr.js → architectureDiagram-5GKGNRK7-h38o5l7b.js} +1 -1
  179. package/static/dist/assets/{back-eu64w89w.js → back-bemaer09.js} +1 -1
  180. package/static/dist/assets/{blockDiagram-I7D4REHJ-n79st4pj.js → blockDiagram-I7D4REHJ-bqquxv2u.js} +1 -1
  181. package/static/dist/assets/{c4Diagram-7LVT6UL2-mi73akzk.js → c4Diagram-7LVT6UL2-f3fb8w6z.js} +1 -1
  182. package/static/dist/assets/{cancel-mzvkdjg8.js → cancel-drd0g6d9.js} +1 -1
  183. package/static/dist/assets/channel-cpdgf867.js +1 -0
  184. package/static/dist/assets/{chunk-4HAMMTFA-laat0g1q.js → chunk-4HAMMTFA-bzfyyzp3.js} +1 -1
  185. package/static/dist/assets/{chunk-75Z2AOVW-0psy1tr2.js → chunk-75Z2AOVW-ly99rfx5.js} +1 -1
  186. package/static/dist/assets/{chunk-DU6HZSFF-lw8uox8x.js → chunk-DU6HZSFF-bg6ecfqf.js} +3 -3
  187. package/static/dist/assets/{chunk-F27PBJKO-erassib3.js → chunk-F27PBJKO-e8k7mmqw.js} +1 -1
  188. package/static/dist/assets/{chunk-GMAD6QVW-fz7rx619.js → chunk-GMAD6QVW-cmalnoaj.js} +1 -1
  189. package/static/dist/assets/{chunk-GVQU2GXP-gdb0epb2.js → chunk-GVQU2GXP-gmif5o01.js} +1 -1
  190. package/static/dist/assets/{chunk-IMKFNOWR-ea8t26qw.js → chunk-IMKFNOWR-f1nwwh6u.js} +1 -1
  191. package/static/dist/assets/{chunk-L3NEJ4N5-mb1gu9kz.js → chunk-L3NEJ4N5-oktfh5v7.js} +1 -1
  192. package/static/dist/assets/{chunk-OSK3NFVY-eovmccvy.js → chunk-OSK3NFVY-b1sdx96z.js} +1 -1
  193. package/static/dist/assets/{chunk-P2QGCYS3-bo55zjo5.js → chunk-P2QGCYS3-fhu4nzxt.js} +1 -1
  194. package/static/dist/assets/{chunk-POPQ4Y6H-ja7ohe4h.js → chunk-POPQ4Y6H-em31rnef.js} +1 -1
  195. package/static/dist/assets/{chunk-PWAF6VOD-e30g9nus.js → chunk-PWAF6VOD-bxhhyftw.js} +1 -1
  196. package/static/dist/assets/{chunk-SHT3W25Y-gbb798f7.js → chunk-SHT3W25Y-fmrvwcav.js} +1 -1
  197. package/static/dist/assets/{chunk-SVP7TREG-h2iw8urm.js → chunk-SVP7TREG-lymukl2j.js} +1 -1
  198. package/static/dist/assets/{chunk-TICWLB2K-fd2cottz.js → chunk-TICWLB2K-lmza6k23.js} +1 -1
  199. package/static/dist/assets/classDiagram-ZZMXUADV-ko09sguk.js +1 -0
  200. package/static/dist/assets/classDiagram-v2-VYDZK3BY-ko09sguk.js +1 -0
  201. package/static/dist/assets/{copied-h65fc3cx.js → copied-ima3pysb.js} +1 -1
  202. package/static/dist/assets/copy-fw5b1pc6.js +1 -0
  203. package/static/dist/assets/{cynefin-OW5HDTMX-lbltyl5j.js → cynefin-OW5HDTMX-czlhbyhs.js} +1 -1
  204. package/static/dist/assets/{cynefinDiagram-5FMLGOSQ-lxhsqq4a.js → cynefinDiagram-5FMLGOSQ-gq7mvswb.js} +1 -1
  205. package/static/dist/assets/{dagre-GXQ25YYZ-gn4nnaln.js → dagre-GXQ25YYZ-cqdbf7dr.js} +1 -1
  206. package/static/dist/assets/{diagram-S7CK7UJ4-pa3ij6q7.js → diagram-S7CK7UJ4-o6arxa58.js} +1 -1
  207. package/static/dist/assets/{diagram-UQ7AKVKN-zbipyz57.js → diagram-UQ7AKVKN-nhnd68tz.js} +1 -1
  208. package/static/dist/assets/{diagram-VSXAHHWV-d1kbpzgf.js → diagram-VSXAHHWV-dk2sclzn.js} +1 -1
  209. package/static/dist/assets/{diagram-VX7I27RA-i3ty14xl.js → diagram-VX7I27RA-n3k5nyx3.js} +1 -1
  210. package/static/dist/assets/{diagram-Z3DM3KII-m8xefqa7.js → diagram-Z3DM3KII-m6q9cwdh.js} +1 -1
  211. package/static/dist/assets/{ebnfDiagram-PWID7BFC-nz7wj05l.js → ebnfDiagram-PWID7BFC-lsa5641p.js} +1 -1
  212. package/static/dist/assets/endpoints-d33siokx.js +64 -0
  213. package/static/dist/assets/{erDiagram-RLTQ6QDP-fa41ib83.js → erDiagram-RLTQ6QDP-fo2ckbe6.js} +1 -1
  214. package/static/dist/assets/eventmodeling-NTZA5JFV-emctlo64.js +1 -0
  215. package/static/dist/assets/flowDiagram-HODETNUW-bfi3moqa.js +1 -0
  216. package/static/dist/assets/{ganttDiagram-EL5Y4UJY-n7zq01qu.js → ganttDiagram-EL5Y4UJY-nzqz6x9g.js} +1 -1
  217. package/static/dist/assets/{gitGraph-4MIJSDKK-c89emb07.js → gitGraph-4MIJSDKK-gukvcxe6.js} +1 -1
  218. package/static/dist/assets/{gitGraphDiagram-WWUBYQGX-cz7cgr6w.js → gitGraphDiagram-WWUBYQGX-lqhdp8f0.js} +1 -1
  219. package/static/dist/assets/{highlighted-body-KPVGNVTW-d9bapmni.js → highlighted-body-KPVGNVTW-igw6cp39.js} +1 -1
  220. package/static/dist/assets/index-cxq58xb1.js +11 -0
  221. package/static/dist/assets/index-hgtx08n5.css +2 -0
  222. package/static/dist/assets/{info-A6RAGUB7-ndddhhhh.js → info-A6RAGUB7-gvu7a93l.js} +1 -1
  223. package/static/dist/assets/{infoDiagram-27XIBGKW-ccxigcpf.js → infoDiagram-27XIBGKW-m8t8g6w1.js} +1 -1
  224. package/static/dist/assets/{ishikawaDiagram-5VMMS53U-le0z9vtc.js → ishikawaDiagram-5VMMS53U-l07vkbgj.js} +1 -1
  225. package/static/dist/assets/{journeyDiagram-3NMN7TZE-ivsmb26o.js → journeyDiagram-3NMN7TZE-hybkgj8l.js} +1 -1
  226. package/static/dist/assets/{kanban-definition-UXKFOSKX-h6n2awt0.js → kanban-definition-UXKFOSKX-by13uvtn.js} +1 -1
  227. package/static/dist/assets/lazyRouteComponent-af0lvgjx.js +1 -0
  228. package/static/dist/assets/{line-dmzlfe0u.js → line-osxq6fq7.js} +1 -1
  229. package/static/dist/assets/link-jyxicdhg.js +1 -0
  230. package/static/dist/assets/{login-kjhasvp8.js → login-ec21t39x.js} +1 -1
  231. package/static/dist/assets/mermaid-HWGCJPDP-gfl8z3ep.js +1 -0
  232. package/static/dist/assets/{mermaid-parser.core-gwyd5bnq.js → mermaid-parser.core-i91oxmou.js} +3 -3
  233. package/static/dist/assets/{mindmap-definition-YA3MSWOX-l68gg5h7.js → mindmap-definition-YA3MSWOX-m82mx8ww.js} +1 -1
  234. package/static/dist/assets/onboarding-btnltvyz.js +1 -0
  235. package/static/dist/assets/onboarding_model_label-dp7xffoh.js +1 -0
  236. package/static/dist/assets/{packet-AYTQ26CC-gpv06065.js → packet-AYTQ26CC-nbtgge2o.js} +1 -1
  237. package/static/dist/assets/{pegDiagram-XKGWAZYB-e52vs23u.js → pegDiagram-XKGWAZYB-f1zxzga1.js} +1 -1
  238. package/static/dist/assets/{pie-WAS4IAKB-l6m7nz5s.js → pie-WAS4IAKB-of8vuhxs.js} +1 -1
  239. package/static/dist/assets/{pieDiagram-E7YTZNPT-b4is36bq.js → pieDiagram-E7YTZNPT-o7y8ftio.js} +1 -1
  240. package/static/dist/assets/{quadrantDiagram-AXDQQJYC-m8vt2788.js → quadrantDiagram-AXDQQJYC-iqiwia1t.js} +1 -1
  241. package/static/dist/assets/{radar-RG4KPBEZ-nxbrhiov.js → radar-RG4KPBEZ-delnsy2v.js} +1 -1
  242. package/static/dist/assets/{railroad-74A4TZTK-222mu9hi.js → railroad-74A4TZTK-nspnyq9u.js} +1 -1
  243. package/static/dist/assets/railroad-abnf-HS5TGJTU-nst1qxyn.js +1 -0
  244. package/static/dist/assets/railroad-ebnf-LZEXJU2U-ci37x8qy.js +1 -0
  245. package/static/dist/assets/railroad-peg-WCYAUIDC-aimkk07z.js +1 -0
  246. package/static/dist/assets/{railroadDiagram-O6MQD6OU-o8lldfzv.js → railroadDiagram-O6MQD6OU-z41tqx5z.js} +1 -1
  247. package/static/dist/assets/refresh-b4uams1i.js +1 -0
  248. package/static/dist/assets/refresh-cw-nt1dtsx4.js +1 -0
  249. package/static/dist/assets/{requirementDiagram-BXWQKSXE-ovyq38kv.js → requirementDiagram-BXWQKSXE-bdvif194.js} +1 -1
  250. package/static/dist/assets/{sankeyDiagram-P5KCCOFB-ou7lznor.js → sankeyDiagram-P5KCCOFB-h73e0rol.js} +1 -1
  251. package/static/dist/assets/{saved-bazmcup9.js → saved-kg52csy7.js} +1 -1
  252. package/static/dist/assets/{sequenceDiagram-WJ2MYXX4-ovckdzf2.js → sequenceDiagram-WJ2MYXX4-iv95mb1z.js} +1 -1
  253. package/static/dist/assets/{settings_section_extensions_title-ertwwhlx.js → settings_section_extensions_title-ej0iapxe.js} +1 -1
  254. package/static/dist/assets/share._token-f97e94r0.js +2 -0
  255. package/static/dist/assets/sliders-horizontal-fj18it47.js +1 -0
  256. package/static/dist/assets/sse-fwpqtzbg.js +1 -0
  257. package/static/dist/assets/{stateDiagram-D77RDMKH-fcrexkkv.js → stateDiagram-D77RDMKH-k417ixmf.js} +1 -1
  258. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-hwn4apct.js +1 -0
  259. package/static/dist/assets/{swimlanes-42K2YHIH-f7usu8fw.js → swimlanes-42K2YHIH-esola70w.js} +1 -1
  260. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-d1h97oyg.js +8 -0
  261. package/static/dist/assets/{timeline-definition-24CTP7MA-gp1hvz9f.js → timeline-definition-24CTP7MA-getrz2y8.js} +1 -1
  262. package/static/dist/assets/todoStore-eginf9h4.js +1 -0
  263. package/static/dist/assets/{treeView-Q6P3EWNA-gb9gf11u.js → treeView-Q6P3EWNA-hc7ap1q7.js} +1 -1
  264. package/static/dist/assets/{treemap-WGGIJYW6-nuvfnvvi.js → treemap-WGGIJYW6-b7k1syy5.js} +1 -1
  265. package/static/dist/assets/tts-lxdxnmjd.js +1 -0
  266. package/static/dist/assets/{untitled-htelhc68.js → untitled-ovpfthg4.js} +1 -1
  267. package/static/dist/assets/{useForm-h2t0u14e.js → useForm-bcblv1rx.js} +1 -1
  268. package/static/dist/assets/useLocale-fi5jb8ma.js +1 -0
  269. package/static/dist/assets/{useParams-dqd64jv7.js → useParams-lhg566ew.js} +1 -1
  270. package/static/dist/assets/{useSearch-j30pvsy7.js → useSearch-lbrh6ejn.js} +1 -1
  271. package/static/dist/assets/{vennDiagram-4TSXK5OY-fzchbzaj.js → vennDiagram-4TSXK5OY-n6pcy5qb.js} +1 -1
  272. package/static/dist/assets/{wardley-WFR3VGLG-m47mhfbh.js → wardley-WFR3VGLG-lpa18vz1.js} +1 -1
  273. package/static/dist/assets/{wardleyDiagram-VM6X3IG4-odg6ct1z.js → wardleyDiagram-VM6X3IG4-kpclwwg7.js} +1 -1
  274. package/static/dist/assets/{xychartDiagram-S5SC5T6Z-mrhms5um.js → xychartDiagram-S5SC5T6Z-paa2n8y0.js} +1 -1
  275. package/static/dist/index.html +1 -1
  276. package/static/dist/sw.js +2 -2
  277. package/static/dist/assets/AppShell-ef3bhu32.js +0 -1
  278. package/static/dist/assets/Button-nx37f4u1.js +0 -1
  279. package/static/dist/assets/ChatPage-cdcpykcg.js +0 -25
  280. package/static/dist/assets/Dialog-mec42hvb.js +0 -1
  281. package/static/dist/assets/HubRoute-ecb65zpr.js +0 -2
  282. package/static/dist/assets/RightPanel-d1lgvk4s.js +0 -1
  283. package/static/dist/assets/Select-h4ivl9qf.js +0 -1
  284. package/static/dist/assets/SessionListPanel-ewib046b.js +0 -1
  285. package/static/dist/assets/SettingsLayout-lx654cup.js +0 -1
  286. package/static/dist/assets/States-ehsb6lzo.js +0 -1
  287. package/static/dist/assets/Toaster-mch1pa3t.js +0 -1
  288. package/static/dist/assets/_app-m8d961ef.js +0 -1
  289. package/static/dist/assets/_app.ext._extensionId-mp33hbzi.js +0 -1
  290. package/static/dist/assets/_app.index-dk6zp7e0.js +0 -1
  291. package/static/dist/assets/_app.insights-jt2fk4i1.js +0 -1
  292. package/static/dist/assets/_app.kanban-if4pubeu.js +0 -1
  293. package/static/dist/assets/_app.logs-mfaw9m6g.js +0 -1
  294. package/static/dist/assets/_app.memory-h3eaarb6.js +0 -1
  295. package/static/dist/assets/_app.profiles-ienktovs.js +0 -1
  296. package/static/dist/assets/_app.settings-dpoe0bzf.js +0 -1
  297. package/static/dist/assets/_app.settings._section-l468ynag.js +0 -3
  298. package/static/dist/assets/_app.skills-kcbncc8i.js +0 -1
  299. package/static/dist/assets/_app.tasks-occdrqhw.js +0 -2
  300. package/static/dist/assets/_app.todos-nnke2rcc.js +0 -1
  301. package/static/dist/assets/_app.workspaces-cdlatvwj.js +0 -1
  302. package/static/dist/assets/architecture-7GRP2DOG-hj11333z.js +0 -1
  303. package/static/dist/assets/channel-mbvmf2vv.js +0 -1
  304. package/static/dist/assets/classDiagram-ZZMXUADV-o8r05k0n.js +0 -1
  305. package/static/dist/assets/classDiagram-v2-VYDZK3BY-o8r05k0n.js +0 -1
  306. package/static/dist/assets/copy-e6977uwq.js +0 -1
  307. package/static/dist/assets/endpoints-k7yf25m0.js +0 -64
  308. package/static/dist/assets/eventmodeling-NTZA5JFV-kpbq09bx.js +0 -1
  309. package/static/dist/assets/flowDiagram-HODETNUW-lcz0kx14.js +0 -1
  310. package/static/dist/assets/index-h00usru2.js +0 -11
  311. package/static/dist/assets/index-n73ijkv2.css +0 -2
  312. package/static/dist/assets/lazyRouteComponent-m1rtyk4t.js +0 -1
  313. package/static/dist/assets/link-budeg5t9.js +0 -1
  314. package/static/dist/assets/matchContext-f8oy3lo7.js +0 -1
  315. package/static/dist/assets/mermaid-HWGCJPDP-jb5d211j.js +0 -1
  316. package/static/dist/assets/onboarding-cdfrk0pj.js +0 -1
  317. package/static/dist/assets/railroad-abnf-HS5TGJTU-kdvgl6x8.js +0 -1
  318. package/static/dist/assets/railroad-ebnf-LZEXJU2U-itiqslby.js +0 -1
  319. package/static/dist/assets/railroad-peg-WCYAUIDC-go7kov78.js +0 -1
  320. package/static/dist/assets/refresh-cw-kbcje1uy.js +0 -1
  321. package/static/dist/assets/search-jen74z4u.js +0 -1
  322. package/static/dist/assets/share._token-dan9hgvj.js +0 -2
  323. package/static/dist/assets/sliders-horizontal-f9cb3lh3.js +0 -1
  324. package/static/dist/assets/stateDiagram-v2-MP3YSRHH-lcfraua2.js +0 -1
  325. package/static/dist/assets/swimlanesDiagram-VR7AAH4N-ogmanni0.js +0 -8
  326. package/static/dist/assets/todoStore-eqtid4r4.js +0 -1
  327. package/static/dist/assets/useLocale-hcsb84pj.js +0 -1
  328. package/static/dist/assets/useNavigate-nwy70ztj.js +0 -1
@@ -3,9 +3,11 @@
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
9
  import { stripAttachedFilesMarker } from './session.js';
10
+ import { decidedEditDiff, toolEditDiff, toolName } from './tool-display.js';
9
11
  export const WORKSPACE_PREFIX_RE = /^\s*\[Workspace::v1:\s*(?:\\.|[^\]\\])+\]\s*/;
10
12
  const LEGACY_WORKSPACE_PREFIX_RE = /^\s*\[Workspace:[^\]]+\]\s*/;
11
13
  const TOOL_RESULT_SNIPPET_MAX = 4000;
@@ -55,7 +57,7 @@ export function messageText(content) {
55
57
  }
56
58
  return str(content);
57
59
  }
58
- export function messageIdentity(msg) {
60
+ export function messageIdentity(msg, textLimit = 500) {
59
61
  if (!isDict(msg))
60
62
  return null;
61
63
  const role = str(msg.role);
@@ -75,7 +77,7 @@ export function messageIdentity(msg) {
75
77
  return null;
76
78
  }
77
79
  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))]);
80
+ return JSON.stringify([role, text.split(/\s+/).join(' ').trim().slice(0, textLimit), str(msg.tool_call_id), JSON.stringify(sortKeysDeep(toolCalls))]);
79
81
  }
80
82
  function sortKeysDeep(value) {
81
83
  if (Array.isArray(value))
@@ -226,6 +228,17 @@ export function injectMaxIterationSummaryFallback(messages, finalResponse) {
226
228
  return messages;
227
229
  return [...messages, { role: 'assistant', content: finalResponse, _max_iteration_summary_fallback: true }];
228
230
  }
231
+ /**
232
+ * TAL-537: the user row the Agent appends to ask for that summary is its own prompt, neither shown nor sent back. It is
233
+ * the exhausted turn's last user row; any other row with the same text (one the user typed) stays.
234
+ */
235
+ export function withoutMaxIterationSummaryRequest(messages, request, msgText) {
236
+ const at = messages.findLastIndex((m) => m.role === 'user');
237
+ const row = messages[at];
238
+ if (!request || row?.content !== request || looksLikeCurrentUserTurn(row, msgText))
239
+ return messages;
240
+ return messages.filter((_, i) => i !== at);
241
+ }
229
242
  export function mergeDisplayMessagesAfterAgentResult(previousDisplay, previousContext, resultMessages, msgText, opts = {}) {
230
243
  const display = previousDisplay.filter((m) => !isContextCompressionMarker(m));
231
244
  const seenPartial = new Set();
@@ -670,26 +683,70 @@ export function withToolCallOutcomes(messages, sessionToolCalls, activeTurnId) {
670
683
  if (!calls.length && !records.length)
671
684
  return m;
672
685
  const running = Boolean(activeTurnId) && m._turn_id === activeTurnId;
673
- const resolve = (id, rec, answered) => {
686
+ const resolve = (id, name, rec, answered) => {
674
687
  const reply = id ? replies.get(key(index, id)) : undefined;
675
688
  const outcome = reply ? { ...toolOutcome(reply.content), flagged: reply.is_error } : null;
689
+ // TAL-448: a file edit's change, from its full reply, else the one its live record decided.
690
+ const editDiff = reply ? toolEditDiff(name, reply.content) : decidedEditDiff(rec?.edit_diff);
676
691
  return {
692
+ ...(editDiff ? { edit_diff: editDiff } : {}),
677
693
  done: Boolean(reply) || answered || !running, is_error: outcome ? outcome.flagged || outcome.is_error : rec?.is_error === true,
678
694
  duration: finiteOrNull(rec?.duration), result: outcome ? outcome.result_text : typeof rec?.snippet === 'string' ? rec.snippet : null,
679
695
  result_view: outcome ? outcome.result_view : isDict(rec?.result_view) ? decidedResultView(rec.result_view) : typeof rec?.snippet === 'string' ? toolResultView(rec.snippet) : null,
680
696
  };
681
697
  };
682
698
  const projected = [
683
- ...calls.map((call) => (isDict(call) ? { ...call, ...resolve(callId(call), recorded.get(callId(call)), false) } : call)),
699
+ ...calls.map((call) => (isDict(call) ? { ...call, ...resolve(callId(call), toolName(call), recorded.get(callId(call)), false) } : call)),
684
700
  ...records.map((tc) => ({
685
701
  ...(str(tc.tid) ? { id: str(tc.tid) } : {}), type: 'function', function: { name: str(tc.name), arguments: JSON.stringify(tc.args ?? {}) },
686
702
  // 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),
703
+ ...resolve(str(tc.tid), tc.name, tc, typeof tc.done === 'boolean' ? tc.done : true),
688
704
  })),
689
705
  ];
690
706
  return { ...m, tool_calls: projected };
691
707
  });
692
708
  }
709
+ /** The prompt text naming every attached file by path after it (TAL-276), so an attachment-only turn still asks something. */
710
+ export function attachedFilesPrompt(text, attachments) {
711
+ const named = attachments.map((att) => (isDict(att) ? str(att.path).trim() : '')).filter(Boolean).map(escapeWorkspacePrefixPath);
712
+ return named.length ? `${text}\n\n[Attached files: ${named.join(', ')}]` : text;
713
+ }
714
+ const TOOL_IMAGE_PART_TYPES = new Set(['image', 'image_url', 'input_image']);
715
+ /**
716
+ * TAL-544, Python `_compact_image_parts_for_persistence`: a settled turn's tool-result images (browser and vision
717
+ * screenshots) become `[screenshot]` text, so saves, loads and later turns stop carrying the base64. A result is a `tool`
718
+ * row or an Anthropic-style `tool_result` block in a user row; the user's own attachments stay.
719
+ */
720
+ export function withoutToolImages(messages) {
721
+ const isImage = (p) => isDict(p) && TOOL_IMAGE_PART_TYPES.has(p.type);
722
+ const hasImage = (parts) => Array.isArray(parts) && parts.some(isImage);
723
+ const compact = (parts) => parts.map((p) => (isImage(p) ? { type: 'text', text: '[screenshot]' } : p));
724
+ const isImageResult = (p) => isDict(p) && p.type === 'tool_result' && hasImage(p.content);
725
+ const out = messages.map((m) => {
726
+ const content = m.content;
727
+ if (m.role === 'tool' && hasImage(content))
728
+ return { ...m, content: compact(content) };
729
+ if (m.role === 'user' && Array.isArray(content) && content.some(isImageResult)) {
730
+ return { ...m, content: content.map((p) => (isImageResult(p) ? { ...p, content: compact(p.content) } : p)) };
731
+ }
732
+ return m;
733
+ });
734
+ // The same array when nothing changed, so a caller can tell whether its rows were rewritten.
735
+ return out.some((m, i) => m !== messages[i]) ? out : messages;
736
+ }
737
+ /** A settled model context without an assistant row repeated back to back, and without tool-result images. */
738
+ export function dedupeContext(messages) {
739
+ const out = [];
740
+ let lastKey = null;
741
+ for (const m of withoutToolImages(messages)) {
742
+ const key = messageIdentity(m);
743
+ if (key !== null && key === lastKey && m.role === 'assistant')
744
+ continue;
745
+ out.push(m);
746
+ lastKey = key;
747
+ }
748
+ return out;
749
+ }
693
750
  /** Python `_build_partial_message`. */
694
751
  export function buildPartialMessage(contentText, reasoningText, toolCalls, now = Date.now() / 1000) {
695
752
  let stripped = '';
@@ -709,6 +766,69 @@ export function buildPartialMessage(contentText, reasoningText, toolCalls, now =
709
766
  msg._partial_tool_calls = [...toolCalls];
710
767
  return msg;
711
768
  }
769
+ /**
770
+ * TAL-536: a dead run's journaled output as partial rows, in order: each row is a stretch of reasoning and prose with the
771
+ * tool calls that followed it, the shape a Stop's snapshot keeps. A run that ended in `done` gets its answer as a settled
772
+ * row: its last prose row, else the one the `done` frame's session carries (an answer that never streamed, like the
773
+ * tool-limit summary). `answered` says the run finished with one.
774
+ */
775
+ export function journalOutputRows(events, turnId) {
776
+ const rows = [];
777
+ const calls = [];
778
+ let text = '';
779
+ let reasoning = '';
780
+ let tools = [];
781
+ let at = 0;
782
+ const flush = () => {
783
+ const row = buildPartialMessage(text, reasoning, tools, at);
784
+ if (row)
785
+ rows.push({ ...row, _turn_id: turnId });
786
+ text = '';
787
+ reasoning = '';
788
+ tools = [];
789
+ };
790
+ for (const e of events) {
791
+ const p = isDict(e.payload) ? e.payload : {};
792
+ if ((e.event === 'token' || e.event === 'reasoning') && tools.length)
793
+ flush();
794
+ if (e.event === 'token')
795
+ text += str(p.text);
796
+ else if (e.event === 'reasoning')
797
+ reasoning += str(p.text);
798
+ else if (e.event === 'tool') {
799
+ const call = { name: p.name, args: p.args ?? {}, tid: str(p.id), done: false };
800
+ calls.push(call);
801
+ tools.push(call);
802
+ }
803
+ else if (e.event === 'tool_complete') {
804
+ // The record is shared with the row that holds it, so a completion after its row closed still lands.
805
+ const call = calls[completedToolIndex(calls, str(p.id), p.name)];
806
+ if (call)
807
+ 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 } : {}) });
808
+ }
809
+ else
810
+ continue;
811
+ at = e.created_at || at;
812
+ }
813
+ flush();
814
+ const done = RunJournal.selectAuthoritativeTerminalEvent(events);
815
+ if (done?.event !== 'done')
816
+ return { rows, answered: false };
817
+ // The last row answers only with visible prose and no calls after it (a reasoning-only segment is no answer).
818
+ const last = rows[rows.length - 1];
819
+ if (last && !last._partial_tool_calls && str(last.content)) {
820
+ delete last._partial;
821
+ return { rows, answered: true };
822
+ }
823
+ const settled = isDict(done.payload) && isDict(done.payload.session) && Array.isArray(done.payload.session.messages) ? done.payload.session.messages : [];
824
+ const answer = settled.findLast((m) => isDict(m) && m.role === 'assistant' && m._turn_id === turnId);
825
+ // Its visible prose, from string or structured content, as the scene's final answer reads it.
826
+ const content = answer && !answer._error && !(Array.isArray(answer.tool_calls) && answer.tool_calls.length) ? splitDisplayText(messageText(answer.content))[0] : '';
827
+ if (!content)
828
+ return { rows, answered: false };
829
+ rows.push({ role: 'assistant', content, timestamp: Math.trunc(done.created_at), _turn_id: turnId });
830
+ return { rows, answered: true };
831
+ }
712
832
  const DSML = '(?:\\s*|\\s*DSML\\s*[||]\\s*)?';
713
833
  /** Markdown code (fenced blocks, an unclosed one running to the end, and inline spans): markup written there is literal. */
714
834
  function codeRanges(text) {
@@ -833,6 +953,9 @@ export function normalizeAssistantDisplay(message) {
833
953
  * replay): rows at or before it, and, for a truncation cut, rows after it until the sidecar advances past it (TAL-504).
834
954
  * A compression watermark only covers the compressed rows. Rows past the sidecar tail (a conversation continued from the
835
955
  * CLI) are appended in state.db order.
956
+ * TAL-493: once a boundary or settled turn recorded the highest state.db id it read (`stateDbSeenId`) and the rows carry
957
+ * ids, identity replaces the timestamp rules: rows up to that id are covered, and every newer row not already in the
958
+ * sidecar is appended, even one a writer stamped before the newest local row or the watermark but committed later.
836
959
  * ponytail: the Python identity memo (api_content sidecars, message ids, workspace-prefix normalisation) is not ported;
837
960
  * add it if a mixed WebUI/CLI transcript shows duplicated turns.
838
961
  */
@@ -843,6 +966,31 @@ export function mergeSessionMessagesAppendOnly(sidecar, state, opts = {}) {
843
966
  return sidecar;
844
967
  const ts = (m) => { const n = Number(m.timestamp); return Number.isFinite(n) ? n : null; };
845
968
  const key = (m) => `${String(m.role)}\0${String(ts(m) ?? '')}\0${typeof m.content === 'string' ? m.content : JSON.stringify(m.content ?? null)}`;
969
+ const seenId = opts.stateDbSeenId;
970
+ if (typeof seenId === 'number' && Number.isFinite(seenId) && state.some((m) => stateDbRowId(m) !== null)) {
971
+ // Each local row stands for at most one new state.db row: a persisted copy by its id, any other by its key.
972
+ const localIds = new Set(sidecar.map(stateDbRowId));
973
+ const localKeys = new Map();
974
+ for (const m of sidecar)
975
+ if (stateDbRowId(m) === null)
976
+ localKeys.set(key(m), (localKeys.get(key(m)) ?? 0) + 1);
977
+ const merged = [...sidecar];
978
+ for (const m of state) {
979
+ const id = stateDbRowId(m);
980
+ if (id !== null && localIds.has(id))
981
+ continue;
982
+ // In state.db order, so a covered row matches its own local copy before a newer duplicate can.
983
+ const left = localKeys.get(key(m)) ?? 0;
984
+ if (left > 0) {
985
+ localKeys.set(key(m), left - 1);
986
+ continue;
987
+ }
988
+ if (id === null || id <= seenId)
989
+ continue;
990
+ merged.push(m);
991
+ }
992
+ return merged;
993
+ }
846
994
  if (!sidecar.length) {
847
995
  if (!hasWatermark) {
848
996
  const seen = new Set();
@@ -877,6 +1025,21 @@ export function mergeSessionMessagesAppendOnly(sidecar, state, opts = {}) {
877
1025
  }
878
1026
  return merged;
879
1027
  }
1028
+ /** The Agent's `messages.id` a state.db row was read with, or null for a database without the column. */
1029
+ function stateDbRowId(m) {
1030
+ const id = m._state_db_row_id;
1031
+ return typeof id === 'number' && Number.isFinite(id) ? id : null;
1032
+ }
1033
+ /** TAL-493: the `state_db_seen_id` after reading `rows`: their highest id, or null when they carry none. */
1034
+ export function stateDbSeenId(rows) {
1035
+ let max = null;
1036
+ for (const m of rows) {
1037
+ const id = stateDbRowId(m);
1038
+ if (id !== null && (max === null || id > max))
1039
+ max = id;
1040
+ }
1041
+ return max;
1042
+ }
880
1043
  /**
881
1044
  * TAL-316: the merged transcript without the running turn's output, which the run journal replays from its start. The turn
882
1045
  * begins at its checkpointed prompt, else at its first stamped row or the first state.db row appended past the sidecar
@@ -1066,7 +1229,8 @@ export function stoppedTurnContext(previousContext, checkpoint, prompt, msgText,
1066
1229
  // A tool result is a `tool` row or an Anthropic-style user row of `tool_result` blocks. A steer the Agent applied is
1067
1230
  // neither a prompt nor a result: the boundary goes after it, and it never makes the turn look unanswered.
1068
1231
  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);
1232
+ // The next turn's own history projection, so an answer the Agent replays from `api_content` counts.
1233
+ const tail = () => sanitizeMessagesForApi(rows.filter((m) => agentSteerText(m) === null), { preserveApiContent: true }).at(-1);
1070
1234
  if (toolResult(tail()))
1071
1235
  rows.push({ role: 'assistant', content: unsettled || 'Operation interrupted.' });
1072
1236
  else if (unsettled)
@@ -1091,6 +1255,10 @@ export function agentSteerText(m) {
1091
1255
  return inner.trim();
1092
1256
  return m.display_kind === 'steer' ? content.trim() : null;
1093
1257
  }
1258
+ /** The Agent's `api_content` replay sidecar: the exact bytes a user/assistant row was sent as, else undefined. */
1259
+ function apiContent(msg) {
1260
+ return (msg.role === 'user' || msg.role === 'assistant') && typeof msg.api_content === 'string' && msg.api_content ? msg.api_content : undefined;
1261
+ }
1094
1262
  /** Python `_is_reasoning_only_assistant_message`: a display-only Thinking card with no visible reply. */
1095
1263
  function isReasoningOnlyAssistant(msg) {
1096
1264
  if (msg.role !== 'assistant' || (Array.isArray(msg.tool_calls) && msg.tool_calls.length))
@@ -1115,8 +1283,10 @@ function stripOobBlocks(content) {
1115
1283
  * reasoning-only assistants), orphaned tool rows and unanswered tool calls, keeps only API-safe keys, strips consumed
1116
1284
  * out-of-band blocks, and keeps a cancelled (`_recovered`) user prompt only where it separates two assistant turns —
1117
1285
  * otherwise the neighbours fuse cleanly or the prompt is stale, and replaying it would answer it again.
1286
+ * `preserveApiContent` (Python `_sanitize_messages_for_agent`) keeps the Agent's `api_content` replay sidecar on
1287
+ * user/assistant rows for turn history; compression and other projections strip it.
1118
1288
  */
1119
- export function sanitizeMessagesForApi(messages) {
1289
+ export function sanitizeMessagesForApi(messages, { preserveApiContent = false } = {}) {
1120
1290
  // Calls are OpenAI `tool_calls` or Anthropic-style `tool_use` content blocks; results name them by `tool_call_id`,
1121
1291
  // `tool_use_id`, or a user row's `tool_result` blocks.
1122
1292
  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 +1306,9 @@ export function sanitizeMessagesForApi(messages) {
1136
1306
  for (const msg of messages) {
1137
1307
  if (!msg || typeof msg !== 'object')
1138
1308
  continue;
1139
- if (isReasoningOnlyAssistant(msg))
1309
+ // A reasoning-only clean stop the Agent answered from `api_content` is a reply, not a Thinking card.
1310
+ const replay = preserveApiContent ? apiContent(msg) : undefined;
1311
+ if (isReasoningOnlyAssistant(msg) && !replay)
1140
1312
  continue;
1141
1313
  // The Agent already received a steer mid-turn; its persisted row is display-only.
1142
1314
  if (msg._error || isDict(msg._steer))
@@ -1152,6 +1324,8 @@ export function sanitizeMessagesForApi(messages) {
1152
1324
  const sanitized = Object.fromEntries(Object.entries(msg).filter(([k]) => API_SAFE_MSG_KEYS.has(k)));
1153
1325
  if (Array.isArray(sanitized.tool_calls) && !sanitized.tool_calls.length)
1154
1326
  Reflect.deleteProperty(sanitized, 'tool_calls');
1327
+ if (replay)
1328
+ sanitized.api_content = replay;
1155
1329
  if (recovered)
1156
1330
  sanitized._recovered = true;
1157
1331
  if ('content' in sanitized)
@@ -1174,7 +1348,7 @@ export function sanitizeMessagesForApi(messages) {
1174
1348
  continue;
1175
1349
  msg = { ...msg, content: parts };
1176
1350
  // Reasoning left behind by a dropped call is not an answer either.
1177
- if (isReasoningOnlyAssistant(msg))
1351
+ if (isReasoningOnlyAssistant(msg) && !apiContent(msg))
1178
1352
  continue;
1179
1353
  }
1180
1354
  if (msg.role === 'assistant' && Array.isArray(msg.tool_calls) && msg.tool_calls.length) {
@@ -1203,4 +1377,33 @@ export function sanitizeMessagesForApi(messages) {
1203
1377
  }
1204
1378
  return final;
1205
1379
  }
1380
+ const isNativeImagePart = (part) => isDict(part) && (part.type === 'image_url' || 'image_url' in part);
1381
+ /** True when any row's content carries a native `image_url` part. */
1382
+ export function hasNativeImages(messages) {
1383
+ return messages.some((msg) => Array.isArray(msg.content) && msg.content.some(isNativeImagePart));
1384
+ }
1385
+ /**
1386
+ * Python `_strip_native_image_parts_from_content` (TAL-545): the history for a turn whose image mode resolved to text.
1387
+ * Native `image_url` parts are dropped and the text kept; a lone text part collapses to its string, as a text-only
1388
+ * provider rejects a replayed image before the Agent's own strip-and-retry guard can recover.
1389
+ */
1390
+ export function withoutNativeImages(messages) {
1391
+ return messages.map((msg) => {
1392
+ if (!Array.isArray(msg.content) || !msg.content.some(isNativeImagePart))
1393
+ return msg;
1394
+ const parts = msg.content.filter((part) => isDict(part) && !isNativeImagePart(part));
1395
+ const content = !parts.length ? '' : parts.length === 1 && parts[0].type === 'text' ? str(parts[0].text) : parts;
1396
+ return { ...msg, content };
1397
+ });
1398
+ }
1399
+ /**
1400
+ * TAL-545: the image-free history is one request's projection, never the session's. The Agent hands the history it got
1401
+ * back ahead of its own rows, so each row it returned exactly as sent (`sent[i]`, stripped from `original[i]`) is swapped
1402
+ * back for the original; a row the Agent rewrote stays its own.
1403
+ */
1404
+ export function withNativeImagesRestored(rows, sent, original) {
1405
+ if (sent === original)
1406
+ return rows;
1407
+ return rows.map((row, i) => (i < sent.length && sent[i] !== original[i] && JSON.stringify(row) === JSON.stringify(sent[i]) ? original[i] : row));
1408
+ }
1206
1409
  //# sourceMappingURL=merge.js.map