@xopcai/xopc 0.0.158 → 0.0.160

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 (218) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/dashscope/src/image-generation-provider.js +1 -1
  3. package/dist/extensions/fal/src/image-generation-provider.js +1 -1
  4. package/dist/extensions/google/src/image-generation-provider.js +1 -1
  5. package/dist/extensions/telegram/xopc.extension.json +1 -1
  6. package/dist/gateway/static/root/assets/{action-boundary-settings-panel-2p1f4-KA.js → action-boundary-settings-panel-CY3sizqC.js} +1 -1
  7. package/dist/gateway/static/root/assets/{activity-store-C-57rvkX.js → activity-store-3Cso_2qm.js} +1 -1
  8. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BIl6X2b_.js → agent-avatar-dicebear-B_27aaZQ.js} +1 -1
  9. package/dist/gateway/static/root/assets/agents-B1l3iii6.js +2 -0
  10. package/dist/gateway/static/root/assets/{api-BjcBIV2O.js → api-BbzB57CJ.js} +1 -1
  11. package/dist/gateway/static/root/assets/{app-management-settings-panel-CZxw161D.js → app-management-settings-panel-DfmyWcyh.js} +1 -1
  12. package/dist/gateway/static/root/assets/{appearance-settings-CRXNlDhH.js → appearance-settings-B2v0c-K-.js} +1 -1
  13. package/dist/gateway/static/root/assets/apps-page-DaNFLsp0.js +1 -0
  14. package/dist/gateway/static/root/assets/{archive-plugin-CpVshjXu.js → archive-plugin-DL5Lnx0C.js} +1 -1
  15. package/dist/gateway/static/root/assets/{attachment-load-M9WqqJnQ.js → attachment-load-InuP-ZjQ.js} +1 -1
  16. package/dist/gateway/static/root/assets/{automation-suggestion-card-CYMsAsYf.js → automation-suggestion-card-CahGuh7B.js} +1 -1
  17. package/dist/gateway/static/root/assets/automations-page-Cd0gMx6p.js +6 -0
  18. package/dist/gateway/static/root/assets/{binary-plugins-Cjn3zb4u.js → binary-plugins-CdOTGYVu.js} +1 -1
  19. package/dist/gateway/static/root/assets/{block-editor-BPKdquaV.js → block-editor-D6ShK1S-.js} +3 -3
  20. package/dist/gateway/static/root/assets/browser-settings-page-BmUYDL2Z.js +8 -0
  21. package/dist/gateway/static/root/assets/{capability-presets-api-Bzkcsyzn.js → capability-presets-api-BzoLm52Z.js} +1 -1
  22. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-D4rH4Dax.js → capability-presets-settings-panel-CE7mrWtS.js} +2 -2
  23. package/dist/gateway/static/root/assets/{channel-recipient-api-CFqrSi5K.js → channel-recipient-api-DbgydMjl.js} +1 -1
  24. package/dist/gateway/static/root/assets/channels-settings-D1_gcAHK.js +1 -0
  25. package/dist/gateway/static/root/assets/channels-status-swr-Cqfqv59m.js +1 -0
  26. package/dist/gateway/static/root/assets/{connector-logo-ljPKdYKh.js → connector-logo-C3bJC9nt.js} +1 -1
  27. package/dist/gateway/static/root/assets/connectors-page-CaLBi6Na.js +2 -0
  28. package/dist/gateway/static/root/assets/desktop-pet-settings-BrHVvbBw.js +1 -0
  29. package/dist/gateway/static/root/assets/desktop-pet-sprite-CFd1jGLJ.js +1 -0
  30. package/dist/gateway/static/root/assets/desktop-pet-wacrnJJ1.js +1 -0
  31. package/dist/gateway/static/root/assets/{directory-picker-path-field-Dmy1035j.js → directory-picker-path-field-BPI969w-.js} +1 -1
  32. package/dist/gateway/static/root/assets/{dreaming-settings-tT4WkBkd.js → dreaming-settings-iw6QXD45.js} +3 -3
  33. package/dist/gateway/static/root/assets/{extension-debug-page-CL79q8AH.js → extension-debug-page-rCHyhEr6.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-hq80wkFI.js → extension-page-C4gQsAPt.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-BV-9GDfT.js → extension-settings-page-DB_3eik7.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-config-api-CFqoN2NW.js → gateway-config-api-Cdt38iF2.js} +1 -1
  37. package/dist/gateway/static/root/assets/gateway-settings-DM4BgyGw.js +1 -0
  38. package/dist/gateway/static/root/assets/{gateway-startup-retry-cxQ94qMm.js → gateway-startup-retry-ChRFNjj_.js} +1 -1
  39. package/dist/gateway/static/root/assets/goal-create-dialog-BQamcEmF.js +1 -0
  40. package/dist/gateway/static/root/assets/goal-detail-page-DZUQ0Lf1.js +4 -0
  41. package/dist/gateway/static/root/assets/{goals-config-api--qJ4qlRq.js → goals-config-api-RvljeEm6.js} +1 -1
  42. package/dist/gateway/static/root/assets/goals-page-BtxVD27C.js +2 -0
  43. package/dist/gateway/static/root/assets/{goals-settings-h7x9h5lb.js → goals-settings-DMGV4S4L.js} +1 -1
  44. package/dist/gateway/static/root/assets/{heartbeat-settings-71IhhM3s.js → heartbeat-settings-B8r5EXc5.js} +1 -1
  45. package/dist/gateway/static/root/assets/index-CHKe7nwC.js +197 -0
  46. package/dist/gateway/static/root/assets/index-CXhfUIjh.css +1 -0
  47. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-BZGmHvLu.js → keyboard-shortcuts-settings-1-LYibQ4.js} +1 -1
  48. package/dist/gateway/static/root/assets/local-app-workbench-page-CTTfyFe3.js +2 -0
  49. package/dist/gateway/static/root/assets/{local-apps-page-CiLqrMIh.js → local-apps-page-CC4vtUUI.js} +1 -1
  50. package/dist/gateway/static/root/assets/{locale-store-C_M71MK9.js → locale-store-CPbGB_6l.js} +1 -1
  51. package/dist/gateway/static/root/assets/logs-page-Bn_taxBV.js +7 -0
  52. package/dist/gateway/static/root/assets/{markdown-split-r1HPWfCU.js → markdown-split-CprEIf8A.js} +1 -1
  53. package/dist/gateway/static/root/assets/{media-plugins-D74kd3hn.js → media-plugins-BXt_Sj2O.js} +1 -1
  54. package/dist/gateway/static/root/assets/{messages-BuT0SR1R.js → messages-DDsiqdJS.js} +4 -4
  55. package/dist/gateway/static/root/assets/models-hub-panel-DJReXRP9.js +2 -0
  56. package/dist/gateway/static/root/assets/{notes-page-Dgu02514.js → notes-page-Wf5-eyyM.js} +1 -1
  57. package/dist/gateway/static/root/assets/notes-workbench-BbdjzYzs.js +4 -0
  58. package/dist/gateway/static/root/assets/{page-tabs-hinRdDy3.js → page-tabs-dtpK_4Fs.js} +1 -1
  59. package/dist/gateway/static/root/assets/{preview-open-alternatives-C7fw3oGy.js → preview-open-alternatives-DijtEVxG.js} +1 -1
  60. package/dist/gateway/static/root/assets/project-detail-page-BwG8SOzI.js +1 -0
  61. package/dist/gateway/static/root/assets/projects-page-nUlyUtxh.js +1 -0
  62. package/dist/gateway/static/root/assets/remote-access-hub-rf7bjije.js +1 -0
  63. package/dist/gateway/static/root/assets/{save-bar-controls-C3aU8-vO.js → save-bar-controls-qhDisdqY.js} +1 -1
  64. package/dist/gateway/static/root/assets/{schedule-field-DjegExFD.js → schedule-field-AhJ50NoT.js} +1 -1
  65. package/dist/gateway/static/root/assets/{schema-form-DLubnsql.js → schema-form-AuJg2CXU.js} +1 -1
  66. package/dist/gateway/static/root/assets/sessions-page-CSoHUe38.js +1 -0
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-Db976IEa.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-collapsible-section-3syQHsNR.js → settings-collapsible-section-D5ganr_X.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-form-section-D4DCZzKg.js → settings-form-section-Db3cKRsg.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-loading-skeleton-c5K85ylS.js → settings-loading-skeleton-D05YKT2x.js} +1 -1
  71. package/dist/gateway/static/root/assets/{settings-page-DNiDlaRq.js → settings-page-DYfXmfTx.js} +1 -1
  72. package/dist/gateway/static/root/assets/{settings-page-layout-iTRY1Hy-.js → settings-page-layout-Cv_Cu4I5.js} +1 -1
  73. package/dist/gateway/static/root/assets/setup-status-panel-wBWOFpvw.js +1 -0
  74. package/dist/gateway/static/root/assets/{share-preview-page-B88Afrhe.js → share-preview-page-CYkZVuse.js} +1 -1
  75. package/dist/gateway/static/root/assets/shares-settings-BAMma1-P.js +1 -0
  76. package/dist/gateway/static/root/assets/skill-reload-api-TWxFFWxM.js +1 -0
  77. package/dist/gateway/static/root/assets/skills-page-Ca2RA29R.js +2 -0
  78. package/dist/gateway/static/root/assets/{system-settings-panel-DtpTq837.js → system-settings-panel-C1Ng5bXh.js} +1 -1
  79. package/dist/gateway/static/root/assets/{theme-store-C8ohIHhw.js → theme-store-LMHIDR9n.js} +1 -1
  80. package/dist/gateway/static/root/assets/{typed-models-lib-ndEnUP3b.js → typed-models-lib-Ch2Bdm_5.js} +1 -1
  81. package/dist/gateway/static/root/assets/{use-channel-catalog-BWzou5ar.js → use-channel-catalog-CZnaMOeL.js} +1 -1
  82. package/dist/gateway/static/root/assets/user-context-page-CTumZa0y.js +1 -0
  83. package/dist/gateway/static/root/assets/voice-api-key-field-DdlMxeqO.js +1 -0
  84. package/dist/gateway/static/root/assets/work-discovery-page-CcfZhdBi.js +1 -0
  85. package/dist/gateway/static/root/assets/work-item-detail-page--wxLw1p_.js +1 -0
  86. package/dist/gateway/static/root/assets/work-page-DyS0XBpV.js +1 -0
  87. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-ukmpkj66.js → workflow-run-setup-panel-BFk8TvTw.js} +2 -2
  88. package/dist/gateway/static/root/assets/workflows-page-CVVJd4gy.js +11 -0
  89. package/dist/gateway/static/root/index.html +7 -7
  90. package/dist/package.js +1 -1
  91. package/dist/src/agent/embedded/session-tool-result-guard.js +14 -0
  92. package/dist/src/agent/image/generation/openai-compatible-image-provider.js +1 -1
  93. package/dist/src/agent/service/process-direct-streaming.js +1 -1
  94. package/dist/src/agent/tools/image-generate-tool.js +10 -3
  95. package/dist/src/agent/tools/send-media.js +20 -70
  96. package/dist/src/agent/tools/tool-media.d.ts +9 -0
  97. package/dist/src/agent/tools/tool-media.js +58 -0
  98. package/dist/src/automations/service/action-executor.js +1 -1
  99. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  100. package/dist/src/config/agent-profile.js +1 -1
  101. package/dist/src/gateway/agent-run-relay.d.ts +2 -0
  102. package/dist/src/gateway/agent-run-relay.js +114 -14
  103. package/dist/src/gateway/agents-admin.js +1 -1
  104. package/dist/src/gateway/chat-stream/mapper.d.ts +1 -0
  105. package/dist/src/gateway/chat-stream/mapper.js +40 -19
  106. package/dist/src/gateway/chat-stream/thinking-delta-coalescer.d.ts +7 -0
  107. package/dist/src/gateway/chat-stream/thinking-delta-coalescer.js +103 -0
  108. package/dist/src/gateway/hono/routes/home.js +15 -2
  109. package/dist/src/gateway/hono/routes/work-discovery.js +451 -0
  110. package/dist/src/gateway/hono/sse.d.ts +1 -1
  111. package/dist/src/gateway/hono/sse.js +1 -1
  112. package/dist/src/gateway/service/run-gateway-agent.js +5 -1
  113. package/dist/src/gateway/service.d.ts +2 -0
  114. package/dist/src/gateway/service.js +27 -2
  115. package/dist/src/media/session-references.js +9 -6
  116. package/dist/src/mobile/notification-service.js +1 -0
  117. package/dist/src/pets/factory.js +23 -26
  118. package/dist/src/pets/manifest.d.ts +2 -1
  119. package/dist/src/pets/manifest.js +15 -8
  120. package/dist/src/pets/validator.js +8 -3
  121. package/dist/src/proactive/calendar-signals.d.ts +4 -0
  122. package/dist/src/proactive/calendar-signals.js +120 -0
  123. package/dist/src/proactive/focus-service.d.ts +62 -0
  124. package/dist/src/proactive/focus-service.js +173 -0
  125. package/dist/src/proactive/index.d.ts +7 -0
  126. package/dist/src/proactive/index.js +7 -0
  127. package/dist/src/proactive/insight-repository.d.ts +19 -0
  128. package/dist/src/proactive/insight-repository.js +106 -0
  129. package/dist/src/proactive/run-processor.d.ts +19 -0
  130. package/dist/src/proactive/run-processor.js +125 -0
  131. package/dist/src/proactive/trial-expiry-reconciler.d.ts +5 -0
  132. package/dist/src/proactive/trial-expiry-reconciler.js +30 -0
  133. package/dist/src/proactive/types.d.ts +64 -0
  134. package/dist/src/proactive/types.js +1 -0
  135. package/dist/src/proactive/watch-repository.d.ts +28 -0
  136. package/dist/src/proactive/watch-repository.js +129 -0
  137. package/dist/src/session/client-history.d.ts +1 -0
  138. package/dist/src/session/client-history.js +56 -12
  139. package/dist/src/session/types.d.ts +1 -0
  140. package/dist/src/storage/sqlite/knowledge-repository.d.ts +1 -0
  141. package/dist/src/storage/sqlite/knowledge-repository.js +4 -0
  142. package/dist/src/storage/sqlite/migrations/047_work_discovery_sources.sql +16 -0
  143. package/dist/src/storage/sqlite/migrations/048_work_understanding_investigations.sql +40 -0
  144. package/dist/src/storage/sqlite/migrations/049_work_understanding_threads.sql +52 -0
  145. package/dist/src/storage/sqlite/migrations/050_work_discovery_source_refreshes.sql +15 -0
  146. package/dist/src/storage/sqlite/migrations/051_focus_watches.sql +26 -0
  147. package/dist/src/storage/sqlite/migrations/052_proactive_insights.sql +25 -0
  148. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  149. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  150. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  151. package/dist/src/storage/sqlite/schema.js +1 -1
  152. package/dist/src/work-discovery/analyzer.d.ts +12 -1
  153. package/dist/src/work-discovery/analyzer.js +126 -7
  154. package/dist/src/work-discovery/candidate-discovery.d.ts +17 -0
  155. package/dist/src/work-discovery/candidate-discovery.js +279 -0
  156. package/dist/src/work-discovery/evaluation.d.ts +11 -0
  157. package/dist/src/work-discovery/evaluation.js +17 -0
  158. package/dist/src/work-discovery/governance.d.ts +25 -0
  159. package/dist/src/work-discovery/governance.js +96 -0
  160. package/dist/src/work-discovery/incremental-repository.d.ts +13 -0
  161. package/dist/src/work-discovery/incremental-repository.js +55 -0
  162. package/dist/src/work-discovery/incremental.d.ts +2 -0
  163. package/dist/src/work-discovery/incremental.js +7 -0
  164. package/dist/src/work-discovery/index.d.ts +10 -0
  165. package/dist/src/work-discovery/index.js +13 -3
  166. package/dist/src/work-discovery/investigation-repository.d.ts +16 -0
  167. package/dist/src/work-discovery/investigation-repository.js +122 -0
  168. package/dist/src/work-discovery/investigator.d.ts +55 -0
  169. package/dist/src/work-discovery/investigator.js +358 -0
  170. package/dist/src/work-discovery/probe.d.ts +22 -0
  171. package/dist/src/work-discovery/probe.js +88 -1
  172. package/dist/src/work-discovery/service.d.ts +110 -1
  173. package/dist/src/work-discovery/service.js +578 -8
  174. package/dist/src/work-discovery/source-repository.d.ts +13 -0
  175. package/dist/src/work-discovery/source-repository.js +72 -0
  176. package/dist/src/work-discovery/thread-repository.d.ts +34 -0
  177. package/dist/src/work-discovery/thread-repository.js +112 -0
  178. package/dist/src/work-discovery/thread-service.d.ts +8 -0
  179. package/dist/src/work-discovery/thread-service.js +104 -0
  180. package/dist/src/work-discovery/types.d.ts +145 -0
  181. package/package.json +1 -1
  182. package/skills/creative/hatch-pet/SKILL.md +2 -2
  183. package/dist/gateway/static/root/assets/agents-bnkKH9EI.js +0 -2
  184. package/dist/gateway/static/root/assets/apps-page-l4ripRNG.js +0 -1
  185. package/dist/gateway/static/root/assets/automations-page-Kny7tLiF.js +0 -6
  186. package/dist/gateway/static/root/assets/browser-settings-page-vr1tXAab.js +0 -8
  187. package/dist/gateway/static/root/assets/channels-settings-Tlhbi5eh.js +0 -1
  188. package/dist/gateway/static/root/assets/channels-status-swr-vooEF4lG.js +0 -1
  189. package/dist/gateway/static/root/assets/connectors-page-_XfvjXoY.js +0 -2
  190. package/dist/gateway/static/root/assets/desktop-pet-DKUlAgm7.js +0 -1
  191. package/dist/gateway/static/root/assets/desktop-pet-settings-aWWzjdza.js +0 -1
  192. package/dist/gateway/static/root/assets/desktop-pet-sprite-DqZ6fbIj.js +0 -1
  193. package/dist/gateway/static/root/assets/gateway-settings-DzR-kM91.js +0 -1
  194. package/dist/gateway/static/root/assets/goal-create-dialog-BLjHRtqe.js +0 -1
  195. package/dist/gateway/static/root/assets/goal-detail-page-BRxeujXh.js +0 -4
  196. package/dist/gateway/static/root/assets/goals-page-BaZ3aw4u.js +0 -2
  197. package/dist/gateway/static/root/assets/index-EXa_i6BT.js +0 -193
  198. package/dist/gateway/static/root/assets/index-gpwk8Nro.css +0 -1
  199. package/dist/gateway/static/root/assets/local-app-workbench-page-lUpd6lSo.js +0 -2
  200. package/dist/gateway/static/root/assets/logs-page-FPDTmcWe.js +0 -7
  201. package/dist/gateway/static/root/assets/models-hub-panel-BXrdePhv.js +0 -2
  202. package/dist/gateway/static/root/assets/notes-workbench-D-EAhXv1.js +0 -4
  203. package/dist/gateway/static/root/assets/project-detail-page-BjpB1wrp.js +0 -1
  204. package/dist/gateway/static/root/assets/projects-page-BxyjqOfC.js +0 -1
  205. package/dist/gateway/static/root/assets/remote-access-hub-BFv6Upke.js +0 -1
  206. package/dist/gateway/static/root/assets/sessions-page-BX4DH8J7.js +0 -1
  207. package/dist/gateway/static/root/assets/settings-advanced-gate-CJ9MbRP8.js +0 -1
  208. package/dist/gateway/static/root/assets/setup-status-panel-BH4xQKM9.js +0 -1
  209. package/dist/gateway/static/root/assets/shares-settings-B6kKkvOb.js +0 -1
  210. package/dist/gateway/static/root/assets/skill-reload-api-DtjS-nUK.js +0 -1
  211. package/dist/gateway/static/root/assets/skills-page-CQEoPv0u.js +0 -2
  212. package/dist/gateway/static/root/assets/sliding-segmented-uWmrxE3P.js +0 -1
  213. package/dist/gateway/static/root/assets/user-context-page-Dn2T3itn.js +0 -1
  214. package/dist/gateway/static/root/assets/voice-api-key-field-wtWc3SfN.js +0 -1
  215. package/dist/gateway/static/root/assets/work-discovery-page-Ckxhj66e.js +0 -1
  216. package/dist/gateway/static/root/assets/work-item-detail-page-_1QgGPNw.js +0 -1
  217. package/dist/gateway/static/root/assets/work-page-BPdf2iuv.js +0 -1
  218. package/dist/gateway/static/root/assets/workflows-page-DdKTx0Hs.js +0 -11
