agents 0.12.2 → 0.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/{agent-tool-types-DSteYkkS.d.ts → agent-tool-types-CM_50fcV.d.ts} +104 -87
  2. package/dist/agent-tool-types.d.ts +1 -1
  3. package/dist/agent-tools-BAdX1vdI.js.map +1 -1
  4. package/dist/{agent-tools-eGTCdVZX.d.ts → agent-tools-BylX6WXG.d.ts} +2 -2
  5. package/dist/agent-tools.d.ts +1 -1
  6. package/dist/agent-tools.js.map +1 -1
  7. package/dist/browser/ai.d.ts +2 -2
  8. package/dist/browser/ai.js +1 -1
  9. package/dist/browser/ai.js.map +1 -1
  10. package/dist/browser/index.d.ts +41 -10
  11. package/dist/browser/index.js +1 -1
  12. package/dist/browser/tanstack-ai.d.ts +2 -2
  13. package/dist/browser/tanstack-ai.js +1 -1
  14. package/dist/browser/tanstack-ai.js.map +1 -1
  15. package/dist/chat/index.d.ts +297 -148
  16. package/dist/chat/index.js +43 -14
  17. package/dist/chat/index.js.map +1 -1
  18. package/dist/{classPrivateFieldGet2-Bqby-AHD.js → classPrivateFieldGet2-CS51BNGR.js} +5 -5
  19. package/dist/cli/index.d.ts +1 -1
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/client-D1kFXo80.js.map +1 -1
  22. package/dist/client.d.ts +11 -10
  23. package/dist/client.js.map +1 -1
  24. package/dist/codemode/ai.d.ts +1 -1
  25. package/dist/{compaction-helpers-CSaqCmdE.js → compaction-helpers-DvcZnvQ1.js} +1 -1
  26. package/dist/{compaction-helpers-CSaqCmdE.js.map → compaction-helpers-DvcZnvQ1.js.map} +1 -1
  27. package/dist/{compaction-helpers-D92Ipstp.d.ts → compaction-helpers-bYvP1o2S.d.ts} +10 -3
  28. package/dist/{do-oauth-client-provider-C38aWbFV.d.ts → do-oauth-client-provider-4OKQU9rT.d.ts} +1 -1
  29. package/dist/{email-X72-zjuq.d.ts → email-J0GGS3sa.d.ts} +1 -1
  30. package/dist/email.d.ts +2 -2
  31. package/dist/email.js.map +1 -1
  32. package/dist/experimental/memory/session/index.d.ts +126 -26
  33. package/dist/experimental/memory/session/index.js +13 -3
  34. package/dist/experimental/memory/session/index.js.map +1 -1
  35. package/dist/experimental/memory/utils/index.d.ts +41 -5
  36. package/dist/experimental/memory/utils/index.js +15 -5
  37. package/dist/experimental/memory/utils/index.js.map +1 -1
  38. package/dist/experimental/webmcp.d.ts +9 -3
  39. package/dist/experimental/webmcp.js.map +1 -1
  40. package/dist/{index-Biv6K70p.d.ts → index-DKey3P4s.d.ts} +26 -2
  41. package/dist/index.d.ts +48 -44
  42. package/dist/index.js +122 -85
  43. package/dist/index.js.map +1 -1
  44. package/dist/{internal_context-BvuGZieY.d.ts → internal_context-BZrMS0B5.d.ts} +1 -1
  45. package/dist/internal_context.d.ts +1 -1
  46. package/dist/mcp/client.d.ts +26 -2
  47. package/dist/mcp/do-oauth-client-provider.d.ts +10 -2
  48. package/dist/mcp/do-oauth-client-provider.js.map +1 -1
  49. package/dist/mcp/index.d.ts +54 -2
  50. package/dist/mcp/index.js +43 -19
  51. package/dist/mcp/index.js.map +1 -1
  52. package/dist/mcp/x402.d.ts +74 -17
  53. package/dist/mcp/x402.js.map +1 -1
  54. package/dist/observability/index.d.ts +16 -2
  55. package/dist/observability/index.js +1 -1
  56. package/dist/observability/index.js.map +1 -1
  57. package/dist/react.d.ts +9 -7
  58. package/dist/react.js +18 -2
  59. package/dist/react.js.map +1 -1
  60. package/dist/{retries-fLD8cGNf.d.ts → retries-BVdRl5ZE.d.ts} +1 -1
  61. package/dist/retries.d.ts +1 -1
  62. package/dist/retries.js.map +1 -1
  63. package/dist/schedule.js.map +1 -1
  64. package/dist/serializable.d.ts +141 -7
  65. package/dist/{shared-Ch9slKdI.d.ts → shared-Cvj92byG.d.ts} +1 -1
  66. package/dist/{shared-C6l4ZKRN.js → shared-DzJYHisH.js} +3 -3
  67. package/dist/{shared-C6l4ZKRN.js.map → shared-DzJYHisH.js.map} +1 -1
  68. package/dist/sub-routing.d.ts +6 -6
  69. package/dist/sub-routing.js.map +1 -1
  70. package/dist/tool-output-truncation-CH-khbZ3.js +98 -0
  71. package/dist/tool-output-truncation-CH-khbZ3.js.map +1 -0
  72. package/dist/{types-DAHCZC_W.d.ts → types-_JjKmv-l.d.ts} +1 -1
  73. package/dist/types.d.ts +1 -1
  74. package/dist/types.js.map +1 -1
  75. package/dist/utils.js.map +1 -1
  76. package/dist/vite.js.map +1 -1
  77. package/dist/{workflow-types-DHs0L0KP.d.ts → workflow-types-Dkzg4hAx.d.ts} +1 -1
  78. package/dist/workflow-types.d.ts +1 -1
  79. package/dist/workflow-types.js.map +1 -1
  80. package/dist/workflows.d.ts +2 -2
  81. package/dist/workflows.js.map +1 -1
  82. package/package.json +9 -9
  83. package/dist/serializable-Brg7fRds.d.ts +0 -131
@@ -1,11 +1,11 @@
1
- import { n as AgentEmail } from "./internal_context-BvuGZieY.js";
2
- import { t as RetryOptions } from "./retries-fLD8cGNf.js";
1
+ import { n as AgentEmail } from "./internal_context-BZrMS0B5.js";
2
+ import { t as RetryOptions } from "./retries-BVdRl5ZE.js";
3
3
  import {
4
4
  n as Observability,
5
5
  r as ObservabilityEvent,
6
6
  s as MCPObservabilityEvent
7
- } from "./index-Biv6K70p.js";
8
- import { t as AgentMcpOAuthProvider } from "./do-oauth-client-provider-C38aWbFV.js";
7
+ } from "./index-DKey3P4s.js";
8
+ import { t as AgentMcpOAuthProvider } from "./do-oauth-client-provider-4OKQU9rT.js";
9
9
  import {
10
10
  _ as WorkflowPage,
11
11
  g as WorkflowInfo,
@@ -13,9 +13,9 @@ import {
13
13
  l as WorkflowCallback,
14
14
  s as RunWorkflowOptions,
15
15
  y as WorkflowQueryCriteria
16
- } from "./workflow-types-DHs0L0KP.js";
17
- import { t as MessageType } from "./types-DAHCZC_W.js";
18
- import { r as EmailResolver } from "./email-X72-zjuq.js";
16
+ } from "./workflow-types-Dkzg4hAx.js";
17
+ import { t as MessageType } from "./types-_JjKmv-l.js";
18
+ import { r as EmailResolver } from "./email-J0GGS3sa.js";
19
19
  import { ToolSet, UIMessage } from "ai";
20
20
  import { RpcTarget } from "cloudflare:workers";
