@agent-native/core 0.98.3 → 0.98.5

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 (230) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +29 -0
  3. package/corpus/core/docs/content/durable-background-runs.mdx +37 -0
  4. package/corpus/core/docs/content/locales/ar-SA/tracking.mdx +2 -0
  5. package/corpus/core/docs/content/locales/de-DE/tracking.mdx +2 -0
  6. package/corpus/core/docs/content/locales/es-ES/tracking.mdx +2 -0
  7. package/corpus/core/docs/content/locales/fr-FR/tracking.mdx +4 -2
  8. package/corpus/core/docs/content/locales/hi-IN/tracking.mdx +2 -0
  9. package/corpus/core/docs/content/locales/ja-JP/tracking.mdx +2 -0
  10. package/corpus/core/docs/content/locales/ko-KR/tracking.mdx +2 -0
  11. package/corpus/core/docs/content/locales/pt-BR/tracking.mdx +2 -0
  12. package/corpus/core/docs/content/locales/zh-CN/tracking.mdx +2 -0
  13. package/corpus/core/docs/content/locales/zh-TW/durable-background-runs.mdx +14 -0
  14. package/corpus/core/docs/content/locales/zh-TW/tracking.mdx +2 -0
  15. package/corpus/core/docs/content/tracking.mdx +2 -0
  16. package/corpus/core/package.json +1 -1
  17. package/corpus/core/src/agent/durable-background.ts +16 -16
  18. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +25 -8
  19. package/corpus/core/src/agent/engine/anthropic-engine.ts +17 -3
  20. package/corpus/core/src/agent/engine/output-tokens.ts +6 -6
  21. package/corpus/core/src/agent/production-agent.ts +200 -27
  22. package/corpus/core/src/agent/run-manager.ts +81 -1
  23. package/corpus/core/src/agent/run-store.ts +301 -41
  24. package/corpus/core/src/client/AgentPanel.tsx +6 -2
  25. package/corpus/core/src/client/AssistantChat.tsx +364 -69
  26. package/corpus/core/src/client/agent-chat-adapter.ts +169 -1
  27. package/corpus/core/src/client/analytics.ts +12 -0
  28. package/corpus/core/src/client/chat/message-components.tsx +3 -0
  29. package/corpus/core/src/client/chat/tool-call-display.tsx +20 -36
  30. package/corpus/core/src/client/conversation/use-near-bottom-autoscroll.ts +7 -0
  31. package/corpus/core/src/client/extensions/AgentNativeExtensionFrame.tsx +2 -0
  32. package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +2 -0
  33. package/corpus/core/src/client/extensions/ExtensionEditor.tsx +9 -2
  34. package/corpus/core/src/client/extensions/ExtensionViewer.tsx +2 -0
  35. package/corpus/core/src/client/extensions/InlineExtensionFrame.tsx +2 -0
  36. package/corpus/core/src/client/extensions/portable-extension.ts +2 -0
  37. package/corpus/core/src/client/session-replay.ts +971 -53
  38. package/corpus/core/src/client/settings/DemoModeSection.tsx +3 -3
  39. package/corpus/core/src/client/sse-event-processor.ts +43 -1
  40. package/corpus/core/src/demo/actions/toggle-demo-mode.ts +2 -2
  41. package/corpus/core/src/demo/config.ts +6 -6
  42. package/corpus/core/src/demo/fetch-interceptor.ts +34 -2
  43. package/corpus/core/src/demo/redact.ts +71 -158
  44. package/corpus/core/src/extensions/html-shell.ts +3 -0
  45. package/corpus/core/src/extensions/session-replay-iframe.ts +131 -0
  46. package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +1 -20
  47. package/corpus/core/src/session-replay-iframe-protocol.ts +58 -0
  48. package/corpus/core/src/shared/reasoning-effort.ts +35 -0
  49. package/corpus/core/src/styles/agent-conversation.css +26 -0
  50. package/corpus/core/src/templates/workspace-core/.agents/skills/observability/SKILL.md +0 -15
  51. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +67 -16
  52. package/corpus/templates/analytics/AGENTS.md +12 -0
  53. package/corpus/templates/analytics/actions/get-error-issue.ts +1 -0
  54. package/corpus/templates/analytics/actions/get-session-replay-events.ts +1 -0
  55. package/corpus/templates/analytics/actions/get-session-replay-summary.ts +1 -0
  56. package/corpus/templates/analytics/actions/list-error-issues.ts +1 -0
  57. package/corpus/templates/analytics/actions/list-session-recordings.ts +1 -0
  58. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +2 -1
  59. package/corpus/templates/analytics/app/global.css +6 -64
  60. package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +41 -4
  61. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +143 -121
  62. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +34 -12
  63. package/corpus/templates/analytics/changelog/2026-07-12-analytics-chat-retries-before-showing-a-generic-no-data-mess.md +6 -0
  64. package/corpus/templates/analytics/changelog/2026-07-12-analytics-sessions-search-no-longer-loses-fast-keystrokes-an.md +6 -0
  65. package/corpus/templates/analytics/changelog/2026-07-12-chart-selection-respects-chat-state.md +6 -0
  66. package/corpus/templates/analytics/changelog/2026-07-12-demo-mode-anonymizes-error-reporting-emails.md +6 -0
  67. package/corpus/templates/analytics/changelog/2026-07-12-fixed-session-replays-that-appeared-ultra-wide-hid-recorded-.md +6 -0
  68. package/corpus/templates/analytics/changelog/2026-07-12-session-replays-load-faster-in-demo-mode-while-visitor-email.md +6 -0
  69. package/corpus/templates/analytics/changelog/2026-07-12-session-replays-show-iframe-content.md +6 -0
  70. package/corpus/templates/analytics/netlify.toml +0 -3
  71. package/corpus/templates/analytics/server/lib/analytics-connector-catalog.ts +14 -0
  72. package/corpus/templates/analytics/server/lib/error-capture.ts +59 -2
  73. package/corpus/templates/analytics/server/lib/real-data-actions.ts +24 -0
  74. package/corpus/templates/analytics/server/lib/session-replay.ts +2 -9
  75. package/corpus/templates/analytics/server/plugins/agent-chat.ts +39 -6
  76. package/corpus/templates/assets/app/global.css +1 -1
  77. package/corpus/templates/brain/app/global.css +2 -2
  78. package/corpus/templates/brain/changelog/2026-07-12-fix-long-response-progress.md +6 -0
  79. package/corpus/templates/calendar/app/components/calendar/DeleteEventDialog.tsx +11 -2
  80. package/corpus/templates/calendar/app/components/calendar/EventAttendeesSection.tsx +14 -2
  81. package/corpus/templates/calendar/changelog/2026-07-12-calendar-responses-can-now-be-saved-with-command-enter-or-ct.md +6 -0
  82. package/corpus/templates/forms/app/components/CloudUpgrade.tsx +1 -1
  83. package/corpus/templates/forms/app/components/ThemeToggle.tsx +22 -6
  84. package/corpus/templates/forms/app/components/builder/FieldPropertiesPanel.tsx +5 -5
  85. package/corpus/templates/forms/app/components/builder/FieldRenderer.tsx +3 -3
  86. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +16 -16
  87. package/corpus/templates/forms/app/global.css +110 -5
  88. package/corpus/templates/forms/app/pages/AskPage.tsx +3 -3
  89. package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +134 -52
  90. package/corpus/templates/forms/app/pages/FormFillPage.tsx +44 -11
  91. package/corpus/templates/forms/app/pages/FormsListPage.tsx +42 -24
  92. package/corpus/templates/forms/app/pages/ResponseInsightsPage.tsx +28 -15
  93. package/corpus/templates/forms/app/pages/ResponsesPage.tsx +38 -15
  94. package/corpus/templates/forms/app/routes/_app.settings.tsx +1 -1
  95. package/corpus/templates/forms/changelog/2026-07-12-form-builder-surfaces-are-calmer-fields-stay-stable-on-hover.md +6 -0
  96. package/corpus/templates/forms/changelog/2026-07-12-smoother-more-tactile-controls-throughout-animated-icon-and-.md +6 -0
  97. package/corpus/templates/mail/app/components/email/EmailThread.tsx +21 -13
  98. package/corpus/templates/mail/app/components/email/email-iframe-document.ts +18 -0
  99. package/dist/agent/durable-background.d.ts +10 -10
  100. package/dist/agent/durable-background.d.ts.map +1 -1
  101. package/dist/agent/durable-background.js +16 -16
  102. package/dist/agent/durable-background.js.map +1 -1
  103. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  104. package/dist/agent/engine/ai-sdk-engine.js +19 -8
  105. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  106. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  107. package/dist/agent/engine/anthropic-engine.js +11 -3
  108. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  109. package/dist/agent/engine/output-tokens.js +6 -6
  110. package/dist/agent/engine/output-tokens.js.map +1 -1
  111. package/dist/agent/production-agent.d.ts +52 -0
  112. package/dist/agent/production-agent.d.ts.map +1 -1
  113. package/dist/agent/production-agent.js +154 -26
  114. package/dist/agent/production-agent.js.map +1 -1
  115. package/dist/agent/run-manager.d.ts +9 -0
  116. package/dist/agent/run-manager.d.ts.map +1 -1
  117. package/dist/agent/run-manager.js +71 -1
  118. package/dist/agent/run-manager.js.map +1 -1
  119. package/dist/agent/run-store.d.ts +9 -0
  120. package/dist/agent/run-store.d.ts.map +1 -1
  121. package/dist/agent/run-store.js +243 -48
  122. package/dist/agent/run-store.js.map +1 -1
  123. package/dist/client/AgentPanel.d.ts.map +1 -1
  124. package/dist/client/AgentPanel.js +6 -2
  125. package/dist/client/AgentPanel.js.map +1 -1
  126. package/dist/client/AssistantChat.d.ts +21 -0
  127. package/dist/client/AssistantChat.d.ts.map +1 -1
  128. package/dist/client/AssistantChat.js +298 -67
  129. package/dist/client/AssistantChat.js.map +1 -1
  130. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  131. package/dist/client/agent-chat-adapter.js +146 -1
  132. package/dist/client/agent-chat-adapter.js.map +1 -1
  133. package/dist/client/analytics.d.ts.map +1 -1
  134. package/dist/client/analytics.js +11 -0
  135. package/dist/client/analytics.js.map +1 -1
  136. package/dist/client/chat/message-components.d.ts.map +1 -1
  137. package/dist/client/chat/message-components.js +2 -1
  138. package/dist/client/chat/message-components.js.map +1 -1
  139. package/dist/client/chat/tool-call-display.d.ts +3 -1
  140. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  141. package/dist/client/chat/tool-call-display.js +13 -37
  142. package/dist/client/chat/tool-call-display.js.map +1 -1
  143. package/dist/client/conversation/use-near-bottom-autoscroll.d.ts +1 -0
  144. package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -1
  145. package/dist/client/conversation/use-near-bottom-autoscroll.js +6 -0
  146. package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -1
  147. package/dist/client/extensions/AgentNativeExtensionFrame.d.ts.map +1 -1
  148. package/dist/client/extensions/AgentNativeExtensionFrame.js +2 -1
  149. package/dist/client/extensions/AgentNativeExtensionFrame.js.map +1 -1
  150. package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
  151. package/dist/client/extensions/EmbeddedExtension.js +2 -1
  152. package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
  153. package/dist/client/extensions/ExtensionEditor.d.ts.map +1 -1
  154. package/dist/client/extensions/ExtensionEditor.js +5 -2
  155. package/dist/client/extensions/ExtensionEditor.js.map +1 -1
  156. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  157. package/dist/client/extensions/ExtensionViewer.js +2 -1
  158. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  159. package/dist/client/extensions/InlineExtensionFrame.d.ts.map +1 -1
  160. package/dist/client/extensions/InlineExtensionFrame.js +2 -1
  161. package/dist/client/extensions/InlineExtensionFrame.js.map +1 -1
  162. package/dist/client/extensions/portable-extension.d.ts.map +1 -1
  163. package/dist/client/extensions/portable-extension.js +2 -0
  164. package/dist/client/extensions/portable-extension.js.map +1 -1
  165. package/dist/client/session-replay.d.ts +12 -3
  166. package/dist/client/session-replay.d.ts.map +1 -1
  167. package/dist/client/session-replay.js +793 -49
  168. package/dist/client/session-replay.js.map +1 -1
  169. package/dist/client/settings/DemoModeSection.js +1 -1
  170. package/dist/client/settings/DemoModeSection.js.map +1 -1
  171. package/dist/client/sse-event-processor.d.ts +5 -0
  172. package/dist/client/sse-event-processor.d.ts.map +1 -1
  173. package/dist/client/sse-event-processor.js +37 -1
  174. package/dist/client/sse-event-processor.js.map +1 -1
  175. package/dist/demo/actions/toggle-demo-mode.js +2 -2
  176. package/dist/demo/actions/toggle-demo-mode.js.map +1 -1
  177. package/dist/demo/config.js +6 -6
  178. package/dist/demo/config.js.map +1 -1
  179. package/dist/demo/fetch-interceptor.d.ts +1 -0
  180. package/dist/demo/fetch-interceptor.d.ts.map +1 -1
  181. package/dist/demo/fetch-interceptor.js +28 -2
  182. package/dist/demo/fetch-interceptor.js.map +1 -1
  183. package/dist/demo/redact.d.ts +14 -7
  184. package/dist/demo/redact.d.ts.map +1 -1
  185. package/dist/demo/redact.js +27 -155
  186. package/dist/demo/redact.js.map +1 -1
  187. package/dist/extensions/html-shell.d.ts.map +1 -1
  188. package/dist/extensions/html-shell.js +2 -0
  189. package/dist/extensions/html-shell.js.map +1 -1
  190. package/dist/extensions/session-replay-iframe.d.ts +10 -0
  191. package/dist/extensions/session-replay-iframe.d.ts.map +1 -0
  192. package/dist/extensions/session-replay-iframe.js +121 -0
  193. package/dist/extensions/session-replay-iframe.js.map +1 -0
  194. package/dist/notifications/routes.d.ts +1 -1
  195. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  196. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  197. package/dist/scripts/agent-engines/list-agent-engines.js +1 -19
  198. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  199. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  200. package/dist/server/transcribe-voice.d.ts +1 -1
  201. package/dist/session-replay-iframe-protocol.d.ts +36 -0
  202. package/dist/session-replay-iframe-protocol.d.ts.map +1 -0
  203. package/dist/session-replay-iframe-protocol.js +24 -0
  204. package/dist/session-replay-iframe-protocol.js.map +1 -0
  205. package/dist/shared/reasoning-effort.d.ts +11 -0
  206. package/dist/shared/reasoning-effort.d.ts.map +1 -1
  207. package/dist/shared/reasoning-effort.js +36 -0
  208. package/dist/shared/reasoning-effort.js.map +1 -1
  209. package/dist/styles/agent-conversation.css +26 -0
  210. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +0 -15
  211. package/docs/content/durable-background-runs.mdx +37 -0
  212. package/docs/content/locales/ar-SA/tracking.mdx +2 -0
  213. package/docs/content/locales/de-DE/tracking.mdx +2 -0
  214. package/docs/content/locales/es-ES/tracking.mdx +2 -0
  215. package/docs/content/locales/fr-FR/tracking.mdx +4 -2
  216. package/docs/content/locales/hi-IN/tracking.mdx +2 -0
  217. package/docs/content/locales/ja-JP/tracking.mdx +2 -0
  218. package/docs/content/locales/ko-KR/tracking.mdx +2 -0
  219. package/docs/content/locales/pt-BR/tracking.mdx +2 -0
  220. package/docs/content/locales/zh-CN/tracking.mdx +2 -0
  221. package/docs/content/locales/zh-TW/durable-background-runs.mdx +14 -0
  222. package/docs/content/locales/zh-TW/tracking.mdx +2 -0
  223. package/docs/content/tracking.mdx +2 -0
  224. package/package.json +2 -2
  225. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +0 -15
  226. package/corpus/core/src/observability/hosted-model-experiment.ts +0 -118
  227. package/dist/observability/hosted-model-experiment.d.ts +0 -39
  228. package/dist/observability/hosted-model-experiment.d.ts.map +0 -1
  229. package/dist/observability/hosted-model-experiment.js +0 -90
  230. package/dist/observability/hosted-model-experiment.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"agent-chat-adapter.d.ts","sourceRoot":"","sources":["../../src/client/agent-chat-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,qBAAqB,CAAC;AAWhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAmBrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,MAAM,oBAAoB;AAC9B;;;;GAIG;AACD,KAAK;AACP,0EAA0E;GACxE,WAAW;AACb,wEAAwE;GACtE,SAAS,CAAC;AAwId,eAAO,MAAM,iCAAiC,SAAU,CAAC;AA6nCzD;;;;GAIG;AACH;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC3C,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC5C,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,eAAe,GAAG,SAAS,CAAA;KAAE,CAAC;IACrD,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAA;KAAE,CAAC;IAC3D,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC;AAyED,wBAAgB,sBAAsB,CACpC,OAAO,CAAC,EAAE,6BAA6B,GACtC,gBAAgB,CA6iElB"}
