experimental-a2 0.17.0 → 0.18.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 (211) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +1 -1
  3. package/dist/{actor-DBbe5xeE.d.ts → actor-Bjce9_5U.d.ts} +5 -5
  4. package/dist/{actor-DBbe5xeE.d.ts.map → actor-Bjce9_5U.d.ts.map} +1 -1
  5. package/dist/actor-client.d.ts +1 -1
  6. package/dist/actor-react.d.ts +3 -3
  7. package/dist/actor-react.js +1 -1
  8. package/dist/actor.d.ts +1 -1
  9. package/dist/actor.js +2 -2
  10. package/dist/{ai-UrWfKeuv.js → ai-BpOGm-zB.js} +2 -2
  11. package/dist/{ai-UrWfKeuv.js.map → ai-BpOGm-zB.js.map} +1 -1
  12. package/dist/{ai-vpGtcaCB.d.ts → ai-DrUaMyRt.d.ts} +3 -3
  13. package/dist/{ai-vpGtcaCB.d.ts.map → ai-DrUaMyRt.d.ts.map} +1 -1
  14. package/dist/ai-client.d.ts +2 -2
  15. package/dist/ai-client.js +2 -2
  16. package/dist/ai-fx.browser.d.ts +1 -0
  17. package/dist/ai-fx.browser.js +6 -0
  18. package/dist/ai-fx.browser.js.map +1 -0
  19. package/dist/ai-fx.d.ts +10 -0
  20. package/dist/ai-fx.d.ts.map +1 -0
  21. package/dist/ai-fx.js +634 -0
  22. package/dist/ai-fx.js.map +1 -0
  23. package/dist/ai-harness-BuLh_EYi.js +273 -0
  24. package/dist/ai-harness-BuLh_EYi.js.map +1 -0
  25. package/dist/ai-harness-DvsPeJeB.d.ts +26 -0
  26. package/dist/ai-harness-DvsPeJeB.d.ts.map +1 -0
  27. package/dist/ai-pi.browser.d.ts +1 -0
  28. package/dist/ai-pi.browser.js +6 -0
  29. package/dist/ai-pi.browser.js.map +1 -0
  30. package/dist/ai-pi.d.ts +17 -0
  31. package/dist/ai-pi.d.ts.map +1 -0
  32. package/dist/ai-pi.js +904 -0
  33. package/dist/ai-pi.js.map +1 -0
  34. package/dist/ai-react.d.ts +5 -5
  35. package/dist/ai-react.js +2 -2
  36. package/dist/ai-server.d.ts +47 -25
  37. package/dist/ai-server.d.ts.map +1 -1
  38. package/dist/ai-server.js +106 -37
  39. package/dist/ai-server.js.map +1 -1
  40. package/dist/ai.d.ts +1 -1
  41. package/dist/ai.js +1 -1
  42. package/dist/bounded-cache-CPHWF-8h.js +41 -0
  43. package/dist/bounded-cache-CPHWF-8h.js.map +1 -0
  44. package/dist/{client-COaiaDub.js → client-BReKqwZC.js} +3 -3
  45. package/dist/{client-COaiaDub.js.map → client-BReKqwZC.js.map} +1 -1
  46. package/dist/{client-qRnRUzBS.d.ts → client-h_DKFAjj.d.ts} +3 -3
  47. package/dist/{client-qRnRUzBS.d.ts.map → client-h_DKFAjj.d.ts.map} +1 -1
  48. package/dist/client.d.ts +3 -3
  49. package/dist/client.js +1 -1
  50. package/dist/index.d.ts +5 -5
  51. package/dist/{initial-snapshot-BrLso5x_.d.ts → initial-snapshot-Bx-c0pDP.d.ts} +2 -2
  52. package/dist/{initial-snapshot-BrLso5x_.d.ts.map → initial-snapshot-Bx-c0pDP.d.ts.map} +1 -1
  53. package/dist/{internal-CbVvEwad.js → internal-B2T3U4Rq.js} +8 -2
  54. package/dist/internal-B2T3U4Rq.js.map +1 -0
  55. package/dist/otel.d.ts +1 -1
  56. package/dist/{react-BbJ-g6Uu.d.ts → react-BBXgHWFc.d.ts} +4 -4
  57. package/dist/{react-BbJ-g6Uu.d.ts.map → react-BBXgHWFc.d.ts.map} +1 -1
  58. package/dist/react.d.ts +1 -1
  59. package/dist/react.js +1 -1
  60. package/dist/reducer-BAXc8JyF.js.map +1 -1
  61. package/dist/{reducer-BYu6DT7h.d.ts → reducer-CqA59Q6U.d.ts} +2 -2
  62. package/dist/{reducer-BYu6DT7h.d.ts.map → reducer-CqA59Q6U.d.ts.map} +1 -1
  63. package/dist/scheduler-qstash.d.ts +2 -2
  64. package/dist/scheduler-qstash.js +2 -2
  65. package/dist/scheduler-vercel.d.ts +2 -2
  66. package/dist/scheduler-vercel.js +2 -2
  67. package/dist/{server-Rj64fNvX.js → server-Dw_k_7kO.js} +93 -60
  68. package/dist/server-Dw_k_7kO.js.map +1 -0
  69. package/dist/{server-CGM8WzRG.d.ts → server-En7cbi3v.d.ts} +36 -7
  70. package/dist/server-En7cbi3v.d.ts.map +1 -0
  71. package/dist/server.d.ts +4 -4
  72. package/dist/server.js +1 -1
  73. package/dist/{session-clear-Dshpuhff.d.ts → session-clear-Bo-XTFEy.d.ts} +2 -2
  74. package/dist/session-clear-Bo-XTFEy.d.ts.map +1 -0
  75. package/dist/{store-Gpkq7WBo.d.ts → store-Djdv0bnZ.d.ts} +31 -2
  76. package/dist/store-Djdv0bnZ.d.ts.map +1 -0
  77. package/dist/store-N8PXxDAS.js.map +1 -1
  78. package/dist/store-memory.d.ts +1 -1
  79. package/dist/store-memory.js +32 -6
  80. package/dist/store-memory.js.map +1 -1
  81. package/dist/{store-polling-4_y8lETm.js → store-polling-B5FcwJfo.js} +2 -2
  82. package/dist/{store-polling-4_y8lETm.js.map → store-polling-B5FcwJfo.js.map} +1 -1
  83. package/dist/store-postgres.d.ts +1 -1
  84. package/dist/store-postgres.js +54 -3
  85. package/dist/store-postgres.js.map +1 -1
  86. package/dist/{store-presence-polling-Q1C-k2dd.js → store-presence-polling-BAwS8RWn.js} +3 -3
  87. package/dist/{store-presence-polling-Q1C-k2dd.js.map → store-presence-polling-BAwS8RWn.js.map} +1 -1
  88. package/dist/store-redis-http.d.ts +1 -1
  89. package/dist/store-redis-http.js +3 -3
  90. package/dist/{store-redis-notify-tqWNnMRu.js → store-redis-notify-BRITti_o.js} +187 -68
  91. package/dist/store-redis-notify-BRITti_o.js.map +1 -0
  92. package/dist/store-redis.d.ts +1 -1
  93. package/dist/store-redis.js +1 -1
  94. package/dist/store-sqlite.d.ts +1 -1
  95. package/dist/store-sqlite.js +32 -2
  96. package/dist/store-sqlite.js.map +1 -1
  97. package/dist/{telemetry-cZH-cibj.d.ts → telemetry-Cyfqo6Qt.d.ts} +2 -2
  98. package/dist/telemetry-Cyfqo6Qt.d.ts.map +1 -0
  99. package/dist/{wire-DjfHOvdW.js → wire-rSUglYo8.js} +2 -2
  100. package/dist/{wire-DjfHOvdW.js.map → wire-rSUglYo8.js.map} +1 -1
  101. package/docs/01-quickstart.mdx +49 -83
  102. package/docs/{guides/07-examples.mdx → 02-examples.mdx} +10 -20
  103. package/docs/actors/01-introduction.mdx +48 -86
  104. package/docs/actors/02-concurrency.mdx +43 -70
  105. package/docs/actors/03-timers.mdx +28 -42
  106. package/docs/actors/04-routes.mdx +110 -150
  107. package/docs/actors/meta.ts +1 -1
  108. package/docs/agents/01-introduction.mdx +257 -0
  109. package/docs/agents/02-tools.mdx +247 -0
  110. package/docs/agents/03-conversations.mdx +538 -0
  111. package/docs/agents/04-harnesses.mdx +136 -0
  112. package/docs/agents/meta.ts +1 -0
  113. package/docs/client/01-react.mdx +294 -0
  114. package/docs/client/02-transports.mdx +86 -0
  115. package/docs/client/03-presence.mdx +224 -0
  116. package/docs/client/meta.ts +1 -0
  117. package/docs/contract/01-events.mdx +57 -0
  118. package/docs/contract/02-state.mdx +142 -0
  119. package/docs/contract/03-sessions.mdx +175 -0
  120. package/docs/index.mdx +108 -144
  121. package/docs/reference/01-core.mdx +139 -0
  122. package/docs/reference/02-server.mdx +855 -0
  123. package/docs/reference/03-client.mdx +301 -0
  124. package/docs/reference/04-ai.mdx +722 -0
  125. package/docs/reference/05-adapters.mdx +351 -0
  126. package/docs/reference/06-errors.mdx +138 -0
  127. package/docs/reference/meta.ts +1 -1
  128. package/docs/server/01-handlers.mdx +200 -0
  129. package/docs/server/02-timers.mdx +130 -0
  130. package/docs/server/03-cancellation.mdx +141 -0
  131. package/docs/server/04-routes.mdx +243 -0
  132. package/docs/server/05-production.mdx +322 -0
  133. package/docs/server/06-guarantees.mdx +123 -0
  134. package/examples/playground/DEPLOY.md +1 -1
  135. package/examples/playground/app/a0/[appId]/page.tsx +11 -6
  136. package/examples/playground/app/a0/app-list.tsx +9 -2
  137. package/examples/playground/app/a0/app-view.tsx +9 -1
  138. package/examples/playground/app/a0/apps/[appId]/route.ts +10 -5
  139. package/examples/playground/app/a0/apps.test.ts +12 -0
  140. package/examples/playground/app/a0/apps.ts +22 -7
  141. package/examples/playground/app/a0/chat.tsx +47 -1
  142. package/examples/playground/app/a0/fx/events/route.ts +9 -0
  143. package/examples/playground/app/a0/fx/scheduler/route.ts +7 -0
  144. package/examples/playground/app/a0/fx/short/events/route.ts +11 -0
  145. package/examples/playground/app/a0/model.test.ts +18 -1
  146. package/examples/playground/app/a0/model.ts +47 -10
  147. package/examples/playground/app/a0/no-photon.cjs +4 -0
  148. package/examples/playground/app/a0/no-quickjs.cjs +3 -0
  149. package/examples/playground/app/a0/pi/events/route.ts +9 -0
  150. package/examples/playground/app/a0/pi/scheduler/route.ts +7 -0
  151. package/examples/playground/app/a0/pi/short/events/route.ts +11 -0
  152. package/examples/playground/app/a0/sandbox-log.ts +10 -4
  153. package/examples/playground/app/a0/sandbox-session.ts +152 -0
  154. package/examples/playground/app/a0/scheduler/route.ts +2 -2
  155. package/examples/playground/app/a0/server.ts +100 -45
  156. package/examples/playground/app/a0/session.ts +17 -5
  157. package/examples/playground/app/a0/shell.tsx +11 -3
  158. package/examples/playground/app/agent/ingress.test.ts +6 -3
  159. package/examples/playground/app/agent/server.ts +9 -6
  160. package/examples/playground/app/agent/telemetry.test.ts +71 -50
  161. package/examples/playground/app/canvas/[canvasId]/canvas-client.tsx +1 -1
  162. package/examples/playground/app/chat/server.test.ts +30 -26
  163. package/examples/playground/app/chat/server.ts +46 -46
  164. package/examples/playground/next.config.ts +17 -5
  165. package/examples/playground/package.json +4 -1
  166. package/examples/playground/vercel.json +18 -0
  167. package/package.json +27 -3
  168. package/src/ai-agent.ts +261 -87
  169. package/src/ai-fx.browser.ts +5 -0
  170. package/src/ai-fx.ts +833 -0
  171. package/src/ai-harness.ts +518 -0
  172. package/src/ai-model-metadata.ts +11 -6
  173. package/src/ai-pi.browser.ts +5 -0
  174. package/src/ai-pi.ts +1263 -0
  175. package/src/ai-sdk-step.ts +2 -2
  176. package/src/ai-server.ts +3 -1
  177. package/src/internal.ts +7 -0
  178. package/src/libfx.d.ts +34 -0
  179. package/src/reducer.ts +1 -1
  180. package/src/server.ts +177 -19
  181. package/src/store-memory.ts +42 -7
  182. package/src/store-postgres.ts +80 -0
  183. package/src/store-redis-core.ts +210 -79
  184. package/src/store-redis-notify.ts +2 -0
  185. package/src/store-sqlite.ts +60 -0
  186. package/src/store.ts +33 -0
  187. package/src/telemetry.ts +1 -0
  188. package/dist/internal-CbVvEwad.js.map +0 -1
  189. package/dist/server-CGM8WzRG.d.ts.map +0 -1
  190. package/dist/server-Rj64fNvX.js.map +0 -1
  191. package/dist/session-clear-Dshpuhff.d.ts.map +0 -1
  192. package/dist/store-Gpkq7WBo.d.ts.map +0 -1
  193. package/dist/store-redis-notify-tqWNnMRu.js.map +0 -1
  194. package/dist/telemetry-cZH-cibj.d.ts.map +0 -1
  195. package/docs/concepts/01-contracts.mdx +0 -237
  196. package/docs/concepts/02-handlers.mdx +0 -284
  197. package/docs/concepts/03-durability.mdx +0 -314
  198. package/docs/concepts/04-state.mdx +0 -209
  199. package/docs/guides/01-timers.mdx +0 -193
  200. package/docs/guides/02-cancellation.mdx +0 -161
  201. package/docs/guides/03-react.mdx +0 -324
  202. package/docs/guides/04-local-first.mdx +0 -47
  203. package/docs/guides/05-production.mdx +0 -534
  204. package/docs/guides/06-ai-agents.mdx +0 -1408
  205. package/docs/guides/08-application-data.mdx +0 -113
  206. package/docs/guides/09-presence.mdx +0 -262
  207. package/docs/guides/10-transports.mdx +0 -221
  208. package/docs/reference/01-api.mdx +0 -2358
  209. package/docs/reference/02-errors.mdx +0 -150
  210. /package/docs/{concepts → contract}/meta.ts +0 -0
  211. /package/docs/{guides → server}/meta.ts +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-pi.js","names":["readLocalFile"],"sources":["../src/ai-pi.ts"],"sourcesContent":["/**\n * experimental-a2/ai/pi — `pi()`: the Pi harness for `agent({ harness })`.\n * Server-only; Pi comes from the optional `@earendil-works/pi-coding-agent`\n * and `@earendil-works/pi-ai` peer dependencies.\n */\n\n// oxlint-disable no-await-in-loop -- turns replay in order, each on the session the last one left.\n\nimport { createHash } from 'node:crypto'\nimport { readFile as readLocalFile, unlink } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { basename, dirname, join } from 'node:path'\nimport type {\n AssistantMessage,\n AssistantMessageEvent,\n AssistantMessageEventStream,\n JsonObject,\n TextContent,\n ThinkingContent,\n ToolCall,\n Usage,\n} from '@earendil-works/pi-ai'\nimport type {\n AgentSession,\n AgentToolResult,\n BashOperations,\n ModelRuntime,\n ResourceLoader,\n SessionEntry,\n SessionHeader,\n ToolDefinition,\n} from '@earendil-works/pi-coding-agent'\nimport {\n asSchema,\n jsonSchema,\n type Experimental_SandboxSession,\n type FinishReason,\n type JSONSchema7,\n type LanguageModelUsage,\n type Tool,\n type ToolExecutionOptions,\n type ToolSet,\n type UIMessageChunk,\n} from 'ai'\nimport {\n type Deferred,\n defineHarness,\n deferred,\n Divergence,\n gatewayCredential,\n type Harness,\n type HarnessGeneration,\n type HarnessRead,\n type HarnessSandbox,\n type HarnessStep,\n type HarnessTurn,\n pending,\n readHarness,\n type RecordedGeneration,\n saveHarness,\n} from './ai-harness.ts'\nimport type { CompactionPartData, ToolResultPayload } from './ai.ts'\nimport { boundedCache } from './bounded-cache.ts'\nimport { ambientToolScopeStorage } from './internal.ts'\n\nexport type {\n Harness,\n HarnessSandbox,\n HarnessSandboxContext,\n} from './ai-harness.ts'\n\n/** What `pi()` takes. */\nexport type PiOptions = {\n /** The session's sandbox: Pi's tools, and the agent's, work in it. */\n sandbox: HarnessSandbox\n}\n\n/**\n * The Pi harness. Every model call Pi makes is one durable step; A2 rebuilds\n * Pi's session for each step from its latest snapshot and the log since.\n */\nexport function pi(options: PiOptions): Harness<'pi', Builtin> {\n if (typeof options?.sandbox !== 'function')\n throw new TypeError('pi() requires sandbox')\n return defineHarness<'pi', Builtin>('pi', {\n sandbox: options.sandbox,\n tools: builtinTools,\n step: (step) =>\n runStep(step, async () =>\n options.sandbox({\n session: { id: step.sessionId },\n signal: step.signal,\n }),\n ),\n })\n}\n\nconst SNAPSHOT_VERSION = 1\nconst GATEWAY = 'vercel-ai-gateway'\n// The most a file read or a command's output moves from the sandbox to the\n// server. Pi's tools show the model 50 KB at a time, after reading it all.\nconst MAX_TRANSFER_BYTES = 4 * 1024 * 1024\nconst MAX_TRANSFER = '4 MiB'\n// Pi's default tools.\nconst BUILTINS = ['read', 'write', 'edit', 'bash'] as const\ntype Builtin = (typeof BUILTINS)[number]\n\ntype PiModules = {\n agent: typeof import('@earendil-works/pi-coding-agent')\n ai: typeof import('@earendil-works/pi-ai')\n}\n\n/** A content block without the text the transcript already holds. */\ntype StoredBlock =\n | (Omit<TextContent, 'text'> & { ref: string })\n | (Omit<ThinkingContent, 'thinking'> & { ref: string })\n | Omit<ToolCall, 'arguments'>\n\n/** What a step's transcript parts do not hold of Pi's response. */\ntype StoredResponse = Omit<AssistantMessage, 'content'> & {\n content: StoredBlock[]\n}\n\n/** The transient record of one model call, for replay. */\ntype PiRecord =\n | { call: 'step'; response: StoredResponse }\n | { call: 'compaction'; response: AssistantMessage }\n\ntype RecordedCall = {\n kind: 'step' | 'compaction'\n response: AssistantMessage\n /** Steering to queue while serving this call. */\n steers: string[]\n}\n\ntype Saved = {\n cwd: string\n header: SessionHeader\n entries: SessionEntry[]\n}\n\ntype Completion = { finishReason?: FinishReason; usage?: LanguageModelUsage }\n\n/** The turn being replayed or run live, as the model and tool hooks see it. */\ntype TurnState = {\n plan: HarnessTurn\n calls: RecordedCall[]\n next: number\n liveStep: boolean\n /** The live step is over; Pi's run is being stopped. */\n over: boolean\n failure?: Error\n /** Resolves when the live step is over: Pi asked for its tools or another step. */\n stepOver: Deferred\n /** Live compaction responses, in request order. */\n compactions: AssistantMessage[]\n}\n\nfunction endStep(state: TurnState): void {\n state.over = true\n state.stepOver.resolve()\n}\n\nconst diverged = (message: string): Divergence => new Divergence('Pi', message)\n\n// ---------------------------------------------------------------- step\n\nasync function runStep(\n step: HarnessStep,\n sandbox: () => Promise<Experimental_SandboxSession>,\n): Promise<HarnessGeneration> {\n const modules = await loadPi()\n const credential = gatewayCredential('pi')\n const name = `${step.agentName}.a2.harness.pi`\n const { replayAll, ...first } = await readHarness({\n step,\n name,\n parse: savedSession,\n })\n let read: HarnessRead<Saved> = first\n let results = read.results\n const cwd =\n read.saved?.cwd ??\n (await sessionCwd({\n key: cwdKey(step.agentName, step.sessionId),\n sandbox,\n }))\n\n let completion: Completion = {}\n let session: AgentSession | undefined\n let compacting = false\n let turn: TurnState | undefined\n\n const fail = (state: TurnState, error: Error): never => {\n state.failure ??= error\n endStep(state)\n void session?.abort()\n throw state.failure\n }\n\n let controller: ReadableStreamDefaultController<UIMessageChunk> | undefined\n let closed = false\n const emit = (chunk: UIMessageChunk): void => {\n if (!closed) controller!.enqueue(chunk)\n }\n const record = (data: PiRecord): void =>\n emit({ type: 'data-a2-pi', data, transient: true })\n\n // ------------------------------------------------------ model calls\n\n const answer = async (\n out: AssistantMessageEventStream,\n model: Parameters<ModelRuntime['streamSimple']>[0],\n context: Parameters<ModelRuntime['streamSimple']>[1],\n options: Parameters<ModelRuntime['streamSimple']>[2],\n ): Promise<void> => {\n const state = turn!\n if (state.failure) throw state.failure\n // Stopping Pi runs its turn-end hooks; nothing they ask the model counts.\n if (state.over) {\n replay(out, interrupted(model))\n return\n }\n const kind = compacting ? 'compaction' : 'step'\n const recorded = state.calls[state.next]\n if (recorded !== undefined) {\n if (recorded.kind !== kind)\n fail(state, diverged(`call ${state.next} is not a ${kind}`))\n state.next++\n // Steering queued while a response streams enters after its tools.\n for (const text of recorded.steers) await session!.steer(text)\n replay(out, recorded.response)\n return\n }\n if (state.plan.end === 'stop')\n fail(state, diverged('Pi continued a turn the log ended'))\n if (state.plan.end === 'interrupted') {\n replay(out, interrupted(model))\n return\n }\n if (kind === 'step' && state.liveStep) {\n // One generation is one step; the next step is A2's next generation.\n endStep(state)\n replay(out, interrupted(model))\n return\n }\n if (kind === 'step') state.liveStep = true\n const upstream = realStream(model, context, {\n ...options,\n headers: { ...options?.headers, ...gatewayHeaders(credential) },\n })\n const live = kind === 'step' ? liveStep() : undefined\n for await (const event of upstream) {\n live?.(event)\n if (event.type === 'done' || event.type === 'error') {\n const response = event.type === 'done' ? event.message : event.error\n if (kind === 'compaction') state.compactions.push(response)\n // A2 retries the step; Pi's own recovery would run outside it.\n if (event.type === 'error' && event.reason === 'error') {\n state.failure ??= new Error(\n response.errorMessage ?? 'the Pi model call failed',\n )\n endStep(state)\n }\n }\n out.push(event)\n }\n }\n\n /** Streams one live step response as UI chunks and records it. */\n const liveStep = () => {\n const ref = (index: number) => `pi:${step.requestIndex}:${index}`\n const started = new Set<string>()\n return (event: AssistantMessageEvent): void => {\n switch (event.type) {\n case 'start':\n emit({ type: 'start-step' })\n break\n case 'text_start':\n emit({ type: 'text-start', id: ref(event.contentIndex) })\n break\n case 'text_delta':\n emit({\n type: 'text-delta',\n id: ref(event.contentIndex),\n delta: event.delta,\n })\n break\n case 'text_end':\n emit({ type: 'text-end', id: ref(event.contentIndex) })\n break\n case 'thinking_start':\n emit({ type: 'reasoning-start', id: ref(event.contentIndex) })\n break\n case 'thinking_delta':\n emit({\n type: 'reasoning-delta',\n id: ref(event.contentIndex),\n delta: event.delta,\n })\n break\n case 'thinking_end':\n emit({ type: 'reasoning-end', id: ref(event.contentIndex) })\n break\n case 'toolcall_start':\n case 'toolcall_delta': {\n const call = event.partial.content[event.contentIndex] as ToolCall\n if (!call.id) break\n if (!started.has(call.id)) {\n started.add(call.id)\n emit({\n type: 'tool-input-start',\n toolCallId: call.id,\n toolName: call.name,\n })\n }\n if (event.type === 'toolcall_delta')\n emit({\n type: 'tool-input-delta',\n toolCallId: call.id,\n inputTextDelta: event.delta,\n })\n break\n }\n case 'done':\n case 'error': {\n const response = event.type === 'done' ? event.message : event.error\n if (event.type === 'done') {\n for (const block of response.content) {\n if (block.type !== 'toolCall') continue\n if (!started.has(block.id))\n emit({\n type: 'tool-input-start',\n toolCallId: block.id,\n toolName: block.name,\n })\n // Pi does not run the calls of a cut-off response.\n emit(\n response.stopReason === 'length'\n ? {\n type: 'tool-input-error',\n toolCallId: block.id,\n toolName: block.name,\n input: block.arguments,\n errorText:\n 'The response hit the output token limit before this call was complete.',\n }\n : {\n type: 'tool-input-available',\n toolCallId: block.id,\n toolName: block.name,\n input: block.arguments,\n },\n )\n }\n }\n record({ call: 'step', response: storedResponse(response, ref) })\n completion = {\n finishReason: finishReason(response.stopReason),\n usage: modelUsage(response.usage),\n }\n break\n }\n }\n }\n }\n\n // ----------------------------------------------------- tool results\n\n const toolResult = async (\n toolCallId: string,\n signal: AbortSignal | undefined,\n shape: 'pi' | 'tool',\n ): Promise<AgentToolResult<unknown>> => {\n const state = turn!\n if (state.failure) throw state.failure\n const result = results.get(toolCallId)\n if (result !== undefined) return answeredTool(result, shape)\n if (state.plan.end === 'live' && state.liveStep) {\n // Pi now waits on tools that A2's tool handlers run.\n endStep(state)\n return pending(signal)\n }\n if (state.plan.end === 'interrupted') {\n void session!.abort()\n return pending(signal)\n }\n return fail(state, diverged(`no recorded result for ${toolCallId}`))\n }\n\n // ------------------------------------------------------------ run\n\n const runtime = await modules.agent.ModelRuntime.create({\n credentials: new modules.ai.InMemoryCredentialStore(),\n modelsPath: null,\n allowModelNetwork: false,\n refreshOnCreate: false,\n })\n await runtime.setRuntimeApiKey(GATEWAY, credential.token)\n const model = runtime.getModel(GATEWAY, step.model)\n if (model === undefined)\n throw new Error(`Pi does not know the Gateway model ${step.model}`)\n const realStream = runtime.streamSimple.bind(runtime)\n runtime.streamSimple = (requested, context, options?) => {\n const out = modules.ai.createAssistantMessageEventStream()\n answer(out, requested, context, options).catch((error: unknown) => {\n const state = turn\n if (state) state.failure ??= asError(error)\n replay(out, { ...interrupted(requested), stopReason: 'error' })\n })\n return out\n }\n\n const tools = await sessionTools(modules, step.tools, cwd, toolResult)\n\n const createSession = async (from: Saved | undefined) => {\n const sessionManager =\n from === undefined\n ? modules.agent.SessionManager.inMemory(cwd, {\n id: sessionUuid(step.agentName, step.sessionId),\n })\n : modules.agent.SessionManager.inMemory(cwd, { id: from.header.id }, [\n from.header,\n ...from.entries,\n ])\n const created = await modules.agent.createAgentSession({\n cwd,\n // Pi reads nothing there: every resource and manager comes from A2.\n agentDir: join(tmpdir(), 'a2-pi'),\n model,\n ...thinkingLevel(step),\n modelRuntime: runtime,\n resourceLoader: resources(modules, step.instructions),\n sessionManager,\n settingsManager: modules.agent.SettingsManager.inMemory({\n // A2 retries failed steps.\n retry: { enabled: false, maxRetries: 0, baseDelayMs: 0 },\n cacheWarming: 'off',\n }),\n customTools: tools,\n tools: tools.map((definition) => definition.name),\n })\n created.session.subscribe((event) => {\n if (event.type === 'compaction_start') compacting = true\n if (event.type !== 'compaction_end') return\n compacting = false\n const state = turn\n if (state === undefined || state.over || state.compactions.length === 0)\n return\n for (const response of state.compactions.splice(0))\n record({ call: 'compaction', response })\n emit({\n type: 'data-a2-compaction',\n id: `pi-compaction:${step.requestIndex}:${compactions++}`,\n data: compactionData(event),\n })\n })\n return created.session\n }\n let compactions = 0\n\n const saveSnapshot = async (): Promise<void> => {\n const manager = session!.sessionManager\n const header = manager.getHeader()\n const entries = manager.getEntries()\n const last = entries.findLast(\n (entry) => entry.type === 'message' && entry.message.role === 'assistant',\n )\n const stop =\n last?.type === 'message' && last.message.role === 'assistant'\n ? last.message.stopReason\n : undefined\n // Only a turn this attempt finished describes the log.\n if (\n header === null ||\n step.signal.aborted ||\n stop === 'aborted' ||\n stop === 'error'\n )\n return\n await saveHarness({\n step,\n name,\n state: { version: SNAPSHOT_VERSION, cwd, header, entries },\n })\n }\n\n const run = async (): Promise<void> => {\n emit({ type: 'start', messageId: step.responseMessageId })\n try {\n session = await createSession(read.saved)\n } catch (error) {\n if (read.saved === undefined) throw error\n // An unusable snapshot: replay the whole log instead.\n read = await replayAll()\n results = read.results\n session = await createSession(undefined)\n }\n for (const plan of read.turns) {\n if (step.signal.aborted) return\n const state: TurnState = {\n plan,\n calls: recordedTurn(plan),\n next: 0,\n liveStep: false,\n over: false,\n stepOver: deferred(),\n compactions: [],\n }\n turn = state\n const running = session.prompt(plan.prompt, {\n expandPromptTemplates: false,\n })\n if (plan.end !== 'live') {\n await running.catch((error: unknown) => {\n throw state.failure ?? error\n })\n if (state.failure) throw state.failure\n continue\n }\n const ended = await Promise.race([\n running.then(() => true),\n state.stepOver.promise.then(() => false),\n ]).catch((error: unknown) => {\n throw state.failure ?? error\n })\n if (!ended) {\n await session.abort()\n await running.catch(() => {})\n }\n if (state.failure) throw state.failure\n if (ended) await saveSnapshot()\n emit({ type: 'finish-step' })\n emit({\n type: 'finish',\n ...(completion.finishReason === undefined\n ? {}\n : { finishReason: completion.finishReason }),\n })\n }\n }\n\n const stream = new ReadableStream<UIMessageChunk>({\n start(streamController) {\n controller = streamController\n const abort = () => void session?.abort()\n step.signal.addEventListener('abort', abort, { once: true })\n void (async () => {\n try {\n await run()\n closed = true\n streamController.close()\n } catch (error) {\n closed = true\n streamController.error(\n step.signal.aborted ? step.signal.reason : error,\n )\n } finally {\n step.signal.removeEventListener('abort', abort)\n session?.dispose()\n }\n })()\n },\n cancel() {\n closed = true\n void session?.abort()\n },\n })\n\n return { stream, completion: () => completion }\n}\n\n// ------------------------------------------------------------ the plan\n\n/** A turn's recorded model calls, in the order Pi made them. */\nfunction recordedTurn(turn: HarnessTurn): RecordedCall[] {\n const calls: RecordedCall[] = []\n turn.generations.forEach((generation, index) => {\n calls.push(...recordedCalls(generation))\n const steers = turn.steers.get(index)\n const last = calls.findLast((call) => call.kind === 'step')\n if (steers !== undefined && last !== undefined) last.steers.push(...steers)\n })\n return calls\n}\n\nfunction recordedCalls(generation: RecordedGeneration): RecordedCall[] {\n const texts = new Map<string, string>()\n const inputs = new Map<string, unknown>()\n const calls: RecordedCall[] = []\n for (const chunk of generation.chunks) {\n switch (chunk.type) {\n case 'text-delta':\n case 'reasoning-delta':\n texts.set(chunk.id, (texts.get(chunk.id) ?? '') + chunk.delta)\n break\n case 'tool-input-available':\n case 'tool-input-error':\n inputs.set(chunk.toolCallId, chunk.input)\n break\n case 'data-a2-pi': {\n const record = chunk.data as PiRecord\n calls.push({\n kind: record.call,\n response:\n record.call === 'step'\n ? restoredResponse(record.response, texts, inputs)\n : record.response,\n steers: [],\n })\n break\n }\n }\n }\n if (!calls.some((call) => call.kind === 'step'))\n throw diverged('a completed generation has no recorded response')\n return calls\n}\n\nfunction storedResponse(\n response: AssistantMessage,\n ref: (index: number) => string,\n): StoredResponse {\n return {\n ...response,\n content: response.content.map((block, index): StoredBlock => {\n switch (block.type) {\n case 'text': {\n const { text: _, ...rest } = block\n return { ...rest, ref: ref(index) }\n }\n case 'thinking': {\n const { thinking: _, ...rest } = block\n return { ...rest, ref: ref(index) }\n }\n case 'toolCall': {\n const { arguments: _, ...rest } = block\n return rest\n }\n }\n }),\n }\n}\n\nfunction restoredResponse(\n stored: StoredResponse,\n texts: ReadonlyMap<string, string>,\n inputs: ReadonlyMap<string, unknown>,\n): AssistantMessage {\n return {\n ...stored,\n content: stored.content.map((block) => {\n if (block.type === 'toolCall')\n return {\n ...block,\n arguments: (inputs.get(block.id) ?? {}) as JsonObject,\n }\n const { ref, ...rest } = block\n const text = texts.get(ref) ?? ''\n return rest.type === 'text'\n ? { ...rest, text }\n : { ...rest, thinking: text }\n }),\n }\n}\n\n/** Hands a recorded response to Pi's loop. */\nfunction replay(out: AssistantMessageEventStream, response: AssistantMessage) {\n out.push({ type: 'start', partial: response })\n const reason = response.stopReason\n if (reason === 'error' || reason === 'aborted')\n out.push({ type: 'error', reason, error: response })\n else if (reason === 'pending')\n out.push({ type: 'done', reason: 'stop', message: response })\n else out.push({ type: 'done', reason, message: response })\n}\n\n/** The response of a model call that A2 interrupted. */\nfunction interrupted(\n model: Parameters<ModelRuntime['streamSimple']>[0],\n): AssistantMessage {\n return {\n role: 'assistant',\n content: [],\n api: model.api,\n provider: model.provider,\n model: model.id,\n usage: {\n input: 0,\n output: 0,\n cacheRead: 0,\n cacheWrite: 0,\n totalTokens: 0,\n cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n },\n stopReason: 'aborted',\n timestamp: Date.now(),\n }\n}\n\n// ----------------------------------------------------------- the tools\n\nconst builtinTools: ToolSet = Object.fromEntries(\n BUILTINS.map((name): [string, Tool] => [\n name,\n {\n inputSchema: jsonSchema(\n async () =>\n builtinDefinition(await loadPi(), name, '/')\n .parameters as JSONSchema7,\n ),\n execute: (input: unknown, options: ToolExecutionOptions<unknown>) =>\n runBuiltin(name, input, options),\n },\n ]),\n)\n\n/** Runs one of Pi's tools in the session's sandbox, as Pi's loop would. */\nasync function runBuiltin(\n name: Builtin,\n input: unknown,\n options: ToolExecutionOptions<unknown>,\n): Promise<AgentToolResult<unknown>> {\n const sandbox = options.experimental_sandbox\n if (sandbox === undefined)\n throw new Error(`pi() runs ${name} in the agent's sandbox`)\n const modules = await loadPi()\n const scope = ambientToolScopeStorage()?.getStore()\n const event = (scope?.context as { event?: { sessionId?: unknown } })?.event\n const cwd = await sessionCwd({\n key:\n scope?.contract !== undefined && typeof event?.sessionId === 'string'\n ? cwdKey(scope.contract.name, event.sessionId)\n : undefined,\n sandbox: async () => sandbox,\n })\n const definition = builtinDefinition(modules, name, cwd, {\n sandbox,\n signal: options.abortSignal,\n })\n const args: unknown = modules.ai.validateToolArguments(definition, {\n type: 'toolCall',\n id: options.toolCallId,\n name,\n arguments: (definition.prepareArguments?.(input) ?? input) as JsonObject,\n })\n // Pi's bash keeps a long output's full text in a local file, named in its\n // updates and its result. It is removed however the call ends.\n let outputFile: string | undefined\n try {\n const result = await definition.execute(\n options.toolCallId,\n args,\n options.abortSignal,\n (update) => {\n outputFile ??= fullOutputPath(update)\n },\n // Pi's tools take their context from the session, which A2 runs elsewhere.\n undefined as never,\n )\n outputFile ??= fullOutputPath(result)\n return await recordedResult(result, sandbox)\n } catch (error) {\n // Output whose last bytes tip it over Pi's limit opens the file only as\n // it ends, after the last update; a failed call then names it in its error.\n outputFile ??= namedOutputFile(error)\n throw error\n } finally {\n if (outputFile !== undefined) await unlink(outputFile).catch(() => {})\n }\n}\n\ntype BuiltinDetails =\n { truncation?: { content?: unknown }; fullOutputPath?: unknown } | undefined\n\nconst fullOutputPath = (\n result: AgentToolResult<unknown>,\n): string | undefined => {\n const path = (result.details as BuiltinDetails)?.fullOutputPath\n return typeof path === 'string' ? path : undefined\n}\n\n/** The full-output file an aborted or timed-out bash call's error names. */\nfunction namedOutputFile(error: unknown): string | undefined {\n if (!(error instanceof Error)) return undefined\n const path = /Full output: ([^\\n]+)\\]\\n\\nCommand [^\\n]+$/.exec(\n error.message,\n )?.[1]\n // The command's own output precedes Pi's note, and could name any file.\n return path !== undefined &&\n dirname(path) === tmpdir() &&\n /^pi-bash-[0-9a-f]{16}\\.log$/.test(basename(path))\n ? path\n : undefined\n}\n\n/**\n * What the log keeps of a result: what Pi's tool-result message holds. A\n * long output's full text moves to the path its result names in the sandbox,\n * where the model's `read` finds it.\n */\nasync function recordedResult(\n result: AgentToolResult<unknown>,\n sandbox: Experimental_SandboxSession,\n): Promise<AgentToolResult<unknown>> {\n // Pi's tool-result message does not carry structured content.\n const { structuredContent: _, ...kept } =\n result as AgentToolResult<unknown> & {\n structuredContent?: unknown\n }\n const details = kept.details as BuiltinDetails\n const path = fullOutputPath(kept)\n if (path !== undefined) {\n try {\n await sandbox.writeBinaryFile({\n path,\n content: await readLocalFile(path),\n })\n } catch {\n // The result stands without it; the model can rerun the command.\n }\n }\n if (details?.truncation === undefined) return kept\n // The truncated text is the result's content already.\n const { content: __, ...truncation } = details.truncation\n return { ...kept, details: { ...details, truncation } }\n}\n\n// Each definition is typed by its parameters; a session takes any of them.\nconst untyped = (definition: object) => definition as ToolDefinition\n\nfunction builtinDefinition(\n modules: PiModules,\n name: Builtin,\n cwd: string,\n call?: {\n sandbox: Experimental_SandboxSession\n signal: AbortSignal | undefined\n },\n): ToolDefinition {\n const sandbox = call?.sandbox\n const files =\n call === undefined ? undefined : { operations: sandboxFiles(call) }\n switch (name) {\n case 'read':\n return untyped(modules.agent.createReadToolDefinition(cwd, files))\n case 'write':\n return untyped(modules.agent.createWriteToolDefinition(cwd, files))\n case 'edit':\n return untyped(modules.agent.createEditToolDefinition(cwd, files))\n case 'bash':\n return untyped(\n modules.agent.createBashToolDefinition(cwd, {\n // No PI_* variables reach the sandbox, so Pi's prompt names none.\n exposeSessionEnvironment: false,\n ...(sandbox === undefined\n ? {}\n : { operations: sandboxBash(sandbox) }),\n }),\n )\n }\n}\n\n/**\n * The tools Pi's session declares: Pi's own, and the agent's. Their results\n * come from A2's log; A2's tool handlers ran them.\n */\nasync function sessionTools(\n modules: PiModules,\n tools: ToolSet,\n cwd: string,\n result: (\n toolCallId: string,\n signal: AbortSignal | undefined,\n shape: 'pi' | 'tool',\n ) => Promise<AgentToolResult<unknown>>,\n): Promise<ToolDefinition[]> {\n return Promise.all(\n Object.entries(tools)\n .filter(([, tool]) => tool.type !== 'provider')\n .map(async ([name, tool]): Promise<ToolDefinition> => {\n const builtin = BUILTINS.find(\n (candidate) => candidate === name && builtinTools[name] === tool,\n )\n if (builtin !== undefined)\n // Pi's own definition, for its prompt; A2 already ran the call.\n return Object.assign(builtinDefinition(modules, builtin, cwd), {\n execute: (\n toolCallId: string,\n _params: unknown,\n signal?: AbortSignal,\n ) => result(toolCallId, signal, 'pi'),\n })\n return {\n name,\n label: name,\n description:\n typeof tool.description === 'string' ? tool.description : '',\n parameters: (await asSchema(tool.inputSchema)\n .jsonSchema) as ToolDefinition['parameters'],\n execute: (toolCallId, _params, signal) =>\n result(toolCallId, signal, 'tool'),\n }\n }),\n )\n}\n\nfunction answeredTool(\n result: ToolResultPayload,\n shape: 'pi' | 'tool',\n): AgentToolResult<unknown> {\n if (result.error !== undefined) throw new Error(result.error)\n if (result.denied === true) throw new Error('The tool call was denied.')\n if (shape === 'pi') return result.output as AgentToolResult<unknown>\n const output = result.output\n return {\n content: [\n {\n type: 'text',\n text:\n typeof output === 'string' ? output : (JSON.stringify(output) ?? ''),\n },\n ],\n details: undefined,\n }\n}\n\n// ------------------------------------------------------------ sandbox\n\n/** Pi's file operations, against the sandbox. */\nfunction sandboxFiles({\n sandbox,\n signal,\n}: {\n sandbox: Experimental_SandboxSession\n /** The tool call's: it stops a read or write in flight. */\n signal: AbortSignal | undefined\n}) {\n const abortSignal = signal === undefined ? {} : { abortSignal: signal }\n let checked: { path: string; bytes: Buffer } | undefined\n const readFile = async (path: string): Promise<Buffer> => {\n if (checked?.path === path) {\n const { bytes } = checked\n checked = undefined\n return bytes\n }\n const stream = await sandbox.readFile({ path, ...abortSignal })\n if (stream === null)\n throw Object.assign(\n new Error(`ENOENT: no such file or directory, open '${path}'`),\n { code: 'ENOENT' },\n )\n const chunks: Uint8Array[] = []\n let size = 0\n // Leaving the loop cancels the stream.\n for await (const chunk of stream) {\n size += chunk.byteLength\n if (size > MAX_TRANSFER_BYTES)\n throw new Error(\n `${path} is larger than ${MAX_TRANSFER}. Read or change parts of it with bash, using sed, head, or grep.`,\n )\n chunks.push(chunk)\n }\n return Buffer.concat(chunks)\n }\n return {\n readFile,\n // Pi checks a file just before reading it; the check's read serves both.\n access: async (path: string): Promise<void> => {\n checked = { path, bytes: await readFile(path) }\n },\n writeFile: async (path: string, content: string): Promise<void> => {\n checked = undefined\n await sandbox.writeTextFile({ path, content, ...abortSignal })\n },\n // The sandbox creates parent directories as it writes.\n mkdir: async (): Promise<void> => {},\n }\n}\n\n/** Pi's shell operations, against the sandbox. */\nconst sandboxBash = (sandbox: Experimental_SandboxSession): BashOperations => ({\n // Pi hands over the server's environment; it never reaches the sandbox.\n exec: (command, cwd, { onData, signal, timeout }) =>\n sandboxExec({\n sandbox,\n command,\n workingDirectory: cwd,\n onData,\n signal,\n timeout,\n }),\n})\n\n/**\n * Runs a command in the sandbox with Pi's error contract. At most\n * `MAX_TRANSFER_BYTES` of its output reach the server; past that, the\n * command is stopped.\n */\nasync function sandboxExec({\n sandbox,\n command,\n workingDirectory,\n onData,\n signal,\n timeout,\n}: {\n sandbox: Experimental_SandboxSession\n command: string\n /** The sandbox's own when absent. */\n workingDirectory?: string\n onData: (data: Buffer, stream: 'stdout' | 'stderr') => void\n signal?: AbortSignal | undefined\n /** In seconds. */\n timeout?: number | undefined\n}): Promise<{ exitCode: number }> {\n if (signal?.aborted) throw new Error('aborted')\n const stop = new AbortController()\n const abort = () => stop.abort()\n signal?.addEventListener('abort', abort, { once: true })\n let timedOut = false\n const timer =\n timeout === undefined || timeout <= 0\n ? undefined\n : setTimeout(() => {\n timedOut = true\n stop.abort()\n }, timeout * 1000)\n let size = 0\n let overflowed = false\n const overflow = (options?: ErrorOptions) =>\n new Error(\n `The command's output passed ${MAX_TRANSFER}, so it was stopped. Write long output to a file and read parts of it with head, tail, or grep.`,\n options,\n )\n let exitCode: number\n try {\n const process = await sandbox.spawn({\n command,\n ...(workingDirectory === undefined ? {} : { workingDirectory }),\n abortSignal: stop.signal,\n })\n const pipe = async (stream: 'stdout' | 'stderr') => {\n for await (const chunk of process[stream]) {\n size += chunk.byteLength\n if (size > MAX_TRANSFER_BYTES) {\n overflowed = true\n stop.abort()\n return\n }\n onData(Buffer.from(chunk), stream)\n }\n }\n const [exited] = await Promise.all([\n process.wait(),\n pipe('stdout'),\n pipe('stderr'),\n ])\n exitCode = exited.exitCode\n } catch (error) {\n if (signal?.aborted) throw new Error('aborted', { cause: error })\n if (timedOut) throw new Error(`timeout:${timeout}`, { cause: error })\n if (overflowed) throw overflow({ cause: error })\n throw error\n } finally {\n clearTimeout(timer)\n signal?.removeEventListener('abort', abort)\n }\n if (signal?.aborted) throw new Error('aborted')\n if (timedOut) throw new Error(`timeout:${timeout}`)\n if (overflowed) throw overflow()\n return { exitCode }\n}\n\n// Sandbox resolvers may return a new object each time; sessions keep theirs.\nconst cwds = boundedCache<string, Promise<string>>({\n maxEntries: 1000,\n maxBytes: 1000,\n})\n\nconst cwdKey = (agentName: string, sessionId: string): string =>\n `${agentName}\\u001f${sessionId}`\n\n/** A session's working directory in its sandbox: Pi's cwd. */\nfunction sessionCwd({\n key,\n sandbox,\n}: {\n /** The agent and session, when known; otherwise the sandbox is asked. */\n key: string | undefined\n sandbox: () => Promise<Experimental_SandboxSession>\n}): Promise<string> {\n const cached = key === undefined ? undefined : cwds.get(key)\n if (cached !== undefined) return cached\n const cwd = sandbox().then(async (resolved) => {\n // Bounded, unlike `run`: a login profile in the sandbox can print anything.\n const output = { stdout: '', stderr: '' }\n const decoder = { stdout: new TextDecoder(), stderr: new TextDecoder() }\n const { exitCode } = await sandboxExec({\n sandbox: resolved,\n command: 'pwd',\n onData: (data, stream) => {\n output[stream] += decoder[stream].decode(data, { stream: true })\n },\n }).catch((error: unknown) => {\n throw new Error(\"pi() could not read the sandbox's working directory\", {\n cause: error,\n })\n })\n const path = output.stdout.trim()\n if (exitCode !== 0 || !path.startsWith('/'))\n throw new Error(\n `pi() could not read the sandbox's working directory: ${(output.stderr || output.stdout).slice(0, 1000)}`,\n )\n return path\n })\n if (key !== undefined) {\n cwds.set(key, cwd, 1)\n cwd.catch(() => cwds.delete(key))\n }\n return cwd\n}\n\n// ------------------------------------------------------------- Pi\n\nlet loading: Promise<PiModules> | undefined\n\nfunction loadPi(): Promise<PiModules> {\n loading ??= Promise.all([\n import('@earendil-works/pi-coding-agent'),\n import('@earendil-works/pi-ai'),\n ]).then(\n ([agent, ai]) => ({ agent, ai }),\n (error: unknown) => {\n loading = undefined\n throw new Error(\n 'pi() needs @earendil-works/pi-coding-agent and @earendil-works/pi-ai: install them',\n { cause: error },\n )\n },\n )\n return loading\n}\n\n/** Pi's resources: nothing discovered from disk, the agent's instructions appended. */\nfunction resources(modules: PiModules, instructions: string[]): ResourceLoader {\n const runtime = modules.agent.createExtensionRuntime()\n return {\n getExtensions: () => ({ extensions: [], errors: [], runtime }),\n getSkills: () => ({ skills: [], diagnostics: [] }),\n getPrompts: () => ({ prompts: [], diagnostics: [] }),\n getThemes: () => ({ themes: [], diagnostics: [] }),\n getAgentsFiles: () => ({ agentsFiles: [] }),\n getSystemPrompt: () => undefined,\n getSystemPromptSource: () => undefined,\n getAppendSystemPrompt: () => instructions,\n getAppendSystemPromptSources: () => [],\n extendResources: () => {},\n reload: async () => {},\n }\n}\n\nfunction thinkingLevel(step: HarnessStep): {\n thinkingLevel?: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh'\n} {\n if (step.reasoning === undefined || step.reasoning === 'provider-default')\n return {}\n return { thinkingLevel: step.reasoning === 'none' ? 'off' : step.reasoning }\n}\n\nfunction gatewayHeaders(credential: {\n token: string\n method: string\n}): Record<string, string> {\n return {\n authorization: `Bearer ${credential.token}`,\n 'ai-gateway-auth-method': credential.method,\n }\n}\n\n/** A stable Pi session ID for an A2 session, so Pi's cache affinity holds. */\nfunction sessionUuid(agentName: string, sessionId: string): string {\n const hex = createHash('sha256')\n .update(`${agentName}\\u001f${sessionId}`)\n .digest('hex')\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-8${hex.slice(13, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`\n}\n\nfunction savedSession(state: unknown): Saved | undefined {\n if (typeof state !== 'object' || state === null) return undefined\n const { version, cwd, header, entries } = state as Record<string, unknown>\n if (\n version !== SNAPSHOT_VERSION ||\n typeof cwd !== 'string' ||\n typeof header !== 'object' ||\n header === null ||\n !Array.isArray(entries)\n )\n return undefined\n return {\n cwd,\n header: header as SessionHeader,\n entries: entries as SessionEntry[],\n }\n}\n\nfunction compactionData(event: {\n result: { summary: string; tokensBefore: number; usage?: Usage } | undefined\n aborted: boolean\n errorMessage?: string\n}): CompactionPartData {\n if (event.result === undefined)\n return { status: event.aborted ? 'interrupted' : 'failed' }\n return {\n status: 'completed',\n inputTokens: event.result.tokensBefore,\n summary: event.result.summary,\n ...(event.result.usage === undefined\n ? {}\n : { usage: modelUsage(event.result.usage) }),\n }\n}\n\nfunction finishReason(reason: AssistantMessage['stopReason']): FinishReason {\n switch (reason) {\n case 'stop':\n return 'stop'\n case 'length':\n return 'length'\n case 'toolUse':\n return 'tool-calls'\n case 'error':\n return 'error'\n default:\n return 'other'\n }\n}\n\nfunction modelUsage(usage: Usage): LanguageModelUsage {\n return {\n inputTokens: usage.input + usage.cacheRead + usage.cacheWrite,\n inputTokenDetails: {\n noCacheTokens: usage.input,\n cacheReadTokens: usage.cacheRead,\n cacheWriteTokens: usage.cacheWrite,\n },\n outputTokens: usage.output,\n outputTokenDetails: {\n textTokens:\n usage.reasoning === undefined\n ? undefined\n : usage.output - usage.reasoning,\n reasoningTokens: usage.reasoning,\n },\n totalTokens: usage.totalTokens,\n }\n}\n\n// ------------------------------------------------------------- helpers\n\nfunction asError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error))\n}\n"],"mappings":"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"}
