@agent-native/core 0.121.0 → 0.121.1

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.
@@ -1,5 +1,11 @@
1
1
  # @agent-native/core
2
2
 
3
+ ## 0.121.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 99997d8: Recognize Netlify's documented Function runtime marker so opted-in durable background work reaches its generated worker instead of falling back to a short synchronous route.
8
+
3
9
  ## 0.121.0
4
10
 
5
11
  ### Minor Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.121.0",
3
+ "version": "0.121.1",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -114,10 +114,15 @@ function isNetlifyHostedRuntimeForDispatch(): boolean {
114
114
  if (process.env.NETLIFY_LOCAL === "true") return false;
115
115
  if (process.env.NETLIFY === "false") return false;
116
116
  if (process.env.NETLIFY && process.env.NETLIFY !== "false") return true;
117
- // Netlify sets AWS Lambda runtime env on deployed Functions, but the build-time
118
- // NETLIFY flag is not always present in the runtime isolate. Treat Lambda as
119
- // Netlify here unless Netlify was explicitly disabled above; non-Netlify AWS
120
- // falls back inline if the /.netlify/functions dispatch fast-fails.
117
+ // NETLIFY is a build-only read-only variable. In deployed Functions Netlify
118
+ // documents URL, SITE_NAME, and SITE_ID as the runtime read-only variables;
119
+ // SITE_ID is the unambiguous host marker. Lambda compatibility mode also
120
+ // exposes AWS runtime variables, so keep the function-name fallback for older
121
+ // deploys. Without either check a modern Netlify Function silently selects the
122
+ // portable framework route even though the emitted background function exists.
123
+ if (process.env.SITE_ID) return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.
124
+ // Non-Netlify AWS falls back inline if the /.netlify/functions dispatch
125
+ // fast-fails.
121
126
  return Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME);
122
127
  }
123
128
 
@@ -202,6 +207,9 @@ export const AGENT_CHAT_BACKGROUND_RUN_FIELD = "__backgroundRun";
202
207
  * what "hosted" means.
203
208
  */