1
+ {"version":3,"file":"agent-chat-adapter.d.ts","sourceRoot":"","sources":["../../src/client/agent-chat-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,qBAAqB,CAAC;AAWhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAmBrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,MAAM,oBAAoB;AAC9B;;;;GAIG;AACD,KAAK;AACP,0EAA0E;GACxE,WAAW;AACb,wEAAwE;GACtE,SAAS,CAAC;AAwId,eAAO,MAAM,iCAAiC,SAAU,CAAC;AAmrCzD;;;;GAIG;AACH;;;GAGG;AACH,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC3C,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IAC5C,SAAS,CAAC,EAAE;QAAE,OAAO,EAAE,eAAe,GAAG,SAAS,CAAA;KAAE,CAAC;IACrD,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAC;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE;QAAE,OAAO,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,CAAA;KAAE,CAAC;IAC3D,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC;AAyED,wBAAgB,sBAAsB,CACpC,OAAO,CAAC,EAAE,6BAA6B,GACtC,gBAAgB,CA+pElB"}
@@ -118,6 +118,15 @@ const BACKGROUND_FOLLOW_POLL_INTERVAL_MS = 1_000;
118
118
  // agent-chat-plugin.ts) instead, and keep this comment's inequality chain
119
119
  // accurate if any of the four numbers change.
120
120
  export const BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS = 150_000;
121
+ // A re-observed terminal run whose outcome would be an ERROR (never a
122
+ // genuine "done" success) gets a short extra grace window before the follow
123
+ // loop surfaces it: the server's dead-run recovery can reap a lost
124
+ // background run and insert a claimable successor a beat after the client
125
+ // first sees the stale terminal row. Deliberately much shorter than
126
+ // BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS — this exists to absorb that narrow
127
+ // insert-latency race, not to mask a genuinely lost run behind a long hang
128
+ // before the user sees an error.
129
+ const BACKGROUND_TERMINAL_ERROR_GRACE_POLLS = 5;
121
130
  /**
122
131
  * User-facing copy for the server's background terminal reasons
123
132
  * (`agent_runs.terminal_reason`, surfaced by /runs/active). These runs died in
@@ -135,6 +144,46 @@ const BACKGROUND_TERMINAL_REASON_MESSAGES = {
135
144
  missing_credentials: LLM_MISSING_CREDENTIALS_MESSAGE,
136
145
  turn_continuation_budget_exhausted: "This request needed more automatic continuations than allowed and was stopped. Try breaking it into smaller steps.",
137
146
  };
147
+ /**
148
+ * `agent_runs.terminal_reason` values that mark a CHUNK boundary, not the end
149
+ * of the turn — `markBackgroundContinuationChunkTerminal` (production-agent.ts)
150
+ * writes status "completed" with one of these bare reasons whenever a
151
+ * background chunk ends at a continuation boundary (mirrors
152
+ * `AgentLoopContinuationReason` there). A run in this state is expected to be
153
+ * replaced by a server-chained successor row; it must never be read as "the
154
+ * turn is done" just because its own row says `status: "completed"`.
155
+ */
156
+ const BACKGROUND_CONTINUATION_TERMINAL_REASONS = new Set([
157
+ "run_timeout",
158
+ "loop_limit",
159
+ "max_tokens",
160
+ "stream_ended",
161
+ "gateway_timeout",
162
+ "network_interrupted",
163
+ "no_progress",
164
+ ]);
165
+ /**
166
+ * True when the given `/runs/active` snapshot, if surfaced as a background
167
+ * terminal outcome right now, would render as an error rather than a
168
+ * successful completion. Mirrors `emitBackgroundTerminalOutcome`'s own
169
+ * mappedMessage/hasErrorTerminalReason/status branching (kept in sync with
170
+ * it) so callers can decide whether an error-surfacing grace window applies
171
+ * BEFORE actually emitting anything.
172
+ */
173
+ function isBackgroundTerminalErrorOutcome(lastKnown) {
174
+ const status = typeof lastKnown?.status === "string" ? lastKnown.status : "";
175
+ const rawTerminalReason = typeof lastKnown?.terminalReason === "string"
176
+ ? lastKnown.terminalReason
177
+ : "";
178
+ const hasErrorTerminalReason = rawTerminalReason.startsWith("error:");
179
+ const terminalReason = rawTerminalReason.replace(/^error:/, "");
180
+ const mappedMessage = terminalReason
181
+ ? BACKGROUND_TERMINAL_REASON_MESSAGES[terminalReason]
182
+ : undefined;
183
+ if (mappedMessage || hasErrorTerminalReason)
184
+ return true;
185
+ return status !== "completed";
186
+ }
138
187
  function normalizeMentions(text) {
139
188
  return text.replace(/@\[([^\]|]+)\|[^\]]+\]/g, "@$1");
