@agent-native/core 0.52.0 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/README.md +41 -95
  2. package/blueprints/action/crud.md +98 -0
  3. package/blueprints/channel/discord.md +74 -0
  4. package/blueprints/provider/stripe.md +87 -0
  5. package/blueprints/sandbox/docker.md +78 -0
  6. package/dist/action.d.ts +64 -1
  7. package/dist/action.d.ts.map +1 -1
  8. package/dist/action.js +73 -2
  9. package/dist/action.js.map +1 -1
  10. package/dist/agent/index.d.ts +1 -0
  11. package/dist/agent/index.d.ts.map +1 -1
  12. package/dist/agent/index.js +1 -0
  13. package/dist/agent/index.js.map +1 -1
  14. package/dist/agent/observational-memory/compactor.d.ts +43 -0
  15. package/dist/agent/observational-memory/compactor.d.ts.map +1 -0
  16. package/dist/agent/observational-memory/compactor.js +50 -0
  17. package/dist/agent/observational-memory/compactor.js.map +1 -0
  18. package/dist/agent/observational-memory/config.d.ts +37 -0
  19. package/dist/agent/observational-memory/config.d.ts.map +1 -0
  20. package/dist/agent/observational-memory/config.js +48 -0
  21. package/dist/agent/observational-memory/config.js.map +1 -0
  22. package/dist/agent/observational-memory/index.d.ts +26 -0
  23. package/dist/agent/observational-memory/index.d.ts.map +1 -0
  24. package/dist/agent/observational-memory/index.js +25 -0
  25. package/dist/agent/observational-memory/index.js.map +1 -0
  26. package/dist/agent/observational-memory/internal-run.d.ts +37 -0
  27. package/dist/agent/observational-memory/internal-run.d.ts.map +1 -0
  28. package/dist/agent/observational-memory/internal-run.js +59 -0
  29. package/dist/agent/observational-memory/internal-run.js.map +1 -0
  30. package/dist/agent/observational-memory/message-text.d.ts +13 -0
  31. package/dist/agent/observational-memory/message-text.d.ts.map +1 -0
  32. package/dist/agent/observational-memory/message-text.js +46 -0
  33. package/dist/agent/observational-memory/message-text.js.map +1 -0
  34. package/dist/agent/observational-memory/migrations.d.ts +13 -0
  35. package/dist/agent/observational-memory/migrations.d.ts.map +1 -0
  36. package/dist/agent/observational-memory/migrations.js +43 -0
  37. package/dist/agent/observational-memory/migrations.js.map +1 -0
  38. package/dist/agent/observational-memory/observer.d.ts +37 -0
  39. package/dist/agent/observational-memory/observer.d.ts.map +1 -0
  40. package/dist/agent/observational-memory/observer.js +82 -0
  41. package/dist/agent/observational-memory/observer.js.map +1 -0
  42. package/dist/agent/observational-memory/plugin.d.ts +16 -0
  43. package/dist/agent/observational-memory/plugin.d.ts.map +1 -0
  44. package/dist/agent/observational-memory/plugin.js +26 -0
  45. package/dist/agent/observational-memory/plugin.js.map +1 -0
  46. package/dist/agent/observational-memory/prompts.d.ts +27 -0
  47. package/dist/agent/observational-memory/prompts.d.ts.map +1 -0
  48. package/dist/agent/observational-memory/prompts.js +42 -0
  49. package/dist/agent/observational-memory/prompts.js.map +1 -0
  50. package/dist/agent/observational-memory/read.d.ts +45 -0
  51. package/dist/agent/observational-memory/read.d.ts.map +1 -0
  52. package/dist/agent/observational-memory/read.js +97 -0
  53. package/dist/agent/observational-memory/read.js.map +1 -0
  54. package/dist/agent/observational-memory/reflector.d.ts +31 -0
  55. package/dist/agent/observational-memory/reflector.d.ts.map +1 -0
  56. package/dist/agent/observational-memory/reflector.js +76 -0
  57. package/dist/agent/observational-memory/reflector.js.map +1 -0
  58. package/dist/agent/observational-memory/schema.d.ts +267 -0
  59. package/dist/agent/observational-memory/schema.d.ts.map +1 -0
  60. package/dist/agent/observational-memory/schema.js +48 -0
  61. package/dist/agent/observational-memory/schema.js.map +1 -0
  62. package/dist/agent/observational-memory/store.d.ts +52 -0
  63. package/dist/agent/observational-memory/store.d.ts.map +1 -0
  64. package/dist/agent/observational-memory/store.js +197 -0
  65. package/dist/agent/observational-memory/store.js.map +1 -0
  66. package/dist/agent/observational-memory/types.d.ts +61 -0
  67. package/dist/agent/observational-memory/types.d.ts.map +1 -0
  68. package/dist/agent/observational-memory/types.js +9 -0
  69. package/dist/agent/observational-memory/types.js.map +1 -0
  70. package/dist/agent/processors.d.ts +146 -0
  71. package/dist/agent/processors.d.ts.map +1 -0
  72. package/dist/agent/processors.js +122 -0
  73. package/dist/agent/processors.js.map +1 -0
  74. package/dist/agent/production-agent.d.ts +25 -0
  75. package/dist/agent/production-agent.d.ts.map +1 -1
  76. package/dist/agent/production-agent.js +341 -1
  77. package/dist/agent/production-agent.js.map +1 -1
  78. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  79. package/dist/agent/run-loop-with-resume.js +48 -0
  80. package/dist/agent/run-loop-with-resume.js.map +1 -1
  81. package/dist/agent/run-store.d.ts +17 -0
  82. package/dist/agent/run-store.d.ts.map +1 -1
  83. package/dist/agent/run-store.js +55 -0
  84. package/dist/agent/run-store.js.map +1 -1
  85. package/dist/agent/runtime-context.d.ts +30 -0
  86. package/dist/agent/runtime-context.d.ts.map +1 -1
  87. package/dist/agent/runtime-context.js +54 -1
  88. package/dist/agent/runtime-context.js.map +1 -1
  89. package/dist/agent/tool-call-journal.d.ts +99 -0
  90. package/dist/agent/tool-call-journal.d.ts.map +1 -0
  91. package/dist/agent/tool-call-journal.js +212 -0
  92. package/dist/agent/tool-call-journal.js.map +1 -0
  93. package/dist/agent/types.d.ts +35 -0
  94. package/dist/agent/types.d.ts.map +1 -1
  95. package/dist/agent/types.js.map +1 -1
  96. package/dist/cli/add.d.ts +109 -0
  97. package/dist/cli/add.d.ts.map +1 -0
  98. package/dist/cli/add.js +352 -0
  99. package/dist/cli/add.js.map +1 -0
  100. package/dist/cli/connect.d.ts +2 -2
  101. package/dist/cli/connect.d.ts.map +1 -1
  102. package/dist/cli/connect.js +92 -24
  103. package/dist/cli/connect.js.map +1 -1
  104. package/dist/cli/eval.d.ts +17 -0
  105. package/dist/cli/eval.d.ts.map +1 -0
  106. package/dist/cli/eval.js +121 -0
  107. package/dist/cli/eval.js.map +1 -0
  108. package/dist/cli/index.js +44 -3
  109. package/dist/cli/index.js.map +1 -1
  110. package/dist/cli/mcp.d.ts.map +1 -1
  111. package/dist/cli/mcp.js +11 -5
  112. package/dist/cli/mcp.js.map +1 -1
  113. package/dist/cli/plan-local.d.ts +66 -5
  114. package/dist/cli/plan-local.d.ts.map +1 -1
  115. package/dist/cli/plan-local.js +622 -21
  116. package/dist/cli/plan-local.js.map +1 -1
  117. package/dist/cli/skills.d.ts +2 -2
  118. package/dist/cli/skills.d.ts.map +1 -1
  119. package/dist/cli/skills.js +108 -62
  120. package/dist/cli/skills.js.map +1 -1
  121. package/dist/client/AssistantChat.d.ts.map +1 -1
  122. package/dist/client/AssistantChat.js +118 -92
  123. package/dist/client/AssistantChat.js.map +1 -1
  124. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  125. package/dist/client/agent-chat-adapter.js +16 -0
  126. package/dist/client/agent-chat-adapter.js.map +1 -1
  127. package/dist/client/chat/tool-call-display.d.ts +20 -1
  128. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  129. package/dist/client/chat/tool-call-display.js +32 -7
  130. package/dist/client/chat/tool-call-display.js.map +1 -1
  131. package/dist/client/sse-event-processor.d.ts +13 -0
  132. package/dist/client/sse-event-processor.d.ts.map +1 -1
  133. package/dist/client/sse-event-processor.js +21 -0
  134. package/dist/client/sse-event-processor.js.map +1 -1
  135. package/dist/coding-tools/run-code.d.ts.map +1 -1
  136. package/dist/coding-tools/run-code.js +18 -2
  137. package/dist/coding-tools/run-code.js.map +1 -1
  138. package/dist/db/client.d.ts +4 -2
  139. package/dist/db/client.d.ts.map +1 -1
  140. package/dist/db/client.js +6 -4
  141. package/dist/db/client.js.map +1 -1
  142. package/dist/deploy/route-discovery.d.ts.map +1 -1
  143. package/dist/deploy/route-discovery.js +1 -0
  144. package/dist/deploy/route-discovery.js.map +1 -1
  145. package/dist/eval/agent-runner.d.ts +63 -0
  146. package/dist/eval/agent-runner.d.ts.map +1 -0
  147. package/dist/eval/agent-runner.js +142 -0
  148. package/dist/eval/agent-runner.js.map +1 -0
  149. package/dist/eval/define-eval.d.ts +29 -0
  150. package/dist/eval/define-eval.d.ts.map +1 -0
  151. package/dist/eval/define-eval.js +43 -0
  152. package/dist/eval/define-eval.js.map +1 -0
  153. package/dist/eval/index.d.ts +18 -0
  154. package/dist/eval/index.d.ts.map +1 -0
  155. package/dist/eval/index.js +17 -0
  156. package/dist/eval/index.js.map +1 -0
  157. package/dist/eval/report.d.ts +8 -0
  158. package/dist/eval/report.d.ts.map +1 -0
  159. package/dist/eval/report.js +44 -0
  160. package/dist/eval/report.js.map +1 -0
  161. package/dist/eval/runner.d.ts +67 -0
  162. package/dist/eval/runner.d.ts.map +1 -0
  163. package/dist/eval/runner.js +256 -0
  164. package/dist/eval/runner.js.map +1 -0
  165. package/dist/eval/scorer.d.ts +83 -0
  166. package/dist/eval/scorer.d.ts.map +1 -0
  167. package/dist/eval/scorer.js +195 -0
  168. package/dist/eval/scorer.js.map +1 -0
  169. package/dist/eval/types.d.ts +162 -0
  170. package/dist/eval/types.d.ts.map +1 -0
  171. package/dist/eval/types.js +20 -0
  172. package/dist/eval/types.js.map +1 -0
  173. package/dist/extensions/fetch-tool.d.ts.map +1 -1
  174. package/dist/extensions/fetch-tool.js +80 -15
  175. package/dist/extensions/fetch-tool.js.map +1 -1
  176. package/dist/extensions/web-content.d.ts +61 -0
  177. package/dist/extensions/web-content.d.ts.map +1 -0
  178. package/dist/extensions/web-content.js +468 -0
  179. package/dist/extensions/web-content.js.map +1 -0
  180. package/dist/extensions/web-search-tool.js +3 -3
  181. package/dist/extensions/web-search-tool.js.map +1 -1
  182. package/dist/mcp/build-server.d.ts.map +1 -1
  183. package/dist/mcp/build-server.js +4 -1
  184. package/dist/mcp/build-server.js.map +1 -1
  185. package/dist/observability/traces.d.ts.map +1 -1
  186. package/dist/observability/traces.js +100 -1
  187. package/dist/observability/traces.js.map +1 -1
  188. package/dist/observability/tracing.d.ts +73 -0
  189. package/dist/observability/tracing.d.ts.map +1 -0
  190. package/dist/observability/tracing.js +126 -0
  191. package/dist/observability/tracing.js.map +1 -0
  192. package/dist/onboarding/default-steps.d.ts.map +1 -1
  193. package/dist/onboarding/default-steps.js +4 -1
  194. package/dist/onboarding/default-steps.js.map +1 -1
  195. package/dist/provider-api/actions/query-staged-dataset.d.ts +1 -1
  196. package/dist/provider-api/corpus-jobs.d.ts +80 -0
  197. package/dist/provider-api/corpus-jobs.d.ts.map +1 -1
  198. package/dist/provider-api/corpus-jobs.js +219 -22
  199. package/dist/provider-api/corpus-jobs.js.map +1 -1
  200. package/dist/provider-api/index.d.ts +24 -32
  201. package/dist/provider-api/index.d.ts.map +1 -1
  202. package/dist/provider-api/index.js +28 -1
  203. package/dist/provider-api/index.js.map +1 -1
  204. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  205. package/dist/scripts/agent-engines/list-agent-engines.js +10 -3
  206. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  207. package/dist/server/action-discovery.d.ts.map +1 -1
  208. package/dist/server/action-discovery.js +4 -0
  209. package/dist/server/action-discovery.js.map +1 -1
  210. package/dist/server/agent-chat-plugin.d.ts +9 -0
  211. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  212. package/dist/server/agent-chat-plugin.js +119 -111
  213. package/dist/server/agent-chat-plugin.js.map +1 -1
  214. package/dist/server/agent-teams.d.ts +62 -0
  215. package/dist/server/agent-teams.d.ts.map +1 -1
  216. package/dist/server/agent-teams.js +99 -2
  217. package/dist/server/agent-teams.js.map +1 -1
  218. package/dist/server/better-auth-instance.d.ts +7 -0
  219. package/dist/server/better-auth-instance.d.ts.map +1 -1
  220. package/dist/server/better-auth-instance.js +90 -0
  221. package/dist/server/better-auth-instance.js.map +1 -1
  222. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  223. package/dist/server/core-routes-plugin.js +7 -4
  224. package/dist/server/core-routes-plugin.js.map +1 -1
  225. package/dist/server/credential-provider.d.ts.map +1 -1
  226. package/dist/server/credential-provider.js +2 -0
  227. package/dist/server/credential-provider.js.map +1 -1
  228. package/dist/server/deep-link.d.ts +7 -0
  229. package/dist/server/deep-link.d.ts.map +1 -1
  230. package/dist/server/deep-link.js +13 -2
  231. package/dist/server/deep-link.js.map +1 -1
  232. package/dist/server/framework-request-handler.d.ts.map +1 -1
  233. package/dist/server/framework-request-handler.js +33 -1
  234. package/dist/server/framework-request-handler.js.map +1 -1
  235. package/dist/server/index.d.ts +2 -1
  236. package/dist/server/index.d.ts.map +1 -1
  237. package/dist/server/index.js +2 -1
  238. package/dist/server/index.js.map +1 -1
  239. package/dist/templates/default/.agents/skills/actions/SKILL.md +52 -1
  240. package/dist/templates/default/.agents/skills/security/SKILL.md +22 -0
  241. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +52 -1
  242. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -4
  243. package/dist/templates/workspace-core/.agents/skills/harness-agents/SKILL.md +20 -0
  244. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +31 -0
  245. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +22 -0
  246. package/docs/content/actions.md +50 -0
  247. package/docs/content/agent-teams.md +32 -0
  248. package/docs/content/blueprint-installer.md +73 -0
  249. package/docs/content/durable-resume.md +49 -0
  250. package/docs/content/evals.md +141 -0
  251. package/docs/content/external-agents.md +2 -2
  252. package/docs/content/human-approval.md +101 -0
  253. package/docs/content/observability.md +21 -0
  254. package/docs/content/observational-memory.md +63 -0
  255. package/docs/content/plan-plugin.md +5 -0
  256. package/docs/content/pr-visual-recap.md +9 -5
  257. package/docs/content/processors.md +99 -0
  258. package/docs/content/sandbox-adapters.md +134 -0
  259. package/docs/content/template-plan.md +97 -21
  260. package/package.json +10 -1
  261. package/src/templates/default/.agents/skills/actions/SKILL.md +52 -1
  262. package/src/templates/default/.agents/skills/security/SKILL.md +22 -0
  263. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +52 -1
  264. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +16 -4
  265. package/src/templates/workspace-core/.agents/skills/harness-agents/SKILL.md +20 -0
  266. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +31 -0
  267. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +22 -0