21
21
  import {
@@ -24,6 +24,7 @@ import {
24
24
  ConnectionContext,
25
25
  ConnectionContext as ConnectionContext$1,
26
26
  PartyServerOptions,
27
+ RoutingRetryOptions,
27
28
  Server,
28
29
  WSMessage,
29
30
  WSMessage as WSMessage$1
@@ -846,7 +847,7 @@ declare class MCPClientConnection {
846
847
  */
847
848
  getTransport(
848
849
  transportType: BaseTransportType
849
- ): StreamableHTTPClientTransport | SSEClientTransport | RPCClientTransport;
850
+ ): RPCClientTransport | SSEClientTransport | StreamableHTTPClientTransport;
850
851
  private tryConnect;
851
852
  private _capabilityErrorHandler;
852
853
  }
@@ -1996,6 +1997,7 @@ declare class Agent<
1996
1997
  * parent-owned WebSocket handles during this window.
1997
1998
  */
1998
1999
  private _suppressProtocolBroadcasts;
2000
+ private _protocolBroadcastExcludeIds;
1999
2001
  private _cf_currentSubAgentBridge?;
2000
2002
  private _cf_virtualSubAgentConnections;
2001
2003
  /**
@@ -2234,7 +2236,7 @@ declare class Agent<
2234
2236
  *
2235
2237
  * IMPORTANT: This hook must be synchronous.
2236
2238
  */
2237
- validateStateChange(nextState: State, source: Connection | "server"): void;
2239
+ validateStateChange(_nextState: State, _source: Connection | "server"): void;
2238
2240
  /**
2239
2241
  * Called after the Agent's state has been persisted and broadcast to all clients.
2240
2242
  * This is a notification hook — errors here are routed to onError and do not
@@ -2243,7 +2245,10 @@ declare class Agent<
2243
2245
  * @param state Updated state
2244
2246
  * @param source Source of the state update ("server" or a client connection)
2245
2247
  */
2246
- onStateChanged(state: State | undefined, source: Connection | "server"): void;
2248
+ onStateChanged(
2249
+ _state: State | undefined,
2250
+ _source: Connection | "server"
2251
+ ): void;
2247
2252
  /**
2248
2253
  * @deprecated Renamed to `onStateChanged` — the behavior is identical.
2249
2254
  * `onStateUpdate` will be removed in the next major version.
@@ -2255,7 +2260,10 @@ declare class Agent<
2255
2260
  * @param state Updated state
2256
2261
  * @param source Source of the state update ("server" or a client connection)
2257
2262
  */
2258
- onStateUpdate(state: State | undefined, source: Connection | "server"): void;
2263
+ onStateUpdate(
2264
+ _state: State | undefined,
2265
+ _source: Connection | "server"
2266
+ ): void;
2259
2267
  /**
2260
2268
  * Dispatch to the appropriate persistence hook based on the mode
2261
2269
  * cached in the constructor. No prototype walks at call time.
@@ -2777,7 +2785,7 @@ declare class Agent<
2777
2785
  _cf_dispatchScheduledCallback(
2778
2786
  ownerPath: ReadonlyArray<AgentPathStep>,
2779
2787
  row: ScheduleStorageRow
2780
- ): Promise<void>;
2788
+ ): Promise<boolean>;
2781
2789
  /**
2782
2790
  * Recursively destroy a descendant facet identified by
2783
2791
  * `targetPath`. Walks down from `selfPath` until reaching the
@@ -3129,13 +3137,17 @@ declare class Agent<
3129
3137
  private _defaultAgentToolPreview;
3130
3138
  private _readAgentToolRun;
3131
3139
  private _resultFromAgentToolRow;
3140
+ private _agentToolRunInfoFromRow;
3132
3141
  private _terminalResultFromInspection;
3142
+ private _finishAgentToolRun;
3143
+ private _runDeferredAgentToolFinishHooks;
3133
3144
  private _updateAgentToolTerminal;
3134
3145
  private _markAgentToolRunning;
3135
3146
  private _parseAgentToolJson;
3136
3147
  private _stringifyAgentToolOutput;
3137
3148
  private _broadcastAgentToolEvent;
3138
3149
  private _broadcastAgentToolChunks;
3150
+ private _broadcastAgentToolStoredChunks;
3139
3151
  private _forwardAgentToolStream;
3140
3152
  private _broadcastAgentToolTerminal;
3141
3153
  private _asAgentToolChildAdapter;
@@ -3727,6 +3739,13 @@ type AgentContext = DurableObjectState;
3727
3739
  * Configuration options for Agent routing
3728
3740
  */
3729
3741
  type AgentOptions<Env> = PartyServerOptions<Env>;
3742
+ type AgentGetOptions<
3743
+ Env,
3744
+ Props extends Record<string, unknown> = Record<string, unknown>
3745
+ > = Pick<
3746
+ PartyServerOptions<Env, Props>,
3747
+ "jurisdiction" | "locationHint" | "props" | "routingRetry"
3748
+ >;
3730
3749
  /**
3731
3750
  * Route a request to the appropriate Agent
3732
3751
  * @param request Request to route
@@ -3789,11 +3808,7 @@ declare function getAgentByName<
3789
3808
  >(
3790
3809
  namespace: DurableObjectNamespace<T>,
3791
3810
  name: string,
3792
- options?: {
3793
- jurisdiction?: DurableObjectJurisdiction;
3794
- locationHint?: DurableObjectLocationHint;
3795
- props?: Props;
3796
- }
3811
+ options?: AgentGetOptions<Env, Props>
3797
3812
  ): Promise<DurableObjectStub<T>>;
3798
3813
  /**
3799
3814
  * A wrapper for streaming responses in callable methods
@@ -3982,93 +3997,95 @@ type AgentToolEventState = {
3982
3997
  };
3983
3998
  //#endregion
3984
3999
  export {
3985
- MCPClientManagerOptions as $,
3986
- FiberRecoveryContext as A,
3987
- SUB_PREFIX as At,
3988
- SqlError as B,
3989
- CallableMetadata as C,
3990
- TransportState as Ct,
3991
- EmailRoutingOptions as D,
3992
- StreamableHTTPEdgeClientTransport as Dt,
3993
- DEFAULT_AGENT_STATIC_OPTIONS as E,
3994
- SSEEdgeClientTransport as Et,
3995
- RPCRequest as F,
3996
- WSMessage$1 as G,
3997
- StreamingResponse as H,
3998
- RPCResponse as I,
3999
- getCurrentAgent as J,
4000
- callable as K,
4001
- Schedule as L,
4002
- MCPServerMessage as M,
4003
- getSubAgentByName as Mt,
4004
- MCPServersState as N,
4005
- parseSubAgentPath as Nt,
4006
- EmailSendBinding as O,
4007
- McpClientOptions as Ot,
4008
- QueueItem as P,
4009
- routeSubAgentRequest as Pt,
4010
- MCPClientManager as Q,
4011
- ScheduleCriteria as R,
4012
- AgentStaticOptions as S,
4013
- getMcpAuthContext as St,
4014
- ConnectionContext$1 as T,
4015
- WorkerTransportOptions as Tt,
4016
- SubAgentClass as U,
4017
- StateUpdateMessage as V,
4018
- SubAgentStub as W,
4019
- routeAgentRequest as X,
4020
- routeAgentEmail as Y,
4021
- unstable_callable as Z,
4000
+ unstable_callable as $,
4001
+ FiberContext as A,
4002
+ McpClientOptions as At,
4003
+ ScheduleCriteria as B,
4004
+ AgentStaticOptions as C,
4005
+ McpAuthContext as Ct,
4006
+ DEFAULT_AGENT_STATIC_OPTIONS as D,
4007
+ WorkerTransportOptions as Dt,
4008
+ ConnectionContext$1 as E,
4009
+ WorkerTransport as Et,
4010
+ QueueItem as F,
4011
+ parseSubAgentPath as Ft,
4012
+ SubAgentClass as G,
4013
+ SqlError as H,
4014
+ RPCRequest as I,
4015
+ routeSubAgentRequest as It,
4016
+ callable as J,
4017
+ SubAgentStub as K,
4018
+ RPCResponse as L,
4019
+ MCPServer as M,
4020
+ SUB_PREFIX as Mt,
4021
+ MCPServerMessage as N,
4022
+ SubAgentPathMatch as Nt,
4023
+ EmailRoutingOptions as O,
4024
+ SSEEdgeClientTransport as Ot,
4025
+ MCPServersState as P,
4026
+ getSubAgentByName as Pt,
4027
+ routeAgentRequest as Q,
4028
+ RoutingRetryOptions as R,
4029
+ AgentOptions as S,
4030
+ experimental_createMcpHandler as St,
4031
+ Connection$1 as T,
4032
+ TransportState as Tt,
4033
+ StateUpdateMessage as U,
4034
+ SendEmailOptions as V,
4035
+ StreamingResponse as W,
4036
+ getCurrentAgent as X,
4037
+ getAgentByName as Y,
4038
+ routeAgentEmail as Z,
4022
4039
  AddRpcMcpServerOptions as _,
4023
- McpAgent as _t,
4040
+ ElicitRequestSchema$1 as _t,
4024
4041
  AgentToolEventState as a,
4025
- MCPServerFilter as at,
4026
- AgentNamespace as b,
4027
- experimental_createMcpHandler as bt,
4042
+ MCPDiscoverResult as at,
4043
+ AgentGetOptions as b,
4044
+ CreateMcpHandlerOptions as bt,
4028
4045
  AgentToolRunInspection as c,
4029
- getNamespacedData as ct,
4046
+ MCPServerOptions as ct,
4030
4047
  AgentToolStoredChunk as d,
4031
- RPCServerTransport as dt,
4032
- MCPClientOAuthCallbackConfig as et,
4048
+ RPCClientTransport as dt,
4049
+ MCPClientManager as et,
4033
4050
  AgentToolTerminalStatus as f,
4034
- RPCServerTransportOptions as ft,
4051
+ RPCClientTransportOptions as ft,
4035
4052
  AddMcpServerOptions as g,
4036
- ElicitResult$1 as gt,
4053
+ ElicitRequest$1 as gt,
4037
4054
  RunAgentToolResult as h,
4038
- ElicitRequestSchema$1 as ht,
4055
+ RPC_DO_PREFIX as ht,
4039
4056
  AgentToolEventMessage as i,
4040
- MCPOAuthCallbackResult as it,
4041
- MCPServer as j,
4042
- SubAgentPathMatch as jt,
4043
- FiberContext as k,
4044
- TransportType as kt,
4057
+ MCPConnectionResult as it,
4058
+ FiberRecoveryContext as j,
4059
+ TransportType as jt,
4060
+ EmailSendBinding as k,
4061
+ StreamableHTTPEdgeClientTransport as kt,
4045
4062
  AgentToolRunState as l,
4046
- RPCClientTransport as lt,
4063
+ RegisterServerOptions as lt,
4047
4064
  RunAgentToolOptions as m,
4048
- ElicitRequest$1 as mt,
4065
+ RPCServerTransportOptions as mt,
4049
4066
  AgentToolDisplayMetadata as n,
4050
- MCPConnectionResult as nt,
4067
+ MCPClientOAuthCallbackConfig as nt,
4051
4068
  AgentToolLifecycleResult as o,
4052
- MCPServerOptions as ot,
4069
+ MCPOAuthCallbackResult as ot,
4053
4070
  ChatCapableAgentClass as p,
4054
- RPC_DO_PREFIX as pt,
4055
- getAgentByName as q,
4071
+ RPCServerTransport as pt,
4072
+ WSMessage$1 as q,
4056
4073
  AgentToolEvent as r,
4057
- MCPDiscoverResult as rt,
4074
+ MCPClientOAuthResult as rt,
4058
4075
  AgentToolRunInfo as s,
4059
- RegisterServerOptions as st,
4076
+ MCPServerFilter as st,
4060
4077
  AgentToolChildAdapter as t,
4061
- MCPClientOAuthResult as tt,
4078
+ MCPClientManagerOptions as tt,
4062
4079
  AgentToolRunStatus as u,
4063
- RPCClientTransportOptions as ut,
4080
+ getNamespacedData as ut,
4064
4081
  Agent as v,
4065
- CreateMcpHandlerOptions as vt,
4066
- Connection$1 as w,
4067
- WorkerTransport as wt,
4068
- AgentOptions as x,
4069
- McpAuthContext as xt,
4082
+ ElicitResult$1 as vt,
4083
+ CallableMetadata as w,
4084
+ getMcpAuthContext as wt,
4085
+ AgentNamespace as x,
4086
+ createMcpHandler as xt,
4070
4087
  AgentContext as y,
4071
- createMcpHandler as yt,
4072
- SendEmailOptions as z
4088
+ McpAgent as yt,
4089
+ Schedule as z
4073
4090
  };
4074
- //# sourceMappingURL=agent-tool-types-DSteYkkS.d.ts.map
4091
+ //# sourceMappingURL=agent-tool-types-CM_50fcV.d.ts.map
@@ -14,7 +14,7 @@ import {
14
14
  s as AgentToolRunInfo,
15
15
  t as AgentToolChildAdapter,
16
16
  u as AgentToolRunStatus
17
- } from "./agent-tool-types-DSteYkkS.js";
17
+ } from "./agent-tool-types-CM_50fcV.js";
18
18
  export {
19
19
  AgentToolChildAdapter,
20
20
  AgentToolDisplayMetadata,
@@ -1 +1 @@
1
- {"version":3,"file":"agent-tools-BAdX1vdI.js","names":[],"sources":["../src/chat/message-builder.ts","../src/chat/agent-tools.ts"],"sourcesContent":["/**\n * Shared message builder for reconstructing UIMessage parts from stream chunks.\n *\n * Used by both @cloudflare/ai-chat (server + client) and @cloudflare/think\n * to avoid duplicating the chunk-type switch/case logic.\n *\n * Operates on a mutable parts array for performance (avoids allocating new arrays\n * on every chunk during streaming).\n */\n\nimport type { UIMessage } from \"ai\";\n\n/** The parts array type from UIMessage */\nexport type MessageParts = UIMessage[\"parts\"];\n\n/** A single part from the UIMessage parts array */\nexport type MessagePart = MessageParts[number];\n\n/**\n * Parsed chunk data from an AI SDK stream event.\n * This is the JSON-parsed body of a CF_AGENT_USE_CHAT_RESPONSE message,\n * or the `data:` payload of an SSE line.\n */\nexport type StreamChunkData = {\n type: string;\n id?: string;\n delta?: string;\n text?: string;\n mediaType?: string;\n url?: string;\n sourceId?: string;\n title?: string;\n filename?: string;\n toolCallId?: string;\n toolName?: string;\n input?: unknown;\n inputTextDelta?: string;\n output?: unknown;\n state?: string;\n errorText?: string;\n /** When true, the output is preliminary (may be updated by a later chunk) */\n preliminary?: boolean;\n /** Approval ID for tools with needsApproval */\n approvalId?: string;\n providerMetadata?: Record<string, unknown>;\n /** Whether the tool was executed by the provider (e.g. Gemini code execution) */\n providerExecuted?: boolean;\n /** Payload for data-* parts (developer-defined typed JSON) */\n data?: unknown;\n /** When true, data parts are ephemeral and not persisted to message.parts */\n transient?: boolean;\n /** Message ID assigned by the server at stream start */\n messageId?: string;\n /** Per-message metadata attached by start/finish/message-metadata chunks */\n messageMetadata?: unknown;\n [key: string]: unknown;\n};\n\n/**\n * Applies a stream chunk to a mutable parts array, building up the message\n * incrementally. Returns true if the chunk was handled, false if it was\n * an unrecognized type (caller may handle it with additional logic).\n *\n * Handles all common chunk types that both server and client need:\n * - text-start / text-delta / text-end\n * - reasoning-start / reasoning-delta / reasoning-end\n * - file\n * - source-url / source-document\n * - tool-input-start / tool-input-delta / tool-input-available / tool-input-error\n * - tool-output-available / tool-output-error\n * - step-start (aliased from start-step)\n * - data-* (developer-defined typed JSON blobs)\n *\n * @param parts - The mutable parts array to update\n * @param chunk - The parsed stream chunk data\n * @returns true if handled, false if the chunk type is not recognized\n */\nexport function applyChunkToParts(\n parts: MessagePart[],\n chunk: StreamChunkData\n): boolean {\n switch (chunk.type) {\n case \"text-start\": {\n parts.push({\n type: \"text\",\n text: \"\",\n state: \"streaming\"\n } as MessagePart);\n return true;\n }\n\n case \"text-delta\": {\n const lastTextPart = findLastPartByType(parts, \"text\");\n if (lastTextPart && lastTextPart.type === \"text\") {\n (lastTextPart as { text: string }).text += chunk.delta ?? \"\";\n } else {\n // No text-start received — create a new text part (stream resumption fallback)\n parts.push({\n type: \"text\",\n text: chunk.delta ?? \"\",\n state: \"streaming\"\n } as MessagePart);\n }\n return true;\n }\n\n case \"text-end\": {\n const lastTextPart = findLastPartByType(parts, \"text\");\n if (lastTextPart && \"state\" in lastTextPart) {\n (lastTextPart as { state: string }).state = \"done\";\n }\n return true;\n }\n\n case \"reasoning-start\": {\n parts.push({\n type: \"reasoning\",\n text: \"\",\n state: \"streaming\"\n } as MessagePart);\n return true;\n }\n\n case \"reasoning-delta\": {\n const lastReasoningPart = findLastPartByType(parts, \"reasoning\");\n if (lastReasoningPart && lastReasoningPart.type === \"reasoning\") {\n (lastReasoningPart as { text: string }).text += chunk.delta ?? \"\";\n mergeProviderMetadata(lastReasoningPart, chunk.providerMetadata);\n } else {\n // No reasoning-start received — create a new reasoning part (stream resumption fallback)\n parts.push({\n type: \"reasoning\",\n text: chunk.delta ?? \"\",\n state: \"streaming\",\n ...(chunk.providerMetadata != null\n ? { providerMetadata: chunk.providerMetadata }\n : {})\n } as MessagePart);\n }\n return true;\n }\n\n case \"reasoning-end\": {\n const lastReasoningPart = findLastPartByType(parts, \"reasoning\");\n if (lastReasoningPart && \"state\" in lastReasoningPart) {\n (lastReasoningPart as { state: string }).state = \"done\";\n mergeProviderMetadata(lastReasoningPart, chunk.providerMetadata);\n }\n return true;\n }\n\n case \"file\": {\n parts.push({\n type: \"file\",\n mediaType: chunk.mediaType,\n url: chunk.url\n } as MessagePart);\n return true;\n }\n\n case \"source-url\": {\n parts.push({\n type: \"source-url\",\n sourceId: chunk.sourceId,\n url: chunk.url,\n title: chunk.title,\n providerMetadata: chunk.providerMetadata\n } as MessagePart);\n return true;\n }\n\n case \"source-document\": {\n parts.push({\n type: \"source-document\",\n sourceId: chunk.sourceId,\n mediaType: chunk.mediaType,\n title: chunk.title,\n filename: chunk.filename,\n providerMetadata: chunk.providerMetadata\n } as MessagePart);\n return true;\n }\n\n case \"tool-input-start\": {\n // Idempotent against an existing tool part with the same toolCallId.\n // Some providers (notably the OpenAI Responses API) replay prior\n // tool calls in continuation streams as a fresh `tool-input-start`\n // → `tool-input-delta` → `tool-input-available` →\n // `tool-output-available` sequence carrying the original toolCallId\n // and original output. Without this guard a replay would push a\n // duplicate part into the streaming message *and* clobber the\n // original part's state when the AI SDK's mutate-in-place\n // `updateToolPart` processes the replay on the client (issue #1404).\n // A model that genuinely wants a fresh tool call always emits a\n // new toolCallId, so an existing match is never a legitimate\n // \"start over\".\n const existing = findToolPartByCallId(parts, chunk.toolCallId);\n if (existing) {\n return true;\n }\n parts.push({\n type: `tool-${chunk.toolName}`,\n toolCallId: chunk.toolCallId,\n toolName: chunk.toolName,\n state: \"input-streaming\",\n input: undefined,\n ...(chunk.providerExecuted != null\n ? { providerExecuted: chunk.providerExecuted }\n : {}),\n ...(chunk.providerMetadata != null\n ? { callProviderMetadata: chunk.providerMetadata }\n : {}),\n ...(chunk.title != null ? { title: chunk.title } : {})\n } as MessagePart);\n return true;\n }\n\n case \"tool-input-delta\": {\n // Only mutate input while the tool is still actively input-streaming.\n // Deltas arriving after the tool has already advanced (input-available\n // or any terminal state) are provider replay and must not regress\n // a fully-formed input back to a partial one.\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (\n toolPart &&\n (toolPart as Record<string, unknown>).state === \"input-streaming\"\n ) {\n (toolPart as Record<string, unknown>).input = chunk.input;\n }\n return true;\n }\n\n case \"tool-input-available\": {\n const existing = findToolPartByCallId(parts, chunk.toolCallId);\n if (existing) {\n const p = existing as Record<string, unknown>;\n // Only advance from the streaming-input phase. Once the tool is\n // already at input-available or any terminal state\n // (output-available, output-error, output-denied,\n // approval-requested, approval-responded), this chunk is a\n // provider replay and must not regress state or overwrite a\n // resolved input/output. See the comment on tool-input-start.\n if (p.state === \"input-streaming\") {\n p.state = \"input-available\";\n p.input = chunk.input;\n if (chunk.providerExecuted != null) {\n p.providerExecuted = chunk.providerExecuted;\n }\n if (chunk.providerMetadata != null) {\n p.callProviderMetadata = chunk.providerMetadata;\n }\n if (chunk.title != null) {\n p.title = chunk.title;\n }\n }\n return true;\n }\n parts.push({\n type: `tool-${chunk.toolName}`,\n toolCallId: chunk.toolCallId,\n toolName: chunk.toolName,\n state: \"input-available\",\n input: chunk.input,\n ...(chunk.providerExecuted != null\n ? { providerExecuted: chunk.providerExecuted }\n : {}),\n ...(chunk.providerMetadata != null\n ? { callProviderMetadata: chunk.providerMetadata }\n : {}),\n ...(chunk.title != null ? { title: chunk.title } : {})\n } as MessagePart);\n return true;\n }\n\n case \"tool-input-error\": {\n const existing = findToolPartByCallId(parts, chunk.toolCallId);\n if (existing) {\n const p = existing as Record<string, unknown>;\n // First-write-wins: a tool that's already terminal must not be\n // regressed (or re-decided as an error) by a later chunk. A\n // tool-input-error here is either provider replay or a confused\n // upstream — preserve the existing terminal state.\n if (\n p.state === \"output-available\" ||\n p.state === \"output-error\" ||\n p.state === \"output-denied\"\n ) {\n return true;\n }\n p.state = \"output-error\";\n p.errorText = chunk.errorText;\n p.input = chunk.input;\n if (chunk.providerExecuted != null) {\n p.providerExecuted = chunk.providerExecuted;\n }\n if (chunk.providerMetadata != null) {\n p.callProviderMetadata = chunk.providerMetadata;\n }\n } else {\n parts.push({\n type: `tool-${chunk.toolName}`,\n toolCallId: chunk.toolCallId,\n toolName: chunk.toolName,\n state: \"output-error\",\n input: chunk.input,\n errorText: chunk.errorText,\n ...(chunk.providerExecuted != null\n ? { providerExecuted: chunk.providerExecuted }\n : {}),\n ...(chunk.providerMetadata != null\n ? { callProviderMetadata: chunk.providerMetadata }\n : {})\n } as MessagePart);\n }\n return true;\n }\n\n case \"tool-approval-request\": {\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (toolPart) {\n const p = toolPart as Record<string, unknown>;\n p.state = \"approval-requested\";\n p.approval = { id: chunk.approvalId };\n }\n return true;\n }\n\n case \"tool-output-denied\": {\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (toolPart) {\n const p = toolPart as Record<string, unknown>;\n p.state = \"output-denied\";\n }\n return true;\n }\n\n case \"tool-output-available\": {\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (toolPart) {\n const p = toolPart as Record<string, unknown>;\n p.state = \"output-available\";\n p.output = chunk.output;\n if (chunk.preliminary !== undefined) {\n p.preliminary = chunk.preliminary;\n }\n }\n return true;\n }\n\n case \"tool-output-error\": {\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (toolPart) {\n const p = toolPart as Record<string, unknown>;\n p.state = \"output-error\";\n p.errorText = chunk.errorText;\n }\n return true;\n }\n\n // Both \"step-start\" (client convention) and \"start-step\" (server convention)\n case \"step-start\":\n case \"start-step\": {\n parts.push({ type: \"step-start\" } as MessagePart);\n return true;\n }\n\n default: {\n // https://ai-sdk.dev/docs/ai-sdk-ui/streaming-data\n if (chunk.type.startsWith(\"data-\")) {\n // Transient parts are ephemeral — the AI SDK client fires an onData\n // callback instead of adding them to message.parts. On the server we\n // still broadcast them (so connected clients see them in real time)\n // but skip persisting them into the stored message parts.\n if (chunk.transient) {\n return true;\n }\n\n // Reconciliation: if a part with the same type AND id already exists,\n // update its data in-place instead of appending a duplicate.\n if (chunk.id != null) {\n const existing = findDataPartByTypeAndId(parts, chunk.type, chunk.id);\n if (existing) {\n (existing as Record<string, unknown>).data = chunk.data;\n return true;\n }\n }\n\n // Append new data parts to the array directly.\n // Note: `chunk.data` should always be provided — if omitted, the\n // persisted part will have `data: undefined` which JSON.stringify\n // drops, so the part will have no `data` field on reload.\n // The cast is needed because UIMessage[\"parts\"] doesn't include\n // data-* types in its union because they're an open extension point.\n parts.push({\n type: chunk.type,\n ...(chunk.id != null && { id: chunk.id }),\n data: chunk.data\n } as MessagePart);\n return true;\n }\n\n return false;\n }\n }\n}\n\n/**\n * Returns true if `chunk` would be a no-op replay against the already-known\n * `parts` — i.e. some upstream is re-emitting events for a tool call that\n * the message has already advanced past.\n *\n * Used by stream broadcasters to suppress re-broadcasting these chunks to\n * connected clients. AI SDK v6's `updateToolPart` mutates an existing tool\n * part in place when a chunk arrives with a matching `toolCallId`, so a\n * replayed `tool-input-start` would clobber an `output-available` part back\n * to `input-streaming` on the client (issue #1404).\n *\n * Only returns true when re-broadcasting would *visibly regress* state on\n * a v6 client. Safe-by-construction chunk types (e.g. `tool-output-available`\n * carrying the same output the part already has) return false.\n *\n * Conditions:\n * - `tool-input-start` for a `toolCallId` that already exists in `parts`.\n * - `tool-input-delta` for a `toolCallId` whose existing part is no longer\n * `input-streaming`.\n * - `tool-input-available` for a `toolCallId` whose existing part is no\n * longer `input-streaming` (i.e. has already advanced to `input-available`\n * or any terminal state).\n */\nexport function isReplayChunk(\n parts: MessagePart[],\n chunk: StreamChunkData\n): boolean {\n if (\n chunk.type !== \"tool-input-start\" &&\n chunk.type !== \"tool-input-delta\" &&\n chunk.type !== \"tool-input-available\"\n ) {\n return false;\n }\n if (!chunk.toolCallId) return false;\n const existing = findToolPartByCallId(parts, chunk.toolCallId);\n if (!existing) return false;\n if (chunk.type === \"tool-input-start\") return true;\n const state = (existing as Record<string, unknown>).state;\n return state !== \"input-streaming\";\n}\n\n/**\n * Finds the last part in the array matching the given type.\n * Searches from the end for efficiency (the part we want is usually recent).\n */\nfunction findLastPartByType(\n parts: MessagePart[],\n type: string\n): MessagePart | undefined {\n for (let i = parts.length - 1; i >= 0; i--) {\n if (parts[i].type === type) {\n return parts[i];\n }\n }\n return undefined;\n}\n\n/**\n * Finds a tool part by its toolCallId.\n * Searches from the end since the tool part is usually recent.\n */\nfunction findToolPartByCallId(\n parts: MessagePart[],\n toolCallId: string | undefined\n): MessagePart | undefined {\n if (!toolCallId) return undefined;\n for (let i = parts.length - 1; i >= 0; i--) {\n const p = parts[i];\n if (\"toolCallId\" in p && p.toolCallId === toolCallId) {\n return p;\n }\n }\n return undefined;\n}\n\n/**\n * Shallow-merges providerMetadata from a chunk onto an existing part.\n * Preserves any metadata already on the part (e.g. from earlier deltas)\n * while adding new keys from the chunk. This is critical for providers\n * like Anthropic that emit the thinking block signature on reasoning-end.\n */\nfunction mergeProviderMetadata(\n part: MessagePart,\n metadata: Record<string, unknown> | undefined\n): void {\n if (metadata == null) return;\n const p = part as Record<string, unknown>;\n p.providerMetadata = {\n ...(p.providerMetadata as Record<string, unknown> | undefined),\n ...metadata\n };\n}\n\n/**\n * Finds a data part by its type and id for reconciliation.\n * Data parts use type+id as a composite key so when the same combination\n * is seen again, the existing part's data is updated in-place.\n */\nfunction findDataPartByTypeAndId(\n parts: MessagePart[],\n type: string,\n id: string\n): MessagePart | undefined {\n for (let i = parts.length - 1; i >= 0; i--) {\n const p = parts[i];\n if (p.type === type && \"id\" in p && (p as { id: string }).id === id) {\n return p;\n }\n }\n return undefined;\n}\n","import { applyChunkToParts } from \"./message-builder\";\nimport type {\n AgentToolEventMessage,\n AgentToolEventState,\n AgentToolRunState\n} from \"../agent-tool-types\";\n\nfunction sortRuns(runs: AgentToolRunState[]): AgentToolRunState[] {\n return [...runs].sort((a, b) => {\n if (a.order !== b.order) return a.order - b.order;\n return a.runId.localeCompare(b.runId);\n });\n}\n\nfunction rebuildIndexes(\n runsById: Record<string, AgentToolRunState>\n): Pick<AgentToolEventState, \"runsByToolCallId\" | \"unboundRuns\"> {\n const grouped: Record<string, AgentToolRunState[]> = {};\n const unboundRuns: AgentToolRunState[] = [];\n for (const run of Object.values(runsById)) {\n if (run.parentToolCallId) {\n grouped[run.parentToolCallId] = grouped[run.parentToolCallId] ?? [];\n grouped[run.parentToolCallId].push(run);\n } else {\n unboundRuns.push(run);\n }\n }\n for (const [toolCallId, runs] of Object.entries(grouped)) {\n grouped[toolCallId] = sortRuns(runs);\n }\n return { runsByToolCallId: grouped, unboundRuns: sortRuns(unboundRuns) };\n}\n\nfunction emptyRun(\n message: AgentToolEventMessage\n): AgentToolRunState | undefined {\n const { event } = message;\n if (event.kind === \"started\") {\n return {\n runId: event.runId,\n agentType: event.agentType,\n parentToolCallId: message.parentToolCallId,\n inputPreview: event.inputPreview,\n order: event.order,\n display: event.display,\n status: \"running\",\n parts: [],\n subAgent: { agent: event.agentType, name: event.runId }\n };\n }\n return undefined;\n}\n\nfunction applyToRun(\n prev: AgentToolRunState | undefined,\n message: AgentToolEventMessage\n): AgentToolRunState | undefined {\n const seeded = prev ?? emptyRun(message);\n const { event } = message;\n\n switch (event.kind) {\n case \"started\":\n if (\n seeded?.status === \"completed\" ||\n seeded?.status === \"error\" ||\n seeded?.status === \"aborted\" ||\n seeded?.status === \"interrupted\"\n ) {\n return seeded;\n }\n return {\n ...seeded,\n runId: event.runId,\n agentType: event.agentType,\n parentToolCallId: message.parentToolCallId,\n inputPreview: event.inputPreview,\n order: event.order,\n display: event.display,\n status: \"running\",\n parts: seeded?.parts ?? [],\n subAgent: { agent: event.agentType, name: event.runId }\n };\n case \"chunk\": {\n if (!seeded) return undefined;\n const parts = [...seeded.parts];\n try {\n applyChunkToParts(parts, JSON.parse(event.body));\n } catch {\n return seeded;\n }\n return { ...seeded, parts };\n }\n case \"finished\":\n if (!seeded) return undefined;\n return {\n ...seeded,\n status: \"completed\",\n summary: event.summary,\n error: undefined\n };\n case \"error\":\n if (!seeded) return undefined;\n return { ...seeded, status: \"error\", error: event.error };\n case \"aborted\":\n if (!seeded) return undefined;\n return { ...seeded, status: \"aborted\", error: event.reason };\n case \"interrupted\":\n if (!seeded) return undefined;\n return { ...seeded, status: \"interrupted\", error: event.error };\n }\n}\n\nexport function createAgentToolEventState(): AgentToolEventState {\n return {\n runsById: {},\n runsByToolCallId: {},\n unboundRuns: []\n };\n}\n\nexport function applyAgentToolEvent(\n state: AgentToolEventState,\n message: AgentToolEventMessage\n): AgentToolEventState {\n if (message.type !== \"agent-tool-event\") return state;\n const runId = message.event.runId;\n const nextRun = applyToRun(state.runsById[runId], message);\n if (!nextRun) return state;\n\n const runsById = { ...state.runsById, [runId]: nextRun };\n return { runsById, ...rebuildIndexes(runsById) };\n}\n\nexport type {\n AgentToolEvent,\n AgentToolEventMessage,\n AgentToolEventState,\n AgentToolRunState\n} from \"../agent-tool-types\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"agent-tools-BAdX1vdI.js","names":[],"sources":["../src/chat/message-builder.ts","../src/chat/agent-tools.ts"],"sourcesContent":["/**\n * Shared message builder for reconstructing UIMessage parts from stream chunks.\n *\n * Used by both @cloudflare/ai-chat (server + client) and @cloudflare/think\n * to avoid duplicating the chunk-type switch/case logic.\n *\n * Operates on a mutable parts array for performance (avoids allocating new arrays\n * on every chunk during streaming).\n */\n\nimport type { UIMessage } from \"ai\";\n\n/** The parts array type from UIMessage */\nexport type MessageParts = UIMessage[\"parts\"];\n\n/** A single part from the UIMessage parts array */\nexport type MessagePart = MessageParts[number];\n\n/**\n * Parsed chunk data from an AI SDK stream event.\n * This is the JSON-parsed body of a CF_AGENT_USE_CHAT_RESPONSE message,\n * or the `data:` payload of an SSE line.\n */\nexport type StreamChunkData = {\n type: string;\n id?: string;\n delta?: string;\n text?: string;\n mediaType?: string;\n url?: string;\n sourceId?: string;\n title?: string;\n filename?: string;\n toolCallId?: string;\n toolName?: string;\n input?: unknown;\n inputTextDelta?: string;\n output?: unknown;\n state?: string;\n errorText?: string;\n /** When true, the output is preliminary (may be updated by a later chunk) */\n preliminary?: boolean;\n /** Approval ID for tools with needsApproval */\n approvalId?: string;\n providerMetadata?: Record<string, unknown>;\n /** Whether the tool was executed by the provider (e.g. Gemini code execution) */\n providerExecuted?: boolean;\n /** Payload for data-* parts (developer-defined typed JSON) */\n data?: unknown;\n /** When true, data parts are ephemeral and not persisted to message.parts */\n transient?: boolean;\n /** Message ID assigned by the server at stream start */\n messageId?: string;\n /** Per-message metadata attached by start/finish/message-metadata chunks */\n messageMetadata?: unknown;\n [key: string]: unknown;\n};\n\n/**\n * Applies a stream chunk to a mutable parts array, building up the message\n * incrementally. Returns true if the chunk was handled, false if it was\n * an unrecognized type (caller may handle it with additional logic).\n *\n * Handles all common chunk types that both server and client need:\n * - text-start / text-delta / text-end\n * - reasoning-start / reasoning-delta / reasoning-end\n * - file\n * - source-url / source-document\n * - tool-input-start / tool-input-delta / tool-input-available / tool-input-error\n * - tool-output-available / tool-output-error\n * - step-start (aliased from start-step)\n * - data-* (developer-defined typed JSON blobs)\n *\n * @param parts - The mutable parts array to update\n * @param chunk - The parsed stream chunk data\n * @returns true if handled, false if the chunk type is not recognized\n */\nexport function applyChunkToParts(\n parts: MessagePart[],\n chunk: StreamChunkData\n): boolean {\n switch (chunk.type) {\n case \"text-start\": {\n parts.push({\n type: \"text\",\n text: \"\",\n state: \"streaming\"\n } as MessagePart);\n return true;\n }\n\n case \"text-delta\": {\n const lastTextPart = findLastPartByType(parts, \"text\");\n if (lastTextPart && lastTextPart.type === \"text\") {\n (lastTextPart as { text: string }).text += chunk.delta ?? \"\";\n } else {\n // No text-start received — create a new text part (stream resumption fallback)\n parts.push({\n type: \"text\",\n text: chunk.delta ?? \"\",\n state: \"streaming\"\n } as MessagePart);\n }\n return true;\n }\n\n case \"text-end\": {\n const lastTextPart = findLastPartByType(parts, \"text\");\n if (lastTextPart && \"state\" in lastTextPart) {\n (lastTextPart as { state: string }).state = \"done\";\n }\n return true;\n }\n\n case \"reasoning-start\": {\n parts.push({\n type: \"reasoning\",\n text: \"\",\n state: \"streaming\"\n } as MessagePart);\n return true;\n }\n\n case \"reasoning-delta\": {\n const lastReasoningPart = findLastPartByType(parts, \"reasoning\");\n if (lastReasoningPart && lastReasoningPart.type === \"reasoning\") {\n (lastReasoningPart as { text: string }).text += chunk.delta ?? \"\";\n mergeProviderMetadata(lastReasoningPart, chunk.providerMetadata);\n } else {\n // No reasoning-start received — create a new reasoning part (stream resumption fallback)\n parts.push({\n type: \"reasoning\",\n text: chunk.delta ?? \"\",\n state: \"streaming\",\n ...(chunk.providerMetadata != null\n ? { providerMetadata: chunk.providerMetadata }\n : {})\n } as MessagePart);\n }\n return true;\n }\n\n case \"reasoning-end\": {\n const lastReasoningPart = findLastPartByType(parts, \"reasoning\");\n if (lastReasoningPart && \"state\" in lastReasoningPart) {\n (lastReasoningPart as { state: string }).state = \"done\";\n mergeProviderMetadata(lastReasoningPart, chunk.providerMetadata);\n }\n return true;\n }\n\n case \"file\": {\n parts.push({\n type: \"file\",\n mediaType: chunk.mediaType,\n url: chunk.url\n } as MessagePart);\n return true;\n }\n\n case \"source-url\": {\n parts.push({\n type: \"source-url\",\n sourceId: chunk.sourceId,\n url: chunk.url,\n title: chunk.title,\n providerMetadata: chunk.providerMetadata\n } as MessagePart);\n return true;\n }\n\n case \"source-document\": {\n parts.push({\n type: \"source-document\",\n sourceId: chunk.sourceId,\n mediaType: chunk.mediaType,\n title: chunk.title,\n filename: chunk.filename,\n providerMetadata: chunk.providerMetadata\n } as MessagePart);\n return true;\n }\n\n case \"tool-input-start\": {\n // Idempotent against an existing tool part with the same toolCallId.\n // Some providers (notably the OpenAI Responses API) replay prior\n // tool calls in continuation streams as a fresh `tool-input-start`\n // → `tool-input-delta` → `tool-input-available` →\n // `tool-output-available` sequence carrying the original toolCallId\n // and original output. Without this guard a replay would push a\n // duplicate part into the streaming message *and* clobber the\n // original part's state when the AI SDK's mutate-in-place\n // `updateToolPart` processes the replay on the client (issue #1404).\n // A model that genuinely wants a fresh tool call always emits a\n // new toolCallId, so an existing match is never a legitimate\n // \"start over\".\n const existing = findToolPartByCallId(parts, chunk.toolCallId);\n if (existing) {\n return true;\n }\n parts.push({\n type: `tool-${chunk.toolName}`,\n toolCallId: chunk.toolCallId,\n toolName: chunk.toolName,\n state: \"input-streaming\",\n input: undefined,\n ...(chunk.providerExecuted != null\n ? { providerExecuted: chunk.providerExecuted }\n : {}),\n ...(chunk.providerMetadata != null\n ? { callProviderMetadata: chunk.providerMetadata }\n : {}),\n ...(chunk.title != null ? { title: chunk.title } : {})\n } as MessagePart);\n return true;\n }\n\n case \"tool-input-delta\": {\n // Only mutate input while the tool is still actively input-streaming.\n // Deltas arriving after the tool has already advanced (input-available\n // or any terminal state) are provider replay and must not regress\n // a fully-formed input back to a partial one.\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (\n toolPart &&\n (toolPart as Record<string, unknown>).state === \"input-streaming\"\n ) {\n (toolPart as Record<string, unknown>).input = chunk.input;\n }\n return true;\n }\n\n case \"tool-input-available\": {\n const existing = findToolPartByCallId(parts, chunk.toolCallId);\n if (existing) {\n const p = existing as Record<string, unknown>;\n // Only advance from the streaming-input phase. Once the tool is\n // already at input-available or any terminal state\n // (output-available, output-error, output-denied,\n // approval-requested, approval-responded), this chunk is a\n // provider replay and must not regress state or overwrite a\n // resolved input/output. See the comment on tool-input-start.\n if (p.state === \"input-streaming\") {\n p.state = \"input-available\";\n p.input = chunk.input;\n if (chunk.providerExecuted != null) {\n p.providerExecuted = chunk.providerExecuted;\n }\n if (chunk.providerMetadata != null) {\n p.callProviderMetadata = chunk.providerMetadata;\n }\n if (chunk.title != null) {\n p.title = chunk.title;\n }\n }\n return true;\n }\n parts.push({\n type: `tool-${chunk.toolName}`,\n toolCallId: chunk.toolCallId,\n toolName: chunk.toolName,\n state: \"input-available\",\n input: chunk.input,\n ...(chunk.providerExecuted != null\n ? { providerExecuted: chunk.providerExecuted }\n : {}),\n ...(chunk.providerMetadata != null\n ? { callProviderMetadata: chunk.providerMetadata }\n : {}),\n ...(chunk.title != null ? { title: chunk.title } : {})\n } as MessagePart);\n return true;\n }\n\n case \"tool-input-error\": {\n const existing = findToolPartByCallId(parts, chunk.toolCallId);\n if (existing) {\n const p = existing as Record<string, unknown>;\n // First-write-wins: a tool that's already terminal must not be\n // regressed (or re-decided as an error) by a later chunk. A\n // tool-input-error here is either provider replay or a confused\n // upstream — preserve the existing terminal state.\n if (\n p.state === \"output-available\" ||\n p.state === \"output-error\" ||\n p.state === \"output-denied\"\n ) {\n return true;\n }\n p.state = \"output-error\";\n p.errorText = chunk.errorText;\n p.input = chunk.input;\n if (chunk.providerExecuted != null) {\n p.providerExecuted = chunk.providerExecuted;\n }\n if (chunk.providerMetadata != null) {\n p.callProviderMetadata = chunk.providerMetadata;\n }\n } else {\n parts.push({\n type: `tool-${chunk.toolName}`,\n toolCallId: chunk.toolCallId,\n toolName: chunk.toolName,\n state: \"output-error\",\n input: chunk.input,\n errorText: chunk.errorText,\n ...(chunk.providerExecuted != null\n ? { providerExecuted: chunk.providerExecuted }\n : {}),\n ...(chunk.providerMetadata != null\n ? { callProviderMetadata: chunk.providerMetadata }\n : {})\n } as MessagePart);\n }\n return true;\n }\n\n case \"tool-approval-request\": {\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (toolPart) {\n const p = toolPart as Record<string, unknown>;\n p.state = \"approval-requested\";\n p.approval = { id: chunk.approvalId };\n }\n return true;\n }\n\n case \"tool-output-denied\": {\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (toolPart) {\n const p = toolPart as Record<string, unknown>;\n p.state = \"output-denied\";\n }\n return true;\n }\n\n case \"tool-output-available\": {\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (toolPart) {\n const p = toolPart as Record<string, unknown>;\n p.state = \"output-available\";\n p.output = chunk.output;\n if (chunk.preliminary !== undefined) {\n p.preliminary = chunk.preliminary;\n }\n }\n return true;\n }\n\n case \"tool-output-error\": {\n const toolPart = findToolPartByCallId(parts, chunk.toolCallId);\n if (toolPart) {\n const p = toolPart as Record<string, unknown>;\n p.state = \"output-error\";\n p.errorText = chunk.errorText;\n }\n return true;\n }\n\n // Both \"step-start\" (client convention) and \"start-step\" (server convention)\n case \"step-start\":\n case \"start-step\": {\n parts.push({ type: \"step-start\" } as MessagePart);\n return true;\n }\n\n default: {\n // https://ai-sdk.dev/docs/ai-sdk-ui/streaming-data\n if (chunk.type.startsWith(\"data-\")) {\n // Transient parts are ephemeral — the AI SDK client fires an onData\n // callback instead of adding them to message.parts. On the server we\n // still broadcast them (so connected clients see them in real time)\n // but skip persisting them into the stored message parts.\n if (chunk.transient) {\n return true;\n }\n\n // Reconciliation: if a part with the same type AND id already exists,\n // update its data in-place instead of appending a duplicate.\n if (chunk.id != null) {\n const existing = findDataPartByTypeAndId(parts, chunk.type, chunk.id);\n if (existing) {\n (existing as Record<string, unknown>).data = chunk.data;\n return true;\n }\n }\n\n // Append new data parts to the array directly.\n // Note: `chunk.data` should always be provided — if omitted, the\n // persisted part will have `data: undefined` which JSON.stringify\n // drops, so the part will have no `data` field on reload.\n // The cast is needed because UIMessage[\"parts\"] doesn't include\n // data-* types in its union because they're an open extension point.\n parts.push({\n type: chunk.type,\n ...(chunk.id != null && { id: chunk.id }),\n data: chunk.data\n } as MessagePart);\n return true;\n }\n\n return false;\n }\n }\n}\n\n/**\n * Returns true if `chunk` would be a no-op replay against the already-known\n * `parts` — i.e. some upstream is re-emitting events for a tool call that\n * the message has already advanced past.\n *\n * Used by stream broadcasters to suppress re-broadcasting these chunks to\n * connected clients. AI SDK v6's `updateToolPart` mutates an existing tool\n * part in place when a chunk arrives with a matching `toolCallId`, so a\n * replayed `tool-input-start` would clobber an `output-available` part back\n * to `input-streaming` on the client (issue #1404).\n *\n * Only returns true when re-broadcasting would *visibly regress* state on\n * a v6 client. Safe-by-construction chunk types (e.g. `tool-output-available`\n * carrying the same output the part already has) return false.\n *\n * Conditions:\n * - `tool-input-start` for a `toolCallId` that already exists in `parts`.\n * - `tool-input-delta` for a `toolCallId` whose existing part is no longer\n * `input-streaming`.\n * - `tool-input-available` for a `toolCallId` whose existing part is no\n * longer `input-streaming` (i.e. has already advanced to `input-available`\n * or any terminal state).\n */\nexport function isReplayChunk(\n parts: MessagePart[],\n chunk: StreamChunkData\n): boolean {\n if (\n chunk.type !== \"tool-input-start\" &&\n chunk.type !== \"tool-input-delta\" &&\n chunk.type !== \"tool-input-available\"\n ) {\n return false;\n }\n if (!chunk.toolCallId) return false;\n const existing = findToolPartByCallId(parts, chunk.toolCallId);\n if (!existing) return false;\n if (chunk.type === \"tool-input-start\") return true;\n const state = (existing as Record<string, unknown>).state;\n return state !== \"input-streaming\";\n}\n\n/**\n * Finds the last part in the array matching the given type.\n * Searches from the end for efficiency (the part we want is usually recent).\n */\nfunction findLastPartByType(\n parts: MessagePart[],\n type: string\n): MessagePart | undefined {\n for (let i = parts.length - 1; i >= 0; i--) {\n if (parts[i].type === type) {\n return parts[i];\n }\n }\n return undefined;\n}\n\n/**\n * Finds a tool part by its toolCallId.\n * Searches from the end since the tool part is usually recent.\n */\nfunction findToolPartByCallId(\n parts: MessagePart[],\n toolCallId: string | undefined\n): MessagePart | undefined {\n if (!toolCallId) return undefined;\n for (let i = parts.length - 1; i >= 0; i--) {\n const p = parts[i];\n if (\"toolCallId\" in p && p.toolCallId === toolCallId) {\n return p;\n }\n }\n return undefined;\n}\n\n/**\n * Shallow-merges providerMetadata from a chunk onto an existing part.\n * Preserves any metadata already on the part (e.g. from earlier deltas)\n * while adding new keys from the chunk. This is critical for providers\n * like Anthropic that emit the thinking block signature on reasoning-end.\n */\nfunction mergeProviderMetadata(\n part: MessagePart,\n metadata: Record<string, unknown> | undefined\n): void {\n if (metadata == null) return;\n const p = part as Record<string, unknown>;\n p.providerMetadata = {\n ...(p.providerMetadata as Record<string, unknown> | undefined),\n ...metadata\n };\n}\n\n/**\n * Finds a data part by its type and id for reconciliation.\n * Data parts use type+id as a composite key so when the same combination\n * is seen again, the existing part's data is updated in-place.\n */\nfunction findDataPartByTypeAndId(\n parts: MessagePart[],\n type: string,\n id: string\n): MessagePart | undefined {\n for (let i = parts.length - 1; i >= 0; i--) {\n const p = parts[i];\n if (p.type === type && \"id\" in p && (p as { id: string }).id === id) {\n return p;\n }\n }\n return undefined;\n}\n","import { applyChunkToParts } from \"./message-builder\";\nimport type {\n AgentToolEventMessage,\n AgentToolEventState,\n AgentToolRunState\n} from \"../agent-tool-types\";\n\nfunction sortRuns(runs: AgentToolRunState[]): AgentToolRunState[] {\n return [...runs].sort((a, b) => {\n if (a.order !== b.order) return a.order - b.order;\n return a.runId.localeCompare(b.runId);\n });\n}\n\nfunction rebuildIndexes(\n runsById: Record<string, AgentToolRunState>\n): Pick<AgentToolEventState, \"runsByToolCallId\" | \"unboundRuns\"> {\n const grouped: Record<string, AgentToolRunState[]> = {};\n const unboundRuns: AgentToolRunState[] = [];\n for (const run of Object.values(runsById)) {\n if (run.parentToolCallId) {\n grouped[run.parentToolCallId] = grouped[run.parentToolCallId] ?? [];\n grouped[run.parentToolCallId].push(run);\n } else {\n unboundRuns.push(run);\n }\n }\n for (const [toolCallId, runs] of Object.entries(grouped)) {\n grouped[toolCallId] = sortRuns(runs);\n }\n return { runsByToolCallId: grouped, unboundRuns: sortRuns(unboundRuns) };\n}\n\nfunction emptyRun(\n message: AgentToolEventMessage\n): AgentToolRunState | undefined {\n const { event } = message;\n if (event.kind === \"started\") {\n return {\n runId: event.runId,\n agentType: event.agentType,\n parentToolCallId: message.parentToolCallId,\n inputPreview: event.inputPreview,\n order: event.order,\n display: event.display,\n status: \"running\",\n parts: [],\n subAgent: { agent: event.agentType, name: event.runId }\n };\n }\n return undefined;\n}\n\nfunction applyToRun(\n prev: AgentToolRunState | undefined,\n message: AgentToolEventMessage\n): AgentToolRunState | undefined {\n const seeded = prev ?? emptyRun(message);\n const { event } = message;\n\n switch (event.kind) {\n case \"started\":\n if (\n seeded?.status === \"completed\" ||\n seeded?.status === \"error\" ||\n seeded?.status === \"aborted\" ||\n seeded?.status === \"interrupted\"\n ) {\n return seeded;\n }\n return {\n ...seeded,\n runId: event.runId,\n agentType: event.agentType,\n parentToolCallId: message.parentToolCallId,\n inputPreview: event.inputPreview,\n order: event.order,\n display: event.display,\n status: \"running\",\n parts: seeded?.parts ?? [],\n subAgent: { agent: event.agentType, name: event.runId }\n };\n case \"chunk\": {\n if (!seeded) return undefined;\n const parts = [...seeded.parts];\n try {\n applyChunkToParts(parts, JSON.parse(event.body));\n } catch {\n return seeded;\n }\n return { ...seeded, parts };\n }\n case \"finished\":\n if (!seeded) return undefined;\n return {\n ...seeded,\n status: \"completed\",\n summary: event.summary,\n error: undefined\n };\n case \"error\":\n if (!seeded) return undefined;\n return { ...seeded, status: \"error\", error: event.error };\n case \"aborted\":\n if (!seeded) return undefined;\n return { ...seeded, status: \"aborted\", error: event.reason };\n case \"interrupted\":\n if (!seeded) return undefined;\n return { ...seeded, status: \"interrupted\", error: event.error };\n }\n}\n\nexport function createAgentToolEventState(): AgentToolEventState {\n return {\n runsById: {},\n runsByToolCallId: {},\n unboundRuns: []\n };\n}\n\nexport function applyAgentToolEvent(\n state: AgentToolEventState,\n message: AgentToolEventMessage\n): AgentToolEventState {\n if (message.type !== \"agent-tool-event\") return state;\n const runId = message.event.runId;\n const nextRun = applyToRun(state.runsById[runId], message);\n if (!nextRun) return state;\n\n const runsById = { ...state.runsById, [runId]: nextRun };\n return { runsById, ...rebuildIndexes(runsById) };\n}\n\nexport type {\n AgentToolEvent,\n AgentToolEventMessage,\n AgentToolEventState,\n AgentToolRunState\n} from \"../agent-tool-types\";\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  a as AgentToolEventState,
3
3
  i as AgentToolEventMessage
4
- } from "./agent-tool-types-DSteYkkS.js";
4
+ } from "./agent-tool-types-CM_50fcV.js";
5
5
 
