@agent-native/core 0.119.3 → 0.119.4

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 (217) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +13 -0
  3. package/corpus/core/package.json +3 -3
  4. package/corpus/core/src/agent/production-agent.ts +107 -125
  5. package/corpus/core/src/agent/run-manager.ts +45 -2
  6. package/corpus/core/src/agent/thread-data-builder.ts +85 -8
  7. package/corpus/core/src/client/AssistantChat.tsx +37 -9
  8. package/corpus/core/src/client/chat/message-components.tsx +9 -1
  9. package/corpus/core/src/client/chat/repo-helpers.ts +77 -0
  10. package/corpus/core/src/client/chat/tool-call-display.tsx +51 -15
  11. package/corpus/core/src/server/agent-chat/framework-prompts.ts +3 -1
  12. package/corpus/core/src/server/agent-chat/plugin-options.ts +9 -0
  13. package/corpus/core/src/server/agent-chat-plugin.ts +12 -3
  14. package/corpus/core/src/templates/chat/.agents/skills/actions/SKILL.md +512 -0
  15. package/corpus/core/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +189 -0
  16. package/corpus/core/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +115 -0
  17. package/corpus/core/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +177 -0
  18. package/corpus/core/src/templates/chat/.agents/skills/capture-learnings/SKILL.md +89 -0
  19. package/corpus/core/src/templates/chat/.agents/skills/create-skill/SKILL.md +221 -0
  20. package/corpus/core/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +220 -0
  21. package/corpus/core/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +263 -0
  22. package/corpus/core/src/templates/chat/.agents/skills/feature-flags/SKILL.md +169 -0
  23. package/corpus/core/src/templates/chat/.agents/skills/frontend-design/SKILL.md +160 -0
  24. package/corpus/core/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +232 -0
  25. package/corpus/core/src/templates/chat/.agents/skills/security/SKILL.md +280 -0
  26. package/corpus/core/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +118 -0
  27. package/corpus/core/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +119 -0
  28. package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +100 -0
  29. package/corpus/core/src/templates/chat/.env.example +5 -0
  30. package/corpus/core/src/templates/chat/.ignore +0 -0
  31. package/corpus/core/src/templates/chat/.oxfmtrc.json +8 -0
  32. package/corpus/core/src/templates/chat/AGENTS.md +69 -0
  33. package/corpus/core/src/templates/chat/CHANGELOG.md +10 -0
  34. package/corpus/core/src/templates/chat/DEVELOPING.md +185 -0
  35. package/corpus/core/src/templates/chat/README.md +32 -0
  36. package/corpus/core/src/templates/chat/_gitignore +43 -0
  37. package/corpus/core/src/templates/chat/actions/hello.ts +13 -0
  38. package/corpus/core/src/templates/chat/actions/navigate.ts +41 -0
  39. package/corpus/core/src/templates/chat/actions/run.ts +2 -0
  40. package/corpus/core/src/templates/chat/actions/view-screen.ts +31 -0
  41. package/corpus/core/src/templates/chat/app/components/layout/Header.tsx +60 -0
  42. package/corpus/core/src/templates/chat/app/components/layout/Layout.tsx +185 -0
  43. package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +450 -0
  44. package/corpus/core/src/templates/chat/app/components/ui/button.tsx +1 -0
  45. package/corpus/core/src/templates/chat/app/components/ui/card.tsx +1 -0
  46. package/corpus/core/src/templates/chat/app/components/ui/dropdown-menu.tsx +1 -0
  47. package/corpus/core/src/templates/chat/app/components/ui/input.tsx +1 -0
  48. package/corpus/core/src/templates/chat/app/components/ui/label.tsx +1 -0
  49. package/corpus/core/src/templates/chat/app/components/ui/sheet.tsx +1 -0
  50. package/corpus/core/src/templates/chat/app/components/ui/toolkit-provider.tsx +17 -0
  51. package/corpus/core/src/templates/chat/app/components/ui/tooltip.tsx +1 -0
  52. package/corpus/core/src/templates/chat/app/design-system.ts +3 -0
  53. package/corpus/core/src/templates/chat/app/entry.client.tsx +19 -0
  54. package/corpus/core/src/templates/chat/app/entry.server.tsx +10 -0
  55. package/corpus/core/src/templates/chat/app/global.css +93 -0
  56. package/corpus/core/src/templates/chat/app/hooks/use-navigation-state.ts +93 -0
  57. package/corpus/core/src/templates/chat/app/i18n/ar-SA.ts +68 -0
  58. package/corpus/core/src/templates/chat/app/i18n/de-DE.ts +71 -0
  59. package/corpus/core/src/templates/chat/app/i18n/en-US.ts +70 -0
  60. package/corpus/core/src/templates/chat/app/i18n/es-ES.ts +71 -0
  61. package/corpus/core/src/templates/chat/app/i18n/fr-FR.ts +71 -0
  62. package/corpus/core/src/templates/chat/app/i18n/hi-IN.ts +69 -0
  63. package/corpus/core/src/templates/chat/app/i18n/index.ts +34 -0
  64. package/corpus/core/src/templates/chat/app/i18n/ja-JP.ts +70 -0
  65. package/corpus/core/src/templates/chat/app/i18n/ko-KR.ts +70 -0
  66. package/corpus/core/src/templates/chat/app/i18n/pt-BR.ts +71 -0
  67. package/corpus/core/src/templates/chat/app/i18n/zh-CN.ts +66 -0
  68. package/corpus/core/src/templates/chat/app/i18n/zh-TW.ts +66 -0
  69. package/corpus/core/src/templates/chat/app/i18n-data.ts +556 -0
  70. package/corpus/core/src/templates/chat/app/lib/agent-page.tsx +49 -0
  71. package/corpus/core/src/templates/chat/app/lib/app-config.ts +11 -0
  72. package/corpus/core/src/templates/chat/app/lib/tab-id.ts +1 -0
  73. package/corpus/core/src/templates/chat/app/lib/utils.ts +1 -0
  74. package/corpus/core/src/templates/chat/app/root.tsx +173 -0
  75. package/corpus/core/src/templates/chat/app/routes/_index.tsx +94 -0
  76. package/corpus/core/src/templates/chat/app/routes/agent.tsx +24 -0
  77. package/corpus/core/src/templates/chat/app/routes/chat.$threadId.tsx +1 -0
  78. package/corpus/core/src/templates/chat/app/routes/database.tsx +17 -0
  79. package/corpus/core/src/templates/chat/app/routes/extensions.$id.$slug.tsx +2 -0
  80. package/corpus/core/src/templates/chat/app/routes/extensions.$id.tsx +11 -0
  81. package/corpus/core/src/templates/chat/app/routes/extensions._index.tsx +11 -0
  82. package/corpus/core/src/templates/chat/app/routes/extensions.tsx +5 -0
  83. package/corpus/core/src/templates/chat/app/routes/observability.tsx +19 -0
  84. package/corpus/core/src/templates/chat/app/routes/settings.tsx +89 -0
  85. package/corpus/core/src/templates/chat/app/routes/team.tsx +11 -0
  86. package/corpus/core/src/templates/chat/app/routes.ts +4 -0
  87. package/corpus/core/src/templates/chat/app/vite-env.d.ts +6 -0
  88. package/corpus/core/src/templates/chat/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
  89. package/corpus/core/src/templates/chat/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  90. package/corpus/core/src/templates/chat/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
  91. package/corpus/core/src/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  92. package/corpus/core/src/templates/chat/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  93. package/corpus/core/src/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  94. package/corpus/core/src/templates/chat/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +6 -0
  95. package/corpus/core/src/templates/chat/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  96. package/corpus/core/src/templates/chat/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +6 -0
  97. package/corpus/core/src/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
  98. package/corpus/core/src/templates/chat/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +6 -0
  99. package/corpus/core/src/templates/chat/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  100. package/corpus/core/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  101. package/corpus/core/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  102. package/corpus/core/src/templates/chat/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  103. package/corpus/core/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  104. package/corpus/core/src/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
  105. package/corpus/core/src/templates/chat/components.json +20 -0
  106. package/corpus/core/src/templates/chat/learnings.defaults.md +5 -0
  107. package/corpus/core/src/templates/chat/netlify.toml +10 -0
  108. package/corpus/core/src/templates/chat/package.json +92 -0
  109. package/corpus/core/src/templates/chat/public/agent-native-icon-dark.svg +10 -0
  110. package/corpus/core/src/templates/chat/public/agent-native-icon-light.svg +10 -0
  111. package/corpus/core/src/templates/chat/public/agent-native-logo-dark.svg +21 -0
  112. package/corpus/core/src/templates/chat/public/agent-native-logo-light.svg +21 -0
  113. package/corpus/core/src/templates/chat/public/favicon.svg +1 -0
  114. package/corpus/core/src/templates/chat/public/icon-180.svg +1 -0
  115. package/corpus/core/src/templates/chat/public/icon-192.svg +1 -0
  116. package/corpus/core/src/templates/chat/public/icon-512.svg +1 -0
  117. package/corpus/core/src/templates/chat/public/manifest.json +21 -0
  118. package/corpus/core/src/templates/chat/react-router.config.ts +7 -0
  119. package/corpus/core/src/templates/chat/server/middleware/auth.ts +15 -0
  120. package/corpus/core/src/templates/chat/server/plugins/agent-chat.ts +21 -0
  121. package/corpus/core/src/templates/chat/server/plugins/auth.ts +17 -0
  122. package/corpus/core/src/templates/chat/server/routes/[...page].get.ts +5 -0
  123. package/corpus/core/src/templates/chat/ssr-entry.ts +15 -0
  124. package/corpus/core/src/templates/chat/tsconfig.json +21 -0
  125. package/corpus/core/src/templates/chat/vite.config.ts +19 -0
  126. package/corpus/templates/analytics/AGENTS.md +19 -11
  127. package/corpus/templates/analytics/actions/list-data-dictionary.ts +3 -1
  128. package/corpus/templates/analytics/actions/save-data-dictionary-entry.ts +14 -0
  129. package/corpus/templates/analytics/actions/search-analytics-query-catalog.ts +41 -0
  130. package/corpus/templates/analytics/app/components/dashboard/DashboardPanelSkeleton.tsx +13 -0
  131. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +12 -11
  132. package/corpus/templates/analytics/app/pages/adhoc/DashboardSkeleton.tsx +3 -3
  133. package/corpus/templates/analytics/changelog/2026-07-23-dashboard-chart-loading-placeholders-are-easier-to-see-in-da.md +6 -0
  134. package/corpus/templates/analytics/changelog/2026-07-23-routine-analytics-lookups-reuse-existing-query-definitions.md +6 -0
  135. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +1 -12
  136. package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +405 -0
  137. package/corpus/templates/analytics/server/plugins/agent-chat.ts +11 -16
  138. package/corpus/templates/content/changelog/2026-07-23-database-toolbar-sort-and-filter-controls-open-reliably.md +6 -0
  139. package/corpus/templates/forms/app/lib/public-form-link.ts +14 -0
  140. package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +6 -14
  141. package/corpus/templates/forms/changelog/2026-07-23-published-form-links-can-be-copied-without-being-asked-to-re.md +6 -0
  142. package/corpus/templates/mail/changelog/2026-07-23-scheduled-emails-now-send-only-once-when-multiple-requests-r.md +6 -0
  143. package/corpus/templates/mail/server/lib/jobs.ts +13 -4
  144. package/corpus/templates/mail/server/plugins/mail-jobs.ts +1 -1
  145. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +7 -18
  146. package/corpus/templates/slides/app/lib/agent-visible-message.ts +28 -0
  147. package/corpus/templates/slides/app/pages/Index.tsx +6 -34
  148. package/corpus/templates/slides/changelog/2026-07-23-full-prompts-stay-visible-in-chat-when-creating-decks-or-add.md +6 -0
  149. package/corpus/toolkit/CHANGELOG.md +13 -0
  150. package/corpus/toolkit/package.json +1 -1
  151. package/corpus/toolkit/src/editor/SharedRichEditor.tsx +23 -2
  152. package/corpus/toolkit/src/editor/SlashCommandMenu.tsx +68 -2
  153. package/corpus/toolkit/src/editor/index.ts +1 -0
  154. package/corpus/toolkit/src/editor.css +75 -0
  155. package/corpus/toolkit/src/ui/button.tsx +3 -2
  156. package/dist/agent/production-agent.d.ts.map +1 -1
  157. package/dist/agent/production-agent.js +96 -115
  158. package/dist/agent/production-agent.js.map +1 -1
  159. package/dist/agent/run-manager.d.ts +9 -1
  160. package/dist/agent/run-manager.d.ts.map +1 -1
  161. package/dist/agent/run-manager.js +26 -0
  162. package/dist/agent/run-manager.js.map +1 -1
  163. package/dist/agent/thread-data-builder.d.ts +2 -0
  164. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  165. package/dist/agent/thread-data-builder.js +69 -9
  166. package/dist/agent/thread-data-builder.js.map +1 -1
  167. package/dist/client/AssistantChat.d.ts.map +1 -1
  168. package/dist/client/AssistantChat.js +32 -10
  169. package/dist/client/AssistantChat.js.map +1 -1
  170. package/dist/client/chat/message-components.d.ts +2 -1
  171. package/dist/client/chat/message-components.d.ts.map +1 -1
  172. package/dist/client/chat/message-components.js +9 -3
  173. package/dist/client/chat/message-components.js.map +1 -1
  174. package/dist/client/chat/repo-helpers.d.ts +4 -0
  175. package/dist/client/chat/repo-helpers.d.ts.map +1 -1
  176. package/dist/client/chat/repo-helpers.js +61 -0
  177. package/dist/client/chat/repo-helpers.js.map +1 -1
  178. package/dist/client/chat/tool-call-display.d.ts +2 -1
  179. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  180. package/dist/client/chat/tool-call-display.js +10 -9
  181. package/dist/client/chat/tool-call-display.js.map +1 -1
  182. package/dist/collab/routes.d.ts +1 -1
  183. package/dist/notifications/routes.d.ts +1 -1
  184. package/dist/observability/routes.d.ts +5 -5
  185. package/dist/progress/routes.d.ts +1 -1
  186. package/dist/provider-api/actions/custom-provider-registration.d.ts +7 -7
  187. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  188. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  189. package/dist/resources/handlers.d.ts +1 -1
  190. package/dist/secrets/routes.d.ts +9 -9
  191. package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
  192. package/dist/server/agent-chat/framework-prompts.js +3 -1
  193. package/dist/server/agent-chat/framework-prompts.js.map +1 -1
  194. package/dist/server/agent-chat/plugin-options.d.ts +9 -0
  195. package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
  196. package/dist/server/agent-chat/plugin-options.js.map +1 -1
  197. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  198. package/dist/server/agent-chat-plugin.js +11 -2
  199. package/dist/server/agent-chat-plugin.js.map +1 -1
  200. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  201. package/dist/server/realtime-token.d.ts +1 -1
  202. package/dist/server/transcribe-voice.d.ts +1 -1
  203. package/package.json +4 -4
  204. package/src/agent/production-agent.ts +107 -125
  205. package/src/agent/run-manager.ts +45 -2
  206. package/src/agent/thread-data-builder.ts +85 -8
  207. package/src/client/AssistantChat.tsx +37 -9
  208. package/src/client/chat/message-components.tsx +9 -1
  209. package/src/client/chat/repo-helpers.ts +77 -0
  210. package/src/client/chat/tool-call-display.tsx +51 -15
  211. package/src/server/agent-chat/framework-prompts.ts +3 -1
  212. package/src/server/agent-chat/plugin-options.ts +9 -0
  213. package/src/server/agent-chat-plugin.ts +12 -3
  214. package/src/templates/chat/actions/hello.spec.ts +0 -23
  215. package/src/templates/chat/actions/navigate.spec.ts +0 -68
  216. package/src/templates/chat/actions/view-screen.spec.ts +0 -40
  217. package/src/templates/chat/app/lib/agent-page.spec.tsx +0 -61