140
189
  }
@@ -1918,6 +1967,44 @@ export function createAgentChatAdapter(options) {
1918
1967
  }
1919
1968
  };
1920
1969
  dispatchResumingUiEvent();
1970
+ // Before surfacing a background terminal ERROR (never called for a
1971
+ // genuine "done" success — see call site), give the server's
1972
+ // reap-and-recover path a short extra window to insert a claimable
1973
+ // successor row for this turn. Returns as soon as `/runs/active`
1974
+ // reports a DIFFERENT runId than the stale one, so the caller can
1975
+ // hand back to the main loop and follow it seamlessly instead of
1976
+ // erroring out from under it.
1977
+ const awaitBackgroundErrorRecoverySuccessor = async (staleRunId) => {
1978
+ for (let attempt = 0; attempt < BACKGROUND_TERMINAL_ERROR_GRACE_POLLS; attempt++) {
1979
+ if (abortSignal.aborted)
1980
+ return "aborted";
1981
+ dispatchResumingUiEvent();
1982
+ await delay(BACKGROUND_FOLLOW_POLL_INTERVAL_MS, abortSignal);
1983
+ if (abortSignal.aborted)
1984
+ return "aborted";
1985
+ let recheck = null;
1986
+ try {
1987
+ const activeRes = await fetch(`${apiUrl}/runs/active?threadId=${encodeURIComponent(threadId)}`, { signal: abortSignal });
1988
+ if (activeRes.ok) {
1989
+ recheck = await activeRes.json().catch(() => null);
1990
+ }
1991
+ }
1992
+ catch (pollErr) {
1993
+ if (pollErr instanceof Error && pollErr.name === "AbortError") {
1994
+ return "aborted";
1995
+ }
1996
+ // Transient poll failure — this attempt counts as "no
1997
+ // successor yet", not a hard failure of the grace window.
1998
+ }
1999
+ const recheckRunId = recheck?.active === true && recheck.runId
2000
+ ? String(recheck.runId)
2001
+ : null;
2002
+ if (recheckRunId && recheckRunId !== staleRunId) {
2003
+ return "successor";
2004
+ }
2005
+ }
2006
+ return "timeout";
2007
+ };
1921
2008
  let idleSince = null;