@@ -11,7 +11,7 @@
11
11
  <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=20260713-1" />
12
12
  <link rel="manifest" href="/site.webmanifest?v=20260713-1" />
13
13
  <title>xopc</title>
14
- <script type="module" crossorigin src="/assets/index-EXa_i6BT.js"></script>
14
+ <script type="module" crossorigin src="/assets/index-CHKe7nwC.js"></script>
15
15
  <link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-aKtaBQYM.js">
16
16
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-zJ_50EbN.js">
17
17
  <link rel="modulepreload" crossorigin href="/assets/vendor-react-BOUWij0V.js">
@@ -24,15 +24,15 @@
24
24
  <link rel="modulepreload" crossorigin href="/assets/check-BODqo66o.js">
25
25
  <link rel="modulepreload" crossorigin href="/assets/circle-alert-RzVebuX2.js">
26
26
  <link rel="modulepreload" crossorigin href="/assets/middleware-Pd0e8Igk.js">
27
- <link rel="modulepreload" crossorigin href="/assets/messages-BuT0SR1R.js">
28
- <link rel="modulepreload" crossorigin href="/assets/locale-store-C_M71MK9.js">
27
+ <link rel="modulepreload" crossorigin href="/assets/messages-DDsiqdJS.js">
28
+ <link rel="modulepreload" crossorigin href="/assets/locale-store-CPbGB_6l.js">
29
29
  <link rel="modulepreload" crossorigin href="/assets/schemas-DgQq6Z5S.js">