@@ -1,9 +1,9 @@
1
- import { s as Contract, t as Reducer, u as EventDefs } from "./reducer-BYu6DT7h.js";
2
- import { t as InitialSnapshot } from "./initial-snapshot-BrLso5x_.js";
3
- import { t as A2Client, u as PushResult } from "./client-qRnRUzBS.js";
4
- import { B as PendingApproval, V as PendingInput, d as AgentStatus, i as AIState, t as AIEventDefs } from "./ai-vpGtcaCB.js";
1
+ import { s as Contract, t as Reducer, u as EventDefs } from "./reducer-CqA59Q6U.js";
2
+ import { t as InitialSnapshot } from "./initial-snapshot-Bx-c0pDP.js";
3
+ import { t as A2Client, u as PushResult } from "./client-h_DKFAjj.js";
4
+ import { B as PendingApproval, V as PendingInput, d as AgentStatus, i as AIState, t as AIEventDefs } from "./ai-DrUaMyRt.js";
5
5
  import { AgentClient, AgentMessage, AnyAgent } from "./ai-client.js";
6
- import { c as UseSessionResult } from "./react-BbJ-g6Uu.js";
6
+ import { c as UseSessionResult } from "./react-BBXgHWFc.js";
7
7
  import { JSONValue, UIMessage } from "ai";