@@ -1 +1 @@
1
- {"version":3,"file":"sse-event-processor.js","sourceRoot":"","sources":["../../src/client/sse-event-processor.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ChatModelRunResult } from \"@assistant-ui/react\";\nimport {\n LLM_MISSING_CREDENTIALS_ERROR_CODE,\n LLM_MISSING_CREDENTIALS_MESSAGE,\n} from \"../agent/engine/credential-errors.js\";\nimport type { AgentMcpAppPayload } from \"../mcp-client/app-result.js\";\nimport { formatChatErrorText, normalizeChatError } from \"./error-format.js\";\nimport { humanizeToolLabelText, runningToolLabel } from \"./tool-display.js\";\n\nexport type ContentPart =\n | { type: \"text\"; text: string }\n | {\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n argsText: string;\n args: Record<string, string>;\n result?: string;\n mcpApp?: AgentMcpAppPayload;\n activity?: boolean;\n /**\n * Structured metadata from the coding-tools executor side-channel.\n * Present only on code-agent tool calls from executors new enough to\n * emit it. The `toolKind` discriminant identifies the shape.\n */\n structuredMeta?: Record<string, unknown>;\n };\n\nexport interface SSEEvent {\n type: string;\n text?: string;\n tool?: string;\n /** Server-assigned call identifier emitted on tool_start / tool_done events. */\n id?: string;\n label?: string;\n input?: Record<string, string>;\n result?: string;\n mcpApp?: AgentMcpAppPayload;\n error?: string;\n seq?: number;\n agent?: string;\n status?: string;\n reason?: string;\n // Agent task fields\n taskId?: string;\n threadId?: string;\n description?: string;\n preview?: string;\n currentStep?: string;\n summary?: string;\n // Structured error metadata — Builder gateway sets these on quota/auth/setup\n // failures so the UI can render a CTA alongside the error text.\n errorCode?: string;\n upgradeUrl?: string;\n details?: string;\n recoverable?: boolean;\n maxIterations?: number;\n}\n\nexport type AgentAutoContinueReason =\n | \"run_timeout\"\n | \"loop_limit\"\n | \"no_progress\"\n | \"stream_ended\"\n | \"stale_run\";\n\nexport type AgentActivityTrailEntry = { label: string; tool?: string };\n\nconst INTERRUPTED_TOOL_RESULT =\n \"Interrupted before this tool returned a result.\";\n\nexport function settleInterruptedToolCalls(\n content: ContentPart[],\n result = INTERRUPTED_TOOL_RESULT,\n): boolean {\n let changed = false;\n for (const part of content) {\n if (\n part.type === \"tool-call\" &&\n part.result === undefined &&\n part.activity !== true\n ) {\n part.result = result;\n changed = true;\n }\n }\n return changed;\n}\n\nexport class AgentAutoContinueSignal extends Error {\n readonly reason: AgentAutoContinueReason;\n readonly maxIterations?: number;\n readonly activityTrail: AgentActivityTrailEntry[];\n\n constructor(options: {\n reason: AgentAutoContinueReason;\n maxIterations?: number;\n activityTrail?: AgentActivityTrailEntry[];\n }) {\n super(`Agent run needs automatic continuation: ${options.reason}`);\n this.name = \"AgentAutoContinueSignal\";\n this.reason = options.reason;\n this.maxIterations = options.maxIterations;\n this.activityTrail = options.activityTrail ?? [];\n }\n}\n\nexport const SSE_NO_PROGRESS_TIMEOUT_MS = 75_000;\n\ntype ActivityTrailEntry = AgentActivityTrailEntry;\n\nfunction findPendingToolCallIndex(\n content: ContentPart[],\n toolName: string,\n toolCallId?: string,\n): number {\n // Prefer id-based match when the event carries an id: parallel same-name\n // calls can be in flight simultaneously, and name-only matching would\n // attach a result to the wrong call.\n if (toolCallId) {\n for (let i = content.length - 1; i >= 0; i--) {\n const part = content[i];\n if (\n part.type === \"tool-call\" &&\n part.toolCallId === toolCallId &&\n part.result === undefined\n ) {\n return i;\n }\n }\n // Fall through to name-matching: the start event may have arrived before\n // the server started emitting ids (e.g. older server build), so the\n // stored toolCallId is the locally-generated \"tc_N\" value rather than the\n // server-assigned one. In that case match by name as a fallback.\n }\n for (let i = content.length - 1; i >= 0; i--) {\n const part = content[i];\n if (\n part.type === \"tool-call\" &&\n part.toolName === toolName &&\n part.result === undefined\n ) {\n return i;\n }\n }\n return -1;\n}\n\nfunction appendActivityTrail(\n trail: ActivityTrailEntry[],\n next: ActivityTrailEntry,\n) {\n const label = next.label.trim();\n if (!label) return;\n const tool = next.tool?.trim();\n const last = trail[trail.length - 1];\n if (last?.label === label && last.tool === tool) return;\n trail.push({ label, ...(tool ? { tool } : {}) });\n if (trail.length > 8) {\n trail.splice(0, trail.length - 8);\n }\n}\n\nasync function readChunkWithProgressTimeout(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n lastMeaningfulEventAt: number,\n): Promise<ReadableStreamReadResult<Uint8Array>> {\n const elapsed = Date.now() - lastMeaningfulEventAt;\n const timeoutMs = Math.max(0, SSE_NO_PROGRESS_TIMEOUT_MS - elapsed);\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n const readPromise = reader.read();\n // If the timeout wins and cancellation causes the pending read to reject,\n // swallow that rejection because the generator is already recovering.\n void readPromise.catch(() => {});\n\n const timeoutPromise = new Promise<\"timeout\">((resolve) => {\n timeoutId = setTimeout(() => resolve(\"timeout\"), timeoutMs);\n });\n const result = await Promise.race([readPromise, timeoutPromise]);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n if (result === \"timeout\") {\n await reader.cancel(\"no_progress\").catch(() => {});\n throw new AgentAutoContinueSignal({ reason: \"no_progress\" });\n }\n return result;\n}\n\nfunction isAutoRecoverableError(ev: SSEEvent, errMsg: string): boolean {\n const code = String(ev.errorCode ?? \"\").toLowerCase();\n const msg = errMsg.toLowerCase();\n\n if (\n code === \"context_length_exceeded\" ||\n code === \"input_too_long\" ||\n code.startsWith(\"credits-limit\") ||\n code === \"billing_error\" ||\n code === \"unauthorized\" ||\n code === \"authentication_error\" ||\n code === \"permission_error\" ||\n code === \"http_401\" ||\n code === \"http_403\" ||\n code === \"rate_limit_exceeded\" ||\n code === \"gateway_not_enabled\" ||\n code === \"missing_api_key\" ||\n code === \"missing_credentials\" ||\n code === \"invalid_request_error\" ||\n code === \"request_too_large\" ||\n code === \"not_found_error\" ||\n code === \"model_not_found\" ||\n // `builder_gateway_error` is the no-detail fallback the Builder engine\n // emits when the gateway returns `{type:\"stop\",reason:\"error\"}` with no\n // explanation — almost always the upstream provider giving up (model\n // quota hit, account misconfiguration, opaque downstream failure). The\n // production-agent already retries this synchronously up to MAX_RETRIES\n // before the error escapes to the SSE stream, so by the time the client\n // sees it, retrying again with another POST /agent-chat will hit the\n // same wall. This used to send the chat into a 32-continuation runaway\n // (each turn cleared+regenerated visible content) for users hitting a\n // misbehaving Builder route. Surface the error instead.\n code === \"builder_gateway_error\"\n ) {\n return false;\n }\n\n if (\n code === \"builder_gateway_network_error\" ||\n code === \"builder_gateway_timeout\" ||\n code === \"stale_run\" ||\n code === \"timeout\" ||\n code === \"timeout_error\" ||\n code === \"http_408\" ||\n code === \"http_429\" ||\n code === \"http_500\" ||\n code === \"http_502\" ||\n code === \"http_503\" ||\n code === \"http_504\" ||\n code === \"rate_limited\" ||\n code === \"too_many_concurrent_requests\" ||\n code === \"overloaded_error\"\n ) {\n return true;\n }\n\n if (ev.recoverable === true) return true;\n\n if (msg.includes(\"daily gateway request cap\")) return false;\n\n // \"gateway error\" intentionally absent — that's the no-detail Builder\n // gateway fallback and the production-agent already retries it\n // synchronously up to MAX_RETRIES before the error escapes here. Treating\n // it as auto-recoverable on top of that produced a 32-continuation\n // runaway in production for users hitting a misbehaving Builder route.\n // (See `code === \"builder_gateway_error\"` in the not-recoverable list.)\n return (\n msg.includes(\"overloaded\") ||\n msg.includes(\"rate_limit\") ||\n msg.includes(\"too many requests\") ||\n msg.includes(\"timeout\") ||\n msg.includes(\"gateway timeout\") ||\n msg.includes(\"inactivity timeout\") ||\n msg.includes(\"socket hang up\") ||\n msg.includes(\"connection reset\") ||\n msg.includes(\"connection\") ||\n msg.includes(\"network\") ||\n msg.includes(\"stream closed\") ||\n msg.includes(\"stream ended\") ||\n msg.includes(\"temporarily unavailable\") ||\n msg.includes(\"502\") ||\n msg.includes(\"503\") ||\n msg.includes(\"504\") ||\n msg.includes(\"529\")\n );\n}\n\nfunction isMissingCredentialText(message: string, errorCode?: string): boolean {\n const code = String(errorCode ?? \"\").toLowerCase();\n const msg = message.toLowerCase();\n return (\n code === \"missing_api_key\" ||\n code === \"missing_credentials\" ||\n msg.includes(\"apikey\") ||\n msg.includes(\"authtoken\") ||\n msg.includes(\"anthropic_api_key\") ||\n msg.includes(\"missing_api_key\") ||\n msg.includes(\"missing api key\") ||\n msg.includes(\"missing credentials\") ||\n msg.includes(\"no llm provider\") ||\n msg.includes(\"llm provider is connected\")\n );\n}\n\nfunction dispatchActivityClear(tabId: string | undefined) {\n if (typeof window === \"undefined\") return;\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:activity-clear\", {\n detail: { tabId },\n }),\n );\n}\n\n/**\n * Process a single SSE event and update the content accumulator.\n * Returns: \"continue\" to keep going, \"done\" to stop, or a yield-ready result.\n */\nexport function processEvent(\n ev: SSEEvent,\n content: ContentPart[],\n toolCallCounter: { value: number },\n tabId: string | undefined,\n): {\n action:\n | \"continue\"\n | \"done\"\n | \"yield\"\n | \"error\"\n | \"missing_api_key\"\n | \"auto_continue\";\n result?: ChatModelRunResult;\n autoContinue?: {\n reason: AgentAutoContinueReason;\n maxIterations?: number;\n };\n} {\n if (ev.type === \"clear\") {\n // Server is retrying — discard partial text/tool output from the failed attempt\n content.length = 0;\n dispatchActivityClear(tabId);\n return { action: \"continue\" };\n }\n\n if (ev.type === \"text\") {\n const lastPart = content[content.length - 1];\n if (lastPart && lastPart.type === \"text\") {\n lastPart.text += ev.text ?? \"\";\n } else {\n content.push({ type: \"text\", text: ev.text ?? \"\" });\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"activity\") {\n const tool = ev.tool?.trim() || undefined;\n const label = humanizeToolLabelText(ev.label ?? \"Working\", tool);\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:activity\", {\n detail: {\n label,\n ...(tool ? { tool } : {}),\n tabId,\n },\n }),\n );\n }\n if (!tool) return { action: \"continue\" };\n\n const pendingToolCallIndex = findPendingToolCallIndex(content, tool);\n if (pendingToolCallIndex === -1) {\n content.push({\n type: \"tool-call\",\n toolCallId: `tc_${++toolCallCounter.value}`,\n toolName: tool,\n argsText: \"\",\n args: {},\n activity: true,\n });\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"tool_start\") {\n const args = (ev.input ?? {}) as Record<string, string>;\n const tool = ev.tool ?? \"unknown\";\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(\n new CustomEvent(\"agent-native:tool-start\", {\n detail: { tool, input: args },\n }),\n );\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:activity\", {\n detail: {\n label: runningToolLabel(tool),\n tool,\n tabId,\n },\n }),\n );\n }\n // Pass the server-assigned id so we upgrade the pending activity card\n // using id-match when available (parallel same-name calls stay separate).\n const pendingToolCallIndex = findPendingToolCallIndex(content, tool, ev.id);\n const pendingToolCall =\n pendingToolCallIndex >= 0 ? content[pendingToolCallIndex] : undefined;\n if (\n pendingToolCall &&\n pendingToolCall.type === \"tool-call\" &&\n pendingToolCall.activity === true &&\n pendingToolCall.argsText === \"\" &&\n Object.keys(pendingToolCall.args).length === 0\n ) {\n // Upgrade the pending activity card in place. Prefer the server-assigned\n // id so the subsequent tool_done can match it precisely (parallel\n // same-name calls each carry their own id). Fall back to the\n // locally-generated id already on the card.\n content[pendingToolCallIndex] = {\n type: \"tool-call\",\n toolCallId: ev.id ?? pendingToolCall.toolCallId,\n toolName: tool,\n argsText: JSON.stringify(args),\n args,\n };\n } else {\n content.push({\n type: \"tool-call\",\n toolCallId: ev.id ?? `tc_${++toolCallCounter.value}`,\n toolName: tool,\n argsText: JSON.stringify(args),\n args,\n });\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"tool_done\") {\n // Normalize identically to tool_start (which stores `ev.tool ?? \"unknown\"`)\n // so a tool_done frame with an undefined tool name still matches its\n // pending tool-call entry instead of leaving it forever unresolved.\n const doneTool = ev.tool ?? \"unknown\";\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(\n new CustomEvent(\"agent-native:tool-done\", {\n detail: { tool: doneTool, result: ev.result },\n }),\n );\n }\n // Use id-based lookup when available so parallel same-name tool calls\n // get their results correctly assigned; fall back to name-matching.\n const doneIdx = findPendingToolCallIndex(content, doneTool, ev.id);\n if (doneIdx >= 0) {\n const part = content[doneIdx];\n if (part.type === \"tool-call\") {\n part.result = ev.result ?? \"\";\n if (ev.mcpApp) part.mcpApp = ev.mcpApp;\n }\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"agent_call\") {\n const agentName = ev.agent ?? \"agent\";\n if (ev.status === \"start\") {\n const toolCallId = `tc_${++toolCallCounter.value}`;\n content.push({\n type: \"tool-call\",\n toolCallId,\n toolName: `agent:${agentName}`,\n argsText: \"\",\n args: {},\n });\n } else if (ev.status === \"done\" || ev.status === \"error\") {\n for (let i = content.length - 1; i >= 0; i--) {\n const part = content[i];\n if (\n part.type === \"tool-call\" &&\n part.toolName === `agent:${agentName}` &&\n part.result === undefined\n ) {\n part.result = ev.status === \"error\" ? \"Error calling agent\" : \"Done\";\n break;\n }\n }\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"agent_call_text\") {\n const agentName = ev.agent ?? \"agent\";\n // Find the in-progress agent tool-call and append streaming text to argsText\n for (let i = content.length - 1; i >= 0; i--) {\n const part = content[i];\n if (\n part.type === \"tool-call\" &&\n part.toolName === `agent:${agentName}` &&\n part.result === undefined\n ) {\n part.argsText += ev.text ?? \"\";\n break;\n }\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n // ─── Agent task events (sub-agent chips) ─────────────────────────\n // These events are dispatched as CustomEvents so AgentTaskCard components\n // can listen for updates to their specific taskId.\n if (\n ev.type === \"agent_task\" ||\n ev.type === \"agent_task_update\" ||\n ev.type === \"agent_task_complete\"\n ) {\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new CustomEvent(\"agent-task-event\", { detail: ev }));\n }\n // Don't add to content — the agent-teams tool call handles rendering\n return { action: \"continue\" };\n }\n\n if (ev.type === \"missing_api_key\") {\n const errMsg = LLM_MISSING_CREDENTIALS_MESSAGE;\n const errorCode = LLM_MISSING_CREDENTIALS_ERROR_CODE;\n const runError = {\n message: normalizeChatError(errMsg).message,\n errorCode,\n };\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new Event(\"agent-chat:missing-api-key\"));\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:run-error\", {\n detail: { ...runError, tabId },\n }),\n );\n }\n settleInterruptedToolCalls(content);\n content.push({\n type: \"text\",\n text: formatChatErrorText(errMsg, undefined, errorCode),\n });\n return {\n action: \"missing_api_key\",\n result: {\n content: [...content],\n status: { type: \"incomplete\" as const, reason: \"error\" as const },\n metadata: { custom: { runError } },\n } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"loop_limit\") {\n const maxIterations =\n typeof ev.maxIterations === \"number\" ? ev.maxIterations : undefined;\n return {\n action: \"auto_continue\",\n autoContinue: {\n reason: \"loop_limit\",\n ...(maxIterations ? { maxIterations } : {}),\n },\n };\n }\n\n if (ev.type === \"auto_continue\") {\n const reason =\n ev.reason === \"stream_ended\" ||\n ev.reason === \"loop_limit\" ||\n ev.reason === \"no_progress\" ||\n ev.reason === \"run_timeout\"\n ? ev.reason\n : ev.errorCode === \"stream_ended\" ||\n ev.errorCode === \"loop_limit\" ||\n ev.errorCode === \"no_progress\" ||\n ev.errorCode === \"run_timeout\"\n ? ev.errorCode\n : ev.error === \"stream_ended\" ||\n ev.error === \"loop_limit\" ||\n ev.error === \"no_progress\" ||\n ev.error === \"run_timeout\"\n ? ev.error\n : ev.status === \"stream_ended\" ||\n ev.status === \"loop_limit\" ||\n ev.status === \"no_progress\" ||\n ev.status === \"run_timeout\"\n ? ev.status\n : \"run_timeout\";\n return {\n action: \"auto_continue\",\n autoContinue: {\n reason,\n ...(typeof ev.maxIterations === \"number\"\n ? { maxIterations: ev.maxIterations }\n : {}),\n },\n };\n }\n\n if (ev.type === \"error\") {\n const errMsg = ev.error ?? \"Unknown error\";\n if (\n (ev.errorCode === \"run_timeout\" && ev.recoverable) ||\n isAutoRecoverableError(ev, errMsg)\n ) {\n return {\n action: \"auto_continue\",\n autoContinue: {\n reason:\n ev.errorCode === \"stale_run\"\n ? \"stale_run\"\n : ev.errorCode === \"builder_gateway_timeout\" ||\n ev.errorCode === \"run_timeout\" ||\n errMsg.toLowerCase().includes(\"timeout\")\n ? \"run_timeout\"\n : \"stream_ended\",\n },\n };\n }\n const normalized = normalizeChatError(errMsg);\n if (isMissingCredentialText(errMsg, ev.errorCode)) {\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new Event(\"agent-chat:missing-api-key\"));\n }\n }\n const runError = {\n message: normalized.message,\n ...(normalized.details || ev.details\n ? { details: ev.details ?? normalized.details }\n : {}),\n ...(ev.errorCode ? { errorCode: ev.errorCode } : {}),\n ...(ev.recoverable ? { recoverable: ev.recoverable } : {}),\n };\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:run-error\", {\n detail: { ...runError, tabId },\n }),\n );\n }\n settleInterruptedToolCalls(content);\n content.push({\n type: \"text\",\n text: formatChatErrorText(errMsg, ev.upgradeUrl, ev.errorCode),\n });\n return {\n action: \"error\",\n result: {\n content: [...content],\n status: { type: \"incomplete\" as const, reason: \"error\" as const },\n metadata: { custom: { runError } },\n } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"done\") {\n return {\n action: \"done\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n return { action: \"continue\" };\n}\n\n/**\n * Read and process SSE events from a ReadableStream response body.\n * Yields ChatModelRunResult for each meaningful event.\n *\n * When `runId` is provided, every yielded result carries\n * `metadata.custom.runId` so the UI can expose the trace ID via\n * \"Copy Request ID\" — including mid-stream, so users can grab it before\n * the run completes (or if the run hangs / ends prematurely).\n */\nexport async function* readSSEStream(\n body: ReadableStream<Uint8Array>,\n content: ContentPart[],\n toolCallCounter: { value: number },\n tabId: string | undefined,\n onSeq?: (seq: number) => void,\n runId?: string | null,\n): AsyncGenerator<ChatModelRunResult> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buf = \"\";\n let lastMeaningfulEventAt = Date.now();\n const activityTrail: ActivityTrailEntry[] = [];\n\n const withStreamMetadata = (r: ChatModelRunResult): ChatModelRunResult => {\n if (!runId && activityTrail.length === 0) return r;\n const metadata = (r.metadata ?? {}) as Record<string, unknown>;\n const custom =\n metadata.custom && typeof metadata.custom === \"object\"\n ? (metadata.custom as Record<string, unknown>)\n : {};\n const runError =\n runId && custom.runError && typeof custom.runError === \"object\"\n ? {\n ...(custom.runError as Record<string, unknown>),\n runId,\n }\n : custom.runError;\n return {\n ...r,\n metadata: {\n ...metadata,\n custom: {\n ...custom,\n ...(runId ? { runId } : {}),\n ...(runError ? { runError } : {}),\n ...(activityTrail.length > 0\n ? { activityTrail: [...activityTrail] }\n : {}),\n },\n },\n };\n };\n\n try {\n while (true) {\n const { done, value } = await readChunkWithProgressTimeout(\n reader,\n lastMeaningfulEventAt,\n );\n if (done) break;\n\n buf += decoder.decode(value, { stream: true });\n const lines = buf.split(\"\\n\");\n buf = lines.pop() ?? \"\";\n let sawDataEvent = false;\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const raw = line.slice(6).trim();\n if (!raw) continue;\n\n let ev: SSEEvent;\n try {\n ev = JSON.parse(raw);\n } catch {\n continue;\n }\n sawDataEvent = true;\n lastMeaningfulEventAt = Date.now();\n\n // Track sequence number for reconnection\n if (ev.seq !== undefined && onSeq) {\n onSeq(ev.seq);\n }\n\n if (ev.type === \"clear\") {\n activityTrail.length = 0;\n } else if (ev.type === \"activity\") {\n const tool = ev.tool?.trim() || undefined;\n appendActivityTrail(activityTrail, {\n label: humanizeToolLabelText(ev.label ?? \"Working\", tool),\n ...(tool ? { tool } : {}),\n });\n } else if (ev.type === \"tool_start\") {\n const tool = ev.tool ?? \"unknown\";\n appendActivityTrail(activityTrail, {\n label: runningToolLabel(tool),\n tool,\n });\n }\n\n const { action, result, autoContinue } = processEvent(\n ev,\n content,\n toolCallCounter,\n tabId,\n );\n\n if (result) yield withStreamMetadata(result);\n if (action === \"auto_continue\") {\n throw new AgentAutoContinueSignal(\n autoContinue\n ? { ...autoContinue, activityTrail: [...activityTrail] }\n : { reason: \"stream_ended\", activityTrail: [...activityTrail] },\n );\n }\n if (\n action === \"done\" ||\n action === \"error\" ||\n action === \"missing_api_key\"\n ) {\n return;\n }\n }\n\n if (\n !sawDataEvent &&\n Date.now() - lastMeaningfulEventAt >= SSE_NO_PROGRESS_TIMEOUT_MS\n ) {\n throw new AgentAutoContinueSignal({ reason: \"no_progress\" });\n }\n }\n } finally {\n try {\n reader.releaseLock();\n } catch {\n // The timeout path cancels the stream before unwinding; some runtimes\n // still consider the pending read active for a tick.\n }\n }\n\n // Stream ended without explicit done event. Even an empty content array is\n // abnormal here: a healthy run emits a terminal `done` event. Treat this as\n // recoverable so the adapter can first reconnect to the run, then continue\n // from durable history if the producer is gone.\n throw new AgentAutoContinueSignal({\n reason: \"stream_ended\",\n activityTrail: [...activityTrail],\n });\n}\n\n/**\n * Read raw SSE events from a ReadableStream and process them into ContentPart[].\n * Unlike readSSEStream, this doesn't yield ChatModelRunResult — it updates the\n * content array in-place and calls onUpdate for each meaningful change.\n * Designed for reconnection scenarios where we render outside assistant-ui's runtime.\n */\nexport async function readSSEStreamRaw(\n body: ReadableStream<Uint8Array>,\n content: ContentPart[],\n toolCallCounter: { value: number },\n tabId: string | undefined,\n onUpdate: (content: ContentPart[]) => void,\n): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buf = \"\";\n let lastMeaningfulEventAt = Date.now();\n // Tracks whether the most recent content state was already pushed via\n // onUpdate inside the loop, so the post-loop flush below doesn't emit the\n // identical content a second time when the stream closes without a terminal\n // event.\n let emittedLatestContent = false;\n\n try {\n while (true) {\n const { done, value } = await readChunkWithProgressTimeout(\n reader,\n lastMeaningfulEventAt,\n );\n if (done) break;\n\n buf += decoder.decode(value, { stream: true });\n const lines = buf.split(\"\\n\");\n buf = lines.pop() ?? \"\";\n\n let updated = false;\n let sawDataEvent = false;\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const raw = line.slice(6).trim();\n if (!raw) continue;\n\n let ev: SSEEvent;\n try {\n ev = JSON.parse(raw);\n } catch {\n continue;\n }\n sawDataEvent = true;\n lastMeaningfulEventAt = Date.now();\n\n const { action, autoContinue } = processEvent(\n ev,\n content,\n toolCallCounter,\n tabId,\n );\n\n if (\n action === \"yield\" ||\n action === \"done\" ||\n action === \"error\" ||\n action === \"missing_api_key\"\n ) {\n updated = true;\n }\n if (action === \"auto_continue\") {\n onUpdate([...content]);\n throw new AgentAutoContinueSignal(\n autoContinue ?? { reason: \"stream_ended\" },\n );\n }\n if (\n action === \"done\" ||\n action === \"error\" ||\n action === \"missing_api_key\"\n ) {\n onUpdate([...content]);\n return;\n }\n }\n\n if (updated) {\n onUpdate([...content]);\n emittedLatestContent = true;\n }\n if (\n !sawDataEvent &&\n Date.now() - lastMeaningfulEventAt >= SSE_NO_PROGRESS_TIMEOUT_MS\n ) {\n throw new AgentAutoContinueSignal({ reason: \"no_progress\" });\n }\n }\n } finally {\n try {\n reader.releaseLock();\n } catch {\n // See readSSEStream: cancellation may race lock release in browsers.\n }\n }\n if (content.length > 0 && !emittedLatestContent) onUpdate([...content]);\n throw new AgentAutoContinueSignal({ reason: \"stream_ended\" });\n}\n"]}
1
+ {"version":3,"file":"sse-event-processor.js","sourceRoot":"","sources":["../../src/client/sse-event-processor.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ChatModelRunResult } from \"@assistant-ui/react\";\nimport {\n LLM_MISSING_CREDENTIALS_ERROR_CODE,\n LLM_MISSING_CREDENTIALS_MESSAGE,\n} from \"../agent/engine/credential-errors.js\";\nimport type { AgentMcpAppPayload } from \"../mcp-client/app-result.js\";\nimport { formatChatErrorText, normalizeChatError } from \"./error-format.js\";\nimport { humanizeToolLabelText, runningToolLabel } from \"./tool-display.js\";\n\nexport type ContentPart =\n | { type: \"text\"; text: string }\n | {\n type: \"tool-call\";\n toolCallId: string;\n toolName: string;\n argsText: string;\n args: Record<string, string>;\n result?: string;\n mcpApp?: AgentMcpAppPayload;\n activity?: boolean;\n /**\n * Set when the server emitted an `approval_required` event for this tool\n * call (opt-in `needsApproval` actions). The action did NOT run; the UI\n * renders an Approve/Deny affordance. `approvalKey` is echoed back in\n * `approvedToolCalls` to approve, `dismissed` records a local Deny.\n */\n approval?: { approvalKey: string; dismissed?: boolean };\n /**\n * Structured metadata from the coding-tools executor side-channel.\n * Present only on code-agent tool calls from executors new enough to\n * emit it. The `toolKind` discriminant identifies the shape.\n */\n structuredMeta?: Record<string, unknown>;\n };\n\nexport interface SSEEvent {\n type: string;\n text?: string;\n tool?: string;\n /** Server-assigned call identifier emitted on tool_start / tool_done events. */\n id?: string;\n label?: string;\n input?: Record<string, string>;\n result?: string;\n mcpApp?: AgentMcpAppPayload;\n /** Stable key the client echoes back in `approvedToolCalls` to approve a\n * paused `needsApproval` tool call. Present on `approval_required` events. */\n approvalKey?: string;\n error?: string;\n seq?: number;\n agent?: string;\n status?: string;\n reason?: string;\n // Agent task fields\n taskId?: string;\n threadId?: string;\n description?: string;\n preview?: string;\n currentStep?: string;\n summary?: string;\n // Structured error metadata — Builder gateway sets these on quota/auth/setup\n // failures so the UI can render a CTA alongside the error text.\n errorCode?: string;\n upgradeUrl?: string;\n details?: string;\n recoverable?: boolean;\n maxIterations?: number;\n}\n\nexport type AgentAutoContinueReason =\n | \"run_timeout\"\n | \"loop_limit\"\n | \"no_progress\"\n | \"stream_ended\"\n | \"stale_run\";\n\nexport type AgentActivityTrailEntry = { label: string; tool?: string };\n\nconst INTERRUPTED_TOOL_RESULT =\n \"Interrupted before this tool returned a result.\";\n\nexport function settleInterruptedToolCalls(\n content: ContentPart[],\n result = INTERRUPTED_TOOL_RESULT,\n): boolean {\n let changed = false;\n for (const part of content) {\n if (\n part.type === \"tool-call\" &&\n part.result === undefined &&\n part.activity !== true\n ) {\n part.result = result;\n changed = true;\n }\n }\n return changed;\n}\n\nexport class AgentAutoContinueSignal extends Error {\n readonly reason: AgentAutoContinueReason;\n readonly maxIterations?: number;\n readonly activityTrail: AgentActivityTrailEntry[];\n\n constructor(options: {\n reason: AgentAutoContinueReason;\n maxIterations?: number;\n activityTrail?: AgentActivityTrailEntry[];\n }) {\n super(`Agent run needs automatic continuation: ${options.reason}`);\n this.name = \"AgentAutoContinueSignal\";\n this.reason = options.reason;\n this.maxIterations = options.maxIterations;\n this.activityTrail = options.activityTrail ?? [];\n }\n}\n\nexport const SSE_NO_PROGRESS_TIMEOUT_MS = 75_000;\n\ntype ActivityTrailEntry = AgentActivityTrailEntry;\n\nfunction findPendingToolCallIndex(\n content: ContentPart[],\n toolName: string,\n toolCallId?: string,\n): number {\n // Prefer id-based match when the event carries an id: parallel same-name\n // calls can be in flight simultaneously, and name-only matching would\n // attach a result to the wrong call.\n if (toolCallId) {\n for (let i = content.length - 1; i >= 0; i--) {\n const part = content[i];\n if (\n part.type === \"tool-call\" &&\n part.toolCallId === toolCallId &&\n part.result === undefined\n ) {\n return i;\n }\n }\n // Fall through to name-matching: the start event may have arrived before\n // the server started emitting ids (e.g. older server build), so the\n // stored toolCallId is the locally-generated \"tc_N\" value rather than the\n // server-assigned one. In that case match by name as a fallback.\n }\n for (let i = content.length - 1; i >= 0; i--) {\n const part = content[i];\n if (\n part.type === \"tool-call\" &&\n part.toolName === toolName &&\n part.result === undefined\n ) {\n return i;\n }\n }\n return -1;\n}\n\nfunction appendActivityTrail(\n trail: ActivityTrailEntry[],\n next: ActivityTrailEntry,\n) {\n const label = next.label.trim();\n if (!label) return;\n const tool = next.tool?.trim();\n const last = trail[trail.length - 1];\n if (last?.label === label && last.tool === tool) return;\n trail.push({ label, ...(tool ? { tool } : {}) });\n if (trail.length > 8) {\n trail.splice(0, trail.length - 8);\n }\n}\n\nasync function readChunkWithProgressTimeout(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n lastMeaningfulEventAt: number,\n): Promise<ReadableStreamReadResult<Uint8Array>> {\n const elapsed = Date.now() - lastMeaningfulEventAt;\n const timeoutMs = Math.max(0, SSE_NO_PROGRESS_TIMEOUT_MS - elapsed);\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n const readPromise = reader.read();\n // If the timeout wins and cancellation causes the pending read to reject,\n // swallow that rejection because the generator is already recovering.\n void readPromise.catch(() => {});\n\n const timeoutPromise = new Promise<\"timeout\">((resolve) => {\n timeoutId = setTimeout(() => resolve(\"timeout\"), timeoutMs);\n });\n const result = await Promise.race([readPromise, timeoutPromise]);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n if (result === \"timeout\") {\n await reader.cancel(\"no_progress\").catch(() => {});\n throw new AgentAutoContinueSignal({ reason: \"no_progress\" });\n }\n return result;\n}\n\nfunction isAutoRecoverableError(ev: SSEEvent, errMsg: string): boolean {\n const code = String(ev.errorCode ?? \"\").toLowerCase();\n const msg = errMsg.toLowerCase();\n\n if (\n code === \"context_length_exceeded\" ||\n code === \"input_too_long\" ||\n code.startsWith(\"credits-limit\") ||\n code === \"billing_error\" ||\n code === \"unauthorized\" ||\n code === \"authentication_error\" ||\n code === \"permission_error\" ||\n code === \"http_401\" ||\n code === \"http_403\" ||\n code === \"rate_limit_exceeded\" ||\n code === \"gateway_not_enabled\" ||\n code === \"missing_api_key\" ||\n code === \"missing_credentials\" ||\n code === \"invalid_request_error\" ||\n code === \"request_too_large\" ||\n code === \"not_found_error\" ||\n code === \"model_not_found\" ||\n // `builder_gateway_error` is the no-detail fallback the Builder engine\n // emits when the gateway returns `{type:\"stop\",reason:\"error\"}` with no\n // explanation — almost always the upstream provider giving up (model\n // quota hit, account misconfiguration, opaque downstream failure). The\n // production-agent already retries this synchronously up to MAX_RETRIES\n // before the error escapes to the SSE stream, so by the time the client\n // sees it, retrying again with another POST /agent-chat will hit the\n // same wall. This used to send the chat into a 32-continuation runaway\n // (each turn cleared+regenerated visible content) for users hitting a\n // misbehaving Builder route. Surface the error instead.\n code === \"builder_gateway_error\"\n ) {\n return false;\n }\n\n if (\n code === \"builder_gateway_network_error\" ||\n code === \"builder_gateway_timeout\" ||\n code === \"stale_run\" ||\n code === \"timeout\" ||\n code === \"timeout_error\" ||\n code === \"http_408\" ||\n code === \"http_429\" ||\n code === \"http_500\" ||\n code === \"http_502\" ||\n code === \"http_503\" ||\n code === \"http_504\" ||\n code === \"rate_limited\" ||\n code === \"too_many_concurrent_requests\" ||\n code === \"overloaded_error\"\n ) {\n return true;\n }\n\n if (ev.recoverable === true) return true;\n\n if (msg.includes(\"daily gateway request cap\")) return false;\n\n // \"gateway error\" intentionally absent — that's the no-detail Builder\n // gateway fallback and the production-agent already retries it\n // synchronously up to MAX_RETRIES before the error escapes here. Treating\n // it as auto-recoverable on top of that produced a 32-continuation\n // runaway in production for users hitting a misbehaving Builder route.\n // (See `code === \"builder_gateway_error\"` in the not-recoverable list.)\n return (\n msg.includes(\"overloaded\") ||\n msg.includes(\"rate_limit\") ||\n msg.includes(\"too many requests\") ||\n msg.includes(\"timeout\") ||\n msg.includes(\"gateway timeout\") ||\n msg.includes(\"inactivity timeout\") ||\n msg.includes(\"socket hang up\") ||\n msg.includes(\"connection reset\") ||\n msg.includes(\"connection\") ||\n msg.includes(\"network\") ||\n msg.includes(\"stream closed\") ||\n msg.includes(\"stream ended\") ||\n msg.includes(\"temporarily unavailable\") ||\n msg.includes(\"502\") ||\n msg.includes(\"503\") ||\n msg.includes(\"504\") ||\n msg.includes(\"529\")\n );\n}\n\nfunction isMissingCredentialText(message: string, errorCode?: string): boolean {\n const code = String(errorCode ?? \"\").toLowerCase();\n const msg = message.toLowerCase();\n return (\n code === \"missing_api_key\" ||\n code === \"missing_credentials\" ||\n msg.includes(\"apikey\") ||\n msg.includes(\"authtoken\") ||\n msg.includes(\"anthropic_api_key\") ||\n msg.includes(\"missing_api_key\") ||\n msg.includes(\"missing api key\") ||\n msg.includes(\"missing credentials\") ||\n msg.includes(\"no llm provider\") ||\n msg.includes(\"llm provider is connected\")\n );\n}\n\nfunction dispatchActivityClear(tabId: string | undefined) {\n if (typeof window === \"undefined\") return;\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:activity-clear\", {\n detail: { tabId },\n }),\n );\n}\n\n/**\n * Process a single SSE event and update the content accumulator.\n * Returns: \"continue\" to keep going, \"done\" to stop, or a yield-ready result.\n */\nexport function processEvent(\n ev: SSEEvent,\n content: ContentPart[],\n toolCallCounter: { value: number },\n tabId: string | undefined,\n): {\n action:\n | \"continue\"\n | \"done\"\n | \"yield\"\n | \"error\"\n | \"missing_api_key\"\n | \"auto_continue\";\n result?: ChatModelRunResult;\n autoContinue?: {\n reason: AgentAutoContinueReason;\n maxIterations?: number;\n };\n} {\n if (ev.type === \"clear\") {\n // Server is retrying — discard partial text/tool output from the failed attempt\n content.length = 0;\n dispatchActivityClear(tabId);\n return { action: \"continue\" };\n }\n\n if (ev.type === \"text\") {\n const lastPart = content[content.length - 1];\n if (lastPart && lastPart.type === \"text\") {\n lastPart.text += ev.text ?? \"\";\n } else {\n content.push({ type: \"text\", text: ev.text ?? \"\" });\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"activity\") {\n const tool = ev.tool?.trim() || undefined;\n const label = humanizeToolLabelText(ev.label ?? \"Working\", tool);\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:activity\", {\n detail: {\n label,\n ...(tool ? { tool } : {}),\n tabId,\n },\n }),\n );\n }\n if (!tool) return { action: \"continue\" };\n\n const pendingToolCallIndex = findPendingToolCallIndex(content, tool);\n if (pendingToolCallIndex === -1) {\n content.push({\n type: \"tool-call\",\n toolCallId: `tc_${++toolCallCounter.value}`,\n toolName: tool,\n argsText: \"\",\n args: {},\n activity: true,\n });\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"tool_start\") {\n const args = (ev.input ?? {}) as Record<string, string>;\n const tool = ev.tool ?? \"unknown\";\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(\n new CustomEvent(\"agent-native:tool-start\", {\n detail: { tool, input: args },\n }),\n );\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:activity\", {\n detail: {\n label: runningToolLabel(tool),\n tool,\n tabId,\n },\n }),\n );\n }\n // Pass the server-assigned id so we upgrade the pending activity card\n // using id-match when available (parallel same-name calls stay separate).\n const pendingToolCallIndex = findPendingToolCallIndex(content, tool, ev.id);\n const pendingToolCall =\n pendingToolCallIndex >= 0 ? content[pendingToolCallIndex] : undefined;\n if (\n pendingToolCall &&\n pendingToolCall.type === \"tool-call\" &&\n pendingToolCall.activity === true &&\n pendingToolCall.argsText === \"\" &&\n Object.keys(pendingToolCall.args).length === 0\n ) {\n // Upgrade the pending activity card in place. Prefer the server-assigned\n // id so the subsequent tool_done can match it precisely (parallel\n // same-name calls each carry their own id). Fall back to the\n // locally-generated id already on the card.\n content[pendingToolCallIndex] = {\n type: \"tool-call\",\n toolCallId: ev.id ?? pendingToolCall.toolCallId,\n toolName: tool,\n argsText: JSON.stringify(args),\n args,\n };\n } else {\n content.push({\n type: \"tool-call\",\n toolCallId: ev.id ?? `tc_${++toolCallCounter.value}`,\n toolName: tool,\n argsText: JSON.stringify(args),\n args,\n });\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"approval_required\") {\n // Opt-in `needsApproval` gate: the server emitted `tool_start` immediately\n // before this, so the matching tool-call part already exists. Mark it as\n // awaiting approval so the UI can render the Approve/Deny affordance. The\n // action did NOT execute; a paused `tool_done` follows.\n const approvalTool = ev.tool ?? \"unknown\";\n const approvalKey = ev.approvalKey;\n if (approvalKey) {\n const idx = findPendingToolCallIndex(content, approvalTool, ev.id);\n if (idx >= 0) {\n const part = content[idx];\n if (part.type === \"tool-call\") {\n part.approval = { approvalKey };\n }\n }\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"tool_done\") {\n // Normalize identically to tool_start (which stores `ev.tool ?? \"unknown\"`)\n // so a tool_done frame with an undefined tool name still matches its\n // pending tool-call entry instead of leaving it forever unresolved.\n const doneTool = ev.tool ?? \"unknown\";\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(\n new CustomEvent(\"agent-native:tool-done\", {\n detail: { tool: doneTool, result: ev.result },\n }),\n );\n }\n // Use id-based lookup when available so parallel same-name tool calls\n // get their results correctly assigned; fall back to name-matching.\n const doneIdx = findPendingToolCallIndex(content, doneTool, ev.id);\n if (doneIdx >= 0) {\n const part = content[doneIdx];\n if (part.type === \"tool-call\") {\n part.result = ev.result ?? \"\";\n if (ev.mcpApp) part.mcpApp = ev.mcpApp;\n }\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"agent_call\") {\n const agentName = ev.agent ?? \"agent\";\n if (ev.status === \"start\") {\n const toolCallId = `tc_${++toolCallCounter.value}`;\n content.push({\n type: \"tool-call\",\n toolCallId,\n toolName: `agent:${agentName}`,\n argsText: \"\",\n args: {},\n });\n } else if (ev.status === \"done\" || ev.status === \"error\") {\n for (let i = content.length - 1; i >= 0; i--) {\n const part = content[i];\n if (\n part.type === \"tool-call\" &&\n part.toolName === `agent:${agentName}` &&\n part.result === undefined\n ) {\n part.result = ev.status === \"error\" ? \"Error calling agent\" : \"Done\";\n break;\n }\n }\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"agent_call_text\") {\n const agentName = ev.agent ?? \"agent\";\n // Find the in-progress agent tool-call and append streaming text to argsText\n for (let i = content.length - 1; i >= 0; i--) {\n const part = content[i];\n if (\n part.type === \"tool-call\" &&\n part.toolName === `agent:${agentName}` &&\n part.result === undefined\n ) {\n part.argsText += ev.text ?? \"\";\n break;\n }\n }\n return {\n action: \"yield\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n // ─── Agent task events (sub-agent chips) ─────────────────────────\n // These events are dispatched as CustomEvents so AgentTaskCard components\n // can listen for updates to their specific taskId.\n if (\n ev.type === \"agent_task\" ||\n ev.type === \"agent_task_update\" ||\n ev.type === \"agent_task_complete\"\n ) {\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new CustomEvent(\"agent-task-event\", { detail: ev }));\n }\n // Don't add to content — the agent-teams tool call handles rendering\n return { action: \"continue\" };\n }\n\n if (ev.type === \"missing_api_key\") {\n const errMsg = LLM_MISSING_CREDENTIALS_MESSAGE;\n const errorCode = LLM_MISSING_CREDENTIALS_ERROR_CODE;\n const runError = {\n message: normalizeChatError(errMsg).message,\n errorCode,\n };\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new Event(\"agent-chat:missing-api-key\"));\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:run-error\", {\n detail: { ...runError, tabId },\n }),\n );\n }\n settleInterruptedToolCalls(content);\n content.push({\n type: \"text\",\n text: formatChatErrorText(errMsg, undefined, errorCode),\n });\n return {\n action: \"missing_api_key\",\n result: {\n content: [...content],\n status: { type: \"incomplete\" as const, reason: \"error\" as const },\n metadata: { custom: { runError } },\n } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"loop_limit\") {\n const maxIterations =\n typeof ev.maxIterations === \"number\" ? ev.maxIterations : undefined;\n return {\n action: \"auto_continue\",\n autoContinue: {\n reason: \"loop_limit\",\n ...(maxIterations ? { maxIterations } : {}),\n },\n };\n }\n\n if (ev.type === \"auto_continue\") {\n const reason =\n ev.reason === \"stream_ended\" ||\n ev.reason === \"loop_limit\" ||\n ev.reason === \"no_progress\" ||\n ev.reason === \"run_timeout\"\n ? ev.reason\n : ev.errorCode === \"stream_ended\" ||\n ev.errorCode === \"loop_limit\" ||\n ev.errorCode === \"no_progress\" ||\n ev.errorCode === \"run_timeout\"\n ? ev.errorCode\n : ev.error === \"stream_ended\" ||\n ev.error === \"loop_limit\" ||\n ev.error === \"no_progress\" ||\n ev.error === \"run_timeout\"\n ? ev.error\n : ev.status === \"stream_ended\" ||\n ev.status === \"loop_limit\" ||\n ev.status === \"no_progress\" ||\n ev.status === \"run_timeout\"\n ? ev.status\n : \"run_timeout\";\n return {\n action: \"auto_continue\",\n autoContinue: {\n reason,\n ...(typeof ev.maxIterations === \"number\"\n ? { maxIterations: ev.maxIterations }\n : {}),\n },\n };\n }\n\n if (ev.type === \"error\") {\n const errMsg = ev.error ?? \"Unknown error\";\n if (\n (ev.errorCode === \"run_timeout\" && ev.recoverable) ||\n isAutoRecoverableError(ev, errMsg)\n ) {\n return {\n action: \"auto_continue\",\n autoContinue: {\n reason:\n ev.errorCode === \"stale_run\"\n ? \"stale_run\"\n : ev.errorCode === \"builder_gateway_timeout\" ||\n ev.errorCode === \"run_timeout\" ||\n errMsg.toLowerCase().includes(\"timeout\")\n ? \"run_timeout\"\n : \"stream_ended\",\n },\n };\n }\n const normalized = normalizeChatError(errMsg);\n if (isMissingCredentialText(errMsg, ev.errorCode)) {\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(new Event(\"agent-chat:missing-api-key\"));\n }\n }\n const runError = {\n message: normalized.message,\n ...(normalized.details || ev.details\n ? { details: ev.details ?? normalized.details }\n : {}),\n ...(ev.errorCode ? { errorCode: ev.errorCode } : {}),\n ...(ev.recoverable ? { recoverable: ev.recoverable } : {}),\n };\n if (typeof window !== \"undefined\") {\n window.dispatchEvent(\n new CustomEvent(\"agent-chat:run-error\", {\n detail: { ...runError, tabId },\n }),\n );\n }\n settleInterruptedToolCalls(content);\n content.push({\n type: \"text\",\n text: formatChatErrorText(errMsg, ev.upgradeUrl, ev.errorCode),\n });\n return {\n action: \"error\",\n result: {\n content: [...content],\n status: { type: \"incomplete\" as const, reason: \"error\" as const },\n metadata: { custom: { runError } },\n } as ChatModelRunResult,\n };\n }\n\n if (ev.type === \"done\") {\n return {\n action: \"done\",\n result: { content: [...content] } as ChatModelRunResult,\n };\n }\n\n return { action: \"continue\" };\n}\n\n/**\n * Read and process SSE events from a ReadableStream response body.\n * Yields ChatModelRunResult for each meaningful event.\n *\n * When `runId` is provided, every yielded result carries\n * `metadata.custom.runId` so the UI can expose the trace ID via\n * \"Copy Request ID\" — including mid-stream, so users can grab it before\n * the run completes (or if the run hangs / ends prematurely).\n */\nexport async function* readSSEStream(\n body: ReadableStream<Uint8Array>,\n content: ContentPart[],\n toolCallCounter: { value: number },\n tabId: string | undefined,\n onSeq?: (seq: number) => void,\n runId?: string | null,\n): AsyncGenerator<ChatModelRunResult> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buf = \"\";\n let lastMeaningfulEventAt = Date.now();\n const activityTrail: ActivityTrailEntry[] = [];\n\n const withStreamMetadata = (r: ChatModelRunResult): ChatModelRunResult => {\n if (!runId && activityTrail.length === 0) return r;\n const metadata = (r.metadata ?? {}) as Record<string, unknown>;\n const custom =\n metadata.custom && typeof metadata.custom === \"object\"\n ? (metadata.custom as Record<string, unknown>)\n : {};\n const runError =\n runId && custom.runError && typeof custom.runError === \"object\"\n ? {\n ...(custom.runError as Record<string, unknown>),\n runId,\n }\n : custom.runError;\n return {\n ...r,\n metadata: {\n ...metadata,\n custom: {\n ...custom,\n ...(runId ? { runId } : {}),\n ...(runError ? { runError } : {}),\n ...(activityTrail.length > 0\n ? { activityTrail: [...activityTrail] }\n : {}),\n },\n },\n };\n };\n\n try {\n while (true) {\n const { done, value } = await readChunkWithProgressTimeout(\n reader,\n lastMeaningfulEventAt,\n );\n if (done) break;\n\n buf += decoder.decode(value, { stream: true });\n const lines = buf.split(\"\\n\");\n buf = lines.pop() ?? \"\";\n let sawDataEvent = false;\n\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const raw = line.slice(6).trim();\n if (!raw) continue;\n\n let ev: SSEEvent;\n try {\n ev = JSON.parse(raw);\n } catch {\n continue;\n }\n sawDataEvent = true;\n lastMeaningfulEventAt = Date.now();\n\n // Track sequence number for reconnection\n if (ev.seq !== undefined && onSeq) {\n onSeq(ev.seq);\n }\n\n if (ev.type === \"clear\") {\n activityTrail.length = 0;\n } else if (ev.type === \"activity\") {\n const tool = ev.tool?.trim() || undefined;\n appendActivityTrail(activityTrail, {\n label: humanizeToolLabelText(ev.label ?? \"Working\", tool),\n ...(tool ? { tool } : {}),\n });\n } else if (ev.type === \"tool_start\") {\n const tool = ev.tool ?? \"unknown\";\n appendActivityTrail(activityTrail, {\n label: runningToolLabel(tool),\n tool,\n });\n }\n\n const { action, result, autoContinue } = processEvent(\n ev,\n content,\n toolCallCounter,\n tabId,\n );\n\n if (result) yield withStreamMetadata(result);\n if (action === \"auto_continue\") {\n throw new AgentAutoContinueSignal(\n autoContinue\n ? { ...autoContinue, activityTrail: [...activityTrail] }\n : { reason: \"stream_ended\", activityTrail: [...activityTrail] },\n );\n }\n if (\n action === \"done\" ||\n action === \"error\" ||\n action === \"missing_api_key\"\n ) {\n return;\n }\n }\n\n if (\n !sawDataEvent &&\n Date.now() - lastMeaningfulEventAt >= SSE_NO_PROGRESS_TIMEOUT_MS\n ) {\n throw new AgentAutoContinueSignal({ reason: \"no_progress\" });\n }\n }\n } finally {\n try {\n reader.releaseLock();\n } catch {\n // The timeout path cancels the stream before unwinding; some runtimes\n // still consider the pending read active for a tick.\n }\n }\n\n // Stream ended without explicit done event. Even an empty content array is\n // abnormal here: a healthy run emits a terminal `done` event. Treat this as\n // recoverable so the adapter can first reconnect to the run, then continue\n // from durable history if the producer is gone.\n throw new AgentAutoContinueSignal({\n reason: \"stream_ended\",\n activityTrail: [...activityTrail],\n });\n}\n\n/**\n * Read raw SSE events from a ReadableStream and process them into ContentPart[].\n * Unlike readSSEStream, this doesn't yield ChatModelRunResult — it updates the\n * content array in-place and calls onUpdate for each meaningful change.\n * Designed for reconnection scenarios where we render outside assistant-ui's runtime.\n */\nexport async function readSSEStreamRaw(\n body: ReadableStream<Uint8Array>,\n content: ContentPart[],\n toolCallCounter: { value: number },\n tabId: string | undefined,\n onUpdate: (content: ContentPart[]) => void,\n): Promise<void> {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buf = \"\";\n let lastMeaningfulEventAt = Date.now();\n // Tracks whether the most recent content state was already pushed via\n // onUpdate inside the loop, so the post-loop flush below doesn't emit the\n // identical content a second time when the stream closes without a terminal\n // event.\n let emittedLatestContent = false;\n\n try {\n while (true) {\n const { done, value } = await readChunkWithProgressTimeout(\n reader,\n lastMeaningfulEventAt,\n );\n if (done) break;\n\n buf += decoder.decode(value, { stream: true });\n const lines = buf.split(\"\\n\");\n buf = lines.pop() ?? \"\";\n\n let updated = false;\n let sawDataEvent = false;\n for (const line of lines) {\n if (!line.startsWith(\"data: \")) continue;\n const raw = line.slice(6).trim();\n if (!raw) continue;\n\n let ev: SSEEvent;\n try {\n ev = JSON.parse(raw);\n } catch {\n continue;\n }\n sawDataEvent = true;\n lastMeaningfulEventAt = Date.now();\n\n const { action, autoContinue } = processEvent(\n ev,\n content,\n toolCallCounter,\n tabId,\n );\n\n if (\n action === \"yield\" ||\n action === \"done\" ||\n action === \"error\" ||\n action === \"missing_api_key\"\n ) {\n updated = true;\n }\n if (action === \"auto_continue\") {\n onUpdate([...content]);\n throw new AgentAutoContinueSignal(\n autoContinue ?? { reason: \"stream_ended\" },\n );\n }\n if (\n action === \"done\" ||\n action === \"error\" ||\n action === \"missing_api_key\"\n ) {\n onUpdate([...content]);\n return;\n }\n }\n\n if (updated) {\n onUpdate([...content]);\n emittedLatestContent = true;\n }\n if (\n !sawDataEvent &&\n Date.now() - lastMeaningfulEventAt >= SSE_NO_PROGRESS_TIMEOUT_MS\n ) {\n throw new AgentAutoContinueSignal({ reason: \"no_progress\" });\n }\n }\n } finally {\n try {\n reader.releaseLock();\n } catch {\n // See readSSEStream: cancellation may race lock release in browsers.\n }\n }\n if (content.length > 0 && !emittedLatestContent) onUpdate([...content]);\n throw new AgentAutoContinueSignal({ reason: \"stream_ended\" });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"run-code.d.ts","sourceRoot":"","sources":["../../src/coding-tools/run-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAoBhE,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAC7C,IAAI,GAAE,cAAmB,GACxB,WAAW,CAiJb"}
1
+ {"version":3,"file":"run-code.d.ts","sourceRoot":"","sources":["../../src/coding-tools/run-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAoBhE,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EAC7C,IAAI,GAAE,cAAmB,GACxB,WAAW,CAmJb"}
@@ -76,8 +76,10 @@ export function createRunCodeEntry(getActions, opts = {}) {
76
76
  " - `providerFetchAll(provider, path, init?)` — generic pagination helper for cursor, page, and offset APIs. Pass `pagination: { itemsPath, cursorPath or nextCursorPath, cursorParam or cursorBodyPath, pageParam, offsetParam, pageSize, maxPages }`. Returns `{ items, pages, pageCount, itemCount, hasMore, lastCursor, stoppedReason }`.",
77
77
  " - `providerSearchAll(provider, path, init?, options?)` — streaming search helper for broad provider corpora such as transcripts, messages, tickets, issues, notes, events, or documents. Use this before hand-written loops when searching many provider records for terms/phrases/regexes or proving absence. Pass the same `pagination` config as `providerFetchAll`, plus options like `{ query, queries, terms, regex, textPaths, idPaths, metadataPaths, maxHits }`. Returns structured hits with item ids, paths, snippets, page/item indexes, and coverage fields (`pageCount`, `itemCount`, `hasMore`, `stoppedReason`).",
78
78
  " - `webFetch(url, init?)` — outbound HTTP request via the web-request action.",
79
- " Returns `{ status, body }` where body is the response text.",
80
- " Example: `const { body } = await webFetch('https://api.example.com/data');`",
79
+ " Returns `{ status, body }` where body is the response text. Supports responseMode, extract, includeLinks, search, maxChars, and saveToFile.",
80
+ " Example: `const { body } = await webFetch('https://api.example.com/data', { responseMode: 'raw' });`",
81
+ " - `webRead(url, init?)` — convenience wrapper for webFetch with `responseMode: 'auto'` and extracted HTML/markdown or bounded matches.",
82
+ " Example: `const docs = await webRead('https://docs.example.com/api', { search: { query: 'pagination' } });`",
81
83
  " - `workspaceRead(path, opts?)` — read a Resources-backed workspace file by path. Returns content string or null. opts: { offset?, maxChars? }.",
82
84
  " - `workspaceReadMeta(path, opts?)` — read a workspace file with metadata such as sizeBytes, truncated, and nextOffset.",
83
85
  " - `workspaceWrite(path, content, contentType?)` — create or overwrite a workspace file. Use `scratch/...` for temporary staging; use durable folders only for files the user should keep.",
@@ -1004,6 +1006,12 @@ async function webFetch(url, init = {}) {
1004
1006
  method,
1005
1007
  ...(init.headers ? { headers: typeof init.headers === "string" ? init.headers : JSON.stringify(init.headers) } : {}),
1006
1008
  ...(init.body ? { body: typeof init.body === "string" ? init.body : JSON.stringify(init.body) } : {}),
1009
+ ...(init.responseMode ? { responseMode: init.responseMode } : {}),
1010
+ ...(init.extract ? { extract: init.extract } : {}),
1011
+ ...(init.includeLinks !== undefined ? { includeLinks: init.includeLinks } : {}),
1012
+ ...(init.search ? { search: init.search } : {}),
1013
+ ...(init.maxChars ? { maxChars: init.maxChars } : {}),
1014
+ ...(init.saveToFile ? { saveToFile: init.saveToFile } : {}),
1007
1015
  });
1008
1016
  // rawResult is "HTTP <status> <statusText>\\n\\n<body>"
1009
1017
  const statusMatch = typeof rawResult === "string" ? rawResult.match(/^HTTP (\\d+) [^\\n]*\\n\\n/) : null;
@@ -1016,6 +1024,14 @@ async function webFetch(url, init = {}) {
1016
1024
  return { status: 0, body: rawResult };
1017
1025
  }
1018
1026
 
1027
+ async function webRead(url, init = {}) {
1028
+ return webFetch(url, {
1029
+ responseMode: "auto",
1030
+ includeLinks: true,
1031
+ ...init,
1032
+ });
1033
+ }
1034
+
1019
1035
  /**
1020
1036
  * Read a Resources-backed workspace file by path. Returns the file content as
1021
1037
  * a string, or null if not found.
@@ -1 +1 @@
1
- {"version":3,"file":"run-code.js","sourceRoot":"","sources":["../../src/coding-tools/run-code.ts"],"names":[],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuwBtB,QAAQ;;;;;CAKT,CAAC;AACF,CAAC","sourcesContent":["/**\n * Sandboxed JavaScript execution tool for the agent.\n *\n * Executes user-supplied JavaScript in an isolated child process with:\n * - A scrubbed environment (no app secrets or env vars; only PATH/HOME/TMPDIR).\n * - A fresh temporary working directory.\n * - An ephemeral bridge HTTP server on 127.0.0.1 so the child can call\n * allowlisted registered tools (provider-api-request, web-request, etc.)\n * with the same request context as the parent — without leaking secrets.\n *\n * Security notes:\n * - The bridge token is a 32-byte random hex string generated per invocation.\n * - The bridge binds to 127.0.0.1 only; no external exposure.\n * - The allowlist of callable bridge tools is enforced server-side.\n * - Secret values are NEVER included in the env passed to the child.\n * - When the Node permission model is available (`--permission`, or\n * `--experimental-permission` on Node 20), the child is denied filesystem\n * access outside its own temp dir, child processes, workers, and native\n * addons. Outbound network from the child is NOT blocked by the permission\n * model; the env scrub means such requests carry no credentials, and all\n * authenticated calls must go through the bridge (which applies the\n * registered tools' host allowlists and SSRF guards).\n *\n * The actual execution is delegated to a pluggable `SandboxAdapter` (see\n * `./sandbox`). The default `LocalChildProcessAdapter` preserves the spawned\n * child-process behavior described above; a remote/durable adapter can be\n * plugged in via `registerSandboxAdapter()` / `AGENT_NATIVE_SANDBOX` without\n * changing this file. The bridge, env scrub, module building, and output\n * formatting stay here in the parent regardless of adapter.\n */\n\nimport crypto from \"node:crypto\";\nimport http from \"node:http\";\n\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport type { ActionRunContext } from \"../action.js\";\nimport { getSandboxAdapter } from \"./sandbox/index.js\";\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst MAX_TIMEOUT_MS = 600_000;\nconst DEFAULT_MAX_OUTPUT_CHARS = 50_000;\nconst MAX_OUTPUT_CHARS = 200_000;\n/** Hard cap on bridge request bodies so sandboxed code can't exhaust parent memory. */\nconst BRIDGE_MAX_BODY_BYTES = 10 * 1024 * 1024;\n\n/** Tools callable via the sandbox bridge by default. */\nconst DEFAULT_BRIDGE_TOOLS = new Set([\n \"provider-api-request\",\n \"provider-api-docs\",\n \"provider-api-catalog\",\n \"web-request\",\n \"workspace-files\",\n]);\n\nexport interface RunCodeOptions {\n /**\n * Extra tool names (beyond the default set) that the sandbox bridge will\n * forward to the registered action registry.\n */\n bridgeTools?: string[];\n}\n\n/**\n * Create a `run-code` ActionEntry.\n *\n * @param getActions Supplier that returns the current action registry (called\n * at invocation time so updates are reflected).\n * @param opts Optional configuration.\n */\nexport function createRunCodeEntry(\n getActions: () => Record<string, ActionEntry>,\n opts: RunCodeOptions = {},\n): ActionEntry {\n const extraBridgeTools = new Set(opts.bridgeTools ?? []);\n\n return {\n readOnly: true,\n // Allow a generous per-call timeout so large data-processing jobs don't hit\n // the agent-loop's default 60 s cap.\n timeoutMs: MAX_TIMEOUT_MS,\n maxResultChars: MAX_OUTPUT_CHARS,\n tool: {\n description: [\n \"Execute JavaScript (Node.js, ESM, top-level await supported) in an isolated sandbox.\",\n \"Use this to fetch, join, aggregate, and reduce large datasets, returning only printed output to the conversation.\",\n \"The sandbox runs with a scrubbed environment (no secrets) and, where the Node permission model is available, no filesystem access outside its own temp dir, no child processes, and no workers. Authenticated calls must go through the provided globals; direct network requests carry no credentials. Note: isolation is process-level (env scrub + Node permission model), not an OS-level container — outbound network from sandbox code is not blocked.\",\n \"Available globals:\",\n \" - `appAction(name, args?)` — call any registered agent-exposed read-only app action/tool and get its parsed result.\",\n \" Use this to loop over app data readers and compose multi-source analyses without forcing every intermediate result into chat.\",\n \" - `providerFetch(provider, path, init?)` — authenticated call to a registered provider via the provider-api-request action.\",\n \" Returns the parsed JSON result (or throws on error).\",\n \" Supports stageAs/saveToFile/fetchAllPages; use cursorBodyPath for POST-body pagination.\",\n \" Example: `const data = await providerFetch('<provider-id>', '/records', { query: { limit: 100 } });`\",\n \" - `providerRequest(provider, path, init?)` — same authenticated call, but returns the full provider-api envelope with request, response status/headers, truncation, and body metadata.\",\n \" - `providerFetchAll(provider, path, init?)` — generic pagination helper for cursor, page, and offset APIs. Pass `pagination: { itemsPath, cursorPath or nextCursorPath, cursorParam or cursorBodyPath, pageParam, offsetParam, pageSize, maxPages }`. Returns `{ items, pages, pageCount, itemCount, hasMore, lastCursor, stoppedReason }`.\",\n \" - `providerSearchAll(provider, path, init?, options?)` — streaming search helper for broad provider corpora such as transcripts, messages, tickets, issues, notes, events, or documents. Use this before hand-written loops when searching many provider records for terms/phrases/regexes or proving absence. Pass the same `pagination` config as `providerFetchAll`, plus options like `{ query, queries, terms, regex, textPaths, idPaths, metadataPaths, maxHits }`. Returns structured hits with item ids, paths, snippets, page/item indexes, and coverage fields (`pageCount`, `itemCount`, `hasMore`, `stoppedReason`).\",\n \" - `webFetch(url, init?)` — outbound HTTP request via the web-request action.\",\n \" Returns `{ status, body }` where body is the response text.\",\n \" Example: `const { body } = await webFetch('https://api.example.com/data');`\",\n \" - `workspaceRead(path, opts?)` — read a Resources-backed workspace file by path. Returns content string or null. opts: { offset?, maxChars? }.\",\n \" - `workspaceReadMeta(path, opts?)` — read a workspace file with metadata such as sizeBytes, truncated, and nextOffset.\",\n \" - `workspaceWrite(path, content, contentType?)` — create or overwrite a workspace file. Use `scratch/...` for temporary staging; use durable folders only for files the user should keep.\",\n \" - `workspaceAppend(path, content)` — append text to a workspace file.\",\n \" - `workspaceList(prefix?)` — list workspace files, returns [{ path, sizeBytes, contentType, updatedAt }].\",\n \"Print results with `console.log()`; only stdout+stderr are returned.\",\n \"Timeout defaults to 120 s (max 600 s). Output is truncated to 50 000 chars by default (max 200 000).\",\n ].join(\" \"),\n parameters: {\n type: \"object\",\n properties: {\n code: {\n type: \"string\",\n description:\n \"JavaScript source to execute. ESM syntax, top-level await allowed.\",\n },\n timeoutMs: {\n type: \"number\",\n description: `Execution timeout in milliseconds. Default: ${DEFAULT_TIMEOUT_MS}. Max: ${MAX_TIMEOUT_MS}.`,\n },\n maxOutputChars: {\n type: \"number\",\n description: `Maximum combined stdout+stderr characters to return. Default: ${DEFAULT_MAX_OUTPUT_CHARS}. Max: ${MAX_OUTPUT_CHARS}.`,\n },\n },\n required: [\"code\"],\n },\n },\n run: async (args: Record<string, string>, context?: ActionRunContext) => {\n const code = typeof args.code === \"string\" ? args.code : \"\";\n if (!code.trim()) return \"Error: code is required.\";\n\n const requestedTimeout = Number(args.timeoutMs);\n const timeoutMs =\n Number.isFinite(requestedTimeout) && requestedTimeout > 0\n ? Math.min(requestedTimeout, MAX_TIMEOUT_MS)\n : DEFAULT_TIMEOUT_MS;\n\n const requestedMaxOutput = Number(args.maxOutputChars);\n const maxOutputChars =\n Number.isFinite(requestedMaxOutput) && requestedMaxOutput > 0\n ? Math.min(requestedMaxOutput, MAX_OUTPUT_CHARS)\n : DEFAULT_MAX_OUTPUT_CHARS;\n\n const actions = getActions();\n const bridgeToken = crypto.randomBytes(32).toString(\"hex\");\n\n // Start bridge server — resolves once the server is listening.\n const {\n bridgePort,\n getUsedTools,\n cleanup: cleanupBridge,\n } = await startBridgeServer(\n bridgeToken,\n actions,\n context,\n DEFAULT_BRIDGE_TOOLS,\n extraBridgeTools,\n );\n\n try {\n // Build scrubbed env — only safe POSIX vars, no secrets. The adapter\n // points TMPDIR/TEMP/TMP at the sandbox's own temp dir.\n const safeEnv: Record<string, string> = {};\n for (const key of [\n \"PATH\",\n \"HOME\",\n \"TMPDIR\",\n \"TEMP\",\n \"TMP\",\n \"LANG\",\n \"LC_ALL\",\n ]) {\n if (process.env[key]) safeEnv[key] = process.env[key]!;\n }\n\n // Delegate execution to the active sandbox adapter (local child process\n // by default; remote/durable adapters can be registered via\n // ./sandbox). The bridge, env scrub, module, and output formatting stay\n // in the parent regardless of adapter.\n const { stdout, stderr, exitCode, timedOut } =\n await getSandboxAdapter().run({\n moduleSource: buildSandboxModule(code, bridgePort, bridgeToken),\n env: safeEnv,\n timeoutMs,\n bridgePort,\n });\n\n const combined =\n [\n stdout ? `stdout:\\n${stdout}` : \"\",\n stderr ? `stderr:\\n${stderr}` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\\n\") || \"(no output)\";\n\n const lines: string[] = [];\n if (timedOut) lines.push(`timedOut: true (${timeoutMs}ms)`);\n if (exitCode !== 0 && exitCode !== null)\n lines.push(`exitCode: ${exitCode}`);\n const usedTools = getUsedTools();\n if (usedTools.length)\n lines.push(`bridgeToolsUsed: ${usedTools.join(\", \")}`);\n lines.push(combined);\n\n const full = lines.join(\"\\n\\n\");\n if (full.length > maxOutputChars) {\n const truncated = full.slice(0, maxOutputChars);\n return `${truncated}\\n\\n...[truncated ${(full.length - maxOutputChars).toLocaleString()} chars]`;\n }\n return full;\n } finally {\n // The active sandbox adapter owns its own temp-file cleanup; the parent\n // only tears down the bridge server here.\n cleanupBridge();\n }\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Bridge server\n// ---------------------------------------------------------------------------\n\ninterface BridgeResult {\n server: http.Server;\n bridgePort: number;\n getUsedTools: () => string[];\n cleanup: () => void;\n}\n\nasync function startBridgeServer(\n token: string,\n actions: Record<string, ActionEntry>,\n context: ActionRunContext | undefined,\n defaultTools: Set<string>,\n extraTools: Set<string>,\n): Promise<BridgeResult> {\n const usedTools = new Set<string>();\n const server = http.createServer((req, res) => {\n if (req.method !== \"POST\" || req.url !== \"/tool\") {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n // Validate bearer token — must match exactly.\n const authHeader = req.headers.authorization ?? \"\";\n if (authHeader !== `Bearer ${token}`) {\n res.writeHead(401);\n res.end(\"Unauthorized\");\n return;\n }\n\n let body = \"\";\n let receivedBytes = 0;\n let rejected = false;\n req.on(\"data\", (chunk: Buffer) => {\n receivedBytes += chunk.length;\n if (receivedBytes > BRIDGE_MAX_BODY_BYTES) {\n rejected = true;\n res.writeHead(413);\n res.end(\"Payload too large\");\n req.destroy();\n return;\n }\n body += chunk.toString();\n });\n req.on(\"end\", () => {\n if (rejected) return;\n handleBridgeRequest(\n body,\n actions,\n context,\n defaultTools,\n extraTools,\n usedTools,\n res,\n );\n });\n req.on(\"error\", () => {\n res.writeHead(500);\n res.end(\"Request error\");\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => resolve());\n });\n\n const addr = server.address() as { port: number };\n const bridgePort = addr.port;\n\n const cleanup = () => {\n try {\n server.close();\n } catch {}\n };\n\n return {\n server,\n bridgePort,\n getUsedTools: () => Array.from(usedTools).sort(),\n cleanup,\n };\n}\n\nfunction handleBridgeRequest(\n rawBody: string,\n actions: Record<string, ActionEntry>,\n context: ActionRunContext | undefined,\n defaultTools: Set<string>,\n extraTools: Set<string>,\n usedTools: Set<string>,\n res: http.ServerResponse,\n): void {\n let parsed: { tool?: string; args?: Record<string, string> };\n try {\n parsed = JSON.parse(rawBody);\n } catch {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Invalid JSON body\" }));\n return;\n }\n\n const toolName = typeof parsed.tool === \"string\" ? parsed.tool.trim() : \"\";\n if (!toolName) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing tool name\" }));\n return;\n }\n\n // Enforce allowlist.\n const entry = actions[toolName];\n const isReadOnlyAction =\n entry?.readOnly === true &&\n entry.agentTool !== false &&\n entry.toolCallable !== false;\n if (\n !defaultTools.has(toolName) &&\n !extraTools.has(toolName) &&\n !isReadOnlyAction\n ) {\n res.writeHead(403, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: `Tool \"${toolName}\" is not an agent-exposed read-only action or sandbox bridge allowlisted tool.`,\n }),\n );\n return;\n }\n\n if (!entry) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: `Tool \"${toolName}\" is not registered.` }));\n return;\n }\n\n const toolArgs = parsed.args ?? {};\n usedTools.add(toolName);\n // Run the tool with the parent request context so auth/org/owner resolution\n // works exactly as it does in the normal agent loop.\n entry\n .run(toolArgs, context)\n .then((result: unknown) => {\n const body =\n typeof result === \"string\" ? result : JSON.stringify(result, null, 2);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ result: body }));\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: message }));\n });\n}\n\n// ---------------------------------------------------------------------------\n// Sandbox module template\n// ---------------------------------------------------------------------------\n\n/**\n * Wrap the user's code in an ESM module that:\n * 1. Defines `providerFetch`, `providerRequest`, `providerFetchAll`,\n * `providerSearchAll`, and `webFetch` helpers via the bridge.\n * 2. Runs the user's code as top-level await in an async IIFE.\n */\nfunction buildSandboxModule(\n userCode: string,\n bridgePort: number,\n bridgeToken: string,\n): string {\n return `\nimport { createRequire } from \"node:module\";\nconst require = createRequire(import.meta.url);\n\nconst _bridgeBase = \"http://127.0.0.1:${bridgePort}/tool\";\nconst _bridgeToken = \"${bridgeToken}\";\n\nasync function _bridgeCall(tool, args) {\n const http = await import(\"node:http\");\n return new Promise((resolve, reject) => {\n const body = JSON.stringify({ tool, args });\n const options = {\n hostname: \"127.0.0.1\",\n port: ${bridgePort},\n path: \"/tool\",\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Length\": Buffer.byteLength(body),\n \"Authorization\": \"Bearer \" + _bridgeToken,\n },\n };\n const req = http.request(options, (res) => {\n let data = \"\";\n res.on(\"data\", (chunk) => { data += chunk; });\n res.on(\"end\", () => {\n try {\n const parsed = JSON.parse(data);\n if (parsed.error) {\n reject(new Error(parsed.error));\n } else {\n resolve(parsed.result);\n }\n } catch (e) {\n reject(new Error(\"Bridge response parse error: \" + e.message));\n }\n });\n });\n req.on(\"error\", reject);\n req.end(body);\n });\n}\n\nfunction _parseBridgeResult(rawResult) {\n if (typeof rawResult !== \"string\") return rawResult;\n try { return JSON.parse(rawResult); } catch { return rawResult; }\n}\n\n/**\n * Call any registered agent-exposed read-only app action/tool via the sandbox bridge.\n * Mutating and explicitly hidden actions are blocked by the parent bridge.\n */\nasync function appAction(name, args = {}) {\n return _parseBridgeResult(await _bridgeCall(name, args));\n}\n\nasync function providerRequest(provider, apiPath, init = {}) {\n const method = (init.method || \"GET\").toUpperCase();\n const rawResult = await _bridgeCall(\"provider-api-request\", {\n provider,\n path: apiPath,\n method,\n ...(init.query ? { query: init.query } : {}),\n ...(init.body ? { body: init.body } : {}),\n ...(init.headers ? { headers: init.headers } : {}),\n ...(init.auth ? { auth: init.auth } : {}),\n ...(init.connectionId ? { connectionId: init.connectionId } : {}),\n ...(init.accountId ? { accountId: init.accountId } : {}),\n ...(init.timeoutMs ? { timeoutMs: init.timeoutMs } : {}),\n ...(init.maxBytes ? { maxBytes: init.maxBytes } : {}),\n ...(init.stageAs ? { stageAs: init.stageAs } : {}),\n ...(init.itemsPath ? { itemsPath: init.itemsPath } : {}),\n ...(init.pagination ? { pagination: init.pagination } : {}),\n ...(init.saveToFile ? { saveToFile: init.saveToFile } : {}),\n ...(init.fetchAllPages ? { fetchAllPages: init.fetchAllPages } : {}),\n });\n return _parseBridgeResult(rawResult);\n}\n\n/**\n * Call a provider API via the authenticated provider-api-request action.\n * Returns the parsed JSON response body (or throws on error).\n */\nasync function providerFetch(provider, apiPath, init = {}) {\n const parsed = await providerRequest(provider, apiPath, init);\n // Unwrap the provider-api-request envelope ({ provider, request, response, guidance })\n // so callers get the actual response body. fetchAllPages / saveToFile results\n // (which have no \\`response\\` field) are returned as-is.\n if (parsed && typeof parsed === \"object\" && parsed.response && typeof parsed.response === \"object\") {\n const r = parsed.response;\n if (typeof r.status === \"number\" && r.status >= 400) {\n const detail = typeof r.text === \"string\" ? r.text : JSON.stringify(r.json ?? \"\");\n throw new Error(\\`Provider request failed (\\${r.status}): \\${String(detail).slice(0, 500)}\\`);\n }\n return r.json !== undefined ? r.json : r.text;\n }\n return parsed;\n}\n\nfunction _cloneJson(value) {\n if (value === undefined || value === null) return value;\n return JSON.parse(JSON.stringify(value));\n}\n\nfunction _pathParts(path) {\n if (!path || typeof path !== \"string\") return [];\n return path\n .replace(/\\\\[(\\\\d+)\\\\]/g, \".$1\")\n .split(\".\")\n .map((part) => part.trim())\n .filter(Boolean);\n}\n\nfunction _getByPath(value, path) {\n let current = value;\n for (const part of _pathParts(path)) {\n if (current === undefined || current === null) return undefined;\n current = current[part];\n }\n return current;\n}\n\nfunction _setByPath(value, path, nextValue) {\n const parts = _pathParts(path);\n if (!parts.length) return value;\n const root = value && typeof value === \"object\" ? _cloneJson(value) : {};\n let current = root;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (!current[part] || typeof current[part] !== \"object\") current[part] = {};\n current = current[part];\n }\n current[parts[parts.length - 1]] = nextValue;\n return root;\n}\n\nfunction _extractItems(page, itemsPath) {\n if (itemsPath) {\n const value = _getByPath(page, itemsPath);\n return Array.isArray(value) ? value : [];\n }\n if (Array.isArray(page)) return page;\n if (!page || typeof page !== \"object\") return [];\n for (const key of [\"data\", \"results\", \"items\", \"records\", \"rows\", \"calls\", \"callTranscripts\", \"transcripts\", \"messages\", \"tickets\", \"issues\", \"deals\", \"events\", \"notes\", \"documents\", \"entries\", \"objects\"]) {\n if (Array.isArray(page[key])) return page[key];\n }\n return [];\n}\n\nfunction _withoutProviderFetchAllOptions(init) {\n const {\n pagination: _pagination,\n fetchAllPages: _fetchAllPages,\n stageAs: _stageAs,\n itemsPath: _itemsPath,\n saveToFile: _saveToFile,\n ...rest\n } = init || {};\n return rest;\n}\n\nfunction _asArray(value) {\n if (value === undefined || value === null) return [];\n return Array.isArray(value) ? value : [value];\n}\n\nfunction _stringifySearchValue(value) {\n if (typeof value === \"string\") return value;\n if (value === undefined || value === null) return \"\";\n if (typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\") {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction _collectStrings(value, basePath = \"\", out = [], limit = 5000) {\n if (out.length >= limit || value === undefined || value === null) return out;\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\") {\n out.push({ path: basePath || \"$\", text: String(value) });\n return out;\n }\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length && out.length < limit; i++) {\n _collectStrings(value[i], basePath ? basePath + \"[\" + i + \"]\" : \"[\" + i + \"]\", out, limit);\n }\n return out;\n }\n if (typeof value === \"object\") {\n for (const key of Object.keys(value)) {\n if (out.length >= limit) break;\n _collectStrings(value[key], basePath ? basePath + \".\" + key : key, out, limit);\n }\n }\n return out;\n}\n\nfunction _collectSearchStrings(item, textPaths, maxFieldsPerItem) {\n const paths = _asArray(textPaths).filter((path) => typeof path === \"string\" && path.trim());\n if (!paths.length) return _collectStrings(item, \"\", [], maxFieldsPerItem);\n const out = [];\n for (const path of paths) {\n const value = _getByPath(item, path);\n if (value !== undefined) _collectStrings(value, path, out, maxFieldsPerItem);\n if (out.length >= maxFieldsPerItem) break;\n }\n return out;\n}\n\nfunction _firstValueByPath(value, paths) {\n for (const path of paths) {\n const found = _getByPath(value, path);\n if (found !== undefined && found !== null && String(found) !== \"\") {\n return { path, value: found };\n }\n }\n return null;\n}\n\nconst _DEFAULT_ID_PATHS = [\n \"id\",\n \"callId\",\n \"callID\",\n \"call_id\",\n \"call.id\",\n \"call.metaData.id\",\n \"metaData.id\",\n \"metadata.id\",\n \"recordId\",\n \"record_id\",\n \"objectId\",\n \"object_id\",\n \"ticketId\",\n \"ticket_id\",\n \"issueId\",\n \"issue_id\",\n \"messageId\",\n \"message_id\",\n \"conversationId\",\n \"conversation_id\",\n \"eventId\",\n \"event_id\",\n \"documentId\",\n \"document_id\",\n \"url\",\n \"webUrl\",\n \"permalink\",\n];\n\nfunction _extractItemIdentity(item, idPaths) {\n const paths = [\n ..._asArray(idPaths).filter((path) => typeof path === \"string\" && path.trim()),\n ..._DEFAULT_ID_PATHS,\n ];\n const found = _firstValueByPath(item, paths);\n if (!found) return { id: null, idPath: null };\n return { id: _stringifySearchValue(found.value), idPath: found.path };\n}\n\nfunction _extractMetadata(item, metadataPaths) {\n const metadata = {};\n for (const path of _asArray(metadataPaths)) {\n if (typeof path !== \"string\" || !path.trim()) continue;\n const value = _getByPath(item, path);\n if (value !== undefined) metadata[path] = value;\n }\n return metadata;\n}\n\nfunction _makeSnippet(text, index, contextChars) {\n const source = String(text);\n const context = Math.max(20, Math.min(Number(contextChars) || 180, 1000));\n const start = Math.max(0, index - context);\n const end = Math.min(source.length, Math.max(index, 0) + context);\n const prefix = start > 0 ? \"...\" : \"\";\n const suffix = end < source.length ? \"...\" : \"\";\n return (prefix + source.slice(start, end) + suffix).replace(/\\\\s+/g, \" \").trim();\n}\n\nfunction _normalizeFlags(flags, caseSensitive) {\n const raw = typeof flags === \"string\" ? flags : \"\";\n const allowed = raw.replace(/[^dgimsuvy]/g, \"\");\n const withoutGlobalOrSticky = allowed.replace(/[gy]/g, \"\");\n const withCase =\n caseSensitive || /i/.test(withoutGlobalOrSticky)\n ? withoutGlobalOrSticky\n : withoutGlobalOrSticky + \"i\";\n return withCase + \"g\";\n}\n\nfunction _normalizedSearchTerms(options) {\n const explicitTerms = _asArray(options.terms)\n .map((term) => String(term).trim())\n .filter(Boolean);\n if (explicitTerms.length) return explicitTerms;\n if (options.matchMode === \"allTerms\" && typeof options.query === \"string\") {\n return options.query\n .split(/\\\\s+/)\n .map((term) => term.trim())\n .filter(Boolean);\n }\n return [];\n}\n\nfunction _findItemWideTermMatch(fields, options) {\n const terms = _normalizedSearchTerms(options);\n if (!terms.length || options.matchMode === \"anyTerm\") return null;\n const caseSensitive = Boolean(options.caseSensitive);\n const normalizedFields = fields.map((field) => ({\n field,\n haystack: caseSensitive ? String(field.text) : String(field.text).toLowerCase(),\n }));\n const termHits = terms.map((term) => {\n const searchTerm = caseSensitive ? term : term.toLowerCase();\n for (const entry of normalizedFields) {\n const index = entry.haystack.indexOf(searchTerm);\n if (index >= 0) return { term, field: entry.field, index };\n }\n return { term, field: null, index: -1 };\n });\n if (termHits.some((hit) => hit.index < 0 || !hit.field)) return null;\n const first = termHits\n .filter((hit) => hit.field)\n .sort((a, b) => {\n const fieldOrder = fields.indexOf(a.field) - fields.indexOf(b.field);\n return fieldOrder || a.index - b.index;\n })[0];\n return {\n field: first.field,\n match: {\n kind: \"allTerms\",\n query: terms.join(\" \"),\n index: first.index,\n match: first.term,\n },\n };\n}\n\nfunction _findSearchMatches(text, options, includeTerms = true) {\n const source = String(text);\n const caseSensitive = Boolean(options.caseSensitive);\n const haystack = caseSensitive ? source : source.toLowerCase();\n const maxMatchesPerField = _boundedNumber(options.maxMatchesPerField, 1000, 1, 100000);\n const matches = [];\n\n const addSubstring = (needle, label, kind) => {\n if (needle === undefined || needle === null) return;\n const rawNeedle = String(needle);\n if (!rawNeedle) return;\n const searchNeedle = caseSensitive ? rawNeedle : rawNeedle.toLowerCase();\n let from = 0;\n while (from <= haystack.length) {\n const index = haystack.indexOf(searchNeedle, from);\n if (index < 0) break;\n matches.push({ kind, query: label ?? rawNeedle, index, match: source.slice(index, index + rawNeedle.length) });\n from = index + Math.max(1, searchNeedle.length);\n if (matches.length >= maxMatchesPerField) break;\n }\n };\n\n if (options.regex) {\n try {\n const regex = new RegExp(String(options.regex), _normalizeFlags(options.regexFlags, caseSensitive));\n let match;\n while ((match = regex.exec(source)) && typeof match.index === \"number\") {\n matches.push({ kind: \"regex\", query: String(options.regex), index: match.index, match: match[0] });\n if (matches.length >= maxMatchesPerField) break;\n if (match[0] === \"\") regex.lastIndex += 1;\n }\n } catch (err) {\n throw new Error(\"providerSearchAll invalid regex: \" + (err?.message || err));\n }\n }\n\n for (const query of _asArray(options.query).concat(_asArray(options.queries))) {\n addSubstring(query, String(query), \"query\");\n }\n\n const terms = includeTerms ? _normalizedSearchTerms(options) : [];\n if (terms.length) {\n const termHits = terms\n .map((term) => {\n const searchTerm = caseSensitive ? term : term.toLowerCase();\n const index = haystack.indexOf(searchTerm);\n return { term, index };\n })\n .filter((hit) => hit.index >= 0);\n const mode = options.matchMode === \"anyTerm\" ? \"anyTerm\" : \"allTerms\";\n if ((mode === \"allTerms\" && termHits.length === terms.length) || (mode === \"anyTerm\" && termHits.length > 0)) {\n const first = termHits.sort((a, b) => a.index - b.index)[0];\n matches.push({ kind: mode, query: terms.join(\" \"), index: first.index, match: first.term });\n }\n }\n\n return matches.sort((a, b) => a.index - b.index);\n}\n\nfunction _boundedNumber(value, defaultValue, min, max) {\n const parsed = Number(value);\n const finite = Number.isFinite(parsed) ? parsed : defaultValue;\n return Math.max(min, Math.min(finite, max));\n}\n\nfunction _hitKey(identity, path, query, index, pageIndex, pageItemIndex) {\n const itemKey =\n identity.id !== null && identity.id !== undefined\n ? \"id:\" + identity.id\n : \"page:\" + String(pageIndex) + \":\" + String(pageItemIndex);\n return [itemKey, path ?? \"\", query ?? \"\", String(index ?? \"\")].join(\"\\\\n\");\n}\n\n/**\n * Stream pages from a provider API and search item text structurally. This is\n * for broad mention searches and absence checks where keeping every raw page\n * in memory or hand-parsing JSON strings is brittle.\n */\nasync function providerSearchAll(provider, apiPath, init = {}, options = {}) {\n const pagination = init.pagination || init.fetchAllPages || {};\n const itemsPath = pagination.itemsPath || init.itemsPath || options.itemsPath;\n const cursorPath = pagination.nextCursorPath || pagination.cursorPath;\n const maxPagesRaw = Number(pagination.maxPages || init.maxPages || options.maxPages || 100);\n const maxPages = Math.max(1, Math.min(Number.isFinite(maxPagesRaw) ? maxPagesRaw : 100, 500));\n const maxHits = _boundedNumber(options.maxHits, 100, 1, 5000);\n const maxHitsPerItem = _boundedNumber(options.maxHitsPerItem, 3, 1, 100);\n const maxFieldsPerItem = _boundedNumber(options.maxFieldsPerItem, 5000, 1, 50000);\n const contextChars = options.contextChars ?? options.snippetChars ?? 180;\n const baseInit = _withoutProviderFetchAllOptions(init);\n let query = _cloneJson(init.query || {});\n let body = _cloneJson(init.body);\n let pageNumber = Number(pagination.startPage || 1);\n let offset = Number(pagination.startOffset || 0);\n let lastCursor = null;\n let stoppedReason = \"completed\";\n let itemCount = 0;\n let matchedItemCount = 0;\n let totalHitCount = 0;\n const hits = [];\n const seenHitKeys = new Set();\n let pageIndex = 0;\n\n for (; pageIndex < maxPages; pageIndex++) {\n if (pagination.pageParam) query = { ...(query || {}), [pagination.pageParam]: pageNumber };\n if (pagination.offsetParam) query = { ...(query || {}), [pagination.offsetParam]: offset };\n\n const page = await providerFetch(provider, apiPath, {\n ...baseInit,\n query,\n ...(body !== undefined ? { body } : {}),\n });\n const nextCursor = cursorPath ? _getByPath(page, cursorPath) : undefined;\n const hasNextCursor =\n nextCursor !== undefined && nextCursor !== null && String(nextCursor) !== \"\";\n if (hasNextCursor && lastCursor !== null && String(nextCursor) === String(lastCursor)) {\n stoppedReason = \"repeated-cursor\";\n break;\n }\n\n const pageItems = _extractItems(page, itemsPath);\n itemCount += pageItems.length;\n\n for (let pageItemIndex = 0; pageItemIndex < pageItems.length; pageItemIndex++) {\n const item = pageItems[pageItemIndex];\n const identity = _extractItemIdentity(item, options.idPaths);\n const metadata = _extractMetadata(item, options.metadataPaths);\n const fields = _collectSearchStrings(item, options.textPaths, maxFieldsPerItem);\n let storedItemHitCount = 0;\n let itemMatched = false;\n\n const addHit = (field, match) => {\n const key = _hitKey(identity, field.path, match.query, match.index, pageIndex, pageItemIndex);\n if (seenHitKeys.has(key)) return false;\n seenHitKeys.add(key);\n totalHitCount += 1;\n if (!itemMatched) {\n matchedItemCount += 1;\n itemMatched = true;\n }\n if (hits.length < maxHits && storedItemHitCount < maxHitsPerItem) {\n storedItemHitCount += 1;\n hits.push({\n id: identity.id,\n idPath: identity.idPath,\n pageIndex,\n pageItemIndex,\n itemIndex: itemCount - pageItems.length + pageItemIndex,\n path: field.path,\n kind: match.kind,\n query: match.query,\n match: match.match,\n snippet: _makeSnippet(field.text, match.index, contextChars),\n ...(Object.keys(metadata).length ? { metadata } : {}),\n });\n }\n return true;\n };\n\n const itemWideTermMatch = _findItemWideTermMatch(fields, options);\n if (itemWideTermMatch) {\n addHit(itemWideTermMatch.field, itemWideTermMatch.match);\n }\n\n for (const field of fields) {\n const fieldMatches = _findSearchMatches(field.text, options, !itemWideTermMatch);\n for (const match of fieldMatches) {\n addHit(field, match);\n }\n }\n }\n\n if (hasNextCursor) {\n lastCursor = nextCursor;\n if (pagination.cursorBodyPath) {\n body = _setByPath(body || {}, pagination.cursorBodyPath, nextCursor);\n } else if (pagination.cursorParam) {\n query = { ...(query || {}), [pagination.cursorParam]: nextCursor };\n } else {\n stoppedReason = \"cursor-found-without-destination\";\n break;\n }\n continue;\n }\n\n lastCursor = null;\n if (pagination.pageParam) {\n if (pageItems.length === 0) {\n stoppedReason = \"empty-page\";\n break;\n }\n pageNumber += 1;\n continue;\n }\n if (pagination.offsetParam) {\n if (pageItems.length === 0) {\n stoppedReason = \"empty-page\";\n break;\n }\n const step = Number(pagination.pageSize || pageItems.length);\n if (!Number.isFinite(step) || step <= 0) {\n stoppedReason = \"invalid-page-size\";\n break;\n }\n offset += step;\n if (pagination.pageSize && pageItems.length < Number(pagination.pageSize)) {\n stoppedReason = \"short-page\";\n break;\n }\n continue;\n }\n\n break;\n }\n\n const pageCount = pageIndex + (pageIndex < maxPages ? 1 : 0);\n const hitPageOrOffsetLimit =\n Boolean(pagination.pageParam || pagination.offsetParam) &&\n stoppedReason === \"completed\" &&\n pageCount >= maxPages;\n const hasMore =\n stoppedReason === \"cursor-found-without-destination\" ||\n (lastCursor !== null && pageCount >= maxPages) || hitPageOrOffsetLimit;\n if (hasMore && stoppedReason === \"completed\") stoppedReason = \"max-pages\";\n\n return {\n hits,\n hitCount: hits.length,\n totalHitCount,\n truncatedHits: totalHitCount > hits.length,\n matchedItemCount,\n itemCount,\n pageCount,\n hasMore,\n lastCursor,\n stoppedReason,\n searched: {\n provider,\n path: apiPath,\n itemsPath: itemsPath || null,\n textPaths: _asArray(options.textPaths),\n idPaths: _asArray(options.idPaths),\n query: options.query ?? null,\n queries: _asArray(options.queries),\n terms: _asArray(options.terms),\n regex: options.regex ?? null,\n matchMode: options.matchMode || (options.terms ? \"allTerms\" : \"query\"),\n caseSensitive: Boolean(options.caseSensitive),\n },\n };\n}\n\n/**\n * Fetch every page from a provider API using generic cursor, page-number, or\n * offset pagination. Prefer this inside run-code when the answer depends on a\n * broad provider corpus rather than a single bounded request.\n */\nasync function providerFetchAll(provider, apiPath, init = {}) {\n const pagination = init.pagination || init.fetchAllPages || {};\n const itemsPath = pagination.itemsPath || init.itemsPath;\n const cursorPath = pagination.nextCursorPath || pagination.cursorPath;\n const maxPagesRaw = Number(pagination.maxPages || init.maxPages || 50);\n const maxPages = Math.max(1, Math.min(Number.isFinite(maxPagesRaw) ? maxPagesRaw : 50, 200));\n const baseInit = _withoutProviderFetchAllOptions(init);\n let query = _cloneJson(init.query || {});\n let body = _cloneJson(init.body);\n let pageNumber = Number(pagination.startPage || 1);\n let offset = Number(pagination.startOffset || 0);\n const pages = [];\n const items = [];\n let lastCursor = null;\n let stoppedReason = \"completed\";\n\n for (let pageIndex = 0; pageIndex < maxPages; pageIndex++) {\n if (pagination.pageParam) {\n query = { ...(query || {}), [pagination.pageParam]: pageNumber };\n }\n if (pagination.offsetParam) {\n query = { ...(query || {}), [pagination.offsetParam]: offset };\n }\n\n const page = await providerFetch(provider, apiPath, {\n ...baseInit,\n query,\n ...(body !== undefined ? { body } : {}),\n });\n pages.push(page);\n const pageItems = _extractItems(page, itemsPath);\n items.push(...pageItems);\n\n const nextCursor = cursorPath ? _getByPath(page, cursorPath) : undefined;\n if (nextCursor !== undefined && nextCursor !== null && String(nextCursor) !== \"\") {\n if (lastCursor !== null && String(nextCursor) === String(lastCursor)) {\n stoppedReason = \"repeated-cursor\";\n break;\n }\n lastCursor = nextCursor;\n if (pagination.cursorBodyPath) {\n body = _setByPath(body || {}, pagination.cursorBodyPath, nextCursor);\n } else if (pagination.cursorParam) {\n query = { ...(query || {}), [pagination.cursorParam]: nextCursor };\n } else {\n stoppedReason = \"cursor-found-without-destination\";\n break;\n }\n continue;\n }\n\n lastCursor = null;\n if (pagination.pageParam) {\n if (pageItems.length === 0) {\n stoppedReason = \"empty-page\";\n break;\n }\n pageNumber += 1;\n continue;\n }\n if (pagination.offsetParam) {\n if (pageItems.length === 0) {\n stoppedReason = \"empty-page\";\n break;\n }\n const step = Number(pagination.pageSize || pageItems.length);\n if (!Number.isFinite(step) || step <= 0) {\n stoppedReason = \"invalid-page-size\";\n break;\n }\n offset += step;\n if (pagination.pageSize && pageItems.length < Number(pagination.pageSize)) {\n stoppedReason = \"short-page\";\n break;\n }\n continue;\n }\n\n break;\n }\n\n const hitPageOrOffsetLimit =\n Boolean(pagination.pageParam || pagination.offsetParam) &&\n stoppedReason === \"completed\" &&\n pages.length >= maxPages;\n const hasMore =\n (lastCursor !== null && pages.length >= maxPages) || hitPageOrOffsetLimit;\n if (hasMore) stoppedReason = \"max-pages\";\n return {\n items,\n pages,\n pageCount: pages.length,\n itemCount: items.length,\n hasMore,\n lastCursor,\n stoppedReason,\n };\n}\n\n/**\n * Make an outbound HTTP request via the web-request action.\n * Returns an object \\`{ status, body }\\` where \\`body\\` is the response text.\n */\nasync function webFetch(url, init = {}) {\n const method = (init.method || \"GET\").toUpperCase();\n const rawResult = await _bridgeCall(\"web-request\", {\n url,\n method,\n ...(init.headers ? { headers: typeof init.headers === \"string\" ? init.headers : JSON.stringify(init.headers) } : {}),\n ...(init.body ? { body: typeof init.body === \"string\" ? init.body : JSON.stringify(init.body) } : {}),\n });\n // rawResult is \"HTTP <status> <statusText>\\\\n\\\\n<body>\"\n const statusMatch = typeof rawResult === \"string\" ? rawResult.match(/^HTTP (\\\\d+) [^\\\\n]*\\\\n\\\\n/) : null;\n if (statusMatch) {\n return {\n status: Number(statusMatch[1]),\n body: rawResult.slice(statusMatch[0].length),\n };\n }\n return { status: 0, body: rawResult };\n}\n\n/**\n * Read a Resources-backed workspace file by path. Returns the file content as\n * a string, or null if not found.\n * Supports optional offset and maxChars for paging large files.\n */\nasync function workspaceRead(path, opts = {}) {\n const parsed = await workspaceReadMeta(path, opts);\n if (parsed && parsed.ok === false) return null;\n return parsed && typeof parsed.content === \"string\" ? parsed.content : null;\n}\n\n/**\n * Read a workspace file by path and return the full metadata envelope.\n * Use this when offset/maxChars paging or truncation status matters.\n */\nasync function workspaceReadMeta(path, opts = {}) {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"read\",\n path,\n ...(opts.offset !== undefined ? { offset: opts.offset } : {}),\n ...(opts.maxChars !== undefined ? { maxChars: opts.maxChars } : {}),\n });\n return _parseBridgeResult(rawResult);\n}\n\n/**\n * Write (create or overwrite) a workspace file. Use \\`scratch/...\\` for\n * temporary staging files.\n * \\`content\\` must be a string. Returns metadata { path, sizeBytes, updatedAt }.\n */\nasync function workspaceWrite(path, content, contentType = \"text/plain\") {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"write\",\n path,\n content: typeof content === \"string\" ? content : JSON.stringify(content),\n contentType,\n });\n try { return typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult; } catch { return rawResult; }\n}\n\n/**\n * Append text to a workspace file (creates if absent).\n */\nasync function workspaceAppend(path, content) {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"append\",\n path,\n content: typeof content === \"string\" ? content : JSON.stringify(content),\n });\n try { return typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult; } catch { return rawResult; }\n}\n\n/**\n * List workspace files, optionally filtered by path prefix.\n * Returns an array of { path, sizeBytes, contentType, updatedAt }.\n */\nasync function workspaceList(prefix) {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"list\",\n ...(prefix ? { path: prefix } : {}),\n });\n const parsed = typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult;\n if (parsed && Array.isArray(parsed.files)) return parsed.files;\n if (Array.isArray(parsed)) return parsed;\n throw new Error(\"workspaceList: unexpected result shape: \" + JSON.stringify(parsed).slice(0, 200));\n}\n\n// Run user code\n(async () => {\n${userCode}\n})().catch((err) => {\n console.error(\"Unhandled error:\", err?.message ?? String(err));\n process.exit(1);\n});\n`;\n}\n"]}
1
+ {"version":3,"file":"run-code.js","sourceRoot":"","sources":["../../src/coding-tools/run-code.ts"],"names":[],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqxBtB,QAAQ;;;;;CAKT,CAAC;AACF,CAAC","sourcesContent":["/**\n * Sandboxed JavaScript execution tool for the agent.\n *\n * Executes user-supplied JavaScript in an isolated child process with:\n * - A scrubbed environment (no app secrets or env vars; only PATH/HOME/TMPDIR).\n * - A fresh temporary working directory.\n * - An ephemeral bridge HTTP server on 127.0.0.1 so the child can call\n * allowlisted registered tools (provider-api-request, web-request, etc.)\n * with the same request context as the parent — without leaking secrets.\n *\n * Security notes:\n * - The bridge token is a 32-byte random hex string generated per invocation.\n * - The bridge binds to 127.0.0.1 only; no external exposure.\n * - The allowlist of callable bridge tools is enforced server-side.\n * - Secret values are NEVER included in the env passed to the child.\n * - When the Node permission model is available (`--permission`, or\n * `--experimental-permission` on Node 20), the child is denied filesystem\n * access outside its own temp dir, child processes, workers, and native\n * addons. Outbound network from the child is NOT blocked by the permission\n * model; the env scrub means such requests carry no credentials, and all\n * authenticated calls must go through the bridge (which applies the\n * registered tools' host allowlists and SSRF guards).\n *\n * The actual execution is delegated to a pluggable `SandboxAdapter` (see\n * `./sandbox`). The default `LocalChildProcessAdapter` preserves the spawned\n * child-process behavior described above; a remote/durable adapter can be\n * plugged in via `registerSandboxAdapter()` / `AGENT_NATIVE_SANDBOX` without\n * changing this file. The bridge, env scrub, module building, and output\n * formatting stay here in the parent regardless of adapter.\n */\n\nimport crypto from \"node:crypto\";\nimport http from \"node:http\";\n\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport type { ActionRunContext } from \"../action.js\";\nimport { getSandboxAdapter } from \"./sandbox/index.js\";\n\nconst DEFAULT_TIMEOUT_MS = 120_000;\nconst MAX_TIMEOUT_MS = 600_000;\nconst DEFAULT_MAX_OUTPUT_CHARS = 50_000;\nconst MAX_OUTPUT_CHARS = 200_000;\n/** Hard cap on bridge request bodies so sandboxed code can't exhaust parent memory. */\nconst BRIDGE_MAX_BODY_BYTES = 10 * 1024 * 1024;\n\n/** Tools callable via the sandbox bridge by default. */\nconst DEFAULT_BRIDGE_TOOLS = new Set([\n \"provider-api-request\",\n \"provider-api-docs\",\n \"provider-api-catalog\",\n \"web-request\",\n \"workspace-files\",\n]);\n\nexport interface RunCodeOptions {\n /**\n * Extra tool names (beyond the default set) that the sandbox bridge will\n * forward to the registered action registry.\n */\n bridgeTools?: string[];\n}\n\n/**\n * Create a `run-code` ActionEntry.\n *\n * @param getActions Supplier that returns the current action registry (called\n * at invocation time so updates are reflected).\n * @param opts Optional configuration.\n */\nexport function createRunCodeEntry(\n getActions: () => Record<string, ActionEntry>,\n opts: RunCodeOptions = {},\n): ActionEntry {\n const extraBridgeTools = new Set(opts.bridgeTools ?? []);\n\n return {\n readOnly: true,\n // Allow a generous per-call timeout so large data-processing jobs don't hit\n // the agent-loop's default 60 s cap.\n timeoutMs: MAX_TIMEOUT_MS,\n maxResultChars: MAX_OUTPUT_CHARS,\n tool: {\n description: [\n \"Execute JavaScript (Node.js, ESM, top-level await supported) in an isolated sandbox.\",\n \"Use this to fetch, join, aggregate, and reduce large datasets, returning only printed output to the conversation.\",\n \"The sandbox runs with a scrubbed environment (no secrets) and, where the Node permission model is available, no filesystem access outside its own temp dir, no child processes, and no workers. Authenticated calls must go through the provided globals; direct network requests carry no credentials. Note: isolation is process-level (env scrub + Node permission model), not an OS-level container — outbound network from sandbox code is not blocked.\",\n \"Available globals:\",\n \" - `appAction(name, args?)` — call any registered agent-exposed read-only app action/tool and get its parsed result.\",\n \" Use this to loop over app data readers and compose multi-source analyses without forcing every intermediate result into chat.\",\n \" - `providerFetch(provider, path, init?)` — authenticated call to a registered provider via the provider-api-request action.\",\n \" Returns the parsed JSON result (or throws on error).\",\n \" Supports stageAs/saveToFile/fetchAllPages; use cursorBodyPath for POST-body pagination.\",\n \" Example: `const data = await providerFetch('<provider-id>', '/records', { query: { limit: 100 } });`\",\n \" - `providerRequest(provider, path, init?)` — same authenticated call, but returns the full provider-api envelope with request, response status/headers, truncation, and body metadata.\",\n \" - `providerFetchAll(provider, path, init?)` — generic pagination helper for cursor, page, and offset APIs. Pass `pagination: { itemsPath, cursorPath or nextCursorPath, cursorParam or cursorBodyPath, pageParam, offsetParam, pageSize, maxPages }`. Returns `{ items, pages, pageCount, itemCount, hasMore, lastCursor, stoppedReason }`.\",\n \" - `providerSearchAll(provider, path, init?, options?)` — streaming search helper for broad provider corpora such as transcripts, messages, tickets, issues, notes, events, or documents. Use this before hand-written loops when searching many provider records for terms/phrases/regexes or proving absence. Pass the same `pagination` config as `providerFetchAll`, plus options like `{ query, queries, terms, regex, textPaths, idPaths, metadataPaths, maxHits }`. Returns structured hits with item ids, paths, snippets, page/item indexes, and coverage fields (`pageCount`, `itemCount`, `hasMore`, `stoppedReason`).\",\n \" - `webFetch(url, init?)` — outbound HTTP request via the web-request action.\",\n \" Returns `{ status, body }` where body is the response text. Supports responseMode, extract, includeLinks, search, maxChars, and saveToFile.\",\n \" Example: `const { body } = await webFetch('https://api.example.com/data', { responseMode: 'raw' });`\",\n \" - `webRead(url, init?)` — convenience wrapper for webFetch with `responseMode: 'auto'` and extracted HTML/markdown or bounded matches.\",\n \" Example: `const docs = await webRead('https://docs.example.com/api', { search: { query: 'pagination' } });`\",\n \" - `workspaceRead(path, opts?)` — read a Resources-backed workspace file by path. Returns content string or null. opts: { offset?, maxChars? }.\",\n \" - `workspaceReadMeta(path, opts?)` — read a workspace file with metadata such as sizeBytes, truncated, and nextOffset.\",\n \" - `workspaceWrite(path, content, contentType?)` — create or overwrite a workspace file. Use `scratch/...` for temporary staging; use durable folders only for files the user should keep.\",\n \" - `workspaceAppend(path, content)` — append text to a workspace file.\",\n \" - `workspaceList(prefix?)` — list workspace files, returns [{ path, sizeBytes, contentType, updatedAt }].\",\n \"Print results with `console.log()`; only stdout+stderr are returned.\",\n \"Timeout defaults to 120 s (max 600 s). Output is truncated to 50 000 chars by default (max 200 000).\",\n ].join(\" \"),\n parameters: {\n type: \"object\",\n properties: {\n code: {\n type: \"string\",\n description:\n \"JavaScript source to execute. ESM syntax, top-level await allowed.\",\n },\n timeoutMs: {\n type: \"number\",\n description: `Execution timeout in milliseconds. Default: ${DEFAULT_TIMEOUT_MS}. Max: ${MAX_TIMEOUT_MS}.`,\n },\n maxOutputChars: {\n type: \"number\",\n description: `Maximum combined stdout+stderr characters to return. Default: ${DEFAULT_MAX_OUTPUT_CHARS}. Max: ${MAX_OUTPUT_CHARS}.`,\n },\n },\n required: [\"code\"],\n },\n },\n run: async (args: Record<string, string>, context?: ActionRunContext) => {\n const code = typeof args.code === \"string\" ? args.code : \"\";\n if (!code.trim()) return \"Error: code is required.\";\n\n const requestedTimeout = Number(args.timeoutMs);\n const timeoutMs =\n Number.isFinite(requestedTimeout) && requestedTimeout > 0\n ? Math.min(requestedTimeout, MAX_TIMEOUT_MS)\n : DEFAULT_TIMEOUT_MS;\n\n const requestedMaxOutput = Number(args.maxOutputChars);\n const maxOutputChars =\n Number.isFinite(requestedMaxOutput) && requestedMaxOutput > 0\n ? Math.min(requestedMaxOutput, MAX_OUTPUT_CHARS)\n : DEFAULT_MAX_OUTPUT_CHARS;\n\n const actions = getActions();\n const bridgeToken = crypto.randomBytes(32).toString(\"hex\");\n\n // Start bridge server — resolves once the server is listening.\n const {\n bridgePort,\n getUsedTools,\n cleanup: cleanupBridge,\n } = await startBridgeServer(\n bridgeToken,\n actions,\n context,\n DEFAULT_BRIDGE_TOOLS,\n extraBridgeTools,\n );\n\n try {\n // Build scrubbed env — only safe POSIX vars, no secrets. The adapter\n // points TMPDIR/TEMP/TMP at the sandbox's own temp dir.\n const safeEnv: Record<string, string> = {};\n for (const key of [\n \"PATH\",\n \"HOME\",\n \"TMPDIR\",\n \"TEMP\",\n \"TMP\",\n \"LANG\",\n \"LC_ALL\",\n ]) {\n if (process.env[key]) safeEnv[key] = process.env[key]!;\n }\n\n // Delegate execution to the active sandbox adapter (local child process\n // by default; remote/durable adapters can be registered via\n // ./sandbox). The bridge, env scrub, module, and output formatting stay\n // in the parent regardless of adapter.\n const { stdout, stderr, exitCode, timedOut } =\n await getSandboxAdapter().run({\n moduleSource: buildSandboxModule(code, bridgePort, bridgeToken),\n env: safeEnv,\n timeoutMs,\n bridgePort,\n });\n\n const combined =\n [\n stdout ? `stdout:\\n${stdout}` : \"\",\n stderr ? `stderr:\\n${stderr}` : \"\",\n ]\n .filter(Boolean)\n .join(\"\\n\\n\") || \"(no output)\";\n\n const lines: string[] = [];\n if (timedOut) lines.push(`timedOut: true (${timeoutMs}ms)`);\n if (exitCode !== 0 && exitCode !== null)\n lines.push(`exitCode: ${exitCode}`);\n const usedTools = getUsedTools();\n if (usedTools.length)\n lines.push(`bridgeToolsUsed: ${usedTools.join(\", \")}`);\n lines.push(combined);\n\n const full = lines.join(\"\\n\\n\");\n if (full.length > maxOutputChars) {\n const truncated = full.slice(0, maxOutputChars);\n return `${truncated}\\n\\n...[truncated ${(full.length - maxOutputChars).toLocaleString()} chars]`;\n }\n return full;\n } finally {\n // The active sandbox adapter owns its own temp-file cleanup; the parent\n // only tears down the bridge server here.\n cleanupBridge();\n }\n },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Bridge server\n// ---------------------------------------------------------------------------\n\ninterface BridgeResult {\n server: http.Server;\n bridgePort: number;\n getUsedTools: () => string[];\n cleanup: () => void;\n}\n\nasync function startBridgeServer(\n token: string,\n actions: Record<string, ActionEntry>,\n context: ActionRunContext | undefined,\n defaultTools: Set<string>,\n extraTools: Set<string>,\n): Promise<BridgeResult> {\n const usedTools = new Set<string>();\n const server = http.createServer((req, res) => {\n if (req.method !== \"POST\" || req.url !== \"/tool\") {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n // Validate bearer token — must match exactly.\n const authHeader = req.headers.authorization ?? \"\";\n if (authHeader !== `Bearer ${token}`) {\n res.writeHead(401);\n res.end(\"Unauthorized\");\n return;\n }\n\n let body = \"\";\n let receivedBytes = 0;\n let rejected = false;\n req.on(\"data\", (chunk: Buffer) => {\n receivedBytes += chunk.length;\n if (receivedBytes > BRIDGE_MAX_BODY_BYTES) {\n rejected = true;\n res.writeHead(413);\n res.end(\"Payload too large\");\n req.destroy();\n return;\n }\n body += chunk.toString();\n });\n req.on(\"end\", () => {\n if (rejected) return;\n handleBridgeRequest(\n body,\n actions,\n context,\n defaultTools,\n extraTools,\n usedTools,\n res,\n );\n });\n req.on(\"error\", () => {\n res.writeHead(500);\n res.end(\"Request error\");\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, \"127.0.0.1\", () => resolve());\n });\n\n const addr = server.address() as { port: number };\n const bridgePort = addr.port;\n\n const cleanup = () => {\n try {\n server.close();\n } catch {}\n };\n\n return {\n server,\n bridgePort,\n getUsedTools: () => Array.from(usedTools).sort(),\n cleanup,\n };\n}\n\nfunction handleBridgeRequest(\n rawBody: string,\n actions: Record<string, ActionEntry>,\n context: ActionRunContext | undefined,\n defaultTools: Set<string>,\n extraTools: Set<string>,\n usedTools: Set<string>,\n res: http.ServerResponse,\n): void {\n let parsed: { tool?: string; args?: Record<string, string> };\n try {\n parsed = JSON.parse(rawBody);\n } catch {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Invalid JSON body\" }));\n return;\n }\n\n const toolName = typeof parsed.tool === \"string\" ? parsed.tool.trim() : \"\";\n if (!toolName) {\n res.writeHead(400, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: \"Missing tool name\" }));\n return;\n }\n\n // Enforce allowlist.\n const entry = actions[toolName];\n const isReadOnlyAction =\n entry?.readOnly === true &&\n entry.agentTool !== false &&\n entry.toolCallable !== false;\n if (\n !defaultTools.has(toolName) &&\n !extraTools.has(toolName) &&\n !isReadOnlyAction\n ) {\n res.writeHead(403, { \"Content-Type\": \"application/json\" });\n res.end(\n JSON.stringify({\n error: `Tool \"${toolName}\" is not an agent-exposed read-only action or sandbox bridge allowlisted tool.`,\n }),\n );\n return;\n }\n\n if (!entry) {\n res.writeHead(404, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: `Tool \"${toolName}\" is not registered.` }));\n return;\n }\n\n const toolArgs = parsed.args ?? {};\n usedTools.add(toolName);\n // Run the tool with the parent request context so auth/org/owner resolution\n // works exactly as it does in the normal agent loop.\n entry\n .run(toolArgs, context)\n .then((result: unknown) => {\n const body =\n typeof result === \"string\" ? result : JSON.stringify(result, null, 2);\n res.writeHead(200, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ result: body }));\n })\n .catch((err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n res.writeHead(500, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify({ error: message }));\n });\n}\n\n// ---------------------------------------------------------------------------\n// Sandbox module template\n// ---------------------------------------------------------------------------\n\n/**\n * Wrap the user's code in an ESM module that:\n * 1. Defines `providerFetch`, `providerRequest`, `providerFetchAll`,\n * `providerSearchAll`, and `webFetch` helpers via the bridge.\n * 2. Runs the user's code as top-level await in an async IIFE.\n */\nfunction buildSandboxModule(\n userCode: string,\n bridgePort: number,\n bridgeToken: string,\n): string {\n return `\nimport { createRequire } from \"node:module\";\nconst require = createRequire(import.meta.url);\n\nconst _bridgeBase = \"http://127.0.0.1:${bridgePort}/tool\";\nconst _bridgeToken = \"${bridgeToken}\";\n\nasync function _bridgeCall(tool, args) {\n const http = await import(\"node:http\");\n return new Promise((resolve, reject) => {\n const body = JSON.stringify({ tool, args });\n const options = {\n hostname: \"127.0.0.1\",\n port: ${bridgePort},\n path: \"/tool\",\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"Content-Length\": Buffer.byteLength(body),\n \"Authorization\": \"Bearer \" + _bridgeToken,\n },\n };\n const req = http.request(options, (res) => {\n let data = \"\";\n res.on(\"data\", (chunk) => { data += chunk; });\n res.on(\"end\", () => {\n try {\n const parsed = JSON.parse(data);\n if (parsed.error) {\n reject(new Error(parsed.error));\n } else {\n resolve(parsed.result);\n }\n } catch (e) {\n reject(new Error(\"Bridge response parse error: \" + e.message));\n }\n });\n });\n req.on(\"error\", reject);\n req.end(body);\n });\n}\n\nfunction _parseBridgeResult(rawResult) {\n if (typeof rawResult !== \"string\") return rawResult;\n try { return JSON.parse(rawResult); } catch { return rawResult; }\n}\n\n/**\n * Call any registered agent-exposed read-only app action/tool via the sandbox bridge.\n * Mutating and explicitly hidden actions are blocked by the parent bridge.\n */\nasync function appAction(name, args = {}) {\n return _parseBridgeResult(await _bridgeCall(name, args));\n}\n\nasync function providerRequest(provider, apiPath, init = {}) {\n const method = (init.method || \"GET\").toUpperCase();\n const rawResult = await _bridgeCall(\"provider-api-request\", {\n provider,\n path: apiPath,\n method,\n ...(init.query ? { query: init.query } : {}),\n ...(init.body ? { body: init.body } : {}),\n ...(init.headers ? { headers: init.headers } : {}),\n ...(init.auth ? { auth: init.auth } : {}),\n ...(init.connectionId ? { connectionId: init.connectionId } : {}),\n ...(init.accountId ? { accountId: init.accountId } : {}),\n ...(init.timeoutMs ? { timeoutMs: init.timeoutMs } : {}),\n ...(init.maxBytes ? { maxBytes: init.maxBytes } : {}),\n ...(init.stageAs ? { stageAs: init.stageAs } : {}),\n ...(init.itemsPath ? { itemsPath: init.itemsPath } : {}),\n ...(init.pagination ? { pagination: init.pagination } : {}),\n ...(init.saveToFile ? { saveToFile: init.saveToFile } : {}),\n ...(init.fetchAllPages ? { fetchAllPages: init.fetchAllPages } : {}),\n });\n return _parseBridgeResult(rawResult);\n}\n\n/**\n * Call a provider API via the authenticated provider-api-request action.\n * Returns the parsed JSON response body (or throws on error).\n */\nasync function providerFetch(provider, apiPath, init = {}) {\n const parsed = await providerRequest(provider, apiPath, init);\n // Unwrap the provider-api-request envelope ({ provider, request, response, guidance })\n // so callers get the actual response body. fetchAllPages / saveToFile results\n // (which have no \\`response\\` field) are returned as-is.\n if (parsed && typeof parsed === \"object\" && parsed.response && typeof parsed.response === \"object\") {\n const r = parsed.response;\n if (typeof r.status === \"number\" && r.status >= 400) {\n const detail = typeof r.text === \"string\" ? r.text : JSON.stringify(r.json ?? \"\");\n throw new Error(\\`Provider request failed (\\${r.status}): \\${String(detail).slice(0, 500)}\\`);\n }\n return r.json !== undefined ? r.json : r.text;\n }\n return parsed;\n}\n\nfunction _cloneJson(value) {\n if (value === undefined || value === null) return value;\n return JSON.parse(JSON.stringify(value));\n}\n\nfunction _pathParts(path) {\n if (!path || typeof path !== \"string\") return [];\n return path\n .replace(/\\\\[(\\\\d+)\\\\]/g, \".$1\")\n .split(\".\")\n .map((part) => part.trim())\n .filter(Boolean);\n}\n\nfunction _getByPath(value, path) {\n let current = value;\n for (const part of _pathParts(path)) {\n if (current === undefined || current === null) return undefined;\n current = current[part];\n }\n return current;\n}\n\nfunction _setByPath(value, path, nextValue) {\n const parts = _pathParts(path);\n if (!parts.length) return value;\n const root = value && typeof value === \"object\" ? _cloneJson(value) : {};\n let current = root;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (!current[part] || typeof current[part] !== \"object\") current[part] = {};\n current = current[part];\n }\n current[parts[parts.length - 1]] = nextValue;\n return root;\n}\n\nfunction _extractItems(page, itemsPath) {\n if (itemsPath) {\n const value = _getByPath(page, itemsPath);\n return Array.isArray(value) ? value : [];\n }\n if (Array.isArray(page)) return page;\n if (!page || typeof page !== \"object\") return [];\n for (const key of [\"data\", \"results\", \"items\", \"records\", \"rows\", \"calls\", \"callTranscripts\", \"transcripts\", \"messages\", \"tickets\", \"issues\", \"deals\", \"events\", \"notes\", \"documents\", \"entries\", \"objects\"]) {\n if (Array.isArray(page[key])) return page[key];\n }\n return [];\n}\n\nfunction _withoutProviderFetchAllOptions(init) {\n const {\n pagination: _pagination,\n fetchAllPages: _fetchAllPages,\n stageAs: _stageAs,\n itemsPath: _itemsPath,\n saveToFile: _saveToFile,\n ...rest\n } = init || {};\n return rest;\n}\n\nfunction _asArray(value) {\n if (value === undefined || value === null) return [];\n return Array.isArray(value) ? value : [value];\n}\n\nfunction _stringifySearchValue(value) {\n if (typeof value === \"string\") return value;\n if (value === undefined || value === null) return \"\";\n if (typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\") {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nfunction _collectStrings(value, basePath = \"\", out = [], limit = 5000) {\n if (out.length >= limit || value === undefined || value === null) return out;\n if (typeof value === \"string\" || typeof value === \"number\" || typeof value === \"boolean\" || typeof value === \"bigint\") {\n out.push({ path: basePath || \"$\", text: String(value) });\n return out;\n }\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length && out.length < limit; i++) {\n _collectStrings(value[i], basePath ? basePath + \"[\" + i + \"]\" : \"[\" + i + \"]\", out, limit);\n }\n return out;\n }\n if (typeof value === \"object\") {\n for (const key of Object.keys(value)) {\n if (out.length >= limit) break;\n _collectStrings(value[key], basePath ? basePath + \".\" + key : key, out, limit);\n }\n }\n return out;\n}\n\nfunction _collectSearchStrings(item, textPaths, maxFieldsPerItem) {\n const paths = _asArray(textPaths).filter((path) => typeof path === \"string\" && path.trim());\n if (!paths.length) return _collectStrings(item, \"\", [], maxFieldsPerItem);\n const out = [];\n for (const path of paths) {\n const value = _getByPath(item, path);\n if (value !== undefined) _collectStrings(value, path, out, maxFieldsPerItem);\n if (out.length >= maxFieldsPerItem) break;\n }\n return out;\n}\n\nfunction _firstValueByPath(value, paths) {\n for (const path of paths) {\n const found = _getByPath(value, path);\n if (found !== undefined && found !== null && String(found) !== \"\") {\n return { path, value: found };\n }\n }\n return null;\n}\n\nconst _DEFAULT_ID_PATHS = [\n \"id\",\n \"callId\",\n \"callID\",\n \"call_id\",\n \"call.id\",\n \"call.metaData.id\",\n \"metaData.id\",\n \"metadata.id\",\n \"recordId\",\n \"record_id\",\n \"objectId\",\n \"object_id\",\n \"ticketId\",\n \"ticket_id\",\n \"issueId\",\n \"issue_id\",\n \"messageId\",\n \"message_id\",\n \"conversationId\",\n \"conversation_id\",\n \"eventId\",\n \"event_id\",\n \"documentId\",\n \"document_id\",\n \"url\",\n \"webUrl\",\n \"permalink\",\n];\n\nfunction _extractItemIdentity(item, idPaths) {\n const paths = [\n ..._asArray(idPaths).filter((path) => typeof path === \"string\" && path.trim()),\n ..._DEFAULT_ID_PATHS,\n ];\n const found = _firstValueByPath(item, paths);\n if (!found) return { id: null, idPath: null };\n return { id: _stringifySearchValue(found.value), idPath: found.path };\n}\n\nfunction _extractMetadata(item, metadataPaths) {\n const metadata = {};\n for (const path of _asArray(metadataPaths)) {\n if (typeof path !== \"string\" || !path.trim()) continue;\n const value = _getByPath(item, path);\n if (value !== undefined) metadata[path] = value;\n }\n return metadata;\n}\n\nfunction _makeSnippet(text, index, contextChars) {\n const source = String(text);\n const context = Math.max(20, Math.min(Number(contextChars) || 180, 1000));\n const start = Math.max(0, index - context);\n const end = Math.min(source.length, Math.max(index, 0) + context);\n const prefix = start > 0 ? \"...\" : \"\";\n const suffix = end < source.length ? \"...\" : \"\";\n return (prefix + source.slice(start, end) + suffix).replace(/\\\\s+/g, \" \").trim();\n}\n\nfunction _normalizeFlags(flags, caseSensitive) {\n const raw = typeof flags === \"string\" ? flags : \"\";\n const allowed = raw.replace(/[^dgimsuvy]/g, \"\");\n const withoutGlobalOrSticky = allowed.replace(/[gy]/g, \"\");\n const withCase =\n caseSensitive || /i/.test(withoutGlobalOrSticky)\n ? withoutGlobalOrSticky\n : withoutGlobalOrSticky + \"i\";\n return withCase + \"g\";\n}\n\nfunction _normalizedSearchTerms(options) {\n const explicitTerms = _asArray(options.terms)\n .map((term) => String(term).trim())\n .filter(Boolean);\n if (explicitTerms.length) return explicitTerms;\n if (options.matchMode === \"allTerms\" && typeof options.query === \"string\") {\n return options.query\n .split(/\\\\s+/)\n .map((term) => term.trim())\n .filter(Boolean);\n }\n return [];\n}\n\nfunction _findItemWideTermMatch(fields, options) {\n const terms = _normalizedSearchTerms(options);\n if (!terms.length || options.matchMode === \"anyTerm\") return null;\n const caseSensitive = Boolean(options.caseSensitive);\n const normalizedFields = fields.map((field) => ({\n field,\n haystack: caseSensitive ? String(field.text) : String(field.text).toLowerCase(),\n }));\n const termHits = terms.map((term) => {\n const searchTerm = caseSensitive ? term : term.toLowerCase();\n for (const entry of normalizedFields) {\n const index = entry.haystack.indexOf(searchTerm);\n if (index >= 0) return { term, field: entry.field, index };\n }\n return { term, field: null, index: -1 };\n });\n if (termHits.some((hit) => hit.index < 0 || !hit.field)) return null;\n const first = termHits\n .filter((hit) => hit.field)\n .sort((a, b) => {\n const fieldOrder = fields.indexOf(a.field) - fields.indexOf(b.field);\n return fieldOrder || a.index - b.index;\n })[0];\n return {\n field: first.field,\n match: {\n kind: \"allTerms\",\n query: terms.join(\" \"),\n index: first.index,\n match: first.term,\n },\n };\n}\n\nfunction _findSearchMatches(text, options, includeTerms = true) {\n const source = String(text);\n const caseSensitive = Boolean(options.caseSensitive);\n const haystack = caseSensitive ? source : source.toLowerCase();\n const maxMatchesPerField = _boundedNumber(options.maxMatchesPerField, 1000, 1, 100000);\n const matches = [];\n\n const addSubstring = (needle, label, kind) => {\n if (needle === undefined || needle === null) return;\n const rawNeedle = String(needle);\n if (!rawNeedle) return;\n const searchNeedle = caseSensitive ? rawNeedle : rawNeedle.toLowerCase();\n let from = 0;\n while (from <= haystack.length) {\n const index = haystack.indexOf(searchNeedle, from);\n if (index < 0) break;\n matches.push({ kind, query: label ?? rawNeedle, index, match: source.slice(index, index + rawNeedle.length) });\n from = index + Math.max(1, searchNeedle.length);\n if (matches.length >= maxMatchesPerField) break;\n }\n };\n\n if (options.regex) {\n try {\n const regex = new RegExp(String(options.regex), _normalizeFlags(options.regexFlags, caseSensitive));\n let match;\n while ((match = regex.exec(source)) && typeof match.index === \"number\") {\n matches.push({ kind: \"regex\", query: String(options.regex), index: match.index, match: match[0] });\n if (matches.length >= maxMatchesPerField) break;\n if (match[0] === \"\") regex.lastIndex += 1;\n }\n } catch (err) {\n throw new Error(\"providerSearchAll invalid regex: \" + (err?.message || err));\n }\n }\n\n for (const query of _asArray(options.query).concat(_asArray(options.queries))) {\n addSubstring(query, String(query), \"query\");\n }\n\n const terms = includeTerms ? _normalizedSearchTerms(options) : [];\n if (terms.length) {\n const termHits = terms\n .map((term) => {\n const searchTerm = caseSensitive ? term : term.toLowerCase();\n const index = haystack.indexOf(searchTerm);\n return { term, index };\n })\n .filter((hit) => hit.index >= 0);\n const mode = options.matchMode === \"anyTerm\" ? \"anyTerm\" : \"allTerms\";\n if ((mode === \"allTerms\" && termHits.length === terms.length) || (mode === \"anyTerm\" && termHits.length > 0)) {\n const first = termHits.sort((a, b) => a.index - b.index)[0];\n matches.push({ kind: mode, query: terms.join(\" \"), index: first.index, match: first.term });\n }\n }\n\n return matches.sort((a, b) => a.index - b.index);\n}\n\nfunction _boundedNumber(value, defaultValue, min, max) {\n const parsed = Number(value);\n const finite = Number.isFinite(parsed) ? parsed : defaultValue;\n return Math.max(min, Math.min(finite, max));\n}\n\nfunction _hitKey(identity, path, query, index, pageIndex, pageItemIndex) {\n const itemKey =\n identity.id !== null && identity.id !== undefined\n ? \"id:\" + identity.id\n : \"page:\" + String(pageIndex) + \":\" + String(pageItemIndex);\n return [itemKey, path ?? \"\", query ?? \"\", String(index ?? \"\")].join(\"\\\\n\");\n}\n\n/**\n * Stream pages from a provider API and search item text structurally. This is\n * for broad mention searches and absence checks where keeping every raw page\n * in memory or hand-parsing JSON strings is brittle.\n */\nasync function providerSearchAll(provider, apiPath, init = {}, options = {}) {\n const pagination = init.pagination || init.fetchAllPages || {};\n const itemsPath = pagination.itemsPath || init.itemsPath || options.itemsPath;\n const cursorPath = pagination.nextCursorPath || pagination.cursorPath;\n const maxPagesRaw = Number(pagination.maxPages || init.maxPages || options.maxPages || 100);\n const maxPages = Math.max(1, Math.min(Number.isFinite(maxPagesRaw) ? maxPagesRaw : 100, 500));\n const maxHits = _boundedNumber(options.maxHits, 100, 1, 5000);\n const maxHitsPerItem = _boundedNumber(options.maxHitsPerItem, 3, 1, 100);\n const maxFieldsPerItem = _boundedNumber(options.maxFieldsPerItem, 5000, 1, 50000);\n const contextChars = options.contextChars ?? options.snippetChars ?? 180;\n const baseInit = _withoutProviderFetchAllOptions(init);\n let query = _cloneJson(init.query || {});\n let body = _cloneJson(init.body);\n let pageNumber = Number(pagination.startPage || 1);\n let offset = Number(pagination.startOffset || 0);\n let lastCursor = null;\n let stoppedReason = \"completed\";\n let itemCount = 0;\n let matchedItemCount = 0;\n let totalHitCount = 0;\n const hits = [];\n const seenHitKeys = new Set();\n let pageIndex = 0;\n\n for (; pageIndex < maxPages; pageIndex++) {\n if (pagination.pageParam) query = { ...(query || {}), [pagination.pageParam]: pageNumber };\n if (pagination.offsetParam) query = { ...(query || {}), [pagination.offsetParam]: offset };\n\n const page = await providerFetch(provider, apiPath, {\n ...baseInit,\n query,\n ...(body !== undefined ? { body } : {}),\n });\n const nextCursor = cursorPath ? _getByPath(page, cursorPath) : undefined;\n const hasNextCursor =\n nextCursor !== undefined && nextCursor !== null && String(nextCursor) !== \"\";\n if (hasNextCursor && lastCursor !== null && String(nextCursor) === String(lastCursor)) {\n stoppedReason = \"repeated-cursor\";\n break;\n }\n\n const pageItems = _extractItems(page, itemsPath);\n itemCount += pageItems.length;\n\n for (let pageItemIndex = 0; pageItemIndex < pageItems.length; pageItemIndex++) {\n const item = pageItems[pageItemIndex];\n const identity = _extractItemIdentity(item, options.idPaths);\n const metadata = _extractMetadata(item, options.metadataPaths);\n const fields = _collectSearchStrings(item, options.textPaths, maxFieldsPerItem);\n let storedItemHitCount = 0;\n let itemMatched = false;\n\n const addHit = (field, match) => {\n const key = _hitKey(identity, field.path, match.query, match.index, pageIndex, pageItemIndex);\n if (seenHitKeys.has(key)) return false;\n seenHitKeys.add(key);\n totalHitCount += 1;\n if (!itemMatched) {\n matchedItemCount += 1;\n itemMatched = true;\n }\n if (hits.length < maxHits && storedItemHitCount < maxHitsPerItem) {\n storedItemHitCount += 1;\n hits.push({\n id: identity.id,\n idPath: identity.idPath,\n pageIndex,\n pageItemIndex,\n itemIndex: itemCount - pageItems.length + pageItemIndex,\n path: field.path,\n kind: match.kind,\n query: match.query,\n match: match.match,\n snippet: _makeSnippet(field.text, match.index, contextChars),\n ...(Object.keys(metadata).length ? { metadata } : {}),\n });\n }\n return true;\n };\n\n const itemWideTermMatch = _findItemWideTermMatch(fields, options);\n if (itemWideTermMatch) {\n addHit(itemWideTermMatch.field, itemWideTermMatch.match);\n }\n\n for (const field of fields) {\n const fieldMatches = _findSearchMatches(field.text, options, !itemWideTermMatch);\n for (const match of fieldMatches) {\n addHit(field, match);\n }\n }\n }\n\n if (hasNextCursor) {\n lastCursor = nextCursor;\n if (pagination.cursorBodyPath) {\n body = _setByPath(body || {}, pagination.cursorBodyPath, nextCursor);\n } else if (pagination.cursorParam) {\n query = { ...(query || {}), [pagination.cursorParam]: nextCursor };\n } else {\n stoppedReason = \"cursor-found-without-destination\";\n break;\n }\n continue;\n }\n\n lastCursor = null;\n if (pagination.pageParam) {\n if (pageItems.length === 0) {\n stoppedReason = \"empty-page\";\n break;\n }\n pageNumber += 1;\n continue;\n }\n if (pagination.offsetParam) {\n if (pageItems.length === 0) {\n stoppedReason = \"empty-page\";\n break;\n }\n const step = Number(pagination.pageSize || pageItems.length);\n if (!Number.isFinite(step) || step <= 0) {\n stoppedReason = \"invalid-page-size\";\n break;\n }\n offset += step;\n if (pagination.pageSize && pageItems.length < Number(pagination.pageSize)) {\n stoppedReason = \"short-page\";\n break;\n }\n continue;\n }\n\n break;\n }\n\n const pageCount = pageIndex + (pageIndex < maxPages ? 1 : 0);\n const hitPageOrOffsetLimit =\n Boolean(pagination.pageParam || pagination.offsetParam) &&\n stoppedReason === \"completed\" &&\n pageCount >= maxPages;\n const hasMore =\n stoppedReason === \"cursor-found-without-destination\" ||\n (lastCursor !== null && pageCount >= maxPages) || hitPageOrOffsetLimit;\n if (hasMore && stoppedReason === \"completed\") stoppedReason = \"max-pages\";\n\n return {\n hits,\n hitCount: hits.length,\n totalHitCount,\n truncatedHits: totalHitCount > hits.length,\n matchedItemCount,\n itemCount,\n pageCount,\n hasMore,\n lastCursor,\n stoppedReason,\n searched: {\n provider,\n path: apiPath,\n itemsPath: itemsPath || null,\n textPaths: _asArray(options.textPaths),\n idPaths: _asArray(options.idPaths),\n query: options.query ?? null,\n queries: _asArray(options.queries),\n terms: _asArray(options.terms),\n regex: options.regex ?? null,\n matchMode: options.matchMode || (options.terms ? \"allTerms\" : \"query\"),\n caseSensitive: Boolean(options.caseSensitive),\n },\n };\n}\n\n/**\n * Fetch every page from a provider API using generic cursor, page-number, or\n * offset pagination. Prefer this inside run-code when the answer depends on a\n * broad provider corpus rather than a single bounded request.\n */\nasync function providerFetchAll(provider, apiPath, init = {}) {\n const pagination = init.pagination || init.fetchAllPages || {};\n const itemsPath = pagination.itemsPath || init.itemsPath;\n const cursorPath = pagination.nextCursorPath || pagination.cursorPath;\n const maxPagesRaw = Number(pagination.maxPages || init.maxPages || 50);\n const maxPages = Math.max(1, Math.min(Number.isFinite(maxPagesRaw) ? maxPagesRaw : 50, 200));\n const baseInit = _withoutProviderFetchAllOptions(init);\n let query = _cloneJson(init.query || {});\n let body = _cloneJson(init.body);\n let pageNumber = Number(pagination.startPage || 1);\n let offset = Number(pagination.startOffset || 0);\n const pages = [];\n const items = [];\n let lastCursor = null;\n let stoppedReason = \"completed\";\n\n for (let pageIndex = 0; pageIndex < maxPages; pageIndex++) {\n if (pagination.pageParam) {\n query = { ...(query || {}), [pagination.pageParam]: pageNumber };\n }\n if (pagination.offsetParam) {\n query = { ...(query || {}), [pagination.offsetParam]: offset };\n }\n\n const page = await providerFetch(provider, apiPath, {\n ...baseInit,\n query,\n ...(body !== undefined ? { body } : {}),\n });\n pages.push(page);\n const pageItems = _extractItems(page, itemsPath);\n items.push(...pageItems);\n\n const nextCursor = cursorPath ? _getByPath(page, cursorPath) : undefined;\n if (nextCursor !== undefined && nextCursor !== null && String(nextCursor) !== \"\") {\n if (lastCursor !== null && String(nextCursor) === String(lastCursor)) {\n stoppedReason = \"repeated-cursor\";\n break;\n }\n lastCursor = nextCursor;\n if (pagination.cursorBodyPath) {\n body = _setByPath(body || {}, pagination.cursorBodyPath, nextCursor);\n } else if (pagination.cursorParam) {\n query = { ...(query || {}), [pagination.cursorParam]: nextCursor };\n } else {\n stoppedReason = \"cursor-found-without-destination\";\n break;\n }\n continue;\n }\n\n lastCursor = null;\n if (pagination.pageParam) {\n if (pageItems.length === 0) {\n stoppedReason = \"empty-page\";\n break;\n }\n pageNumber += 1;\n continue;\n }\n if (pagination.offsetParam) {\n if (pageItems.length === 0) {\n stoppedReason = \"empty-page\";\n break;\n }\n const step = Number(pagination.pageSize || pageItems.length);\n if (!Number.isFinite(step) || step <= 0) {\n stoppedReason = \"invalid-page-size\";\n break;\n }\n offset += step;\n if (pagination.pageSize && pageItems.length < Number(pagination.pageSize)) {\n stoppedReason = \"short-page\";\n break;\n }\n continue;\n }\n\n break;\n }\n\n const hitPageOrOffsetLimit =\n Boolean(pagination.pageParam || pagination.offsetParam) &&\n stoppedReason === \"completed\" &&\n pages.length >= maxPages;\n const hasMore =\n (lastCursor !== null && pages.length >= maxPages) || hitPageOrOffsetLimit;\n if (hasMore) stoppedReason = \"max-pages\";\n return {\n items,\n pages,\n pageCount: pages.length,\n itemCount: items.length,\n hasMore,\n lastCursor,\n stoppedReason,\n };\n}\n\n/**\n * Make an outbound HTTP request via the web-request action.\n * Returns an object \\`{ status, body }\\` where \\`body\\` is the response text.\n */\nasync function webFetch(url, init = {}) {\n const method = (init.method || \"GET\").toUpperCase();\n const rawResult = await _bridgeCall(\"web-request\", {\n url,\n method,\n ...(init.headers ? { headers: typeof init.headers === \"string\" ? init.headers : JSON.stringify(init.headers) } : {}),\n ...(init.body ? { body: typeof init.body === \"string\" ? init.body : JSON.stringify(init.body) } : {}),\n ...(init.responseMode ? { responseMode: init.responseMode } : {}),\n ...(init.extract ? { extract: init.extract } : {}),\n ...(init.includeLinks !== undefined ? { includeLinks: init.includeLinks } : {}),\n ...(init.search ? { search: init.search } : {}),\n ...(init.maxChars ? { maxChars: init.maxChars } : {}),\n ...(init.saveToFile ? { saveToFile: init.saveToFile } : {}),\n });\n // rawResult is \"HTTP <status> <statusText>\\\\n\\\\n<body>\"\n const statusMatch = typeof rawResult === \"string\" ? rawResult.match(/^HTTP (\\\\d+) [^\\\\n]*\\\\n\\\\n/) : null;\n if (statusMatch) {\n return {\n status: Number(statusMatch[1]),\n body: rawResult.slice(statusMatch[0].length),\n };\n }\n return { status: 0, body: rawResult };\n}\n\nasync function webRead(url, init = {}) {\n return webFetch(url, {\n responseMode: \"auto\",\n includeLinks: true,\n ...init,\n });\n}\n\n/**\n * Read a Resources-backed workspace file by path. Returns the file content as\n * a string, or null if not found.\n * Supports optional offset and maxChars for paging large files.\n */\nasync function workspaceRead(path, opts = {}) {\n const parsed = await workspaceReadMeta(path, opts);\n if (parsed && parsed.ok === false) return null;\n return parsed && typeof parsed.content === \"string\" ? parsed.content : null;\n}\n\n/**\n * Read a workspace file by path and return the full metadata envelope.\n * Use this when offset/maxChars paging or truncation status matters.\n */\nasync function workspaceReadMeta(path, opts = {}) {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"read\",\n path,\n ...(opts.offset !== undefined ? { offset: opts.offset } : {}),\n ...(opts.maxChars !== undefined ? { maxChars: opts.maxChars } : {}),\n });\n return _parseBridgeResult(rawResult);\n}\n\n/**\n * Write (create or overwrite) a workspace file. Use \\`scratch/...\\` for\n * temporary staging files.\n * \\`content\\` must be a string. Returns metadata { path, sizeBytes, updatedAt }.\n */\nasync function workspaceWrite(path, content, contentType = \"text/plain\") {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"write\",\n path,\n content: typeof content === \"string\" ? content : JSON.stringify(content),\n contentType,\n });\n try { return typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult; } catch { return rawResult; }\n}\n\n/**\n * Append text to a workspace file (creates if absent).\n */\nasync function workspaceAppend(path, content) {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"append\",\n path,\n content: typeof content === \"string\" ? content : JSON.stringify(content),\n });\n try { return typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult; } catch { return rawResult; }\n}\n\n/**\n * List workspace files, optionally filtered by path prefix.\n * Returns an array of { path, sizeBytes, contentType, updatedAt }.\n */\nasync function workspaceList(prefix) {\n const rawResult = await _bridgeCall(\"workspace-files\", {\n action: \"list\",\n ...(prefix ? { path: prefix } : {}),\n });\n const parsed = typeof rawResult === \"string\" ? JSON.parse(rawResult) : rawResult;\n if (parsed && Array.isArray(parsed.files)) return parsed.files;\n if (Array.isArray(parsed)) return parsed;\n throw new Error(\"workspaceList: unexpected result shape: \" + JSON.stringify(parsed).slice(0, 200));\n}\n\n// Run user code\n(async () => {\n${userCode}\n})().catch((err) => {\n console.error(\"Unhandled error:\", err?.message ?? String(err));\n process.exit(1);\n});\n`;\n}\n"]}