30
30
  <link rel="modulepreload" crossorigin href="/assets/config-reload-event-Bjh2zoKp.js">
31
31
  <link rel="modulepreload" crossorigin href="/assets/copy-to-clipboard-HOJ79TWv.js">
32
- <link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-cxQ94qMm.js">
33
- <link rel="modulepreload" crossorigin href="/assets/activity-store-C-57rvkX.js">
34
- <link rel="modulepreload" crossorigin href="/assets/theme-store-C8ohIHhw.js">
35
- <link rel="stylesheet" crossorigin href="/assets/index-gpwk8Nro.css">
32
+ <link rel="modulepreload" crossorigin href="/assets/gateway-startup-retry-ChRFNjj_.js">
33
+ <link rel="modulepreload" crossorigin href="/assets/activity-store-3Cso_2qm.js">
34
+ <link rel="modulepreload" crossorigin href="/assets/theme-store-LMHIDR9n.js">
35
+ <link rel="stylesheet" crossorigin href="/assets/index-CXhfUIjh.css">
36
36
  </head>
37
37
  <body>
38
38
  <div id="root"></div>
package/dist/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "0.0.158";
2
+ var version = "0.0.160";
3
3
  //#endregion
4
4
  export { version };
@@ -173,6 +173,20 @@ function sanitizeToolResultDetailsForPersistence(details) {
173
173
  out.sessions = src.sessions.slice(0, MAX_PERSISTED_DETAIL_SESSION_COUNT).map(sanitizePersistedSessionDetail);
174
174
  if (src.sessions.length > MAX_PERSISTED_DETAIL_SESSION_COUNT) out.sessionsTruncated = src.sessions.length - MAX_PERSISTED_DETAIL_SESSION_COUNT;
175
175
  }