204
209
  export function isHostedRuntimeForDurableBackground(): boolean {
210
+ if (process.env.NETLIFY_LOCAL === "true") return false;
211
+ if (process.env.NETLIFY === "false") return false;
212
+ if (process.env.SITE_ID) return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.
205
213
  if (
206
214
  process.env.NETLIFY &&
207
215
  process.env.NETLIFY !== "false" &&
@@ -319,6 +319,9 @@ export interface ResolveRunSoftTimeoutOptions {
319
319
  * that clamp (and the platform wall behind it) exists.
320
320
  */
321
321
  export function isHostedRuntime(): boolean {
322
+ if (process.env.NETLIFY_LOCAL === "true") return false;
323
+ if (process.env.NETLIFY === "false") return false;
324
+ if (process.env.SITE_ID) return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.
322
325
  if (
323
326
  process.env.NETLIFY &&
324
327
  process.env.NETLIFY !== "false" &&
@@ -1 +1 @@
1
- {"version":3,"file":"durable-background.d.ts","sourceRoot":"","sources":["../../src/agent/durable-background.ts"],"names":[],"mappings":"AAgDA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,2CACE,CAAC;AAE3C;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,4BAA4B,CAAC;AAExE;;;;;;;;;GASG;AACH,eAAO,MAAM,kCAAkC,gDAA0D,CAAC;AAE1G;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,2BAA2B,CAAC;AACzE,eAAO,MAAM,8BAA8B,QAAQ,CAAC;AACpD,eAAO,MAAM,sCAAsC,gBAAgB,CAAC;AACpE,eAAO,MAAM,gCAAgC,UAAU,CAAC;AACxD,eAAO,MAAM,sCAAsC,gCACpB,CAAC;AAiChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,sCAAsC,IAAI,MAAM,CAQ/D;AAED,wBAAgB,oCAAoC,CAClD,YAAY,EAAE,MAAM,GACnB,MAAM,CAQR;AAED,wBAAgB,4CAA4C,CAC1D,YAAY,EAAE,MAAM,GACnB,OAAO,CAET;AAED;;;GAGG;AACH,eAAO,MAAM,iCAAiC,kCACb,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,oBAAoB,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,mCAAmC,IAAI,OAAO,CAsB7D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAsBvD;AAED,wBAAgB,2CAA2C,CACzD,MAAM,EAAE,OAAO,GACd,OAAO,CAOT;AAED,wBAAgB,2CAA2C,CACzD,OAAO,EAAE,OAAO,GACf,OAAO,CAKT;AAED,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAQzE;AAwCD;;;;;;;GAOG;AACH,wBAAgB,mCAAmC,CAAC,OAAO,CAAC,EAAE;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAiBV;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oCAAoC,qCACb,CAAC;AAiBrC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qCAAqC,IAAI,OAAO,CAM/D;AAED,uDAAuD;AACvD,MAAM,MAAM,qBAAqB,GAC7B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEN;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAahE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,QAAQ,GAAE,OAAe,GACxB,qBAAqB,CAqDvB"}
1
+ {"version":3,"file":"durable-background.d.ts","sourceRoot":"","sources":["../../src/agent/durable-background.ts"],"names":[],"mappings":"AAgDA;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,2CACE,CAAC;AAE3C;;;;;;;;GAQG;AACH,eAAO,MAAM,8BAA8B,4BAA4B,CAAC;AAExE;;;;;;;;;GASG;AACH,eAAO,MAAM,kCAAkC,gDAA0D,CAAC;AAE1G;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,2BAA2B,CAAC;AACzE,eAAO,MAAM,8BAA8B,QAAQ,CAAC;AACpD,eAAO,MAAM,sCAAsC,gBAAgB,CAAC;AACpE,eAAO,MAAM,gCAAgC,UAAU,CAAC;AACxD,eAAO,MAAM,sCAAsC,gCACpB,CAAC;AAsChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,sCAAsC,IAAI,MAAM,CAQ/D;AAED,wBAAgB,oCAAoC,CAClD,YAAY,EAAE,MAAM,GACnB,MAAM,CAQR;AAED,wBAAgB,4CAA4C,CAC1D,YAAY,EAAE,MAAM,GACnB,OAAO,CAET;AAED;;;GAGG;AACH,eAAO,MAAM,iCAAiC,kCACb,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,+BAA+B,oBAAoB,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,mCAAmC,IAAI,OAAO,CAyB7D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,6BAA6B,IAAI,OAAO,CAsBvD;AAED,wBAAgB,2CAA2C,CACzD,MAAM,EAAE,OAAO,GACd,OAAO,CAOT;AAED,wBAAgB,2CAA2C,CACzD,OAAO,EAAE,OAAO,GACf,OAAO,CAKT;AAED,wBAAgB,iCAAiC,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAQzE;AAwCD;;;;;;;GAOG;AACH,wBAAgB,mCAAmC,CAAC,OAAO,CAAC,EAAE;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAiBV;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oCAAoC,qCACb,CAAC;AAiBrC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qCAAqC,IAAI,OAAO,CAM/D;AAED,uDAAuD;AACvD,MAAM,MAAM,qBAAqB,GAC7B;IACE,EAAE,EAAE,IAAI,CAAC;IACT,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B,GACD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAEN;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAahE;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,OAAO,EACb,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,QAAQ,GAAE,OAAe,GACxB,qBAAqB,CAqDvB"}
@@ -105,10 +105,16 @@ function isNetlifyHostedRuntimeForDispatch() {
105
105
  return false;
106
106
  if (process.env.NETLIFY && process.env.NETLIFY !== "false")
107
107
  return true;
108
- // Netlify sets AWS Lambda runtime env on deployed Functions, but the build-time
109
- // NETLIFY flag is not always present in the runtime isolate. Treat Lambda as
110
- // Netlify here unless Netlify was explicitly disabled above; non-Netlify AWS
111
- // falls back inline if the /.netlify/functions dispatch fast-fails.
108
+ // NETLIFY is a build-only read-only variable. In deployed Functions Netlify
109
+ // documents URL, SITE_NAME, and SITE_ID as the runtime read-only variables;
110
+ // SITE_ID is the unambiguous host marker. Lambda compatibility mode also
111
+ // exposes AWS runtime variables, so keep the function-name fallback for older
112
+ // deploys. Without either check a modern Netlify Function silently selects the
113
+ // portable framework route even though the emitted background function exists.
114
+ if (process.env.SITE_ID)
115
+ return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.
116
+ // Non-Netlify AWS falls back inline if the /.netlify/functions dispatch
117
+ // fast-fails.
112
118
  return Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME);
113
119
  }
114
120
  /**
@@ -178,6 +184,12 @@ export const AGENT_CHAT_BACKGROUND_RUN_FIELD = "__backgroundRun";
178
184
  * what "hosted" means.
179
185
  */
180
186
  export function isHostedRuntimeForDurableBackground() {
187
+ if (process.env.NETLIFY_LOCAL === "true")
188
+ return false;
189
+ if (process.env.NETLIFY === "false")
190
+ return false;
191
+ if (process.env.SITE_ID)
192
+ return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.
181
193
  if (process.env.NETLIFY &&
182
194
  process.env.NETLIFY !== "false" &&
183
195
  process.env.NETLIFY_LOCAL !== "true") {
@@ -1 +1 @@
1
- {"version":3,"file":"durable-background.js","sourceRoot":"","sources":["../../src/agent/durable-background.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Durable background agent-chat runs (Netlify background functions).\n *\n * Off by default. When enabled, a long in-app agent-chat turn is dispatched\n * into a Netlify *background* function (15-min budget) instead of completing\n * synchronously under the ~40s soft-timeout. The foreground POST claims the\n * run slot, inserts the run row, fires an HMAC-signed self-dispatch to\n * `AGENT_CHAT_PROCESS_RUN_PATH`, and returns the existing SSE subscription so\n * the client streams the same events (via the cross-isolate SQL-poll path)\n * with no client change.\n *\n * This module owns ONLY the gating decision + shared constants so both the\n * HTTP handler (`production-agent.ts`) and the processor route\n * (`agent-chat-plugin.ts`) agree on when the path is active without a circular\n * import. The actual run machinery is reused verbatim from run-manager /\n * run-store / self-dispatch / internal-token.\n *\n * GUARDRAIL: when `isAgentChatDurableBackgroundEnabled()` returns false, the\n * agent-chat handler must behave byte-for-byte like the current synchronous\n * path. The gate is true only when ALL of these hold:\n * 1. `AGENT_CHAT_DURABLE_BACKGROUND` env is explicitly enabled, or a\n * workspace app's agent-chat plugin opts in with `durableBackgroundRuns`\n * where the workspace deploy emits a per-app background function by\n * default. Single-template Netlify deploys must set the env flag because\n * that same flag controls whether `server-agent-background` is emitted.\n * 2. The runtime is hosted/serverless (local dev keeps the inline path so SSE\n * stays a single live stream and no second function is needed).\n * 3. `A2A_SECRET` is configured (the HMAC handoff is required to authenticate\n * the background dispatch; without it the dispatch can't be trusted).\n *\n * Opt-in keeps the blast radius small while the worker path is still being\n * proven. And even when enabled, a *dispatch failure degrades to an inline run*:\n * if the self-dispatch self-POST can't be delivered (fast connection error or\n * fast non-2xx), the foreground handler runs the turn synchronously instead of\n * erroring (see `production-agent.ts` — the inline fallback claims the run row\n * atomically so a delayed delivery can never double-execute). So an app where\n * durable dispatch happens to fail still gets a working chat, just without the\n * 15-min budget.\n */\nimport {\n hasConfiguredA2ASecret,\n isTrustedLocalRuntime,\n} from \"../a2a/auth-policy.js\";\nimport {\n extractBearerToken,\n verifyInternalToken,\n} from \"../integrations/internal-token.js\";\n\n/**\n * Framework route the background function actually runs — sibling to\n * `AGENT_TEAM_PROCESS_RUN_PATH`. Reached *through* the Netlify background\n * function, so it inherits the 15-min budget.\n */\nexport const AGENT_CHAT_PROCESS_RUN_PATH =\n \"/_agent-native/agent-chat/_process-run\";\n\n/**\n * Name of the standalone Netlify background function the build emits (see\n * `emitSingleTemplateNetlifyBackgroundFunction` in deploy/build.ts). Shared so\n * the emit and the dispatch-path helper below can never drift on the name.\n *\n * MUST end in `-background` — both because that is the conventional Netlify\n * async-function suffix and because `isInBackgroundFunctionRuntime()` reads the\n * `AWS_LAMBDA_FUNCTION_NAME` `-background` suffix as a secondary runtime signal.\n */\nexport const AGENT_BACKGROUND_FUNCTION_NAME = \"server-agent-background\";\n\n/**\n * Default function URL of the background function on Netlify. Every Netlify\n * function is reachable at `/.netlify/functions/<name>` BY DEFAULT; that default\n * url is removed ONLY if the function declares a custom `config.path`. The\n * emitted background function declares NO custom `config.path` (it sets\n * `background: true` and nothing else routing-related), so it KEEPS this default\n * url — and the Nitro `server` function already excludes `/.netlify/*` from its\n * `/*` catch-all, so this namespace is never shadowed. The foreground therefore\n * dispatches HERE on hosted Netlify (see `resolveAgentChatProcessRunDispatchPath`).\n */\nexport const AGENT_BACKGROUND_FUNCTION_URL_PATH = `/.netlify/functions/${AGENT_BACKGROUND_FUNCTION_NAME}`;\n\n/**\n * Marker carried in a Netlify background-function body when the shared\n * long-running worker should route to a processor other than agent chat.\n * The emitted wrapper defaults to the normal agent-chat `_process-run` route;\n * A2A uses this marker to reuse the same 15-minute function for async tasks.\n */\nexport const AGENT_BACKGROUND_PROCESSOR_FIELD = \"__agentNativeProcessor\";\nexport const AGENT_BACKGROUND_PROCESSOR_A2A = \"a2a\";\nexport const AGENT_BACKGROUND_PROCESSOR_INTEGRATION = \"integration\";\nexport const AGENT_BACKGROUND_PROCESSOR_ROUTE = \"route\";\nexport const AGENT_BACKGROUND_PROCESSOR_ROUTE_FIELD =\n \"__agentNativeProcessorRoute\";\n\n/**\n * The per-app workspace background function URL path. Workspace deploy emits one\n * background function per app named `<app>-agent-background`, reachable at its\n * DEFAULT url `/.netlify/functions/<app>-agent-background` (no custom\n * `config.path`). The foreground resolves the current workspace app id from\n * `AGENT_NATIVE_WORKSPACE_APP_ID` (set by the workspace function entry) so it can\n * dispatch to the right per-app function url. Returns `null` when no workspace\n * app id is configured (single-template deploy).\n */\nfunction resolveWorkspaceBackgroundFunctionUrlPath(): string | null {\n const raw = process.env.AGENT_NATIVE_WORKSPACE_APP_ID;\n if (typeof raw !== \"string\") return null;\n // Mirror the workspace app-id normalization (resources/store.ts): take the\n // first path segment and accept only the safe slug shape used for function\n // names. Anything else falls back to the single-template name.\n const candidate = raw.trim().replace(/^\\/+/, \"\").split(\"/\")[0] ?? \"\";\n if (!/^[a-z0-9][a-z0-9-]{0,127}$/.test(candidate)) return null;\n return `/.netlify/functions/${candidate}-agent-background`;\n}\n\nfunction isNetlifyHostedRuntimeForDispatch(): boolean {\n if (process.env.NETLIFY_LOCAL === \"true\") return false;\n if (process.env.NETLIFY === \"false\") return false;\n if (process.env.NETLIFY && process.env.NETLIFY !== \"false\") return true;\n // Netlify sets AWS Lambda runtime env on deployed Functions, but the build-time\n // NETLIFY flag is not always present in the runtime isolate. Treat Lambda as\n // Netlify here unless Netlify was explicitly disabled above; non-Netlify AWS\n // falls back inline if the /.netlify/functions dispatch fast-fails.\n return Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME);\n}\n\n/**\n * Resolve the path the foreground POST should self-dispatch the chat background\n * worker to.\n *\n * GROUNDED IN THE REAL NETLIFY BUILD OUTPUT + THE NETLIFY DOCS DEFAULT-URL RULE:\n * the background function is emitted INTO the scanned dir\n * (`.netlify/functions-internal/server-agent-background`, or per-app\n * `<app>-agent-background` for workspaces) with `export const config = {\n * background: true, ... }` and NO custom `config.path`. Because it has no custom\n * path, Netlify keeps its DEFAULT function url `/.netlify/functions/<name>`, and\n * `background: true` makes any invocation of that url ASYNC (immediate 202,\n * 15-min budget). The Nitro `server` function already excludes `/.netlify/*`\n * from its `/*` catch-all, so the default-url namespace is NEVER shadowed by the\n * synchronous function.\n *\n * Therefore on hosted Netlify the foreground dispatches to the function's DEFAULT\n * url (`/.netlify/functions/<name>`); the function entry then rewrites the\n * incoming pathname to `AGENT_CHAT_PROCESS_RUN_PATH` (base-path-prefixed for\n * workspaces) before delegating to the Nitro router, so the `_process-run`\n * plugin runs with the async 15-min budget. Everywhere else (local dev, `netlify\n * dev`, non-Netlify hosts where no second function exists) there is no second\n * function, so the foreground dispatches to the framework route\n * `AGENT_CHAT_PROCESS_RUN_PATH` and the same in-process catch-all handles it\n * inline. The HMAC token (signed over the runId) is unchanged either way.\n *\n * NOTE: this is the DOC-CORRECT approach. An earlier attempt gave the function a\n * custom `config.path` + a catch-all `excludedPath` patch; the custom path was\n * NOT honored as a route in prod (probe → 404). Using the default function url\n * (no custom path) is what Netlify documents and is simpler — there is nothing\n * to shadow because `/.netlify/*` is already excluded from the `server` catch-all.\n */\nexport function resolveAgentChatProcessRunDispatchPath(): string {\n if (isNetlifyHostedRuntimeForDispatch()) {\n return (\n resolveWorkspaceBackgroundFunctionUrlPath() ??\n AGENT_BACKGROUND_FUNCTION_URL_PATH\n );\n }\n return AGENT_CHAT_PROCESS_RUN_PATH;\n}\n\nexport function resolveDurableBackgroundDispatchPath(\n fallbackPath: string,\n): string {\n if (isNetlifyHostedRuntimeForDispatch()) {\n return (\n resolveWorkspaceBackgroundFunctionUrlPath() ??\n AGENT_BACKGROUND_FUNCTION_URL_PATH\n );\n }\n return fallbackPath;\n}\n\nexport function dispatchPathTargetsNetlifyBackgroundFunction(\n dispatchPath: string,\n): boolean {\n return dispatchPath.startsWith(\"/.netlify/functions/\");\n}\n\n/**\n * Env flag for durable background runs. DEFAULT-OFF (opt-in): unset means\n * disabled; an app opts IN with an explicit truthy value (`true`/`1`/`yes`/`on`).\n */\nexport const AGENT_CHAT_DURABLE_BACKGROUND_ENV =\n \"AGENT_CHAT_DURABLE_BACKGROUND\";\n\n/**\n * Body field the foreground handler injects when self-dispatching to the\n * background processor. Its presence is how the re-entered handler knows it is\n * the background worker (run inline with the background soft-timeout; do NOT\n * re-claim the slot or re-dispatch). Untrusted on its own — the route also\n * verifies the HMAC token before invoking the handler.\n */\nexport const AGENT_CHAT_BACKGROUND_RUN_FIELD = \"__backgroundRun\";\n\n/**\n * Mirror of run-manager's private `isHostedRuntime`. Kept in sync deliberately:\n * the durable-background gate must agree with the soft-timeout regime about\n * what \"hosted\" means.\n */\nexport function isHostedRuntimeForDurableBackground(): boolean {\n if (\n process.env.NETLIFY &&\n process.env.NETLIFY !== \"false\" &&\n process.env.NETLIFY_LOCAL !== \"true\"\n ) {\n return true;\n }\n if (\n process.env.AWS_LAMBDA_FUNCTION_NAME &&\n process.env.NETLIFY_LOCAL !== \"true\"\n ) {\n return true;\n }\n return Boolean(\n process.env.CF_PAGES ||\n process.env.VERCEL ||\n process.env.VERCEL_ENV ||\n process.env.RENDER ||\n process.env.FLY_APP_NAME ||\n process.env.K_SERVICE,\n );\n}\n\n/**\n * True when THIS process is actually executing inside a Netlify *background*\n * function (the long, 15-min-budget async function whose deployed name ends in\n * `-background`). Netlify runs functions on AWS Lambda and sets\n * `AWS_LAMBDA_FUNCTION_NAME` to the function's name, so a `-background` suffix is\n * the runtime proof that the ~60s synchronous wall does NOT apply here.\n *\n * This is the SAFETY GUARD for the soft-timeout regime. The `_process-run`\n * self-dispatch worker (`isBackgroundWorker`) is NOT enough on its own: if the\n * `-background` function was never emitted (deploy gate off, or Netlify routed\n * the path to the synchronous function), the self-POST lands on the regular\n * ~60s `server` function. A worker there MUST use the 40s soft-timeout and\n * checkpoint before the 60s wall — using the ~13min budget would overshoot the\n * hard wall and get killed at 60s, then re-dispatch/resume in a wasteful loop.\n * So the 13-min budget is taken ONLY when this returns true.\n *\n * The PRIMARY signal is a `globalThis` marker the emitted background function's\n * entry sets at cold start — the deployed Lambda name is not guaranteed to end\n * in `-background` on Netlify, so the entry marks its own runtime. A `globalThis`\n * flag (not `process.env`) keeps the no-env-mutation guard satisfied and carries\n * no cross-request state (set once per isolate). The `AWS_LAMBDA_FUNCTION_NAME`\n * suffix and the explicit `AGENT_CHAT_FORCE_BACKGROUND_RUNTIME` env (truthy) are\n * additional signals — the latter an operator escape hatch. Off by default.\n */\nexport function isInBackgroundFunctionRuntime(): boolean {\n // Set by the emitted `-background` function entry at cold start (the primary,\n // most reliable signal — see the emit in deploy/build.ts).\n if (\n (globalThis as Record<string, unknown>)\n .__AGENT_NATIVE_BACKGROUND_RUNTIME__ === true\n ) {\n return true;\n }\n const lambdaName = process.env.AWS_LAMBDA_FUNCTION_NAME;\n if (\n typeof lambdaName === \"string\" &&\n lambdaName.toLowerCase().endsWith(\"-background\")\n ) {\n return true;\n }\n const forced = process.env.AGENT_CHAT_FORCE_BACKGROUND_RUNTIME;\n if (forced != null) {\n const v = forced.trim().toLowerCase();\n return v === \"1\" || v === \"true\" || v === \"yes\" || v === \"on\";\n }\n return false;\n}\n\nexport function backgroundRunMarkerExpectsBackgroundRuntime(\n marker: unknown,\n): boolean {\n return (\n typeof marker === \"object\" &&\n marker !== null &&\n (marker as { backgroundFunctionRuntimeExpected?: unknown })\n .backgroundFunctionRuntimeExpected === true\n );\n}\n\nexport function shouldUseBackgroundFunctionTimeoutForWorker(\n _marker: unknown,\n): boolean {\n // The dispatch marker says which URL the foreground targeted, not where the\n // request actually landed. Only the worker runtime proof can safely lift the\n // hosted 40s clamp to the 15-minute background-function budget.\n return isInBackgroundFunctionRuntime();\n}\n\nexport function backgroundRuntimeDiagnosticDetail(marker: unknown): string {\n return [\n `markerExpected=${backgroundRunMarkerExpectsBackgroundRuntime(marker)}`,\n `runtimeDetected=${isInBackgroundFunctionRuntime()}`,\n `globalMarker=${(globalThis as Record<string, unknown>).__AGENT_NATIVE_BACKGROUND_RUNTIME__ === true}`,\n `lambdaNameEndsBackground=${typeof process.env.AWS_LAMBDA_FUNCTION_NAME === \"string\" && process.env.AWS_LAMBDA_FUNCTION_NAME.toLowerCase().endsWith(\"-background\")}`,\n `forceEnv=${typeof process.env.AGENT_CHAT_FORCE_BACKGROUND_RUNTIME === \"string\" && process.env.AGENT_CHAT_FORCE_BACKGROUND_RUNTIME.trim().length > 0}`,\n ].join(\" \");\n}\n\nfunction isFlagEnabled(): boolean {\n // Read the literal key (not `process.env[CONST]`) so guard:no-env-credentials\n // can statically verify it against the allowlisted `AGENT_*` prefix. Keep this\n // in sync with AGENT_CHAT_DURABLE_BACKGROUND_ENV.\n //\n // DEFAULT-OFF (opt-in): durable background runs are still being hardened. A\n // premature fleet-wide default-on caused real-user incidents (Assets/Analytics\n // hit \"Failed to dispatch\" + stalls, 2026-06-24) because the async background\n // worker path is not yet proven end-to-end and the deploy-time env opt-out is\n // not reliably baked into a given deploy. So an unset/empty/unknown flag means\n // OFF; an app opts IN only with an explicit truthy value\n // (AGENT_CHAT_DURABLE_BACKGROUND=true). This still composes with the hosted +\n // A2A_SECRET gates below. Flip back to default-on only after the 15-min\n // background-function worker is verified live in production (see the\n // project_durable_bg_prod_verified memory).\n const raw = process.env.AGENT_CHAT_DURABLE_BACKGROUND;\n if (raw == null) return false;\n const normalized = raw.trim().toLowerCase();\n return (\n normalized === \"1\" ||\n normalized === \"true\" ||\n normalized === \"yes\" ||\n normalized === \"on\"\n );\n}\n\nfunction isFlagExplicitlyDisabled(): boolean {\n const raw = process.env.AGENT_CHAT_DURABLE_BACKGROUND;\n if (raw == null) return false;\n const normalized = raw.trim().toLowerCase();\n return (\n normalized === \"0\" ||\n normalized === \"false\" ||\n normalized === \"no\" ||\n normalized === \"off\"\n );\n}\n\n/**\n * The single gate. True when the env flag is explicitly enabled, or a workspace\n * app opted in and has a per-app background-function target, AND the runtime is\n * hosted AND A2A_SECRET is configured. False otherwise — and false means the\n * current synchronous behavior is used unchanged. Single-template Netlify app\n * opt-ins deliberately require the env flag too because that flag controls\n * whether the `server-agent-background` function exists in the deploy output.\n */\nexport function isAgentChatDurableBackgroundEnabled(options?: {\n appOptIn?: boolean;\n}): boolean {\n // An app-level opt-out must win over a stale deploy-wide env flag. Netlify\n // environment variables can outlive the source config that originally set\n // them; allowing that flag to re-enable a worker an app explicitly disabled\n // recreates the missing-background-function failure this gate is meant to\n // prevent.\n if (options?.appOptIn === false) return false;\n const envOptIn = isFlagEnabled();\n const workspaceAppOptIn =\n options?.appOptIn === true &&\n !isFlagExplicitlyDisabled() &&\n resolveWorkspaceBackgroundFunctionUrlPath() !== null;\n return (\n (envOptIn || workspaceAppOptIn) &&\n isHostedRuntimeForDurableBackground() &&\n hasConfiguredA2ASecret()\n );\n}\n\n/**\n * Env flag for the FOREGROUND server-driven self-chain. DEFAULT-OFF: a hosted\n * app must explicitly opt in with a truthy value (`true`/`1`/`yes`/`on`). A\n * regular Netlify function has a fixed 60-second wall, and a self-dispatched\n * successor can otherwise be killed before it persists its next continuation.\n * Keep this separate from `AGENT_CHAT_DURABLE_BACKGROUND` so the experimental\n * regular-function chain can be enabled independently after its deployment is\n * proven safe.\n */\nexport const AGENT_CHAT_FOREGROUND_SELF_CHAIN_ENV =\n \"AGENT_CHAT_FOREGROUND_SELF_CHAIN\";\n\nfunction isForegroundSelfChainExplicitlyEnabled(): boolean {\n // Read the literal key (not `process.env[CONST]`) so guard:no-env-credentials\n // can statically verify it against the allowlisted `AGENT_*` prefix. Keep this\n // in sync with AGENT_CHAT_FOREGROUND_SELF_CHAIN_ENV.\n const raw = process.env.AGENT_CHAT_FOREGROUND_SELF_CHAIN;\n if (raw == null) return false;\n const normalized = raw.trim().toLowerCase();\n return (\n normalized === \"1\" ||\n normalized === \"true\" ||\n normalized === \"yes\" ||\n normalized === \"on\"\n );\n}\n\n/**\n * Gate for the foreground self-chain: a normal (non-durable-background)\n * agent-chat turn that hits its soft-timeout chunk boundary continues via a\n * server-side self-dispatch on the REGULAR function (not a Netlify\n * `-background` function) instead of depending on the client to re-POST\n * `auto_continue`. Composes exactly like `isAgentChatDurableBackgroundEnabled`:\n * true only when the env flag is explicitly truthy, the runtime is hosted, and\n * `A2A_SECRET` is configured (the HMAC handoff authenticates the dispatch).\n * False means the existing client-driven `auto_continue` re-POST path is used.\n *\n * Deliberately independent of `isAgentChatDurableBackgroundEnabled`: an app can\n * use this narrower capability without opting into the full 15-min\n * background-function worker path, and the two gates never need to agree.\n * When BOTH would be true for a given run, the durable-background dispatch\n * decision in `production-agent.ts` is evaluated first and takes precedence —\n * a run already dispatched to the durable background worker chains via the\n * existing `isBackgroundWorker` path, not this one.\n */\nexport function isAgentChatForegroundSelfChainEnabled(): boolean {\n return (\n isForegroundSelfChainExplicitlyEnabled() &&\n isHostedRuntimeForDurableBackground() &&\n hasConfiguredA2ASecret()\n );\n}\n\n/** Decision returned by `prepareProcessRunRequest`. */\nexport type ProcessRunPreparation =\n | {\n ok: true;\n /** The pre-claimed run id the background worker must reuse. */\n runId: string;\n /** Body to stash for the re-entered handler (marker guaranteed present). */\n body: Record<string, unknown>;\n }\n | {\n ok: false;\n /** HTTP status the route should return. */\n status: number;\n /** Error payload. */\n error: string;\n /**\n * The run id parsed from the body, when present. Carried even on failure\n * so the route can RECORD the auth/validation failure ONTO the run\n * (diag_stage) before returning the error status — otherwise a 401/503 in\n * the unreadable Netlify background function would leave the run to time\n * out with no clue why. Null when no run id could be parsed.\n */\n runId: string | null;\n };\n\n/**\n * Parse the run id from a `_process-run` request body without authenticating.\n * Mirrors the precedence in `prepareProcessRunRequest` (marker.runId, then\n * top-level taskId). Returns null when neither is a usable string. Used so the\n * route can attach a diagnostic to the run even on an auth/validation failure.\n */\nexport function extractProcessRunId(body: unknown): string | null {\n if (!body || typeof body !== \"object\") return null;\n const record = body as Record<string, unknown>;\n const marker = record[AGENT_CHAT_BACKGROUND_RUN_FIELD] as\n | { runId?: unknown }\n | undefined;\n if (marker && typeof marker.runId === \"string\" && marker.runId) {\n return marker.runId;\n }\n if (typeof record.taskId === \"string\" && record.taskId) {\n return record.taskId;\n }\n return null;\n}\n\n/**\n * Pure, transport-agnostic core of the `_process-run` route: validate the body,\n * authenticate the HMAC self-dispatch, and produce the body the re-entered\n * agent-chat handler should run as the background worker.\n *\n * Auth policy mirrors the agent-teams processor exactly:\n * - `A2A_SECRET` set → require a valid `verifyInternalToken(runId, token)`.\n * - no secret → require `isTrustedLocalRuntime({ loopback })` (see\n * auth-policy.ts): refuse (503) unless `A2A_ALLOW_UNSIGNED_INTERNAL=1` is\n * set. This function has no h3 `event` of its own, so callers that CAN\n * see the inbound socket peer (the route handler, which has the event)\n * should compute `loopback` from it and pass it through; callers that\n * can't determine the peer address should omit it (defaults to `false`\n * — never trust unsigned dispatch without an explicit opt-in).\n *\n * Extracted from the route handler so the auth + marker-prep decision is unit\n * testable without booting the whole Nitro plugin. The route only adds body\n * reading and the final handler invocation around this.\n */\nexport function prepareProcessRunRequest(\n body: unknown,\n authHeader: string | undefined,\n loopback: boolean = false,\n): ProcessRunPreparation {\n if (!body || typeof body !== \"object\") {\n return {\n ok: false,\n status: 400,\n error: \"Invalid request body\",\n runId: null,\n };\n }\n const record = body as Record<string, unknown>;\n const marker = record[AGENT_CHAT_BACKGROUND_RUN_FIELD] as\n | { runId?: unknown }\n | undefined;\n const runId =\n marker && typeof marker.runId === \"string\"\n ? marker.runId\n : typeof record.taskId === \"string\"\n ? (record.taskId as string)\n : \"\";\n if (!runId) {\n return { ok: false, status: 400, error: \"runId required\", runId: null };\n }\n\n if (hasConfiguredA2ASecret()) {\n const token = extractBearerToken(authHeader);\n if (!verifyInternalToken(runId, token ?? \"\")) {\n return {\n ok: false,\n status: 401,\n error: \"Invalid or expired processor token\",\n runId,\n };\n }\n } else if (!isTrustedLocalRuntime({ loopback })) {\n // Callers that can see the h3 `event` (the route handler) pass the real\n // loopback signal; callers without one default to non-loopback. Unsigned\n // dispatch is still allowed via A2A_ALLOW_UNSIGNED_INTERNAL=1 for trusted\n // local/dev setups; see auth-policy.ts `isTrustedLocalRuntime`.\n return {\n ok: false,\n status: 503,\n error:\n \"Agent chat background processor not configured — set A2A_SECRET on this deployment (or A2A_ALLOW_UNSIGNED_INTERNAL=1 for trusted local dev).\",\n runId,\n };\n }\n\n // Ensure the marker is present so the re-entered handler runs as the\n // background worker (reuses runId/turnId, no re-claim, no re-dispatch).\n if (!marker || typeof marker.runId !== \"string\") {\n record[AGENT_CHAT_BACKGROUND_RUN_FIELD] = { runId };\n }\n return { ok: true, runId, body: record };\n}\n"]}
1
+ {"version":3,"file":"durable-background.js","sourceRoot":"","sources":["../../src/agent/durable-background.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Durable background agent-chat runs (Netlify background functions).\n *\n * Off by default. When enabled, a long in-app agent-chat turn is dispatched\n * into a Netlify *background* function (15-min budget) instead of completing\n * synchronously under the ~40s soft-timeout. The foreground POST claims the\n * run slot, inserts the run row, fires an HMAC-signed self-dispatch to\n * `AGENT_CHAT_PROCESS_RUN_PATH`, and returns the existing SSE subscription so\n * the client streams the same events (via the cross-isolate SQL-poll path)\n * with no client change.\n *\n * This module owns ONLY the gating decision + shared constants so both the\n * HTTP handler (`production-agent.ts`) and the processor route\n * (`agent-chat-plugin.ts`) agree on when the path is active without a circular\n * import. The actual run machinery is reused verbatim from run-manager /\n * run-store / self-dispatch / internal-token.\n *\n * GUARDRAIL: when `isAgentChatDurableBackgroundEnabled()` returns false, the\n * agent-chat handler must behave byte-for-byte like the current synchronous\n * path. The gate is true only when ALL of these hold:\n * 1. `AGENT_CHAT_DURABLE_BACKGROUND` env is explicitly enabled, or a\n * workspace app's agent-chat plugin opts in with `durableBackgroundRuns`\n * where the workspace deploy emits a per-app background function by\n * default. Single-template Netlify deploys must set the env flag because\n * that same flag controls whether `server-agent-background` is emitted.\n * 2. The runtime is hosted/serverless (local dev keeps the inline path so SSE\n * stays a single live stream and no second function is needed).\n * 3. `A2A_SECRET` is configured (the HMAC handoff is required to authenticate\n * the background dispatch; without it the dispatch can't be trusted).\n *\n * Opt-in keeps the blast radius small while the worker path is still being\n * proven. And even when enabled, a *dispatch failure degrades to an inline run*:\n * if the self-dispatch self-POST can't be delivered (fast connection error or\n * fast non-2xx), the foreground handler runs the turn synchronously instead of\n * erroring (see `production-agent.ts` — the inline fallback claims the run row\n * atomically so a delayed delivery can never double-execute). So an app where\n * durable dispatch happens to fail still gets a working chat, just without the\n * 15-min budget.\n */\nimport {\n hasConfiguredA2ASecret,\n isTrustedLocalRuntime,\n} from \"../a2a/auth-policy.js\";\nimport {\n extractBearerToken,\n verifyInternalToken,\n} from \"../integrations/internal-token.js\";\n\n/**\n * Framework route the background function actually runs — sibling to\n * `AGENT_TEAM_PROCESS_RUN_PATH`. Reached *through* the Netlify background\n * function, so it inherits the 15-min budget.\n */\nexport const AGENT_CHAT_PROCESS_RUN_PATH =\n \"/_agent-native/agent-chat/_process-run\";\n\n/**\n * Name of the standalone Netlify background function the build emits (see\n * `emitSingleTemplateNetlifyBackgroundFunction` in deploy/build.ts). Shared so\n * the emit and the dispatch-path helper below can never drift on the name.\n *\n * MUST end in `-background` — both because that is the conventional Netlify\n * async-function suffix and because `isInBackgroundFunctionRuntime()` reads the\n * `AWS_LAMBDA_FUNCTION_NAME` `-background` suffix as a secondary runtime signal.\n */\nexport const AGENT_BACKGROUND_FUNCTION_NAME = \"server-agent-background\";\n\n/**\n * Default function URL of the background function on Netlify. Every Netlify\n * function is reachable at `/.netlify/functions/<name>` BY DEFAULT; that default\n * url is removed ONLY if the function declares a custom `config.path`. The\n * emitted background function declares NO custom `config.path` (it sets\n * `background: true` and nothing else routing-related), so it KEEPS this default\n * url — and the Nitro `server` function already excludes `/.netlify/*` from its\n * `/*` catch-all, so this namespace is never shadowed. The foreground therefore\n * dispatches HERE on hosted Netlify (see `resolveAgentChatProcessRunDispatchPath`).\n */\nexport const AGENT_BACKGROUND_FUNCTION_URL_PATH = `/.netlify/functions/${AGENT_BACKGROUND_FUNCTION_NAME}`;\n\n/**\n * Marker carried in a Netlify background-function body when the shared\n * long-running worker should route to a processor other than agent chat.\n * The emitted wrapper defaults to the normal agent-chat `_process-run` route;\n * A2A uses this marker to reuse the same 15-minute function for async tasks.\n */\nexport const AGENT_BACKGROUND_PROCESSOR_FIELD = \"__agentNativeProcessor\";\nexport const AGENT_BACKGROUND_PROCESSOR_A2A = \"a2a\";\nexport const AGENT_BACKGROUND_PROCESSOR_INTEGRATION = \"integration\";\nexport const AGENT_BACKGROUND_PROCESSOR_ROUTE = \"route\";\nexport const AGENT_BACKGROUND_PROCESSOR_ROUTE_FIELD =\n \"__agentNativeProcessorRoute\";\n\n/**\n * The per-app workspace background function URL path. Workspace deploy emits one\n * background function per app named `<app>-agent-background`, reachable at its\n * DEFAULT url `/.netlify/functions/<app>-agent-background` (no custom\n * `config.path`). The foreground resolves the current workspace app id from\n * `AGENT_NATIVE_WORKSPACE_APP_ID` (set by the workspace function entry) so it can\n * dispatch to the right per-app function url. Returns `null` when no workspace\n * app id is configured (single-template deploy).\n */\nfunction resolveWorkspaceBackgroundFunctionUrlPath(): string | null {\n const raw = process.env.AGENT_NATIVE_WORKSPACE_APP_ID;\n if (typeof raw !== \"string\") return null;\n // Mirror the workspace app-id normalization (resources/store.ts): take the\n // first path segment and accept only the safe slug shape used for function\n // names. Anything else falls back to the single-template name.\n const candidate = raw.trim().replace(/^\\/+/, \"\").split(\"/\")[0] ?? \"\";\n if (!/^[a-z0-9][a-z0-9-]{0,127}$/.test(candidate)) return null;\n return `/.netlify/functions/${candidate}-agent-background`;\n}\n\nfunction isNetlifyHostedRuntimeForDispatch(): boolean {\n if (process.env.NETLIFY_LOCAL === \"true\") return false;\n if (process.env.NETLIFY === \"false\") return false;\n if (process.env.NETLIFY && process.env.NETLIFY !== \"false\") return true;\n // NETLIFY is a build-only read-only variable. In deployed Functions Netlify\n // documents URL, SITE_NAME, and SITE_ID as the runtime read-only variables;\n // SITE_ID is the unambiguous host marker. Lambda compatibility mode also\n // exposes AWS runtime variables, so keep the function-name fallback for older\n // deploys. Without either check a modern Netlify Function silently selects the\n // portable framework route even though the emitted background function exists.\n if (process.env.SITE_ID) return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.\n // Non-Netlify AWS falls back inline if the /.netlify/functions dispatch\n // fast-fails.\n return Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME);\n}\n\n/**\n * Resolve the path the foreground POST should self-dispatch the chat background\n * worker to.\n *\n * GROUNDED IN THE REAL NETLIFY BUILD OUTPUT + THE NETLIFY DOCS DEFAULT-URL RULE:\n * the background function is emitted INTO the scanned dir\n * (`.netlify/functions-internal/server-agent-background`, or per-app\n * `<app>-agent-background` for workspaces) with `export const config = {\n * background: true, ... }` and NO custom `config.path`. Because it has no custom\n * path, Netlify keeps its DEFAULT function url `/.netlify/functions/<name>`, and\n * `background: true` makes any invocation of that url ASYNC (immediate 202,\n * 15-min budget). The Nitro `server` function already excludes `/.netlify/*`\n * from its `/*` catch-all, so the default-url namespace is NEVER shadowed by the\n * synchronous function.\n *\n * Therefore on hosted Netlify the foreground dispatches to the function's DEFAULT\n * url (`/.netlify/functions/<name>`); the function entry then rewrites the\n * incoming pathname to `AGENT_CHAT_PROCESS_RUN_PATH` (base-path-prefixed for\n * workspaces) before delegating to the Nitro router, so the `_process-run`\n * plugin runs with the async 15-min budget. Everywhere else (local dev, `netlify\n * dev`, non-Netlify hosts where no second function exists) there is no second\n * function, so the foreground dispatches to the framework route\n * `AGENT_CHAT_PROCESS_RUN_PATH` and the same in-process catch-all handles it\n * inline. The HMAC token (signed over the runId) is unchanged either way.\n *\n * NOTE: this is the DOC-CORRECT approach. An earlier attempt gave the function a\n * custom `config.path` + a catch-all `excludedPath` patch; the custom path was\n * NOT honored as a route in prod (probe → 404). Using the default function url\n * (no custom path) is what Netlify documents and is simpler — there is nothing\n * to shadow because `/.netlify/*` is already excluded from the `server` catch-all.\n */\nexport function resolveAgentChatProcessRunDispatchPath(): string {\n if (isNetlifyHostedRuntimeForDispatch()) {\n return (\n resolveWorkspaceBackgroundFunctionUrlPath() ??\n AGENT_BACKGROUND_FUNCTION_URL_PATH\n );\n }\n return AGENT_CHAT_PROCESS_RUN_PATH;\n}\n\nexport function resolveDurableBackgroundDispatchPath(\n fallbackPath: string,\n): string {\n if (isNetlifyHostedRuntimeForDispatch()) {\n return (\n resolveWorkspaceBackgroundFunctionUrlPath() ??\n AGENT_BACKGROUND_FUNCTION_URL_PATH\n );\n }\n return fallbackPath;\n}\n\nexport function dispatchPathTargetsNetlifyBackgroundFunction(\n dispatchPath: string,\n): boolean {\n return dispatchPath.startsWith(\"/.netlify/functions/\");\n}\n\n/**\n * Env flag for durable background runs. DEFAULT-OFF (opt-in): unset means\n * disabled; an app opts IN with an explicit truthy value (`true`/`1`/`yes`/`on`).\n */\nexport const AGENT_CHAT_DURABLE_BACKGROUND_ENV =\n \"AGENT_CHAT_DURABLE_BACKGROUND\";\n\n/**\n * Body field the foreground handler injects when self-dispatching to the\n * background processor. Its presence is how the re-entered handler knows it is\n * the background worker (run inline with the background soft-timeout; do NOT\n * re-claim the slot or re-dispatch). Untrusted on its own — the route also\n * verifies the HMAC token before invoking the handler.\n */\nexport const AGENT_CHAT_BACKGROUND_RUN_FIELD = \"__backgroundRun\";\n\n/**\n * Mirror of run-manager's private `isHostedRuntime`. Kept in sync deliberately:\n * the durable-background gate must agree with the soft-timeout regime about\n * what \"hosted\" means.\n */\nexport function isHostedRuntimeForDurableBackground(): boolean {\n if (process.env.NETLIFY_LOCAL === \"true\") return false;\n if (process.env.NETLIFY === \"false\") return false;\n if (process.env.SITE_ID) return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.\n if (\n process.env.NETLIFY &&\n process.env.NETLIFY !== \"false\" &&\n process.env.NETLIFY_LOCAL !== \"true\"\n ) {\n return true;\n }\n if (\n process.env.AWS_LAMBDA_FUNCTION_NAME &&\n process.env.NETLIFY_LOCAL !== \"true\"\n ) {\n return true;\n }\n return Boolean(\n process.env.CF_PAGES ||\n process.env.VERCEL ||\n process.env.VERCEL_ENV ||\n process.env.RENDER ||\n process.env.FLY_APP_NAME ||\n process.env.K_SERVICE,\n );\n}\n\n/**\n * True when THIS process is actually executing inside a Netlify *background*\n * function (the long, 15-min-budget async function whose deployed name ends in\n * `-background`). Netlify runs functions on AWS Lambda and sets\n * `AWS_LAMBDA_FUNCTION_NAME` to the function's name, so a `-background` suffix is\n * the runtime proof that the ~60s synchronous wall does NOT apply here.\n *\n * This is the SAFETY GUARD for the soft-timeout regime. The `_process-run`\n * self-dispatch worker (`isBackgroundWorker`) is NOT enough on its own: if the\n * `-background` function was never emitted (deploy gate off, or Netlify routed\n * the path to the synchronous function), the self-POST lands on the regular\n * ~60s `server` function. A worker there MUST use the 40s soft-timeout and\n * checkpoint before the 60s wall — using the ~13min budget would overshoot the\n * hard wall and get killed at 60s, then re-dispatch/resume in a wasteful loop.\n * So the 13-min budget is taken ONLY when this returns true.\n *\n * The PRIMARY signal is a `globalThis` marker the emitted background function's\n * entry sets at cold start — the deployed Lambda name is not guaranteed to end\n * in `-background` on Netlify, so the entry marks its own runtime. A `globalThis`\n * flag (not `process.env`) keeps the no-env-mutation guard satisfied and carries\n * no cross-request state (set once per isolate). The `AWS_LAMBDA_FUNCTION_NAME`\n * suffix and the explicit `AGENT_CHAT_FORCE_BACKGROUND_RUNTIME` env (truthy) are\n * additional signals — the latter an operator escape hatch. Off by default.\n */\nexport function isInBackgroundFunctionRuntime(): boolean {\n // Set by the emitted `-background` function entry at cold start (the primary,\n // most reliable signal — see the emit in deploy/build.ts).\n if (\n (globalThis as Record<string, unknown>)\n .__AGENT_NATIVE_BACKGROUND_RUNTIME__ === true\n ) {\n return true;\n }\n const lambdaName = process.env.AWS_LAMBDA_FUNCTION_NAME;\n if (\n typeof lambdaName === \"string\" &&\n lambdaName.toLowerCase().endsWith(\"-background\")\n ) {\n return true;\n }\n const forced = process.env.AGENT_CHAT_FORCE_BACKGROUND_RUNTIME;\n if (forced != null) {\n const v = forced.trim().toLowerCase();\n return v === \"1\" || v === \"true\" || v === \"yes\" || v === \"on\";\n }\n return false;\n}\n\nexport function backgroundRunMarkerExpectsBackgroundRuntime(\n marker: unknown,\n): boolean {\n return (\n typeof marker === \"object\" &&\n marker !== null &&\n (marker as { backgroundFunctionRuntimeExpected?: unknown })\n .backgroundFunctionRuntimeExpected === true\n );\n}\n\nexport function shouldUseBackgroundFunctionTimeoutForWorker(\n _marker: unknown,\n): boolean {\n // The dispatch marker says which URL the foreground targeted, not where the\n // request actually landed. Only the worker runtime proof can safely lift the\n // hosted 40s clamp to the 15-minute background-function budget.\n return isInBackgroundFunctionRuntime();\n}\n\nexport function backgroundRuntimeDiagnosticDetail(marker: unknown): string {\n return [\n `markerExpected=${backgroundRunMarkerExpectsBackgroundRuntime(marker)}`,\n `runtimeDetected=${isInBackgroundFunctionRuntime()}`,\n `globalMarker=${(globalThis as Record<string, unknown>).__AGENT_NATIVE_BACKGROUND_RUNTIME__ === true}`,\n `lambdaNameEndsBackground=${typeof process.env.AWS_LAMBDA_FUNCTION_NAME === \"string\" && process.env.AWS_LAMBDA_FUNCTION_NAME.toLowerCase().endsWith(\"-background\")}`,\n `forceEnv=${typeof process.env.AGENT_CHAT_FORCE_BACKGROUND_RUNTIME === \"string\" && process.env.AGENT_CHAT_FORCE_BACKGROUND_RUNTIME.trim().length > 0}`,\n ].join(\" \");\n}\n\nfunction isFlagEnabled(): boolean {\n // Read the literal key (not `process.env[CONST]`) so guard:no-env-credentials\n // can statically verify it against the allowlisted `AGENT_*` prefix. Keep this\n // in sync with AGENT_CHAT_DURABLE_BACKGROUND_ENV.\n //\n // DEFAULT-OFF (opt-in): durable background runs are still being hardened. A\n // premature fleet-wide default-on caused real-user incidents (Assets/Analytics\n // hit \"Failed to dispatch\" + stalls, 2026-06-24) because the async background\n // worker path is not yet proven end-to-end and the deploy-time env opt-out is\n // not reliably baked into a given deploy. So an unset/empty/unknown flag means\n // OFF; an app opts IN only with an explicit truthy value\n // (AGENT_CHAT_DURABLE_BACKGROUND=true). This still composes with the hosted +\n // A2A_SECRET gates below. Flip back to default-on only after the 15-min\n // background-function worker is verified live in production (see the\n // project_durable_bg_prod_verified memory).\n const raw = process.env.AGENT_CHAT_DURABLE_BACKGROUND;\n if (raw == null) return false;\n const normalized = raw.trim().toLowerCase();\n return (\n normalized === \"1\" ||\n normalized === \"true\" ||\n normalized === \"yes\" ||\n normalized === \"on\"\n );\n}\n\nfunction isFlagExplicitlyDisabled(): boolean {\n const raw = process.env.AGENT_CHAT_DURABLE_BACKGROUND;\n if (raw == null) return false;\n const normalized = raw.trim().toLowerCase();\n return (\n normalized === \"0\" ||\n normalized === \"false\" ||\n normalized === \"no\" ||\n normalized === \"off\"\n );\n}\n\n/**\n * The single gate. True when the env flag is explicitly enabled, or a workspace\n * app opted in and has a per-app background-function target, AND the runtime is\n * hosted AND A2A_SECRET is configured. False otherwise — and false means the\n * current synchronous behavior is used unchanged. Single-template Netlify app\n * opt-ins deliberately require the env flag too because that flag controls\n * whether the `server-agent-background` function exists in the deploy output.\n */\nexport function isAgentChatDurableBackgroundEnabled(options?: {\n appOptIn?: boolean;\n}): boolean {\n // An app-level opt-out must win over a stale deploy-wide env flag. Netlify\n // environment variables can outlive the source config that originally set\n // them; allowing that flag to re-enable a worker an app explicitly disabled\n // recreates the missing-background-function failure this gate is meant to\n // prevent.\n if (options?.appOptIn === false) return false;\n const envOptIn = isFlagEnabled();\n const workspaceAppOptIn =\n options?.appOptIn === true &&\n !isFlagExplicitlyDisabled() &&\n resolveWorkspaceBackgroundFunctionUrlPath() !== null;\n return (\n (envOptIn || workspaceAppOptIn) &&\n isHostedRuntimeForDurableBackground() &&\n hasConfiguredA2ASecret()\n );\n}\n\n/**\n * Env flag for the FOREGROUND server-driven self-chain. DEFAULT-OFF: a hosted\n * app must explicitly opt in with a truthy value (`true`/`1`/`yes`/`on`). A\n * regular Netlify function has a fixed 60-second wall, and a self-dispatched\n * successor can otherwise be killed before it persists its next continuation.\n * Keep this separate from `AGENT_CHAT_DURABLE_BACKGROUND` so the experimental\n * regular-function chain can be enabled independently after its deployment is\n * proven safe.\n */\nexport const AGENT_CHAT_FOREGROUND_SELF_CHAIN_ENV =\n \"AGENT_CHAT_FOREGROUND_SELF_CHAIN\";\n\nfunction isForegroundSelfChainExplicitlyEnabled(): boolean {\n // Read the literal key (not `process.env[CONST]`) so guard:no-env-credentials\n // can statically verify it against the allowlisted `AGENT_*` prefix. Keep this\n // in sync with AGENT_CHAT_FOREGROUND_SELF_CHAIN_ENV.\n const raw = process.env.AGENT_CHAT_FOREGROUND_SELF_CHAIN;\n if (raw == null) return false;\n const normalized = raw.trim().toLowerCase();\n return (\n normalized === \"1\" ||\n normalized === \"true\" ||\n normalized === \"yes\" ||\n normalized === \"on\"\n );\n}\n\n/**\n * Gate for the foreground self-chain: a normal (non-durable-background)\n * agent-chat turn that hits its soft-timeout chunk boundary continues via a\n * server-side self-dispatch on the REGULAR function (not a Netlify\n * `-background` function) instead of depending on the client to re-POST\n * `auto_continue`. Composes exactly like `isAgentChatDurableBackgroundEnabled`:\n * true only when the env flag is explicitly truthy, the runtime is hosted, and\n * `A2A_SECRET` is configured (the HMAC handoff authenticates the dispatch).\n * False means the existing client-driven `auto_continue` re-POST path is used.\n *\n * Deliberately independent of `isAgentChatDurableBackgroundEnabled`: an app can\n * use this narrower capability without opting into the full 15-min\n * background-function worker path, and the two gates never need to agree.\n * When BOTH would be true for a given run, the durable-background dispatch\n * decision in `production-agent.ts` is evaluated first and takes precedence —\n * a run already dispatched to the durable background worker chains via the\n * existing `isBackgroundWorker` path, not this one.\n */\nexport function isAgentChatForegroundSelfChainEnabled(): boolean {\n return (\n isForegroundSelfChainExplicitlyEnabled() &&\n isHostedRuntimeForDurableBackground() &&\n hasConfiguredA2ASecret()\n );\n}\n\n/** Decision returned by `prepareProcessRunRequest`. */\nexport type ProcessRunPreparation =\n | {\n ok: true;\n /** The pre-claimed run id the background worker must reuse. */\n runId: string;\n /** Body to stash for the re-entered handler (marker guaranteed present). */\n body: Record<string, unknown>;\n }\n | {\n ok: false;\n /** HTTP status the route should return. */\n status: number;\n /** Error payload. */\n error: string;\n /**\n * The run id parsed from the body, when present. Carried even on failure\n * so the route can RECORD the auth/validation failure ONTO the run\n * (diag_stage) before returning the error status — otherwise a 401/503 in\n * the unreadable Netlify background function would leave the run to time\n * out with no clue why. Null when no run id could be parsed.\n */\n runId: string | null;\n };\n\n/**\n * Parse the run id from a `_process-run` request body without authenticating.\n * Mirrors the precedence in `prepareProcessRunRequest` (marker.runId, then\n * top-level taskId). Returns null when neither is a usable string. Used so the\n * route can attach a diagnostic to the run even on an auth/validation failure.\n */\nexport function extractProcessRunId(body: unknown): string | null {\n if (!body || typeof body !== \"object\") return null;\n const record = body as Record<string, unknown>;\n const marker = record[AGENT_CHAT_BACKGROUND_RUN_FIELD] as\n | { runId?: unknown }\n | undefined;\n if (marker && typeof marker.runId === \"string\" && marker.runId) {\n return marker.runId;\n }\n if (typeof record.taskId === \"string\" && record.taskId) {\n return record.taskId;\n }\n return null;\n}\n\n/**\n * Pure, transport-agnostic core of the `_process-run` route: validate the body,\n * authenticate the HMAC self-dispatch, and produce the body the re-entered\n * agent-chat handler should run as the background worker.\n *\n * Auth policy mirrors the agent-teams processor exactly:\n * - `A2A_SECRET` set → require a valid `verifyInternalToken(runId, token)`.\n * - no secret → require `isTrustedLocalRuntime({ loopback })` (see\n * auth-policy.ts): refuse (503) unless `A2A_ALLOW_UNSIGNED_INTERNAL=1` is\n * set. This function has no h3 `event` of its own, so callers that CAN\n * see the inbound socket peer (the route handler, which has the event)\n * should compute `loopback` from it and pass it through; callers that\n * can't determine the peer address should omit it (defaults to `false`\n * — never trust unsigned dispatch without an explicit opt-in).\n *\n * Extracted from the route handler so the auth + marker-prep decision is unit\n * testable without booting the whole Nitro plugin. The route only adds body\n * reading and the final handler invocation around this.\n */\nexport function prepareProcessRunRequest(\n body: unknown,\n authHeader: string | undefined,\n loopback: boolean = false,\n): ProcessRunPreparation {\n if (!body || typeof body !== \"object\") {\n return {\n ok: false,\n status: 400,\n error: \"Invalid request body\",\n runId: null,\n };\n }\n const record = body as Record<string, unknown>;\n const marker = record[AGENT_CHAT_BACKGROUND_RUN_FIELD] as\n | { runId?: unknown }\n | undefined;\n const runId =\n marker && typeof marker.runId === \"string\"\n ? marker.runId\n : typeof record.taskId === \"string\"\n ? (record.taskId as string)\n : \"\";\n if (!runId) {\n return { ok: false, status: 400, error: \"runId required\", runId: null };\n }\n\n if (hasConfiguredA2ASecret()) {\n const token = extractBearerToken(authHeader);\n if (!verifyInternalToken(runId, token ?? \"\")) {\n return {\n ok: false,\n status: 401,\n error: \"Invalid or expired processor token\",\n runId,\n };\n }\n } else if (!isTrustedLocalRuntime({ loopback })) {\n // Callers that can see the h3 `event` (the route handler) pass the real\n // loopback signal; callers without one default to non-loopback. Unsigned\n // dispatch is still allowed via A2A_ALLOW_UNSIGNED_INTERNAL=1 for trusted\n // local/dev setups; see auth-policy.ts `isTrustedLocalRuntime`.\n return {\n ok: false,\n status: 503,\n error:\n \"Agent chat background processor not configured — set A2A_SECRET on this deployment (or A2A_ALLOW_UNSIGNED_INTERNAL=1 for trusted local dev).\",\n runId,\n };\n }\n\n // Ensure the marker is present so the re-entered handler runs as the\n // background worker (reuses runId/turnId, no re-claim, no re-dispatch).\n if (!marker || typeof marker.runId !== \"string\") {\n record[AGENT_CHAT_BACKGROUND_RUN_FIELD] = { runId };\n }\n return { ok: true, runId, body: record };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"run-manager.d.ts","sourceRoot":"","sources":["../../src/agent/run-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-manager.d.ts","sourceRoot":"","sources":["../../src/agent/run-manager.ts"],"names":[],"mappings":"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"}
@@ -187,6 +187,12 @@ function shouldCaptureRunError(err) {
187
187
  * that clamp (and the platform wall behind it) exists.
188
188
  */
189
189
  export function isHostedRuntime() {
190
+ if (process.env.NETLIFY_LOCAL === "true")
191
+ return false;
192
+ if (process.env.NETLIFY === "false")
193
+ return false;
194
+ if (process.env.SITE_ID)
195
+ return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.
190
196
  if (process.env.NETLIFY &&
191
197
  process.env.NETLIFY !== "false" &&
192
198
  process.env.NETLIFY_LOCAL !== "true") {
@@ -1 +1 @@
1
- {"version":3,"file":"run-manager.js","sourceRoot":"","sources":["../../src/agent/run-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { captureError } from \"../server/capture-error.js\";\nimport {\n isLlmCredentialError,\n LLM_MISSING_CREDENTIALS_ERROR_CODE,\n LLM_MISSING_CREDENTIALS_MESSAGE,\n} from \"./engine/credential-errors.js\";\nimport { EngineError } from \"./engine/types.js\";\nimport {\n insertRun,\n insertRunEvent,\n updateRunStatusIfRunning,\n markRunAborted,\n getRunAbortState,\n getRunStatus,\n getRunEventsSince,\n getRunById,\n getRunByThread,\n cleanupOldRuns,\n updateRunHeartbeat,\n bumpRunProgress,\n setRunInFlightMarker,\n reapIfStale,\n reapUnclaimedBackgroundRun,\n shouldRedispatchUnclaimedBackgroundRun,\n reconcileTerminalRunFromEvents,\n ensureTerminalRunEvent,\n getLastTerminalRunEvent,\n resolveErroredRunTerminalEvent,\n setRunError,\n setRunTerminalReason,\n} from \"./run-store.js\";\nimport type { AgentChatEvent, RunEvent, RunStatus } from \"./types.js\";\n\nexport interface ActiveRun {\n runId: string;\n threadId: string;\n /** Logical-turn identity (see StartRunOptions.turnId). Defaults to runId. */\n turnId: string;\n events: RunEvent[];\n status: RunStatus;\n subscribers: Set<(event: RunEvent) => void>;\n abort: AbortController;\n abortReason?: string;\n /**\n * Terminal event to emit when a server-driven continuation has been handed\n * off successfully. The continuation runs outside this process, so the\n * normal loop-level auto_continue event is not sent through this run's\n * `send` callback.\n */\n continuationTerminalEvent?: Extract<\n AgentChatEvent,\n { type: \"auto_continue\" }\n >;\n startedAt: number;\n}\n\nexport interface StartedRun extends ActiveRun {\n /**\n * Resolves after the terminal event and final SQL status have been persisted.\n * Serverless workers must await this before returning or the runtime can\n * freeze the isolate between onComplete and terminalization.\n */\n finalized: Promise<void>;\n}\n\nconst activeRuns = new Map<string, ActiveRun>();\nconst threadToRun = new Map<string, string>();\n\n/** How long to keep completed runs in memory before cleanup (5 min) */\nconst CLEANUP_DELAY_MS = 5 * 60 * 1000;\n\n/**\n * Default run chunk budget for hosted/serverless deploys.\n *\n * This MUST fire before the two upstream hard walls that otherwise kill a run\n * mid-turn with no chance to hand off:\n * 1. The Builder model gateway keeps a 45s cap only for hosted foreground\n * runs; local and proven background-function runs use longer caps.\n * 2. Serverless functions are hard-killed around 60-65s (the heartbeat then\n * reaps the row as a stale_run).\n * Production data showed every cutoff landing in the 44-70s window with ZERO\n * auto_continue events ever emitted — i.e. the old 45s default raced the 45s\n * gateway and lost, and per-template overrides (e.g. 240_000) pushed it past\n * BOTH walls so it could never fire. 40s leaves ~5s of headroom under the\n * gateway wall to abort, persist the partial turn, write the terminal event,\n * and emit a clean auto_continue so the client resumes seamlessly.\n */\nexport const DEFAULT_HOSTED_RUN_SOFT_TIMEOUT_MS = 40_000;\n\n/**\n * Hard ceiling for the hosted soft timeout. On a hosted runtime the\n * foreground auto_continue soft timeout can never usefully exceed this — the\n * synchronous function (~60s) wall kills the run first, so a larger configured\n * or env value just guarantees the cutoff is a hard error instead of a graceful\n * hand-off. Any resolved value above this is clamped down for hosted foreground\n * runs. Local dev (non-hosted) is left alone so long-running local turns aren't\n * chunked.\n *\n * IMPORTANT: this clamp is for the INTERACTIVE / foreground path and must NOT\n * be raised. The foreground POST still rides a synchronous serverless function\n * (~60-65s wall), so 40s remains correct there. The only sanctioned exception\n * is the opt-in `backgroundFunction` mode (see\n * `BACKGROUND_SOFT_TIMEOUT_CEILING_MS`), which runs inside a Netlify background\n * function (no ~60s wall, 15-min budget) and therefore can safely outlast 40s.\n */\nexport const HOSTED_SOFT_TIMEOUT_CEILING_MS = 40_000;\n\n/**\n * Hard ceiling for the soft timeout when a run executes inside a Netlify\n * background function (any deployed function whose name ends in `-background`).\n * Background functions return 202 immediately and run detached for up to 15\n * minutes, so the ~60s synchronous function wall that 40s defends against does\n * NOT apply. 13 minutes leaves ~2 min of headroom under Netlify's 15-min hard\n * kill to abort, persist the partial turn, write the terminal event, and (for\n * the rare >13-min turn) self-fire another background continuation.\n *\n * This ceiling is used ONLY when a caller explicitly opts in with\n * `backgroundFunction: true`. It does not change the foreground/interactive\n * ceiling and does not fire unless the durable-background path dispatched the\n * run into a background function. Per the design doc Guardrail, the 40s\n * interactive clamp stays correct for every non-background run.\n */\nexport const BACKGROUND_SOFT_TIMEOUT_CEILING_MS = 13 * 60_000; // 780_000\n\n/**\n * Default soft-timeout budget for a background-function run when the caller\n * does not pass an explicit `softTimeoutMs`. Same value as the ceiling — we\n * want a background turn to use nearly its whole 15-min budget before handing\n * off to a chained background continuation.\n */\nexport const DEFAULT_BACKGROUND_RUN_SOFT_TIMEOUT_MS =\n BACKGROUND_SOFT_TIMEOUT_CEILING_MS;\n\n/**\n * Default no-progress window for a run executing inside a proven durable\n * background function. Keep this below the 13-minute soft timeout so a truly\n * wedged background turn can still checkpoint, persist, and continue before\n * the function budget expires, but far above the foreground 150s window so\n * large Design/Plan/Assets generations are not chopped up while the model is\n * legitimately planning a big tool payload.\n */\nexport const DEFAULT_BACKGROUND_NO_PROGRESS_TIMEOUT_MS =\n BACKGROUND_SOFT_TIMEOUT_CEILING_MS - 60_000;\n\n/**\n * AUTHORITATIVE no-progress backstop for a run, enforced by the run manager\n * itself (timer-driven, independent of any layer below).\n *\n * The finer-grained watchdogs inside the agent loop (model-stream and\n * action-preparation no-progress, both 90s) only guard the model event stream\n * — a stall in any segment OUTSIDE that guarded loop (engine-call\n * establishment, worker setup between continuation chunks, a wedged transport\n * that emits keepalives while the loop never runs) previously hung forever\n * with the client watching keepalives. This backstop covers every segment by\n * construction: if no REAL progress event (see `shouldBumpProgressForEvent`;\n * keepalives and zero-byte prep activity don't count) lands for this long —\n * and no tool call is in flight (tool execution legitimately emits nothing\n * for minutes and has its own 12-min timeout) — the run manager emits\n * `auto_continue { reason: \"no_progress\" }` and aborts the chunk, exactly\n * like the soft timeout, so the normal continuation machinery recovers it.\n *\n * Sits above the 90s in-loop watchdogs (they get first chance to recover with\n * better context). Foreground hosted chunks keep this short so the user sees\n * recovery promptly; proven durable-background chunks use\n * `DEFAULT_BACKGROUND_NO_PROGRESS_TIMEOUT_MS` so large outputs can use the\n * background budget. Only armed when a soft-timeout regime is active (hosted\n * runs); local dev stays unbounded.\n */\nexport const RUN_NO_PROGRESS_HARD_TIMEOUT_MS = 150_000;\n\n/** Default SQL retention for completed run event logs (24 hours). */\nexport const DEFAULT_COMPLETED_RUN_RETENTION_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Default SQL retention for errored/aborted run event logs (7 days). Kept\n * longer than completed runs so cut-off / failed chats survive for pattern\n * analysis (listErroredRuns) — these are rare and small, and they are exactly\n * the runs we need to study to keep hardening reliability.\n */\nexport const DEFAULT_ERRORED_RUN_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;\n\n/**\n * How recently a terminal run must have started for `/runs/active` to surface\n * it. Reconnect after this window won't replay the run — typical real-world\n * disconnects resolve in seconds, so 10 minutes is generous while keeping us\n * from resurrecting ancient turns when the user reopens an old thread.\n */\nexport const TERMINAL_RUN_RECONNECT_WINDOW_MS = 10 * 60 * 1000;\n\n/** Fast poll cadence while a SQL-backed SSE subscription is actively receiving rows. */\nexport const SQL_SUBSCRIPTION_ACTIVE_POLL_MS = 125;\n\n/** Baseline SQL-backed SSE poll cadence when the run is idle. */\nexport const SQL_SUBSCRIPTION_IDLE_POLL_MS = 500;\n\n/**\n * Keep briefly polling quickly after rows arrive so token streams stay smooth,\n * then back off to the idle cadence if the producer goes quiet.\n */\nexport const SQL_SUBSCRIPTION_ACTIVE_GRACE_MS = 2_000;\n\n/** Keep terminal/status probes at the historical cadence to bound DB work. */\nexport const SQL_SUBSCRIPTION_STATUS_POLL_MS = 500;\n\nexport function resolveSqlSubscriptionPollMs(\n now: number,\n activePollUntil: number,\n): number {\n return now < activePollUntil\n ? SQL_SUBSCRIPTION_ACTIVE_POLL_MS\n : SQL_SUBSCRIPTION_IDLE_POLL_MS;\n}\n\nconst PROVIDER_RATE_LIMITED_ERROR_CODE = \"provider_rate_limited\";\n\nfunction isPreparingActionActivityEvent(event: AgentChatEvent): boolean {\n if (event.type !== \"activity\") return false;\n const label = event.label.trim().toLowerCase();\n return label.startsWith(\"preparing \") && label.includes(\" action\");\n}\n\nfunction getRunErrorMessage(err: unknown): string {\n if (\n typeof err === \"object\" &&\n err !== null &&\n \"message\" in err &&\n typeof err.message === \"string\" &&\n err.message.trim().length > 0\n ) {\n return err.message;\n }\n return \"Unknown error\";\n}\n\nfunction getEngineRunErrorCode(err: EngineError): string | undefined {\n if (err.errorCode) return err.errorCode;\n if (err.statusCode === 429) return PROVIDER_RATE_LIMITED_ERROR_CODE;\n return undefined;\n}\n\nfunction getEngineRunErrorDetails(err: EngineError): string | undefined {\n if (err.statusCode === 429) return err.message;\n return undefined;\n}\n\nfunction shouldCaptureRunError(err: unknown): boolean {\n if (!(err instanceof EngineError)) return true;\n const errorCode = getEngineRunErrorCode(err);\n if (isLlmCredentialError(err, errorCode)) return false;\n if (err.statusCode === 401 || err.statusCode === 403) return false;\n if (/^40[13] status code\\b/i.test(err.message)) return false;\n if (err.message.trim().toLowerCase() === \"connection error.\") return false;\n if (!errorCode) return true;\n const normalizedCode = errorCode.toLowerCase();\n return (\n !normalizedCode.startsWith(\"credits-limit\") &&\n normalizedCode !== \"builder_gateway_network_error\" &&\n normalizedCode !== \"provider_rate_limited\" &&\n normalizedCode !== \"rate_limit_exceeded\"\n );\n}\n\nexport interface StartRunOptions {\n /** Optional internal run chunk budget. When reached, the framework emits an\n * auto-continuation signal instead of a user-facing timeout. Leave unset for\n * no framework-imposed run timeout. */\n softTimeoutMs?: number;\n /** Opt into the hosted/serverless default chunk budget. Only callers with\n * automatic continuation support should enable this. */\n useHostedSoftTimeoutDefault?: boolean;\n /** Stable identity for the logical assistant turn this run belongs to. A\n * turn may span several continuation runs (each chunk is its own run); they\n * share one `turnId` so the durable assistant message can be folded across\n * them instead of dropped per-run. Defaults to the runId (turn == run). */\n turnId?: string;\n /**\n * Opt into the durable-background-function soft-timeout regime for THIS run\n * only. When true, `resolveRunSoftTimeoutMs` lifts the hosted ceiling from\n * 40s to ~13min (`BACKGROUND_SOFT_TIMEOUT_CEILING_MS`) because the run is\n * executing inside a Netlify background function (no ~60s wall). Off by\n * default — the foreground/interactive path never sets this, so its 40s\n * clamp is unchanged. See the design doc + the durable-background dispatch\n * decision in production-agent.ts.\n */\n backgroundFunction?: boolean;\n /**\n * Override the run-manager-level no-progress backstop\n * (`RUN_NO_PROGRESS_HARD_TIMEOUT_MS`). `0` disables it. Defaults to the\n * backstop constant whenever a soft-timeout regime is active (hosted runs)\n * and to disabled otherwise (local dev stays unbounded).\n */\n noProgressTimeoutMs?: number;\n /**\n * Lifecycle metadata persisted to `agent_runs.dispatch_mode` and surfaced to\n * clients through `/runs/active`. This does not change run-manager behavior;\n * callers use it to describe who owns continuation at hosted chunk boundaries.\n */\n dispatchMode?: \"foreground\" | \"foreground-self-chain\";\n}\n\nexport interface ResolveRunSoftTimeoutOptions {\n useHostedDefault?: boolean;\n /**\n * Resolve the soft timeout for a run executing inside a Netlify background\n * function. Lifts the hosted clamp to `BACKGROUND_SOFT_TIMEOUT_CEILING_MS`\n * (~13min) for this invocation only and, when no override/env is supplied,\n * defaults to `DEFAULT_BACKGROUND_RUN_SOFT_TIMEOUT_MS`. Does NOT change the\n * foreground ceiling. Off by default.\n */\n backgroundFunction?: boolean;\n}\n\n/**\n * True on hosted/serverless runtimes where the soft-timeout regime applies\n * (see `resolveRunSoftTimeoutMs`, which resolves to 0 — disabled — off these\n * runtimes). Exported so production-agent.ts can gate its foreground\n * first-model-event cap (`FOREGROUND_FIRST_MODEL_EVENT_TIMEOUT_MS`) on the\n * SAME predicate that selects the 40s clamp: the cap only makes sense where\n * that clamp (and the platform wall behind it) exists.\n */\nexport function isHostedRuntime(): boolean {\n if (\n process.env.NETLIFY &&\n process.env.NETLIFY !== \"false\" &&\n process.env.NETLIFY_LOCAL !== \"true\"\n ) {\n return true;\n }\n if (\n process.env.AWS_LAMBDA_FUNCTION_NAME &&\n process.env.NETLIFY_LOCAL !== \"true\"\n ) {\n return true;\n }\n return Boolean(\n process.env.CF_PAGES ||\n process.env.VERCEL ||\n process.env.VERCEL_ENV ||\n process.env.RENDER ||\n process.env.FLY_APP_NAME ||\n process.env.K_SERVICE,\n );\n}\n\nexport function resolveRunSoftTimeoutMs(\n overrideMs?: number,\n options?: ResolveRunSoftTimeoutOptions,\n): number {\n const hosted = isHostedRuntime();\n const background = options?.backgroundFunction === true;\n // The interactive/foreground ceiling is 40s — the synchronous serverless\n // function wall. A background-function run (opt-in only) has no ~60s wall, so\n // it is allowed to outlast that and is clamped to the larger 13-min ceiling\n // instead. The 40s clamp for non-background hosted runs is unchanged.\n const ceiling = background\n ? BACKGROUND_SOFT_TIMEOUT_CEILING_MS\n : HOSTED_SOFT_TIMEOUT_CEILING_MS;\n // A configured/env soft timeout that exceeds the upstream walls can never\n // actually fire (the gateway/function kills the run first), so clamp it down\n // on hosted runtimes. This is what makes auto_continue reach the client\n // instead of the run dying as builder_gateway_timeout / stale_run. `0` means\n // \"disabled\" and is never clamped up.\n const clampHosted = (ms: number): number =>\n hosted && ms > ceiling ? ceiling : ms;\n\n if (typeof overrideMs === \"number\" && Number.isFinite(overrideMs)) {\n return clampHosted(Math.max(0, overrideMs));\n }\n const envValue = process.env.AGENT_RUN_SOFT_TIMEOUT_MS;\n if (envValue !== undefined) {\n const raw = Number(envValue);\n if (Number.isFinite(raw) && raw >= 0) return clampHosted(raw);\n }\n // A background-function run uses the full background budget by default; the\n // foreground default (40s) is unchanged.\n if (background) {\n return hosted ? DEFAULT_BACKGROUND_RUN_SOFT_TIMEOUT_MS : 0;\n }\n return options?.useHostedDefault && hosted\n ? DEFAULT_HOSTED_RUN_SOFT_TIMEOUT_MS\n : 0;\n}\n\nexport function resolveCompletedRunRetentionMs(): number {\n const envValue = process.env.AGENT_RUN_RETENTION_MS;\n if (envValue !== undefined) {\n const raw = Number(envValue);\n if (Number.isFinite(raw) && raw >= 0) return raw;\n }\n return DEFAULT_COMPLETED_RUN_RETENTION_MS;\n}\n\nexport function resolveErroredRunRetentionMs(): number {\n const envValue = process.env.AGENT_ERRORED_RUN_RETENTION_MS;\n if (envValue !== undefined) {\n const raw = Number(envValue);\n if (Number.isFinite(raw) && raw >= 0) return raw;\n }\n return DEFAULT_ERRORED_RUN_RETENTION_MS;\n}\n\nfunction isTerminalRunEvent(event: AgentChatEvent): boolean {\n return (\n event.type === \"done\" ||\n event.type === \"error\" ||\n event.type === \"missing_api_key\" ||\n event.type === \"loop_limit\" ||\n event.type === \"auto_continue\"\n );\n}\n\nfunction terminalEventForcesErroredStatus(event: AgentChatEvent | null) {\n return event?.type === \"error\" || event?.type === \"missing_api_key\";\n}\n\nfunction terminalReasonForRun(\n finalStatus: \"completed\" | \"errored\" | \"aborted\",\n terminalEvent: AgentChatEvent | null,\n abortReason: string | undefined,\n completionError: unknown,\n): string {\n if (terminalEvent?.type === \"auto_continue\") {\n return terminalEvent.reason || \"auto_continue\";\n }\n if (terminalEvent?.type === \"loop_limit\") return \"loop_limit\";\n if (terminalEvent?.type === \"missing_api_key\") return \"missing_api_key\";\n if (terminalEvent?.type === \"error\") {\n return `error:${terminalEvent.errorCode || \"unknown\"}`;\n }\n if (finalStatus === \"aborted\") return `aborted:${abortReason ?? \"user\"}`;\n if (completionError) return \"completion_error\";\n if (finalStatus === \"errored\") return \"error:unknown\";\n return \"done\";\n}\n\nfunction abortInMemoryRun(run: ActiveRun, reason: string = \"user\") {\n run.abortReason = reason;\n run.status = \"aborted\";\n if (threadToRun.get(run.threadId) === run.runId) {\n threadToRun.delete(run.threadId);\n }\n run.abort.abort(reason);\n for (const subscriber of run.subscribers) {\n try {\n subscriber({ seq: run.events.length, event: { type: \"done\" } });\n } catch {\n // ignore — subscriber is being removed below\n }\n }\n run.subscribers.clear();\n}\n\n/**\n * Start a new agent run in the background.\n * `runFn` receives a `send` callback and an `AbortSignal`.\n * The run continues even if all SSE subscribers disconnect.\n *\n * Events are persisted to SQL for cross-isolate access (Cloudflare Workers).\n */\nexport function startRun(\n runId: string,\n threadId: string,\n runFn: (\n send: (event: AgentChatEvent) => void,\n signal: AbortSignal,\n ) => Promise<void>,\n onComplete?: (run: ActiveRun) => void | Promise<void>,\n options?: StartRunOptions,\n): StartedRun {\n // If there's already a run for this thread, abort it\n const existingRunId = threadToRun.get(threadId);\n if (existingRunId) {\n abortRun(existingRunId);\n }\n\n const abort = new AbortController();\n let softTimedOut = false;\n let resolveFinalized: () => void = () => {};\n let rejectFinalized: (reason?: unknown) => void = () => {};\n const finalized = new Promise<void>((resolve, reject) => {\n resolveFinalized = resolve;\n rejectFinalized = reject;\n });\n // Foreground callers do not await this promise, but terminal persistence\n // failures must still be observable to background workers without creating\n // an unhandled rejection in the foreground path.\n void finalized.catch(() => {});\n const run: StartedRun = {\n runId,\n threadId,\n turnId: options?.turnId ?? runId,\n events: [],\n status: \"running\",\n subscribers: new Set(),\n abort,\n startedAt: Date.now(),\n finalized,\n };\n\n activeRuns.set(runId, run);\n threadToRun.set(threadId, runId);\n\n const captureRunPersistenceError = (\n error: unknown,\n phase: \"insert-run\" | \"insert-event\",\n extra: Record<string, unknown> = {},\n ) => {\n captureError(error, {\n route: \"/_agent-native/agent-chat\",\n tags: {\n source: \"agent-run-manager\",\n phase,\n runStatus: run.status,\n },\n extra: {\n runId,\n threadId,\n eventCount: run.events.length,\n startedAt: run.startedAt,\n ...extra,\n },\n contexts: {\n agentRun: {\n runId,\n threadId,\n status: run.status,\n phase,\n eventCount: run.events.length,\n startedAt: run.startedAt,\n },\n },\n });\n };\n\n // Persist run to SQL without blocking the response. Keep the promise so\n // final status cannot race ahead of a slow initial INSERT and then get\n // overwritten by a late row stuck at status='running'.\n const insertOptions = options?.dispatchMode\n ? { dispatchMode: options.dispatchMode }\n : undefined;\n const insertRunPromise = (\n insertOptions\n ? insertRun(runId, threadId, options?.turnId, insertOptions)\n : insertRun(runId, threadId, options?.turnId)\n ).catch((error) => {\n captureRunPersistenceError(error, \"insert-run\");\n });\n\n // Per-run event persistence chain: events are chained so SQL inserts commit\n // in seq order. Without this, a fast seq=5 commit before a slow seq=4 means\n // the SQL poller advances its cursor past seq=4 (lastSeq = 5+1 = 6) and\n // reconnecting clients permanently miss that event (silent gap). Chaining\n // per run ensures order without blocking the fast in-memory SSE path.\n let persistenceChain: Promise<void> = Promise.resolve();\n\n // Throttle the durable progress timestamp to at most once per second so\n // a chatty token-by-token stream doesn't translate into one DB write per\n // chunk. The stuck-detector threshold is on the order of tens of seconds,\n // so 1s resolution is plenty.\n let lastProgressBumpAt = 0;\n const preparingActivityBytes = new Map<string, number>();\n const preparingActivityTools = new Map<string, string>();\n const preparingActivityRestartHighWater = new Map<string, number>();\n let eventPersistenceErrorCaptured = false;\n const bumpProgressIfDue = () => {\n const now = Date.now();\n if (now - lastProgressBumpAt < 1000) return;\n lastProgressBumpAt = now;\n bumpRunProgress(runId).catch(() => {});\n };\n const shouldBumpProgressForEvent = (event: AgentChatEvent): boolean => {\n if (event.type === \"stream_keepalive\") return false;\n if (event.type === \"clear\") {\n for (const [key, bytes] of preparingActivityBytes) {\n const toolKey = preparingActivityTools.get(key) ?? key;\n preparingActivityRestartHighWater.set(\n toolKey,\n Math.max(preparingActivityRestartHighWater.get(toolKey) ?? 0, bytes),\n );\n }\n preparingActivityBytes.clear();\n preparingActivityTools.clear();\n return false;\n }\n if (event.type === \"activity\" && isPreparingActionActivityEvent(event)) {\n const toolKey = event.tool?.trim() || event.label.trim();\n const activityKey = `${toolKey}:${event.id?.trim() || \"no-id\"}`;\n const progressBytes =\n typeof event.progressBytes === \"number\" &&\n Number.isFinite(event.progressBytes) &&\n event.progressBytes >= 0\n ? Math.floor(event.progressBytes)\n : undefined;\n if (progressBytes === undefined) return false;\n const restartHighWater =\n preparingActivityRestartHighWater.get(toolKey) ?? 0;\n if (!event.id?.trim()) {\n if (progressBytes <= restartHighWater) return false;\n preparingActivityTools.set(activityKey, toolKey);\n preparingActivityBytes.set(\n activityKey,\n Math.max(preparingActivityBytes.get(activityKey) ?? 0, progressBytes),\n );\n if (preparingActivityRestartHighWater.has(toolKey)) {\n preparingActivityRestartHighWater.set(\n toolKey,\n Math.max(restartHighWater, progressBytes),\n );\n }\n return progressBytes > 0;\n }\n const previousBytes = Math.max(\n preparingActivityBytes.get(activityKey) ?? 0,\n restartHighWater,\n );\n if (\n !preparingActivityBytes.has(activityKey) &&\n progressBytes === 0 &&\n !preparingActivityRestartHighWater.has(toolKey)\n ) {\n preparingActivityTools.set(activityKey, toolKey);\n preparingActivityBytes.set(activityKey, 0);\n preparingActivityRestartHighWater.set(toolKey, 0);\n return true;\n }\n if (progressBytes <= previousBytes) {\n preparingActivityTools.set(activityKey, toolKey);\n preparingActivityBytes.set(\n activityKey,\n Math.max(previousBytes, progressBytes),\n );\n return false;\n }\n preparingActivityTools.set(activityKey, toolKey);\n preparingActivityBytes.set(activityKey, progressBytes);\n if (preparingActivityRestartHighWater.has(toolKey)) {\n preparingActivityRestartHighWater.set(\n toolKey,\n Math.max(\n preparingActivityRestartHighWater.get(toolKey) ?? 0,\n progressBytes,\n ),\n );\n }\n return true;\n }\n if (event.type === \"tool_start\" || event.type === \"tool_done\") {\n preparingActivityBytes.clear();\n preparingActivityTools.clear();\n preparingActivityRestartHighWater.clear();\n }\n if (event.type === \"done\" || event.type === \"error\") {\n preparingActivityBytes.clear();\n preparingActivityTools.clear();\n preparingActivityRestartHighWater.clear();\n }\n return true;\n };\n\n // ── No-progress backstop (see RUN_NO_PROGRESS_HARD_TIMEOUT_MS) ──────────\n // Timer-driven and independent of the agent loop, so it fires even when the\n // stall is in a segment the in-loop watchdogs never see (engine-call\n // establishment, setup, a wedged transport emitting keepalives). Tool calls\n // and sub-agent calls in flight suspend it — tool execution legitimately\n // emits nothing for minutes and carries its own 12-min timeout.\n let lastRealProgressAt = Date.now();\n let inFlightWorkCount = 0;\n const trackInFlightWork = (event: AgentChatEvent) => {\n const wasIdle = inFlightWorkCount === 0;\n if (event.type === \"tool_start\") {\n inFlightWorkCount += 1;\n } else if (event.type === \"tool_done\") {\n inFlightWorkCount = Math.max(0, inFlightWorkCount - 1);\n } else if (event.type === \"agent_call\") {\n if (event.status === \"start\") {\n inFlightWorkCount += 1;\n } else {\n inFlightWorkCount = Math.max(0, inFlightWorkCount - 1);\n }\n } else {\n return; // Not a work-tracking event — no transition possible.\n }\n // Mirror the 0<->N transition into SQL so a stale reaper running in a\n // DIFFERENT isolate (a client's SQL-subscription poll, a sibling\n // isolate's opportunistic cleanup, a fresh boot's startup sweep) can\n // grant this demonstrably-alive run a bounded grace even when THIS\n // isolate's own heartbeat write is failing (e.g. Neon pooler saturation)\n // — `inFlightWorkCount` itself is in-memory and invisible to those other\n // isolates. Fire-and-forget: never block event emission on this write,\n // and a write failure here is no worse than today's behavior (the row\n // just gets no grace). See `setRunInFlightMarker` / `IN_FLIGHT_RUN_STALE_GRACE_MS`\n // in run-store.ts for the full reasoning and the bounded-grace derivation.\n if (wasIdle && inFlightWorkCount > 0) {\n setRunInFlightMarker(runId, true).catch(() => {});\n } else if (!wasIdle && inFlightWorkCount === 0) {\n setRunInFlightMarker(runId, false).catch(() => {});\n }\n };\n const checkNoProgressBackstop = () => {\n if (noProgressTimeoutMs <= 0) return;\n if (run.status !== \"running\" || abort.signal.aborted) return;\n if (inFlightWorkCount > 0) return;\n if (Date.now() - lastRealProgressAt < noProgressTimeoutMs) return;\n console.error(\n `[run-manager] no real progress for ${noProgressTimeoutMs}ms with no tool in flight — ` +\n `checkpointing run for continuation`,\n runId,\n );\n // Mirror the soft-timeout semantics exactly: the chunk completes (not\n // aborts) at an auto_continue boundary, so the continuation machinery —\n // server-chained for background workers, client-driven for foreground —\n // recovers the turn.\n softTimedOut = true;\n send({ type: \"auto_continue\", reason: \"no_progress\" });\n abort.abort(\"no_progress\");\n };\n\n // Periodic SQL abort check interval (for cross-isolate abort on Workers).\n // Also self-aborts when our row is no longer status='running' — catches the\n // false-stale-reap zombie scenario where the reaper flipped the row while\n // this isolate was briefly unable to heartbeat (DB latency / GC pause).\n let lastAbortCheck = Date.now() - 3000;\n const checkSqlAbort = () => {\n const now = Date.now();\n if (now - lastAbortCheck < 3000) return;\n lastAbortCheck = now;\n getRunAbortState(runId)\n .then(async (state) => {\n if (state.aborted && !abort.signal.aborted) {\n abortInMemoryRun(run, state.reason ?? \"user\");\n return;\n }\n // If the row is no longer 'running' (reaped / replaced) and we're\n // still executing, self-abort so we stop executing and don't overwrite\n // the newer state with our terminal write.\n if (!abort.signal.aborted) {\n const status = await getRunStatus(runId);\n if (status !== null && status !== \"running\") {\n abortInMemoryRun(run, \"displaced\");\n }\n }\n })\n .catch(() => {});\n };\n\n // Heartbeat: bump heartbeat_at every 1.5s so watchers can detect a dead\n // producer (process crash, HMR restart, isolate eviction) quickly and\n // reap the row. Paired with RUN_STALE_MS (15s) — 10x the interval to\n // tolerate transient DB slowness without false positives.\n let consecutiveHeartbeatFailures = 0;\n // Single-flight the heartbeat write. The timer fires every 1.5s but a write\n // can take up to the DB op timeout (~8s) when the Neon pooler is saturated.\n // Firing a fresh write each tick regardless piled up ~5 concurrent writes\n // under contention, each holding a pooler connection — ADDING to the exact\n // connection-cap exhaustion that starves the heartbeat and false-reaps the\n // run as stale. Skip a tick's write while one is still outstanding so a run\n // holds at most one heartbeat connection. The abort/backstop checks below\n // still run every tick (they don't touch the DB on the hot path).\n let heartbeatInFlight = false;\n const heartbeatTimer: ReturnType<typeof setInterval> = setInterval(() => {\n if (!heartbeatInFlight) {\n heartbeatInFlight = true;\n updateRunHeartbeat(runId)\n .then(() => {\n consecutiveHeartbeatFailures = 0;\n })\n .catch((error) => {\n consecutiveHeartbeatFailures += 1;\n // Swallow routine single-tick blips; escalate once failures approach\n // the stale window so false-positive stale_run from silent write\n // failures is diagnosable.\n if (consecutiveHeartbeatFailures >= 3) {\n captureError(error, {\n route: \"/_agent-native/agent-chat\",\n tags: {\n source: \"agent-run-manager\",\n phase: \"heartbeat\",\n consecutiveFailures: String(consecutiveHeartbeatFailures),\n },\n extra: { runId, threadId },\n });\n }\n })\n .finally(() => {\n heartbeatInFlight = false;\n });\n }\n checkSqlAbort();\n checkNoProgressBackstop();\n }, 1500);\n const softTimeoutMs = resolveRunSoftTimeoutMs(options?.softTimeoutMs, {\n useHostedDefault: options?.useHostedSoftTimeoutDefault === true,\n backgroundFunction: options?.backgroundFunction === true,\n });\n // Armed only when a soft-timeout regime is active (hosted): local dev keeps\n // unbounded runs. For 40s foreground chunks the soft timeout always fires\n // first, so in practice this guards the long background chunks.\n const noProgressTimeoutMs =\n options?.noProgressTimeoutMs ??\n (softTimeoutMs > 0\n ? options?.backgroundFunction === true\n ? DEFAULT_BACKGROUND_NO_PROGRESS_TIMEOUT_MS\n : RUN_NO_PROGRESS_HARD_TIMEOUT_MS\n : 0);\n const softTimeoutTimer =\n softTimeoutMs > 0\n ? setTimeout(() => {\n if (run.status !== \"running\" || abort.signal.aborted) return;\n softTimedOut = true;\n send({\n type: \"auto_continue\",\n reason: \"run_timeout\",\n });\n abort.abort(\"run_timeout\");\n }, softTimeoutMs)\n : null;\n let pendingTerminalEvent: RunEvent | null = null;\n\n const captureRunError = (error: unknown, phase: \"run\" | \"completion\") => {\n const errorCode =\n error instanceof EngineError ? getEngineRunErrorCode(error) : undefined;\n captureError(error, {\n route: \"/_agent-native/agent-chat\",\n tags: {\n source: \"agent-run-manager\",\n phase,\n runStatus: run.status,\n softTimedOut: softTimedOut ? \"true\" : \"false\",\n abortReason: run.abortReason,\n errorCode,\n },\n extra: {\n runId,\n threadId,\n eventCount: run.events.length,\n startedAt: run.startedAt,\n softTimeoutMs,\n },\n contexts: {\n agentRun: {\n runId,\n threadId,\n status: run.status,\n phase,\n eventCount: run.events.length,\n startedAt: run.startedAt,\n softTimeoutMs,\n softTimedOut,\n abortReason: run.abortReason,\n },\n },\n });\n };\n\n const emitRunEvent = (\n runEvent: RunEvent,\n options?: { surfacePersistenceError?: boolean },\n ): Promise<void> => {\n run.events.push(runEvent);\n\n // Notify in-memory subscribers (same isolate, fast path)\n for (const subscriber of run.subscribers) {\n try {\n subscriber(runEvent);\n } catch {\n run.subscribers.delete(subscriber);\n }\n }\n\n // Bump the durable progress timestamp. Distinct from the heartbeat:\n // heartbeat = \"process is up\", progress = \"real work is happening.\" The\n // gap between them is what the client-side stuck-detector reads to tell\n // a hung run from a healthy one. Keepalive and zero-byte action prep are\n // liveness only; streamed input bytes, text, and tool lifecycle events are\n // real progress.\n trackInFlightWork(runEvent.event);\n if (shouldBumpProgressForEvent(runEvent.event)) {\n lastRealProgressAt = Date.now();\n bumpProgressIfDue();\n }\n\n // Persist event to SQL. Events are chained through persistenceChain so\n // inserts commit in seq order — an out-of-order commit would advance the\n // SQL poller's cursor past the slow row, permanently dropping it for\n // reconnecting clients. Terminal events surface persistence errors so the\n // caller can decide how to handle a failed final write.\n const thisInsert = persistenceChain.then(() =>\n insertRunEvent(runId, runEvent.seq, JSON.stringify(runEvent.event)),\n );\n persistenceChain = thisInsert.catch((error) => {\n if (!eventPersistenceErrorCaptured) {\n eventPersistenceErrorCaptured = true;\n captureRunPersistenceError(error, \"insert-event\", {\n seq: runEvent.seq,\n eventType: runEvent.event.type,\n });\n }\n });\n const persistence = thisInsert;\n if (!options?.surfacePersistenceError) {\n persistence.catch(() => {});\n }\n\n checkSqlAbort();\n return persistence;\n };\n\n const send = (event: AgentChatEvent) => {\n if (run.status === \"aborted\" && abort.signal.aborted) return;\n\n const runEvent: RunEvent = { seq: run.events.length, event };\n if (isTerminalRunEvent(event)) {\n pendingTerminalEvent = runEvent;\n return;\n }\n\n emitRunEvent(runEvent);\n };\n\n // Run in background — intentionally detached from any HTTP connection\n const runPromise = runFn(send, abort.signal)\n .then(() => {\n if (abort.signal.aborted) {\n run.status = softTimedOut ? \"completed\" : \"aborted\";\n return;\n }\n run.status = \"completed\";\n })\n .catch((err) => {\n // Don't surface abort errors — the run was intentionally stopped\n if (abort.signal.aborted) {\n run.status = softTimedOut ? \"completed\" : \"aborted\";\n return;\n }\n run.status = \"errored\";\n if (shouldCaptureRunError(err)) {\n captureRunError(err, \"run\");\n }\n const errorMessage = getRunErrorMessage(err);\n const errorCode =\n err instanceof EngineError ? getEngineRunErrorCode(err) : undefined;\n const details =\n err instanceof EngineError ? getEngineRunErrorDetails(err) : undefined;\n send({\n type: \"error\",\n error: errorMessage,\n ...(errorCode ? { errorCode } : {}),\n ...(details ? { details } : {}),\n ...(err instanceof EngineError && err.upgradeUrl\n ? { upgradeUrl: err.upgradeUrl }\n : {}),\n });\n })\n .finally(async () => {\n // Ordering matters here — this is the atomic-complete boundary.\n // Invariant: once agent_runs.status flips to \"completed\"/\"errored\"\n // in SQL, thread_data for this turn is already durable. This lets\n // reconnecting clients trust the simple rule \"status != running →\n // fetch thread_data\" without polling/retrying for a race window\n // where onComplete was still pending.\n\n // 1. Await the completion callback (thread_data save). Heartbeat is\n // still ticking so the run doesn't look stale to any concurrent\n // /runs/active check while we wait for SQL writes to land.\n let completionError: unknown = null;\n let terminalPersistenceError: unknown = null;\n const resolveTerminalEventForCompletion = () => {\n const continuationTerminalEvent = run.continuationTerminalEvent\n ? {\n seq: run.events.length,\n event: run.continuationTerminalEvent,\n }\n : null;\n return continuationTerminalEvent ?? pendingTerminalEvent;\n };\n let terminalEventForCompletion = resolveTerminalEventForCompletion();\n let terminalEvent = terminalEventForCompletion?.event ?? null;\n if (\n onComplete &&\n !(run.status === \"aborted\" && run.abortReason === \"no_progress\")\n ) {\n try {\n const completionStatus =\n run.status !== \"aborted\" &&\n terminalEventForcesErroredStatus(terminalEvent)\n ? \"errored\"\n : run.status;\n const completionRun: ActiveRun =\n terminalEventForCompletion || completionStatus !== run.status\n ? {\n ...run,\n status: completionStatus,\n events: terminalEventForCompletion\n ? [...run.events, terminalEventForCompletion]\n : run.events,\n }\n : run;\n await onComplete(completionRun);\n } catch (err) {\n completionError = err;\n captureRunError(err, \"completion\");\n console.error(\n \"[run-manager] onComplete callback error:\",\n err instanceof Error ? err.message : err,\n );\n }\n }\n\n // Server-driven continuation is installed by onComplete after the\n // successor has been dispatched. Resolve the terminal event again so\n // this chunk emits auto_continue instead of a misleading done event.\n terminalEventForCompletion = resolveTerminalEventForCompletion();\n terminalEvent = terminalEventForCompletion?.event ?? null;\n\n // 2. Compute final status. If the completion callback threw, we'd\n // rather mark the run errored than claim success with incomplete\n // thread_data.\n const finalStatus =\n run.status === \"aborted\"\n ? \"aborted\"\n : run.status === \"errored\" ||\n completionError ||\n terminalEventForcesErroredStatus(terminalEvent)\n ? \"errored\"\n : \"completed\";\n const terminalReason = terminalReasonForRun(\n finalStatus,\n terminalEvent,\n run.abortReason,\n completionError,\n );\n\n // 3. Emit the terminal event only after thread_data is durable. Live\n // SSE clients close on this event and usually fetch thread_data\n // immediately, so emitting it earlier recreates the final-message\n // race this manager is meant to avoid.\n if (finalStatus === \"completed\" || finalStatus === \"errored\") {\n // Choose the terminal event payload (done / the stashed terminal /\n // a synthesized error). NOTE: the `seq` carried by\n // `pendingTerminalEvent` was captured by `send()` at stash time as\n // `run.events.length` and is NOT authoritative — if the runFn emitted\n // any more events before it actually stopped on the abort signal,\n // those events were pushed and reused that same seq. Persisting the\n // terminal event with the stale seq would collide with an\n // already-persisted streaming event and get silently dropped by\n // insertRunEvent's `ON CONFLICT (run_id, seq) DO NOTHING`, so the\n // client would never see the terminal/continuation signal. We always\n // re-stamp the seq at emit time (max-seq+1) just below.\n const terminalEvent: AgentChatEvent =\n finalStatus === \"completed\"\n ? (terminalEventForCompletion?.event ?? { type: \"done\" })\n : terminalEventForCompletion?.event.type === \"error\" ||\n terminalEventForCompletion?.event.type === \"missing_api_key\"\n ? terminalEventForCompletion.event\n : terminalEventForCompletion?.event.type === \"auto_continue\"\n ? // The run was checkpointed at a soft-timeout/loop boundary and\n // is recoverable: the partial turn is in agent_run_events and\n // the continuation run will re-attempt the thread_data save.\n // Even though the completion save failed (finalStatus stays\n // \"errored\" for SQL/diagnostics), re-emit the auto_continue so\n // the client resumes instead of seeing a dead chat.\n terminalEventForCompletion.event\n : {\n type: \"error\",\n error: completionError\n ? \"Agent response could not be saved.\"\n : \"Agent run ended unexpectedly\",\n };\n const last = run.events[run.events.length - 1];\n if (!last || !isTerminalRunEvent(last.event)) {\n // Assign the seq at EMIT time, not at stash time. `run.events` is a\n // contiguous 0-based log, so `run.events.length` is the next free\n // seq and can never collide with an event that was pushed after the\n // terminal event was stashed.\n const terminal: RunEvent = {\n seq: run.events.length,\n event: terminalEvent,\n };\n try {\n await emitRunEvent(terminal, { surfacePersistenceError: true });\n } catch (err) {\n terminalPersistenceError = err;\n captureRunError(err, \"completion\");\n console.error(\n \"[run-manager] terminal event persistence error:\",\n err instanceof Error ? err.message : err,\n );\n try {\n await insertRunEvent(\n runId,\n terminal.seq,\n JSON.stringify(terminal.event),\n );\n terminalPersistenceError = null;\n } catch (retryError) {\n terminalPersistenceError = retryError;\n captureRunError(retryError, \"completion\");\n console.error(\n \"[run-manager] terminal event retry persistence error:\",\n retryError instanceof Error ? retryError.message : retryError,\n );\n }\n }\n }\n }\n for (const subscriber of run.subscribers) {\n run.subscribers.delete(subscriber);\n }\n\n // 4. Stop the heartbeat — all liveness writes are done.\n clearInterval(heartbeatTimer);\n if (softTimeoutTimer) clearTimeout(softTimeoutTimer);\n\n // 5. Persist final status to SQL. Use the conditional write so a zombie\n // run (reaped or displaced while executing) cannot clobber the newer\n // status written by the reaper or a replacement run.\n try {\n await insertRunPromise;\n if (!terminalPersistenceError) {\n let statusUpdated = false;\n try {\n statusUpdated = await updateRunStatusIfRunning(runId, finalStatus);\n } catch {\n statusUpdated = false;\n }\n if (statusUpdated) {\n await setRunTerminalReason(runId, terminalReason);\n } else {\n await reconcileTerminalRunFromEvents(runId).catch(() => false);\n }\n }\n } catch {\n // Best-effort — reapIfStale will eventually clean this up via\n // the heartbeat-stale path.\n }\n\n // 5b. Record terminal failure classification for errored runs so\n // cut-off / failed chats are queryable for pattern analysis. Read\n // the actual error event the run emitted (errorCode + message) so\n // diagnostics reflect the real cause (builder_gateway_timeout,\n // stale_run, context_length_exceeded, completion_error, …).\n if (finalStatus === \"errored\") {\n let errorCode: string | undefined;\n let errorDetail: string | undefined;\n const diagnosticEvents = pendingTerminalEvent\n ? [...run.events, pendingTerminalEvent]\n : run.events;\n for (let i = diagnosticEvents.length - 1; i >= 0; i--) {\n const ev = diagnosticEvents[i].event as {\n type: string;\n error?: string;\n errorCode?: string;\n details?: string;\n };\n if (ev.type === \"missing_api_key\") {\n errorCode = LLM_MISSING_CREDENTIALS_ERROR_CODE;\n errorDetail = LLM_MISSING_CREDENTIALS_MESSAGE;\n break;\n } else if (ev.type === \"error\") {\n errorCode = ev.errorCode;\n errorDetail = ev.error ?? ev.details;\n break;\n }\n }\n if (completionError && !errorCode) {\n errorCode = \"completion_error\";\n errorDetail =\n errorDetail ??\n (completionError instanceof Error\n ? completionError.message\n : String(completionError));\n }\n await setRunError(runId, errorCode ?? \"unknown\", errorDetail);\n }\n\n if (terminalPersistenceError) {\n const reconciled = await reconcileTerminalRunFromEvents(runId).catch(\n () => false,\n );\n if (!reconciled) throw terminalPersistenceError;\n }\n\n // 6. Schedule in-memory cleanup + opportunistic old-run pruning.\n setTimeout(() => {\n activeRuns.delete(runId);\n if (threadToRun.get(threadId) === runId) {\n threadToRun.delete(threadId);\n }\n }, CLEANUP_DELAY_MS);\n cleanupOldRuns(\n resolveCompletedRunRetentionMs(),\n resolveErroredRunRetentionMs(),\n ).catch(() => {});\n });\n runPromise.then(resolveFinalized, rejectFinalized);\n\n // On Cloudflare Workers, keep the isolate alive for this run\n try {\n const cfCtx = (\n globalThis as typeof globalThis & {\n __cf_ctx?: { waitUntil(promise: Promise<unknown>): void };\n }\n ).__cf_ctx;\n if (cfCtx?.waitUntil) {\n cfCtx.waitUntil(runPromise);\n }\n } catch {\n // Not on Workers — ignore\n }\n\n return run;\n}\n\n/**\n * Subscribe to a run's events starting from `fromSeq`.\n * Returns a ReadableStream that replays buffered events then live-tails.\n * Cancelling the stream only unsubscribes — does NOT abort the agent.\n *\n * Falls back to SQL polling when the run is not in local memory\n * (cross-isolate reconnection on Workers).\n */\nexport function subscribeToRun(\n runId: string,\n fromSeq: number,\n): ReadableStream<Uint8Array> | null {\n const run = activeRuns.get(runId);\n if (run) {\n return subscribeInMemory(run, fromSeq);\n }\n // Not in local memory — try SQL (cross-isolate path)\n return subscribeFromSQL(runId, fromSeq);\n}\n\n/** In-memory subscription (same isolate, fast path) */\nfunction subscribeInMemory(\n run: ActiveRun,\n fromSeq: number,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n let subscriberRef: ((event: RunEvent) => void) | null = null;\n let pingTimer: ReturnType<typeof setInterval> | null = null;\n\n return new ReadableStream({\n start(controller) {\n const ping = () => {\n try {\n controller.enqueue(encoder.encode(`: ping ${Date.now()}\\n\\n`));\n } catch {\n if (subscriberRef) run.subscribers.delete(subscriberRef);\n if (pingTimer) clearInterval(pingTimer);\n }\n };\n ping();\n pingTimer = setInterval(ping, 10_000);\n\n // Replay buffered events from fromSeq\n for (let i = fromSeq; i < run.events.length; i++) {\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ ...run.events[i].event, seq: run.events[i].seq })}\\n\\n`,\n ),\n );\n } catch {\n return;\n }\n }\n\n // If run is already done, close immediately\n if (run.status !== \"running\") {\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n return;\n }\n\n // Subscribe to live events\n subscriberRef = (event: RunEvent) => {\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ ...event.event, seq: event.seq })}\\n\\n`,\n ),\n );\n // Close stream after terminal events\n if (isTerminalRunEvent(event.event)) {\n run.subscribers.delete(subscriberRef!);\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n }\n } catch {\n run.subscribers.delete(subscriberRef!);\n }\n };\n\n run.subscribers.add(subscriberRef);\n },\n cancel() {\n // Only unsubscribe — do NOT abort the agent run\n if (subscriberRef) run.subscribers.delete(subscriberRef);\n if (pingTimer) clearInterval(pingTimer);\n },\n });\n}\n\n/** SQL-based subscription (cross-isolate, polling) */\nfunction subscribeFromSQL(\n runId: string,\n fromSeq: number,\n): ReadableStream<Uint8Array> | null {\n const encoder = new TextEncoder();\n let cancelled = false;\n let pollTimer: ReturnType<typeof setTimeout> | null = null;\n let pingTimer: ReturnType<typeof setInterval> | null = null;\n\n return new ReadableStream({\n async start(controller) {\n let lastSeq = fromSeq;\n let activePollUntil = 0;\n let lastStatusCheckAt = 0;\n const ping = () => {\n try {\n controller.enqueue(encoder.encode(`: ping ${Date.now()}\\n\\n`));\n } catch {\n cancelled = true;\n if (pingTimer) clearInterval(pingTimer);\n }\n };\n ping();\n pingTimer = setInterval(ping, 10_000);\n\n const poll = async () => {\n if (cancelled) return;\n try {\n // Read new events from SQL\n const events = await getRunEventsSince(runId, lastSeq);\n if (events.length > 0) {\n activePollUntil = Date.now() + SQL_SUBSCRIPTION_ACTIVE_GRACE_MS;\n }\n for (const { seq, eventData } of events) {\n // Advance the cursor first, before any parse/enqueue branch can\n // `continue`/`return`. Otherwise a single corrupt (unparseable)\n // event row is re-fetched on every poll tick forever, wedging the\n // SSE stream open and never delivering a terminal event.\n lastSeq = seq + 1;\n let parsed: any;\n try {\n parsed = JSON.parse(eventData);\n } catch {\n continue;\n }\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ ...parsed, seq })}\\n\\n`,\n ),\n );\n } catch {\n cancelled = true;\n return;\n }\n\n // Close on terminal events\n if (isTerminalRunEvent(parsed)) {\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n return;\n }\n }\n\n // Check if run completed (no terminal event but status changed)\n if (events.length === 0) {\n const now = Date.now();\n if (now - lastStatusCheckAt < SQL_SUBSCRIPTION_STATUS_POLL_MS) {\n if (!cancelled) {\n const pollMs = resolveSqlSubscriptionPollMs(\n now,\n activePollUntil,\n );\n pollTimer = setTimeout(poll, pollMs);\n }\n return;\n }\n lastStatusCheckAt = now;\n // Opportunistically reap a stale producer before trusting SQL's\n // \"running\" status — otherwise a crashed server leaves us polling\n // forever.\n await reapIfStale(runId).catch(() => {});\n const run = await getRunById(runId);\n if (!run || run.status !== \"running\") {\n // Run ended — do one final event read, then close\n const finalEvents = await getRunEventsSince(runId, lastSeq);\n for (const { seq, eventData } of finalEvents) {\n // Advance first — see the main poll loop above for why.\n lastSeq = seq + 1;\n let parsed: any;\n try {\n parsed = JSON.parse(eventData);\n } catch {\n continue;\n }\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ ...parsed, seq })}\\n\\n`,\n ),\n );\n } catch {\n cancelled = true;\n return;\n }\n if (isTerminalRunEvent(parsed)) {\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n return;\n }\n }\n if (run?.status === \"aborted\") {\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ type: \"done\", seq: lastSeq })}\\n\\n`,\n ),\n );\n } catch {\n cancelled = true;\n return;\n }\n } else if (run?.status === \"completed\") {\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ type: \"done\", seq: lastSeq })}\\n\\n`,\n ),\n );\n } catch {\n cancelled = true;\n return;\n }\n } else if (run?.status === \"errored\") {\n // The run row is terminal but this subscriber's cursor is\n // already past (or never saw) the terminal event. Prefer the\n // REAL last terminal event / row error_detail over inventing\n // a stale_run card — slides prod showed Connection error.\n // rows being mislabeled as stale_run on reconnect because\n // this path always synthesized STALE_RUN_ERROR_EVENT.\n const existing = await getLastTerminalRunEvent(runId).catch(\n () => null,\n );\n const resolved = existing\n ? { event: existing.event, shouldPersist: false }\n : resolveErroredRunTerminalEvent(run);\n if (resolved.shouldPersist) {\n await ensureTerminalRunEvent(runId, resolved.event).catch(\n () => {},\n );\n }\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({\n ...resolved.event,\n seq: existing?.seq ?? lastSeq,\n })}\\n\\n`,\n ),\n );\n } catch {\n cancelled = true;\n return;\n }\n }\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n return;\n }\n }\n\n // Schedule next poll\n if (!cancelled) {\n const pollMs = resolveSqlSubscriptionPollMs(\n Date.now(),\n activePollUntil,\n );\n pollTimer = setTimeout(poll, pollMs);\n }\n } catch {\n // SQL error — close stream\n try {\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n } catch {}\n }\n };\n\n // Verify run exists before starting poll\n try {\n const run = await getRunById(runId);\n if (!run) {\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n return;\n }\n } catch {\n controller.close();\n return;\n }\n\n await poll();\n },\n cancel() {\n cancelled = true;\n if (pollTimer) clearTimeout(pollTimer);\n if (pingTimer) clearInterval(pingTimer);\n },\n });\n}\n\n/** Get the active run for a thread (if any) — checks memory then SQL */\nexport function getActiveRunForThread(threadId: string): ActiveRun | null {\n const runId = threadToRun.get(threadId);\n if (runId) {\n const run = activeRuns.get(runId);\n if (run) return run;\n }\n return null;\n}\n\n/**\n * Async version that also checks SQL — for cross-isolate access.\n * Used by the /runs/active endpoint.\n *\n * Returns `heartbeatAt` so the client can independently decide a run is\n * dead even before the server-side stale reap has fired. Returns\n * `lastProgressAt` so the client-side stuck-detector can show a\n * user-visible \"this chat looks stuck\" affordance when a run is alive\n * (heartbeating) but not actually emitting events. Returns\n * `awaitingRedispatch` so the client's background follow loop can tell a\n * legitimately-deferred `chainServerDrivenContinuation` successor (recovery\n * in progress server-side) apart from a genuinely dead run — see this\n * field's own doc comment below.\n */\nexport async function getActiveRunForThreadAsync(threadId: string): Promise<{\n runId: string;\n threadId: string;\n turnId: string;\n status: string;\n heartbeatAt: number;\n lastProgressAt: number | null;\n /** How the run was dispatched/continued (foreground, foreground-self-chain, background...). */\n dispatchMode?: string | null;\n /** Compact terminal classification, e.g. done, run_timeout, stale_run. */\n terminalReason?: string | null;\n /**\n * Last reached `_process-run` worker stage as a JSON string\n * `{stage,detail?,at}`. Surfaced so a silent background-worker death is\n * diagnosable from the client WITHOUT the unreadable bg-fn logs.\n */\n diagStage?: string | null;\n /**\n * True exactly when this run is a `chainServerDrivenContinuation` deferral\n * (dispatch_mode === 'background', never claimed) still inside\n * `UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS` — the same condition this\n * function already uses below to skip its own `reapUnclaimedBackgroundRun`.\n * Surfaced on `/runs/active` (agent-chat-plugin.ts) so\n * `agent-chat-adapter.ts`'s follow loop can tell \"silently deferred,\n * server-side recovery in progress\" apart from \"dead\" and stop counting the\n * quiet gap against its idle timeout — see the THREE-SITE INVARIANT comment\n * below and in agent-chat-plugin.ts / production-agent.ts. Always false for\n * an in-memory run (that isolate IS the live producer) and for any run that\n * isn't an unclaimed background dispatch.\n */\n awaitingRedispatch: boolean;\n /**\n * True exactly when this run's `in_flight_since` marker is set — a tool\n * call or A2A `agent_call` delegation is open and has not yet resolved\n * (see `setRunInFlightMarker` / `IN_FLIGHT_RUN_STALE_GRACE_MS` in\n * run-store.ts). This is the SAME signal `reapIfStale` reads to grant its\n * bounded stale-reap grace — computed here from the identical\n * `in_flight_since` column via `getRunByThread`, never re-derived, so the\n * client and the reaper cannot disagree about what \"in flight\" means.\n *\n * Surfaced on `/runs/active` (agent-chat-plugin.ts) as the\n * server-authoritative alternative to the client-side proxy\n * `RunStuckBanner` currently infers from unresolved `tool-call` content\n * parts in the local message list — that proxy can go stale after a\n * reconnect or reader-mode replay; this cannot, because it is read fresh\n * from SQL on every poll.\n */\n hasInFlightWork: boolean;\n} | null> {\n // Check memory first — return both running AND recently-completed runs\n // that still have events in memory. This allows sub-agent tabs to replay\n // the full conversation from completed runs via SSE.\n const memRun = getActiveRunForThread(threadId);\n if (memRun && (memRun.status === \"running\" || memRun.events.length > 0)) {\n const sqlSnapshot = await fetchRunThreadSnapshot(memRun.runId, threadId);\n\n // FIX 1 (durable-background incident): a terminal in-memory run (chunk\n // completed at a soft-timeout/no-progress/loop-limit boundary, or any\n // other terminal outcome) never clears `threadToRun` — it stays this\n // thread's resident in-memory candidate for up to CLEANUP_DELAY_MS\n // (5 min), and `fetchRunThreadSnapshot` above returns null the instant\n // SQL's newest row for the thread is no longer THIS run (i.e. a\n // successor already exists). Left alone, every poll that lands on this\n // warm isolate would keep falling back to `memRun.status` below and\n // never discover that a newer, still-running successor already exists\n // in SQL — exactly the \"stale terminal run masks a live successor\" bug\n // that produced the mid-sentence dead turn. Only pay for the extra SQL\n // read here, in the terminal-candidate branch; the common \"still\n // running\" poll (the vast majority) never reaches it.\n if (!sqlSnapshot && memRun.status !== \"running\") {\n const successor = await fetchNewerNonTerminalRunForSameTurn(\n threadId,\n memRun,\n );\n if (successor) {\n return {\n runId: successor.id,\n threadId: successor.threadId,\n turnId: successor.turnId ?? successor.id,\n status: successor.status,\n heartbeatAt: successor.heartbeatAt ?? successor.startedAt,\n lastProgressAt: successor.lastProgressAt,\n dispatchMode: successor.dispatchMode,\n terminalReason: successor.terminalReason,\n diagStage: successor.diagStage,\n // Definitionally non-terminal and freshly read from SQL above —\n // never the stale in-memory candidate's own state.\n awaitingRedispatch: false,\n hasInFlightWork: successor.inFlightSince != null,\n };\n }\n }\n\n const status = sqlSnapshot?.status ?? memRun.status;\n const heartbeatAt =\n status === \"running\"\n ? Date.now()\n : (sqlSnapshot?.heartbeatAt ?? memRun.startedAt);\n return {\n runId: memRun.runId,\n threadId: memRun.threadId,\n turnId: memRun.turnId,\n status,\n // In-memory means this isolate is the producer. By definition, the\n // heartbeat is fresh as of \"now\" while the run is still running. Once\n // SQL has terminal truth, prefer that timestamp so a stale in-memory\n // buffer cannot keep the browser believing a finished background run is\n // still alive.\n heartbeatAt,\n // For an in-memory run we don't have a separate \"last event emit\"\n // timestamp tracked in JS — the SQL bump is throttled per-second.\n // Read it back from SQL on demand. For the common case the SQL row\n // is well under 1s old; if it isn't, the stuck-detector will pick\n // it up on the next poll cycle.\n lastProgressAt: sqlSnapshot?.lastProgressAt ?? null,\n dispatchMode: sqlSnapshot?.dispatchMode ?? null,\n terminalReason: sqlSnapshot?.terminalReason ?? null,\n diagStage: sqlSnapshot?.diagStage ?? null,\n // In-memory means this isolate is the live producer — never the\n // \"deferred, nobody producing\" state this flag identifies.\n awaitingRedispatch: false,\n // Read from the SAME SQL snapshot the other fields above already read\n // (`fetchRunThreadSnapshot` -> `getRunByThread`) rather than the\n // producer's own in-memory `inFlightWorkCount` — this isolate IS the\n // live producer, but there is no separate in-memory channel wired for\n // that counter today, and the SQL marker is written on every 0<->N\n // transition (see run-manager's `trackInFlightWork`), so it is at most\n // one event behind here — the same tolerance `lastProgressAt` above\n // already accepts.\n hasInFlightWork: sqlSnapshot?.inFlightSince != null,\n };\n }\n // Fall back to SQL — also surface recently terminated runs so the client\n // can reconnect and replay synthesized done/error events instead of\n // retrying the original POST. Without this, a POST that fails after the\n // server already accepted (and finished) the run would re-execute the\n // turn and double-apply mutations: the in-memory branch above already\n // returns terminal runs whose events are still buffered, but the SQL\n // path is the only authority once memory has been evicted.\n try {\n const sqlRun = await getRunByThread(threadId, { includeTerminal: true });\n if (!sqlRun) return null;\n if (sqlRun.status === \"running\") {\n // FALLBACK HARDENING: a background-dispatched run that is still UNCLAIMED\n // (dispatch_mode === 'background', never flipped to 'background-processing')\n // past the tight grace means the bg-fn worker never started — a silent\n // async-worker death that the 202-ack inline fallback can't catch. Reap it\n // early and recoverably (background_worker_never_started) so the run no\n // longer hangs for the full 90s window. Only fires when there is provably\n // no live worker; a claimed/heartbeating run is left alone by the\n // conditional SQL.\n //\n // REDISPATCH-BOUND GUARD (must be kept in lockstep with the \"Unclaimed\n // background-run sweep\" in agent-chat-plugin.ts and with\n // chainServerDrivenContinuation's deferral in production-agent.ts — do NOT\n // remove this guard without reading those two sites):\n // `chainServerDrivenContinuation` now DEFERS a dispatch-failed successor\n // instead of erroring it — it leaves the row status='running',\n // dispatch_mode='background' with its dispatch_payload intact so the sweep\n // can silently redispatch it. This client poll runs every ~1s while a\n // client is connected, so without this guard it would reap that deferred\n // successor at the 25s unclaimed grace — long before the ~2-min sweep —\n // converting the intended SILENT server-side recovery into a user-visible\n // `background_worker_never_started` manual-retry error (that terminal\n // reason does NOT auto-continue in the client follow loop; only `stale_run`\n // does). While the successor is still inside its redispatch bound we skip\n // this reap and leave it for the sweep. The outer backstops still bound it:\n // `reapIfStale` below reaps a heartbeat-stale background row at 90s\n // (BACKGROUND_RUN_STALE_MS) to the recoverable `stale_run` — which the\n // follow loop AUTO-continues — and once the redispatch bound is exceeded\n // this reap fires loudly as before. So recovery stays automatic in the\n // common case and loud failure is only moved later, never removed.\n //\n // `isUnclaimedBackgroundDispatch` also becomes the `awaitingRedispatch`\n // wire field below once the still-inside-the-bound check passes — see\n // this function's doc comment and the THREE-SITE INVARIANT comment in\n // agent-chat-plugin.ts / production-agent.ts.\n const isUnclaimedBackgroundDispatch =\n sqlRun.dispatchMode === \"background\";\n const stillInsideRedispatchBound = shouldRedispatchUnclaimedBackgroundRun(\n { startedAt: sqlRun.startedAt },\n );\n if (isUnclaimedBackgroundDispatch && !stillInsideRedispatchBound) {\n const recovered = await reapUnclaimedBackgroundRun(sqlRun.id).catch(\n () => false,\n );\n if (recovered) return null;\n }\n // If the producer is dead (no recent heartbeat), reap before the\n // client can see a stale \"running\" status and enter a reconnect\n // loop it can never exit.\n const reaped = await reapIfStale(sqlRun.id).catch(() => false);\n if (reaped) return null;\n return {\n runId: sqlRun.id,\n threadId: sqlRun.threadId,\n turnId: sqlRun.turnId ?? sqlRun.id,\n status: sqlRun.status,\n heartbeatAt: sqlRun.heartbeatAt ?? sqlRun.startedAt,\n lastProgressAt: sqlRun.lastProgressAt,\n dispatchMode: sqlRun.dispatchMode,\n terminalReason: sqlRun.terminalReason,\n diagStage: sqlRun.diagStage,\n awaitingRedispatch:\n isUnclaimedBackgroundDispatch && stillInsideRedispatchBound,\n // Same `in_flight_since` column `reapIfStale` (just called above,\n // and it did NOT reap this row) reads for its own grace decision —\n // one source of truth, not a second re-derived notion of \"in flight\".\n hasInFlightWork: sqlRun.inFlightSince != null,\n };\n }\n if (sqlRun.status === \"completed\" || sqlRun.status === \"errored\") {\n // Cap how far back we'll surface terminal runs as \"active\". The goal\n // is to catch the recently-completed-but-reconnecting case, not to\n // resurrect ancient turns when the user reopens an old thread.\n //\n // Measure age from the run's terminal timestamp, not its start. A\n // long-running task that ran 11 minutes and completed five seconds\n // ago should still be reachable — the client's disconnect happened\n // around completion, so completion time is what matters for the\n // \"is the user still here waiting?\" question. Fall back to the last\n // heartbeat (older deployments may have unset completed_at) and\n // finally to startedAt for ancient rows.\n const referenceAt =\n sqlRun.completedAt ?? sqlRun.heartbeatAt ?? sqlRun.startedAt;\n const terminalAge = Date.now() - referenceAt;\n if (terminalAge > TERMINAL_RUN_RECONNECT_WINDOW_MS) return null;\n return {\n runId: sqlRun.id,\n threadId: sqlRun.threadId,\n turnId: sqlRun.turnId ?? sqlRun.id,\n status: sqlRun.status,\n heartbeatAt: sqlRun.heartbeatAt ?? sqlRun.startedAt,\n lastProgressAt: sqlRun.lastProgressAt,\n dispatchMode: sqlRun.dispatchMode,\n terminalReason: sqlRun.terminalReason,\n diagStage: sqlRun.diagStage,\n // Terminal already — never the \"still deferred, running\" state.\n awaitingRedispatch: false,\n // Terminal already — no live work can still be in flight.\n hasInFlightWork: false,\n };\n }\n } catch {\n // SQL error — fall through\n }\n return null;\n}\n\nasync function fetchRunThreadSnapshot(runId: string, threadId: string) {\n try {\n // `getRunById` returns a narrow projection today; ask for the row via\n // the thread lookup which carries dispatch/terminal/progress fields.\n const byThread = await getRunByThread(threadId, {\n includeTerminal: true,\n });\n if (byThread && byThread.id === runId) return byThread;\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * FIX 1 (durable-background incident): find a genuinely newer, still-running\n * SQL row for the SAME turn as a terminal in-memory `ActiveRun` — used only\n * when `fetchRunThreadSnapshot` found no SQL row matching the in-memory\n * run's own id (i.e. SQL's newest row for the thread is a different run).\n * `getRunByThread` always returns the thread's newest row by `started_at`,\n * so this is the same read `fetchRunThreadSnapshot` already made; we just\n * don't throw its result away when the id doesn't match.\n *\n * Scoped to the SAME `turnId` (not just the same thread) so an unrelated,\n * later user turn on the same thread is never mistaken for a continuation\n * successor of this one.\n */\nasync function fetchNewerNonTerminalRunForSameTurn(\n threadId: string,\n memRun: ActiveRun,\n): Promise<Awaited<ReturnType<typeof getRunByThread>> | null> {\n try {\n const latest = await getRunByThread(threadId, { includeTerminal: true });\n if (\n latest &&\n latest.id !== memRun.runId &&\n latest.status === \"running\" &&\n latest.startedAt > memRun.startedAt &&\n (latest.turnId ?? latest.id) === memRun.turnId\n ) {\n return latest;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/** Get a run by ID */\nexport function getRun(runId: string): ActiveRun | null {\n return activeRuns.get(runId) ?? null;\n}\n\nfunction abortRunInMemory(runId: string, reason: string): boolean {\n const run = activeRuns.get(runId);\n if (run) {\n abortInMemoryRun(run, reason);\n }\n return !!run;\n}\n\n/** Explicitly abort a run (e.g. Stop button). */\nexport function abortRun(runId: string, reason: string = \"user\"): boolean {\n const abortedInMemory = abortRunInMemory(runId, reason);\n // Also mark as aborted in SQL (for cross-isolate abort on Workers)\n markRunAborted(runId, reason).catch(() => {});\n return abortedInMemory;\n}\n\n/**\n * Abort a run and wait until the cross-isolate SQL state and terminal event\n * are durable. Request handlers that start recovery immediately after aborting\n * must use this path; otherwise the recovery POST can race the old row while\n * it is still marked running.\n */\nexport async function abortRunDurably(\n runId: string,\n reason: string = \"user\",\n): Promise<boolean> {\n const abortedInMemory = abortRunInMemory(runId, reason);\n try {\n await markRunAborted(runId, reason);\n } catch (error) {\n // The local run is already stopped. A transient durable cleanup failure\n // must not turn the user's Stop/Retry request into a 500 after that\n // irreversible in-memory outcome. Capture it for repair/reaping and let\n // the request report the abort it did complete.\n captureError(error, {\n route: \"/_agent-native/agent-chat/runs/:id/abort\",\n tags: {\n source: \"agent-run-manager\",\n phase: \"abort-run\",\n },\n extra: { runId, reason, abortedInMemory },\n });\n console.error(\n \"[run-manager] durable abort persistence failed:\",\n error instanceof Error ? error.message : error,\n );\n }\n return abortedInMemory;\n}\n\n// Re-export so callers can avoid importing from run-store directly.\nexport { tryClaimRunSlot } from \"./run-store.js\";\n"]}
1
+ {"version":3,"file":"run-manager.js","sourceRoot":"","sources":["../../src/agent/run-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import { captureError } from \"../server/capture-error.js\";\nimport {\n isLlmCredentialError,\n LLM_MISSING_CREDENTIALS_ERROR_CODE,\n LLM_MISSING_CREDENTIALS_MESSAGE,\n} from \"./engine/credential-errors.js\";\nimport { EngineError } from \"./engine/types.js\";\nimport {\n insertRun,\n insertRunEvent,\n updateRunStatusIfRunning,\n markRunAborted,\n getRunAbortState,\n getRunStatus,\n getRunEventsSince,\n getRunById,\n getRunByThread,\n cleanupOldRuns,\n updateRunHeartbeat,\n bumpRunProgress,\n setRunInFlightMarker,\n reapIfStale,\n reapUnclaimedBackgroundRun,\n shouldRedispatchUnclaimedBackgroundRun,\n reconcileTerminalRunFromEvents,\n ensureTerminalRunEvent,\n getLastTerminalRunEvent,\n resolveErroredRunTerminalEvent,\n setRunError,\n setRunTerminalReason,\n} from \"./run-store.js\";\nimport type { AgentChatEvent, RunEvent, RunStatus } from \"./types.js\";\n\nexport interface ActiveRun {\n runId: string;\n threadId: string;\n /** Logical-turn identity (see StartRunOptions.turnId). Defaults to runId. */\n turnId: string;\n events: RunEvent[];\n status: RunStatus;\n subscribers: Set<(event: RunEvent) => void>;\n abort: AbortController;\n abortReason?: string;\n /**\n * Terminal event to emit when a server-driven continuation has been handed\n * off successfully. The continuation runs outside this process, so the\n * normal loop-level auto_continue event is not sent through this run's\n * `send` callback.\n */\n continuationTerminalEvent?: Extract<\n AgentChatEvent,\n { type: \"auto_continue\" }\n >;\n startedAt: number;\n}\n\nexport interface StartedRun extends ActiveRun {\n /**\n * Resolves after the terminal event and final SQL status have been persisted.\n * Serverless workers must await this before returning or the runtime can\n * freeze the isolate between onComplete and terminalization.\n */\n finalized: Promise<void>;\n}\n\nconst activeRuns = new Map<string, ActiveRun>();\nconst threadToRun = new Map<string, string>();\n\n/** How long to keep completed runs in memory before cleanup (5 min) */\nconst CLEANUP_DELAY_MS = 5 * 60 * 1000;\n\n/**\n * Default run chunk budget for hosted/serverless deploys.\n *\n * This MUST fire before the two upstream hard walls that otherwise kill a run\n * mid-turn with no chance to hand off:\n * 1. The Builder model gateway keeps a 45s cap only for hosted foreground\n * runs; local and proven background-function runs use longer caps.\n * 2. Serverless functions are hard-killed around 60-65s (the heartbeat then\n * reaps the row as a stale_run).\n * Production data showed every cutoff landing in the 44-70s window with ZERO\n * auto_continue events ever emitted — i.e. the old 45s default raced the 45s\n * gateway and lost, and per-template overrides (e.g. 240_000) pushed it past\n * BOTH walls so it could never fire. 40s leaves ~5s of headroom under the\n * gateway wall to abort, persist the partial turn, write the terminal event,\n * and emit a clean auto_continue so the client resumes seamlessly.\n */\nexport const DEFAULT_HOSTED_RUN_SOFT_TIMEOUT_MS = 40_000;\n\n/**\n * Hard ceiling for the hosted soft timeout. On a hosted runtime the\n * foreground auto_continue soft timeout can never usefully exceed this — the\n * synchronous function (~60s) wall kills the run first, so a larger configured\n * or env value just guarantees the cutoff is a hard error instead of a graceful\n * hand-off. Any resolved value above this is clamped down for hosted foreground\n * runs. Local dev (non-hosted) is left alone so long-running local turns aren't\n * chunked.\n *\n * IMPORTANT: this clamp is for the INTERACTIVE / foreground path and must NOT\n * be raised. The foreground POST still rides a synchronous serverless function\n * (~60-65s wall), so 40s remains correct there. The only sanctioned exception\n * is the opt-in `backgroundFunction` mode (see\n * `BACKGROUND_SOFT_TIMEOUT_CEILING_MS`), which runs inside a Netlify background\n * function (no ~60s wall, 15-min budget) and therefore can safely outlast 40s.\n */\nexport const HOSTED_SOFT_TIMEOUT_CEILING_MS = 40_000;\n\n/**\n * Hard ceiling for the soft timeout when a run executes inside a Netlify\n * background function (any deployed function whose name ends in `-background`).\n * Background functions return 202 immediately and run detached for up to 15\n * minutes, so the ~60s synchronous function wall that 40s defends against does\n * NOT apply. 13 minutes leaves ~2 min of headroom under Netlify's 15-min hard\n * kill to abort, persist the partial turn, write the terminal event, and (for\n * the rare >13-min turn) self-fire another background continuation.\n *\n * This ceiling is used ONLY when a caller explicitly opts in with\n * `backgroundFunction: true`. It does not change the foreground/interactive\n * ceiling and does not fire unless the durable-background path dispatched the\n * run into a background function. Per the design doc Guardrail, the 40s\n * interactive clamp stays correct for every non-background run.\n */\nexport const BACKGROUND_SOFT_TIMEOUT_CEILING_MS = 13 * 60_000; // 780_000\n\n/**\n * Default soft-timeout budget for a background-function run when the caller\n * does not pass an explicit `softTimeoutMs`. Same value as the ceiling — we\n * want a background turn to use nearly its whole 15-min budget before handing\n * off to a chained background continuation.\n */\nexport const DEFAULT_BACKGROUND_RUN_SOFT_TIMEOUT_MS =\n BACKGROUND_SOFT_TIMEOUT_CEILING_MS;\n\n/**\n * Default no-progress window for a run executing inside a proven durable\n * background function. Keep this below the 13-minute soft timeout so a truly\n * wedged background turn can still checkpoint, persist, and continue before\n * the function budget expires, but far above the foreground 150s window so\n * large Design/Plan/Assets generations are not chopped up while the model is\n * legitimately planning a big tool payload.\n */\nexport const DEFAULT_BACKGROUND_NO_PROGRESS_TIMEOUT_MS =\n BACKGROUND_SOFT_TIMEOUT_CEILING_MS - 60_000;\n\n/**\n * AUTHORITATIVE no-progress backstop for a run, enforced by the run manager\n * itself (timer-driven, independent of any layer below).\n *\n * The finer-grained watchdogs inside the agent loop (model-stream and\n * action-preparation no-progress, both 90s) only guard the model event stream\n * — a stall in any segment OUTSIDE that guarded loop (engine-call\n * establishment, worker setup between continuation chunks, a wedged transport\n * that emits keepalives while the loop never runs) previously hung forever\n * with the client watching keepalives. This backstop covers every segment by\n * construction: if no REAL progress event (see `shouldBumpProgressForEvent`;\n * keepalives and zero-byte prep activity don't count) lands for this long —\n * and no tool call is in flight (tool execution legitimately emits nothing\n * for minutes and has its own 12-min timeout) — the run manager emits\n * `auto_continue { reason: \"no_progress\" }` and aborts the chunk, exactly\n * like the soft timeout, so the normal continuation machinery recovers it.\n *\n * Sits above the 90s in-loop watchdogs (they get first chance to recover with\n * better context). Foreground hosted chunks keep this short so the user sees\n * recovery promptly; proven durable-background chunks use\n * `DEFAULT_BACKGROUND_NO_PROGRESS_TIMEOUT_MS` so large outputs can use the\n * background budget. Only armed when a soft-timeout regime is active (hosted\n * runs); local dev stays unbounded.\n */\nexport const RUN_NO_PROGRESS_HARD_TIMEOUT_MS = 150_000;\n\n/** Default SQL retention for completed run event logs (24 hours). */\nexport const DEFAULT_COMPLETED_RUN_RETENTION_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Default SQL retention for errored/aborted run event logs (7 days). Kept\n * longer than completed runs so cut-off / failed chats survive for pattern\n * analysis (listErroredRuns) — these are rare and small, and they are exactly\n * the runs we need to study to keep hardening reliability.\n */\nexport const DEFAULT_ERRORED_RUN_RETENTION_MS = 7 * 24 * 60 * 60 * 1000;\n\n/**\n * How recently a terminal run must have started for `/runs/active` to surface\n * it. Reconnect after this window won't replay the run — typical real-world\n * disconnects resolve in seconds, so 10 minutes is generous while keeping us\n * from resurrecting ancient turns when the user reopens an old thread.\n */\nexport const TERMINAL_RUN_RECONNECT_WINDOW_MS = 10 * 60 * 1000;\n\n/** Fast poll cadence while a SQL-backed SSE subscription is actively receiving rows. */\nexport const SQL_SUBSCRIPTION_ACTIVE_POLL_MS = 125;\n\n/** Baseline SQL-backed SSE poll cadence when the run is idle. */\nexport const SQL_SUBSCRIPTION_IDLE_POLL_MS = 500;\n\n/**\n * Keep briefly polling quickly after rows arrive so token streams stay smooth,\n * then back off to the idle cadence if the producer goes quiet.\n */\nexport const SQL_SUBSCRIPTION_ACTIVE_GRACE_MS = 2_000;\n\n/** Keep terminal/status probes at the historical cadence to bound DB work. */\nexport const SQL_SUBSCRIPTION_STATUS_POLL_MS = 500;\n\nexport function resolveSqlSubscriptionPollMs(\n now: number,\n activePollUntil: number,\n): number {\n return now < activePollUntil\n ? SQL_SUBSCRIPTION_ACTIVE_POLL_MS\n : SQL_SUBSCRIPTION_IDLE_POLL_MS;\n}\n\nconst PROVIDER_RATE_LIMITED_ERROR_CODE = \"provider_rate_limited\";\n\nfunction isPreparingActionActivityEvent(event: AgentChatEvent): boolean {\n if (event.type !== \"activity\") return false;\n const label = event.label.trim().toLowerCase();\n return label.startsWith(\"preparing \") && label.includes(\" action\");\n}\n\nfunction getRunErrorMessage(err: unknown): string {\n if (\n typeof err === \"object\" &&\n err !== null &&\n \"message\" in err &&\n typeof err.message === \"string\" &&\n err.message.trim().length > 0\n ) {\n return err.message;\n }\n return \"Unknown error\";\n}\n\nfunction getEngineRunErrorCode(err: EngineError): string | undefined {\n if (err.errorCode) return err.errorCode;\n if (err.statusCode === 429) return PROVIDER_RATE_LIMITED_ERROR_CODE;\n return undefined;\n}\n\nfunction getEngineRunErrorDetails(err: EngineError): string | undefined {\n if (err.statusCode === 429) return err.message;\n return undefined;\n}\n\nfunction shouldCaptureRunError(err: unknown): boolean {\n if (!(err instanceof EngineError)) return true;\n const errorCode = getEngineRunErrorCode(err);\n if (isLlmCredentialError(err, errorCode)) return false;\n if (err.statusCode === 401 || err.statusCode === 403) return false;\n if (/^40[13] status code\\b/i.test(err.message)) return false;\n if (err.message.trim().toLowerCase() === \"connection error.\") return false;\n if (!errorCode) return true;\n const normalizedCode = errorCode.toLowerCase();\n return (\n !normalizedCode.startsWith(\"credits-limit\") &&\n normalizedCode !== \"builder_gateway_network_error\" &&\n normalizedCode !== \"provider_rate_limited\" &&\n normalizedCode !== \"rate_limit_exceeded\"\n );\n}\n\nexport interface StartRunOptions {\n /** Optional internal run chunk budget. When reached, the framework emits an\n * auto-continuation signal instead of a user-facing timeout. Leave unset for\n * no framework-imposed run timeout. */\n softTimeoutMs?: number;\n /** Opt into the hosted/serverless default chunk budget. Only callers with\n * automatic continuation support should enable this. */\n useHostedSoftTimeoutDefault?: boolean;\n /** Stable identity for the logical assistant turn this run belongs to. A\n * turn may span several continuation runs (each chunk is its own run); they\n * share one `turnId` so the durable assistant message can be folded across\n * them instead of dropped per-run. Defaults to the runId (turn == run). */\n turnId?: string;\n /**\n * Opt into the durable-background-function soft-timeout regime for THIS run\n * only. When true, `resolveRunSoftTimeoutMs` lifts the hosted ceiling from\n * 40s to ~13min (`BACKGROUND_SOFT_TIMEOUT_CEILING_MS`) because the run is\n * executing inside a Netlify background function (no ~60s wall). Off by\n * default — the foreground/interactive path never sets this, so its 40s\n * clamp is unchanged. See the design doc + the durable-background dispatch\n * decision in production-agent.ts.\n */\n backgroundFunction?: boolean;\n /**\n * Override the run-manager-level no-progress backstop\n * (`RUN_NO_PROGRESS_HARD_TIMEOUT_MS`). `0` disables it. Defaults to the\n * backstop constant whenever a soft-timeout regime is active (hosted runs)\n * and to disabled otherwise (local dev stays unbounded).\n */\n noProgressTimeoutMs?: number;\n /**\n * Lifecycle metadata persisted to `agent_runs.dispatch_mode` and surfaced to\n * clients through `/runs/active`. This does not change run-manager behavior;\n * callers use it to describe who owns continuation at hosted chunk boundaries.\n */\n dispatchMode?: \"foreground\" | \"foreground-self-chain\";\n}\n\nexport interface ResolveRunSoftTimeoutOptions {\n useHostedDefault?: boolean;\n /**\n * Resolve the soft timeout for a run executing inside a Netlify background\n * function. Lifts the hosted clamp to `BACKGROUND_SOFT_TIMEOUT_CEILING_MS`\n * (~13min) for this invocation only and, when no override/env is supplied,\n * defaults to `DEFAULT_BACKGROUND_RUN_SOFT_TIMEOUT_MS`. Does NOT change the\n * foreground ceiling. Off by default.\n */\n backgroundFunction?: boolean;\n}\n\n/**\n * True on hosted/serverless runtimes where the soft-timeout regime applies\n * (see `resolveRunSoftTimeoutMs`, which resolves to 0 — disabled — off these\n * runtimes). Exported so production-agent.ts can gate its foreground\n * first-model-event cap (`FOREGROUND_FIRST_MODEL_EVENT_TIMEOUT_MS`) on the\n * SAME predicate that selects the 40s clamp: the cap only makes sense where\n * that clamp (and the platform wall behind it) exists.\n */\nexport function isHostedRuntime(): boolean {\n if (process.env.NETLIFY_LOCAL === \"true\") return false;\n if (process.env.NETLIFY === \"false\") return false;\n if (process.env.SITE_ID) return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.\n if (\n process.env.NETLIFY &&\n process.env.NETLIFY !== \"false\" &&\n process.env.NETLIFY_LOCAL !== \"true\"\n ) {\n return true;\n }\n if (\n process.env.AWS_LAMBDA_FUNCTION_NAME &&\n process.env.NETLIFY_LOCAL !== \"true\"\n ) {\n return true;\n }\n return Boolean(\n process.env.CF_PAGES ||\n process.env.VERCEL ||\n process.env.VERCEL_ENV ||\n process.env.RENDER ||\n process.env.FLY_APP_NAME ||\n process.env.K_SERVICE,\n );\n}\n\nexport function resolveRunSoftTimeoutMs(\n overrideMs?: number,\n options?: ResolveRunSoftTimeoutOptions,\n): number {\n const hosted = isHostedRuntime();\n const background = options?.backgroundFunction === true;\n // The interactive/foreground ceiling is 40s — the synchronous serverless\n // function wall. A background-function run (opt-in only) has no ~60s wall, so\n // it is allowed to outlast that and is clamped to the larger 13-min ceiling\n // instead. The 40s clamp for non-background hosted runs is unchanged.\n const ceiling = background\n ? BACKGROUND_SOFT_TIMEOUT_CEILING_MS\n : HOSTED_SOFT_TIMEOUT_CEILING_MS;\n // A configured/env soft timeout that exceeds the upstream walls can never\n // actually fire (the gateway/function kills the run first), so clamp it down\n // on hosted runtimes. This is what makes auto_continue reach the client\n // instead of the run dying as builder_gateway_timeout / stale_run. `0` means\n // \"disabled\" and is never clamped up.\n const clampHosted = (ms: number): number =>\n hosted && ms > ceiling ? ceiling : ms;\n\n if (typeof overrideMs === \"number\" && Number.isFinite(overrideMs)) {\n return clampHosted(Math.max(0, overrideMs));\n }\n const envValue = process.env.AGENT_RUN_SOFT_TIMEOUT_MS;\n if (envValue !== undefined) {\n const raw = Number(envValue);\n if (Number.isFinite(raw) && raw >= 0) return clampHosted(raw);\n }\n // A background-function run uses the full background budget by default; the\n // foreground default (40s) is unchanged.\n if (background) {\n return hosted ? DEFAULT_BACKGROUND_RUN_SOFT_TIMEOUT_MS : 0;\n }\n return options?.useHostedDefault && hosted\n ? DEFAULT_HOSTED_RUN_SOFT_TIMEOUT_MS\n : 0;\n}\n\nexport function resolveCompletedRunRetentionMs(): number {\n const envValue = process.env.AGENT_RUN_RETENTION_MS;\n if (envValue !== undefined) {\n const raw = Number(envValue);\n if (Number.isFinite(raw) && raw >= 0) return raw;\n }\n return DEFAULT_COMPLETED_RUN_RETENTION_MS;\n}\n\nexport function resolveErroredRunRetentionMs(): number {\n const envValue = process.env.AGENT_ERRORED_RUN_RETENTION_MS;\n if (envValue !== undefined) {\n const raw = Number(envValue);\n if (Number.isFinite(raw) && raw >= 0) return raw;\n }\n return DEFAULT_ERRORED_RUN_RETENTION_MS;\n}\n\nfunction isTerminalRunEvent(event: AgentChatEvent): boolean {\n return (\n event.type === \"done\" ||\n event.type === \"error\" ||\n event.type === \"missing_api_key\" ||\n event.type === \"loop_limit\" ||\n event.type === \"auto_continue\"\n );\n}\n\nfunction terminalEventForcesErroredStatus(event: AgentChatEvent | null) {\n return event?.type === \"error\" || event?.type === \"missing_api_key\";\n}\n\nfunction terminalReasonForRun(\n finalStatus: \"completed\" | \"errored\" | \"aborted\",\n terminalEvent: AgentChatEvent | null,\n abortReason: string | undefined,\n completionError: unknown,\n): string {\n if (terminalEvent?.type === \"auto_continue\") {\n return terminalEvent.reason || \"auto_continue\";\n }\n if (terminalEvent?.type === \"loop_limit\") return \"loop_limit\";\n if (terminalEvent?.type === \"missing_api_key\") return \"missing_api_key\";\n if (terminalEvent?.type === \"error\") {\n return `error:${terminalEvent.errorCode || \"unknown\"}`;\n }\n if (finalStatus === \"aborted\") return `aborted:${abortReason ?? \"user\"}`;\n if (completionError) return \"completion_error\";\n if (finalStatus === \"errored\") return \"error:unknown\";\n return \"done\";\n}\n\nfunction abortInMemoryRun(run: ActiveRun, reason: string = \"user\") {\n run.abortReason = reason;\n run.status = \"aborted\";\n if (threadToRun.get(run.threadId) === run.runId) {\n threadToRun.delete(run.threadId);\n }\n run.abort.abort(reason);\n for (const subscriber of run.subscribers) {\n try {\n subscriber({ seq: run.events.length, event: { type: \"done\" } });\n } catch {\n // ignore — subscriber is being removed below\n }\n }\n run.subscribers.clear();\n}\n\n/**\n * Start a new agent run in the background.\n * `runFn` receives a `send` callback and an `AbortSignal`.\n * The run continues even if all SSE subscribers disconnect.\n *\n * Events are persisted to SQL for cross-isolate access (Cloudflare Workers).\n */\nexport function startRun(\n runId: string,\n threadId: string,\n runFn: (\n send: (event: AgentChatEvent) => void,\n signal: AbortSignal,\n ) => Promise<void>,\n onComplete?: (run: ActiveRun) => void | Promise<void>,\n options?: StartRunOptions,\n): StartedRun {\n // If there's already a run for this thread, abort it\n const existingRunId = threadToRun.get(threadId);\n if (existingRunId) {\n abortRun(existingRunId);\n }\n\n const abort = new AbortController();\n let softTimedOut = false;\n let resolveFinalized: () => void = () => {};\n let rejectFinalized: (reason?: unknown) => void = () => {};\n const finalized = new Promise<void>((resolve, reject) => {\n resolveFinalized = resolve;\n rejectFinalized = reject;\n });\n // Foreground callers do not await this promise, but terminal persistence\n // failures must still be observable to background workers without creating\n // an unhandled rejection in the foreground path.\n void finalized.catch(() => {});\n const run: StartedRun = {\n runId,\n threadId,\n turnId: options?.turnId ?? runId,\n events: [],\n status: \"running\",\n subscribers: new Set(),\n abort,\n startedAt: Date.now(),\n finalized,\n };\n\n activeRuns.set(runId, run);\n threadToRun.set(threadId, runId);\n\n const captureRunPersistenceError = (\n error: unknown,\n phase: \"insert-run\" | \"insert-event\",\n extra: Record<string, unknown> = {},\n ) => {\n captureError(error, {\n route: \"/_agent-native/agent-chat\",\n tags: {\n source: \"agent-run-manager\",\n phase,\n runStatus: run.status,\n },\n extra: {\n runId,\n threadId,\n eventCount: run.events.length,\n startedAt: run.startedAt,\n ...extra,\n },\n contexts: {\n agentRun: {\n runId,\n threadId,\n status: run.status,\n phase,\n eventCount: run.events.length,\n startedAt: run.startedAt,\n },\n },\n });\n };\n\n // Persist run to SQL without blocking the response. Keep the promise so\n // final status cannot race ahead of a slow initial INSERT and then get\n // overwritten by a late row stuck at status='running'.\n const insertOptions = options?.dispatchMode\n ? { dispatchMode: options.dispatchMode }\n : undefined;\n const insertRunPromise = (\n insertOptions\n ? insertRun(runId, threadId, options?.turnId, insertOptions)\n : insertRun(runId, threadId, options?.turnId)\n ).catch((error) => {\n captureRunPersistenceError(error, \"insert-run\");\n });\n\n // Per-run event persistence chain: events are chained so SQL inserts commit\n // in seq order. Without this, a fast seq=5 commit before a slow seq=4 means\n // the SQL poller advances its cursor past seq=4 (lastSeq = 5+1 = 6) and\n // reconnecting clients permanently miss that event (silent gap). Chaining\n // per run ensures order without blocking the fast in-memory SSE path.\n let persistenceChain: Promise<void> = Promise.resolve();\n\n // Throttle the durable progress timestamp to at most once per second so\n // a chatty token-by-token stream doesn't translate into one DB write per\n // chunk. The stuck-detector threshold is on the order of tens of seconds,\n // so 1s resolution is plenty.\n let lastProgressBumpAt = 0;\n const preparingActivityBytes = new Map<string, number>();\n const preparingActivityTools = new Map<string, string>();\n const preparingActivityRestartHighWater = new Map<string, number>();\n let eventPersistenceErrorCaptured = false;\n const bumpProgressIfDue = () => {\n const now = Date.now();\n if (now - lastProgressBumpAt < 1000) return;\n lastProgressBumpAt = now;\n bumpRunProgress(runId).catch(() => {});\n };\n const shouldBumpProgressForEvent = (event: AgentChatEvent): boolean => {\n if (event.type === \"stream_keepalive\") return false;\n if (event.type === \"clear\") {\n for (const [key, bytes] of preparingActivityBytes) {\n const toolKey = preparingActivityTools.get(key) ?? key;\n preparingActivityRestartHighWater.set(\n toolKey,\n Math.max(preparingActivityRestartHighWater.get(toolKey) ?? 0, bytes),\n );\n }\n preparingActivityBytes.clear();\n preparingActivityTools.clear();\n return false;\n }\n if (event.type === \"activity\" && isPreparingActionActivityEvent(event)) {\n const toolKey = event.tool?.trim() || event.label.trim();\n const activityKey = `${toolKey}:${event.id?.trim() || \"no-id\"}`;\n const progressBytes =\n typeof event.progressBytes === \"number\" &&\n Number.isFinite(event.progressBytes) &&\n event.progressBytes >= 0\n ? Math.floor(event.progressBytes)\n : undefined;\n if (progressBytes === undefined) return false;\n const restartHighWater =\n preparingActivityRestartHighWater.get(toolKey) ?? 0;\n if (!event.id?.trim()) {\n if (progressBytes <= restartHighWater) return false;\n preparingActivityTools.set(activityKey, toolKey);\n preparingActivityBytes.set(\n activityKey,\n Math.max(preparingActivityBytes.get(activityKey) ?? 0, progressBytes),\n );\n if (preparingActivityRestartHighWater.has(toolKey)) {\n preparingActivityRestartHighWater.set(\n toolKey,\n Math.max(restartHighWater, progressBytes),\n );\n }\n return progressBytes > 0;\n }\n const previousBytes = Math.max(\n preparingActivityBytes.get(activityKey) ?? 0,\n restartHighWater,\n );\n if (\n !preparingActivityBytes.has(activityKey) &&\n progressBytes === 0 &&\n !preparingActivityRestartHighWater.has(toolKey)\n ) {\n preparingActivityTools.set(activityKey, toolKey);\n preparingActivityBytes.set(activityKey, 0);\n preparingActivityRestartHighWater.set(toolKey, 0);\n return true;\n }\n if (progressBytes <= previousBytes) {\n preparingActivityTools.set(activityKey, toolKey);\n preparingActivityBytes.set(\n activityKey,\n Math.max(previousBytes, progressBytes),\n );\n return false;\n }\n preparingActivityTools.set(activityKey, toolKey);\n preparingActivityBytes.set(activityKey, progressBytes);\n if (preparingActivityRestartHighWater.has(toolKey)) {\n preparingActivityRestartHighWater.set(\n toolKey,\n Math.max(\n preparingActivityRestartHighWater.get(toolKey) ?? 0,\n progressBytes,\n ),\n );\n }\n return true;\n }\n if (event.type === \"tool_start\" || event.type === \"tool_done\") {\n preparingActivityBytes.clear();\n preparingActivityTools.clear();\n preparingActivityRestartHighWater.clear();\n }\n if (event.type === \"done\" || event.type === \"error\") {\n preparingActivityBytes.clear();\n preparingActivityTools.clear();\n preparingActivityRestartHighWater.clear();\n }\n return true;\n };\n\n // ── No-progress backstop (see RUN_NO_PROGRESS_HARD_TIMEOUT_MS) ──────────\n // Timer-driven and independent of the agent loop, so it fires even when the\n // stall is in a segment the in-loop watchdogs never see (engine-call\n // establishment, setup, a wedged transport emitting keepalives). Tool calls\n // and sub-agent calls in flight suspend it — tool execution legitimately\n // emits nothing for minutes and carries its own 12-min timeout.\n let lastRealProgressAt = Date.now();\n let inFlightWorkCount = 0;\n const trackInFlightWork = (event: AgentChatEvent) => {\n const wasIdle = inFlightWorkCount === 0;\n if (event.type === \"tool_start\") {\n inFlightWorkCount += 1;\n } else if (event.type === \"tool_done\") {\n inFlightWorkCount = Math.max(0, inFlightWorkCount - 1);\n } else if (event.type === \"agent_call\") {\n if (event.status === \"start\") {\n inFlightWorkCount += 1;\n } else {\n inFlightWorkCount = Math.max(0, inFlightWorkCount - 1);\n }\n } else {\n return; // Not a work-tracking event — no transition possible.\n }\n // Mirror the 0<->N transition into SQL so a stale reaper running in a\n // DIFFERENT isolate (a client's SQL-subscription poll, a sibling\n // isolate's opportunistic cleanup, a fresh boot's startup sweep) can\n // grant this demonstrably-alive run a bounded grace even when THIS\n // isolate's own heartbeat write is failing (e.g. Neon pooler saturation)\n // — `inFlightWorkCount` itself is in-memory and invisible to those other\n // isolates. Fire-and-forget: never block event emission on this write,\n // and a write failure here is no worse than today's behavior (the row\n // just gets no grace). See `setRunInFlightMarker` / `IN_FLIGHT_RUN_STALE_GRACE_MS`\n // in run-store.ts for the full reasoning and the bounded-grace derivation.\n if (wasIdle && inFlightWorkCount > 0) {\n setRunInFlightMarker(runId, true).catch(() => {});\n } else if (!wasIdle && inFlightWorkCount === 0) {\n setRunInFlightMarker(runId, false).catch(() => {});\n }\n };\n const checkNoProgressBackstop = () => {\n if (noProgressTimeoutMs <= 0) return;\n if (run.status !== \"running\" || abort.signal.aborted) return;\n if (inFlightWorkCount > 0) return;\n if (Date.now() - lastRealProgressAt < noProgressTimeoutMs) return;\n console.error(\n `[run-manager] no real progress for ${noProgressTimeoutMs}ms with no tool in flight — ` +\n `checkpointing run for continuation`,\n runId,\n );\n // Mirror the soft-timeout semantics exactly: the chunk completes (not\n // aborts) at an auto_continue boundary, so the continuation machinery —\n // server-chained for background workers, client-driven for foreground —\n // recovers the turn.\n softTimedOut = true;\n send({ type: \"auto_continue\", reason: \"no_progress\" });\n abort.abort(\"no_progress\");\n };\n\n // Periodic SQL abort check interval (for cross-isolate abort on Workers).\n // Also self-aborts when our row is no longer status='running' — catches the\n // false-stale-reap zombie scenario where the reaper flipped the row while\n // this isolate was briefly unable to heartbeat (DB latency / GC pause).\n let lastAbortCheck = Date.now() - 3000;\n const checkSqlAbort = () => {\n const now = Date.now();\n if (now - lastAbortCheck < 3000) return;\n lastAbortCheck = now;\n getRunAbortState(runId)\n .then(async (state) => {\n if (state.aborted && !abort.signal.aborted) {\n abortInMemoryRun(run, state.reason ?? \"user\");\n return;\n }\n // If the row is no longer 'running' (reaped / replaced) and we're\n // still executing, self-abort so we stop executing and don't overwrite\n // the newer state with our terminal write.\n if (!abort.signal.aborted) {\n const status = await getRunStatus(runId);\n if (status !== null && status !== \"running\") {\n abortInMemoryRun(run, \"displaced\");\n }\n }\n })\n .catch(() => {});\n };\n\n // Heartbeat: bump heartbeat_at every 1.5s so watchers can detect a dead\n // producer (process crash, HMR restart, isolate eviction) quickly and\n // reap the row. Paired with RUN_STALE_MS (15s) — 10x the interval to\n // tolerate transient DB slowness without false positives.\n let consecutiveHeartbeatFailures = 0;\n // Single-flight the heartbeat write. The timer fires every 1.5s but a write\n // can take up to the DB op timeout (~8s) when the Neon pooler is saturated.\n // Firing a fresh write each tick regardless piled up ~5 concurrent writes\n // under contention, each holding a pooler connection — ADDING to the exact\n // connection-cap exhaustion that starves the heartbeat and false-reaps the\n // run as stale. Skip a tick's write while one is still outstanding so a run\n // holds at most one heartbeat connection. The abort/backstop checks below\n // still run every tick (they don't touch the DB on the hot path).\n let heartbeatInFlight = false;\n const heartbeatTimer: ReturnType<typeof setInterval> = setInterval(() => {\n if (!heartbeatInFlight) {\n heartbeatInFlight = true;\n updateRunHeartbeat(runId)\n .then(() => {\n consecutiveHeartbeatFailures = 0;\n })\n .catch((error) => {\n consecutiveHeartbeatFailures += 1;\n // Swallow routine single-tick blips; escalate once failures approach\n // the stale window so false-positive stale_run from silent write\n // failures is diagnosable.\n if (consecutiveHeartbeatFailures >= 3) {\n captureError(error, {\n route: \"/_agent-native/agent-chat\",\n tags: {\n source: \"agent-run-manager\",\n phase: \"heartbeat\",\n consecutiveFailures: String(consecutiveHeartbeatFailures),\n },\n extra: { runId, threadId },\n });\n }\n })\n .finally(() => {\n heartbeatInFlight = false;\n });\n }\n checkSqlAbort();\n checkNoProgressBackstop();\n }, 1500);\n const softTimeoutMs = resolveRunSoftTimeoutMs(options?.softTimeoutMs, {\n useHostedDefault: options?.useHostedSoftTimeoutDefault === true,\n backgroundFunction: options?.backgroundFunction === true,\n });\n // Armed only when a soft-timeout regime is active (hosted): local dev keeps\n // unbounded runs. For 40s foreground chunks the soft timeout always fires\n // first, so in practice this guards the long background chunks.\n const noProgressTimeoutMs =\n options?.noProgressTimeoutMs ??\n (softTimeoutMs > 0\n ? options?.backgroundFunction === true\n ? DEFAULT_BACKGROUND_NO_PROGRESS_TIMEOUT_MS\n : RUN_NO_PROGRESS_HARD_TIMEOUT_MS\n : 0);\n const softTimeoutTimer =\n softTimeoutMs > 0\n ? setTimeout(() => {\n if (run.status !== \"running\" || abort.signal.aborted) return;\n softTimedOut = true;\n send({\n type: \"auto_continue\",\n reason: \"run_timeout\",\n });\n abort.abort(\"run_timeout\");\n }, softTimeoutMs)\n : null;\n let pendingTerminalEvent: RunEvent | null = null;\n\n const captureRunError = (error: unknown, phase: \"run\" | \"completion\") => {\n const errorCode =\n error instanceof EngineError ? getEngineRunErrorCode(error) : undefined;\n captureError(error, {\n route: \"/_agent-native/agent-chat\",\n tags: {\n source: \"agent-run-manager\",\n phase,\n runStatus: run.status,\n softTimedOut: softTimedOut ? \"true\" : \"false\",\n abortReason: run.abortReason,\n errorCode,\n },\n extra: {\n runId,\n threadId,\n eventCount: run.events.length,\n startedAt: run.startedAt,\n softTimeoutMs,\n },\n contexts: {\n agentRun: {\n runId,\n threadId,\n status: run.status,\n phase,\n eventCount: run.events.length,\n startedAt: run.startedAt,\n softTimeoutMs,\n softTimedOut,\n abortReason: run.abortReason,\n },\n },\n });\n };\n\n const emitRunEvent = (\n runEvent: RunEvent,\n options?: { surfacePersistenceError?: boolean },\n ): Promise<void> => {\n run.events.push(runEvent);\n\n // Notify in-memory subscribers (same isolate, fast path)\n for (const subscriber of run.subscribers) {\n try {\n subscriber(runEvent);\n } catch {\n run.subscribers.delete(subscriber);\n }\n }\n\n // Bump the durable progress timestamp. Distinct from the heartbeat:\n // heartbeat = \"process is up\", progress = \"real work is happening.\" The\n // gap between them is what the client-side stuck-detector reads to tell\n // a hung run from a healthy one. Keepalive and zero-byte action prep are\n // liveness only; streamed input bytes, text, and tool lifecycle events are\n // real progress.\n trackInFlightWork(runEvent.event);\n if (shouldBumpProgressForEvent(runEvent.event)) {\n lastRealProgressAt = Date.now();\n bumpProgressIfDue();\n }\n\n // Persist event to SQL. Events are chained through persistenceChain so\n // inserts commit in seq order — an out-of-order commit would advance the\n // SQL poller's cursor past the slow row, permanently dropping it for\n // reconnecting clients. Terminal events surface persistence errors so the\n // caller can decide how to handle a failed final write.\n const thisInsert = persistenceChain.then(() =>\n insertRunEvent(runId, runEvent.seq, JSON.stringify(runEvent.event)),\n );\n persistenceChain = thisInsert.catch((error) => {\n if (!eventPersistenceErrorCaptured) {\n eventPersistenceErrorCaptured = true;\n captureRunPersistenceError(error, \"insert-event\", {\n seq: runEvent.seq,\n eventType: runEvent.event.type,\n });\n }\n });\n const persistence = thisInsert;\n if (!options?.surfacePersistenceError) {\n persistence.catch(() => {});\n }\n\n checkSqlAbort();\n return persistence;\n };\n\n const send = (event: AgentChatEvent) => {\n if (run.status === \"aborted\" && abort.signal.aborted) return;\n\n const runEvent: RunEvent = { seq: run.events.length, event };\n if (isTerminalRunEvent(event)) {\n pendingTerminalEvent = runEvent;\n return;\n }\n\n emitRunEvent(runEvent);\n };\n\n // Run in background — intentionally detached from any HTTP connection\n const runPromise = runFn(send, abort.signal)\n .then(() => {\n if (abort.signal.aborted) {\n run.status = softTimedOut ? \"completed\" : \"aborted\";\n return;\n }\n run.status = \"completed\";\n })\n .catch((err) => {\n // Don't surface abort errors — the run was intentionally stopped\n if (abort.signal.aborted) {\n run.status = softTimedOut ? \"completed\" : \"aborted\";\n return;\n }\n run.status = \"errored\";\n if (shouldCaptureRunError(err)) {\n captureRunError(err, \"run\");\n }\n const errorMessage = getRunErrorMessage(err);\n const errorCode =\n err instanceof EngineError ? getEngineRunErrorCode(err) : undefined;\n const details =\n err instanceof EngineError ? getEngineRunErrorDetails(err) : undefined;\n send({\n type: \"error\",\n error: errorMessage,\n ...(errorCode ? { errorCode } : {}),\n ...(details ? { details } : {}),\n ...(err instanceof EngineError && err.upgradeUrl\n ? { upgradeUrl: err.upgradeUrl }\n : {}),\n });\n })\n .finally(async () => {\n // Ordering matters here — this is the atomic-complete boundary.\n // Invariant: once agent_runs.status flips to \"completed\"/\"errored\"\n // in SQL, thread_data for this turn is already durable. This lets\n // reconnecting clients trust the simple rule \"status != running →\n // fetch thread_data\" without polling/retrying for a race window\n // where onComplete was still pending.\n\n // 1. Await the completion callback (thread_data save). Heartbeat is\n // still ticking so the run doesn't look stale to any concurrent\n // /runs/active check while we wait for SQL writes to land.\n let completionError: unknown = null;\n let terminalPersistenceError: unknown = null;\n const resolveTerminalEventForCompletion = () => {\n const continuationTerminalEvent = run.continuationTerminalEvent\n ? {\n seq: run.events.length,\n event: run.continuationTerminalEvent,\n }\n : null;\n return continuationTerminalEvent ?? pendingTerminalEvent;\n };\n let terminalEventForCompletion = resolveTerminalEventForCompletion();\n let terminalEvent = terminalEventForCompletion?.event ?? null;\n if (\n onComplete &&\n !(run.status === \"aborted\" && run.abortReason === \"no_progress\")\n ) {\n try {\n const completionStatus =\n run.status !== \"aborted\" &&\n terminalEventForcesErroredStatus(terminalEvent)\n ? \"errored\"\n : run.status;\n const completionRun: ActiveRun =\n terminalEventForCompletion || completionStatus !== run.status\n ? {\n ...run,\n status: completionStatus,\n events: terminalEventForCompletion\n ? [...run.events, terminalEventForCompletion]\n : run.events,\n }\n : run;\n await onComplete(completionRun);\n } catch (err) {\n completionError = err;\n captureRunError(err, \"completion\");\n console.error(\n \"[run-manager] onComplete callback error:\",\n err instanceof Error ? err.message : err,\n );\n }\n }\n\n // Server-driven continuation is installed by onComplete after the\n // successor has been dispatched. Resolve the terminal event again so\n // this chunk emits auto_continue instead of a misleading done event.\n terminalEventForCompletion = resolveTerminalEventForCompletion();\n terminalEvent = terminalEventForCompletion?.event ?? null;\n\n // 2. Compute final status. If the completion callback threw, we'd\n // rather mark the run errored than claim success with incomplete\n // thread_data.\n const finalStatus =\n run.status === \"aborted\"\n ? \"aborted\"\n : run.status === \"errored\" ||\n completionError ||\n terminalEventForcesErroredStatus(terminalEvent)\n ? \"errored\"\n : \"completed\";\n const terminalReason = terminalReasonForRun(\n finalStatus,\n terminalEvent,\n run.abortReason,\n completionError,\n );\n\n // 3. Emit the terminal event only after thread_data is durable. Live\n // SSE clients close on this event and usually fetch thread_data\n // immediately, so emitting it earlier recreates the final-message\n // race this manager is meant to avoid.\n if (finalStatus === \"completed\" || finalStatus === \"errored\") {\n // Choose the terminal event payload (done / the stashed terminal /\n // a synthesized error). NOTE: the `seq` carried by\n // `pendingTerminalEvent` was captured by `send()` at stash time as\n // `run.events.length` and is NOT authoritative — if the runFn emitted\n // any more events before it actually stopped on the abort signal,\n // those events were pushed and reused that same seq. Persisting the\n // terminal event with the stale seq would collide with an\n // already-persisted streaming event and get silently dropped by\n // insertRunEvent's `ON CONFLICT (run_id, seq) DO NOTHING`, so the\n // client would never see the terminal/continuation signal. We always\n // re-stamp the seq at emit time (max-seq+1) just below.\n const terminalEvent: AgentChatEvent =\n finalStatus === \"completed\"\n ? (terminalEventForCompletion?.event ?? { type: \"done\" })\n : terminalEventForCompletion?.event.type === \"error\" ||\n terminalEventForCompletion?.event.type === \"missing_api_key\"\n ? terminalEventForCompletion.event\n : terminalEventForCompletion?.event.type === \"auto_continue\"\n ? // The run was checkpointed at a soft-timeout/loop boundary and\n // is recoverable: the partial turn is in agent_run_events and\n // the continuation run will re-attempt the thread_data save.\n // Even though the completion save failed (finalStatus stays\n // \"errored\" for SQL/diagnostics), re-emit the auto_continue so\n // the client resumes instead of seeing a dead chat.\n terminalEventForCompletion.event\n : {\n type: \"error\",\n error: completionError\n ? \"Agent response could not be saved.\"\n : \"Agent run ended unexpectedly\",\n };\n const last = run.events[run.events.length - 1];\n if (!last || !isTerminalRunEvent(last.event)) {\n // Assign the seq at EMIT time, not at stash time. `run.events` is a\n // contiguous 0-based log, so `run.events.length` is the next free\n // seq and can never collide with an event that was pushed after the\n // terminal event was stashed.\n const terminal: RunEvent = {\n seq: run.events.length,\n event: terminalEvent,\n };\n try {\n await emitRunEvent(terminal, { surfacePersistenceError: true });\n } catch (err) {\n terminalPersistenceError = err;\n captureRunError(err, \"completion\");\n console.error(\n \"[run-manager] terminal event persistence error:\",\n err instanceof Error ? err.message : err,\n );\n try {\n await insertRunEvent(\n runId,\n terminal.seq,\n JSON.stringify(terminal.event),\n );\n terminalPersistenceError = null;\n } catch (retryError) {\n terminalPersistenceError = retryError;\n captureRunError(retryError, \"completion\");\n console.error(\n \"[run-manager] terminal event retry persistence error:\",\n retryError instanceof Error ? retryError.message : retryError,\n );\n }\n }\n }\n }\n for (const subscriber of run.subscribers) {\n run.subscribers.delete(subscriber);\n }\n\n // 4. Stop the heartbeat — all liveness writes are done.\n clearInterval(heartbeatTimer);\n if (softTimeoutTimer) clearTimeout(softTimeoutTimer);\n\n // 5. Persist final status to SQL. Use the conditional write so a zombie\n // run (reaped or displaced while executing) cannot clobber the newer\n // status written by the reaper or a replacement run.\n try {\n await insertRunPromise;\n if (!terminalPersistenceError) {\n let statusUpdated = false;\n try {\n statusUpdated = await updateRunStatusIfRunning(runId, finalStatus);\n } catch {\n statusUpdated = false;\n }\n if (statusUpdated) {\n await setRunTerminalReason(runId, terminalReason);\n } else {\n await reconcileTerminalRunFromEvents(runId).catch(() => false);\n }\n }\n } catch {\n // Best-effort — reapIfStale will eventually clean this up via\n // the heartbeat-stale path.\n }\n\n // 5b. Record terminal failure classification for errored runs so\n // cut-off / failed chats are queryable for pattern analysis. Read\n // the actual error event the run emitted (errorCode + message) so\n // diagnostics reflect the real cause (builder_gateway_timeout,\n // stale_run, context_length_exceeded, completion_error, …).\n if (finalStatus === \"errored\") {\n let errorCode: string | undefined;\n let errorDetail: string | undefined;\n const diagnosticEvents = pendingTerminalEvent\n ? [...run.events, pendingTerminalEvent]\n : run.events;\n for (let i = diagnosticEvents.length - 1; i >= 0; i--) {\n const ev = diagnosticEvents[i].event as {\n type: string;\n error?: string;\n errorCode?: string;\n details?: string;\n };\n if (ev.type === \"missing_api_key\") {\n errorCode = LLM_MISSING_CREDENTIALS_ERROR_CODE;\n errorDetail = LLM_MISSING_CREDENTIALS_MESSAGE;\n break;\n } else if (ev.type === \"error\") {\n errorCode = ev.errorCode;\n errorDetail = ev.error ?? ev.details;\n break;\n }\n }\n if (completionError && !errorCode) {\n errorCode = \"completion_error\";\n errorDetail =\n errorDetail ??\n (completionError instanceof Error\n ? completionError.message\n : String(completionError));\n }\n await setRunError(runId, errorCode ?? \"unknown\", errorDetail);\n }\n\n if (terminalPersistenceError) {\n const reconciled = await reconcileTerminalRunFromEvents(runId).catch(\n () => false,\n );\n if (!reconciled) throw terminalPersistenceError;\n }\n\n // 6. Schedule in-memory cleanup + opportunistic old-run pruning.\n setTimeout(() => {\n activeRuns.delete(runId);\n if (threadToRun.get(threadId) === runId) {\n threadToRun.delete(threadId);\n }\n }, CLEANUP_DELAY_MS);\n cleanupOldRuns(\n resolveCompletedRunRetentionMs(),\n resolveErroredRunRetentionMs(),\n ).catch(() => {});\n });\n runPromise.then(resolveFinalized, rejectFinalized);\n\n // On Cloudflare Workers, keep the isolate alive for this run\n try {\n const cfCtx = (\n globalThis as typeof globalThis & {\n __cf_ctx?: { waitUntil(promise: Promise<unknown>): void };\n }\n ).__cf_ctx;\n if (cfCtx?.waitUntil) {\n cfCtx.waitUntil(runPromise);\n }\n } catch {\n // Not on Workers — ignore\n }\n\n return run;\n}\n\n/**\n * Subscribe to a run's events starting from `fromSeq`.\n * Returns a ReadableStream that replays buffered events then live-tails.\n * Cancelling the stream only unsubscribes — does NOT abort the agent.\n *\n * Falls back to SQL polling when the run is not in local memory\n * (cross-isolate reconnection on Workers).\n */\nexport function subscribeToRun(\n runId: string,\n fromSeq: number,\n): ReadableStream<Uint8Array> | null {\n const run = activeRuns.get(runId);\n if (run) {\n return subscribeInMemory(run, fromSeq);\n }\n // Not in local memory — try SQL (cross-isolate path)\n return subscribeFromSQL(runId, fromSeq);\n}\n\n/** In-memory subscription (same isolate, fast path) */\nfunction subscribeInMemory(\n run: ActiveRun,\n fromSeq: number,\n): ReadableStream<Uint8Array> {\n const encoder = new TextEncoder();\n let subscriberRef: ((event: RunEvent) => void) | null = null;\n let pingTimer: ReturnType<typeof setInterval> | null = null;\n\n return new ReadableStream({\n start(controller) {\n const ping = () => {\n try {\n controller.enqueue(encoder.encode(`: ping ${Date.now()}\\n\\n`));\n } catch {\n if (subscriberRef) run.subscribers.delete(subscriberRef);\n if (pingTimer) clearInterval(pingTimer);\n }\n };\n ping();\n pingTimer = setInterval(ping, 10_000);\n\n // Replay buffered events from fromSeq\n for (let i = fromSeq; i < run.events.length; i++) {\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ ...run.events[i].event, seq: run.events[i].seq })}\\n\\n`,\n ),\n );\n } catch {\n return;\n }\n }\n\n // If run is already done, close immediately\n if (run.status !== \"running\") {\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n return;\n }\n\n // Subscribe to live events\n subscriberRef = (event: RunEvent) => {\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ ...event.event, seq: event.seq })}\\n\\n`,\n ),\n );\n // Close stream after terminal events\n if (isTerminalRunEvent(event.event)) {\n run.subscribers.delete(subscriberRef!);\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n }\n } catch {\n run.subscribers.delete(subscriberRef!);\n }\n };\n\n run.subscribers.add(subscriberRef);\n },\n cancel() {\n // Only unsubscribe — do NOT abort the agent run\n if (subscriberRef) run.subscribers.delete(subscriberRef);\n if (pingTimer) clearInterval(pingTimer);\n },\n });\n}\n\n/** SQL-based subscription (cross-isolate, polling) */\nfunction subscribeFromSQL(\n runId: string,\n fromSeq: number,\n): ReadableStream<Uint8Array> | null {\n const encoder = new TextEncoder();\n let cancelled = false;\n let pollTimer: ReturnType<typeof setTimeout> | null = null;\n let pingTimer: ReturnType<typeof setInterval> | null = null;\n\n return new ReadableStream({\n async start(controller) {\n let lastSeq = fromSeq;\n let activePollUntil = 0;\n let lastStatusCheckAt = 0;\n const ping = () => {\n try {\n controller.enqueue(encoder.encode(`: ping ${Date.now()}\\n\\n`));\n } catch {\n cancelled = true;\n if (pingTimer) clearInterval(pingTimer);\n }\n };\n ping();\n pingTimer = setInterval(ping, 10_000);\n\n const poll = async () => {\n if (cancelled) return;\n try {\n // Read new events from SQL\n const events = await getRunEventsSince(runId, lastSeq);\n if (events.length > 0) {\n activePollUntil = Date.now() + SQL_SUBSCRIPTION_ACTIVE_GRACE_MS;\n }\n for (const { seq, eventData } of events) {\n // Advance the cursor first, before any parse/enqueue branch can\n // `continue`/`return`. Otherwise a single corrupt (unparseable)\n // event row is re-fetched on every poll tick forever, wedging the\n // SSE stream open and never delivering a terminal event.\n lastSeq = seq + 1;\n let parsed: any;\n try {\n parsed = JSON.parse(eventData);\n } catch {\n continue;\n }\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ ...parsed, seq })}\\n\\n`,\n ),\n );\n } catch {\n cancelled = true;\n return;\n }\n\n // Close on terminal events\n if (isTerminalRunEvent(parsed)) {\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n return;\n }\n }\n\n // Check if run completed (no terminal event but status changed)\n if (events.length === 0) {\n const now = Date.now();\n if (now - lastStatusCheckAt < SQL_SUBSCRIPTION_STATUS_POLL_MS) {\n if (!cancelled) {\n const pollMs = resolveSqlSubscriptionPollMs(\n now,\n activePollUntil,\n );\n pollTimer = setTimeout(poll, pollMs);\n }\n return;\n }\n lastStatusCheckAt = now;\n // Opportunistically reap a stale producer before trusting SQL's\n // \"running\" status — otherwise a crashed server leaves us polling\n // forever.\n await reapIfStale(runId).catch(() => {});\n const run = await getRunById(runId);\n if (!run || run.status !== \"running\") {\n // Run ended — do one final event read, then close\n const finalEvents = await getRunEventsSince(runId, lastSeq);\n for (const { seq, eventData } of finalEvents) {\n // Advance first — see the main poll loop above for why.\n lastSeq = seq + 1;\n let parsed: any;\n try {\n parsed = JSON.parse(eventData);\n } catch {\n continue;\n }\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ ...parsed, seq })}\\n\\n`,\n ),\n );\n } catch {\n cancelled = true;\n return;\n }\n if (isTerminalRunEvent(parsed)) {\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n return;\n }\n }\n if (run?.status === \"aborted\") {\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ type: \"done\", seq: lastSeq })}\\n\\n`,\n ),\n );\n } catch {\n cancelled = true;\n return;\n }\n } else if (run?.status === \"completed\") {\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({ type: \"done\", seq: lastSeq })}\\n\\n`,\n ),\n );\n } catch {\n cancelled = true;\n return;\n }\n } else if (run?.status === \"errored\") {\n // The run row is terminal but this subscriber's cursor is\n // already past (or never saw) the terminal event. Prefer the\n // REAL last terminal event / row error_detail over inventing\n // a stale_run card — slides prod showed Connection error.\n // rows being mislabeled as stale_run on reconnect because\n // this path always synthesized STALE_RUN_ERROR_EVENT.\n const existing = await getLastTerminalRunEvent(runId).catch(\n () => null,\n );\n const resolved = existing\n ? { event: existing.event, shouldPersist: false }\n : resolveErroredRunTerminalEvent(run);\n if (resolved.shouldPersist) {\n await ensureTerminalRunEvent(runId, resolved.event).catch(\n () => {},\n );\n }\n try {\n controller.enqueue(\n encoder.encode(\n `data: ${JSON.stringify({\n ...resolved.event,\n seq: existing?.seq ?? lastSeq,\n })}\\n\\n`,\n ),\n );\n } catch {\n cancelled = true;\n return;\n }\n }\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n return;\n }\n }\n\n // Schedule next poll\n if (!cancelled) {\n const pollMs = resolveSqlSubscriptionPollMs(\n Date.now(),\n activePollUntil,\n );\n pollTimer = setTimeout(poll, pollMs);\n }\n } catch {\n // SQL error — close stream\n try {\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n } catch {}\n }\n };\n\n // Verify run exists before starting poll\n try {\n const run = await getRunById(runId);\n if (!run) {\n if (pingTimer) clearInterval(pingTimer);\n controller.close();\n return;\n }\n } catch {\n controller.close();\n return;\n }\n\n await poll();\n },\n cancel() {\n cancelled = true;\n if (pollTimer) clearTimeout(pollTimer);\n if (pingTimer) clearInterval(pingTimer);\n },\n });\n}\n\n/** Get the active run for a thread (if any) — checks memory then SQL */\nexport function getActiveRunForThread(threadId: string): ActiveRun | null {\n const runId = threadToRun.get(threadId);\n if (runId) {\n const run = activeRuns.get(runId);\n if (run) return run;\n }\n return null;\n}\n\n/**\n * Async version that also checks SQL — for cross-isolate access.\n * Used by the /runs/active endpoint.\n *\n * Returns `heartbeatAt` so the client can independently decide a run is\n * dead even before the server-side stale reap has fired. Returns\n * `lastProgressAt` so the client-side stuck-detector can show a\n * user-visible \"this chat looks stuck\" affordance when a run is alive\n * (heartbeating) but not actually emitting events. Returns\n * `awaitingRedispatch` so the client's background follow loop can tell a\n * legitimately-deferred `chainServerDrivenContinuation` successor (recovery\n * in progress server-side) apart from a genuinely dead run — see this\n * field's own doc comment below.\n */\nexport async function getActiveRunForThreadAsync(threadId: string): Promise<{\n runId: string;\n threadId: string;\n turnId: string;\n status: string;\n heartbeatAt: number;\n lastProgressAt: number | null;\n /** How the run was dispatched/continued (foreground, foreground-self-chain, background...). */\n dispatchMode?: string | null;\n /** Compact terminal classification, e.g. done, run_timeout, stale_run. */\n terminalReason?: string | null;\n /**\n * Last reached `_process-run` worker stage as a JSON string\n * `{stage,detail?,at}`. Surfaced so a silent background-worker death is\n * diagnosable from the client WITHOUT the unreadable bg-fn logs.\n */\n diagStage?: string | null;\n /**\n * True exactly when this run is a `chainServerDrivenContinuation` deferral\n * (dispatch_mode === 'background', never claimed) still inside\n * `UNCLAIMED_BACKGROUND_RUN_REDISPATCH_BOUND_MS` — the same condition this\n * function already uses below to skip its own `reapUnclaimedBackgroundRun`.\n * Surfaced on `/runs/active` (agent-chat-plugin.ts) so\n * `agent-chat-adapter.ts`'s follow loop can tell \"silently deferred,\n * server-side recovery in progress\" apart from \"dead\" and stop counting the\n * quiet gap against its idle timeout — see the THREE-SITE INVARIANT comment\n * below and in agent-chat-plugin.ts / production-agent.ts. Always false for\n * an in-memory run (that isolate IS the live producer) and for any run that\n * isn't an unclaimed background dispatch.\n */\n awaitingRedispatch: boolean;\n /**\n * True exactly when this run's `in_flight_since` marker is set — a tool\n * call or A2A `agent_call` delegation is open and has not yet resolved\n * (see `setRunInFlightMarker` / `IN_FLIGHT_RUN_STALE_GRACE_MS` in\n * run-store.ts). This is the SAME signal `reapIfStale` reads to grant its\n * bounded stale-reap grace — computed here from the identical\n * `in_flight_since` column via `getRunByThread`, never re-derived, so the\n * client and the reaper cannot disagree about what \"in flight\" means.\n *\n * Surfaced on `/runs/active` (agent-chat-plugin.ts) as the\n * server-authoritative alternative to the client-side proxy\n * `RunStuckBanner` currently infers from unresolved `tool-call` content\n * parts in the local message list — that proxy can go stale after a\n * reconnect or reader-mode replay; this cannot, because it is read fresh\n * from SQL on every poll.\n */\n hasInFlightWork: boolean;\n} | null> {\n // Check memory first — return both running AND recently-completed runs\n // that still have events in memory. This allows sub-agent tabs to replay\n // the full conversation from completed runs via SSE.\n const memRun = getActiveRunForThread(threadId);\n if (memRun && (memRun.status === \"running\" || memRun.events.length > 0)) {\n const sqlSnapshot = await fetchRunThreadSnapshot(memRun.runId, threadId);\n\n // FIX 1 (durable-background incident): a terminal in-memory run (chunk\n // completed at a soft-timeout/no-progress/loop-limit boundary, or any\n // other terminal outcome) never clears `threadToRun` — it stays this\n // thread's resident in-memory candidate for up to CLEANUP_DELAY_MS\n // (5 min), and `fetchRunThreadSnapshot` above returns null the instant\n // SQL's newest row for the thread is no longer THIS run (i.e. a\n // successor already exists). Left alone, every poll that lands on this\n // warm isolate would keep falling back to `memRun.status` below and\n // never discover that a newer, still-running successor already exists\n // in SQL — exactly the \"stale terminal run masks a live successor\" bug\n // that produced the mid-sentence dead turn. Only pay for the extra SQL\n // read here, in the terminal-candidate branch; the common \"still\n // running\" poll (the vast majority) never reaches it.\n if (!sqlSnapshot && memRun.status !== \"running\") {\n const successor = await fetchNewerNonTerminalRunForSameTurn(\n threadId,\n memRun,\n );\n if (successor) {\n return {\n runId: successor.id,\n threadId: successor.threadId,\n turnId: successor.turnId ?? successor.id,\n status: successor.status,\n heartbeatAt: successor.heartbeatAt ?? successor.startedAt,\n lastProgressAt: successor.lastProgressAt,\n dispatchMode: successor.dispatchMode,\n terminalReason: successor.terminalReason,\n diagStage: successor.diagStage,\n // Definitionally non-terminal and freshly read from SQL above —\n // never the stale in-memory candidate's own state.\n awaitingRedispatch: false,\n hasInFlightWork: successor.inFlightSince != null,\n };\n }\n }\n\n const status = sqlSnapshot?.status ?? memRun.status;\n const heartbeatAt =\n status === \"running\"\n ? Date.now()\n : (sqlSnapshot?.heartbeatAt ?? memRun.startedAt);\n return {\n runId: memRun.runId,\n threadId: memRun.threadId,\n turnId: memRun.turnId,\n status,\n // In-memory means this isolate is the producer. By definition, the\n // heartbeat is fresh as of \"now\" while the run is still running. Once\n // SQL has terminal truth, prefer that timestamp so a stale in-memory\n // buffer cannot keep the browser believing a finished background run is\n // still alive.\n heartbeatAt,\n // For an in-memory run we don't have a separate \"last event emit\"\n // timestamp tracked in JS — the SQL bump is throttled per-second.\n // Read it back from SQL on demand. For the common case the SQL row\n // is well under 1s old; if it isn't, the stuck-detector will pick\n // it up on the next poll cycle.\n lastProgressAt: sqlSnapshot?.lastProgressAt ?? null,\n dispatchMode: sqlSnapshot?.dispatchMode ?? null,\n terminalReason: sqlSnapshot?.terminalReason ?? null,\n diagStage: sqlSnapshot?.diagStage ?? null,\n // In-memory means this isolate is the live producer — never the\n // \"deferred, nobody producing\" state this flag identifies.\n awaitingRedispatch: false,\n // Read from the SAME SQL snapshot the other fields above already read\n // (`fetchRunThreadSnapshot` -> `getRunByThread`) rather than the\n // producer's own in-memory `inFlightWorkCount` — this isolate IS the\n // live producer, but there is no separate in-memory channel wired for\n // that counter today, and the SQL marker is written on every 0<->N\n // transition (see run-manager's `trackInFlightWork`), so it is at most\n // one event behind here — the same tolerance `lastProgressAt` above\n // already accepts.\n hasInFlightWork: sqlSnapshot?.inFlightSince != null,\n };\n }\n // Fall back to SQL — also surface recently terminated runs so the client\n // can reconnect and replay synthesized done/error events instead of\n // retrying the original POST. Without this, a POST that fails after the\n // server already accepted (and finished) the run would re-execute the\n // turn and double-apply mutations: the in-memory branch above already\n // returns terminal runs whose events are still buffered, but the SQL\n // path is the only authority once memory has been evicted.\n try {\n const sqlRun = await getRunByThread(threadId, { includeTerminal: true });\n if (!sqlRun) return null;\n if (sqlRun.status === \"running\") {\n // FALLBACK HARDENING: a background-dispatched run that is still UNCLAIMED\n // (dispatch_mode === 'background', never flipped to 'background-processing')\n // past the tight grace means the bg-fn worker never started — a silent\n // async-worker death that the 202-ack inline fallback can't catch. Reap it\n // early and recoverably (background_worker_never_started) so the run no\n // longer hangs for the full 90s window. Only fires when there is provably\n // no live worker; a claimed/heartbeating run is left alone by the\n // conditional SQL.\n //\n // REDISPATCH-BOUND GUARD (must be kept in lockstep with the \"Unclaimed\n // background-run sweep\" in agent-chat-plugin.ts and with\n // chainServerDrivenContinuation's deferral in production-agent.ts — do NOT\n // remove this guard without reading those two sites):\n // `chainServerDrivenContinuation` now DEFERS a dispatch-failed successor\n // instead of erroring it — it leaves the row status='running',\n // dispatch_mode='background' with its dispatch_payload intact so the sweep\n // can silently redispatch it. This client poll runs every ~1s while a\n // client is connected, so without this guard it would reap that deferred\n // successor at the 25s unclaimed grace — long before the ~2-min sweep —\n // converting the intended SILENT server-side recovery into a user-visible\n // `background_worker_never_started` manual-retry error (that terminal\n // reason does NOT auto-continue in the client follow loop; only `stale_run`\n // does). While the successor is still inside its redispatch bound we skip\n // this reap and leave it for the sweep. The outer backstops still bound it:\n // `reapIfStale` below reaps a heartbeat-stale background row at 90s\n // (BACKGROUND_RUN_STALE_MS) to the recoverable `stale_run` — which the\n // follow loop AUTO-continues — and once the redispatch bound is exceeded\n // this reap fires loudly as before. So recovery stays automatic in the\n // common case and loud failure is only moved later, never removed.\n //\n // `isUnclaimedBackgroundDispatch` also becomes the `awaitingRedispatch`\n // wire field below once the still-inside-the-bound check passes — see\n // this function's doc comment and the THREE-SITE INVARIANT comment in\n // agent-chat-plugin.ts / production-agent.ts.\n const isUnclaimedBackgroundDispatch =\n sqlRun.dispatchMode === \"background\";\n const stillInsideRedispatchBound = shouldRedispatchUnclaimedBackgroundRun(\n { startedAt: sqlRun.startedAt },\n );\n if (isUnclaimedBackgroundDispatch && !stillInsideRedispatchBound) {\n const recovered = await reapUnclaimedBackgroundRun(sqlRun.id).catch(\n () => false,\n );\n if (recovered) return null;\n }\n // If the producer is dead (no recent heartbeat), reap before the\n // client can see a stale \"running\" status and enter a reconnect\n // loop it can never exit.\n const reaped = await reapIfStale(sqlRun.id).catch(() => false);\n if (reaped) return null;\n return {\n runId: sqlRun.id,\n threadId: sqlRun.threadId,\n turnId: sqlRun.turnId ?? sqlRun.id,\n status: sqlRun.status,\n heartbeatAt: sqlRun.heartbeatAt ?? sqlRun.startedAt,\n lastProgressAt: sqlRun.lastProgressAt,\n dispatchMode: sqlRun.dispatchMode,\n terminalReason: sqlRun.terminalReason,\n diagStage: sqlRun.diagStage,\n awaitingRedispatch:\n isUnclaimedBackgroundDispatch && stillInsideRedispatchBound,\n // Same `in_flight_since` column `reapIfStale` (just called above,\n // and it did NOT reap this row) reads for its own grace decision —\n // one source of truth, not a second re-derived notion of \"in flight\".\n hasInFlightWork: sqlRun.inFlightSince != null,\n };\n }\n if (sqlRun.status === \"completed\" || sqlRun.status === \"errored\") {\n // Cap how far back we'll surface terminal runs as \"active\". The goal\n // is to catch the recently-completed-but-reconnecting case, not to\n // resurrect ancient turns when the user reopens an old thread.\n //\n // Measure age from the run's terminal timestamp, not its start. A\n // long-running task that ran 11 minutes and completed five seconds\n // ago should still be reachable — the client's disconnect happened\n // around completion, so completion time is what matters for the\n // \"is the user still here waiting?\" question. Fall back to the last\n // heartbeat (older deployments may have unset completed_at) and\n // finally to startedAt for ancient rows.\n const referenceAt =\n sqlRun.completedAt ?? sqlRun.heartbeatAt ?? sqlRun.startedAt;\n const terminalAge = Date.now() - referenceAt;\n if (terminalAge > TERMINAL_RUN_RECONNECT_WINDOW_MS) return null;\n return {\n runId: sqlRun.id,\n threadId: sqlRun.threadId,\n turnId: sqlRun.turnId ?? sqlRun.id,\n status: sqlRun.status,\n heartbeatAt: sqlRun.heartbeatAt ?? sqlRun.startedAt,\n lastProgressAt: sqlRun.lastProgressAt,\n dispatchMode: sqlRun.dispatchMode,\n terminalReason: sqlRun.terminalReason,\n diagStage: sqlRun.diagStage,\n // Terminal already — never the \"still deferred, running\" state.\n awaitingRedispatch: false,\n // Terminal already — no live work can still be in flight.\n hasInFlightWork: false,\n };\n }\n } catch {\n // SQL error — fall through\n }\n return null;\n}\n\nasync function fetchRunThreadSnapshot(runId: string, threadId: string) {\n try {\n // `getRunById` returns a narrow projection today; ask for the row via\n // the thread lookup which carries dispatch/terminal/progress fields.\n const byThread = await getRunByThread(threadId, {\n includeTerminal: true,\n });\n if (byThread && byThread.id === runId) return byThread;\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * FIX 1 (durable-background incident): find a genuinely newer, still-running\n * SQL row for the SAME turn as a terminal in-memory `ActiveRun` — used only\n * when `fetchRunThreadSnapshot` found no SQL row matching the in-memory\n * run's own id (i.e. SQL's newest row for the thread is a different run).\n * `getRunByThread` always returns the thread's newest row by `started_at`,\n * so this is the same read `fetchRunThreadSnapshot` already made; we just\n * don't throw its result away when the id doesn't match.\n *\n * Scoped to the SAME `turnId` (not just the same thread) so an unrelated,\n * later user turn on the same thread is never mistaken for a continuation\n * successor of this one.\n */\nasync function fetchNewerNonTerminalRunForSameTurn(\n threadId: string,\n memRun: ActiveRun,\n): Promise<Awaited<ReturnType<typeof getRunByThread>> | null> {\n try {\n const latest = await getRunByThread(threadId, { includeTerminal: true });\n if (\n latest &&\n latest.id !== memRun.runId &&\n latest.status === \"running\" &&\n latest.startedAt > memRun.startedAt &&\n (latest.turnId ?? latest.id) === memRun.turnId\n ) {\n return latest;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/** Get a run by ID */\nexport function getRun(runId: string): ActiveRun | null {\n return activeRuns.get(runId) ?? null;\n}\n\nfunction abortRunInMemory(runId: string, reason: string): boolean {\n const run = activeRuns.get(runId);\n if (run) {\n abortInMemoryRun(run, reason);\n }\n return !!run;\n}\n\n/** Explicitly abort a run (e.g. Stop button). */\nexport function abortRun(runId: string, reason: string = \"user\"): boolean {\n const abortedInMemory = abortRunInMemory(runId, reason);\n // Also mark as aborted in SQL (for cross-isolate abort on Workers)\n markRunAborted(runId, reason).catch(() => {});\n return abortedInMemory;\n}\n\n/**\n * Abort a run and wait until the cross-isolate SQL state and terminal event\n * are durable. Request handlers that start recovery immediately after aborting\n * must use this path; otherwise the recovery POST can race the old row while\n * it is still marked running.\n */\nexport async function abortRunDurably(\n runId: string,\n reason: string = \"user\",\n): Promise<boolean> {\n const abortedInMemory = abortRunInMemory(runId, reason);\n try {\n await markRunAborted(runId, reason);\n } catch (error) {\n // The local run is already stopped. A transient durable cleanup failure\n // must not turn the user's Stop/Retry request into a 500 after that\n // irreversible in-memory outcome. Capture it for repair/reaping and let\n // the request report the abort it did complete.\n captureError(error, {\n route: \"/_agent-native/agent-chat/runs/:id/abort\",\n tags: {\n source: \"agent-run-manager\",\n phase: \"abort-run\",\n },\n extra: { runId, reason, abortedInMemory },\n });\n console.error(\n \"[run-manager] durable abort persistence failed:\",\n error instanceof Error ? error.message : error,\n );\n }\n return abortedInMemory;\n}\n\n// Re-export so callers can avoid importing from run-store directly.\nexport { tryClaimRunSlot } from \"./run-store.js\";\n"]}
@@ -13,8 +13,8 @@
13
13
  * Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
14
14
  */
15
15
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- error: string;
17
16
  ok?: undefined;
17
+ error: string;
18
18
  } | {
19
19
  error?: undefined;
20
20
  ok: boolean;
@@ -17,12 +17,12 @@ declare const _default: import("../../action.js").ActionDefinition<{
17
17
  id?: undefined;
18
18
  provider?: undefined;
19
19
  } | {
20
- error?: undefined;
21
20
  configured?: undefined;
22
21
  connectPath?: undefined;
23
22
  url: string;
24
23
  id: string;
25
24
  provider: string;
25
+ error?: undefined;
26
26
  }>;
27
27
  export default _default;
28
28
  //# sourceMappingURL=upload-image.d.ts.map
@@ -28,7 +28,7 @@ export declare function createNotificationsHandler(): import("h3").EventHandlerW
28
28
  } | {
29
29
  count?: undefined;
30
30
  updated?: undefined;
31
- ok: boolean;
32
31
  error?: undefined;
32
+ ok: boolean;
33
33
  }>>;
34
34
  //# sourceMappingURL=routes.d.ts.map
@@ -62,7 +62,7 @@ export declare function createObservabilityHandler(): import("h3").EventHandlerW
62
62
  summary?: undefined;
63
63
  spans?: undefined;
64
64
  id?: undefined;
65
- error?: undefined;
66
65
  ok: boolean;
66
+ error?: undefined;
67
67
  }>>;
68
68
  //# sourceMappingURL=routes.d.ts.map
@@ -49,8 +49,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
49
49
  }>;
50
50
  /** DELETE /_agent-native/resources/:id — delete a resource */
51
51
  export declare function handleDeleteResource(event: any): Promise<{
52
- ok?: undefined;
53
52
  error: string;
53
+ ok?: undefined;
54
54
  } | {
55
55
  error?: undefined;
56
56
  ok: boolean;
@@ -27,11 +27,11 @@ export declare function resolveAgentEngineApiKeyWriteTarget(event: H3Event, scop
27
27
  export declare function createAgentEngineApiKeyHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
28
28
  error: any;
29
29
  } | {
30
+ error?: undefined;
30
31
  ok: boolean;
31
32
  key: string;
32
33
  baseUrlKey?: string;
33
34
  scope: AgentEngineApiKeyScope;
34
- error?: undefined;
35
35
  }>>;
36
36
  export {};
37
37
  //# sourceMappingURL=agent-engine-api-key-route.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.121.0",
3
+ "version": "0.121.1",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -114,10 +114,15 @@ function isNetlifyHostedRuntimeForDispatch(): boolean {
114
114
  if (process.env.NETLIFY_LOCAL === "true") return false;
115
115
  if (process.env.NETLIFY === "false") return false;
116
116
  if (process.env.NETLIFY && process.env.NETLIFY !== "false") return true;
117
- // Netlify sets AWS Lambda runtime env on deployed Functions, but the build-time
118
- // NETLIFY flag is not always present in the runtime isolate. Treat Lambda as
119
- // Netlify here unless Netlify was explicitly disabled above; non-Netlify AWS
120
- // falls back inline if the /.netlify/functions dispatch fast-fails.
117
+ // NETLIFY is a build-only read-only variable. In deployed Functions Netlify
118
+ // documents URL, SITE_NAME, and SITE_ID as the runtime read-only variables;
119
+ // SITE_ID is the unambiguous host marker. Lambda compatibility mode also
120
+ // exposes AWS runtime variables, so keep the function-name fallback for older
121
+ // deploys. Without either check a modern Netlify Function silently selects the
122
+ // portable framework route even though the emitted background function exists.
123
+ if (process.env.SITE_ID) return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.
124
+ // Non-Netlify AWS falls back inline if the /.netlify/functions dispatch
125
+ // fast-fails.
121
126
  return Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME);
122
127
  }
123
128
 
@@ -202,6 +207,9 @@ export const AGENT_CHAT_BACKGROUND_RUN_FIELD = "__backgroundRun";
202
207
  * what "hosted" means.
203
208
  */
204
209
  export function isHostedRuntimeForDurableBackground(): boolean {
210
+ if (process.env.NETLIFY_LOCAL === "true") return false;
211
+ if (process.env.NETLIFY === "false") return false;
212
+ if (process.env.SITE_ID) return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.
205
213
  if (
206
214
  process.env.NETLIFY &&
207
215
  process.env.NETLIFY !== "false" &&
@@ -319,6 +319,9 @@ export interface ResolveRunSoftTimeoutOptions {
319
319
  * that clamp (and the platform wall behind it) exists.
320
320
  */
321
321
  export function isHostedRuntime(): boolean {
322
+ if (process.env.NETLIFY_LOCAL === "true") return false;
323
+ if (process.env.NETLIFY === "false") return false;
324
+ if (process.env.SITE_ID) return true; // guard:allow-env-credential -- Netlify's read-only public site identifier is a runtime host marker, not a user credential.
322
325
  if (
323
326
  process.env.NETLIFY &&
324
327
  process.env.NETLIFY !== "false" &&