agents 0.3.10 → 0.4.1
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 +2 -2
- package/dist/{index-N6791tVt.d.ts → agent-DY6QmSI_.d.ts} +3 -25
- package/dist/ai-types.js +1 -1
- package/dist/client-connection-CGMuV62J.js +472 -0
- package/dist/client-connection-CGMuV62J.js.map +1 -0
- package/dist/client-storage-Cvy5r9FG.d.ts +355 -0
- package/dist/client.d.ts +11 -7
- package/dist/client.js +6 -2
- package/dist/client.js.map +1 -1
- package/dist/email.d.ts +146 -16
- package/dist/email.js +222 -2
- package/dist/email.js.map +1 -0
- package/dist/index.d.ts +142 -41
- package/dist/index.js +2326 -6
- package/dist/index.js.map +1 -0
- package/dist/internal_context.d.ts +33 -6
- package/dist/internal_context.js +11 -2
- package/dist/internal_context.js.map +1 -0
- package/dist/mcp/client.d.ts +516 -2
- package/dist/mcp/client.js +662 -3
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/do-oauth-client-provider.d.ts +61 -2
- package/dist/mcp/do-oauth-client-provider.js +154 -2
- package/dist/mcp/do-oauth-client-provider.js.map +1 -0
- package/dist/mcp/index.d.ts +3 -5
- package/dist/mcp/index.js +8 -7
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/x402.d.ts +34 -14
- package/dist/mcp/x402.js +128 -66
- package/dist/mcp/x402.js.map +1 -1
- package/dist/{mcp-BwPscEiF.d.ts → mcp-Dw5vDrY8.d.ts} +1 -1
- package/dist/observability/index.d.ts +23 -2
- package/dist/observability/index.js +25 -6
- package/dist/observability/index.js.map +1 -0
- package/dist/react.d.ts +10 -10
- package/dist/react.js +6 -2
- package/dist/react.js.map +1 -1
- package/dist/types.d.ts +14 -1
- package/dist/types.js +16 -2
- package/dist/types.js.map +1 -0
- package/dist/utils.js +15 -2
- package/dist/utils.js.map +1 -0
- package/dist/workflow-types.d.ts +235 -23
- package/dist/workflows.d.ts +22 -24
- package/dist/workflows.js +2 -5
- package/dist/workflows.js.map +1 -1
- package/package.json +24 -28
- package/dist/client-CtC9E06G.js +0 -1122
- package/dist/client-CtC9E06G.js.map +0 -1
- package/dist/client-DV1CZKqa.d.ts +0 -969
- package/dist/do-oauth-client-provider-BqnOQzjy.d.ts +0 -70
- package/dist/do-oauth-client-provider-DDg8QrEA.js +0 -155
- package/dist/do-oauth-client-provider-DDg8QrEA.js.map +0 -1
- package/dist/email-8ljcpvwV.d.ts +0 -157
- package/dist/email-XHsSYsTO.js +0 -223
- package/dist/email-XHsSYsTO.js.map +0 -1
- package/dist/internal_context-CEu5ji80.d.ts +0 -29
- package/dist/internal_context-D9eKFth1.js +0 -8
- package/dist/internal_context-D9eKFth1.js.map +0 -1
- package/dist/src-i_UcyBYf.js +0 -2147
- package/dist/src-i_UcyBYf.js.map +0 -1
- package/dist/types-BITaDFf-.js +0 -16
- package/dist/types-BITaDFf-.js.map +0 -1
- package/dist/types-DSSHBW6w.d.ts +0 -14
- package/dist/utils-B49TmLCI.js +0 -16
- package/dist/utils-B49TmLCI.js.map +0 -1
- package/dist/workflow-types-Z_Oem1FJ.d.ts +0 -260
package/dist/email.js
CHANGED
|
@@ -1,3 +1,223 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/email.ts
|
|
2
|
+
/**
|
|
3
|
+
* Check if an email appears to be an auto-reply based on standard headers.
|
|
4
|
+
* Checks for Auto-Submitted (RFC 3834), X-Auto-Response-Suppress, and Precedence headers.
|
|
5
|
+
*
|
|
6
|
+
* @param headers - Headers array from postal-mime Email.headers or similar format
|
|
7
|
+
* @returns true if email appears to be an auto-reply
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* if (isAutoReplyEmail(parsed.headers)) {
|
|
12
|
+
* // Skip processing auto-replies
|
|
13
|
+
* return;
|
|
14
|
+
* }
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
function isAutoReplyEmail(headers) {
|
|
18
|
+
return headers.some((h) => {
|
|
19
|
+
const key = h.key.toLowerCase();
|
|
20
|
+
const value = h.value.toLowerCase();
|
|
21
|
+
if (key === "auto-submitted") return value !== "no";
|
|
22
|
+
if (key === "x-auto-response-suppress") return true;
|
|
23
|
+
if (key === "precedence") return value === "bulk" || value === "junk" || value === "list";
|
|
24
|
+
return false;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/** Default signature expiration: 30 days in seconds */
|
|
28
|
+
const DEFAULT_MAX_AGE_SECONDS = 720 * 60 * 60;
|
|
29
|
+
/** Maximum allowed clock skew for future timestamps: 5 minutes */
|
|
30
|
+
const MAX_CLOCK_SKEW_SECONDS = 300;
|
|
31
|
+
/**
|
|
32
|
+
* Compute HMAC-SHA256 signature for agent routing headers
|
|
33
|
+
* @param secret - Secret key for HMAC
|
|
34
|
+
* @param agentName - Name of the agent
|
|
35
|
+
* @param agentId - ID of the agent instance
|
|
36
|
+
* @param timestamp - Unix timestamp in seconds
|
|
37
|
+
* @returns Base64-encoded HMAC signature
|
|
38
|
+
*/
|
|
39
|
+
async function computeAgentSignature(secret, agentName, agentId, timestamp) {
|
|
40
|
+
const encoder = new TextEncoder();
|
|
41
|
+
const key = await crypto.subtle.importKey("raw", encoder.encode(secret), {
|
|
42
|
+
name: "HMAC",
|
|
43
|
+
hash: "SHA-256"
|
|
44
|
+
}, false, ["sign"]);
|
|
45
|
+
const data = encoder.encode(`${agentName}:${agentId}:${timestamp}`);
|
|
46
|
+
const signature = await crypto.subtle.sign("HMAC", key, data);
|
|
47
|
+
return btoa(String.fromCharCode(...new Uint8Array(signature)));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Verify HMAC-SHA256 signature for agent routing headers
|
|
51
|
+
* @param secret - Secret key for HMAC
|
|
52
|
+
* @param agentName - Name of the agent
|
|
53
|
+
* @param agentId - ID of the agent instance
|
|
54
|
+
* @param signature - Base64-encoded signature to verify
|
|
55
|
+
* @param timestamp - Unix timestamp in seconds when signature was created
|
|
56
|
+
* @param maxAgeSeconds - Maximum age of signature in seconds (default: 30 days)
|
|
57
|
+
* @returns Verification result with reason if invalid
|
|
58
|
+
*/
|
|
59
|
+
async function verifyAgentSignature(secret, agentName, agentId, signature, timestamp, maxAgeSeconds = DEFAULT_MAX_AGE_SECONDS) {
|
|
60
|
+
try {
|
|
61
|
+
const timestampNum = Number.parseInt(timestamp, 10);
|
|
62
|
+
if (Number.isNaN(timestampNum)) return {
|
|
63
|
+
valid: false,
|
|
64
|
+
reason: "malformed_timestamp"
|
|
65
|
+
};
|
|
66
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
67
|
+
if (timestampNum > now + MAX_CLOCK_SKEW_SECONDS) return {
|
|
68
|
+
valid: false,
|
|
69
|
+
reason: "invalid"
|
|
70
|
+
};
|
|
71
|
+
if (now - timestampNum > maxAgeSeconds) return {
|
|
72
|
+
valid: false,
|
|
73
|
+
reason: "expired"
|
|
74
|
+
};
|
|
75
|
+
const expected = await computeAgentSignature(secret, agentName, agentId, timestamp);
|
|
76
|
+
if (expected.length !== signature.length) return {
|
|
77
|
+
valid: false,
|
|
78
|
+
reason: "invalid"
|
|
79
|
+
};
|
|
80
|
+
let result = 0;
|
|
81
|
+
for (let i = 0; i < expected.length; i++) result |= expected.charCodeAt(i) ^ signature.charCodeAt(i);
|
|
82
|
+
if (result !== 0) return {
|
|
83
|
+
valid: false,
|
|
84
|
+
reason: "invalid"
|
|
85
|
+
};
|
|
86
|
+
return { valid: true };
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.warn("[agents] Signature verification error:", error);
|
|
89
|
+
return {
|
|
90
|
+
valid: false,
|
|
91
|
+
reason: "invalid"
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Sign agent routing headers for secure reply flows.
|
|
97
|
+
* Use this when sending outbound emails to ensure replies can be securely routed back.
|
|
98
|
+
*
|
|
99
|
+
* @param secret - Secret key for HMAC signing (store in environment variables)
|
|
100
|
+
* @param agentName - Name of the agent
|
|
101
|
+
* @param agentId - ID of the agent instance
|
|
102
|
+
* @returns Headers object with X-Agent-Name, X-Agent-ID, X-Agent-Sig, and X-Agent-Sig-Ts
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* const headers = await signAgentHeaders(env.EMAIL_SECRET, "MyAgent", this.name);
|
|
107
|
+
* // Use these headers when sending outbound emails
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
async function signAgentHeaders(secret, agentName, agentId) {
|
|
111
|
+
if (!secret) throw new Error("secret is required for signing agent headers");
|
|
112
|
+
if (!agentName) throw new Error("agentName is required for signing agent headers");
|
|
113
|
+
if (!agentId) throw new Error("agentId is required for signing agent headers");
|
|
114
|
+
if (agentName.includes(":")) throw new Error("agentName cannot contain colons");
|
|
115
|
+
if (agentId.includes(":")) throw new Error("agentId cannot contain colons");
|
|
116
|
+
const timestamp = Math.floor(Date.now() / 1e3).toString();
|
|
117
|
+
const signature = await computeAgentSignature(secret, agentName, agentId, timestamp);
|
|
118
|
+
return {
|
|
119
|
+
"X-Agent-Name": agentName,
|
|
120
|
+
"X-Agent-ID": agentId,
|
|
121
|
+
"X-Agent-Sig": signature,
|
|
122
|
+
"X-Agent-Sig-Ts": timestamp
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* @deprecated REMOVED due to security vulnerability (IDOR via spoofed headers).
|
|
127
|
+
* @throws Always throws an error with migration guidance.
|
|
128
|
+
*/
|
|
129
|
+
function createHeaderBasedEmailResolver() {
|
|
130
|
+
throw new Error("createHeaderBasedEmailResolver has been removed due to a security vulnerability. It trusted attacker-controlled email headers for routing, enabling IDOR attacks.\n\nMigration options:\n - For inbound mail: use createAddressBasedEmailResolver(agentName)\n - For reply flows: use createSecureReplyEmailResolver(secret) with signed headers\n\nSee https://github.com/cloudflare/agents/blob/main/docs/email.md for details.");
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Create a resolver for routing email replies with signature verification.
|
|
134
|
+
* This resolver verifies that replies contain a valid HMAC signature, preventing
|
|
135
|
+
* attackers from routing emails to arbitrary agent instances.
|
|
136
|
+
*
|
|
137
|
+
* @param secret - Secret key for HMAC verification (must match the key used with signAgentHeaders)
|
|
138
|
+
* @param options - Optional configuration for signature verification
|
|
139
|
+
* @returns A function that resolves the agent to route the email to, or null if signature is invalid
|
|
140
|
+
*
|
|
141
|
+
* @example
|
|
142
|
+
* ```typescript
|
|
143
|
+
* // In your email handler
|
|
144
|
+
* const secureResolver = createSecureReplyEmailResolver(env.EMAIL_SECRET, {
|
|
145
|
+
* maxAge: 7 * 24 * 60 * 60, // 7 days
|
|
146
|
+
* onInvalidSignature: (email, reason) => {
|
|
147
|
+
* console.warn(`Invalid signature from ${email.from}: ${reason}`);
|
|
148
|
+
* }
|
|
149
|
+
* });
|
|
150
|
+
* const addressResolver = createAddressBasedEmailResolver("MyAgent");
|
|
151
|
+
*
|
|
152
|
+
* await routeAgentEmail(email, env, {
|
|
153
|
+
* resolver: async (email, env) => {
|
|
154
|
+
* // Try secure reply routing first
|
|
155
|
+
* const replyRouting = await secureResolver(email, env);
|
|
156
|
+
* if (replyRouting) return replyRouting;
|
|
157
|
+
* // Fall back to address-based routing
|
|
158
|
+
* return addressResolver(email, env);
|
|
159
|
+
* }
|
|
160
|
+
* });
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
function createSecureReplyEmailResolver(secret, options) {
|
|
164
|
+
if (!secret) throw new Error("secret is required for createSecureReplyEmailResolver");
|
|
165
|
+
const maxAge = options?.maxAge ?? DEFAULT_MAX_AGE_SECONDS;
|
|
166
|
+
const onInvalidSignature = options?.onInvalidSignature;
|
|
167
|
+
return async (email, _env) => {
|
|
168
|
+
const agentName = email.headers.get("x-agent-name");
|
|
169
|
+
const agentId = email.headers.get("x-agent-id");
|
|
170
|
+
const signature = email.headers.get("x-agent-sig");
|
|
171
|
+
const timestamp = email.headers.get("x-agent-sig-ts");
|
|
172
|
+
if (!agentName || !agentId || !signature || !timestamp) {
|
|
173
|
+
onInvalidSignature?.(email, "missing_headers");
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
const result = await verifyAgentSignature(secret, agentName, agentId, signature, timestamp, maxAge);
|
|
177
|
+
if (!result.valid) {
|
|
178
|
+
onInvalidSignature?.(email, result.reason);
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
agentName,
|
|
183
|
+
agentId,
|
|
184
|
+
_secureRouted: true
|
|
185
|
+
};
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Create a resolver that uses the email address to determine the agent to route the email to
|
|
190
|
+
* @param defaultAgentName The default agent name to use if the email address does not contain a sub-address
|
|
191
|
+
* @returns A function that resolves the agent to route the email to
|
|
192
|
+
*/
|
|
193
|
+
function createAddressBasedEmailResolver(defaultAgentName) {
|
|
194
|
+
return async (email, _env) => {
|
|
195
|
+
const emailMatch = email.to.match(/^([^+@]{1,64})(?:\+([^@]{1,64}))?@(.{1,253})$/);
|
|
196
|
+
if (!emailMatch) return null;
|
|
197
|
+
const [, localPart, subAddress] = emailMatch;
|
|
198
|
+
if (subAddress) return {
|
|
199
|
+
agentName: localPart,
|
|
200
|
+
agentId: subAddress
|
|
201
|
+
};
|
|
202
|
+
return {
|
|
203
|
+
agentName: defaultAgentName,
|
|
204
|
+
agentId: localPart
|
|
205
|
+
};
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Create a resolver that uses the agentName and agentId to determine the agent to route the email to
|
|
210
|
+
* @param agentName The name of the agent to route the email to
|
|
211
|
+
* @param agentId The id of the agent to route the email to
|
|
212
|
+
* @returns A function that resolves the agent to route the email to
|
|
213
|
+
*/
|
|
214
|
+
function createCatchAllEmailResolver(agentName, agentId) {
|
|
215
|
+
return async () => ({
|
|
216
|
+
agentName,
|
|
217
|
+
agentId
|
|
218
|
+
});
|
|
219
|
+
}
|
|
2
220
|
|
|
3
|
-
|
|
221
|
+
//#endregion
|
|
222
|
+
export { DEFAULT_MAX_AGE_SECONDS, createAddressBasedEmailResolver, createCatchAllEmailResolver, createHeaderBasedEmailResolver, createSecureReplyEmailResolver, isAutoReplyEmail, signAgentHeaders };
|
|
223
|
+
//# sourceMappingURL=email.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.js","names":[],"sources":["../src/email.ts"],"sourcesContent":["/**\n * Email routing types, resolvers, and signing utilities for Agents\n */\n\n// Re-export AgentEmail type\nexport type { AgentEmail } from \"./internal_context\";\n\n// ============================================================================\n// Email header utilities\n// ============================================================================\n\n/**\n * Header object as returned by postal-mime and similar email parsing libraries.\n * Each header has a lowercase key and a string value.\n */\nexport type EmailHeader = {\n /** Lowercase header name (e.g., \"content-type\", \"x-custom-header\") */\n key: string;\n /** Header value */\n value: string;\n};\n\n/**\n * Check if an email appears to be an auto-reply based on standard headers.\n * Checks for Auto-Submitted (RFC 3834), X-Auto-Response-Suppress, and Precedence headers.\n *\n * @param headers - Headers array from postal-mime Email.headers or similar format\n * @returns true if email appears to be an auto-reply\n *\n * @example\n * ```typescript\n * if (isAutoReplyEmail(parsed.headers)) {\n * // Skip processing auto-replies\n * return;\n * }\n * ```\n */\nexport function isAutoReplyEmail(headers: EmailHeader[]): boolean {\n return headers.some((h) => {\n const key = h.key.toLowerCase();\n const value = h.value.toLowerCase();\n\n // RFC 3834: Auto-Submitted header\n // \"no\" means normal (human-sent) email, anything else indicates auto-reply\n if (key === \"auto-submitted\") {\n return value !== \"no\";\n }\n\n // X-Auto-Response-Suppress: any value indicates sender doesn't want auto-replies\n if (key === \"x-auto-response-suppress\") {\n return true;\n }\n\n // Precedence: only bulk/junk/list indicate automated/mass mail\n if (key === \"precedence\") {\n return value === \"bulk\" || value === \"junk\" || value === \"list\";\n }\n\n return false;\n });\n}\n\n// ============================================================================\n// Signing utilities\n// ============================================================================\n\n/** Default signature expiration: 30 days in seconds */\nexport const DEFAULT_MAX_AGE_SECONDS = 30 * 24 * 60 * 60;\n\n/** Maximum allowed clock skew for future timestamps: 5 minutes */\nconst MAX_CLOCK_SKEW_SECONDS = 5 * 60;\n\n/**\n * Compute HMAC-SHA256 signature for agent routing headers\n * @param secret - Secret key for HMAC\n * @param agentName - Name of the agent\n * @param agentId - ID of the agent instance\n * @param timestamp - Unix timestamp in seconds\n * @returns Base64-encoded HMAC signature\n */\nasync function computeAgentSignature(\n secret: string,\n agentName: string,\n agentId: string,\n timestamp: string\n): Promise<string> {\n const encoder = new TextEncoder();\n const key = await crypto.subtle.importKey(\n \"raw\",\n encoder.encode(secret),\n { name: \"HMAC\", hash: \"SHA-256\" },\n false,\n [\"sign\"]\n );\n const data = encoder.encode(`${agentName}:${agentId}:${timestamp}`);\n const signature = await crypto.subtle.sign(\"HMAC\", key, data);\n return btoa(String.fromCharCode(...new Uint8Array(signature)));\n}\n\n/**\n * Result of signature verification\n */\ntype SignatureVerificationResult =\n | { valid: true }\n | { valid: false; reason: \"expired\" | \"invalid\" | \"malformed_timestamp\" };\n\n/**\n * Verify HMAC-SHA256 signature for agent routing headers\n * @param secret - Secret key for HMAC\n * @param agentName - Name of the agent\n * @param agentId - ID of the agent instance\n * @param signature - Base64-encoded signature to verify\n * @param timestamp - Unix timestamp in seconds when signature was created\n * @param maxAgeSeconds - Maximum age of signature in seconds (default: 30 days)\n * @returns Verification result with reason if invalid\n */\nasync function verifyAgentSignature(\n secret: string,\n agentName: string,\n agentId: string,\n signature: string,\n timestamp: string,\n maxAgeSeconds: number = DEFAULT_MAX_AGE_SECONDS\n): Promise<SignatureVerificationResult> {\n try {\n // Validate timestamp format\n const timestampNum = Number.parseInt(timestamp, 10);\n if (Number.isNaN(timestampNum)) {\n return { valid: false, reason: \"malformed_timestamp\" };\n }\n\n // Check timestamp validity\n const now = Math.floor(Date.now() / 1000);\n\n // Reject timestamps too far in the future (prevents extending signature validity)\n if (timestampNum > now + MAX_CLOCK_SKEW_SECONDS) {\n return { valid: false, reason: \"invalid\" };\n }\n\n // Check if signature has expired\n if (now - timestampNum > maxAgeSeconds) {\n return { valid: false, reason: \"expired\" };\n }\n\n const expected = await computeAgentSignature(\n secret,\n agentName,\n agentId,\n timestamp\n );\n // Constant-time comparison to prevent timing attacks\n if (expected.length !== signature.length) {\n return { valid: false, reason: \"invalid\" };\n }\n let result = 0;\n for (let i = 0; i < expected.length; i++) {\n result |= expected.charCodeAt(i) ^ signature.charCodeAt(i);\n }\n if (result !== 0) {\n return { valid: false, reason: \"invalid\" };\n }\n return { valid: true };\n } catch (error) {\n console.warn(\"[agents] Signature verification error:\", error);\n return { valid: false, reason: \"invalid\" };\n }\n}\n\n/**\n * Sign agent routing headers for secure reply flows.\n * Use this when sending outbound emails to ensure replies can be securely routed back.\n *\n * @param secret - Secret key for HMAC signing (store in environment variables)\n * @param agentName - Name of the agent\n * @param agentId - ID of the agent instance\n * @returns Headers object with X-Agent-Name, X-Agent-ID, X-Agent-Sig, and X-Agent-Sig-Ts\n *\n * @example\n * ```typescript\n * const headers = await signAgentHeaders(env.EMAIL_SECRET, \"MyAgent\", this.name);\n * // Use these headers when sending outbound emails\n * ```\n */\nexport async function signAgentHeaders(\n secret: string,\n agentName: string,\n agentId: string\n): Promise<Record<string, string>> {\n if (!secret) {\n throw new Error(\"secret is required for signing agent headers\");\n }\n if (!agentName) {\n throw new Error(\"agentName is required for signing agent headers\");\n }\n if (!agentId) {\n throw new Error(\"agentId is required for signing agent headers\");\n }\n // Reject colons to prevent signature confusion attacks\n // (signature payload uses colon as delimiter: \"agentName:agentId:timestamp\")\n if (agentName.includes(\":\")) {\n throw new Error(\"agentName cannot contain colons\");\n }\n if (agentId.includes(\":\")) {\n throw new Error(\"agentId cannot contain colons\");\n }\n\n const timestamp = Math.floor(Date.now() / 1000).toString();\n const signature = await computeAgentSignature(\n secret,\n agentName,\n agentId,\n timestamp\n );\n return {\n \"X-Agent-Name\": agentName,\n \"X-Agent-ID\": agentId,\n \"X-Agent-Sig\": signature,\n \"X-Agent-Sig-Ts\": timestamp\n };\n}\n\n// ============================================================================\n// Email routing types and resolvers\n// ============================================================================\n\nexport type EmailResolverResult = {\n agentName: string;\n agentId: string;\n /** @internal Indicates this resolver requires secure reply signing */\n _secureRouted?: boolean;\n} | null;\n\nexport type EmailResolver<Env> = (\n email: ForwardableEmailMessage,\n env: Env\n) => Promise<EmailResolverResult>;\n\n/**\n * Reason for signature verification failure\n */\nexport type SignatureFailureReason =\n | \"missing_headers\"\n | \"expired\"\n | \"invalid\"\n | \"malformed_timestamp\";\n\n/**\n * Options for createSecureReplyEmailResolver\n */\nexport type SecureReplyResolverOptions = {\n /**\n * Maximum age of signature in seconds.\n * Signatures older than this will be rejected.\n * Default: 30 days (2592000 seconds)\n */\n maxAge?: number;\n /**\n * Callback invoked when signature verification fails.\n * Useful for logging and debugging.\n */\n onInvalidSignature?: (\n email: ForwardableEmailMessage,\n reason: SignatureFailureReason\n ) => void;\n};\n\n/**\n * @deprecated REMOVED due to security vulnerability (IDOR via spoofed headers).\n * @throws Always throws an error with migration guidance.\n */\nexport function createHeaderBasedEmailResolver<Env>(): EmailResolver<Env> {\n throw new Error(\n \"createHeaderBasedEmailResolver has been removed due to a security vulnerability. \" +\n \"It trusted attacker-controlled email headers for routing, enabling IDOR attacks.\\n\\n\" +\n \"Migration options:\\n\" +\n \" - For inbound mail: use createAddressBasedEmailResolver(agentName)\\n\" +\n \" - For reply flows: use createSecureReplyEmailResolver(secret) with signed headers\\n\\n\" +\n \"See https://github.com/cloudflare/agents/blob/main/docs/email.md for details.\"\n );\n}\n\n/**\n * Create a resolver for routing email replies with signature verification.\n * This resolver verifies that replies contain a valid HMAC signature, preventing\n * attackers from routing emails to arbitrary agent instances.\n *\n * @param secret - Secret key for HMAC verification (must match the key used with signAgentHeaders)\n * @param options - Optional configuration for signature verification\n * @returns A function that resolves the agent to route the email to, or null if signature is invalid\n *\n * @example\n * ```typescript\n * // In your email handler\n * const secureResolver = createSecureReplyEmailResolver(env.EMAIL_SECRET, {\n * maxAge: 7 * 24 * 60 * 60, // 7 days\n * onInvalidSignature: (email, reason) => {\n * console.warn(`Invalid signature from ${email.from}: ${reason}`);\n * }\n * });\n * const addressResolver = createAddressBasedEmailResolver(\"MyAgent\");\n *\n * await routeAgentEmail(email, env, {\n * resolver: async (email, env) => {\n * // Try secure reply routing first\n * const replyRouting = await secureResolver(email, env);\n * if (replyRouting) return replyRouting;\n * // Fall back to address-based routing\n * return addressResolver(email, env);\n * }\n * });\n * ```\n */\nexport function createSecureReplyEmailResolver<Env>(\n secret: string,\n options?: SecureReplyResolverOptions\n): EmailResolver<Env> {\n if (!secret) {\n throw new Error(\"secret is required for createSecureReplyEmailResolver\");\n }\n\n const maxAge = options?.maxAge ?? DEFAULT_MAX_AGE_SECONDS;\n const onInvalidSignature = options?.onInvalidSignature;\n\n return async (email: ForwardableEmailMessage, _env: Env) => {\n const agentName = email.headers.get(\"x-agent-name\");\n const agentId = email.headers.get(\"x-agent-id\");\n const signature = email.headers.get(\"x-agent-sig\");\n const timestamp = email.headers.get(\"x-agent-sig-ts\");\n\n if (!agentName || !agentId || !signature || !timestamp) {\n onInvalidSignature?.(email, \"missing_headers\");\n return null;\n }\n\n const result = await verifyAgentSignature(\n secret,\n agentName,\n agentId,\n signature,\n timestamp,\n maxAge\n );\n\n if (!result.valid) {\n onInvalidSignature?.(email, result.reason);\n return null;\n }\n\n return { agentName, agentId, _secureRouted: true };\n };\n}\n\n/**\n * Create a resolver that uses the email address to determine the agent to route the email to\n * @param defaultAgentName The default agent name to use if the email address does not contain a sub-address\n * @returns A function that resolves the agent to route the email to\n */\nexport function createAddressBasedEmailResolver<Env>(\n defaultAgentName: string\n): EmailResolver<Env> {\n return async (email: ForwardableEmailMessage, _env: Env) => {\n // Length limits per RFC 5321: local part max 64 chars, domain max 253 chars\n const emailMatch = email.to.match(\n /^([^+@]{1,64})(?:\\+([^@]{1,64}))?@(.{1,253})$/\n );\n if (!emailMatch) {\n return null;\n }\n\n const [, localPart, subAddress] = emailMatch;\n\n if (subAddress) {\n return {\n agentName: localPart,\n agentId: subAddress\n };\n }\n\n // Option 2: Use defaultAgentName namespace, localPart as agentId\n // Common for catch-all email routing to a single EmailAgent namespace\n return {\n agentName: defaultAgentName,\n agentId: localPart\n };\n };\n}\n\n/**\n * Create a resolver that uses the agentName and agentId to determine the agent to route the email to\n * @param agentName The name of the agent to route the email to\n * @param agentId The id of the agent to route the email to\n * @returns A function that resolves the agent to route the email to\n */\nexport function createCatchAllEmailResolver<Env>(\n agentName: string,\n agentId: string\n): EmailResolver<Env> {\n return async () => ({ agentName, agentId });\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAqCA,SAAgB,iBAAiB,SAAiC;AAChE,QAAO,QAAQ,MAAM,MAAM;EACzB,MAAM,MAAM,EAAE,IAAI,aAAa;EAC/B,MAAM,QAAQ,EAAE,MAAM,aAAa;AAInC,MAAI,QAAQ,iBACV,QAAO,UAAU;AAInB,MAAI,QAAQ,2BACV,QAAO;AAIT,MAAI,QAAQ,aACV,QAAO,UAAU,UAAU,UAAU,UAAU,UAAU;AAG3D,SAAO;GACP;;;AAQJ,MAAa,0BAA0B,MAAU,KAAK;;AAGtD,MAAM,yBAAyB;;;;;;;;;AAU/B,eAAe,sBACb,QACA,WACA,SACA,WACiB;CACjB,MAAM,UAAU,IAAI,aAAa;CACjC,MAAM,MAAM,MAAM,OAAO,OAAO,UAC9B,OACA,QAAQ,OAAO,OAAO,EACtB;EAAE,MAAM;EAAQ,MAAM;EAAW,EACjC,OACA,CAAC,OAAO,CACT;CACD,MAAM,OAAO,QAAQ,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,YAAY;CACnE,MAAM,YAAY,MAAM,OAAO,OAAO,KAAK,QAAQ,KAAK,KAAK;AAC7D,QAAO,KAAK,OAAO,aAAa,GAAG,IAAI,WAAW,UAAU,CAAC,CAAC;;;;;;;;;;;;AAoBhE,eAAe,qBACb,QACA,WACA,SACA,WACA,WACA,gBAAwB,yBACc;AACtC,KAAI;EAEF,MAAM,eAAe,OAAO,SAAS,WAAW,GAAG;AACnD,MAAI,OAAO,MAAM,aAAa,CAC5B,QAAO;GAAE,OAAO;GAAO,QAAQ;GAAuB;EAIxD,MAAM,MAAM,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK;AAGzC,MAAI,eAAe,MAAM,uBACvB,QAAO;GAAE,OAAO;GAAO,QAAQ;GAAW;AAI5C,MAAI,MAAM,eAAe,cACvB,QAAO;GAAE,OAAO;GAAO,QAAQ;GAAW;EAG5C,MAAM,WAAW,MAAM,sBACrB,QACA,WACA,SACA,UACD;AAED,MAAI,SAAS,WAAW,UAAU,OAChC,QAAO;GAAE,OAAO;GAAO,QAAQ;GAAW;EAE5C,IAAI,SAAS;AACb,OAAK,IAAI,IAAI,GAAG,IAAI,SAAS,QAAQ,IACnC,WAAU,SAAS,WAAW,EAAE,GAAG,UAAU,WAAW,EAAE;AAE5D,MAAI,WAAW,EACb,QAAO;GAAE,OAAO;GAAO,QAAQ;GAAW;AAE5C,SAAO,EAAE,OAAO,MAAM;UACf,OAAO;AACd,UAAQ,KAAK,0CAA0C,MAAM;AAC7D,SAAO;GAAE,OAAO;GAAO,QAAQ;GAAW;;;;;;;;;;;;;;;;;;AAmB9C,eAAsB,iBACpB,QACA,WACA,SACiC;AACjC,KAAI,CAAC,OACH,OAAM,IAAI,MAAM,+CAA+C;AAEjE,KAAI,CAAC,UACH,OAAM,IAAI,MAAM,kDAAkD;AAEpE,KAAI,CAAC,QACH,OAAM,IAAI,MAAM,gDAAgD;AAIlE,KAAI,UAAU,SAAS,IAAI,CACzB,OAAM,IAAI,MAAM,kCAAkC;AAEpD,KAAI,QAAQ,SAAS,IAAI,CACvB,OAAM,IAAI,MAAM,gCAAgC;CAGlD,MAAM,YAAY,KAAK,MAAM,KAAK,KAAK,GAAG,IAAK,CAAC,UAAU;CAC1D,MAAM,YAAY,MAAM,sBACtB,QACA,WACA,SACA,UACD;AACD,QAAO;EACL,gBAAgB;EAChB,cAAc;EACd,eAAe;EACf,kBAAkB;EACnB;;;;;;AAoDH,SAAgB,iCAA0D;AACxE,OAAM,IAAI,MACR,saAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCH,SAAgB,+BACd,QACA,SACoB;AACpB,KAAI,CAAC,OACH,OAAM,IAAI,MAAM,wDAAwD;CAG1E,MAAM,SAAS,SAAS,UAAU;CAClC,MAAM,qBAAqB,SAAS;AAEpC,QAAO,OAAO,OAAgC,SAAc;EAC1D,MAAM,YAAY,MAAM,QAAQ,IAAI,eAAe;EACnD,MAAM,UAAU,MAAM,QAAQ,IAAI,aAAa;EAC/C,MAAM,YAAY,MAAM,QAAQ,IAAI,cAAc;EAClD,MAAM,YAAY,MAAM,QAAQ,IAAI,iBAAiB;AAErD,MAAI,CAAC,aAAa,CAAC,WAAW,CAAC,aAAa,CAAC,WAAW;AACtD,wBAAqB,OAAO,kBAAkB;AAC9C,UAAO;;EAGT,MAAM,SAAS,MAAM,qBACnB,QACA,WACA,SACA,WACA,WACA,OACD;AAED,MAAI,CAAC,OAAO,OAAO;AACjB,wBAAqB,OAAO,OAAO,OAAO;AAC1C,UAAO;;AAGT,SAAO;GAAE;GAAW;GAAS,eAAe;GAAM;;;;;;;;AAStD,SAAgB,gCACd,kBACoB;AACpB,QAAO,OAAO,OAAgC,SAAc;EAE1D,MAAM,aAAa,MAAM,GAAG,MAC1B,gDACD;AACD,MAAI,CAAC,WACH,QAAO;EAGT,MAAM,GAAG,WAAW,cAAc;AAElC,MAAI,WACF,QAAO;GACL,WAAW;GACX,SAAS;GACV;AAKH,SAAO;GACL,WAAW;GACX,SAAS;GACV;;;;;;;;;AAUL,SAAgB,4BACd,WACA,SACoB;AACpB,QAAO,aAAa;EAAE;EAAW;EAAS"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,27 +1,32 @@
|
|
|
1
|
-
import { n as AgentEmail } from "./internal_context-CEu5ji80.js";
|
|
2
1
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
} from "./
|
|
2
|
+
AgentEmail,
|
|
3
|
+
__DO_NOT_USE_WILL_BREAK__agentContext
|
|
4
|
+
} from "./internal_context.js";
|
|
5
|
+
import { EmailResolver, createHeaderBasedEmailResolver } from "./email.js";
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
} from "./client-DV1CZKqa.js";
|
|
7
|
+
l as TransportType,
|
|
8
|
+
r as MCPConnectionState
|
|
9
|
+
} from "./client-storage-Cvy5r9FG.js";
|
|
11
10
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
11
|
+
AgentMcpOAuthProvider,
|
|
12
|
+
AgentsOAuthProvider
|
|
13
|
+
} from "./mcp/do-oauth-client-provider.js";
|
|
14
|
+
import { MCPClientManager } from "./mcp/client.js";
|
|
15
|
+
import {
|
|
16
|
+
RunWorkflowOptions,
|
|
17
|
+
WorkflowCallback,
|
|
18
|
+
WorkflowEventPayload,
|
|
19
|
+
WorkflowInfo,
|
|
20
|
+
WorkflowPage,
|
|
21
|
+
WorkflowQueryCriteria
|
|
22
|
+
} from "./workflow-types.js";
|
|
23
|
+
import { Observability } from "./observability/index.js";
|
|
24
|
+
import { MessageType } from "./types.js";
|
|
21
25
|
import {
|
|
22
26
|
Connection,
|
|
23
27
|
Connection as Connection$1,
|
|
24
28
|
ConnectionContext,
|
|
29
|
+
ConnectionContext as ConnectionContext$1,
|
|
25
30
|
PartyServerOptions,
|
|
26
31
|
Server,
|
|
27
32
|
WSMessage
|
|
@@ -77,7 +82,7 @@ type RPCResponse = {
|
|
|
77
82
|
* Metadata for a callable method
|
|
78
83
|
*/
|
|
79
84
|
type CallableMetadata = {
|
|
80
|
-
/** Optional description of what the method does */ description?: string
|
|
85
|
+
/** Optional description of what the method does */ description?: string /** Whether the method supports streaming responses */;
|
|
81
86
|
streaming?: boolean;
|
|
82
87
|
};
|
|
83
88
|
/**
|
|
@@ -96,7 +101,7 @@ declare function callable(
|
|
|
96
101
|
metadata?: CallableMetadata
|
|
97
102
|
): <This, Args extends unknown[], Return>(
|
|
98
103
|
target: (this: This, ...args: Args) => Return,
|
|
99
|
-
|
|
104
|
+
_context: ClassMethodDecoratorContext
|
|
100
105
|
) => (this: This, ...args: Args) => Return;
|
|
101
106
|
/**
|
|
102
107
|
* Decorator that marks a method as callable by clients
|
|
@@ -107,7 +112,7 @@ declare const unstable_callable: (
|
|
|
107
112
|
metadata?: CallableMetadata
|
|
108
113
|
) => <This, Args extends unknown[], Return>(
|
|
109
114
|
target: (this: This, ...args: Args) => Return,
|
|
110
|
-
|
|
115
|
+
_context: ClassMethodDecoratorContext
|
|
111
116
|
) => (this: This, ...args: Args) => Return;
|
|
112
117
|
type QueueItem<T = string> = {
|
|
113
118
|
id: string;
|
|
@@ -120,27 +125,27 @@ type QueueItem<T = string> = {
|
|
|
120
125
|
* @template T Type of the payload data
|
|
121
126
|
*/
|
|
122
127
|
type Schedule<T = string> = {
|
|
123
|
-
/** Unique identifier for the schedule */ id: string
|
|
124
|
-
callback: string
|
|
128
|
+
/** Unique identifier for the schedule */ id: string /** Name of the method to be called */;
|
|
129
|
+
callback: string /** Data to be passed to the callback */;
|
|
125
130
|
payload: T;
|
|
126
131
|
} & (
|
|
127
132
|
| {
|
|
128
|
-
/** Type of schedule for one-time execution at a specific time */ type: "scheduled"
|
|
133
|
+
/** Type of schedule for one-time execution at a specific time */ type: "scheduled" /** Timestamp when the task should execute */;
|
|
129
134
|
time: number;
|
|
130
135
|
}
|
|
131
136
|
| {
|
|
132
|
-
/** Type of schedule for delayed execution */ type: "delayed"
|
|
133
|
-
time: number
|
|
137
|
+
/** Type of schedule for delayed execution */ type: "delayed" /** Timestamp when the task should execute */;
|
|
138
|
+
time: number /** Number of seconds to delay execution */;
|
|
134
139
|
delayInSeconds: number;
|
|
135
140
|
}
|
|
136
141
|
| {
|
|
137
|
-
/** Type of schedule for recurring execution based on cron expression */ type: "cron"
|
|
138
|
-
time: number
|
|
142
|
+
/** Type of schedule for recurring execution based on cron expression */ type: "cron" /** Timestamp for the next execution */;
|
|
143
|
+
time: number /** Cron expression defining the schedule */;
|
|
139
144
|
cron: string;
|
|
140
145
|
}
|
|
141
146
|
| {
|
|
142
|
-
/** Type of schedule for recurring execution at fixed intervals */ type: "interval"
|
|
143
|
-
time: number
|
|
147
|
+
/** Type of schedule for recurring execution at fixed intervals */ type: "interval" /** Timestamp for the next execution */;
|
|
148
|
+
time: number /** Number of seconds between executions */;
|
|
144
149
|
intervalSeconds: number;
|
|
145
150
|
}
|
|
146
151
|
);
|
|
@@ -178,11 +183,19 @@ type MCPServer = {
|
|
|
178
183
|
* Options for adding an MCP server
|
|
179
184
|
*/
|
|
180
185
|
type AddMcpServerOptions = {
|
|
181
|
-
/** OAuth callback host (auto-derived from request if omitted) */ callbackHost?: string;
|
|
182
|
-
|
|
183
|
-
|
|
186
|
+
/** OAuth callback host (auto-derived from request if omitted) */ callbackHost?: string;
|
|
187
|
+
/**
|
|
188
|
+
* Custom callback URL path — bypasses the default `/agents/{class}/{name}/callback` construction.
|
|
189
|
+
* Required when `sendIdentityOnConnect` is `false` to prevent leaking the instance name.
|
|
190
|
+
* When set, the callback URL becomes `{callbackHost}/{callbackPath}`.
|
|
191
|
+
* The developer must route this path to the agent instance via `getAgentByName`.
|
|
192
|
+
* Should be a plain path (e.g., `/mcp-callback`) — do not include query strings or fragments.
|
|
193
|
+
*/
|
|
194
|
+
callbackPath?: string /** Agents routing prefix (default: "agents") */;
|
|
195
|
+
agentsPrefix?: string /** MCP client options */;
|
|
196
|
+
client?: ConstructorParameters<typeof Client>[1] /** Transport options */;
|
|
184
197
|
transport?: {
|
|
185
|
-
/** Custom headers for authentication (e.g., bearer tokens, CF Access) */ headers?: HeadersInit
|
|
198
|
+
/** Custom headers for authentication (e.g., bearer tokens, CF Access) */ headers?: HeadersInit /** Transport type: "sse", "streamable-http", or "auto" (default) */;
|
|
186
199
|
type?: TransportType;
|
|
187
200
|
};
|
|
188
201
|
};
|
|
@@ -191,7 +204,7 @@ type AddMcpServerOptions = {
|
|
|
191
204
|
* Child classes can override specific options without spreading.
|
|
192
205
|
*/
|
|
193
206
|
declare const DEFAULT_AGENT_STATIC_OPTIONS: {
|
|
194
|
-
/** Whether the Agent should hibernate when inactive */ hibernate: boolean
|
|
207
|
+
/** Whether the Agent should hibernate when inactive */ hibernate: boolean /** Whether to send identity (name, agent) to clients on connect */;
|
|
195
208
|
sendIdentityOnConnect: boolean;
|
|
196
209
|
/**
|
|
197
210
|
* Timeout in seconds before a running interval schedule is considered "hung"
|
|
@@ -242,6 +255,19 @@ declare class Agent<
|
|
|
242
255
|
private _state;
|
|
243
256
|
private _disposables;
|
|
244
257
|
private _destroyed;
|
|
258
|
+
/**
|
|
259
|
+
* Stores raw state accessors for wrapped connections.
|
|
260
|
+
* Used by setConnectionReadonly/isConnectionReadonly to read/write the
|
|
261
|
+
* _cf_readonly flag without going through the user-facing state/setState.
|
|
262
|
+
*/
|
|
263
|
+
private _rawStateAccessors;
|
|
264
|
+
/**
|
|
265
|
+
* Cached persistence-hook dispatch mode, computed once in the constructor.
|
|
266
|
+
* - "new" → call onStateChanged
|
|
267
|
+
* - "old" → call onStateUpdate (deprecated)
|
|
268
|
+
* - "none" → neither hook is overridden, skip entirely
|
|
269
|
+
*/
|
|
270
|
+
private _persistenceHookMode;
|
|
245
271
|
private _ParentClass;
|
|
246
272
|
readonly mcp: MCPClientManager;
|
|
247
273
|
/**
|
|
@@ -290,8 +316,39 @@ declare class Agent<
|
|
|
290
316
|
/**
|
|
291
317
|
* Update the Agent's state
|
|
292
318
|
* @param state New state to set
|
|
319
|
+
* @throws Error if called from a readonly connection context
|
|
293
320
|
*/
|
|
294
321
|
setState(state: State): void;
|
|
322
|
+
/**
|
|
323
|
+
* Wraps connection.state and connection.setState so that the internal
|
|
324
|
+
* _cf_readonly flag is hidden from user code and cannot be accidentally
|
|
325
|
+
* overwritten. Must be called before any user code sees the connection.
|
|
326
|
+
*
|
|
327
|
+
* Idempotent — safe to call multiple times on the same connection.
|
|
328
|
+
*/
|
|
329
|
+
private _ensureConnectionWrapped;
|
|
330
|
+
/**
|
|
331
|
+
* Mark a connection as readonly or readwrite
|
|
332
|
+
* @param connection The connection to mark
|
|
333
|
+
* @param readonly Whether the connection should be readonly (default: true)
|
|
334
|
+
*/
|
|
335
|
+
setConnectionReadonly(connection: Connection$1, readonly?: boolean): void;
|
|
336
|
+
/**
|
|
337
|
+
* Check if a connection is marked as readonly
|
|
338
|
+
* @param connection The connection to check
|
|
339
|
+
* @returns True if the connection is readonly
|
|
340
|
+
*/
|
|
341
|
+
isConnectionReadonly(connection: Connection$1): boolean;
|
|
342
|
+
/**
|
|
343
|
+
* Override this method to determine if a connection should be readonly on connect
|
|
344
|
+
* @param _connection The connection that is being established
|
|
345
|
+
* @param _ctx Connection context
|
|
346
|
+
* @returns True if the connection should be readonly
|
|
347
|
+
*/
|
|
348
|
+
shouldConnectionBeReadonly(
|
|
349
|
+
_connection: Connection$1,
|
|
350
|
+
_ctx: ConnectionContext$1
|
|
351
|
+
): boolean;
|
|
295
352
|
/**
|
|
296
353
|
* Called before the Agent's state is persisted and broadcast.
|
|
297
354
|
* Override to validate or reject an update by throwing an error.
|
|
@@ -300,7 +357,25 @@ declare class Agent<
|
|
|
300
357
|
*/
|
|
301
358
|
validateStateChange(nextState: State, source: Connection$1 | "server"): void;
|
|
302
359
|
/**
|
|
303
|
-
* Called
|
|
360
|
+
* Called after the Agent's state has been persisted and broadcast to all clients.
|
|
361
|
+
* This is a notification hook — errors here are routed to onError and do not
|
|
362
|
+
* affect state persistence or client broadcasts.
|
|
363
|
+
*
|
|
364
|
+
* @param state Updated state
|
|
365
|
+
* @param source Source of the state update ("server" or a client connection)
|
|
366
|
+
*/
|
|
367
|
+
onStateChanged(
|
|
368
|
+
state: State | undefined,
|
|
369
|
+
source: Connection$1 | "server"
|
|
370
|
+
): void;
|
|
371
|
+
/**
|
|
372
|
+
* @deprecated Renamed to `onStateChanged` — the behavior is identical.
|
|
373
|
+
* `onStateUpdate` will be removed in the next major version.
|
|
374
|
+
*
|
|
375
|
+
* Called after the Agent's state has been persisted and broadcast to all clients.
|
|
376
|
+
* This is a server-side notification hook. For the client-side state callback,
|
|
377
|
+
* see the `onStateUpdate` option in `useAgent` / `AgentClient`.
|
|
378
|
+
*
|
|
304
379
|
* @param state Updated state
|
|
305
380
|
* @param source Source of the state update ("server" or a client connection)
|
|
306
381
|
*/
|
|
@@ -308,6 +383,11 @@ declare class Agent<
|
|
|
308
383
|
state: State | undefined,
|
|
309
384
|
source: Connection$1 | "server"
|
|
310
385
|
): void;
|
|
386
|
+
/**
|
|
387
|
+
* Dispatch to the appropriate persistence hook based on the mode
|
|
388
|
+
* cached in the constructor. No prototype walks at call time.
|
|
389
|
+
*/
|
|
390
|
+
private _callStatePersistenceHook;
|
|
311
391
|
/**
|
|
312
392
|
* Called when the Agent receives an email via routeAgentEmail()
|
|
313
393
|
* Override this method to handle incoming emails
|
|
@@ -883,6 +963,29 @@ declare class Agent<
|
|
|
883
963
|
>;
|
|
884
964
|
removeMcpServer(id: string): Promise<void>;
|
|
885
965
|
getMcpServers(): MCPServersState;
|
|
966
|
+
/**
|
|
967
|
+
* Create the OAuth provider used when connecting to MCP servers that require authentication.
|
|
968
|
+
*
|
|
969
|
+
* Override this method in a subclass to supply a custom OAuth provider implementation,
|
|
970
|
+
* for example to use pre-registered client credentials, mTLS-based authentication,
|
|
971
|
+
* or any other OAuth flow beyond dynamic client registration.
|
|
972
|
+
*
|
|
973
|
+
* @example
|
|
974
|
+
* // Custom OAuth provider
|
|
975
|
+
* class MyAgent extends Agent {
|
|
976
|
+
* createMcpOAuthProvider(callbackUrl: string): AgentMcpOAuthProvider {
|
|
977
|
+
* return new MyCustomOAuthProvider(
|
|
978
|
+
* this.ctx.storage,
|
|
979
|
+
* this.name,
|
|
980
|
+
* callbackUrl
|
|
981
|
+
* );
|
|
982
|
+
* }
|
|
983
|
+
* }
|
|
984
|
+
*
|
|
985
|
+
* @param callbackUrl The OAuth callback URL for the authorization flow
|
|
986
|
+
* @returns An {@link AgentMcpOAuthProvider} instance used by {@link addMcpServer}
|
|
987
|
+
*/
|
|
988
|
+
createMcpOAuthProvider(callbackUrl: string): AgentMcpOAuthProvider;
|
|
886
989
|
private broadcastMcpServers;
|
|
887
990
|
/**
|
|
888
991
|
* Handle MCP OAuth callback request if it's an OAuth callback.
|
|
@@ -920,12 +1023,7 @@ type AgentContext = DurableObjectState;
|
|
|
920
1023
|
/**
|
|
921
1024
|
* Configuration options for Agent routing
|
|
922
1025
|
*/
|
|
923
|
-
type AgentOptions<Env> = PartyServerOptions<Env
|
|
924
|
-
/**
|
|
925
|
-
* Whether to enable CORS for the Agent
|
|
926
|
-
*/
|
|
927
|
-
cors?: boolean | HeadersInit | undefined;
|
|
928
|
-
};
|
|
1026
|
+
type AgentOptions<Env> = PartyServerOptions<Env>;
|
|
929
1027
|
/**
|
|
930
1028
|
* Route a request to the appropriate Agent
|
|
931
1029
|
* @param request Request to route
|
|
@@ -1017,9 +1115,11 @@ export {
|
|
|
1017
1115
|
AddMcpServerOptions,
|
|
1018
1116
|
Agent,
|
|
1019
1117
|
AgentContext,
|
|
1118
|
+
type AgentMcpOAuthProvider,
|
|
1020
1119
|
AgentNamespace,
|
|
1021
1120
|
AgentOptions,
|
|
1022
1121
|
AgentStaticOptions,
|
|
1122
|
+
type AgentsOAuthProvider,
|
|
1023
1123
|
CallableMetadata,
|
|
1024
1124
|
type Connection,
|
|
1025
1125
|
type ConnectionContext,
|
|
@@ -1037,6 +1137,7 @@ export {
|
|
|
1037
1137
|
StreamingResponse,
|
|
1038
1138
|
type TransportType,
|
|
1039
1139
|
type WSMessage,
|
|
1140
|
+
__DO_NOT_USE_WILL_BREAK__agentContext,
|
|
1040
1141
|
callable,
|
|
1041
1142
|
createHeaderBasedEmailResolver,
|
|
1042
1143
|
getAgentByName,
|