176
+ if (Array.isArray(src.media)) out.media = src.media.slice(0, 12).map((item) => {
177
+ if (!item || typeof item !== "object") return item;
178
+ const media = item;
179
+ return Object.fromEntries([
180
+ "id",
181
+ "bucket",
182
+ "type",
183
+ "mimeType",
184
+ "name",
185
+ "size",
186
+ "uri",
187
+ "path"
188
+ ].filter((key) => media[key] !== void 0).map((key) => [key, media[key]]));
189
+ });
176
190
  return enforcePersistedDetailsByteCap(out, src, originalSize);
177
191
  }
178
192
  function capToolResultDetails(msg) {
@@ -1,11 +1,11 @@
1
1
  import { createLogger } from "../../../utils/logger/index.js";
2
2
  import { init_logger } from "../../../utils/logger.js";
3
+ import { imageAssetFromBase64, imageFileExtensionForMimeType } from "./image-assets.js";
3
4
  import { pickTimeoutMsOrFallback } from "../../../media-shared/http/deadline.js";
4
5
  import { privateNetworkPolicyToSsrfGuardOptions } from "../../../media-shared/http/private-network.js";
5
6
  import { resolveProviderHttpRequestConfig } from "../../../media-shared/http/resolve-provider-http-request-config.js";
6
7
  import { postJsonRequest, postMultipartRequest } from "../../../media-shared/http/provider-http.js";
7
8
  import "../../../media-shared/http/index.js";
8
- import { imageAssetFromBase64, imageFileExtensionForMimeType } from "./image-assets.js";
9
9
  //#region src/agent/image/generation/openai-compatible-image-provider.ts
10
10
  init_logger();
11
11
  const log = createLogger("ImageGen:OpenAICompat");
@@ -102,7 +102,7 @@ function pushAssistantReceipt(queue, text, runId, metadata) {
102
102
  message
103
103
  });
