agents 0.20.1 → 0.22.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.
- package/README.md +51 -12
- package/dist/{agent-tool-types-BC-WFlsz.d.ts → agent-routing-CnkaHb-v.d.ts} +3305 -3138
- package/dist/agent-routing.d.ts +14 -0
- package/dist/agent-routing.js +187 -0
- package/dist/agent-routing.js.map +1 -0
- package/dist/agent-tool-types.d.ts +26 -26
- package/dist/{agent-tools-DeHe9Xov.d.ts → agent-tools-C0XJqWzB.d.ts} +7 -7
- package/dist/agent-tools.d.ts +44 -28
- package/dist/agent-tools.js +16 -7
- package/dist/agent-tools.js.map +1 -1
- package/dist/browser/ai.d.ts +5 -3
- package/dist/browser/ai.js +88 -8
- package/dist/browser/ai.js.map +1 -1
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/tanstack-ai.js +13 -1
- package/dist/browser/tanstack-ai.js.map +1 -1
- package/dist/capability-BjSKYpzg.js +42 -0
- package/dist/capability-BjSKYpzg.js.map +1 -0
- package/dist/capability-runner-CvHGZqUu.d.ts +150 -0
- package/dist/chat/index.d.ts +51 -15
- package/dist/chat/index.js +59 -4
- package/dist/chat/index.js.map +1 -1
- package/dist/chat/react.d.ts +19 -180
- package/dist/chat/react.js +93 -600
- package/dist/chat/react.js.map +1 -1
- package/dist/chat/transport.d.ts +10 -0
- package/dist/chat/transport.js +2 -0
- package/dist/chat-sdk/index.d.ts +4 -4
- package/dist/chat-sdk/index.js +1 -1
- package/dist/{client-zqKcsyFa.js → client-jagG8a9_.js} +129 -37
- package/dist/client-jagG8a9_.js.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +1 -1
- package/dist/{cloudflare-BduZwmYK.js → cloudflare-Dzvc7V2N.js} +10 -3
- package/dist/{cloudflare-BduZwmYK.js.map → cloudflare-Dzvc7V2N.js.map} +1 -1
- package/dist/{connector-v2M1zlZp.d.ts → connector-CkQD4MK3.d.ts} +20 -3
- package/dist/{connector-KEJnl6e5.js → connector-CptFKzRh.js} +158 -40
- package/dist/connector-CptFKzRh.js.map +1 -0
- package/dist/current-agent-CuMErtly.d.ts +283 -0
- package/dist/current-agent-DhoDkSnH.js +51 -0
- package/dist/current-agent-DhoDkSnH.js.map +1 -0
- package/dist/diagnostics-CaBjfz4J.js +41 -0
- package/dist/diagnostics-CaBjfz4J.js.map +1 -0
- package/dist/{do-oauth-client-provider-VTZj2VtM.d.ts → do-oauth-client-provider-Tmf1vgKz.d.ts} +2 -2
- package/dist/durable-object-lifecycle-D6nNQJJd.js +862 -0
- package/dist/durable-object-lifecycle-D6nNQJJd.js.map +1 -0
- package/dist/{email-CL27preh.d.ts → email-7TatiTnl.d.ts} +38 -9
- package/dist/email-send.d.ts +15 -0
- package/dist/email-send.js +32 -0
- package/dist/email-send.js.map +1 -0
- package/dist/email.d.ts +14 -10
- package/dist/email.js.map +1 -1
- package/dist/experimental/memory/session/index.d.ts +3 -2
- package/dist/experimental/memory/session/index.js +15 -10
- package/dist/experimental/memory/session/index.js.map +1 -1
- package/dist/{handler-stateless-C_bo-Ytq.d.ts → handler-stateless-DxYpJ_XF.d.ts} +3 -3
- package/dist/{handler-stateless-CIkKPETH.js → handler-stateless-VvrWSAVA.js} +5 -5
- package/dist/handler-stateless-VvrWSAVA.js.map +1 -0
- package/dist/{index-BRnybD6X.d.ts → index-DcSAZKsB.d.ts} +19 -31
- package/dist/index.d.ts +102 -91
- package/dist/index.js +12 -7235
- package/dist/internal_context-BlxFEWfn.d.ts +19 -0
- package/dist/internal_context.d.ts +10 -4
- package/dist/internal_context.js +1 -10
- package/dist/{client-invoker-BNSZxAkv.d.ts → invoker-CG0_p_Wq.d.ts} +2 -2
- package/dist/{client-invoker-VNZ7X0nn.js → invoker-CHMnoxIA.js} +2 -2
- package/dist/invoker-CHMnoxIA.js.map +1 -0
- package/dist/lifecycle/index.d.ts +48 -0
- package/dist/lifecycle/index.js +4 -0
- package/dist/mcp/{do-oauth-client-provider.d.ts → client/do-oauth-client-provider.d.ts} +1 -1
- package/dist/mcp/{do-oauth-client-provider.js → client/do-oauth-client-provider.js} +1 -1
- package/dist/mcp/client/do-oauth-client-provider.js.map +1 -0
- package/dist/mcp/client/index.d.ts +42 -0
- package/dist/mcp/{client.js → client/index.js} +1 -1
- package/dist/mcp/{x402.d.ts → client/x402.d.ts} +2 -2
- package/dist/mcp/{x402.js → client/x402.js} +2 -2
- package/dist/mcp/client/x402.js.map +1 -0
- package/dist/mcp/index.d.ts +36 -36
- package/dist/mcp/index.js +14 -16
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/{server.d.ts → server/index.d.ts} +1 -1
- package/dist/mcp/{server.js → server/index.js} +1 -1
- package/dist/observability/ai/index.d.ts +1 -130
- package/dist/observability/ai/index.js +88 -433
- package/dist/observability/ai/index.js.map +1 -1
- package/dist/observability/index.d.ts +4 -4
- package/dist/observability/index.js +3 -50
- package/dist/observability/index.js.map +1 -1
- package/dist/{wire-types-CU9rLoeS.js → protocol-B0nh6KNf.js} +20 -66
- package/dist/protocol-B0nh6KNf.js.map +1 -0
- package/dist/react.d.ts +4 -4
- package/dist/react.js +6 -9
- package/dist/react.js.map +1 -1
- package/dist/schedule.d.ts +25 -94
- package/dist/schedule.js +1 -98
- package/dist/schedule.js.map +1 -1
- package/dist/scheduler-CR9RHGos.js +857 -0
- package/dist/scheduler-CR9RHGos.js.map +1 -0
- package/dist/scheduler-DQoTGoAW.d.ts +224 -0
- package/dist/schedules/index.d.ts +22 -0
- package/dist/schedules/index.js +2 -0
- package/dist/schedules/parser.d.ts +79 -0
- package/dist/schedules/parser.js +103 -0
- package/dist/schedules/parser.js.map +1 -0
- package/dist/serializable.d.ts +1 -1
- package/dist/sql-error-CPY-GXyI.d.ts +12 -0
- package/dist/sql-error.d.ts +2 -0
- package/dist/sql-error.js +16 -0
- package/dist/sql-error.js.map +1 -0
- package/dist/src-5W6JNKVb.js +6613 -0
- package/dist/src-5W6JNKVb.js.map +1 -0
- package/dist/sub-routing.d.ts +18 -6
- package/dist/sub-routing.js +92 -2
- package/dist/sub-routing.js.map +1 -1
- package/dist/wire-types-CnMt6_HR.js +47 -0
- package/dist/wire-types-CnMt6_HR.js.map +1 -0
- package/dist/workflow-types.d.ts +25 -25
- package/dist/workflow-types.js.map +1 -1
- package/dist/workflows.d.ts +22 -22
- package/dist/workflows.js +2 -1
- package/dist/workflows.js.map +1 -1
- package/dist/ws-chat-transport-UNRIS2xl.d.ts +184 -0
- package/dist/ws-chat-transport-rWwta645.js +698 -0
- package/dist/ws-chat-transport-rWwta645.js.map +1 -0
- package/docs/adding-to-existing-project.md +4 -2
- package/docs/agent-class.md +29 -87
- package/docs/agent-tools.md +29 -0
- package/docs/browse-the-web.md +16 -1
- package/docs/chat-agents.md +16 -13
- package/docs/client-sdk.md +12 -8
- package/docs/configuration.md +7 -1
- package/docs/cross-domain-authentication.md +7 -35
- package/docs/durable-execution.md +1 -1
- package/docs/email.md +2 -13
- package/docs/http-websockets.md +1 -11
- package/docs/human-in-the-loop.md +16 -13
- package/docs/index.md +1 -0
- package/docs/lifecycle.md +323 -0
- package/docs/long-running-agents.md +13 -15
- package/docs/mcp-client.md +55 -0
- package/docs/mcp-servers.md +6 -0
- package/docs/mcp-transports.md +18 -12
- package/docs/migration-to-ai-sdk-v5.md +2 -2
- package/docs/migration-to-ai-sdk-v6.md +5 -1
- package/docs/observability.md +33 -77
- package/docs/resumable-streaming.md +1 -1
- package/docs/routing.md +27 -0
- package/docs/scheduling.md +175 -15
- package/docs/server-driven-messages.md +1 -1
- package/docs/sub-agents.md +47 -2
- package/docs/webhooks.md +109 -136
- package/docs/workflows.md +9 -1
- package/package.json +41 -23
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/index.js +0 -26
- package/dist/cli/index.js.map +0 -1
- package/dist/client-invoker-VNZ7X0nn.js.map +0 -1
- package/dist/client-zqKcsyFa.js.map +0 -1
- package/dist/connector-KEJnl6e5.js.map +0 -1
- package/dist/handler-stateless-CIkKPETH.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/internal_context-Dg4Cgjcu.d.ts +0 -37
- package/dist/internal_context.js.map +0 -1
- package/dist/mcp/client.d.ts +0 -42
- package/dist/mcp/do-oauth-client-provider.js.map +0 -1
- package/dist/mcp/x402.js.map +0 -1
- package/dist/wire-types-CU9rLoeS.js.map +0 -1
- package/dist/workflow-types-Baz_PO5v.d.ts +0 -280
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
-
import { Connection } from "partyserver";
|
|
3
|
-
|
|
4
|
-
//#region src/internal_context.d.ts
|
|
5
|
-
type AgentEmail = {
|
|
6
|
-
from: string;
|
|
7
|
-
to: string;
|
|
8
|
-
getRaw: () => Promise<Uint8Array>;
|
|
9
|
-
headers: Headers;
|
|
10
|
-
rawSize: number;
|
|
11
|
-
setReject: (reason: string) => void;
|
|
12
|
-
forward: (rcptTo: string, headers?: Headers) => Promise<EmailSendResult>;
|
|
13
|
-
reply: (options: {
|
|
14
|
-
from: string;
|
|
15
|
-
to: string;
|
|
16
|
-
raw: string;
|
|
17
|
-
}) => Promise<EmailSendResult> /** @internal Indicates email was routed via createSecureReplyEmailResolver */;
|
|
18
|
-
_secureRouted?: boolean;
|
|
19
|
-
};
|
|
20
|
-
type AgentContextStore = {
|
|
21
|
-
agent: unknown;
|
|
22
|
-
connection: Connection | undefined;
|
|
23
|
-
request: Request | undefined;
|
|
24
|
-
email: AgentEmail | undefined;
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* @internal — This is an internal implementation detail.
|
|
28
|
-
* Importing or relying on this symbol **will** break your code in a future release.
|
|
29
|
-
*/
|
|
30
|
-
declare const __DO_NOT_USE_WILL_BREAK__agentContext: AsyncLocalStorage<AgentContextStore>;
|
|
31
|
-
//#endregion
|
|
32
|
-
export {
|
|
33
|
-
AgentEmail as n,
|
|
34
|
-
__DO_NOT_USE_WILL_BREAK__agentContext as r,
|
|
35
|
-
AgentContextStore as t
|
|
36
|
-
};
|
|
37
|
-
//# sourceMappingURL=internal_context-Dg4Cgjcu.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"internal_context.js","names":[],"sources":["../src/internal_context.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { Connection } from \"partyserver\";\n\nexport type AgentEmail = {\n from: string;\n to: string;\n getRaw: () => Promise<Uint8Array>;\n headers: Headers;\n rawSize: number;\n setReject: (reason: string) => void;\n forward: (rcptTo: string, headers?: Headers) => Promise<EmailSendResult>;\n reply: (options: {\n from: string;\n to: string;\n raw: string;\n }) => Promise<EmailSendResult>;\n /** @internal Indicates email was routed via createSecureReplyEmailResolver */\n _secureRouted?: boolean;\n};\n\nexport type AgentContextStore = {\n // Using unknown to avoid circular dependency with Agent\n agent: unknown;\n connection: Connection | undefined;\n request: Request | undefined;\n email: AgentEmail | undefined;\n};\n\n/**\n * @internal — This is an internal implementation detail.\n * Importing or relying on this symbol **will** break your code in a future release.\n */\nexport const __DO_NOT_USE_WILL_BREAK__agentContext =\n new AsyncLocalStorage<AgentContextStore>();\n"],"mappings":";;;;;;AAgCA,MAAa,wCACX,IAAI,kBAAqC"}
|
package/dist/mcp/client.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
At as MCPServerFilter,
|
|
3
|
-
Ct as MCPClientManager,
|
|
4
|
-
Dt as MCPConnectionResult,
|
|
5
|
-
Et as MCPClientOAuthResult,
|
|
6
|
-
Ft as normalizeServerId,
|
|
7
|
-
Mt as MCP_SERVER_ID_MAX_LENGTH,
|
|
8
|
-
Nt as RegisterServerOptions,
|
|
9
|
-
Ot as MCPDiscoverResult,
|
|
10
|
-
Pt as getNamespacedData,
|
|
11
|
-
St as MCPClientElicitationHandlers,
|
|
12
|
-
Tt as MCPClientOAuthCallbackConfig,
|
|
13
|
-
_t as ElicitRequest,
|
|
14
|
-
bt as MCPAIToolSet,
|
|
15
|
-
jt as MCPServerOptions,
|
|
16
|
-
kt as MCPOAuthCallbackResult,
|
|
17
|
-
vt as ElicitResult,
|
|
18
|
-
wt as MCPClientManagerOptions,
|
|
19
|
-
xt as MCPClientElicitationHandler,
|
|
20
|
-
yt as MCPAITool
|
|
21
|
-
} from "../agent-tool-types-BC-WFlsz.js";
|
|
22
|
-
export {
|
|
23
|
-
type ElicitRequest,
|
|
24
|
-
type ElicitResult,
|
|
25
|
-
MCPAITool,
|
|
26
|
-
MCPAIToolSet,
|
|
27
|
-
MCPClientElicitationHandler,
|
|
28
|
-
MCPClientElicitationHandlers,
|
|
29
|
-
MCPClientManager,
|
|
30
|
-
MCPClientManagerOptions,
|
|
31
|
-
MCPClientOAuthCallbackConfig,
|
|
32
|
-
MCPClientOAuthResult,
|
|
33
|
-
MCPConnectionResult,
|
|
34
|
-
MCPDiscoverResult,
|
|
35
|
-
MCPOAuthCallbackResult,
|
|
36
|
-
MCPServerFilter,
|
|
37
|
-
MCPServerOptions,
|
|
38
|
-
MCP_SERVER_ID_MAX_LENGTH,
|
|
39
|
-
RegisterServerOptions,
|
|
40
|
-
getNamespacedData,
|
|
41
|
-
normalizeServerId
|
|
42
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"do-oauth-client-provider.js","names":[],"sources":["../../src/mcp/do-oauth-client-provider.ts"],"sourcesContent":["import type {\n OAuthClientInformationContext,\n OAuthClientMetadata,\n OAuthClientProvider,\n OAuthDiscoveryState,\n StoredOAuthClientInformation,\n StoredOAuthTokens\n} from \"@modelcontextprotocol/client\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { nanoid } from \"nanoid\";\n\nconst STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes\n\nconst codeVerifierStateStorage = new AsyncLocalStorage<{\n state: string;\n servedKey?: string;\n}>();\n\ninterface StoredState {\n nonce: string;\n serverId: string;\n createdAt: number;\n}\n\ninterface StoredCodeVerifier {\n verifier: string;\n createdAt: number;\n}\n\n// A slight extension to the standard OAuthClientProvider interface because `redirectToAuthorization` doesn't give us the interface we need\n// This allows us to track authentication for a specific server and associated dynamic client registration\nexport interface AgentMcpOAuthProvider extends OAuthClientProvider {\n authUrl: string | undefined;\n clientId: string | undefined;\n serverId: string | undefined;\n checkState(\n state: string\n ): Promise<{ valid: boolean; serverId?: string; error?: string }>;\n consumeState(state: string): Promise<void>;\n runWithCodeVerifierState?<T>(\n state: string,\n callback: () => Promise<T>\n ): Promise<T>;\n deleteCodeVerifier(): Promise<void>;\n}\n\nfunction parseOAuthState(\n state: string\n): { nonce: string; serverId: string } | undefined {\n const parts = state.split(\".\");\n if (parts.length !== 2) {\n return undefined;\n }\n\n const [nonce, serverId] = parts;\n if (!nonce || !serverId) {\n return undefined;\n }\n\n return { nonce, serverId };\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nasync function createCodeChallenge(verifier: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(verifier)\n );\n return base64UrlEncode(new Uint8Array(digest));\n}\n\nfunction isExpired(createdAt: number): boolean {\n return Date.now() - createdAt > STATE_EXPIRATION_MS;\n}\n\n/**\n * @deprecated Use {@link AgentMcpOAuthProvider} instead.\n */\nexport type AgentsOAuthProvider = AgentMcpOAuthProvider;\n\nexport class DurableObjectOAuthClientProvider implements AgentMcpOAuthProvider {\n private _authUrl_: string | undefined;\n private _serverId_: string | undefined;\n private _clientId_: string | undefined;\n\n constructor(\n public storage: DurableObjectStorage,\n public clientName: string,\n public baseRedirectUrl: string\n ) {\n if (!storage) {\n throw new Error(\n \"DurableObjectOAuthClientProvider requires a valid DurableObjectStorage instance\"\n );\n }\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return {\n client_name: this.clientName,\n client_uri: this.clientUri,\n grant_types: [\"authorization_code\", \"refresh_token\"],\n redirect_uris: [this.redirectUrl],\n response_types: [\"code\"],\n token_endpoint_auth_method: \"none\"\n };\n }\n\n get clientUri() {\n return new URL(this.redirectUrl).origin;\n }\n\n get redirectUrl() {\n return this.baseRedirectUrl;\n }\n\n get clientId() {\n if (!this._clientId_) {\n throw new Error(\"Trying to access clientId before it was set\");\n }\n return this._clientId_;\n }\n\n set clientId(clientId_: string) {\n this._clientId_ = clientId_;\n }\n\n get serverId() {\n if (!this._serverId_) {\n throw new Error(\"Trying to access serverId before it was set\");\n }\n return this._serverId_;\n }\n\n set serverId(serverId_: string) {\n this._serverId_ = serverId_;\n }\n\n keyPrefix(clientId: string) {\n return `/${this.clientName}/${this.serverId}/${clientId}`;\n }\n\n clientInfoKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/client_info/`;\n }\n\n discoveryStateKey() {\n return `/${this.clientName}/${this.serverId}/oauth_discovery`;\n }\n\n async saveDiscoveryState(state: OAuthDiscoveryState): Promise<void> {\n await this.storage.put(this.discoveryStateKey(), state);\n }\n\n async discoveryState(): Promise<OAuthDiscoveryState | undefined> {\n return (\n (await this.storage.get<OAuthDiscoveryState>(this.discoveryStateKey())) ??\n undefined\n );\n }\n\n async clientInformation(\n _context?: OAuthClientInformationContext\n ): Promise<StoredOAuthClientInformation | undefined> {\n if (!this._clientId_) return undefined;\n return (\n (await this.storage.get<StoredOAuthClientInformation>(\n this.clientInfoKey(this.clientId)\n )) ?? undefined\n );\n }\n\n async saveClientInformation(\n clientInformation: StoredOAuthClientInformation,\n _context?: OAuthClientInformationContext\n ): Promise<void> {\n this.clientId = clientInformation.client_id;\n // Round-trip the SDK's issuer stamp verbatim. The SDK treats a credential\n // stamped for another issuer as absent, so one durable slot per MCP server\n // is both sufficient and safer than maintaining our own issuer index.\n await this.storage.put(\n this.clientInfoKey(clientInformation.client_id),\n clientInformation\n );\n }\n\n tokenKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/token`;\n }\n\n async tokens(\n _context?: OAuthClientInformationContext\n ): Promise<StoredOAuthTokens | undefined> {\n if (!this._clientId_) return undefined;\n return (\n (await this.storage.get<StoredOAuthTokens>(\n this.tokenKey(this.clientId)\n )) ?? undefined\n );\n }\n\n async saveTokens(\n tokens: StoredOAuthTokens,\n _context?: OAuthClientInformationContext\n ): Promise<void> {\n // Keep the SDK-owned issuer stamp intact for SEP-2352 validation. Discovery\n // is needed across the browser redirect, but once token issuance succeeds\n // it must not pin later re-authorization to this AS: a subsequent 401 must\n // re-read PRM so an authorization-server migration can be observed.\n await this.storage.put(this.tokenKey(this.clientId), tokens);\n await this.storage.delete(this.discoveryStateKey());\n }\n\n get authUrl() {\n return this._authUrl_;\n }\n\n stateKey(nonce: string) {\n return `/${this.clientName}/${this.serverId}/state/${nonce}`;\n }\n\n async state(): Promise<string> {\n const nonce = nanoid();\n const state = `${nonce}.${this.serverId}`;\n const storedState: StoredState = {\n nonce,\n serverId: this.serverId,\n createdAt: Date.now()\n };\n await this.storage.put(this.stateKey(nonce), storedState);\n return state;\n }\n\n async checkState(\n state: string\n ): Promise<{ valid: boolean; serverId?: string; error?: string }> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n return { valid: false, error: \"Invalid state format\" };\n }\n\n const { nonce, serverId } = parsed;\n const key = this.stateKey(nonce);\n const storedState = await this.storage.get<StoredState>(key);\n\n if (!storedState) {\n return { valid: false, error: \"State not found or already used\" };\n }\n\n if (storedState.serverId !== serverId) {\n await this.storage.delete(key);\n return { valid: false, error: \"State serverId mismatch\" };\n }\n\n if (isExpired(storedState.createdAt)) {\n const deleteKeys = [key];\n if (this._clientId_) {\n deleteKeys.push(this.stateCodeVerifierKey(this.clientId, nonce));\n }\n await this.storage.delete(deleteKeys);\n return { valid: false, error: \"State expired\" };\n }\n\n return { valid: true, serverId };\n }\n\n async consumeState(state: string): Promise<void> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n // This should never happen since checkState validates format first.\n // Log for debugging but don't throw - state consumption is best-effort.\n console.warn(`[OAuth] consumeState called with invalid state format`);\n return;\n }\n await this.storage.delete(this.stateKey(parsed.nonce));\n }\n\n async redirectToAuthorization(authUrl: URL): Promise<void> {\n this._authUrl_ = authUrl.toString();\n\n const clientId = this._clientId_;\n const serverId = this._serverId_;\n if (!clientId || !serverId) {\n return;\n }\n\n const state = authUrl.searchParams.get(\"state\");\n const codeChallenge = authUrl.searchParams.get(\"code_challenge\");\n if (!state || !codeChallenge) {\n return;\n }\n\n const parsed = parseOAuthState(state);\n if (!parsed || parsed.serverId !== serverId) {\n return;\n }\n\n const challengeKey = this.challengeCodeVerifierKey(clientId, codeChallenge);\n const pendingVerifier =\n await this.storage.get<StoredCodeVerifier>(challengeKey);\n if (!pendingVerifier) {\n return;\n }\n\n if (isExpired(pendingVerifier.createdAt)) {\n await this.storage.delete(challengeKey);\n return;\n }\n\n await this.storage.put(\n this.stateCodeVerifierKey(clientId, parsed.nonce),\n pendingVerifier\n );\n await this.storage.delete(challengeKey);\n }\n\n async invalidateCredentials(\n scope: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\"\n ): Promise<void> {\n const deleteKeys: string[] = [];\n\n if (scope === \"all\" || scope === \"discovery\") {\n deleteKeys.push(this.discoveryStateKey());\n }\n\n if (this._clientId_) {\n const clientId = this.clientId;\n if (scope === \"all\" || scope === \"client\") {\n deleteKeys.push(this.clientInfoKey(clientId));\n }\n if (scope === \"all\" || scope === \"tokens\") {\n deleteKeys.push(this.tokenKey(clientId));\n }\n if (scope === \"all\" || scope === \"verifier\") {\n deleteKeys.push(\n ...(await this.codeVerifierKeys(clientId, {\n includeChallengeKeys: true\n }))\n );\n }\n }\n\n if (deleteKeys.length > 0) {\n await this.storage.delete([...new Set(deleteKeys)]);\n }\n }\n\n codeVerifierKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier`;\n }\n\n stateCodeVerifierPrefix(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier/`;\n }\n\n stateCodeVerifierKey(clientId: string, nonce: string) {\n return `${this.stateCodeVerifierPrefix(clientId)}${nonce}`;\n }\n\n challengeCodeVerifierPrefix(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier_challenge/`;\n }\n\n challengeCodeVerifierKey(clientId: string, codeChallenge: string) {\n return `${this.challengeCodeVerifierPrefix(clientId)}${codeChallenge}`;\n }\n\n async codeVerifierKeys(\n clientId: string,\n options: { includeChallengeKeys?: boolean } = {}\n ): Promise<string[]> {\n const legacyKey = this.codeVerifierKey(clientId);\n const keys: string[] = [];\n\n if (await this.storage.get(legacyKey)) {\n keys.push(legacyKey);\n }\n\n const stateKeys = await this.storage.list({\n prefix: this.stateCodeVerifierPrefix(clientId)\n });\n keys.push(...stateKeys.keys());\n\n if (options.includeChallengeKeys) {\n const challengeKeys = await this.storage.list({\n prefix: this.challengeCodeVerifierPrefix(clientId)\n });\n keys.push(...challengeKeys.keys());\n }\n\n return keys;\n }\n\n async saveCodeVerifier(verifier: string): Promise<void> {\n await this.deleteExpiredChallengeCodeVerifiers(this.clientId);\n\n const codeChallenge = await createCodeChallenge(verifier);\n const storedVerifier: StoredCodeVerifier = {\n verifier,\n createdAt: Date.now()\n };\n\n await this.storage.put(\n this.challengeCodeVerifierKey(this.clientId, codeChallenge),\n storedVerifier\n );\n }\n\n private async deleteExpiredChallengeCodeVerifiers(\n clientId: string\n ): Promise<void> {\n const challengeVerifiers = await this.storage.list<StoredCodeVerifier>({\n prefix: this.challengeCodeVerifierPrefix(clientId)\n });\n const expiredKeys = [...challengeVerifiers.entries()]\n .filter(([, storedVerifier]) => isExpired(storedVerifier.createdAt))\n .map(([key]) => key);\n if (expiredKeys.length > 0) {\n await this.storage.delete(expiredKeys);\n }\n }\n\n async codeVerifier(): Promise<string> {\n const context = codeVerifierStateStorage.getStore();\n if (context) {\n const stateVerifier = await this.codeVerifierForState(context.state);\n if (stateVerifier) {\n context.servedKey = stateVerifier.key;\n return stateVerifier.verifier;\n }\n }\n\n const legacyVerifier = await this.storage.get<string>(\n this.codeVerifierKey(this.clientId)\n );\n if (legacyVerifier) {\n if (context) {\n context.servedKey = this.codeVerifierKey(this.clientId);\n }\n return legacyVerifier;\n }\n\n if (context) {\n throw new Error(\"No code verifier found for OAuth state\");\n }\n\n const pendingVerifiers = await this.storage.list<StoredCodeVerifier>({\n prefix: this.stateCodeVerifierPrefix(this.clientId)\n });\n const unexpiredPendingVerifiers = [...pendingVerifiers.entries()].filter(\n ([, storedVerifier]) => !isExpired(storedVerifier.createdAt)\n );\n const expiredKeys = [...pendingVerifiers.entries()]\n .filter(([, storedVerifier]) => isExpired(storedVerifier.createdAt))\n .map(([key]) => key);\n if (expiredKeys.length > 0) {\n await this.storage.delete(expiredKeys);\n }\n\n if (unexpiredPendingVerifiers.length === 1) {\n const [[, storedVerifier]] = unexpiredPendingVerifiers;\n return storedVerifier.verifier;\n }\n\n if (unexpiredPendingVerifiers.length > 1) {\n throw new Error(\n \"Multiple OAuth code verifiers are pending; complete authorization with the callback state\"\n );\n }\n\n throw new Error(\"No code verifier found\");\n }\n\n private async codeVerifierForState(\n state: string\n ): Promise<{ key: string; verifier: string } | undefined> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n throw new Error(\"Invalid state format\");\n }\n\n const key = this.stateCodeVerifierKey(this.clientId, parsed.nonce);\n const storedVerifier = await this.storage.get<StoredCodeVerifier>(key);\n if (!storedVerifier) {\n return undefined;\n }\n\n if (isExpired(storedVerifier.createdAt)) {\n await this.storage.delete(key);\n throw new Error(\"Code verifier expired\");\n }\n\n return { key, verifier: storedVerifier.verifier };\n }\n\n async runWithCodeVerifierState<T>(\n state: string,\n callback: () => Promise<T>\n ): Promise<T> {\n return codeVerifierStateStorage.run({ state }, callback);\n }\n\n async deleteCodeVerifier(): Promise<void> {\n const context = codeVerifierStateStorage.getStore();\n if (context?.servedKey) {\n await this.storage.delete(context.servedKey);\n return;\n }\n\n if (context) {\n const parsed = parseOAuthState(context.state);\n if (parsed) {\n await this.storage.delete(\n this.stateCodeVerifierKey(this.clientId, parsed.nonce)\n );\n return;\n }\n }\n\n const keys = await this.codeVerifierKeys(this.clientId);\n if (keys.length > 0) {\n await this.storage.delete(keys);\n }\n }\n}\n"],"mappings":"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"}
|
package/dist/mcp/x402.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"x402.js","names":[],"sources":["../../src/mcp/x402.ts"],"sourcesContent":["/**\n * X402 MCP Integration (v2)\n *\n * Based on:\n * - Coinbase's x402 (Apache 2.0): https://github.com/coinbase/x402\n * - @ethanniser and his work at https://github.com/ethanniser/x402-mcp\n */\n\nimport type {\n McpServer,\n RegisteredTool,\n ToolCallback\n} from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type {\n CallToolRequest,\n CallToolRequestOptions,\n Client as MCPClient\n} from \"@modelcontextprotocol/client\";\nimport type {\n CallToolResult,\n ToolAnnotations\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n bindMcpClient,\n type CallToolSchemaOrOptions,\n type CompatibleMcpClient,\n type LegacyCallToolResultSchema\n} from \"./client-invoker\";\nimport type { ZodRawShape } from \"zod\";\n\n// v2 imports from @x402/core\nimport { x402ResourceServer, HTTPFacilitatorClient } from \"@x402/core/server\";\nimport type { FacilitatorConfig, ResourceConfig } from \"@x402/core/server\";\nimport { x402Client } from \"@x402/core/client\";\nimport type {\n PaymentPayload,\n PaymentRequirements,\n PaymentRequired,\n Network\n} from \"@x402/core/types\";\n\n// v2 imports from @x402/evm\nimport { registerExactEvmScheme as registerServerEvmScheme } from \"@x402/evm/exact/server\";\nimport { registerExactEvmScheme as registerClientEvmScheme } from \"@x402/evm/exact/client\";\nimport type { ClientEvmSigner } from \"@x402/evm\";\n\n// Re-export commonly used types for consumer convenience\nexport type {\n PaymentRequirements,\n PaymentRequired,\n Network\n} from \"@x402/core/types\";\nexport type { FacilitatorConfig } from \"@x402/core/server\";\nexport type { ClientEvmSigner } from \"@x402/evm\";\n\n/**\n * Map of legacy v1 network names to CAIP-2 identifiers.\n * Allows backward compatibility with v1 config.\n */\nconst LEGACY_NETWORK_MAP: Record<string, string> = {\n \"base-sepolia\": \"eip155:84532\",\n base: \"eip155:8453\",\n ethereum: \"eip155:1\",\n sepolia: \"eip155:11155111\"\n};\n\n/**\n * Normalize a network identifier to CAIP-2 format.\n * Accepts both legacy v1 names (\"base-sepolia\") and CAIP-2 (\"eip155:84532\").\n */\nexport function normalizeNetwork(network: string): Network {\n return (LEGACY_NETWORK_MAP[network] ?? network) as Network;\n}\n\n/*\n ======= SERVER SIDE =======\n*/\n\nexport type X402Config = {\n /**\n * Network identifier.\n * Accepts both legacy names (\"base-sepolia\") and CAIP-2 format (\"eip155:84532\").\n */\n network: string;\n /** Payment recipient address */\n recipient: `0x${string}`;\n /** Facilitator configuration. Defaults to https://x402.org/facilitator */\n facilitator?: FacilitatorConfig;\n /** @deprecated No longer used in v2. The protocol version is determined automatically. */\n version?: number;\n};\n\nexport interface X402AugmentedServer {\n paidTool<Args extends ZodRawShape>(\n name: string,\n description: string,\n priceUSD: number,\n paramsSchema: Args,\n annotations: ToolAnnotations,\n cb: ToolCallback<Args>\n ): RegisteredTool;\n}\n\nexport function withX402<T extends McpServer>(\n server: T,\n cfg: X402Config\n): T & X402AugmentedServer {\n const network = normalizeNetwork(cfg.network);\n const facilitatorConfig: FacilitatorConfig = cfg.facilitator ?? {\n url: \"https://x402.org/facilitator\"\n };\n\n // Create v2 resource server with facilitator client\n const facilitatorClient = new HTTPFacilitatorClient(facilitatorConfig);\n const resourceServer = new x402ResourceServer(facilitatorClient);\n registerServerEvmScheme(resourceServer);\n\n // Lazy initialization: fetch supported kinds from facilitator on first use\n let initPromise: Promise<void> | null = null;\n function ensureInitialized(): Promise<void> {\n if (!initPromise) {\n initPromise = resourceServer.initialize().catch((err) => {\n initPromise = null; // allow retry on failure\n throw err;\n });\n }\n return initPromise;\n }\n\n function paidTool<Args extends ZodRawShape>(\n name: string,\n description: string,\n priceUSD: number,\n paramsSchema: Args,\n annotations: ToolAnnotations,\n cb: ToolCallback<Args>\n ): RegisteredTool {\n return server.registerTool(\n name,\n {\n description,\n inputSchema: paramsSchema,\n annotations,\n _meta: {\n \"agents-x402/paymentRequired\": true,\n \"agents-x402/priceUSD\": priceUSD\n }\n },\n (async (args, extra) => {\n await ensureInitialized();\n\n // Build v2 payment requirements for this tool call\n const resourceConfig: ResourceConfig = {\n scheme: \"exact\",\n payTo: cfg.recipient,\n price: priceUSD,\n network,\n maxTimeoutSeconds: 300\n };\n\n let requirements: PaymentRequirements[];\n try {\n requirements =\n await resourceServer.buildPaymentRequirements(resourceConfig);\n } catch {\n const payload = { x402Version: 2, error: \"PRICE_COMPUTE_FAILED\" };\n return {\n isError: true,\n _meta: { \"x402/error\": payload },\n content: [{ type: \"text\", text: JSON.stringify(payload) }]\n } as const;\n }\n\n const resourceInfo = {\n url: `x402://${name}`,\n description,\n mimeType: \"application/json\"\n };\n\n // Get payment token from MCP _meta or HTTP headers\n // Support both v2 (PAYMENT-SIGNATURE) and v1 (X-PAYMENT) header names\n const headers = extra?.requestInfo?.headers ?? {};\n const token =\n (extra?._meta?.[\"x402/payment\"] as string | undefined) ??\n headers[\"PAYMENT-SIGNATURE\"] ??\n headers[\"X-PAYMENT\"];\n\n const paymentRequired = (\n reason = \"PAYMENT_REQUIRED\",\n extraFields: Record<string, unknown> = {}\n ) => {\n const payload = {\n x402Version: 2,\n error: reason,\n resource: resourceInfo,\n accepts: requirements,\n ...extraFields\n };\n return {\n isError: true,\n _meta: { \"x402/error\": payload },\n content: [{ type: \"text\", text: JSON.stringify(payload) }]\n } as const;\n };\n\n if (!token || typeof token !== \"string\") return paymentRequired();\n\n // Decode the payment payload (base64-encoded JSON)\n let paymentPayload: PaymentPayload;\n try {\n paymentPayload = JSON.parse(atob(token));\n } catch {\n return paymentRequired(\"INVALID_PAYMENT\");\n }\n\n // Find matching requirements for this payment\n const matchingReq = resourceServer.findMatchingRequirements(\n requirements,\n paymentPayload\n );\n if (!matchingReq) {\n return paymentRequired(\"INVALID_PAYMENT\");\n }\n\n // Verify payment with facilitator\n try {\n const vr = await resourceServer.verifyPayment(\n paymentPayload,\n matchingReq\n );\n if (!vr.isValid) {\n return paymentRequired(vr.invalidReason ?? \"INVALID_PAYMENT\", {\n payer: vr.payer\n });\n }\n } catch {\n return paymentRequired(\"INVALID_PAYMENT\");\n }\n\n // Execute the tool callback\n let result: CallToolResult;\n let failed = false;\n try {\n result = await cb(args, extra);\n if (\n result &&\n typeof result === \"object\" &&\n \"isError\" in result &&\n result.isError\n ) {\n failed = true;\n }\n } catch (e) {\n failed = true;\n result = {\n isError: true,\n content: [\n { type: \"text\", text: `Tool execution failed: ${String(e)}` }\n ]\n };\n }\n\n // Settle payment only on success\n if (!failed) {\n try {\n const s = await resourceServer.settlePayment(\n paymentPayload,\n matchingReq\n );\n if (s.success) {\n result._meta ??= {};\n result._meta[\"x402/payment-response\"] = {\n success: true,\n transaction: s.transaction,\n network: s.network,\n payer: s.payer\n };\n } else {\n return paymentRequired(s.errorReason ?? \"SETTLEMENT_FAILED\");\n }\n } catch {\n return paymentRequired(\"SETTLEMENT_FAILED\");\n }\n }\n\n return result;\n }) as ToolCallback<Args>\n );\n }\n\n Object.defineProperty(server, \"paidTool\", {\n value: paidTool,\n writable: false,\n enumerable: false,\n configurable: true\n });\n\n // Tell TS the object now also has the paidTool method\n return server as T & X402AugmentedServer;\n}\n\n/*\n ======= CLIENT SIDE =======\n*/\n\nexport interface X402AugmentedClient {\n callTool(\n x402ConfirmationCallback:\n | ((payment: PaymentRequirements[]) => Promise<boolean>)\n | null,\n params: CallToolRequest[\"params\"],\n options?: CallToolRequestOptions\n ): Promise<CallToolResult>;\n /**\n * @deprecated Prefer the request-options overload. Explicit legacy result\n * schemas remain honored through the SDK v2 request funnel.\n */\n callTool(\n x402ConfirmationCallback:\n | ((payment: PaymentRequirements[]) => Promise<boolean>)\n | null,\n params: CallToolRequest[\"params\"],\n resultSchema: LegacyCallToolResultSchema,\n options?: CallToolRequestOptions\n ): Promise<CallToolResult>;\n}\n\nexport type X402ClientConfig = {\n /**\n * EVM account/signer for signing payment authorizations.\n * Use `privateKeyToAccount()` from viem/accounts to create one.\n */\n account: ClientEvmSigner;\n /**\n * Preferred network identifier (optional).\n * Accepts both legacy names (\"base-sepolia\") and CAIP-2 format (\"eip155:84532\").\n * When set, the client prefers payment requirements matching this network.\n * If omitted, the client automatically selects from available requirements.\n */\n network?: string;\n /** Maximum payment value in atomic units (default: 0.10 USDC = 100000) */\n maxPaymentValue?: bigint;\n /** @deprecated No longer used in v2. The protocol version is determined automatically. */\n version?: number;\n /** Confirmation callback for payment approval */\n confirmationCallback?: (payment: PaymentRequirements[]) => Promise<boolean>;\n};\n\nexport function withX402Client<T extends CompatibleMcpClient>(\n client: T,\n x402Config: X402ClientConfig\n): X402AugmentedClient & T {\n const invoker = bindMcpClient(client);\n const { account } = x402Config;\n\n const maxPaymentValue = x402Config.maxPaymentValue ?? BigInt(100_000); // 0.10 USDC\n\n // Create v2 x402 payment client with EVM scheme support\n const paymentClient = new x402Client();\n registerClientEvmScheme(paymentClient, { signer: account });\n\n // If a preferred network is specified, register a policy to prefer it\n if (x402Config.network) {\n const preferredNetwork = normalizeNetwork(x402Config.network);\n paymentClient.registerPolicy((_version, reqs) => {\n const matching = reqs.filter((r) => r.network === preferredNetwork);\n return matching.length > 0 ? matching : reqs;\n });\n }\n\n const listTools = async (\n params?: Parameters<MCPClient[\"listTools\"]>[0],\n options?: Parameters<MCPClient[\"listTools\"]>[1]\n ) => {\n const toolsRes = await invoker.listTools(params, options);\n return {\n ...toolsRes,\n tools: toolsRes.tools.map((tool) => {\n let description = tool.description;\n // Check _meta for payment information (agents-x402/ is our extension for pre-advertising prices)\n if (tool._meta?.[\"agents-x402/paymentRequired\"]) {\n const cost = tool._meta?.[\"agents-x402/priceUSD\"]\n ? `$${tool._meta?.[\"agents-x402/priceUSD\"]}`\n : \"an unknown amount\";\n description += ` (This is a paid tool, you will be charged ${cost} for its execution)`;\n }\n return {\n ...tool,\n description\n };\n })\n };\n };\n\n const callToolWithPayment = async (\n x402ConfirmationCallback:\n | ((payment: PaymentRequirements[]) => Promise<boolean>)\n | null,\n params: CallToolRequest[\"params\"],\n schemaOrOptions?: CallToolSchemaOrOptions,\n options?: CallToolRequestOptions\n ): ReturnType<MCPClient[\"callTool\"]> => {\n const invoke = (callParams: CallToolRequest[\"params\"]) =>\n invoker.callTool(callParams, schemaOrOptions, options);\n const res = await invoke(params);\n\n // Check for x402 payment required error in response metadata\n const maybeX402Error = res._meta?.[\"x402/error\"] as\n | (PaymentRequired & Record<string, unknown>)\n | undefined;\n\n if (\n res.isError &&\n maybeX402Error &&\n maybeX402Error.accepts &&\n Array.isArray(maybeX402Error.accepts) &&\n maybeX402Error.accepts.length > 0\n ) {\n const accepts = maybeX402Error.accepts;\n const confirmationCallback =\n x402ConfirmationCallback ?? x402Config.confirmationCallback;\n\n // Use the confirmation callback if provided\n if (confirmationCallback && !(await confirmationCallback(accepts))) {\n return {\n isError: true,\n content: [{ type: \"text\", text: \"User declined payment\" }]\n };\n }\n\n // Check max payment value against the first requirement's amount\n const selectedReq = accepts[0];\n if (!selectedReq || selectedReq.scheme !== \"exact\") return res;\n\n let amount: bigint;\n try {\n amount = BigInt(selectedReq.amount);\n } catch {\n return res; // malformed amount — return original error\n }\n if (amount > maxPaymentValue) {\n return {\n isError: true,\n content: [\n {\n type: \"text\",\n text: `Payment exceeds client cap: ${amount} > ${maxPaymentValue}`\n }\n ]\n };\n }\n\n // Reconstruct the PaymentRequired response for the v2 x402 client\n const paymentRequiredResponse: PaymentRequired = {\n x402Version: (maybeX402Error.x402Version as number) ?? 2,\n resource: (maybeX402Error.resource as PaymentRequired[\"resource\"]) ?? {\n url: \"\",\n description: \"\",\n mimeType: \"application/json\"\n },\n accepts,\n extensions: maybeX402Error.extensions as\n | Record<string, unknown>\n | undefined\n };\n\n // Create the payment payload using the v2 x402 client\n let paymentPayload: PaymentPayload;\n try {\n paymentPayload = await paymentClient.createPaymentPayload(\n paymentRequiredResponse\n );\n } catch {\n return {\n isError: true,\n content: [{ type: \"text\", text: \"Failed to create payment payload\" }]\n };\n }\n\n // Encode the payment payload as a base64 JSON token for MCP transport\n const token = btoa(JSON.stringify(paymentPayload));\n\n // Retry the tool call with the payment token\n return invoke({\n ...params,\n _meta: {\n ...params._meta,\n \"x402/payment\": token\n }\n });\n }\n\n return res;\n };\n\n const _client = client as X402AugmentedClient & T;\n Object.defineProperty(_client, \"listTools\", {\n value: listTools,\n writable: false,\n enumerable: false,\n configurable: true\n });\n Object.defineProperty(_client, \"callTool\", {\n value: callToolWithPayment,\n writable: false,\n enumerable: false,\n configurable: true\n });\n\n return _client;\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"wire-types-CU9rLoeS.js","names":[],"sources":["../src/chat/stream-accumulator.ts","../src/chat/broadcast-state.ts","../src/chat/protocol.ts","../src/chat/wire-types.ts"],"sourcesContent":["/**\n * StreamAccumulator — unified chunk-to-message builder.\n *\n * Used by @cloudflare/ai-chat (server + client) and @cloudflare/think\n * to incrementally build a UIMessage from stream chunks. Wraps\n * applyChunkToParts and handles the metadata chunk types (start, finish,\n * message-metadata, error) that applyChunkToParts does not cover.\n *\n * The accumulator signals domain-specific concerns (early persistence,\n * cross-message tool updates) via ChunkAction returns — callers handle\n * these according to their context.\n */\n\nimport type { UIMessage } from \"ai\";\nimport { applyChunkToParts, type StreamChunkData } from \"./message-builder\";\n\nfunction asMetadata(value: unknown): Record<string, unknown> | undefined {\n if (value != null && typeof value === \"object\" && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n return undefined;\n}\n\nexport interface StreamAccumulatorOptions {\n messageId: string;\n continuation?: boolean;\n existingParts?: UIMessage[\"parts\"];\n existingMetadata?: Record<string, unknown>;\n}\n\nexport type ChunkAction =\n | {\n type: \"start\";\n messageId?: string;\n metadata?: Record<string, unknown>;\n }\n | {\n type: \"finish\";\n finishReason?: string;\n metadata?: Record<string, unknown>;\n }\n | { type: \"message-metadata\"; metadata: Record<string, unknown> }\n | { type: \"tool-approval-request\"; toolCallId: string }\n | {\n type: \"cross-message-tool-update\";\n updateType: \"output-available\" | \"output-error\";\n toolCallId: string;\n output?: unknown;\n errorText?: string;\n preliminary?: boolean;\n }\n | { type: \"error\"; error: string };\n\nexport interface ChunkResult {\n handled: boolean;\n action?: ChunkAction;\n}\n\nexport class StreamAccumulator {\n messageId: string;\n readonly parts: UIMessage[\"parts\"];\n metadata?: Record<string, unknown>;\n private _isContinuation: boolean;\n\n constructor(options: StreamAccumulatorOptions) {\n this.messageId = options.messageId;\n this._isContinuation = options.continuation ?? false;\n this.parts = options.existingParts ? [...options.existingParts] : [];\n this.metadata = options.existingMetadata\n ? { ...options.existingMetadata }\n : undefined;\n }\n\n applyChunk(chunk: StreamChunkData): ChunkResult {\n const handled = applyChunkToParts(this.parts, chunk);\n\n // Detect tool-approval-request for early persistence signaling\n if (chunk.type === \"tool-approval-request\" && chunk.toolCallId) {\n return {\n handled,\n action: { type: \"tool-approval-request\", toolCallId: chunk.toolCallId }\n };\n }\n\n // Detect cross-message tool output/error: applyChunkToParts returns true\n // for recognized types but silently does nothing when the toolCallId\n // doesn't exist in the current parts array.\n if (\n (chunk.type === \"tool-output-available\" ||\n chunk.type === \"tool-output-error\") &&\n chunk.toolCallId\n ) {\n const foundInParts = this.parts.some(\n (p) => \"toolCallId\" in p && p.toolCallId === chunk.toolCallId\n );\n if (!foundInParts) {\n return {\n handled,\n action: {\n type: \"cross-message-tool-update\",\n updateType:\n chunk.type === \"tool-output-available\"\n ? \"output-available\"\n : \"output-error\",\n toolCallId: chunk.toolCallId,\n output: chunk.output,\n errorText: chunk.errorText,\n preliminary: chunk.preliminary\n }\n };\n }\n }\n\n if (!handled) {\n switch (chunk.type) {\n case \"start\": {\n if (chunk.messageId != null && !this._isContinuation) {\n this.messageId = chunk.messageId;\n }\n const startMeta = asMetadata(chunk.messageMetadata);\n if (startMeta) {\n this.metadata = this.metadata\n ? { ...this.metadata, ...startMeta }\n : { ...startMeta };\n }\n return {\n handled: true,\n action: {\n type: \"start\",\n messageId: chunk.messageId,\n metadata: startMeta\n }\n };\n }\n case \"finish\": {\n const finishMeta = asMetadata(chunk.messageMetadata);\n if (finishMeta) {\n this.metadata = this.metadata\n ? { ...this.metadata, ...finishMeta }\n : { ...finishMeta };\n }\n const finishReason =\n \"finishReason\" in chunk\n ? (chunk.finishReason as string)\n : undefined;\n return {\n handled: true,\n action: {\n type: \"finish\",\n finishReason,\n metadata: finishMeta\n }\n };\n }\n case \"message-metadata\": {\n const msgMeta = asMetadata(chunk.messageMetadata);\n if (msgMeta) {\n this.metadata = this.metadata\n ? { ...this.metadata, ...msgMeta }\n : { ...msgMeta };\n }\n return {\n handled: true,\n action: {\n type: \"message-metadata\",\n metadata: msgMeta ?? {}\n }\n };\n }\n case \"finish-step\": {\n return { handled: true };\n }\n case \"error\": {\n return {\n handled: true,\n action: {\n type: \"error\",\n error: chunk.errorText ?? JSON.stringify(chunk)\n }\n };\n }\n }\n }\n\n return { handled };\n }\n\n /** Snapshot the current state as a UIMessage. */\n toMessage(): UIMessage {\n return {\n id: this.messageId,\n role: \"assistant\",\n parts: [...this.parts],\n ...(this.metadata != null && { metadata: this.metadata })\n } as UIMessage;\n }\n\n /**\n * Merge this accumulator's message into an existing message array.\n * Handles continuation (walk backward for last assistant), replacement\n * (update existing by messageId), or append (new message).\n */\n mergeInto(messages: UIMessage[]): UIMessage[] {\n let existingIdx = messages.findIndex((m) => m.id === this.messageId);\n\n if (existingIdx < 0 && this._isContinuation) {\n for (let i = messages.length - 1; i >= 0; i--) {\n if (messages[i].role === \"assistant\") {\n existingIdx = i;\n break;\n }\n }\n }\n\n const messageId =\n existingIdx >= 0 ? messages[existingIdx].id : this.messageId;\n\n const partialMessage: UIMessage = {\n id: messageId,\n role: \"assistant\",\n parts: [...this.parts],\n ...(this.metadata != null && { metadata: this.metadata })\n } as UIMessage;\n\n if (existingIdx >= 0) {\n const updated = [...messages];\n updated[existingIdx] = partialMessage;\n return updated;\n }\n return [...messages, partialMessage];\n }\n}\n","/**\n * Broadcast stream state machine.\n *\n * Manages the lifecycle of a StreamAccumulator for broadcast/resume\n * streams — the path where this client is *observing* a stream owned\n * by another tab or resumed after reconnect, rather than the transport-\n * owned path that feeds directly into useChat.\n *\n * The transition function is pure (no React, no WebSocket, no side\n * effects). Callers dispatch events and apply the returned state +\n * messagesUpdate. Side effects (sending ACKs, calling onData) stay\n * in the caller.\n */\n\nimport type { UIMessage } from \"ai\";\nimport { StreamAccumulator } from \"./stream-accumulator\";\nimport type { StreamChunkData } from \"./message-builder\";\n\n// ── State ──────────────────────────────────────────────────────────\n\nexport type BroadcastStreamState =\n | { status: \"idle\" }\n | {\n status: \"observing\";\n streamId: string;\n accumulator: StreamAccumulator;\n };\n\n// ── Events ─────────────────────────────────────────────────────────\n\nexport type BroadcastStreamEvent =\n | {\n type: \"response\";\n streamId: string;\n /** Fallback message ID for a new accumulator (ignored if one exists for this stream). */\n messageId: string;\n chunkData?: unknown;\n done?: boolean;\n error?: boolean;\n replay?: boolean;\n replayComplete?: boolean;\n continuation?: boolean;\n /** Required when continuation=true so the accumulator can pick up existing parts. */\n currentMessages?: UIMessage[];\n }\n | {\n type: \"resume-fallback\";\n streamId: string;\n messageId: string;\n }\n | { type: \"clear\" };\n\n// ── Result ─────────────────────────────────────────────────────────\n\nexport interface TransitionResult {\n state: BroadcastStreamState;\n messagesUpdate?: (prev: UIMessage[]) => UIMessage[];\n isStreaming: boolean;\n}\n\n// ── Transition ─────────────────────────────────────────────────────\n\nexport function transition(\n state: BroadcastStreamState,\n event: BroadcastStreamEvent\n): TransitionResult {\n switch (event.type) {\n case \"clear\":\n return { state: { status: \"idle\" }, isStreaming: false };\n\n case \"resume-fallback\": {\n const accumulator = new StreamAccumulator({\n messageId: event.messageId\n });\n return {\n state: {\n status: \"observing\",\n streamId: event.streamId,\n accumulator\n },\n isStreaming: true\n };\n }\n\n case \"response\": {\n let accumulator: StreamAccumulator;\n\n // A replayed `start` chunk means the server is re-sending the stream\n // buffer from chunk 0 (resume replay). Re-initialize the accumulator\n // instead of appending into an existing one: replaying into an\n // accumulator that already holds this stream's parts would duplicate\n // them (a second `text-start` unconditionally opens a second text\n // part — #1733). Re-initializing makes replay idempotent under any\n // number of replays, including a second replay triggered by a\n // duplicate STREAM_RESUMING → ACK cycle or a reconnect.\n const isReplayedStart =\n event.replay === true &&\n (event.chunkData as { type?: string } | null | undefined)?.type ===\n \"start\";\n\n if (\n state.status === \"idle\" ||\n state.streamId !== event.streamId ||\n isReplayedStart\n ) {\n let messageId = event.messageId;\n let existingParts: UIMessage[\"parts\"] | undefined;\n let existingMetadata: Record<string, unknown> | undefined;\n\n if (event.continuation && event.currentMessages) {\n for (let i = event.currentMessages.length - 1; i >= 0; i--) {\n if (event.currentMessages[i].role === \"assistant\") {\n messageId = event.currentMessages[i].id;\n existingParts = [...event.currentMessages[i].parts];\n if (event.currentMessages[i].metadata != null) {\n existingMetadata = {\n ...(event.currentMessages[i].metadata as Record<\n string,\n unknown\n >)\n };\n }\n break;\n }\n }\n }\n\n accumulator = new StreamAccumulator({\n messageId,\n continuation: event.continuation,\n existingParts,\n existingMetadata\n });\n } else {\n accumulator = state.accumulator;\n }\n\n if (event.chunkData) {\n accumulator.applyChunk(event.chunkData as StreamChunkData);\n }\n\n let messagesUpdate: ((prev: UIMessage[]) => UIMessage[]) | undefined;\n\n if (event.done) {\n messagesUpdate = (prev) => accumulator.mergeInto(prev);\n return {\n state: { status: \"idle\" },\n messagesUpdate,\n isStreaming: false\n };\n }\n\n if (event.chunkData && !event.replay) {\n messagesUpdate = (prev) => accumulator.mergeInto(prev);\n } else if (event.replayComplete) {\n messagesUpdate = (prev) => accumulator.mergeInto(prev);\n }\n\n return {\n state: {\n status: \"observing\",\n streamId: event.streamId,\n accumulator\n },\n messagesUpdate,\n isStreaming: true\n };\n }\n }\n}\n","/**\n * Wire protocol message type constants for the cf_agent_chat_* protocol.\n *\n * These are the string values used on the wire between agent servers and\n * clients. Both @cloudflare/ai-chat (via its MessageType enum) and\n * @cloudflare/think use these values.\n */\nexport const STREAM_RESUME_NONE_REASONS = {\n /** No active, pending, or terminal stream exists for this agent. */\n IDLE: \"idle\",\n /** An active tool continuation is owned by another live connection. */\n CONTINUATION_OWNED: \"continuation-owned\"\n} as const;\n\nexport type StreamResumeNoneReason =\n (typeof STREAM_RESUME_NONE_REASONS)[keyof typeof STREAM_RESUME_NONE_REASONS];\n\nexport const CHAT_MESSAGE_TYPES = {\n CHAT_MESSAGES: \"cf_agent_chat_messages\",\n USE_CHAT_REQUEST: \"cf_agent_use_chat_request\",\n USE_CHAT_RESPONSE: \"cf_agent_use_chat_response\",\n CHAT_CLEAR: \"cf_agent_chat_clear\",\n CHAT_REQUEST_CANCEL: \"cf_agent_chat_request_cancel\",\n STREAM_RESUMING: \"cf_agent_stream_resuming\",\n STREAM_RESUME_ACK: \"cf_agent_stream_resume_ack\",\n STREAM_RESUME_REQUEST: \"cf_agent_stream_resume_request\",\n STREAM_RESUME_NONE: \"cf_agent_stream_resume_none\",\n // Server→client: a turn has been accepted but its resumable stream has not\n // started yet (queued, debouncing, waiting on MCP setup, or running async\n // work in `onChatMessage`). Sent in response to a resume request (or on\n // connect) so a reconnecting/re-mounting client keeps its expectation instead\n // of resolving its resume probe to \"no stream\" and then false-timing-out the\n // turn. Resolved by a later `STREAM_RESUMING` (stream started) or\n // `STREAM_RESUME_NONE` (turn settled without streaming). Backward-compatible —\n // clients that don't understand it ignore it. See issue #1784.\n STREAM_PENDING: \"cf_agent_stream_pending\",\n TOOL_RESULT: \"cf_agent_tool_result\",\n TOOL_APPROVAL: \"cf_agent_tool_approval\",\n MESSAGE_UPDATED: \"cf_agent_message_updated\",\n // Server→client: a durable chat turn is being recovered (interrupted by a\n // deploy/eviction or a stream-stall watchdog abort and now resuming). Sent\n // when a recovery continuation is scheduled and cleared on every terminal\n // outcome; `@cloudflare/think` also replays it on connect so a client that\n // joins mid-recovery learns it. Purely a progress hint — backward-compatible\n // (clients that don't understand it ignore it). See issue #1620.\n CHAT_RECOVERING: \"cf_agent_chat_recovering\"\n} as const;\n","import type { JSONSchema7, UIMessage } from \"ai\";\nimport type { StreamResumeNoneReason } from \"./protocol\";\n\n/**\n * Enum for message types to improve type safety and maintainability\n */\nexport enum MessageType {\n CF_AGENT_CHAT_MESSAGES = \"cf_agent_chat_messages\",\n CF_AGENT_USE_CHAT_REQUEST = \"cf_agent_use_chat_request\",\n CF_AGENT_USE_CHAT_RESPONSE = \"cf_agent_use_chat_response\",\n CF_AGENT_CHAT_CLEAR = \"cf_agent_chat_clear\",\n CF_AGENT_CHAT_REQUEST_CANCEL = \"cf_agent_chat_request_cancel\",\n\n /** Sent by server when client connects and there's an active stream to resume */\n CF_AGENT_STREAM_RESUMING = \"cf_agent_stream_resuming\",\n /** Sent by client to acknowledge stream resuming notification and request chunks */\n CF_AGENT_STREAM_RESUME_ACK = \"cf_agent_stream_resume_ack\",\n /** Sent by client after message handler is ready, requesting stream resume check */\n CF_AGENT_STREAM_RESUME_REQUEST = \"cf_agent_stream_resume_request\",\n /** Sent by server when client requests resume but no active stream exists */\n CF_AGENT_STREAM_RESUME_NONE = \"cf_agent_stream_resume_none\",\n /**\n * Sent by server when a turn is accepted but its resumable stream has not\n * started yet (queued / debouncing / waiting on MCP / async setup). Tells a\n * reconnecting client to keep waiting rather than resolve its resume probe to\n * \"no stream\". Resolved by a later `CF_AGENT_STREAM_RESUMING` (stream started)\n * or `CF_AGENT_STREAM_RESUME_NONE` (settled without streaming). See #1784.\n */\n CF_AGENT_STREAM_PENDING = \"cf_agent_stream_pending\",\n\n /** Client sends tool result to server (for client-side tools) */\n CF_AGENT_TOOL_RESULT = \"cf_agent_tool_result\",\n /** Server notifies client that a message was updated (e.g., tool result applied) */\n CF_AGENT_MESSAGE_UPDATED = \"cf_agent_message_updated\",\n /** Client sends tool approval response to server (for tools with needsApproval) */\n CF_AGENT_TOOL_APPROVAL = \"cf_agent_tool_approval\",\n\n /**\n * Server→client progress hint: a durable chat turn is being recovered\n * (interrupted by a deploy/eviction or a stream-stall watchdog abort and now\n * resuming). Sent when a recovery continuation is scheduled and cleared on\n * every terminal outcome. (`@cloudflare/think` also replays it on connect;\n * `@cloudflare/ai-chat` broadcasts the live signal only — see #1645.)\n * Backward-compatible — clients that don't understand it ignore it. See #1620.\n */\n CF_AGENT_CHAT_RECOVERING = \"cf_agent_chat_recovering\"\n}\n\n/**\n * Types of messages sent from the Agent to clients\n */\nexport type OutgoingMessage<ChatMessage extends UIMessage = UIMessage> =\n | {\n /** Indicates this message is a command to clear chat history */\n type: MessageType.CF_AGENT_CHAT_CLEAR;\n }\n | {\n /** Indicates this message contains updated chat messages */\n type: MessageType.CF_AGENT_CHAT_MESSAGES;\n /** Array of chat messages */\n messages: readonly ChatMessage[];\n }\n | {\n /** Indicates this message is a response to a chat request */\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE;\n /** Unique ID of the request this response corresponds to */\n id: string;\n /** Content body of the response */\n body: string;\n /** Whether this is the final chunk of the response */\n done: boolean;\n /** Whether this response contains an error */\n error?: boolean;\n /** Whether this is a continuation (append to last assistant message) */\n continuation?: boolean;\n /** Whether this chunk is being replayed from storage (stream resumption) */\n replay?: boolean;\n /** Signals that replay of stored chunks is complete (stream is still active) */\n replayComplete?: boolean;\n }\n | {\n /** Indicates the server is resuming an active stream */\n type: MessageType.CF_AGENT_STREAM_RESUMING;\n /** The request ID of the stream being resumed */\n id: string;\n /** Present when this offer directly answers a client resume probe. */\n probeId?: string;\n }\n | {\n /** Server notifies client that a message was updated (e.g., tool result applied) */\n type: MessageType.CF_AGENT_MESSAGE_UPDATED;\n /** The updated message */\n message: ChatMessage;\n }\n | {\n /** Server responds to a resume request with no stream for this client. */\n type: MessageType.CF_AGENT_STREAM_RESUME_NONE;\n /**\n * Why no stream was offered. Only `idle` proves global inactivity;\n * omitted by older servers and by non-authoritative delayed releases.\n */\n reason?: StreamResumeNoneReason;\n /** Correlates an authoritative response to its client resume probe. */\n probeId?: string;\n }\n | {\n /**\n * Server signals an accepted turn whose resumable stream has not started\n * yet — the client should keep waiting for `STREAM_RESUMING` (or a later\n * `STREAM_RESUME_NONE`) rather than give up. See #1784.\n */\n type: MessageType.CF_AGENT_STREAM_PENDING;\n /** The accepted request id, when known. */\n id?: string;\n /** Correlates a direct keep-waiting response to its client probe. */\n probeId?: string;\n }\n | {\n /**\n * Progress hint: a durable chat turn is being recovered (`recovering:\n * true`) or recovery has resolved (`recovering: false`). Purely advisory;\n * a client renders a \"recovering…\" indicator while true.\n */\n type: MessageType.CF_AGENT_CHAT_RECOVERING;\n /** Whether recovery is in progress (true) or has resolved (false). */\n recovering: boolean;\n /** The recovery-root request id of the turn being recovered, if known. */\n id?: string;\n };\n\n/**\n * Types of messages sent from clients to the Agent\n */\nexport type IncomingMessage<ChatMessage extends UIMessage = UIMessage> =\n | {\n /** Indicates this message is a command to clear chat history */\n type: MessageType.CF_AGENT_CHAT_CLEAR;\n }\n | {\n /** Indicates this message is a request to the chat API */\n type: MessageType.CF_AGENT_USE_CHAT_REQUEST;\n /** Unique ID for this request */\n id: string;\n /** Request initialization options */\n init: Pick<\n RequestInit,\n | \"method\"\n | \"keepalive\"\n | \"headers\"\n | \"body\"\n | \"redirect\"\n | \"integrity\"\n | \"credentials\"\n | \"mode\"\n | \"referrer\"\n | \"referrerPolicy\"\n | \"window\"\n >;\n }\n | {\n /** Indicates this message contains updated chat messages */\n type: MessageType.CF_AGENT_CHAT_MESSAGES;\n /** Array of chat messages */\n messages: ChatMessage[];\n }\n | {\n /** Indicates the user wants to stop generation of this message */\n type: MessageType.CF_AGENT_CHAT_REQUEST_CANCEL;\n id: string;\n }\n | {\n /** Client acknowledges stream resuming notification and is ready to receive chunks */\n type: MessageType.CF_AGENT_STREAM_RESUME_ACK;\n /** The request ID of the stream being resumed */\n id: string;\n }\n | {\n /** Client requests stream resume check after message handler is registered */\n type: MessageType.CF_AGENT_STREAM_RESUME_REQUEST;\n /** Opaque correlation id echoed by direct server responses. */\n probeId?: string;\n }\n | {\n /** Client sends tool result to server (for client-side tools) */\n type: MessageType.CF_AGENT_TOOL_RESULT;\n /** The tool call ID this result is for */\n toolCallId: string;\n /** The name of the tool */\n toolName: string;\n /** The output from the tool execution */\n output: unknown;\n /** Override the tool part state (e.g. \"output-error\" for custom denial) */\n state?: \"output-available\" | \"output-error\";\n /** Error message when state is \"output-error\" */\n errorText?: string;\n /** Whether server should auto-continue the conversation after applying result */\n autoContinue?: boolean;\n /** Client tool schemas for continuation (client is source of truth) */\n clientTools?: Array<{\n name: string;\n description?: string;\n parameters?: JSONSchema7;\n }>;\n }\n | {\n /** Client sends tool approval response to server (for tools with needsApproval) */\n type: MessageType.CF_AGENT_TOOL_APPROVAL;\n /** The tool call ID this approval is for */\n toolCallId: string;\n /** Whether the tool execution was approved */\n approved: boolean;\n /** Whether server should auto-continue the conversation after applying approval */\n autoContinue?: boolean;\n };\n"],"mappings":";;AAgBA,SAAS,WAAW,OAAqD;CACvE,IAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GACpE,OAAO;AAGX;AAqCA,IAAa,oBAAb,MAA+B;CAM7B,YAAY,SAAmC;EAC7C,KAAK,YAAY,QAAQ;EACzB,KAAK,kBAAkB,QAAQ,gBAAgB;EAC/C,KAAK,QAAQ,QAAQ,gBAAgB,CAAC,GAAG,QAAQ,aAAa,IAAI,CAAC;EACnE,KAAK,WAAW,QAAQ,mBACpB,EAAE,GAAG,QAAQ,iBAAiB,IAC9B,KAAA;CACN;CAEA,WAAW,OAAqC;EAC9C,MAAM,UAAU,kBAAkB,KAAK,OAAO,KAAK;EAGnD,IAAI,MAAM,SAAS,2BAA2B,MAAM,YAClD,OAAO;GACL;GACA,QAAQ;IAAE,MAAM;IAAyB,YAAY,MAAM;GAAW;EACxE;EAMF,KACG,MAAM,SAAS,2BACd,MAAM,SAAS,wBACjB,MAAM;OAKF,CAHiB,KAAK,MAAM,MAC7B,MAAM,gBAAgB,KAAK,EAAE,eAAe,MAAM,UAErC,GACd,OAAO;IACL;IACA,QAAQ;KACN,MAAM;KACN,YACE,MAAM,SAAS,0BACX,qBACA;KACN,YAAY,MAAM;KAClB,QAAQ,MAAM;KACd,WAAW,MAAM;KACjB,aAAa,MAAM;IACrB;GACF;EAAA;EAIJ,IAAI,CAAC,SACH,QAAQ,MAAM,MAAd;GACE,KAAK,SAAS;IACZ,IAAI,MAAM,aAAa,QAAQ,CAAC,KAAK,iBACnC,KAAK,YAAY,MAAM;IAEzB,MAAM,YAAY,WAAW,MAAM,eAAe;IAClD,IAAI,WACF,KAAK,WAAW,KAAK,WACjB;KAAE,GAAG,KAAK;KAAU,GAAG;IAAU,IACjC,EAAE,GAAG,UAAU;IAErB,OAAO;KACL,SAAS;KACT,QAAQ;MACN,MAAM;MACN,WAAW,MAAM;MACjB,UAAU;KACZ;IACF;GACF;GACA,KAAK,UAAU;IACb,MAAM,aAAa,WAAW,MAAM,eAAe;IACnD,IAAI,YACF,KAAK,WAAW,KAAK,WACjB;KAAE,GAAG,KAAK;KAAU,GAAG;IAAW,IAClC,EAAE,GAAG,WAAW;IAMtB,OAAO;KACL,SAAS;KACT,QAAQ;MACN,MAAM;MACN,cAPF,kBAAkB,QACb,MAAM,eACP,KAAA;MAMF,UAAU;KACZ;IACF;GACF;GACA,KAAK,oBAAoB;IACvB,MAAM,UAAU,WAAW,MAAM,eAAe;IAChD,IAAI,SACF,KAAK,WAAW,KAAK,WACjB;KAAE,GAAG,KAAK;KAAU,GAAG;IAAQ,IAC/B,EAAE,GAAG,QAAQ;IAEnB,OAAO;KACL,SAAS;KACT,QAAQ;MACN,MAAM;MACN,UAAU,WAAW,CAAC;KACxB;IACF;GACF;GACA,KAAK,eACH,OAAO,EAAE,SAAS,KAAK;GAEzB,KAAK,SACH,OAAO;IACL,SAAS;IACT,QAAQ;KACN,MAAM;KACN,OAAO,MAAM,aAAa,KAAK,UAAU,KAAK;IAChD;GACF;EAEJ;EAGF,OAAO,EAAE,QAAQ;CACnB;;CAGA,YAAuB;EACrB,OAAO;GACL,IAAI,KAAK;GACT,MAAM;GACN,OAAO,CAAC,GAAG,KAAK,KAAK;GACrB,GAAI,KAAK,YAAY,QAAQ,EAAE,UAAU,KAAK,SAAS;EACzD;CACF;;;;;;CAOA,UAAU,UAAoC;EAC5C,IAAI,cAAc,SAAS,WAAW,MAAM,EAAE,OAAO,KAAK,SAAS;EAEnE,IAAI,cAAc,KAAK,KAAK;QACrB,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KACxC,IAAI,SAAS,EAAE,CAAC,SAAS,aAAa;IACpC,cAAc;IACd;GACF;;EAOJ,MAAM,iBAA4B;GAChC,IAHA,eAAe,IAAI,SAAS,YAAY,CAAC,KAAK,KAAK;GAInD,MAAM;GACN,OAAO,CAAC,GAAG,KAAK,KAAK;GACrB,GAAI,KAAK,YAAY,QAAQ,EAAE,UAAU,KAAK,SAAS;EACzD;EAEA,IAAI,eAAe,GAAG;GACpB,MAAM,UAAU,CAAC,GAAG,QAAQ;GAC5B,QAAQ,eAAe;GACvB,OAAO;EACT;EACA,OAAO,CAAC,GAAG,UAAU,cAAc;CACrC;AACF;;;ACzKA,SAAgB,WACd,OACA,OACkB;CAClB,QAAQ,MAAM,MAAd;EACE,KAAK,SACH,OAAO;GAAE,OAAO,EAAE,QAAQ,OAAO;GAAG,aAAa;EAAM;EAEzD,KAAK,mBAAmB;GACtB,MAAM,cAAc,IAAI,kBAAkB,EACxC,WAAW,MAAM,UACnB,CAAC;GACD,OAAO;IACL,OAAO;KACL,QAAQ;KACR,UAAU,MAAM;KAChB;IACF;IACA,aAAa;GACf;EACF;EAEA,KAAK,YAAY;GACf,IAAI;GAUJ,MAAM,kBACJ,MAAM,WAAW,QAChB,MAAM,WAAoD,SACzD;GAEJ,IACE,MAAM,WAAW,UACjB,MAAM,aAAa,MAAM,YACzB,iBACA;IACA,IAAI,YAAY,MAAM;IACtB,IAAI;IACJ,IAAI;IAEJ,IAAI,MAAM,gBAAgB,MAAM;UACzB,IAAI,IAAI,MAAM,gBAAgB,SAAS,GAAG,KAAK,GAAG,KACrD,IAAI,MAAM,gBAAgB,EAAE,CAAC,SAAS,aAAa;MACjD,YAAY,MAAM,gBAAgB,EAAE,CAAC;MACrC,gBAAgB,CAAC,GAAG,MAAM,gBAAgB,EAAE,CAAC,KAAK;MAClD,IAAI,MAAM,gBAAgB,EAAE,CAAC,YAAY,MACvC,mBAAmB,EACjB,GAAI,MAAM,gBAAgB,EAAE,CAAC,SAI/B;MAEF;KACF;;IAIJ,cAAc,IAAI,kBAAkB;KAClC;KACA,cAAc,MAAM;KACpB;KACA;IACF,CAAC;GACH,OACE,cAAc,MAAM;GAGtB,IAAI,MAAM,WACR,YAAY,WAAW,MAAM,SAA4B;GAG3D,IAAI;GAEJ,IAAI,MAAM,MAAM;IACd,kBAAkB,SAAS,YAAY,UAAU,IAAI;IACrD,OAAO;KACL,OAAO,EAAE,QAAQ,OAAO;KACxB;KACA,aAAa;IACf;GACF;GAEA,IAAI,MAAM,aAAa,CAAC,MAAM,QAC5B,kBAAkB,SAAS,YAAY,UAAU,IAAI;QAChD,IAAI,MAAM,gBACf,kBAAkB,SAAS,YAAY,UAAU,IAAI;GAGvD,OAAO;IACL,OAAO;KACL,QAAQ;KACR,UAAU,MAAM;KAChB;IACF;IACA;IACA,aAAa;GACf;EACF;CACF;AACF;;;;;;;;;;AClKA,MAAa,6BAA6B;;CAExC,MAAM;;CAEN,oBAAoB;AACtB;AAKA,MAAa,qBAAqB;CAChC,eAAe;CACf,kBAAkB;CAClB,mBAAmB;CACnB,YAAY;CACZ,qBAAqB;CACrB,iBAAiB;CACjB,mBAAmB;CACnB,uBAAuB;CACvB,oBAAoB;CASpB,gBAAgB;CAChB,aAAa;CACb,eAAe;CACf,iBAAiB;CAOjB,iBAAiB;AACnB;;;;;;ACxCA,IAAY,cAAL,yBAAA,aAAA;CACL,YAAA,4BAAA;CACA,YAAA,+BAAA;CACA,YAAA,gCAAA;CACA,YAAA,yBAAA;CACA,YAAA,kCAAA;;CAGA,YAAA,8BAAA;;CAEA,YAAA,gCAAA;;CAEA,YAAA,oCAAA;;CAEA,YAAA,iCAAA;;;;;;;;CAQA,YAAA,6BAAA;;CAGA,YAAA,0BAAA;;CAEA,YAAA,8BAAA;;CAEA,YAAA,4BAAA;;;;;;;;;CAUA,YAAA,8BAAA;;AACF,EAAA,CAAA,CAAA"}
|
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
WorkflowEvent,
|
|
3
|
-
WorkflowSleepDuration,
|
|
4
|
-
WorkflowStep
|
|
5
|
-
} from "cloudflare:workers";
|
|
6
|
-
|
|
7
|
-
//#region src/workflow-types.d.ts
|
|
8
|
-
type AgentWorkflowPathStep = {
|
|
9
|
-
className: string;
|
|
10
|
-
name: string;
|
|
11
|
-
};
|
|
12
|
-
type AgentWorkflowOrigin =
|
|
13
|
-
| {
|
|
14
|
-
kind: "agent";
|
|
15
|
-
version: 1 /** Environment binding name for the top-level Agent namespace */;
|
|
16
|
-
binding: string /** Name/ID of the top-level Agent */;
|
|
17
|
-
name: string;
|
|
18
|
-
}
|
|
19
|
-
| {
|
|
20
|
-
kind: "facet";
|
|
21
|
-
version: 1 /** Environment binding name for the root Agent namespace */;
|
|
22
|
-
rootBinding: string /** Root-first path to the originating facet, including itself */;
|
|
23
|
-
path: AgentWorkflowPathStep[];
|
|
24
|
-
};
|
|
25
|
-
/**
|
|
26
|
-
* Type alias for WorkflowEvent in AgentWorkflow context.
|
|
27
|
-
* Identical to WorkflowEvent - provided for naming consistency with AgentWorkflowStep.
|
|
28
|
-
*/
|
|
29
|
-
type AgentWorkflowEvent<Params = unknown> = WorkflowEvent<Params>;
|
|
30
|
-
/**
|
|
31
|
-
* Extended WorkflowStep with durable Agent communication methods.
|
|
32
|
-
* All added methods on this interface are durable - they're idempotent and won't
|
|
33
|
-
* repeat on workflow retry.
|
|
34
|
-
*/
|
|
35
|
-
interface AgentWorkflowStep extends WorkflowStep {
|
|
36
|
-
/**
|
|
37
|
-
* Report successful completion to the Agent (durable).
|
|
38
|
-
* Triggers onWorkflowComplete() on the Agent.
|
|
39
|
-
* @param result - Optional result data
|
|
40
|
-
*/
|
|
41
|
-
reportComplete<T = unknown>(result?: T): Promise<void>;
|
|
42
|
-
/**
|
|
43
|
-
* Report an error to the Agent (durable).
|
|
44
|
-
* Triggers onWorkflowError() on the Agent.
|
|
45
|
-
* @param error - Error or error message
|
|
46
|
-
*/
|
|
47
|
-
reportError(error: Error | string): Promise<void>;
|
|
48
|
-
/**
|
|
49
|
-
* Send a custom event to the Agent (durable).
|
|
50
|
-
* Triggers onWorkflowEvent() on the Agent.
|
|
51
|
-
* @param event - Custom event payload
|
|
52
|
-
*/
|
|
53
|
-
sendEvent<T = unknown>(event: T): Promise<void>;
|
|
54
|
-
/**
|
|
55
|
-
* Update the Agent's state entirely (durable).
|
|
56
|
-
* This will replace the Agent's state and broadcast to all connected clients.
|
|
57
|
-
* @param state - New state to set
|
|
58
|
-
*/
|
|
59
|
-
updateAgentState(state: unknown): Promise<void>;
|
|
60
|
-
/**
|
|
61
|
-
* Merge partial state into the Agent's existing state (durable).
|
|
62
|
-
* Performs a shallow merge and broadcasts to all connected clients.
|
|
63
|
-
* @param partialState - Partial state to merge
|
|
64
|
-
*/
|
|
65
|
-
mergeAgentState(partialState: Record<string, unknown>): Promise<void>;
|
|
66
|
-
/**
|
|
67
|
-
* Reset the Agent's state to its initialState (durable).
|
|
68
|
-
* Broadcasts the reset state to all connected clients.
|
|
69
|
-
*/
|
|
70
|
-
resetAgentState(): Promise<void>;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Internal parameters injected by runWorkflow() to identify the originating Agent
|
|
74
|
-
*/
|
|
75
|
-
type AgentWorkflowInternalParams = {
|
|
76
|
-
/** Name/ID of the Agent that started this workflow */ __agentName: string /** Environment binding name for the Agent's namespace */;
|
|
77
|
-
__agentBinding: string /** Workflow binding name (for callbacks) */;
|
|
78
|
-
__workflowName: string /** Versioned origin identity for top-level Agents and sub-agent facets */;
|
|
79
|
-
__agentOrigin?: AgentWorkflowOrigin;
|
|
80
|
-
};
|
|
81
|
-
/**
|
|
82
|
-
* Combined workflow params: user params + internal agent params
|
|
83
|
-
*/
|
|
84
|
-
type AgentWorkflowParams<T = unknown> = T & AgentWorkflowInternalParams;
|
|
85
|
-
/**
|
|
86
|
-
* Workflow callback types for Agent-Workflow communication
|
|
87
|
-
*/
|
|
88
|
-
type WorkflowCallbackType = "progress" | "complete" | "error" | "event";
|
|
89
|
-
/**
|
|
90
|
-
* Base callback structure sent from Workflow to Agent
|
|
91
|
-
*/
|
|
92
|
-
type WorkflowCallbackBase = {
|
|
93
|
-
/** Workflow binding name */ workflowName: string /** ID of the workflow instance */;
|
|
94
|
-
workflowId: string /** Type of callback */;
|
|
95
|
-
type: WorkflowCallbackType /** Timestamp when callback was sent */;
|
|
96
|
-
timestamp: number;
|
|
97
|
-
};
|
|
98
|
-
/**
|
|
99
|
-
* Default progress type - covers common use cases.
|
|
100
|
-
* Developers can define their own progress type for domain-specific needs.
|
|
101
|
-
*/
|
|
102
|
-
type DefaultProgress = {
|
|
103
|
-
/** Current step name */ step?: string /** Step/overall status */;
|
|
104
|
-
status?:
|
|
105
|
-
| "pending"
|
|
106
|
-
| "running"
|
|
107
|
-
| "complete"
|
|
108
|
-
| "error" /** Human-readable message */;
|
|
109
|
-
message?: string /** Progress percentage (0-1) */;
|
|
110
|
-
percent?: number /** Allow additional custom fields */;
|
|
111
|
-
[key: string]: unknown;
|
|
112
|
-
};
|
|
113
|
-
/**
|
|
114
|
-
* Progress callback - reports workflow progress with typed payload
|
|
115
|
-
*/
|
|
116
|
-
type WorkflowProgressCallback<P = DefaultProgress> = WorkflowCallbackBase & {
|
|
117
|
-
type: "progress" /** Typed progress data */;
|
|
118
|
-
progress: P;
|
|
119
|
-
};
|
|
120
|
-
/**
|
|
121
|
-
* Complete callback - workflow finished successfully
|
|
122
|
-
*/
|
|
123
|
-
type WorkflowCompleteCallback = WorkflowCallbackBase & {
|
|
124
|
-
type: "complete" /** Result of the workflow */;
|
|
125
|
-
result?: unknown;
|
|
126
|
-
};
|
|
127
|
-
/**
|
|
128
|
-
* Error callback - workflow encountered an error
|
|
129
|
-
*/
|
|
130
|
-
type WorkflowErrorCallback = WorkflowCallbackBase & {
|
|
131
|
-
type: "error" /** Error message */;
|
|
132
|
-
error: string;
|
|
133
|
-
};
|
|
134
|
-
/**
|
|
135
|
-
* Event callback - custom event from workflow
|
|
136
|
-
*/
|
|
137
|
-
type WorkflowEventCallback = WorkflowCallbackBase & {
|
|
138
|
-
type: "event" /** Custom event payload */;
|
|
139
|
-
event: unknown;
|
|
140
|
-
};
|
|
141
|
-
/**
|
|
142
|
-
* Union of all callback types
|
|
143
|
-
*/
|
|
144
|
-
type WorkflowCallback<P = DefaultProgress> =
|
|
145
|
-
| WorkflowProgressCallback<P>
|
|
146
|
-
| WorkflowCompleteCallback
|
|
147
|
-
| WorkflowErrorCallback
|
|
148
|
-
| WorkflowEventCallback;
|
|
149
|
-
/**
|
|
150
|
-
* Workflow status values - derived from Cloudflare's InstanceStatus
|
|
151
|
-
*/
|
|
152
|
-
type WorkflowStatus = InstanceStatus["status"];
|
|
153
|
-
/**
|
|
154
|
-
* Row structure for cf_agents_workflows tracking table
|
|
155
|
-
*/
|
|
156
|
-
type WorkflowTrackingRow = {
|
|
157
|
-
/** Internal row ID (UUID) */ id: string /** Cloudflare Workflow instance ID */;
|
|
158
|
-
workflow_id: string /** Workflow binding name */;
|
|
159
|
-
workflow_name: string /** Current workflow status */;
|
|
160
|
-
status: WorkflowStatus /** JSON-serialized metadata for querying */;
|
|
161
|
-
metadata: string | null /** Error name if workflow failed */;
|
|
162
|
-
error_name: string | null /** Error message if workflow failed */;
|
|
163
|
-
error_message: string | null /** Unix timestamp when workflow was created */;
|
|
164
|
-
created_at: number /** Unix timestamp when workflow was last updated */;
|
|
165
|
-
updated_at: number /** Unix timestamp when workflow completed (null if not complete) */;
|
|
166
|
-
completed_at: number | null;
|
|
167
|
-
};
|
|
168
|
-
/**
|
|
169
|
-
* Options for runWorkflow()
|
|
170
|
-
*/
|
|
171
|
-
type RunWorkflowOptions = {
|
|
172
|
-
/** Custom workflow instance ID (auto-generated if not provided) */ id?: string /** Optional metadata for querying (stored as JSON) */;
|
|
173
|
-
metadata?: Record<
|
|
174
|
-
string,
|
|
175
|
-
unknown
|
|
176
|
-
> /** Agent binding name (auto-detected from class name if not provided) */;
|
|
177
|
-
agentBinding?: string;
|
|
178
|
-
};
|
|
179
|
-
/**
|
|
180
|
-
* Event payload for sendWorkflowEvent()
|
|
181
|
-
*/
|
|
182
|
-
type WorkflowEventPayload = {
|
|
183
|
-
/** Event type name */ type: string /** Event payload data */;
|
|
184
|
-
payload: unknown;
|
|
185
|
-
};
|
|
186
|
-
/**
|
|
187
|
-
* Parsed workflow tracking info returned by getWorkflow()
|
|
188
|
-
*/
|
|
189
|
-
type WorkflowInfo = {
|
|
190
|
-
/** Internal row ID */ id: string /** Cloudflare Workflow instance ID */;
|
|
191
|
-
workflowId: string /** Workflow binding name */;
|
|
192
|
-
workflowName: string /** Current workflow status */;
|
|
193
|
-
status: WorkflowStatus /** Metadata (parsed from JSON) */;
|
|
194
|
-
metadata: Record<string, unknown> | null /** Error info if workflow failed */;
|
|
195
|
-
error: {
|
|
196
|
-
name: string;
|
|
197
|
-
message: string;
|
|
198
|
-
} | null /** When workflow was created */;
|
|
199
|
-
createdAt: Date /** When workflow was last updated */;
|
|
200
|
-
updatedAt: Date /** When workflow completed (null if not complete) */;
|
|
201
|
-
completedAt: Date | null;
|
|
202
|
-
};
|
|
203
|
-
/**
|
|
204
|
-
* Criteria for querying tracked workflows
|
|
205
|
-
*/
|
|
206
|
-
type WorkflowQueryCriteria = {
|
|
207
|
-
/** Filter by status */ status?:
|
|
208
|
-
| WorkflowStatus
|
|
209
|
-
| WorkflowStatus[] /** Filter by workflow binding name */;
|
|
210
|
-
workflowName?: string /** Filter by metadata key-value pairs (exact match) */;
|
|
211
|
-
metadata?: Record<
|
|
212
|
-
string,
|
|
213
|
-
string | number | boolean
|
|
214
|
-
> /** Limit number of results (default 50, max 100) */;
|
|
215
|
-
limit?: number /** Order by created_at */;
|
|
216
|
-
orderBy?:
|
|
217
|
-
| "asc"
|
|
218
|
-
| "desc" /** Cursor for pagination (from previous WorkflowPage.nextCursor) */;
|
|
219
|
-
cursor?: string;
|
|
220
|
-
};
|
|
221
|
-
/**
|
|
222
|
-
* Paginated result from getWorkflows()
|
|
223
|
-
*/
|
|
224
|
-
type WorkflowPage = {
|
|
225
|
-
/** Workflows for this page */ workflows: WorkflowInfo[] /** Total count of workflows matching the criteria (ignoring pagination) */;
|
|
226
|
-
total: number /** Cursor for next page, or null if no more pages */;
|
|
227
|
-
nextCursor: string | null;
|
|
228
|
-
};
|
|
229
|
-
/**
|
|
230
|
-
* Standard approval event payload used by approveWorkflow/rejectWorkflow
|
|
231
|
-
*/
|
|
232
|
-
type ApprovalEventPayload = {
|
|
233
|
-
/** Whether the workflow was approved */ approved: boolean /** Optional reason for approval/rejection */;
|
|
234
|
-
reason?: string /** Optional additional metadata */;
|
|
235
|
-
metadata?: Record<string, unknown>;
|
|
236
|
-
};
|
|
237
|
-
/**
|
|
238
|
-
* Options for waitForApproval()
|
|
239
|
-
*/
|
|
240
|
-
type WaitForApprovalOptions = {
|
|
241
|
-
/** Step name for waitForEvent (default: "wait-for-approval") */ stepName?: string /** Timeout duration (e.g., "7 days") */;
|
|
242
|
-
timeout?: WorkflowSleepDuration /** Event type to wait for (default: "approval") */;
|
|
243
|
-
eventType?: string;
|
|
244
|
-
};
|
|
245
|
-
/**
|
|
246
|
-
* Error thrown when a workflow is rejected via rejectWorkflow()
|
|
247
|
-
*/
|
|
248
|
-
declare class WorkflowRejectedError extends Error {
|
|
249
|
-
readonly reason?: string | undefined;
|
|
250
|
-
readonly workflowId?: string | undefined;
|
|
251
|
-
constructor(reason?: string | undefined, workflowId?: string | undefined);
|
|
252
|
-
}
|
|
253
|
-
//#endregion
|
|
254
|
-
export {
|
|
255
|
-
WorkflowStatus as C,
|
|
256
|
-
WorkflowRejectedError as S,
|
|
257
|
-
WorkflowEventPayload as _,
|
|
258
|
-
AgentWorkflowPathStep as a,
|
|
259
|
-
WorkflowProgressCallback as b,
|
|
260
|
-
DefaultProgress as c,
|
|
261
|
-
WorkflowCallback as d,
|
|
262
|
-
WorkflowCallbackBase as f,
|
|
263
|
-
WorkflowEventCallback as g,
|
|
264
|
-
WorkflowErrorCallback as h,
|
|
265
|
-
AgentWorkflowParams as i,
|
|
266
|
-
RunWorkflowOptions as l,
|
|
267
|
-
WorkflowCompleteCallback as m,
|
|
268
|
-
AgentWorkflowInternalParams as n,
|
|
269
|
-
AgentWorkflowStep as o,
|
|
270
|
-
WorkflowCallbackType as p,
|
|
271
|
-
AgentWorkflowOrigin as r,
|
|
272
|
-
ApprovalEventPayload as s,
|
|
273
|
-
AgentWorkflowEvent as t,
|
|
274
|
-
WaitForApprovalOptions as u,
|
|
275
|
-
WorkflowInfo as v,
|
|
276
|
-
WorkflowTrackingRow as w,
|
|
277
|
-
WorkflowQueryCriteria as x,
|
|
278
|
-
WorkflowPage as y
|
|
279
|
-
};
|
|
280
|
-
//# sourceMappingURL=workflow-types-Baz_PO5v.d.ts.map
|