@@ -5881,17 +5881,6 @@ export function createProductionAgentHandler(options) {
5881
5881
  metadata: trackedProgressMetadata ?? undefined,
5882
5882
  }).catch(() => { });
5883
5883
  }
5884
- // The background worker must AWAIT the run to completion before returning,
5885
- // or Netlify freezes/kills the function the instant the handler returns and
5886
- // the detached run dies mid-turn (mirrors the agent-teams processor, which
5887
- // wraps startRun in `await new Promise(resolve => startRun(..., onComplete:
5888
- // () => resolve()))`). We resolve this when the run's onComplete fires.
5889
- let resolveBackgroundRunDone = null;
5890
- const backgroundRunDone = isBackgroundWorker
5891
- ? new Promise((resolve) => {
5892
- resolveBackgroundRunDone = resolve;
5893
- })
5894
- : null;
5895
5884
  const baseHandleRunComplete = options.onRunComplete || trackedProgressRunId
5896
5885
  ? async (run) => {
5897
5886
  try {
@@ -5904,109 +5893,103 @@ export function createProductionAgentHandler(options) {
5904
5893
  await completeTrackedProgressRun(run);
5905
5894
  }
5906
5895
  : undefined;
5907
- // Wrap so the background worker is unblocked even when there is no app
5908
- // onRunComplete / tracked-progress callback configured. Also installed for
5909
- // a foreground run eligible for self-chain that path needs this same
5910
- // wrapper to fire the continuation dispatch below.
5896
+ // Install the completion callback for background continuation even when
5897
+ // there is no app onRunComplete / tracked-progress callback configured.
5898
+ // The foreground self-chain path uses the same continuation dispatch.
5911
5899
  const handleRunComplete = isBackgroundWorker || foregroundSelfChainEligible || baseHandleRunComplete
5912
5900
  ? async (run) => {
5913
- try {
5914
- // DIAGNOSTIC: a background worker that completed in an errored
5915
- // state threw inside the loop. Record it (with the last error
5916
- // event's message when available) so the failure cause is
5917
- // readable from the client. Skipped for clean completions and for
5918
- // recoverable soft-timeout boundaries (those chain a continuation
5919
- // below, they did not "throw").
5920
- if (isBackgroundWorker &&
5921
- run.status === "errored" &&
5922
- !willChainBackgroundContinuation(run)) {
5923
- const errEvent = [...run.events]
5924
- .reverse()
5925
- .find((e) => e.event.type === "error")?.event;
5926
- await recordRunDiagnostic(run.runId, RUN_DIAG_STAGE.workerThrew, errEvent?.errorCode || errEvent?.error
5927
- ? `${errEvent.errorCode ?? ""} ${errEvent.error ?? ""}`.trim()
5928
- : "run ended in errored state").catch(() => { });
5929
- }
5930
- // Persist the (partial) assistant turn to thread_data FIRST — the
5931
- // server-driven continuation below rebuilds from it, so it must be
5932
- // committed before we re-fire.
5933
- await baseHandleRunComplete?.(run);
5934
- // Server-driven background→background continuation. If this chunk
5935
- // hit its soft-timeout still unfinished (ended at an auto_continue
5936
- // / loop_limit / recoverable boundary), chain the next chunk by
5937
- // re-firing the `_process-run` self-dispatch with mode "continue"
5938
- // (carried as internalContinuation + an incremented count),
5939
- // instead of relying on the client to re-POST. Mirrors the
5940
- // agent-teams `fireInternalDispatch({ body: { mode: "continue" }})`
5941
- // chain. Bounded by MAX_BACKGROUND_RUN_CONTINUATIONS. Aborted /
5942
- // user-stopped runs do NOT chain.
5943
- // Self-chain server-side for EVERY durable worker, not only the
5944
- // ones inside a `-background` function. Server-driven
5945
- // continuation is the whole point of durable background: the run
5946
- // must survive the client disconnecting (closed tab), so it
5947
- // cannot depend on the browser re-POSTing `auto_continue`. A
5948
- // worker on the regular ~60s function — a Netlify routing miss,
5949
- // or a non-Netlify host (Vercel/Cloudflare/Render/Fly) that
5950
- // never emits a `-background` function — checkpoints at the 40s
5951
- // soft-timeout and self-dispatches the next 40s chunk; a worker
5952
- // in a real `-background` function chains ~13-min chunks. Only
5953
- // the per-chunk BUDGET differs by function type (gated by
5954
- // `runsInBackgroundFunction` at the startRun call below); the
5955
- // continuation itself must stay server-driven on both. (The
5956
- // self-chain is only reachable when the initial dispatch already
5957
- // succeeded — a dispatch fast-fail degrades to the inline
5958
- // foreground fallback, which is not a worker and rides the
5959
- // connected client's auto_continue instead.)
5960
- if (willChainBackgroundContinuation(run)) {
5961
- // Full handoff discipline lives in
5962
- // `chainServerDrivenContinuation` (exported + unit-tested):
5963
- // per-turn SQL run budget, successor row PRE-INSERTED before
5964
- // the dispatch, fully awaited dispatch with retries, loud
5965
- // diag/terminal marking on failure. Never throws.
5966
- await chainServerDrivenContinuation({
5967
- event,
5968
- run,
5969
- effectiveThreadId,
5970
- effectiveTurnId,
5971
- requestBody: body,
5972
- backgroundContinuationCount,
5973
- // Re-evaluate the durable gate rather than keying off
5974
- // isBackgroundWorker: a successor chunk of a FOREGROUND
5975
- // self-chain re-enters as a worker too, and must keep
5976
- // chaining via the regular function — the Netlify
5977
- // `-background` function is only emitted into the deploy
5978
- // output when the durable flag is on.
5979
- //
5980
- // `&& !runsInBackgroundFunction`: a worker PROVEN to already
5981
- // be executing inside the real `-background` function must
5982
- // never dispatch back to that same function's own URL — a
5983
- // background function invoking itself by URL from inside a
5984
- // live invocation is a documented Netlify platform
5985
- // limitation (404), unlike the initial foreground→background
5986
- // dispatch or a worker that landed on the regular function
5987
- // (a genuinely different function calling the background
5988
- // one, which works). This only changes the dispatch TARGET
5989
- // for that one proven-in-bg-function case — by this point
5990
- // (with the in-process resumable-error resume above) it is
5991
- // reached only when the chunk genuinely exhausted its
5992
- // budget, so falling back to the regular `_process-run`
5993
- // function (40s clamp) here is the correct, safe target.
5994
- chainViaDurableBackground: isAgentChatDurableBackgroundEnabled({
5995
- appOptIn: options.durableBackgroundRuns,
5996
- }) && !runsInBackgroundFunction,
5997
- // Only changes the retry BUDGET, never the dispatch target
5998
- // above: a worker proven in a real background function has
5999
- // minutes of remaining wall clock and no connected-client
6000
- // fallback, so it must not be demoted to the foreground's
6001
- // 2-attempt budget just because it was forced onto the
6002
- // regular-function dispatch target. See
6003
- // `resolveContinuationDispatchBudget`.
6004
- workerProvenInBackgroundFunction: runsInBackgroundFunction,
6005
- });
6006
- }
5901
+ // DIAGNOSTIC: a background worker that completed in an errored
5902
+ // state threw inside the loop. Record it (with the last error
5903
+ // event's message when available) so the failure cause is
5904
+ // readable from the client. Skipped for clean completions and for
5905
+ // recoverable soft-timeout boundaries (those chain a continuation
5906
+ // below, they did not "throw").
5907
+ if (isBackgroundWorker &&
5908
+ run.status === "errored" &&
5909
+ !willChainBackgroundContinuation(run)) {
5910
+ const errEvent = [...run.events]
5911
+ .reverse()
5912
+ .find((e) => e.event.type === "error")?.event;
5913
+ await recordRunDiagnostic(run.runId, RUN_DIAG_STAGE.workerThrew, errEvent?.errorCode || errEvent?.error
5914
+ ? `${errEvent.errorCode ?? ""} ${errEvent.error ?? ""}`.trim()
5915
+ : "run ended in errored state").catch(() => { });
6007
5916
  }
6008
- finally {
6009
- resolveBackgroundRunDone?.();
5917
+ // Persist the (partial) assistant turn to thread_data FIRST — the
5918
+ // server-driven continuation below rebuilds from it, so it must be
5919
+ // committed before we re-fire.
5920
+ await baseHandleRunComplete?.(run);
5921
+ // Server-driven background→background continuation. If this chunk
5922
+ // hit its soft-timeout still unfinished (ended at an auto_continue
5923
+ // / loop_limit / recoverable boundary), chain the next chunk by
5924
+ // re-firing the `_process-run` self-dispatch with mode "continue"
5925
+ // (carried as internalContinuation + an incremented count),
5926
+ // instead of relying on the client to re-POST. Mirrors the
5927
+ // agent-teams `fireInternalDispatch({ body: { mode: "continue" }})`
5928
+ // chain. Bounded by MAX_BACKGROUND_RUN_CONTINUATIONS. Aborted /
5929
+ // user-stopped runs do NOT chain.
5930
+ // Self-chain server-side for EVERY durable worker, not only the
5931
+ // ones inside a `-background` function. Server-driven
5932
+ // continuation is the whole point of durable background: the run
5933
+ // must survive the client disconnecting (closed tab), so it
5934
+ // cannot depend on the browser re-POSTing `auto_continue`. A
5935
+ // worker on the regular ~60s function — a Netlify routing miss,
5936
+ // or a non-Netlify host (Vercel/Cloudflare/Render/Fly) that
5937
+ // never emits a `-background` function — checkpoints at the 40s
5938
+ // soft-timeout and self-dispatches the next 40s chunk; a worker
5939
+ // in a real `-background` function chains ~13-min chunks. Only
5940
+ // the per-chunk BUDGET differs by function type (gated by
5941
+ // `runsInBackgroundFunction` at the startRun call below); the
5942
+ // continuation itself must stay server-driven on both. (The
5943
+ // self-chain is only reachable when the initial dispatch already
5944
+ // succeeded — a dispatch fast-fail degrades to the inline
5945
+ // foreground fallback, which is not a worker and rides the
5946
+ // connected client's auto_continue instead.)
5947
+ if (willChainBackgroundContinuation(run)) {
5948
+ // Full handoff discipline lives in
5949
+ // `chainServerDrivenContinuation` (exported + unit-tested):
5950
+ // per-turn SQL run budget, successor row PRE-INSERTED before
5951
+ // the dispatch, fully awaited dispatch with retries, loud
5952
+ // diag/terminal marking on failure. Never throws.
5953
+ await chainServerDrivenContinuation({
5954
+ event,
5955
+ run,
5956
+ effectiveThreadId,
5957
+ effectiveTurnId,
5958
+ requestBody: body,
5959
+ backgroundContinuationCount,
5960
+ // Re-evaluate the durable gate rather than keying off
5961
+ // isBackgroundWorker: a successor chunk of a FOREGROUND
5962
+ // self-chain re-enters as a worker too, and must keep
5963
+ // chaining via the regular function — the Netlify
5964
+ // `-background` function is only emitted into the deploy
5965
+ // output when the durable flag is on.
5966
+ //
5967
+ // `&& !runsInBackgroundFunction`: a worker PROVEN to already
5968
+ // be executing inside the real `-background` function must
5969
+ // never dispatch back to that same function's own URL — a
5970
+ // background function invoking itself by URL from inside a
5971
+ // live invocation is a documented Netlify platform
5972
+ // limitation (404), unlike the initial foreground→background
5973
+ // dispatch or a worker that landed on the regular function
5974
+ // (a genuinely different function calling the background
5975
+ // one, which works). This only changes the dispatch TARGET
5976
+ // for that one proven-in-bg-function case — by this point
5977
+ // (with the in-process resumable-error resume above) it is
5978
+ // reached only when the chunk genuinely exhausted its
5979
+ // budget, so falling back to the regular `_process-run`
5980
+ // function (40s clamp) here is the correct, safe target.
5981
+ chainViaDurableBackground: isAgentChatDurableBackgroundEnabled({
5982
+ appOptIn: options.durableBackgroundRuns,
5983
+ }) && !runsInBackgroundFunction,
5984
+ // Only changes the retry BUDGET, never the dispatch target
5985
+ // above: a worker proven in a real background function has
5986
+ // minutes of remaining wall clock and no connected-client
5987
+ // fallback, so it must not be demoted to the foreground's
5988
+ // 2-attempt budget just because it was forced onto the
5989
+ // regular-function dispatch target. See
5990
+ // `resolveContinuationDispatchBudget`.
5991
+ workerProvenInBackgroundFunction: runsInBackgroundFunction,
5992
+ });
6010
5993
  }
6011
5994
  }
6012
5995
  : undefined;
@@ -6075,7 +6058,7 @@ export function createProductionAgentHandler(options) {
6075
6058
  backgroundFunction: false,
6076
6059
  }))
6077
6060
  : null;
6078
- startRun(runId, effectiveThreadId, async (rawSend, signal) => {
6061
+ const startedRun = startRun(runId, effectiveThreadId, async (rawSend, signal) => {
6079
6062
  const send = (event) => {
6080
6063
  rawSend(event);
6081
6064
  updateTrackedProgressFromEvent(event);
@@ -6461,10 +6444,8 @@ export function createProductionAgentHandler(options) {
6461
6444
  // Background worker: await the run to completion so Netlify keeps the
6462
6445
  // background function alive for the whole turn (the client is streaming the
6463
6446
  // same events via the foreground POST's cross-isolate SQL subscription).
6464
- // The onComplete wrapper above resolves `backgroundRunDone`.
6465
6447
  if (isBackgroundWorker) {
6466
- if (backgroundRunDone)
6467
- await backgroundRunDone;
6448
+ await startedRun.finalized;
6468
6449
  return { ok: true, runId };
6469
6450
  }
6470
6451
  // Subscribe to the run and stream events to the client