6
6
  //#region src/chat/agent-tools.d.ts
7
7
  declare function createAgentToolEventState(): AgentToolEventState;
@@ -11,4 +11,4 @@ declare function applyAgentToolEvent(
11
11
  ): AgentToolEventState;
12
12
  //#endregion
13
13
  export { createAgentToolEventState as n, applyAgentToolEvent as t };
14
- //# sourceMappingURL=agent-tools-eGTCdVZX.d.ts.map
14
+ //# sourceMappingURL=agent-tools-BylX6WXG.d.ts.map
@@ -14,7 +14,7 @@ import {
14
14
  s as AgentToolRunInfo,
15
15
  t as AgentToolChildAdapter,
16
16
  u as AgentToolRunStatus
17
- } from "./agent-tool-types-DSteYkkS.js";
17
+ } from "./agent-tool-types-CM_50fcV.js";
18
18
  import { Tool } from "ai";
19
19
 
20
20
  //#region src/agent-tools.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"agent-tools.js","names":["agentContext","createTool"],"sources":["../src/agent-tools.ts"],"sourcesContent":["import { tool, type Tool } from \"ai\";\nimport { __DO_NOT_USE_WILL_BREAK__agentContext as agentContext } from \"./internal_context\";\nimport type {\n ChatCapableAgentClass,\n RunAgentToolOptions,\n RunAgentToolResult,\n AgentToolDisplayMetadata\n} from \"./agent-tool-types\";\n\ntype SchemaLike<T = unknown> = {\n parse(value: unknown): T;\n};\n\ntype AgentToolFactoryOptions<Output = unknown> = {\n description: string;\n inputSchema: unknown;\n outputSchema?: SchemaLike<Output>;\n displayName?: string;\n icon?: string;\n display?: AgentToolDisplayMetadata;\n};\n\ntype ToolExecutionOptions = {\n toolCallId?: string;\n abortSignal?: AbortSignal;\n};\n\ntype AgentToolRunner = {\n runAgentTool<Input, Output>(\n cls: ChatCapableAgentClass,\n options: RunAgentToolOptions<Input>\n ): Promise<RunAgentToolResult<Output>>;\n};\n\nfunction currentAgentToolRunner(): AgentToolRunner {\n const agent = agentContext.getStore()?.agent;\n if (\n agent === null ||\n typeof agent !== \"object\" ||\n typeof (agent as { runAgentTool?: unknown }).runAgentTool !== \"function\"\n ) {\n throw new Error(\n \"agentTool() can only run inside an Agent turn. Use it from getTools() on an Agent subclass.\"\n );\n }\n return agent as AgentToolRunner;\n}\n\nfunction failure(error: string): { ok: false; error: string } {\n return { ok: false, error };\n}\n\n/**\n * Create an AI SDK tool that dispatches a chat-capable sub-agent through\n * `Agent.runAgentTool`.\n */\nexport function agentTool<Input = unknown, Output = unknown>(\n cls: ChatCapableAgentClass,\n options: AgentToolFactoryOptions<Output>\n): Tool<Input, string | Output | { ok: false; error: string }> {\n const createTool = tool as unknown as <I, O>(config: {\n description: string;\n inputSchema: unknown;\n execute: (input: I, options?: ToolExecutionOptions) => Promise<O>;\n }) => Tool<I, O>;\n\n return createTool<Input, string | Output | { ok: false; error: string }>({\n description: options.description,\n inputSchema: options.inputSchema,\n execute: async (input: Input, executeOptions?: ToolExecutionOptions) => {\n const display: AgentToolDisplayMetadata | undefined =\n options.displayName || options.icon || options.display\n ? {\n ...options.display,\n ...(options.displayName ? { name: options.displayName } : {}),\n ...(options.icon ? { icon: options.icon } : {})\n }\n : undefined;\n\n const result = await currentAgentToolRunner().runAgentTool<Input, Output>(\n cls,\n {\n input,\n parentToolCallId: executeOptions?.toolCallId,\n signal: executeOptions?.abortSignal,\n display\n }\n );\n\n if (result.status === \"completed\") {\n if (options.outputSchema) {\n if (result.output === undefined) {\n return failure(\n \"agent tool completed without structured output required by outputSchema\"\n );\n }\n return options.outputSchema.parse(result.output);\n }\n return result.summary ?? \"\";\n }\n\n if (result.status === \"aborted\") {\n return failure(\"agent tool run was cancelled\");\n }\n if (result.status === \"interrupted\") {\n return failure(\"agent tool run was interrupted; no recoverable output\");\n }\n return failure(result.error ?? \"agent tool run failed\");\n }\n });\n}\n\nexport type { AgentToolFactoryOptions };\nexport type {\n AgentToolChildAdapter,\n AgentToolDisplayMetadata,\n AgentToolEvent,\n AgentToolEventMessage,\n AgentToolEventState,\n AgentToolLifecycleResult,\n AgentToolRunInfo,\n AgentToolRunInspection,\n AgentToolRunState,\n AgentToolRunStatus,\n AgentToolStoredChunk,\n AgentToolTerminalStatus,\n ChatCapableAgentClass,\n RunAgentToolOptions,\n RunAgentToolResult\n} from \"./agent-tool-types\";\n"],"mappings":";;;AAkCA,SAAS,yBAA0C;CACjD,MAAM,QAAQA,sCAAa,UAAU,EAAE;AACvC,KACE,UAAU,QACV,OAAO,UAAU,YACjB,OAAQ,MAAqC,iBAAiB,WAE9D,OAAM,IAAI,MACR,8FACD;AAEH,QAAO;;AAGT,SAAS,QAAQ,OAA6C;AAC5D,QAAO;EAAE,IAAI;EAAO;EAAO;;;;;;AAO7B,SAAgB,UACd,KACA,SAC6D;AAO7D,QAAOC,KAAkE;EACvE,aAAa,QAAQ;EACrB,aAAa,QAAQ;EACrB,SAAS,OAAO,OAAc,mBAA0C;GACtE,MAAM,UACJ,QAAQ,eAAe,QAAQ,QAAQ,QAAQ,UAC3C;IACE,GAAG,QAAQ;IACX,GAAI,QAAQ,cAAc,EAAE,MAAM,QAAQ,aAAa,GAAG,EAAE;IAC5D,GAAI,QAAQ,OAAO,EAAE,MAAM,QAAQ,MAAM,GAAG,EAAE;IAC/C,GACD,KAAA;GAEN,MAAM,SAAS,MAAM,wBAAwB,CAAC,aAC5C,KACA;IACE;IACA,kBAAkB,gBAAgB;IAClC,QAAQ,gBAAgB;IACxB;IACD,CACF;AAED,OAAI,OAAO,WAAW,aAAa;AACjC,QAAI,QAAQ,cAAc;AACxB,SAAI,OAAO,WAAW,KAAA,EACpB,QAAO,QACL,0EACD;AAEH,YAAO,QAAQ,aAAa,MAAM,OAAO,OAAO;;AAElD,WAAO,OAAO,WAAW;;AAG3B,OAAI,OAAO,WAAW,UACpB,QAAO,QAAQ,+BAA+B;AAEhD,OAAI,OAAO,WAAW,cACpB,QAAO,QAAQ,wDAAwD;AAEzE,UAAO,QAAQ,OAAO,SAAS,wBAAwB;;EAE1D,CAAC"}
