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
|
@@ -457,7 +457,7 @@ Pre-aborted signals short-circuit before any model work runs.
|
|
|
457
457
|
### Limitations
|
|
458
458
|
|
|
459
459
|
- **Signals cannot cross Durable Object boundaries.** `AbortSignal` is not an RPC-serializable type. Construct the controller inside the DO that calls `saveMessages`. For Think child-agent orchestration, use [Agent Tools](./agent-tools.md); `runAgentTool()` bridges parent aborts into the child run. For lower-level custom RPC, return a `ReadableStream` from the child and let the parent cancel it — workerd propagates the cancel back to the source's `cancel` callback.
|
|
460
|
-
- **Hibernation drops the listener.** The signal lives in memory.
|
|
460
|
+
- **Hibernation drops the listener.** The signal lives in memory. After the DO restarts, durable recovery usually calls `continueLastTurn()` without the original signal, so an abort fired after restart has no effect. For pre-stream interruptions, recovery can instead retry the latest unanswered user message automatically. This is true for top-level agents and sub-agents. If cancellation must survive restart, persist the cancellation intent in agent state or SQL, check it in `onChatRecovery()`, and return `{ continue: false }`. Durable recovery cannot be disabled.
|
|
461
461
|
|
|
462
462
|
This is the integration point for agent-tool orchestration where the parent's AI SDK abort signal needs to propagate into a child DO's `saveMessages` call. See [`cloudflare/agents#1406`](https://github.com/cloudflare/agents/issues/1406) for the original use case.
|
|
463
463
|
|
package/docs/sub-agents.md
CHANGED
|
@@ -273,7 +273,52 @@ const chat = useAgent({
|
|
|
273
273
|
|
|
274
274
|
Every other `useAgent` feature works as usual: `state` sync, `stub.method()` calls, `@callable` RPCs, `useAgentChat` on top of the returned socket.
|
|
275
275
|
|
|
276
|
-
### Direct HTTP
|
|
276
|
+
### Direct HTTP and WebSocket URLs
|
|
277
|
+
|
|
278
|
+
Use `buildAgentPath()` to turn a root-first Agent identity into the canonical URL pathname used by both HTTP requests and WebSocket connections:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
import { buildAgentPath } from "agents";
|
|
282
|
+
|
|
283
|
+
const path = buildAgentPath(
|
|
284
|
+
[
|
|
285
|
+
{ className: "Inbox", name: userId },
|
|
286
|
+
{ className: "Chat", name: chatId }
|
|
287
|
+
],
|
|
288
|
+
{ leafPath: "/callbacks/job" }
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
// /agents/inbox/{userId}/sub/chat/{chatId}/callbacks/job
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Inside an Agent, pass `this.selfPath` directly. If the root Durable Object binding name differs from its class name, also pass `rootBinding` in the options. `buildAgentUrl()` adds a public origin, which is useful when registering callbacks, webhooks, approval URLs, or asynchronous job-completion URLs with an external system:
|
|
295
|
+
|
|
296
|
+
```typescript
|
|
297
|
+
import { buildAgentUrl } from "agents";
|
|
298
|
+
|
|
299
|
+
export class Chat extends Agent<Env> {
|
|
300
|
+
callbackUrl() {
|
|
301
|
+
return buildAgentUrl(this.env.PUBLIC_ORIGIN, this.selfPath, {
|
|
302
|
+
leafPath: "/callbacks/job"
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
override async onRequest(request: Request) {
|
|
307
|
+
if (new URL(request.url).pathname === "/callbacks/job") {
|
|
308
|
+
return this.handleJobCallback(request);
|
|
309
|
+
}
|
|
310
|
+
return new Response("Not found", { status: 404 });
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
The Worker must pass the incoming request to `routeAgentRequest()`. Each ancestor's `onBeforeSubAgent` hook runs before the destination receives the request. For a sub-agent destination, the nested `/sub/...` routing segments are removed during forwarding, so its pathname is the `leafPath` suffix.
|
|
316
|
+
|
|
317
|
+
`buildAgentUrl()` accepts an HTTP(S) or WS(S) origin without a pathname, query, fragment, or credentials. Set callback query parameters through the returned URL's `searchParams`. If you use a custom routing prefix, pass the same value to both `buildAgentPath()` and `routeAgentRequest()`.
|
|
318
|
+
|
|
319
|
+
Root Agent names follow `routeAgentRequest`'s raw pathname-segment behavior and must already be externally routable. The `sub` segment is reserved in routing prefixes, class and binding names, and root Agent names. Descendant names are URL-encoded by the helper, so names containing spaces, Unicode, `/`, or URL-reserved characters round-trip safely.
|
|
320
|
+
|
|
321
|
+
### Custom routing
|
|
277
322
|
|
|
278
323
|
For fetch handlers that do their own top-level URL parsing, use `routeSubAgentRequest` to dispatch a request into a sub-agent from an already-resolved parent stub:
|
|
279
324
|
|
|
@@ -293,7 +338,7 @@ export default {
|
|
|
293
338
|
};
|
|
294
339
|
```
|
|
295
340
|
|
|
296
|
-
`fromPath` takes the sub-agent tail (something like `/sub/chat/chat-abc/...`). The helper parses
|
|
341
|
+
`fromPath` takes any pathname containing the sub-agent tail (something like `/sub/chat/chat-abc/...`). When the destination is already represented as a root-first Agent path, pass the result of `buildAgentPath()` directly. The helper parses the first child hop, runs the parent's `onBeforeSubAgent` hook, and forwards into the facet.
|
|
297
342
|
|
|
298
343
|
### External typed RPC
|
|
299
344
|
|
package/docs/webhooks.md
CHANGED
|
@@ -7,56 +7,54 @@ Receive webhook events from external services and route them to dedicated agent
|
|
|
7
7
|
```typescript
|
|
8
8
|
import { Agent, getAgentByName, routeAgentRequest } from "agents";
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
type GitHubWebhookPayload = {
|
|
11
|
+
repository?: { full_name?: string };
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
async function verifyGitHubWebhook(
|
|
15
|
+
rawBody: string,
|
|
16
|
+
signature: string | null,
|
|
17
|
+
secret: string
|
|
18
|
+
): Promise<boolean> {
|
|
19
|
+
if (!signature || !/^sha256=[0-9a-f]{64}$/i.test(signature)) return false;
|
|
20
|
+
|
|
21
|
+
const encoder = new TextEncoder();
|
|
22
|
+
const key = await crypto.subtle.importKey(
|
|
23
|
+
"raw",
|
|
24
|
+
encoder.encode(secret),
|
|
25
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
26
|
+
false,
|
|
27
|
+
["verify"]
|
|
28
|
+
);
|
|
29
|
+
const signatureBytes = Uint8Array.from(
|
|
30
|
+
signature.slice("sha256=".length).match(/.{2}/g) ?? [],
|
|
31
|
+
(byte) => Number.parseInt(byte, 16)
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
return crypto.subtle.verify(
|
|
35
|
+
"HMAC",
|
|
36
|
+
key,
|
|
37
|
+
signatureBytes,
|
|
38
|
+
encoder.encode(rawBody)
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
11
42
|
export class WebhookAgent extends Agent<Env> {
|
|
12
43
|
async onRequest(request: Request): Promise<Response> {
|
|
13
44
|
if (request.method !== "POST") {
|
|
14
45
|
return new Response("Method not allowed", { status: 405 });
|
|
15
46
|
}
|
|
16
47
|
|
|
17
|
-
|
|
48
|
+
const rawBody = await request.text();
|
|
18
49
|
const signature = request.headers.get("X-Hub-Signature-256");
|
|
19
|
-
const body = await request.text();
|
|
20
|
-
|
|
21
50
|
if (
|
|
22
|
-
!(await
|
|
51
|
+
!(await verifyGitHubWebhook(rawBody, signature, this.env.WEBHOOK_SECRET))
|
|
23
52
|
) {
|
|
24
53
|
return new Response("Invalid signature", { status: 401 });
|
|
25
54
|
}
|
|
26
55
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
await this.processEvent(payload);
|
|
30
|
-
|
|
31
|
-
return new Response("OK", { status: 200 });
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
private async verifySignature(
|
|
35
|
-
payload: string,
|
|
36
|
-
signature: string | null,
|
|
37
|
-
secret: string
|
|
38
|
-
): Promise<boolean> {
|
|
39
|
-
if (!signature) return false;
|
|
40
|
-
|
|
41
|
-
const encoder = new TextEncoder();
|
|
42
|
-
const key = await crypto.subtle.importKey(
|
|
43
|
-
"raw",
|
|
44
|
-
encoder.encode(secret),
|
|
45
|
-
{ name: "HMAC", hash: "SHA-256" },
|
|
46
|
-
false,
|
|
47
|
-
["sign"]
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
const signatureBytes = await crypto.subtle.sign(
|
|
51
|
-
"HMAC",
|
|
52
|
-
key,
|
|
53
|
-
encoder.encode(payload)
|
|
54
|
-
);
|
|
55
|
-
const expected = `sha256=${Array.from(new Uint8Array(signatureBytes))
|
|
56
|
-
.map((b) => b.toString(16).padStart(2, "0"))
|
|
57
|
-
.join("")}`;
|
|
58
|
-
|
|
59
|
-
return signature === expected;
|
|
56
|
+
await this.processEvent(JSON.parse(rawBody));
|
|
57
|
+
return new Response("OK");
|
|
60
58
|
}
|
|
61
59
|
|
|
62
60
|
private async processEvent(payload: unknown) {
|
|
@@ -64,19 +62,30 @@ export class WebhookAgent extends Agent<Env> {
|
|
|
64
62
|
}
|
|
65
63
|
}
|
|
66
64
|
|
|
67
|
-
// Route webhooks to the right agent instance
|
|
68
65
|
export default {
|
|
69
66
|
async fetch(request: Request, env: Env): Promise<Response> {
|
|
70
67
|
const url = new URL(request.url);
|
|
71
68
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
|
|
69
|
+
if (url.pathname === "/webhooks/github" && request.method === "POST") {
|
|
70
|
+
const rawBody = await request.clone().text();
|
|
71
|
+
const signature = request.headers.get("X-Hub-Signature-256");
|
|
72
|
+
if (
|
|
73
|
+
!(await verifyGitHubWebhook(rawBody, signature, env.WEBHOOK_SECRET))
|
|
74
|
+
) {
|
|
75
|
+
return new Response("Invalid signature", { status: 401 });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const payload = JSON.parse(rawBody) as GitHubWebhookPayload;
|
|
79
|
+
const repository = payload.repository?.full_name;
|
|
80
|
+
if (!repository) {
|
|
81
|
+
return new Response("Missing repository", { status: 400 });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const agentName = repository.toLowerCase().replace(/\//g, "-");
|
|
85
|
+
const agent = await getAgentByName(env.WebhookAgent, agentName);
|
|
76
86
|
return agent.fetch(request);
|
|
77
87
|
}
|
|
78
88
|
|
|
79
|
-
// Default routing for WebSocket connections
|
|
80
89
|
return (
|
|
81
90
|
(await routeAgentRequest(request, env)) ||
|
|
82
91
|
new Response("Not found", { status: 404 })
|
|
@@ -131,7 +140,7 @@ Webhooks combined with agents enable powerful patterns where each external entit
|
|
|
131
140
|
|
|
132
141
|
## Routing Webhooks to Agents
|
|
133
142
|
|
|
134
|
-
The key pattern is
|
|
143
|
+
The key pattern is verifying the raw request before parsing it, then deriving the Agent identity from authenticated payload data. A body signature does not authenticate an unrelated URL segment or arbitrary header.
|
|
135
144
|
|
|
136
145
|
### Extract Entity from Payload
|
|
137
146
|
|
|
@@ -140,19 +149,23 @@ Most webhooks include an identifier in the payload:
|
|
|
140
149
|
```typescript
|
|
141
150
|
export default {
|
|
142
151
|
async fetch(request: Request, env: Env): Promise<Response> {
|
|
152
|
+
const url = new URL(request.url);
|
|
143
153
|
if (request.method === "POST" && url.pathname === "/webhooks/github") {
|
|
144
|
-
const
|
|
154
|
+
const rawBody = await request.clone().text();
|
|
155
|
+
const signature = request.headers.get("X-Hub-Signature-256");
|
|
156
|
+
if (
|
|
157
|
+
!(await verifyGitHubWebhook(rawBody, signature, env.WEBHOOK_SECRET))
|
|
158
|
+
) {
|
|
159
|
+
return new Response("Invalid signature", { status: 401 });
|
|
160
|
+
}
|
|
145
161
|
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
if (!
|
|
162
|
+
const payload = JSON.parse(rawBody) as GitHubWebhookPayload;
|
|
163
|
+
const repository = payload.repository?.full_name;
|
|
164
|
+
if (!repository) {
|
|
149
165
|
return new Response("Missing repository", { status: 400 });
|
|
150
166
|
}
|
|
151
167
|
|
|
152
|
-
|
|
153
|
-
const agentName = repoFullName.toLowerCase().replace(/\//g, "-");
|
|
154
|
-
|
|
155
|
-
// Route to dedicated agent
|
|
168
|
+
const agentName = repository.toLowerCase().replace(/\//g, "-");
|
|
156
169
|
const agent = await getAgentByName(env.RepoAgent, agentName);
|
|
157
170
|
return agent.fetch(request);
|
|
158
171
|
}
|
|
@@ -160,69 +173,21 @@ export default {
|
|
|
160
173
|
};
|
|
161
174
|
```
|
|
162
175
|
|
|
163
|
-
###
|
|
164
|
-
|
|
165
|
-
Alternatively, include the entity ID in the webhook URL:
|
|
166
|
-
|
|
167
|
-
```typescript
|
|
168
|
-
// Webhook URL: https://your-worker.dev/webhooks/stripe/cus_123456
|
|
169
|
-
if (url.pathname.startsWith("/webhooks/stripe/")) {
|
|
170
|
-
const customerId = url.pathname.split("/")[3]; // "cus_123456"
|
|
171
|
-
const agent = await getAgentByName(env.StripeAgent, customerId);
|
|
172
|
-
return agent.fetch(request);
|
|
173
|
-
}
|
|
174
|
-
```
|
|
176
|
+
### Validate Entity IDs in URLs
|
|
175
177
|
|
|
176
|
-
|
|
178
|
+
A provider's body signature does not authenticate the webhook URL. If the URL includes an entity ID, compare it with the corresponding identity from the verified provider payload and reject a mismatch before calling `getAgentByName()`.
|
|
177
179
|
|
|
178
|
-
|
|
180
|
+
### Derive Slack Identity from the Verified Body
|
|
179
181
|
|
|
180
|
-
|
|
181
|
-
// Slack sends workspace info in headers
|
|
182
|
-
const teamId = request.headers.get("X-Slack-Team-Id");
|
|
183
|
-
if (teamId) {
|
|
184
|
-
const agent = await getAgentByName(env.SlackAgent, teamId);
|
|
185
|
-
return agent.fetch(request);
|
|
186
|
-
}
|
|
187
|
-
```
|
|
182
|
+
Slack does not send an authenticated `X-Slack-Team-Id` routing header. Validate Slack's timestamped signature and replay window against the raw body, then read `team_id` from the verified event or form body.
|
|
188
183
|
|
|
189
184
|
## Signature Verification
|
|
190
185
|
|
|
191
|
-
Always verify webhook signatures
|
|
186
|
+
Always verify webhook signatures before trusting or processing the payload.
|
|
192
187
|
|
|
193
|
-
### HMAC-SHA256 Pattern
|
|
188
|
+
### GitHub HMAC-SHA256 Pattern
|
|
194
189
|
|
|
195
|
-
|
|
196
|
-
async function verifySignature(
|
|
197
|
-
payload: string,
|
|
198
|
-
signature: string | null,
|
|
199
|
-
secret: string
|
|
200
|
-
): Promise<boolean> {
|
|
201
|
-
if (!signature) return false;
|
|
202
|
-
|
|
203
|
-
const encoder = new TextEncoder();
|
|
204
|
-
const key = await crypto.subtle.importKey(
|
|
205
|
-
"raw",
|
|
206
|
-
encoder.encode(secret),
|
|
207
|
-
{ name: "HMAC", hash: "SHA-256" },
|
|
208
|
-
false,
|
|
209
|
-
["sign"]
|
|
210
|
-
);
|
|
211
|
-
|
|
212
|
-
const signatureBytes = await crypto.subtle.sign(
|
|
213
|
-
"HMAC",
|
|
214
|
-
key,
|
|
215
|
-
encoder.encode(payload)
|
|
216
|
-
);
|
|
217
|
-
|
|
218
|
-
const expected = `sha256=${Array.from(new Uint8Array(signatureBytes))
|
|
219
|
-
.map((b) => b.toString(16).padStart(2, "0"))
|
|
220
|
-
.join("")}`;
|
|
221
|
-
|
|
222
|
-
// Use timing-safe comparison in production
|
|
223
|
-
return signature === expected;
|
|
224
|
-
}
|
|
225
|
-
```
|
|
190
|
+
The Quick Start's `verifyGitHubWebhook()` helper verifies GitHub's `sha256=<hex>` signature over the raw body with `crypto.subtle.verify()`. This format is GitHub-specific. Other providers use different signature encodings, signed inputs, timestamp checks, and replay protections; follow the provider documentation linked under [Common Webhook Providers](#common-webhook-providers).
|
|
226
191
|
|
|
227
192
|
### Provider-Specific Headers
|
|
228
193
|
|
|
@@ -238,7 +203,7 @@ async function verifySignature(
|
|
|
238
203
|
|
|
239
204
|
### The onRequest Handler
|
|
240
205
|
|
|
241
|
-
Use `onRequest()` to handle incoming webhooks in your agent:
|
|
206
|
+
Use `onRequest()` to handle incoming webhooks in your agent. If the Worker has not already verified the request, verify it before parsing the body. This example reuses the Quick Start's `verifyGitHubWebhook()` helper:
|
|
242
207
|
|
|
243
208
|
```typescript
|
|
244
209
|
export class WebhookAgent extends Agent<Env, MyState> {
|
|
@@ -248,14 +213,16 @@ export class WebhookAgent extends Agent<Env, MyState> {
|
|
|
248
213
|
return new Response("Method not allowed", { status: 405 });
|
|
249
214
|
}
|
|
250
215
|
|
|
251
|
-
// 2. Get event type
|
|
252
|
-
const eventType = request.headers.get("X-Event
|
|
216
|
+
// 2. Get the GitHub event type
|
|
217
|
+
const eventType = request.headers.get("X-GitHub-Event") ?? "unknown";
|
|
253
218
|
|
|
254
|
-
// 3. Verify signature
|
|
255
|
-
const signature = request.headers.get("X-Signature");
|
|
219
|
+
// 3. Verify the GitHub signature
|
|
220
|
+
const signature = request.headers.get("X-Hub-Signature-256");
|
|
256
221
|
const body = await request.text();
|
|
257
222
|
|
|
258
|
-
if (
|
|
223
|
+
if (
|
|
224
|
+
!(await verifyGitHubWebhook(body, signature, this.env.WEBHOOK_SECRET))
|
|
225
|
+
) {
|
|
259
226
|
return new Response("Invalid signature", { status: 401 });
|
|
260
227
|
}
|
|
261
228
|
|
|
@@ -462,35 +429,41 @@ fibers retain status, dedupe provider retries, and let `onFiberRecovered()` or
|
|
|
462
429
|
|
|
463
430
|
### Multi-Provider Routing
|
|
464
431
|
|
|
465
|
-
|
|
432
|
+
Keep provider-specific verification and parsing behind one typed seam. Its implementation must validate the raw request according to the provider documentation linked under [Common Webhook Providers](#common-webhook-providers), then derive `agentName` only from the verified body.
|
|
466
433
|
|
|
467
434
|
```typescript
|
|
435
|
+
type VerifiedWebhook =
|
|
436
|
+
| { provider: "github"; agentName: string }
|
|
437
|
+
| { provider: "stripe"; agentName: string }
|
|
438
|
+
| { provider: "slack"; agentName: string };
|
|
439
|
+
|
|
440
|
+
declare function verifyAndParseWebhook(
|
|
441
|
+
request: Request,
|
|
442
|
+
env: Env
|
|
443
|
+
): Promise<VerifiedWebhook | null>;
|
|
444
|
+
|
|
468
445
|
export default {
|
|
469
446
|
async fetch(request: Request, env: Env): Promise<Response> {
|
|
470
447
|
const url = new URL(request.url);
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
const payload = await request.clone().json();
|
|
476
|
-
const repoName = payload.repository?.full_name?.replace("/", "-");
|
|
477
|
-
const agent = await getAgentByName(env.GitHubAgent, repoName);
|
|
478
|
-
return agent.fetch(request);
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
// Stripe webhooks
|
|
482
|
-
if (url.pathname.startsWith("/webhooks/stripe/")) {
|
|
483
|
-
const payload = await request.clone().json();
|
|
484
|
-
const customerId = payload.data?.object?.customer;
|
|
485
|
-
const agent = await getAgentByName(env.StripeAgent, customerId);
|
|
486
|
-
return agent.fetch(request);
|
|
448
|
+
if (request.method === "POST" && url.pathname.startsWith("/webhooks/")) {
|
|
449
|
+
const verified = await verifyAndParseWebhook(request.clone(), env);
|
|
450
|
+
if (!verified) {
|
|
451
|
+
return new Response("Invalid signature", { status: 401 });
|
|
487
452
|
}
|
|
488
453
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
454
|
+
switch (verified.provider) {
|
|
455
|
+
case "github":
|
|
456
|
+
return (
|
|
457
|
+
await getAgentByName(env.GitHubAgent, verified.agentName)
|
|
458
|
+
).fetch(request);
|
|
459
|
+
case "stripe":
|
|
460
|
+
return (
|
|
461
|
+
await getAgentByName(env.StripeAgent, verified.agentName)
|
|
462
|
+
).fetch(request);
|
|
463
|
+
case "slack":
|
|
464
|
+
return (
|
|
465
|
+
await getAgentByName(env.SlackAgent, verified.agentName)
|
|
466
|
+
).fetch(request);
|
|
494
467
|
}
|
|
495
468
|
}
|
|
496
469
|
|
package/docs/workflows.md
CHANGED
|
@@ -246,7 +246,11 @@ const instanceId = await this.runWorkflow(
|
|
|
246
246
|
{
|
|
247
247
|
id: "custom-id", // optional - auto-generated if not provided
|
|
248
248
|
metadata: { userId: "user-456", priority: "high" }, // optional - for querying
|
|
249
|
-
agentBinding: "MyAgent" // optional - auto-detected from class name if not provided
|
|
249
|
+
agentBinding: "MyAgent", // optional - auto-detected from class name if not provided
|
|
250
|
+
retention: {
|
|
251
|
+
successRetention: "1 day",
|
|
252
|
+
errorRetention: "7 days"
|
|
253
|
+
}
|
|
250
254
|
}
|
|
251
255
|
);
|
|
252
256
|
```
|
|
@@ -258,6 +262,10 @@ const instanceId = await this.runWorkflow(
|
|
|
258
262
|
- `options.id` - Custom workflow ID (auto-generated if not provided)
|
|
259
263
|
- `options.metadata` - Optional metadata stored for querying (not passed to workflow)
|
|
260
264
|
- `options.agentBinding` - Agent binding name (auto-detected from class name if not provided). When called from a sub-agent, this is the root Agent binding name.
|
|
265
|
+
- [`options.retention`](https://developers.cloudflare.com/workflows/build/workers-api/#workflowinstancecreateoptions) - Workflow retention passed unchanged to
|
|
266
|
+
`Workflow.create()`.
|
|
267
|
+
Use `successRetention` for successful instances and `errorRetention` for
|
|
268
|
+
errored or terminated instances.
|
|
261
269
|
|
|
262
270
|
**Returns:** Workflow instance ID
|
|
263
271
|
|
package/package.json
CHANGED
|
@@ -9,16 +9,13 @@
|
|
|
9
9
|
"durable objects"
|
|
10
10
|
],
|
|
11
11
|
"type": "module",
|
|
12
|
-
"version": "0.
|
|
12
|
+
"version": "0.22.0",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"repository": {
|
|
15
15
|
"directory": "packages/agents",
|
|
16
16
|
"type": "git",
|
|
17
17
|
"url": "git+https://github.com/cloudflare/agents.git"
|
|
18
18
|
},
|
|
19
|
-
"bin": {
|
|
20
|
-
"agents": "dist/cli/index.js"
|
|
21
|
-
},
|
|
22
19
|
"author": "Cloudflare Inc.",
|
|
23
20
|
"bugs": {
|
|
24
21
|
"url": "https://github.com/cloudflare/agents/issues"
|
|
@@ -31,13 +28,12 @@
|
|
|
31
28
|
"esbuild": "^0.28.1",
|
|
32
29
|
"mimetext": "^3.0.28",
|
|
33
30
|
"nanoid": "^5.1.16",
|
|
34
|
-
"partyserver": "^0.5.8",
|
|
35
31
|
"partysocket": "1.3.0",
|
|
36
|
-
"yaml": "^2.9.0"
|
|
37
|
-
"yargs": "^18.0.0"
|
|
32
|
+
"yaml": "^2.9.0"
|
|
38
33
|
},
|
|
39
34
|
"devDependencies": {
|
|
40
35
|
"@ai-sdk/react": "^4.0.0",
|
|
36
|
+
"@ai-sdk/valibot": "3.0.6",
|
|
41
37
|
"@cloudflare/codemode": "^0.5.1",
|
|
42
38
|
"@modelcontextprotocol/client": "2.0.0",
|
|
43
39
|
"@modelcontextprotocol/conformance-v2": "npm:@modelcontextprotocol/conformance@0.2.0-alpha.10",
|
|
@@ -45,8 +41,7 @@
|
|
|
45
41
|
"@modelcontextprotocol/server": "2.0.0",
|
|
46
42
|
"@tanstack/ai": "0.38.0",
|
|
47
43
|
"@types/react": "^19.2.17",
|
|
48
|
-
"@
|
|
49
|
-
"@vitest/browser-playwright": "^4.1.9",
|
|
44
|
+
"@valibot/to-json-schema": "1.3.0",
|
|
50
45
|
"@x402/core": "^2.17.0",
|
|
51
46
|
"@x402/evm": "^2.17.0",
|
|
52
47
|
"ai": "^7.0.0",
|
|
@@ -54,7 +49,7 @@
|
|
|
54
49
|
"glob": "^13.0.6",
|
|
55
50
|
"just-bash": "^3.0.2",
|
|
56
51
|
"react": "^19.2.7",
|
|
57
|
-
"
|
|
52
|
+
"valibot": "1.4.1",
|
|
58
53
|
"zod": "^4.4.3"
|
|
59
54
|
},
|
|
60
55
|
"peerDependencies": {
|
|
@@ -98,6 +93,9 @@
|
|
|
98
93
|
"just-bash": {
|
|
99
94
|
"optional": true
|
|
100
95
|
},
|
|
96
|
+
"react": {
|
|
97
|
+
"optional": true
|
|
98
|
+
},
|
|
101
99
|
"vite": {
|
|
102
100
|
"optional": true
|
|
103
101
|
}
|
|
@@ -119,6 +117,11 @@
|
|
|
119
117
|
"import": "./dist/client.js",
|
|
120
118
|
"require": "./dist/client.js"
|
|
121
119
|
},
|
|
120
|
+
"./lifecycle": {
|
|
121
|
+
"types": "./dist/lifecycle/index.d.ts",
|
|
122
|
+
"import": "./dist/lifecycle/index.js",
|
|
123
|
+
"require": "./dist/lifecycle/index.js"
|
|
124
|
+
},
|
|
122
125
|
"./agent-tools": {
|
|
123
126
|
"types": "./dist/agent-tools.d.ts",
|
|
124
127
|
"import": "./dist/agent-tools.js",
|
|
@@ -135,19 +138,19 @@
|
|
|
135
138
|
"require": "./dist/mcp/index.js"
|
|
136
139
|
},
|
|
137
140
|
"./mcp/client": {
|
|
138
|
-
"types": "./dist/mcp/client.d.ts",
|
|
139
|
-
"import": "./dist/mcp/client.js",
|
|
140
|
-
"require": "./dist/mcp/client.js"
|
|
141
|
+
"types": "./dist/mcp/client/index.d.ts",
|
|
142
|
+
"import": "./dist/mcp/client/index.js",
|
|
143
|
+
"require": "./dist/mcp/client/index.js"
|
|
141
144
|
},
|
|
142
145
|
"./mcp/server": {
|
|
143
|
-
"types": "./dist/mcp/server.d.ts",
|
|
144
|
-
"import": "./dist/mcp/server.js",
|
|
145
|
-
"require": "./dist/mcp/server.js"
|
|
146
|
+
"types": "./dist/mcp/server/index.d.ts",
|
|
147
|
+
"import": "./dist/mcp/server/index.js",
|
|
148
|
+
"require": "./dist/mcp/server/index.js"
|
|
146
149
|
},
|
|
147
150
|
"./mcp/do-oauth-client-provider": {
|
|
148
|
-
"types": "./dist/mcp/do-oauth-client-provider.d.ts",
|
|
149
|
-
"import": "./dist/mcp/do-oauth-client-provider.js",
|
|
150
|
-
"require": "./dist/mcp/do-oauth-client-provider.js"
|
|
151
|
+
"types": "./dist/mcp/client/do-oauth-client-provider.d.ts",
|
|
152
|
+
"import": "./dist/mcp/client/do-oauth-client-provider.js",
|
|
153
|
+
"require": "./dist/mcp/client/do-oauth-client-provider.js"
|
|
151
154
|
},
|
|
152
155
|
"./observability": {
|
|
153
156
|
"types": "./dist/observability/index.d.ts",
|
|
@@ -169,6 +172,16 @@
|
|
|
169
172
|
"import": "./dist/schedule.js",
|
|
170
173
|
"require": "./dist/schedule.js"
|
|
171
174
|
},
|
|
175
|
+
"./schedules": {
|
|
176
|
+
"types": "./dist/schedules/index.d.ts",
|
|
177
|
+
"import": "./dist/schedules/index.js",
|
|
178
|
+
"require": "./dist/schedules/index.js"
|
|
179
|
+
},
|
|
180
|
+
"./schedules/parser": {
|
|
181
|
+
"types": "./dist/schedules/parser.d.ts",
|
|
182
|
+
"import": "./dist/schedules/parser.js",
|
|
183
|
+
"require": "./dist/schedules/parser.js"
|
|
184
|
+
},
|
|
172
185
|
"./workflows": {
|
|
173
186
|
"types": "./dist/workflows.d.ts",
|
|
174
187
|
"import": "./dist/workflows.js",
|
|
@@ -190,15 +203,20 @@
|
|
|
190
203
|
"require": "./dist/experimental/webmcp.js"
|
|
191
204
|
},
|
|
192
205
|
"./x402": {
|
|
193
|
-
"types": "./dist/mcp/x402.d.ts",
|
|
194
|
-
"import": "./dist/mcp/x402.js",
|
|
195
|
-
"require": "./dist/mcp/x402.js"
|
|
206
|
+
"types": "./dist/mcp/client/x402.d.ts",
|
|
207
|
+
"import": "./dist/mcp/client/x402.js",
|
|
208
|
+
"require": "./dist/mcp/client/x402.js"
|
|
196
209
|
},
|
|
197
210
|
"./chat": {
|
|
198
211
|
"types": "./dist/chat/index.d.ts",
|
|
199
212
|
"import": "./dist/chat/index.js",
|
|
200
213
|
"require": "./dist/chat/index.js"
|
|
201
214
|
},
|
|
215
|
+
"./chat/transport": {
|
|
216
|
+
"types": "./dist/chat/transport.d.ts",
|
|
217
|
+
"import": "./dist/chat/transport.js",
|
|
218
|
+
"require": "./dist/chat/transport.js"
|
|
219
|
+
},
|
|
202
220
|
"./chat/react": {
|
|
203
221
|
"types": "./dist/chat/react.d.ts",
|
|
204
222
|
"import": "./dist/chat/react.js",
|
|
@@ -299,7 +317,7 @@
|
|
|
299
317
|
"build": "tsx ./scripts/build.ts",
|
|
300
318
|
"evals": "(cd evals; evalite)",
|
|
301
319
|
"test": "vitest --run",
|
|
302
|
-
"test:
|
|
320
|
+
"test:node": "vitest --project node",
|
|
303
321
|
"test:react": "vitest --project react",
|
|
304
322
|
"test:browser": "vitest run --config src/browser-tests/vitest.config.ts",
|
|
305
323
|
"test:workers": "vitest --project workers",
|
package/dist/cli/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/cli/index.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import yargs from "yargs";
|
|
3
|
-
import { hideBin } from "yargs/helpers";
|
|
4
|
-
//#region src/cli/create.ts
|
|
5
|
-
function createCli(argv = process.argv) {
|
|
6
|
-
return yargs(hideBin(argv)).scriptName("agents").usage("$0 <command> [options]").command(["init", "create"], "Initialize an agents project", (cmd) => cmd, async () => {
|
|
7
|
-
console.log("agents init: not implemented yet");
|
|
8
|
-
process.exit(0);
|
|
9
|
-
}).command("dev", "Start development server", (cmd) => cmd, async () => {
|
|
10
|
-
console.log("agents dev: not implemented yet");
|
|
11
|
-
process.exit(0);
|
|
12
|
-
}).command("deploy", "Deploy agents to Cloudflare", (cmd) => cmd, async () => {
|
|
13
|
-
console.log("agents deploy: not implemented yet");
|
|
14
|
-
process.exit(0);
|
|
15
|
-
}).command("mcp", "The agents mcp server", (cmd) => cmd, async () => {
|
|
16
|
-
console.log("agents mcp: not implemented yet");
|
|
17
|
-
process.exit(0);
|
|
18
|
-
}).demandCommand(1, "Please provide a command").strict().help();
|
|
19
|
-
}
|
|
20
|
-
//#endregion
|
|
21
|
-
//#region src/cli/index.ts
|
|
22
|
-
createCli().parse();
|
|
23
|
-
//#endregion
|
|
24
|
-
export {};
|
|
25
|
-
|
|
26
|
-
//# sourceMappingURL=index.js.map
|
package/dist/cli/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/cli/create.ts","../../src/cli/index.ts"],"sourcesContent":["import yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\n\nexport function createCli(argv = process.argv) {\n return yargs(hideBin(argv))\n .scriptName(\"agents\")\n .usage(\"$0 <command> [options]\")\n .command(\n [\"init\", \"create\"],\n \"Initialize an agents project\",\n (cmd) => cmd,\n async () => {\n console.log(\"agents init: not implemented yet\");\n process.exit(0);\n }\n )\n .command(\n \"dev\",\n \"Start development server\",\n (cmd) => cmd,\n async () => {\n console.log(\"agents dev: not implemented yet\");\n process.exit(0);\n }\n )\n .command(\n \"deploy\",\n \"Deploy agents to Cloudflare\",\n (cmd) => cmd,\n async () => {\n console.log(\"agents deploy: not implemented yet\");\n process.exit(0);\n }\n )\n .command(\n \"mcp\",\n \"The agents mcp server\",\n (cmd) => cmd,\n async () => {\n console.log(\"agents mcp: not implemented yet\");\n process.exit(0);\n }\n )\n .demandCommand(1, \"Please provide a command\")\n .strict()\n .help();\n}\n","#!/usr/bin/env node\n\nimport { createCli } from \"./create\";\n\nvoid createCli().parse();\n"],"mappings":";;;;AAGA,SAAgB,UAAU,OAAO,QAAQ,MAAM;CAC7C,OAAO,MAAM,QAAQ,IAAI,CAAC,CAAC,CACxB,WAAW,QAAQ,CAAC,CACpB,MAAM,wBAAwB,CAAC,CAC/B,QACC,CAAC,QAAQ,QAAQ,GACjB,iCACC,QAAQ,KACT,YAAY;EACV,QAAQ,IAAI,kCAAkC;EAC9C,QAAQ,KAAK,CAAC;CAChB,CACF,CAAC,CACA,QACC,OACA,6BACC,QAAQ,KACT,YAAY;EACV,QAAQ,IAAI,iCAAiC;EAC7C,QAAQ,KAAK,CAAC;CAChB,CACF,CAAC,CACA,QACC,UACA,gCACC,QAAQ,KACT,YAAY;EACV,QAAQ,IAAI,oCAAoC;EAChD,QAAQ,KAAK,CAAC;CAChB,CACF,CAAC,CACA,QACC,OACA,0BACC,QAAQ,KACT,YAAY;EACV,QAAQ,IAAI,iCAAiC;EAC7C,QAAQ,KAAK,CAAC;CAChB,CACF,CAAC,CACA,cAAc,GAAG,0BAA0B,CAAC,CAC5C,OAAO,CAAC,CACR,KAAK;AACV;;;AC1CK,UAAU,CAAC,CAAC,MAAM"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client-invoker-VNZ7X0nn.js","names":[],"sources":["../src/mcp/client-invoker.ts"],"sourcesContent":["import type {\n CallToolRequest,\n CallToolRequestOptions,\n CallToolResult,\n Client,\n ListToolsResult\n} from \"@modelcontextprotocol/client\";\nimport type { Client as LegacyClient } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type {\n CallToolResult as LegacyCallToolResult,\n CallToolResultSchema,\n CompatibilityCallToolResultSchema,\n ListToolsRequest\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { RequestOptions as LegacyRequestOptions } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\n\nexport type LegacyCallToolResultSchema =\n | typeof CallToolResultSchema\n | typeof CompatibilityCallToolResultSchema;\n\nexport type CallToolSchemaOrOptions =\n | LegacyCallToolResultSchema\n | CallToolRequestOptions;\n\nexport type CompatibleMcpClient = Client | LegacyClient;\n\nexport interface BoundMcpClientInvoker {\n listTools(\n params?: ListToolsRequest[\"params\"],\n options?: CallToolRequestOptions\n ): Promise<ListToolsResult>;\n callTool(\n params: CallToolRequest[\"params\"],\n schemaOrOptions?: CallToolSchemaOrOptions,\n options?: CallToolRequestOptions\n ): Promise<LegacyCallToolResult>;\n}\n\nfunction isLegacyResultSchema(\n value: CallToolSchemaOrOptions | undefined\n): value is LegacyCallToolResultSchema {\n return (\n typeof (value as { parse?: unknown } | undefined)?.parse === \"function\"\n );\n}\n\nfunction normalizeCallToolArguments(\n schemaOrOptions?: CallToolSchemaOrOptions,\n options?: CallToolRequestOptions\n): {\n schema?: LegacyCallToolResultSchema;\n options?: CallToolRequestOptions;\n} {\n return isLegacyResultSchema(schemaOrOptions)\n ? { schema: schemaOrOptions, options }\n : { options: schemaOrOptions ?? options };\n}\n\n/**\n * Invoke SDK v2 while preserving the deprecated v1 result-schema overload.\n * The v2 request funnel still owns decoding and automatic MRTR.\n */\nexport function callV2Tool(\n client: Client,\n params: CallToolRequest[\"params\"],\n schemaOrOptions?: CallToolSchemaOrOptions,\n options?: CallToolRequestOptions\n): Promise<CallToolResult> {\n const normalized = normalizeCallToolArguments(schemaOrOptions, options);\n if (normalized.schema) {\n return client.request(\n { method: \"tools/call\", params },\n normalized.schema as never,\n normalized.options\n ) as Promise<CallToolResult>;\n }\n return client.callTool(params, normalized.options);\n}\n\n/**\n * Bind the original methods before decorators such as x402 replace them. All\n * generation-specific calling conventions stay behind this small interface.\n */\nexport function bindMcpClient(\n client: CompatibleMcpClient\n): BoundMcpClientInvoker {\n const isV2 =\n \"getProtocolEra\" in client &&\n typeof (client as { getProtocolEra?: unknown }).getProtocolEra ===\n \"function\";\n\n if (isV2) {\n const v2Client = client as Client;\n const listTools = v2Client.listTools.bind(v2Client);\n const callTool = v2Client.callTool.bind(v2Client);\n return {\n listTools: (params, options) => listTools(params, options),\n callTool: (params, schemaOrOptions, options) => {\n const normalized = normalizeCallToolArguments(schemaOrOptions, options);\n const pending = normalized.schema\n ? v2Client.request(\n { method: \"tools/call\", params },\n normalized.schema as never,\n normalized.options\n )\n : callTool(params, normalized.options);\n return pending as Promise<LegacyCallToolResult>;\n }\n };\n }\n\n const legacy = client as LegacyClient;\n const listTools = legacy.listTools.bind(legacy);\n const callTool = legacy.callTool.bind(legacy);\n return {\n listTools: (params, options) =>\n listTools(\n params,\n options as LegacyRequestOptions\n ) as Promise<ListToolsResult>,\n callTool: (params, schemaOrOptions, options) => {\n const normalized = normalizeCallToolArguments(schemaOrOptions, options);\n return callTool(\n params as Parameters<LegacyClient[\"callTool\"]>[0],\n normalized.schema,\n normalized.options as LegacyRequestOptions\n ) as Promise<LegacyCallToolResult>;\n }\n };\n}\n"],"mappings":";AAsCA,SAAS,qBACP,OACqC;CACrC,OACE,OAAQ,OAA2C,UAAU;AAEjE;AAEA,SAAS,2BACP,iBACA,SAIA;CACA,OAAO,qBAAqB,eAAe,IACvC;EAAE,QAAQ;EAAiB;CAAQ,IACnC,EAAE,SAAS,mBAAmB,QAAQ;AAC5C;;;;;AAMA,SAAgB,WACd,QACA,QACA,iBACA,SACyB;CACzB,MAAM,aAAa,2BAA2B,iBAAiB,OAAO;CACtE,IAAI,WAAW,QACb,OAAO,OAAO,QACZ;EAAE,QAAQ;EAAc;CAAO,GAC/B,WAAW,QACX,WAAW,OACb;CAEF,OAAO,OAAO,SAAS,QAAQ,WAAW,OAAO;AACnD;;;;;AAMA,SAAgB,cACd,QACuB;CAMvB,IAJE,oBAAoB,UACpB,OAAQ,OAAwC,mBAC9C,YAEM;EACR,MAAM,WAAW;EACjB,MAAM,YAAY,SAAS,UAAU,KAAK,QAAQ;EAClD,MAAM,WAAW,SAAS,SAAS,KAAK,QAAQ;EAChD,OAAO;GACL,YAAY,QAAQ,YAAY,UAAU,QAAQ,OAAO;GACzD,WAAW,QAAQ,iBAAiB,YAAY;IAC9C,MAAM,aAAa,2BAA2B,iBAAiB,OAAO;IAQtE,OAPgB,WAAW,SACvB,SAAS,QACP;KAAE,QAAQ;KAAc;IAAO,GAC/B,WAAW,QACX,WAAW,OACb,IACA,SAAS,QAAQ,WAAW,OAAO;GAEzC;EACF;CACF;CAEA,MAAM,SAAS;CACf,MAAM,YAAY,OAAO,UAAU,KAAK,MAAM;CAC9C,MAAM,WAAW,OAAO,SAAS,KAAK,MAAM;CAC5C,OAAO;EACL,YAAY,QAAQ,YAClB,UACE,QACA,OACF;EACF,WAAW,QAAQ,iBAAiB,YAAY;GAC9C,MAAM,aAAa,2BAA2B,iBAAiB,OAAO;GACtE,OAAO,SACL,QACA,WAAW,QACX,WAAW,OACb;EACF;CACF;AACF"}
|