104
104
  queue.push({
105
- type: "message_update",
105
+ type: "assistant_snapshot",
106
106
  runId,
107
107
  message
108
108
  });
@@ -1,7 +1,8 @@
1
1
  import { getAgentDefaultImageGenerationModelConfig, init_schema } from "../../config/schema.js";
2
+ import { imageAssetFromDataUrl, imageFileExtensionForMimeType, mimeTypeFromFileName, parseImageDataUrl, sniffImageMimeType } from "../image/generation/image-assets.js";
3
+ import { persistToolMedia } from "./tool-media.js";
2
4
  import { applyImageGenerationModelConfigDefaults } from "../image/image-helpers.js";
3
5
  import { isFailoverError } from "../failover-error.js";
4
- import { imageAssetFromDataUrl, imageFileExtensionForMimeType, mimeTypeFromFileName, parseImageDataUrl, sniffImageMimeType } from "../image/generation/image-assets.js";
5
6
  import { getImageGenerationProvider } from "../image/generation/provider-registry.js";
6
7
  import { generateImage, listImageGenerationProvidersSummary } from "../image/generation/runtime.js";
7
8
  import path from "node:path";
@@ -174,7 +175,7 @@ function createImageGenerateTool(options) {
174
175
  return {
175
176
  name: "image_generate",
176
177
  label: "Image Generation",
177
- description: "Generate images with the configured image-generation model (default OpenAI). Use action=\"list\" to see providers. Saves files under workspace/media/generated/.",
178
+ description: "Generate and attach images with the configured image-generation model. Use action=\"list\" to see providers. Also saves files under workspace/media/generated/. Do not call send_media for generated images.",
178
179
  parameters: ImageGenerateToolSchema,
179
180
  async execute(_toolCallId, args) {
180
181
  const params = args;
@@ -254,7 +255,12 @@ function createImageGenerateTool(options) {
254
255
  ...filename ? { filenameHint: filename } : {}
255
256
  });
256
257
  const workspaceRelativePaths = paths.map((p) => path.relative(options.workspace, p).split(path.sep).join("/"));
257
- const lines = [`Generated ${paths.length} image(s) with ${result.provider}/${result.model}.`, ...paths.map((p) => `Saved: ${p}`)];
258
+ const media = await Promise.all(result.images.map((image, index) => persistToolMedia({
259
+ buffer: image.buffer,
260
+ filePath: paths[index],
261
+ mediaType: "photo"
262
+ })));
263
+ const lines = [`Generated and attached ${paths.length} image(s) with ${result.provider}/${result.model}.`, ...paths.map((p) => `Saved: ${p}`)];
258
264
  for (const note of buildNormalizationNotes(result.normalization, result.ignoredOverrides)) lines.push(note);
259
265
  return {
260
266
  content: [{
@@ -266,6 +272,7 @@ function createImageGenerateTool(options) {
266
272
  model: result.model,
267
273
  paths,
268
274
  workspaceRelativePaths,
275
+ media,
269
276
  attempts: result.attempts,
270
277
  ...result.normalization ? { normalization: result.normalization } : {},
271
278
  ...result.ignoredOverrides.length > 0 ? { ignoredOverrides: result.ignoredOverrides } : {},
@@ -1,5 +1,6 @@
1
1
  import { checkFileSafety } from "../prompt/safety.js";
2
2
  import { resolvePathUnderWorkspace } from "./tool-paths.js";
3
+ import { persistToolMedia } from "./tool-media.js";
3
4
  import { basename } from "node:path";
4
5
  import { readFile } from "fs/promises";
5
6
  import { Type } from "@sinclair/typebox";
@@ -14,61 +15,6 @@ const SendMediaSchema = Type.Object({
14
15
  }, { description: "Type of media to send (auto-detected if not specified)" })),
15
16
  caption: Type.Optional(Type.String({ description: "Caption for the media" }))
16
17
  });
17
- function detectMediaType(filePath) {
18
- const ext = filePath.split(".").pop()?.toLowerCase();
19
- const imageExts = [
20
- "jpg",
21
- "jpeg",
22
- "png",
23
- "gif",
24
- "webp",
25
- "bmp"
26
- ];
27
- const videoExts = [
28
- "mp4",
29
- "mov",
30
- "avi",
31
- "webm",
32
- "mkv"
33
- ];
34
- const audioExts = [
35
- "mp3",
36
- "wav",
37
- "ogg",
38
- "m4a",
39
- "flac"
40
- ];
41
- if (imageExts.includes(ext || "")) return "photo";
42
- if (videoExts.includes(ext || "")) return "video";
43
- if (audioExts.includes(ext || "")) return "audio";
44
- return "document";
45
- }
46
- function detectMimeType(filePath) {
47
- return {
48
- jpg: "image/jpeg",
49
- jpeg: "image/jpeg",
50
- png: "image/png",
51
- gif: "image/gif",
52
- webp: "image/webp",
53
- bmp: "image/bmp",
54
- svg: "image/svg+xml",
55
- mp4: "video/mp4",
56
- mov: "video/quicktime",
57
- avi: "video/x-msvideo",
58
- webm: "video/webm",
59
- mp3: "audio/mpeg",
60
- wav: "audio/wav",
61
- ogg: "audio/ogg",
62
- m4a: "audio/mp4",
63
- flac: "audio/flac",
64
- pdf: "application/pdf",
65
- doc: "application/msword",
66
- docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
67
- txt: "text/plain",
68
- zip: "application/zip",
69
- rar: "application/x-rar-compressed"
70
- }[filePath.split(".").pop()?.toLowerCase() || ""] || "application/octet-stream";
71
- }
72
18
  function createSendMediaTool(workspace, bus, getContext) {
73
19
  return {
74
20
  name: "send_media",
@@ -95,26 +41,30 @@ function createSendMediaTool(workspace, bus, getContext) {
95
41
  details: {}
96
42
  };
97
43
  try {
98
- const base64 = (await readFile(resolved)).toString("base64");
99
- const mimeType = detectMimeType(resolved);
100
- const mediaType = p.mediaType || detectMediaType(resolved);
101
- const dataUrl = `data:${mimeType};base64,${base64}`;
102
- const msg = {
103
- channel: ctx.channel,
104
- chat_id: ctx.chatId,
105
- content: p.caption || "",
106
- mediaUrl: dataUrl,
107
- mediaType
108
- };
109
- await bus.publishOutbound(msg);
44
+ const fileBuffer = await readFile(resolved);
45
+ const media = await persistToolMedia({
46
+ buffer: fileBuffer,
47
+ filePath: resolved,
48
+ ...p.mediaType ? { mediaType: p.mediaType } : {}
49
+ });
50
+ if (ctx.channel !== "webchat") {
51
+ const msg = {
52
+ channel: ctx.channel,
53
+ chat_id: ctx.chatId,
54
+ content: p.caption || "",
55
+ mediaUrl: `data:${media.mimeType};base64,${fileBuffer.toString("base64")}`,
56
+ mediaType: media.type
57
+ };
58
+ await bus.publishOutbound(msg);
59
+ }
110
60
  return {
111
61
  content: [{
112
62
  type: "text",
113
- text: `✅ Media sent: ${basename(resolved)} (${mediaType})`
63
+ text: `Media attached: ${basename(resolved)} (${media.type})`
114
64
  }],
115
65
  details: {
116
- filePath: resolved,
117
- mediaType
66
+ media: [media],
67
+ ...p.caption ? { caption: p.caption } : {}
118
68
  }
119
69
  };
120
70
  } catch (error) {
@@ -0,0 +1,9 @@
1
+ import type { MediaRef } from '../../media/types.js';
2
+ export type ToolMediaType = 'photo' | 'video' | 'audio' | 'document';
3
+ export declare function detectToolMediaMimeType(buffer: Buffer, filePath: string): string;
4
+ export declare function mediaTypeFromMimeType(mimeType: string): ToolMediaType;
5
+ export declare function persistToolMedia(params: {
6
+ buffer: Buffer;
7
+ filePath: string;
8
+ mediaType?: ToolMediaType;
9
+ }): Promise<MediaRef>;
@@ -0,0 +1,58 @@
1
+ import { sniffImageMimeType } from "../image/generation/image-assets.js";
2
+ import { mimeTypeFromMediaPath, saveMediaBuffer } from "../../media/store.js";
3
+ import { basename } from "node:path";
4
+ //#region src/agent/tools/tool-media.ts
5
+ const MAX_TOOL_MEDIA_BYTES = 50 * 1024 * 1024;
6
+ function hasImageMagic(buffer) {
7
+ if (buffer.length >= 8 && buffer.subarray(0, 8).equals(Buffer.from([
8
+ 137,
9
+ 80,
10
+ 78,
11
+ 71,
12
+ 13,
13
+ 10,
14
+ 26,
15
+ 10
16
+ ]))) return true;
17
+ if (buffer.length >= 3 && buffer.subarray(0, 3).equals(Buffer.from([
18
+ 255,
19
+ 216,
20
+ 255
21
+ ]))) return true;
22
+ if (buffer.length >= 4 && buffer.subarray(0, 4).toString("ascii") === "GIF8") return true;
23
+ return buffer.length >= 12 && buffer.subarray(0, 4).toString("ascii") === "RIFF" && buffer.subarray(8, 12).toString("ascii") === "WEBP";
24
+ }
25
+ function detectToolMediaMimeType(buffer, filePath) {
26
+ if (hasImageMagic(buffer)) return sniffImageMimeType(buffer).mimeType;
27
+ if (buffer.length >= 5 && buffer.subarray(0, 5).toString("ascii") === "%PDF-") return "application/pdf";
28
+ return mimeTypeFromMediaPath(filePath);
29
+ }
30
+ function mediaTypeFromMimeType(mimeType) {
31
+ if (mimeType === "image/svg+xml") return "document";
32
+ if (mimeType.startsWith("image/")) return "photo";
33
+ if (mimeType.startsWith("video/")) return "video";
34
+ if (mimeType.startsWith("audio/")) return "audio";
35
+ return "document";
36
+ }
37
+ async function persistToolMedia(params) {
38
+ const name = basename(params.filePath);
39
+ const mimeType = detectToolMediaMimeType(params.buffer, params.filePath);
40
+ const saved = await saveMediaBuffer(params.buffer, {
41
+ bucket: "outbound",
42
+ contentType: mimeType,
43
+ originalFilename: name,
44
+ maxBytes: MAX_TOOL_MEDIA_BYTES
45
+ });
46
+ return {
47
+ id: saved.id,
48
+ bucket: saved.bucket,
49
+ type: params.mediaType ?? mediaTypeFromMimeType(mimeType),
50
+ mimeType: saved.contentType,
51
+ name,
52
+ size: saved.size,
53
+ uri: saved.uri,
54
+ path: saved.path
55
+ };
56
+ }
57
+ //#endregion
58
+ export { detectToolMediaMimeType, mediaTypeFromMimeType, persistToolMedia };
@@ -84,7 +84,7 @@ var AutomationActionExecutor = class {
84
84
  const model = agentService.getModelForSession?.(sessionKey);
85
85
  return {
86
86
  status: "succeeded",
87
- summary: response.slice(0, 500),
87
+ summary: response.slice(0, 4e3),
88
88
  sessionKey,
89
89
  model
90
90
  };
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
52
52
  id: "database-schema",
53
53
  label: "Database schema",
54
54
  status: "pass",
55
- message: `SQLite schema v${status.dbVersion} (current release v46).`,
55
+ message: `SQLite schema v${status.dbVersion} (current release v52).`,
56
56
  hints: []
57
57
  };
58
58
  }
@@ -1,6 +1,6 @@
1
+ import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
1
2
  import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
2
3
  import "../agent-manifest/index.js";
3
- import { init_agent_scope, normalizeAgentId, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
4
4
  import { init_session_key, parseSessionKey } from "../routing/session-key.js";
5
5
  import { agentExists, getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
6
6
  //#region src/config/agent-profile.ts
@@ -7,7 +7,9 @@ export type RelayEvent = {
7
7
  type: string;
8
8
  } & Record<string, unknown>;
9
9
  export declare class AgentRunRelay {
10
+ private readonly maxEvents;
10
11
  private runs;
12
+ constructor(maxEvents?: number);
11
13
  ensureRun(runId: string, sessionKey: string): void;
12
14
  getSessionKey(runId: string): string | undefined;
13
15
  hasRun(runId: string): boolean;
@@ -5,8 +5,84 @@ init_logger();
5
5
  const log = createLogger("Gateway:AgentRunRelay");
6
6
  const COMPLETE_TTL_MS = 5 * 6e4;
7
7
  const MAX_EVENTS = 8e3;
8
+ const COMPACT_TO_RATIO = .75;
9
+ const MAX_MERGED_DELTA_CHARS = 16 * 1024;
10
+ const REPLAY_DELTA_TYPES = new Set([
11
+ "assistant_delta",
12
+ "thinking_delta",
13
+ "command_output_delta",
14
+ "review_delta"
15
+ ]);
16
+ function eventSeq(event) {
17
+ return typeof event.seq === "number" ? event.seq : void 0;
18
+ }
19
+ function findEventAtOrAfter(events, seq) {
20
+ let low = 0;
21
+ let high = events.length;
22
+ while (low < high) {
23
+ const middle = low + Math.floor((high - low) / 2);
24
+ if ((eventSeq(events[middle]) ?? Number.MAX_SAFE_INTEGER) < seq) low = middle + 1;
25
+ else high = middle;
26
+ }
27
+ return events[low];
28
+ }
29
+ function recordValue(value) {
30
+ return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
31
+ }
32
+ function sameDeltaStream(left, right) {
33
+ if (left.type !== right.type || !REPLAY_DELTA_TYPES.has(left.type)) return false;
34
+ const leftPayload = recordValue(left.payload);
35
+ const rightPayload = recordValue(right.payload);
36
+ if (!leftPayload || !rightPayload) return false;
37
+ return [
38
+ "messageId",
39
+ "toolCallId",
40
+ "reviewId",
41
+ "stream"
42
+ ].every((key) => leftPayload[key] === rightPayload[key]);
43
+ }
44
+ function mergeReplayDelta(events, event) {
45
+ const previous = events.at(-1);
46
+ if (!previous || !sameDeltaStream(previous, event)) return false;
47
+ const previousPayload = recordValue(previous.payload);
48
+ const payload = recordValue(event.payload);
49
+ const previousDelta = previousPayload?.delta;
50
+ const delta = payload?.delta;
51
+ if (typeof previousDelta !== "string" || typeof delta !== "string") return false;
52
+ if (previousDelta.length + delta.length > MAX_MERGED_DELTA_CHARS) return false;
53
+ events[events.length - 1] = {
54
+ ...previous,
55
+ payload: {
56
+ ...previousPayload,
57
+ delta: previousDelta + delta
58
+ }
59
+ };
60
+ return true;
61
+ }
62
+ function compactEvents(events, targetSize) {
63
+ let remaining = Math.max(0, events.length - targetSize);
64
+ const retained = [];
65
+ const removedByType = {};
66
+ for (const event of events) {
67
+ if (remaining > 0 && REPLAY_DELTA_TYPES.has(event.type)) {
68
+ remaining -= 1;
69
+ removedByType[event.type] = (removedByType[event.type] ?? 0) + 1;
70
+ continue;
71
+ }
72
+ retained.push(event);
73
+ }
74
+ if (remaining > 0) for (const event of retained.splice(0, remaining)) removedByType[event.type] = (removedByType[event.type] ?? 0) + 1;
75
+ return {
76
+ events: retained,
77
+ removedByType
78
+ };
79
+ }
8
80
  var AgentRunRelay = class {
9
81
  runs = /* @__PURE__ */ new Map();
82
+ constructor(maxEvents = MAX_EVENTS) {
83
+ this.maxEvents = maxEvents;
84
+ if (!Number.isInteger(maxEvents) || maxEvents < 2) throw new Error("AgentRunRelay maxEvents must be an integer greater than 1");
85
+ }
10
86
  ensureRun(runId, sessionKey) {
11
87
  if (this.runs.has(runId)) return;
12
88
  this.runs.set(runId, {
@@ -14,7 +90,9 @@ var AgentRunRelay = class {
14
90
  events: [],
15
91
  nextSeq: 1,
16
92
  done: false,
17
- waiters: []
93
+ waiters: [],
94
+ subscriberCount: 0,
95
+ compactionWarned: false
18
96
  });
19
97
  }
20
98
  getSessionKey(runId) {
@@ -31,12 +109,22 @@ var AgentRunRelay = class {
31
109
  runId,
32
110
  seq: state.nextSeq++
33
111
  };
34
- if (state.events.length >= MAX_EVENTS) log.warn({
35
- runId,
36
- max: MAX_EVENTS,
37
- droppedType: relayed.type
38
- }, "Relay buffer full; dropping event (resume may miss tool_end/tokens)");
39
- else state.events.push(relayed);
112
+ const merged = state.subscriberCount === 0 && mergeReplayDelta(state.events, relayed);
113
+ if (!merged && state.events.length >= this.maxEvents) {
114
+ const targetSize = Math.max(1, Math.floor(this.maxEvents * COMPACT_TO_RATIO));
115
+ const compacted = compactEvents(state.events, targetSize);
116
+ state.events = compacted.events;
117
+ if (!state.compactionWarned) {
118
+ state.compactionWarned = true;
119
+ log.warn({
120
+ runId,
121
+ max: this.maxEvents,
122
+ retained: state.events.length,
123
+ removedByType: compacted.removedByType
124
+ }, "Relay replay buffer compacted; old delta events are no longer resumable");
125
+ }
126
+ }
127
+ if (!merged) state.events.push(relayed);
40
128
  const waiters = state.waiters.splice(0);
41
129
  for (const w of waiters) w();
42
130
  return relayed;
@@ -55,13 +143,25 @@ var AgentRunRelay = class {
55
143
  async *subscribe(runId) {
56
144
  const state = this.runs.get(runId);
57
145
  if (!state) throw new Error("UNKNOWN_RUN");
58
- let cursor = 0;
59
- while (true) {
60
- while (cursor < state.events.length) yield state.events[cursor++];
61
- if (state.done) break;
62
- await new Promise((resolve) => {
63
- state.waiters.push(resolve);
64
- });
146
+ state.subscriberCount += 1;
147
+ try {
148
+ let nextSeq = eventSeq(state.events[0]) ?? state.nextSeq;
149
+ while (true) {
150
+ const earliestSeq = eventSeq(state.events[0]);
151
+ if (earliestSeq !== void 0 && nextSeq < earliestSeq) nextSeq = earliestSeq;
152
+ const available = findEventAtOrAfter(state.events, nextSeq);
153
+ if (available) {
154
+ nextSeq = (eventSeq(available) ?? nextSeq) + 1;
155
+ yield available;
156
+ continue;
157
+ }
158
+ if (state.done) break;
159
+ await new Promise((resolve) => {
160
+ state.waiters.push(resolve);
161
+ });
162
+ }
163
+ } finally {
164
+ state.subscriberCount -= 1;
65
165
  }
66
166
  }
67
167
  };
@@ -1,5 +1,5 @@
1
- import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
2
1
  import { init_agent_scope, listAgentEntries, normalizeAgentId, resolveAgentDir, resolveAgentProfileDir, resolveAgentWorkspaceDir, resolveDefaultAgentId, resolveUserPath, validateAgentIdForNewAgent } from "../agent/agent-scope.js";
2
+ import { resolveEffectiveAgentManifest } from "../agent-manifest/resolver.js";
3
3
  import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
4
4
  import { WORKSPACE_FILES, init_paths, resolveUserProfilePath } from "../config/paths.js";
5
5
  import { AGENT_PROFILE_MARKDOWN_SYSTEM_FILES, REQUIRED_AGENT_PROFILE_MARKDOWN_FILE_SET } from "../agent/context/workspace.js";
@@ -30,6 +30,7 @@ export declare class ChatStreamMapper {
30
30
  error(message: string, code?: string): ChatStreamEvent[];
31
31
  private mapMessageStart;
32
32
  private mapMessageUpdate;
33
+ private mapAssistantSnapshot;
33
34
  private mapMessageEnd;
34
35
  private mapToolStart;
35
36
  private mapToolUpdate;
@@ -23,6 +23,7 @@ var ChatStreamMapper = class {
23
23
  case "agent_end": return [];
24
24
  case "message_start": return this.mapMessageStart(event.message);
25
25
  case "message_update": return this.mapMessageUpdate(event);
26
+ case "assistant_snapshot": return this.mapAssistantSnapshot(event.message);
26
27
  case "message_end": return this.mapMessageEnd(event.message);
27
28
  case "tool_execution_start": return this.mapToolStart(event);
28
29
  case "tool_execution_update": return this.mapToolUpdate(event);
@@ -44,7 +45,7 @@ var ChatStreamMapper = class {
44
45
  status: event.status === "error" ? "error" : "complete",
45
46
  ...typeof event.message === "string" && event.message ? { message: event.message } : {}
46
47
  })];
47
- case "user_message": return [this.make("user_message", { message: userMessageFromLegacyEvent(event) })];
48
+ case "user_message": return [this.make("user_message", { message: userMessageFromEvent(event) })];
48
49
  case "user_transcript": return [this.make("user_transcript", {
49
50
  text: String(event.text ?? ""),
50
51
  media: event.media
@@ -155,40 +156,60 @@ var ChatStreamMapper = class {
155
156
  const message = event.message;
156
157
  if (message?.role !== "assistant") return [];
157
158
  const messageId = this.ensureAssistantMessageId();
159
+ const events = [];
158
160
  const review = extractReview(message);
159
161
  if (review && !this.currentAssistantReviewEmitted) {
160
162
  this.currentAssistantReviewEmitted = true;
161
- return [this.make("review", {
163
+ events.push(this.make("review", {
162
164
  messageId,
163
165
  review
164
- })];
166
+ }));
165
167
  }
166
168
  const delta = event.assistantMessageEvent;
167
169
  if (delta?.type === "text_delta" && typeof delta.delta === "string" && delta.delta) {
170
+ events.push(this.make("assistant_delta", {
171
+ messageId,
172
+ delta: delta.delta
173
+ }));
174
+ this.currentAssistantText += delta.delta;
175
+ }
176
+ if (delta?.type === "thinking_delta" && typeof delta.delta === "string" && delta.delta) events.push(this.make("thinking_delta", {
177
+ messageId,
178
+ delta: delta.delta
179
+ }));
180
+ if (!delta) {
168
181
  const text = extractTextFromMessage(message);
169
- const suffixFromMessage = appendSuffix(this.currentAssistantText, text);
170
- const suffix = text ? suffixFromMessage : appendSuffix(this.currentAssistantText, delta.delta);
171
- if (!suffix) {
172
- if (text) this.currentAssistantText = text;
173
- return [];
182
+ const suffix = appendSuffix(this.currentAssistantText, text);
183
+ if (suffix) {
184
+ events.push(this.make("assistant_delta", {
185
+ messageId,
186
+ delta: suffix
187
+ }));
188
+ this.currentAssistantText = text || `${this.currentAssistantText}${suffix}`;
174
189
  }
175
- this.currentAssistantText = text || `${this.currentAssistantText}${suffix}`;
176
- return [this.make("assistant_delta", {
190
+ }
191
+ return events;
192
+ }
193
+ mapAssistantSnapshot(raw) {
194
+ const message = raw;
195
+ if (message?.role !== "assistant") return [];
196
+ const messageId = this.ensureAssistantMessageId();
197
+ const review = extractReview(message);
198
+ if (review && !this.currentAssistantReviewEmitted) {
199
+ this.currentAssistantReviewEmitted = true;
200
+ return [this.make("review", {
177
201
  messageId,
178
- delta: suffix
202
+ review
179
203
  })];
180
204
  }
181
- if (delta?.type === "thinking_delta" && typeof delta.delta === "string" && delta.delta) return [this.make("thinking_delta", {
182
- messageId,
183
- delta: delta.delta
184
- })];
185
205
  const text = extractTextFromMessage(message);
186
206
  const suffix = appendSuffix(this.currentAssistantText, text);
187
- this.currentAssistantText = text || this.currentAssistantText;
188
- return suffix ? [this.make("assistant_delta", {
207
+ if (!suffix) return [];
208
+ this.currentAssistantText = text || `${this.currentAssistantText}${suffix}`;
209
+ return [this.make("assistant_delta", {
189
210
  messageId,
190
211
  delta: suffix
191
- })] : [];
212
+ })];
192
213
  }
193
214
  mapMessageEnd(raw) {
194
215
  const message = raw;
@@ -368,7 +389,7 @@ var ChatStreamMapper = class {
368
389
  }
369
390
  }
370
391
  };
371
- function userMessageFromLegacyEvent(event) {
392
+ function userMessageFromEvent(event) {
372
393
  return {
373
394
  role: "user",
374
395
  content: event.content ?? [],
@@ -0,0 +1,7 @@
1
+ import type { ChatStreamEvent } from './protocol.js';
2
+ type CoalescerOptions = {
3
+ windowMs?: number;
4
+ maxChars?: number;
5
+ };
6
+ export declare function coalesceThinkingDeltas(source: AsyncIterable<ChatStreamEvent>, options?: CoalescerOptions): AsyncGenerator<ChatStreamEvent>;
7
+ export {};