1
+ {"version":3,"file":"agent-tools.js","names":["agentContext","createTool"],"sources":["../src/agent-tools.ts"],"sourcesContent":["import { tool, type Tool } from \"ai\";\nimport { __DO_NOT_USE_WILL_BREAK__agentContext as agentContext } from \"./internal_context\";\nimport type {\n ChatCapableAgentClass,\n RunAgentToolOptions,\n RunAgentToolResult,\n AgentToolDisplayMetadata\n} from \"./agent-tool-types\";\n\ntype SchemaLike<T = unknown> = {\n parse(value: unknown): T;\n};\n\ntype AgentToolFactoryOptions<Output = unknown> = {\n description: string;\n inputSchema: unknown;\n outputSchema?: SchemaLike<Output>;\n displayName?: string;\n icon?: string;\n display?: AgentToolDisplayMetadata;\n};\n\ntype ToolExecutionOptions = {\n toolCallId?: string;\n abortSignal?: AbortSignal;\n};\n\ntype AgentToolRunner = {\n runAgentTool<Input, Output>(\n cls: ChatCapableAgentClass,\n options: RunAgentToolOptions<Input>\n ): Promise<RunAgentToolResult<Output>>;\n};\n\nfunction currentAgentToolRunner(): AgentToolRunner {\n const agent = agentContext.getStore()?.agent;\n if (\n agent === null ||\n typeof agent !== \"object\" ||\n typeof (agent as { runAgentTool?: unknown }).runAgentTool !== \"function\"\n ) {\n throw new Error(\n \"agentTool() can only run inside an Agent turn. Use it from getTools() on an Agent subclass.\"\n );\n }\n return agent as AgentToolRunner;\n}\n\nfunction failure(error: string): { ok: false; error: string } {\n return { ok: false, error };\n}\n\n/**\n * Create an AI SDK tool that dispatches a chat-capable sub-agent through\n * `Agent.runAgentTool`.\n */\nexport function agentTool<Input = unknown, Output = unknown>(\n cls: ChatCapableAgentClass,\n options: AgentToolFactoryOptions<Output>\n): Tool<Input, string | Output | { ok: false; error: string }> {\n const createTool = tool as unknown as <I, O>(config: {\n description: string;\n inputSchema: unknown;\n execute: (input: I, options?: ToolExecutionOptions) => Promise<O>;\n }) => Tool<I, O>;\n\n return createTool<Input, string | Output | { ok: false; error: string }>({\n description: options.description,\n inputSchema: options.inputSchema,\n execute: async (input: Input, executeOptions?: ToolExecutionOptions) => {\n const display: AgentToolDisplayMetadata | undefined =\n options.displayName || options.icon || options.display\n ? {\n ...options.display,\n ...(options.displayName ? { name: options.displayName } : {}),\n ...(options.icon ? { icon: options.icon } : {})\n }\n : undefined;\n\n const result = await currentAgentToolRunner().runAgentTool<Input, Output>(\n cls,\n {\n input,\n parentToolCallId: executeOptions?.toolCallId,\n signal: executeOptions?.abortSignal,\n display\n }\n );\n\n if (result.status === \"completed\") {\n if (options.outputSchema) {\n if (result.output === undefined) {\n return failure(\n \"agent tool completed without structured output required by outputSchema\"\n );\n }\n return options.outputSchema.parse(result.output);\n }\n return result.summary ?? \"\";\n }\n\n if (result.status === \"aborted\") {\n return failure(\"agent tool run was cancelled\");\n }\n if (result.status === \"interrupted\") {\n return failure(\"agent tool run was interrupted; no recoverable output\");\n }\n return failure(result.error ?? \"agent tool run failed\");\n }\n });\n}\n\nexport type { AgentToolFactoryOptions };\nexport type {\n AgentToolChildAdapter,\n AgentToolDisplayMetadata,\n AgentToolEvent,\n AgentToolEventMessage,\n AgentToolEventState,\n AgentToolLifecycleResult,\n AgentToolRunInfo,\n AgentToolRunInspection,\n AgentToolRunState,\n AgentToolRunStatus,\n AgentToolStoredChunk,\n AgentToolTerminalStatus,\n ChatCapableAgentClass,\n RunAgentToolOptions,\n RunAgentToolResult\n} from \"./agent-tool-types\";\n"],"mappings":";;;AAkCA,SAAS,yBAA0C;CACjD,MAAM,QAAQA,sCAAa,UAAU,EAAE;CACvC,IACE,UAAU,QACV,OAAO,UAAU,YACjB,OAAQ,MAAqC,iBAAiB,YAE9D,MAAM,IAAI,MACR,8FACD;CAEH,OAAO;;AAGT,SAAS,QAAQ,OAA6C;CAC5D,OAAO;EAAE,IAAI;EAAO;EAAO;;;;;;AAO7B,SAAgB,UACd,KACA,SAC6D;CAO7D,OAAOC,KAAkE;EACvE,aAAa,QAAQ;EACrB,aAAa,QAAQ;EACrB,SAAS,OAAO,OAAc,mBAA0C;GACtE,MAAM,UACJ,QAAQ,eAAe,QAAQ,QAAQ,QAAQ,UAC3C;IACE,GAAG,QAAQ;IACX,GAAI,QAAQ,cAAc,EAAE,MAAM,QAAQ,aAAa,GAAG,EAAE;IAC5D,GAAI,QAAQ,OAAO,EAAE,MAAM,QAAQ,MAAM,GAAG,EAAE;IAC/C,GACD,KAAA;GAEN,MAAM,SAAS,MAAM,wBAAwB,CAAC,aAC5C,KACA;IACE;IACA,kBAAkB,gBAAgB;IAClC,QAAQ,gBAAgB;IACxB;IACD,CACF;GAED,IAAI,OAAO,WAAW,aAAa;IACjC,IAAI,QAAQ,cAAc;KACxB,IAAI,OAAO,WAAW,KAAA,GACpB,OAAO,QACL,0EACD;KAEH,OAAO,QAAQ,aAAa,MAAM,OAAO,OAAO;;IAElD,OAAO,OAAO,WAAW;;GAG3B,IAAI,OAAO,WAAW,WACpB,OAAO,QAAQ,+BAA+B;GAEhD,IAAI,OAAO,WAAW,eACpB,OAAO,QAAQ,wDAAwD;GAEzE,OAAO,QAAQ,OAAO,SAAS,wBAAwB;;EAE1D,CAAC"}
@@ -1,4 +1,4 @@
1
- import { t as BrowserToolsOptions } from "../shared-Ch9slKdI.js";
1
+ import { t as BrowserToolsOptions } from "../shared-Cvj92byG.js";
2
2
  import { ToolSet } from "ai";