8
8
  //#region src/ai-agent-actions.d.ts
9
9
  /** The input message type of a state: what its inbox holds. */
package/dist/ai-react.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use client";
2
- import { t as createClient } from "./client-COaiaDub.js";
2
+ import { t as createClient } from "./client-BReKqwZC.js";
3
3
  import { useSession } from "./react.js";
4
- import { s as inputs, x as isCompactionPart } from "./ai-UrWfKeuv.js";
4
+ import { s as inputs, x as isCompactionPart } from "./ai-BpOGm-zB.js";
5
5
  import { createAgentClient } from "./ai-client.js";
6
6
  //#region src/ai-agent-actions.ts
7
7
  const visible = (part) => part.type === "text" ? part.text.length > 0 : part.type !== "reasoning" && part.type !== "step-start" && !isCompactionPart(part);
@@ -1,7 +1,8 @@
1
- import { c as ContractEvent, s as Contract, t as Reducer, u as EventDefs, v as StandardSchemaV1 } from "./reducer-BYu6DT7h.js";
2
- import { n as A2Server, p as ServerOptions, s as HandlerContext } from "./server-CGM8WzRG.js";
3
- import { H as ReasoningLevel, a as AI_STATE_REDUCER, f as AgentToolContext, i as AIState, p as AgentToolEventDefs, r as AIMessageOf, t as AIEventDefs } from "./ai-vpGtcaCB.js";
4
- import { Instructions, LanguageModel, ModelMessage, TextStreamPart, ToolSet, ToolSet as ToolSet$1, UIMessage, UIMessageChunk, streamText } from "ai";
1
+ import { c as ContractEvent, s as Contract, t as Reducer, u as EventDefs, v as StandardSchemaV1 } from "./reducer-CqA59Q6U.js";
2
+ import { c as HandlerContext, m as ServerOptions, n as A2Server } from "./server-En7cbi3v.js";
3
+ import { H as ReasoningLevel, a as AI_STATE_REDUCER, f as AgentToolContext, i as AIState, p as AgentToolEventDefs, r as AIMessageOf, t as AIEventDefs } from "./ai-DrUaMyRt.js";
4
+ import { t as Harness } from "./ai-harness-DvsPeJeB.js";
5
+ import { Instructions, ModelMessage, TextStreamPart, ToolSet, ToolSet as ToolSet$1, UIMessage, UIMessageChunk, streamText } from "ai";
5
6
  //#region src/ai-sdk-step.d.ts