1922
2009
  let lastSeenActive = null;
1923
2010
  // Terminal runs already replayed once. A recoverable terminal error
@@ -1925,7 +2012,10 @@ export function createAgentChatAdapter(options) {
1925
2012
  // which used to re-drive a POST in foreground mode. In follow mode
1926
2013
  // the server owns recovery, so a SECOND visit to the same terminal
1927
2014
  // run means the turn is over — surface the outcome instead of
1928
- // re-replaying it every poll for the whole reconnect window.
2015
+ // re-replaying it every poll for the whole reconnect window. (A
2016
+ // CONTINUATION-class terminal_reason is the one exception: see the
2017
+ // isContinuationChunkBoundary check below, which keeps polling
2018
+ // instead of surfacing anything.)
1929
2019
  const replayedTerminalRunIds = new Set();
1930
2020
  while (true) {
1931
2021
  if (abortSignal.aborted) {
@@ -1975,6 +2065,54 @@ export function createAgentChatAdapter(options) {
1975
2065
  return "client_continue";
1976
2066
  }
1977
2067
  }
2068
+ const rawTerminalReason = typeof active?.terminalReason === "string"
2069
+ ? active.terminalReason
2070
+ : "";
2071
+ const bareTerminalReason = rawTerminalReason.replace(/^error:/, "");
2072
+ // A re-observed "completed" row with a CONTINUATION-class
2073
+ // reason (run_timeout/no_progress/loop_limit/…) is a MID-TURN
2074
+ // chunk boundary, not the end of the turn — a warm instance
2075
+ // can keep serving this stale row for a beat before the
2076
+ // pre-inserted successor becomes visible. Emitting a terminal
2077
+ // outcome here is exactly the bug this branch exists to
2078
+ // avoid: it would flip the message to "done" while the
2079
+ // successor's content is still coming. Keep polling on the
2080
+ // shared idle budget instead; a truly stuck handoff still
2081
+ // fails loud (never a silent stop) once it expires.
2082
+ const isContinuationChunkBoundary = activeStatus === "completed" &&
2083
+ !rawTerminalReason.startsWith("error:") &&
2084
+ !BACKGROUND_TERMINAL_REASON_MESSAGES[bareTerminalReason] &&
2085
+ BACKGROUND_CONTINUATION_TERMINAL_REASONS.has(bareTerminalReason);
2086
+ if (isContinuationChunkBoundary) {
2087
+ if (idleSince === null)
2088
+ idleSince = Date.now();
2089
+ if (Date.now() - idleSince >=
2090
+ BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS) {
2091
+ yield* emitBackgroundTerminalError({
2092
+ message: "The agent's background run stopped between chunks and no continuation appeared. You can retry from the preserved chat context.",
2093
+ errorCode: "background_run_lost",
2094
+ details: `terminal_reason: ${rawTerminalReason}`,
2095
+ });
2096
+ return "completed";
2097
+ }
2098
+ dispatchResumingUiEvent();
2099
+ await delay(BACKGROUND_FOLLOW_POLL_INTERVAL_MS, abortSignal);
2100
+ continue;
2101
+ }
2102
+ if (isBackgroundTerminalErrorOutcome(active)) {
2103
+ const graceOutcome = await awaitBackgroundErrorRecoverySuccessor(activeRunId);
2104
+ if (graceOutcome === "aborted") {
2105
+ clearActiveRun();
2106
+ return "completed";
2107
+ }
2108
+ if (graceOutcome === "successor") {
2109
+ // A successor claimed the turn while we waited — hand
2110
+ // back to the top of the loop so it attaches and follows
2111
+ // it exactly like any other newly-discovered run instead
2112
+ // of duplicating that bookkeeping here.
2113
+ continue;
2114
+ }
2115
+ }
1978
2116
  yield* emitBackgroundTerminalOutcome(active);
1979
2117
  return "completed";
1980
2118
  }
@@ -2031,6 +2169,13 @@ export function createAgentChatAdapter(options) {
2031
2169
  dispatchResumingUiEvent();
2032
2170
  }
2033
2171
  else {
2172
+ // No active run visible for this turn yet (the gap between a
2173
+ // chunk ending and the successor becoming pollable). Refresh
2174
+ // the "Resuming…" bridge on every tick here too — not just
2175
+ // when an active run IS visible — so the client's own
2176
+ // isAutoResuming window can't lapse into a false-idle UI while
2177
+ // this loop is still confidently waiting out its own budget.
2178
+ dispatchResumingUiEvent();
2034
2179
  if (idleSince === null)
2035
2180
  idleSince = Date.now();
2036
2181
  if (Date.now() - idleSince >= BACKGROUND_FOLLOW_IDLE_TIMEOUT_MS) {