3
3
 
4
4
  //#region src/browser/ai.d.ts
@@ -28,4 +28,4 @@ import { ToolSet } from "ai";
28
28
  declare function createBrowserTools(options: BrowserToolsOptions): ToolSet;
29
29
  //#endregion
30
30
  export { type BrowserToolsOptions, createBrowserTools };
31
- //# sourceMappingURL=ai.d.ts.map
31
+ //# sourceMappingURL=ai.d.ts.map
@@ -1,4 +1,4 @@
1
- import { n as SEARCH_DESCRIPTION, r as createBrowserToolHandlers, t as EXECUTE_DESCRIPTION } from "../shared-C6l4ZKRN.js";
1
+ import { n as SEARCH_DESCRIPTION, r as createBrowserToolHandlers, t as EXECUTE_DESCRIPTION } from "../shared-DzJYHisH.js";
2
2
  import { tool } from "ai";
3
3
  import { z } from "zod";
4
4
  //#region src/browser/ai.ts
@@ -1 +1 @@
1
- {"version":3,"file":"ai.js","names":[],"sources":["../../src/browser/ai.ts"],"sourcesContent":["import { tool } from \"ai\";\nimport type { ToolSet } from \"ai\";\nimport { z } from \"zod\";\nimport {\n createBrowserToolHandlers,\n SEARCH_DESCRIPTION,\n EXECUTE_DESCRIPTION,\n type BrowserToolsOptions\n} from \"./shared\";\n\nexport type { BrowserToolsOptions } from \"./shared\";\n\n/**\n * Create AI SDK tools for browser automation via CDP code mode.\n *\n * Returns a `ToolSet` with `search` (query the CDP spec) and\n * `execute` (run CDP commands against a live browser).\n *\n * @example\n * ```ts\n * import { createBrowserTools } from \"agents/browser/ai\";\n * import { generateText } from \"ai\";\n *\n * const browserTools = createBrowserTools({\n * browser: env.BROWSER,\n * loader: env.LOADER,\n * });\n *\n * const result = await generateText({\n * model,\n * tools: { ...browserTools, ...otherTools },\n * messages,\n * });\n * ```\n */\nexport function createBrowserTools(options: BrowserToolsOptions): ToolSet {\n const handlers = createBrowserToolHandlers(options);\n\n return {\n browser_search: tool({\n description: SEARCH_DESCRIPTION,\n inputSchema: z.object({\n code: z\n .string()\n .describe(\"JavaScript async arrow function that queries the CDP spec\")\n }),\n execute: async ({ code }) => {\n const result = await handlers.search(code);\n if (result.isError) {\n throw new Error(result.text);\n }\n return result.text;\n }\n }),\n\n browser_execute: tool({\n description: EXECUTE_DESCRIPTION,\n inputSchema: z.object({\n code: z\n .string()\n .describe(\"JavaScript async arrow function that uses the cdp helper\")\n }),\n execute: async ({ code }) => {\n const result = await handlers.execute(code);\n if (result.isError) {\n throw new Error(result.text);\n }\n return result.text;\n }\n })\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAgB,mBAAmB,SAAuC;CACxE,MAAM,WAAW,0BAA0B,QAAQ;AAEnD,QAAO;EACL,gBAAgB,KAAK;GACnB,aAAa;GACb,aAAa,EAAE,OAAO,EACpB,MAAM,EACH,QAAQ,CACR,SAAS,4DAA4D,EACzE,CAAC;GACF,SAAS,OAAO,EAAE,WAAW;IAC3B,MAAM,SAAS,MAAM,SAAS,OAAO,KAAK;AAC1C,QAAI,OAAO,QACT,OAAM,IAAI,MAAM,OAAO,KAAK;AAE9B,WAAO,OAAO;;GAEjB,CAAC;EAEF,iBAAiB,KAAK;GACpB,aAAa;GACb,aAAa,EAAE,OAAO,EACpB,MAAM,EACH,QAAQ,CACR,SAAS,2DAA2D,EACxE,CAAC;GACF,SAAS,OAAO,EAAE,WAAW;IAC3B,MAAM,SAAS,MAAM,SAAS,QAAQ,KAAK;AAC3C,QAAI,OAAO,QACT,OAAM,IAAI,MAAM,OAAO,KAAK;AAE9B,WAAO,OAAO;;GAEjB,CAAC;EACH"}
1
+ {"version":3,"file":"ai.js","names":[],"sources":["../../src/browser/ai.ts"],"sourcesContent":["import { tool } from \"ai\";\nimport type { ToolSet } from \"ai\";\nimport { z } from \"zod\";\nimport {\n createBrowserToolHandlers,\n SEARCH_DESCRIPTION,\n EXECUTE_DESCRIPTION,\n type BrowserToolsOptions\n} from \"./shared\";\n\nexport type { BrowserToolsOptions } from \"./shared\";\n\n/**\n * Create AI SDK tools for browser automation via CDP code mode.\n *\n * Returns a `ToolSet` with `search` (query the CDP spec) and\n * `execute` (run CDP commands against a live browser).\n *\n * @example\n * ```ts\n * import { createBrowserTools } from \"agents/browser/ai\";\n * import { generateText } from \"ai\";\n *\n * const browserTools = createBrowserTools({\n * browser: env.BROWSER,\n * loader: env.LOADER,\n * });\n *\n * const result = await generateText({\n * model,\n * tools: { ...browserTools, ...otherTools },\n * messages,\n * });\n * ```\n */\nexport function createBrowserTools(options: BrowserToolsOptions): ToolSet {\n const handlers = createBrowserToolHandlers(options);\n\n return {\n browser_search: tool({\n description: SEARCH_DESCRIPTION,\n inputSchema: z.object({\n code: z\n .string()\n .describe(\"JavaScript async arrow function that queries the CDP spec\")\n }),\n execute: async ({ code }) => {\n const result = await handlers.search(code);\n if (result.isError) {\n throw new Error(result.text);\n }\n return result.text;\n }\n }),\n\n browser_execute: tool({\n description: EXECUTE_DESCRIPTION,\n inputSchema: z.object({\n code: z\n .string()\n .describe(\"JavaScript async arrow function that uses the cdp helper\")\n }),\n execute: async ({ code }) => {\n const result = await handlers.execute(code);\n if (result.isError) {\n throw new Error(result.text);\n }\n return result.text;\n }\n })\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAgB,mBAAmB,SAAuC;CACxE,MAAM,WAAW,0BAA0B,QAAQ;CAEnD,OAAO;EACL,gBAAgB,KAAK;GACnB,aAAa;GACb,aAAa,EAAE,OAAO,EACpB,MAAM,EACH,QAAQ,CACR,SAAS,4DAA4D,EACzE,CAAC;GACF,SAAS,OAAO,EAAE,WAAW;IAC3B,MAAM,SAAS,MAAM,SAAS,OAAO,KAAK;IAC1C,IAAI,OAAO,SACT,MAAM,IAAI,MAAM,OAAO,KAAK;IAE9B,OAAO,OAAO;;GAEjB,CAAC;EAEF,iBAAiB,KAAK;GACpB,aAAa;GACb,aAAa,EAAE,OAAO,EACpB,MAAM,EACH,QAAQ,CACR,SAAS,2DAA2D,EACxE,CAAC;GACF,SAAS,OAAO,EAAE,WAAW;IAC3B,MAAM,SAAS,MAAM,SAAS,QAAQ,KAAK;IAC3C,IAAI,OAAO,SACT,MAAM,IAAI,MAAM,OAAO,KAAK;IAE9B,OAAO,OAAO;;GAEjB,CAAC;EACH"}
@@ -1,4 +1,10 @@
1
- import { a as createBrowserToolHandlers, i as ToolResult, n as EXECUTE_DESCRIPTION, r as SEARCH_DESCRIPTION, t as BrowserToolsOptions } from "../shared-Ch9slKdI.js";
1
+ import {
2
+ a as createBrowserToolHandlers,
3
+ i as ToolResult,
4
+ n as EXECUTE_DESCRIPTION,
5
+ r as SEARCH_DESCRIPTION,
6
+ t as BrowserToolsOptions
7
+ } from "../shared-Cvj92byG.js";
2
8
 
3
9
  //#region src/browser/cdp-session.d.ts
4
10
  interface DebugEntry {
@@ -22,8 +28,16 @@ interface CdpAttachOptions {
22
28
  */
23
29
  declare class CdpSession {
24
30
  #private;
25
- constructor(socket: WebSocket, defaultTimeoutMs?: number, dispose?: () => void);
26
- send(method: string, params?: unknown, options?: CdpSendOptions): Promise<unknown>;
31
+ constructor(
32
+ socket: WebSocket,
33
+ defaultTimeoutMs?: number,
34
+ dispose?: () => void
35
+ );
36
+ send(
37
+ method: string,
38
+ params?: unknown,
39
+ options?: CdpSendOptions
40
+ ): Promise<unknown>;
27
41
  attachToTarget(targetId: string, options?: CdpAttachOptions): Promise<string>;
28
42
  getDebugLog(limit?: number): DebugEntry[];
29
43
  clearDebugLog(): void;
@@ -33,7 +47,10 @@ declare class CdpSession {
33
47
  * Connect to a browser via the Browser Rendering binding (Fetcher).
34
48
  * Establishes a CDP WebSocket through the binding's fetch interface.
35
49
  */
36
- declare function connectBrowser(browser: Fetcher, timeoutMs?: number): Promise<CdpSession>;
50
+ declare function connectBrowser(
51
+ browser: Fetcher,
52
+ timeoutMs?: number
53
+ ): Promise<CdpSession>;
37
54
  /**
38
55
  * Connect to a browser via a CDP base URL (e.g. http://localhost:9222).
39
56
  * Discovers the WebSocket debugger URL via /json/version,
@@ -42,10 +59,24 @@ declare function connectBrowser(browser: Fetcher, timeoutMs?: number): Promise<C
42
59
  * Useful for local development with `chrome --remote-debugging-port=9222`
43
60
  * or when connecting through a tunnel.
44
61
  */
45
- declare function connectUrl(baseUrl: string, options?: {
46
- timeoutMs?: number;
47
- headers?: Record<string, string>;
48
- }): Promise<CdpSession>;
62
+ declare function connectUrl(
63
+ baseUrl: string,
64
+ options?: {
65
+ timeoutMs?: number;
66
+ headers?: Record<string, string>;
67
+ }
68
+ ): Promise<CdpSession>;
49
69
  //#endregion
50
- export { type BrowserToolsOptions, type CdpAttachOptions, type CdpSendOptions, CdpSession, EXECUTE_DESCRIPTION, SEARCH_DESCRIPTION, type ToolResult, connectBrowser, connectUrl, createBrowserToolHandlers };
51
- //# sourceMappingURL=index.d.ts.map
70
+ export {
71
+ type BrowserToolsOptions,
72
+ type CdpAttachOptions,
73
+ type CdpSendOptions,
74
+ CdpSession,
75
+ EXECUTE_DESCRIPTION,
76
+ SEARCH_DESCRIPTION,
77
+ type ToolResult,
78
+ connectBrowser,
79
+ connectUrl,
80
+ createBrowserToolHandlers
81
+ };
82
+ //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1,2 @@
1
- import { a as connectBrowser, i as CdpSession, n as SEARCH_DESCRIPTION, o as connectUrl, r as createBrowserToolHandlers, t as EXECUTE_DESCRIPTION } from "../shared-C6l4ZKRN.js";
1
+ import { a as connectBrowser, i as CdpSession, n as SEARCH_DESCRIPTION, o as connectUrl, r as createBrowserToolHandlers, t as EXECUTE_DESCRIPTION } from "../shared-DzJYHisH.js";
2
2
  export { CdpSession, EXECUTE_DESCRIPTION, SEARCH_DESCRIPTION, connectBrowser, connectUrl, createBrowserToolHandlers };
@@ -1,4 +1,4 @@
1
- import { t as BrowserToolsOptions } from "../shared-Ch9slKdI.js";
1
+ import { t as BrowserToolsOptions } from "../shared-Cvj92byG.js";
2
2
  import { ServerTool } from "@tanstack/ai";
3
3
 
4
4
  //#region src/browser/tanstack-ai.d.ts
@@ -28,4 +28,4 @@ import { ServerTool } from "@tanstack/ai";
28
28
  declare function createBrowserTools(options: BrowserToolsOptions): ServerTool[];
29
29
  //#endregion
30
30
  export { type BrowserToolsOptions, createBrowserTools };
31
- //# sourceMappingURL=tanstack-ai.d.ts.map
31
+ //# sourceMappingURL=tanstack-ai.d.ts.map