6
7
  type StreamTextOptions<T extends ToolSet$1> = Parameters<typeof streamText<T>>[0];
7
8
  type ModelStepTimeout<T extends ToolSet$1> = number | Omit<Exclude<StreamTextOptions<T>["timeout"], number | undefined>, "toolMs" | "tools">;
@@ -41,7 +42,8 @@ type AISDKStepSettings<T extends ToolSet$1> = Partial<Omit<StreamTextOptions<T>,
41
42
  type AgentGenerateContext<M extends UIMessage, D extends AIEventDefs<M> & EventDefs, T extends ToolSet, X extends object = Record<never, never>> = AgentResolverContext<M, D, X> & {
42
43
  generationId: string;
43
44
  modelMessages: ModelMessage[];
44
- model: LanguageModel;
45
+ /** The resolved AI Gateway model ID. */
46
+ model: string;
45
47
  tools: T;
46
48
  instructions?: Instructions;
47
49
  generation: AgentGenerationSettings<T>;
@@ -65,7 +67,8 @@ type AgentResolverContext<M extends UIMessage, D extends AIEventDefs<M> & EventD
65
67
  type Resolvable<T, C> = T | ((context: C) => T | Promise<T>);
66
68
  /** A model with its reasoning level and speed, chosen together. */
67
69
  type ModelSettings = {
68
- model: LanguageModel;
70
+ /** An AI Gateway model ID, such as `'anthropic/claude-sonnet-5.5'`. */
71
+ model: string;
69
72
  /** Overrides `generation.reasoning`. */
70
73
  reasoning?: ReasoningLevel;
71
74
  /** `fast` prefers AI Gateway's faster tier when the model offers one. */
@@ -87,20 +90,16 @@ type AutomaticCompaction = {
87
90
  };
88
91
  type CompactionOptions<M extends UIMessage, D extends AIEventDefs<M> & EventDefs, X extends object = Record<never, never>> = false | AutomaticCompaction | CompactionPolicy<M, D, X>;
89
92
  type AgentGenerationSettings<T extends ToolSet> = AISDKStepSettings<T>;
90
- type AgentModelOptions<M extends UIMessage, D extends AIEventDefs<M> & EventDefs, T extends ToolSet = ToolSet, X extends object = Record<never, never>> = {
91
- /**
92
- * AI SDK model string or provider model, or `ModelSettings` to choose its
93
- * reasoning level and speed with it, optionally resolved per generation.
94
- */
95
- model: Resolvable<LanguageModel | ModelSettings, AgentResolverContext<M, D, X>>;
96
- tools?: T;
97
- instructions?: Resolvable<Instructions | undefined, AgentResolverContext<M, D, X>>;
93
+ /** What a tool call does when a crash or a cancellation may have cut it short. */
94
+ type ToolRecovery = "rerun" | "report";
95
+ /**
96
+ * The AI SDK harness, the default: one AI SDK `streamText()` step per
97
+ * durable generation, with A2 running tools, approvals, and compaction.
98
+ */
99
+ type AISDKHarness<M extends UIMessage = UIMessage, D extends AIEventDefs<M> & EventDefs = AIEventDefs<M> & EventDefs, T extends ToolSet = ToolSet, X extends object = Record<never, never>> = {
100
+ type: "ai-sdk";
98
101
  /** Settings for each one-step AI SDK streamText call, resolved per generation. */
99
102
  generation?: Resolvable<AgentGenerationSettings<T>, AgentResolverContext<M, D, X>>;
100
- /**
101
- * Maximum model steps in one assistant response. Defaults to Infinity.
102
- */
103
- maxSteps?: number;
104
103
  /** Map default AI SDK stream parts to typed assistant message metadata. */
105
104
  messageMetadata?: AgentMessageMetadata<M, D, T, X>;
106
105
  /**
@@ -109,6 +108,29 @@ type AgentModelOptions<M extends UIMessage, D extends AIEventDefs<M> & EventDefs
109
108
  */
110
109
  generate?: AgentGenerate<M, D, T, X>;
111
110
  compaction?: Resolvable<CompactionOptions<M, D, X>, AgentResolverContext<M, D, X>>;
111
+ };
112
+ type AgentLoopOptions<M extends UIMessage, D extends AIEventDefs<M> & EventDefs, T extends ToolSet, X extends object, H extends string> = {
113
+ /** The agent's loop: the AI SDK's (the default), or `fx()` or `pi()`. */
114
+ harness?: AISDKHarness<M, D, T, X>;
115
+ /** Per tool name: rerun an interrupted call (the default) or report it to the model. */
116
+ toolRecovery?: Readonly<Partial<Record<NoInfer<keyof T & string>, ToolRecovery>>>;
117
+ } | {
118
+ harness: Harness<"fx" | "pi", H>;
119
+ /** Per tool name, the harness's own tools included: rerun an interrupted call (the default) or report it. */
120
+ toolRecovery?: Readonly<Partial<Record<NoInfer<(keyof T & string) | H>, ToolRecovery>>>;
121
+ };
122
+ type AgentModelOptions<M extends UIMessage, D extends AIEventDefs<M> & EventDefs, T extends ToolSet = ToolSet, X extends object = Record<never, never>, H extends string = string> = {
123
+ /**
124
+ * An AI Gateway model ID, or `ModelSettings` to choose its reasoning level
125
+ * and speed with it, optionally resolved per generation.
126
+ */
127
+ model: Resolvable<string | ModelSettings, AgentResolverContext<M, D, X>>;
128
+ tools?: T;
129
+ instructions?: Resolvable<Instructions | undefined, AgentResolverContext<M, D, X>>;
130
+ /**
131
+ * Maximum model steps in one assistant response. Defaults to Infinity.
132
+ */
133
+ maxSteps?: number;
112
134
  /** Progress is durably flushed at either limit, whichever is reached first. */
113
135
  progress?: {
114
136
  maxChunks?: number;
@@ -119,12 +141,12 @@ type AgentModelOptions<M extends UIMessage, D extends AIEventDefs<M> & EventDefs
119
141
  * independent tools run concurrently.
120
142
  */
121
143
  toolLane?: string;
122
- };
123
- type AgentServerOptions<M extends UIMessage, D extends AIEventDefs<M> & EventDefs, S, T extends ToolSet, X extends object = Record<never, never>> = AgentModelOptions<M, D, T, X> & Omit<ServerOptions<D, Record<never, never>, Reducer<D, S>>, "contract" | "handlers"> & {
144
+ } & AgentLoopOptions<M, D, T, X, H>;
145
+ type AgentServerOptions<M extends UIMessage, D extends AIEventDefs<M> & EventDefs, S, T extends ToolSet, X extends object = Record<never, never>, H extends string = string> = AgentModelOptions<M, D, T, X, H> & Omit<ServerOptions<D, Record<never, never>, Reducer<D, S>>, "contract" | "handlers"> & {
124
146
  /** Handlers for application events. */
125
147
  handlers?: ServerOptions<D, Record<never, never>, Reducer<D, S>>["handlers"];
126
148
  };
127
- type AgentOptions<M extends UIMessage, E extends EventDefs, T extends ToolSet> = AgentServerOptions<NoInfer<M>, AIEventDefs<NoInfer<M>> & E, AIState<NoInfer<M>>, T> & {
149
+ type AgentOptions<M extends UIMessage, E extends EventDefs, T extends ToolSet, H extends string = string> = AgentServerOptions<NoInfer<M>, AIEventDefs<NoInfer<M>> & E, AIState<NoInfer<M>>, T, Record<never, never>, H> & {
128
150
  /** Identity: prefixes storage keys and queue messages. */
129
151
  name: string;
130
152
  /**
@@ -135,7 +157,7 @@ type AgentOptions<M extends UIMessage, E extends EventDefs, T extends ToolSet> =
135
157
  /** Optional stricter schema for custom UIMessage metadata/data/tool types. */
136
158
  messageSchema?: StandardSchemaV1<M>;
137
159
  };
138
- type AgentFromContractOptions<D extends AIEventDefs<AIMessageOf<D>> & EventDefs, S, T extends ToolSet, Name extends string = string, X extends object = Record<never, never>> = AgentServerOptions<AIMessageOf<D>, D, S, T, X> & {
160
+ type AgentFromContractOptions<D extends AIEventDefs<AIMessageOf<D>> & EventDefs, S, T extends ToolSet, Name extends string = string, X extends object = Record<never, never>, H extends string = string> = AgentServerOptions<AIMessageOf<D>, D, S, T, X, H> & {
139
161
  /**
140
162
  * A shared `agentContract()`. Its application state reaches every resolver
141
163
  * as `state`; a fully custom contract is core A2, served by `createServer()`.
@@ -160,8 +182,8 @@ declare function runWithHandlerContext<D extends AgentToolEventDefs, R>(ctx: Age
160
182
  * built-in protocol, or a shared `agentContract()` when clients fold
161
183
  * application state.
162
184
  */
163
- declare function agent<T extends ToolSet = ToolSet, M extends UIMessage = UIMessage, E extends EventDefs = Record<never, never>>(options: AgentOptions<M, E, T>): Agent<AIEventDefs<M> & E, AIState<M>, typeof AI_STATE_REDUCER>;
164
- declare function agent<D extends AIEventDefs<AIMessageOf<D>> & EventDefs, S, T extends ToolSet = ToolSet, Name extends string = string, X extends object = Record<never, never>>(options: AgentFromContractOptions<D, S, T, Name, X>): Agent<D, S, Name>;
185
+ declare function agent<T extends ToolSet = ToolSet, M extends UIMessage = UIMessage, E extends EventDefs = Record<never, never>, H extends string = never>(options: AgentOptions<M, E, T, H>): Agent<AIEventDefs<M> & E, AIState<M>, typeof AI_STATE_REDUCER>;
186
+ declare function agent<D extends AIEventDefs<AIMessageOf<D>> & EventDefs, S, T extends ToolSet = ToolSet, Name extends string = string, X extends object = Record<never, never>, H extends string = never>(options: AgentFromContractOptions<D, S, T, Name, X, H>): Agent<D, S, Name>;
165
187
  //#endregion
166
- export { type Agent, type AgentFromContractOptions, type AgentGenerate, type AgentGenerateContext, type AgentGenerationSettings, type AgentMessageMetadata, type AgentModelOptions, type AgentOptions, type AgentResolverContext, type AutomaticCompaction, type CompactionOptions, type CompactionPolicy, type Instructions, type LanguageModel, type ModelSettings, type Resolvable, type ToolSet, agent, runWithHandlerContext };
188
+ export { type AISDKHarness, type Agent, type AgentFromContractOptions, type AgentGenerate, type AgentGenerateContext, type AgentGenerationSettings, type AgentMessageMetadata, type AgentModelOptions, type AgentOptions, type AgentResolverContext, type AutomaticCompaction, type CompactionOptions, type CompactionPolicy, type Harness, type Instructions, type ModelSettings, type Resolvable, type ToolRecovery, type ToolSet, agent, runWithHandlerContext };
167
189
  //# sourceMappingURL=ai-server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-server.d.ts","names":[],"sources":["../src/ai-sdk-step.ts","../src/ai-agent.ts"],"mappings":"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"}
1
+ {"version":3,"file":"ai-server.d.ts","names":[],"sources":["../src/ai-sdk-step.ts","../src/ai-agent.ts"],"mappings":"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"}
package/dist/ai-server.js CHANGED
@@ -1,8 +1,10 @@
1
1
  import { i as A2Error } from "./session-clear-DGI4jTQ5.js";
2
2
  import { a as reducer, s as validateSync } from "./reducer-BAXc8JyF.js";
3
- import { m as installAmbientToolScopeStorage, p as consumeSchedulerSendFailure } from "./internal-CbVvEwad.js";
4
- import { a as CONSOLE_TELEMETRY, l as boundedCache, o as setServerFetchHooks, t as createServer } from "./server-Rj64fNvX.js";
5
- import { A as interruptUIMessage, C as reduceToolActivity, D as flattenProgressBatches, E as upsertResponse, M as assertMessageBase, N as restoreMessageBase, O as progressBatches, S as projectedMessage, T as upsertMessage, _ as applyControlChanges, a as events, b as findMessage, d as appSlice, f as isAgentContract, g as initialControlState, h as aiEventId, j as pauseUIMessage, k as progressOwnedBy, m as AI_EVENT_ID_PREFIX, n as agentContract, p as withAIStorage, u as appReducerOf, v as controlCommit, w as retainMessageBase, y as advanceProjection } from "./ai-UrWfKeuv.js";
3
+ import { h as installAmbientToolScopeStorage, m as failedPreviousAttempt, p as consumeSchedulerSendFailure } from "./internal-B2T3U4Rq.js";
4
+ import { t as boundedCache } from "./bounded-cache-CPHWF-8h.js";
5
+ import { a as CONSOLE_TELEMETRY, o as setServerFetchHooks, t as createServer } from "./server-Dw_k_7kO.js";
6
+ import { A as interruptUIMessage, C as reduceToolActivity, D as flattenProgressBatches, E as upsertResponse, M as assertMessageBase, N as restoreMessageBase, O as progressBatches, S as projectedMessage, T as upsertMessage, _ as applyControlChanges, a as events, b as findMessage, d as appSlice, f as isAgentContract, g as initialControlState, h as aiEventId, j as pauseUIMessage, k as progressOwnedBy, m as AI_EVENT_ID_PREFIX, n as agentContract, p as withAIStorage, u as appReducerOf, v as controlCommit, w as retainMessageBase, y as advanceProjection } from "./ai-BpOGm-zB.js";
7
+ import { a as harnessDriver, o as harnessLog, s as harnessStates, u as registerHarnessStates } from "./ai-harness-BuLh_EYi.js";
6
8
  import { AsyncLocalStorage } from "node:async_hooks";
7
9
  import { createHash } from "node:crypto";
8
10
  import { asSchema, convertToModelMessages, isToolUIPart, stepCountIs, streamText, toUIMessageStream } from "ai";
@@ -1441,9 +1443,15 @@ const catalogUrl = "https://ai-gateway.vercel.sh/v1/models";
1441
1443
  const catalogLifetimeMs = 36e5;
1442
1444
  const catalogTimeoutMs = 5e3;
1443
1445
  let catalog;
1446
+ /**
1447
+ * The model's AI Gateway ID: the model string, unless an AI SDK global
1448
+ * provider resolves it to a model that is not Gateway's.
1449
+ */
1444
1450
  const gatewayModelId = (model) => {
1445
- if (typeof model === "string") return globalThis.AI_SDK_DEFAULT_PROVIDER === void 0 ? model : void 0;
1446
- return model.provider === "gateway" ? model.modelId : void 0;
1451
+ const provider = globalThis.AI_SDK_DEFAULT_PROVIDER;
1452
+ if (provider === void 0) return model;
1453
+ if (typeof provider.languageModel !== "function") return void 0;
1454
+ return provider.languageModel(model).provider === "gateway" ? model : void 0;
1447
1455
  };
1448
1456
  const readCatalog = () => {
1449
1457
  if (catalog && catalog.expiresAt > Date.now()) return catalog.promise;
@@ -1581,11 +1589,7 @@ const withModelSettings = (options) => {
1581
1589
  } }
1582
1590
  };
1583
1591
  };
1584
- const modelName = (model) => {
1585
- if (typeof model === "string") return model;
1586
- if ("modelId" in model && typeof model.modelId === "string") return model.modelId;
1587
- return "custom";
1588
- };
1592
+ const instructionTexts = (instructions) => instructions === void 0 ? [] : typeof instructions === "string" ? [instructions] : (Array.isArray(instructions) ? instructions : [instructions]).map((message) => message.content);
1589
1593
  const errorMessage = (error) => error instanceof Error ? error.message : String(error);
1590
1594
  const toolScopeStorage = installAmbientToolScopeStorage(() => new AsyncLocalStorage());
1591
1595
  /** Run `fn` with `ctx` as the ambient tool handler context, for direct tool tests. */
@@ -1887,7 +1891,7 @@ const lifecycleEvents = async (options) => {
1887
1891
  ...chunk.title === void 0 ? {} : { title: chunk.title }
1888
1892
  };
1889
1893
  take(payload.toolCallId);
1890
- const classification = approvalClassification(options.tools, options.generation, chunk.toolName);
1894
+ const classification = options.approvals === false ? "automatic" : approvalClassification(options.tools, options.generation, chunk.toolName);
1891
1895
  if (classification === "automatic") result.push(await toolCalledEvent(payload));
1892
1896
  else pending.push({
1893
1897
  call: payload,
@@ -2028,19 +2032,50 @@ const validateCompaction = (options) => {
2028
2032
  }
2029
2033
  return compaction;
2030
2034
  };
2035
+ const AI_SDK_HARNESS_OPTIONS = [
2036
+ "generation",
2037
+ "generate",
2038
+ "compaction",
2039
+ "messageMetadata"
2040
+ ];
2041
+ const assertNoLoopOptions = (options) => {
2042
+ const harness = options.harness?.type ?? "ai-sdk";
2043
+ for (const key of AI_SDK_HARNESS_OPTIONS) {
2044
+ if (!Object.hasOwn(options, key)) continue;
2045
+ throw new TypeError(harness === "ai-sdk" ? `${key} belongs to the harness: agent({ harness: { type: 'ai-sdk', ${key} } })` : `${key} is an option of the AI SDK harness; ${harness}() runs its own loop`);
2046
+ }
2047
+ };
2031
2048
  function createHandlers(options) {
2032
2049
  if (options.model === void 0) throw new TypeError("agent requires model");
2033
2050
  if (options.progress?.maxChunks !== void 0 && (!Number.isInteger(options.progress.maxChunks) || options.progress.maxChunks < 1)) throw new TypeError("progress.maxChunks must be a positive integer");
2034
2051
  if (options.progress?.maxDelayMs !== void 0 && (!Number.isFinite(options.progress.maxDelayMs) || options.progress.maxDelayMs < 0)) throw new TypeError("progress.maxDelayMs must be a non-negative number");
2035
2052
  if (options.maxSteps !== void 0 && options.maxSteps !== Number.POSITIVE_INFINITY && (!Number.isInteger(options.maxSteps) || options.maxSteps < 1)) throw new TypeError("maxSteps must be a positive integer or Infinity");
2036
- const configuredCompaction = options.compaction ?? (options.generate === void 0 ? {} : false);
2053
+ assertNoLoopOptions(options);
2054
+ const configured = options.harness;
2055
+ const loop = configured?.type === "ai-sdk" ? configured : {};
2056
+ const harness = configured === void 0 || configured.type === "ai-sdk" ? void 0 : harnessDriver(configured);
2057
+ const states = options.harnessStates ?? harnessStates();
2058
+ if (harness !== void 0) for (const [name, tool] of Object.entries(options.tools ?? {})) {
2059
+ const needsApproval = tool.needsApproval;
2060
+ if (needsApproval !== void 0 && needsApproval !== false) throw new TypeError(`a harness runs tools without approval; '${name}' sets needsApproval`);
2061
+ }
2062
+ const configuredCompaction = loop.compaction ?? (loop.generate === void 0 && harness === void 0 ? {} : false);
2037
2063
  const staticCompaction = typeof configuredCompaction === "function" ? void 0 : validateCompaction({
2038
2064
  compaction: configuredCompaction,
2039
- explicit: options.compaction !== void 0,
2040
- generation: typeof options.generation === "function" ? void 0 : options.generation,
2065
+ explicit: loop.compaction !== void 0,
2066
+ generation: typeof loop.generation === "function" ? void 0 : loop.generation,
2041
2067
  tools: options.tools
2042
2068
  });
2043
- const tools = options.tools ?? {};
2069
+ const tools = harness === void 0 ? options.tools ?? {} : {
2070
+ ...harness.tools,
2071
+ ...options.tools
2072
+ };
2073
+ const toolRecovery = options.toolRecovery ?? {};
2074
+ for (const [name, recovery] of Object.entries(toolRecovery)) {
2075
+ if (!Object.hasOwn(tools, name)) throw new TypeError(`toolRecovery names '${name}', which is not one of the agent's tools`);
2076
+ if (typeof tools[name].execute !== "function") throw new TypeError(`toolRecovery names '${name}', which has no execute function`);
2077
+ if (recovery !== "rerun" && recovery !== "report") throw new TypeError(`toolRecovery for '${name}' must be 'rerun' or 'report'`);
2078
+ }
2044
2079
  const telemetry = options.telemetry ?? CONSOLE_TELEMETRY;
2045
2080
  const maxSteps = options.maxSteps ?? Number.POSITIVE_INFINITY;
2046
2081
  const control = createControlRuntime({
@@ -2126,13 +2161,14 @@ function createHandlers(options) {
2126
2161
  if (schedulerFailure === "retryable") throw error;
2127
2162
  return resultEvent(call, `${ctx.event.id}:execution:error`, { error: errorMessage(error) });
2128
2163
  };
2129
- const runToolExecution = async (ctx, call, execute, messages) => {
2164
+ const runToolExecution = async (ctx, call, execute, messages, sandbox) => {
2130
2165
  let output;
2131
2166
  try {
2132
2167
  output = await execute(call.input, {
2133
2168
  toolCallId: call.toolCallId,
2134
2169
  messages,
2135
- abortSignal: ctx.signal
2170
+ abortSignal: ctx.signal,
2171
+ ...sandbox === void 0 ? {} : { experimental_sandbox: sandbox }
2136
2172
  });
2137
2173
  } catch (error) {
2138
2174
  return toolExecutionFailure(ctx, call, error);
@@ -2183,13 +2219,27 @@ function createHandlers(options) {
2183
2219
  const { ctx, call } = input;
2184
2220
  const execute = tools[call.toolName]?.execute;
2185
2221
  if (execute === void 0) return resultEvent(call, `${ctx.event.id}:execution:error`, { error: `Tool '${call.toolName}' has no server executor` });
2222
+ const report = toolRecovery[call.toolName] === "report";
2223
+ const interrupted = () => resultEvent(call, `${ctx.event.id}:execution:error`, { error: `Tool '${call.toolName}' was interrupted and may have partly run.` });
2224
+ if (report && ctx.attempt > 1 && !failedPreviousAttempt.has(ctx)) return interrupted();
2186
2225
  const messages = await promptMessages(input);
2226
+ const sandbox = harness?.sandbox === void 0 ? void 0 : await resolve(harness.sandbox, {
2227
+ session: { id: ctx.session.id },
2228
+ signal: ctx.signal
2229
+ });
2187
2230
  if (checkAbort(ctx.signal)) return;
2188
2231
  const scope = {
2189
2232
  contract: options.contract,
2190
2233
  context: ctx
2191
2234
  };
2192
- return toolScopeStorage.run(scope, () => runToolExecution(ctx, call, execute, messages));
2235
+ const run = () => toolScopeStorage.run(scope, () => runToolExecution(ctx, call, execute, messages, sandbox));
2236
+ if (!report) return run();
2237
+ try {
2238
+ return await run() ?? await interrupted();
2239
+ } catch {
2240
+ checkAbort(ctx.signal);
2241
+ return interrupted();
2242
+ }
2193
2243
  };
2194
2244
  const handleToolExecution = async (ctx) => {
2195
2245
  try {
@@ -2304,7 +2354,7 @@ function createHandlers(options) {
2304
2354
  generationId,
2305
2355
  responseMessageId,
2306
2356
  attempt,
2307
- ...model === void 0 ? {} : { model: modelName(model) },
2357
+ ...model === void 0 ? {} : { model },
2308
2358
  promptThroughIndex: snapshot.index
2309
2359
  });
2310
2360
  let resolvedModel;
@@ -2313,23 +2363,23 @@ function createHandlers(options) {
2313
2363
  try {
2314
2364
  const choice = await resolve(options.model, resolverContext);
2315
2365
  if (choice === void 0) throw new TypeError("the model resolver returned undefined");
2316
- const settings = typeof choice === "string" || "specificationVersion" in choice ? { model: choice } : choice;
2366
+ const settings = typeof choice === "string" ? { model: choice } : choice;
2317
2367
  const model = settings.model;
2318
- if (typeof model !== "string" && (typeof model !== "object" || model === null)) throw new TypeError("the model resolver must return a model");
2368
+ if (typeof model !== "string" || model === "") throw new TypeError("the model must be an AI Gateway model ID");
2319
2369
  resolvedModel = model;
2320
2370
  if (checkAbort(ctx.signal)) return;
2321
2371
  const resolvedInstructions = options.instructions === void 0 ? void 0 : await resolve(options.instructions, resolverContext);
2322
2372
  if (checkAbort(ctx.signal)) return;
2323
- const resolvedGeneration = await resolve(options.generation ?? {}, resolverContext);
2373
+ const resolvedGeneration = await resolve(loop.generation ?? {}, resolverContext);
2324
2374
  if (checkAbort(ctx.signal)) return;
2325
2375
  if (resolvedGeneration === null || typeof resolvedGeneration !== "object" || Array.isArray(resolvedGeneration)) throw new TypeError("the generation resolver must return settings");
2326
2376
  const generation = withModelSettings({
2327
2377
  generation: resolvedGeneration,
2328
2378
  settings
2329
2379
  });
2330
- const compaction = typeof configuredCompaction === "function" || typeof options.generation === "function" ? validateCompaction({
2380
+ const compaction = typeof configuredCompaction === "function" || typeof loop.generation === "function" ? validateCompaction({
2331
2381
  compaction: typeof configuredCompaction === "function" ? await resolve(configuredCompaction, resolverContext) : staticCompaction,
2332
- explicit: options.compaction !== void 0,
2382
+ explicit: loop.compaction !== void 0,
2333
2383
  generation,
2334
2384
  tools: options.tools
2335
2385
  }) : staticCompaction;
@@ -2393,7 +2443,7 @@ function createHandlers(options) {
2393
2443
  });
2394
2444
  const inputTokens = measuredInputTokens({
2395
2445
  estimate: inputTokenEstimate,
2396
- model: modelName(resolvedModel),
2446
+ model: resolvedModel,
2397
2447
  calibration: coordinatorState.calibration
2398
2448
  });
2399
2449
  const threshold = policy.thresholdTokens ?? (limits === void 0 ? void 0 : Math.floor(Math.min(limits.contextWindow * .75, limits.contextWindow - (generation.maxOutputTokens ?? 0))));
@@ -2500,13 +2550,30 @@ function createHandlers(options) {
2500
2550
  messages: generationMessages,
2501
2551
  modelMessages
2502
2552
  };
2503
- const custom = options.generate !== void 0;
2504
2553
  const updates = consumeGeneration({
2505
- source: options.generate === void 0 ? await generateWithAISDK({
2554
+ source: harness !== void 0 ? await harness.step({
2555
+ agentName: options.contract.name,
2556
+ sessionId: ctx.event.sessionId,
2557
+ requestIndex: ctx.event.index,
2558
+ generationId,
2559
+ responseMessageId,
2560
+ throughIndex: snapshot.index,
2561
+ messages: generationMessages,
2562
+ model,
2563
+ ...settings.reasoning === void 0 ? {} : { reasoning: settings.reasoning },
2564
+ ...settings.speed === void 0 ? {} : { speed: settings.speed },
2565
+ instructions: instructionTexts(resolvedInstructions),
2566
+ tools,
2567
+ log: harnessLog({
2568
+ states,
2569
+ session: ctx.session
2570
+ }),
2571
+ signal: ctx.signal
2572
+ }) : loop.generate === void 0 ? await generateWithAISDK({
2506
2573
  agentName: options.contract.name,
2507
2574
  context: generateContext,
2508
- messageMetadata: options.messageMetadata
2509
- }) : { stream: await options.generate(generateContext) },
2575
+ messageMetadata: loop.messageMetadata
2576
+ }) : { stream: await loop.generate(generateContext) },
2510
2577
  ...options.progress === void 0 ? {} : { progress: options.progress }
2511
2578
  });
2512
2579
  let sequence = 0;
@@ -2530,7 +2597,7 @@ function createHandlers(options) {
2530
2597
  pending: pendingToolCalls,
2531
2598
  tools,
2532
2599
  generation,
2533
- custom
2600
+ approvals: harness === void 0
2534
2601
  });
2535
2602
  pendingToolCalls = lifecycle.pending;
2536
2603
  await control.append({
@@ -2559,9 +2626,9 @@ function createHandlers(options) {
2559
2626
  id: await aiEventId("a2.ai.completed", generationId),
2560
2627
  payload: completed
2561
2628
  };
2562
- const unresolved = options.generate ? pendingToolCalls.filter((pending) => pending.classification !== "automatic") : [];
2629
+ const unresolved = loop.generate ? pendingToolCalls.filter((pending) => pending.classification !== "automatic") : [];
2563
2630
  if (unresolved.length > 0) throw new Error(`generation ended with unresolved tool authorization for '${unresolved[0].call.toolName}'`);
2564
- const pendingEvents = await Promise.all(pendingToolCalls.filter((pending) => pending.classification === "automatic" || options.generate === void 0 && pending.classification === "unknown").map((pending) => toolCalledEvent(pending.call)));
2631
+ const pendingEvents = await Promise.all(pendingToolCalls.filter((pending) => pending.classification === "automatic" || loop.generate === void 0 && pending.classification === "unknown").map((pending) => toolCalledEvent(pending.call)));
2565
2632
  if (finish.finishReason === "tool-calls") return [...pendingEvents, completionEvent];
2566
2633
  forgetPrompt(ctx.event.sessionId, generationId);
2567
2634
  return [
@@ -2691,7 +2758,8 @@ function createHandlers(options) {
2691
2758
  };
2692
2759
  }
2693
2760
  function agent(options) {
2694
- const { model, tools, instructions, generation, maxSteps, messageMetadata, generate, compaction, progress, toolLane, handlers, ...rest } = options;
2761
+ assertNoLoopOptions(options);
2762
+ const { model, tools, instructions, maxSteps, harness, toolRecovery, progress, toolLane, handlers, ...rest } = options;
2695
2763
  let contract;
2696
2764
  let serverOptions;
2697
2765
  if ("contract" in rest) {
@@ -2709,17 +2777,17 @@ function agent(options) {
2709
2777
  });
2710
2778
  serverOptions = remaining;
2711
2779
  }
2780
+ const states = harnessStates();
2712
2781
  const builtIns = createHandlers({
2713
2782
  contract,
2714
2783
  model,
2784
+ harnessStates: states,
2715
2785
  ...serverOptions.telemetry === void 0 ? {} : { telemetry: serverOptions.telemetry },
2716
2786
  ...tools === void 0 ? {} : { tools },
2717
2787
  ...instructions === void 0 ? {} : { instructions },
2718
- ...generation === void 0 ? {} : { generation },
2719
2788
  ...maxSteps === void 0 ? {} : { maxSteps },
2720
- ...messageMetadata === void 0 ? {} : { messageMetadata },
2721
- ...generate === void 0 ? {} : { generate },
2722
- ...compaction === void 0 ? {} : { compaction },
2789
+ ...harness === void 0 ? {} : { harness },
2790
+ ...toolRecovery === void 0 ? {} : { toolRecovery },
2723
2791
  ...progress === void 0 ? {} : { progress },
2724
2792
  ...toolLane === void 0 ? {} : { toolLane }
2725
2793
  });
@@ -2732,6 +2800,7 @@ function agent(options) {
2732
2800
  ...handlers
2733
2801
  }
2734
2802
  });
2803
+ registerHarnessStates(server, states);
2735
2804
  const applicationEvents = "contract" in rest;
2736
2805
  setServerFetchHooks(server, { validateIngress: (context) => validateAgentIngress({
2737
2806
  context,