agents 0.0.0-d4257c1 → 0.0.0-d520fe8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +5 -3
  2. package/dist/ai-chat-agent.d.ts +86 -13
  3. package/dist/ai-chat-agent.js +340 -74
  4. package/dist/ai-chat-agent.js.map +1 -1
  5. package/dist/{ai-chat-v5-migration-gdyLiTd8.js → ai-chat-v5-migration-BSiGZmYU.js} +2 -2
  6. package/dist/{ai-chat-v5-migration-gdyLiTd8.js.map → ai-chat-v5-migration-BSiGZmYU.js.map} +1 -1
  7. package/dist/ai-chat-v5-migration.js +1 -1
  8. package/dist/ai-react.d.ts +14 -9
  9. package/dist/ai-react.js +172 -36
  10. package/dist/ai-react.js.map +1 -1
  11. package/dist/{ai-types-BWW4umHY.d.ts → ai-types-81H_-Uxh.d.ts} +16 -8
  12. package/dist/{ai-types-UZlfLOYP.js → ai-types-CrMqkwc_.js} +6 -2
  13. package/dist/ai-types-CrMqkwc_.js.map +1 -0
  14. package/dist/ai-types.d.ts +4 -4
  15. package/dist/ai-types.js +1 -1
  16. package/dist/cli.d.ts +8 -0
  17. package/dist/cli.js +27 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/{client-DjR-lC16.js → client-B3SR12TQ.js} +3 -3
  20. package/dist/{client-DjR-lC16.js.map → client-B3SR12TQ.js.map} +1 -1
  21. package/dist/{client-CmMi85Sj.d.ts → client-BAQA84dr.d.ts} +10 -10
  22. package/dist/client-BZq9qau2.js +1093 -0
  23. package/dist/client-BZq9qau2.js.map +1 -0
  24. package/dist/client-CsaP9Irq.d.ts +1528 -0
  25. package/dist/client.d.ts +8 -8
  26. package/dist/client.js +2 -2
  27. package/dist/codemode/ai.js +5 -5
  28. package/dist/{do-oauth-client-provider-CCwGwnrA.d.ts → do-oauth-client-provider-C2CHH5x-.d.ts} +2 -2
  29. package/dist/{do-oauth-client-provider-B2jr6UNq.js → do-oauth-client-provider-CwqK5SXm.js} +3 -2
  30. package/dist/do-oauth-client-provider-CwqK5SXm.js.map +1 -0
  31. package/dist/{index-W4JUkafc.d.ts → index-BUle9RiP.d.ts} +7 -3
  32. package/dist/{index-CkQU40oY.d.ts → index-Bx5KK3VJ.d.ts} +75 -46
  33. package/dist/index.d.ts +36 -36
  34. package/dist/index.js +5 -5
  35. package/dist/mcp/client.d.ts +4 -4
  36. package/dist/mcp/client.js +2 -1
  37. package/dist/mcp/do-oauth-client-provider.d.ts +1 -1
  38. package/dist/mcp/do-oauth-client-provider.js +1 -1
  39. package/dist/mcp/index.d.ts +129 -11
  40. package/dist/mcp/index.js +632 -32
  41. package/dist/mcp/index.js.map +1 -1
  42. package/dist/mcp/x402.js +10 -6
  43. package/dist/mcp/x402.js.map +1 -1
  44. package/dist/{mcp-BEwaCsxO.d.ts → mcp-BwPscEiF.d.ts} +2 -2
  45. package/dist/observability/index.d.ts +2 -2
  46. package/dist/observability/index.js +5 -5
  47. package/dist/{react-B4e1rDid.d.ts → react-CbwD4fBf.d.ts} +17 -17
  48. package/dist/react.d.ts +9 -9
  49. package/dist/react.js +2 -2
  50. package/dist/react.js.map +1 -1
  51. package/dist/{serializable-gtr9YMhp.d.ts → serializable-faDkMCai.d.ts} +8 -3
  52. package/dist/serializable.d.ts +5 -5
  53. package/dist/{src-COfG--3R.js → src-D_KKH_4c.js} +125 -120
  54. package/dist/src-D_KKH_4c.js.map +1 -0
  55. package/package.json +55 -40
  56. package/dist/ai-types-UZlfLOYP.js.map +0 -1
  57. package/dist/client-C-nwz-3N.d.ts +0 -5313
  58. package/dist/client-CZBVDDoO.js +0 -786
  59. package/dist/client-CZBVDDoO.js.map +0 -1
  60. package/dist/do-oauth-client-provider-B2jr6UNq.js.map +0 -1
  61. package/dist/src-COfG--3R.js.map +0 -1
  62. package/src/index.ts +0 -2031
@@ -1,6 +1,6 @@
1
- import { Agent, MCPServersState } from "./index-CkQU40oY.js";
2
- import { Method, RPCMethod } from "./serializable-gtr9YMhp.js";
3
- import { StreamOptions } from "./client-CmMi85Sj.js";
1
+ import { m as MCPServersState, t as Agent } from "./index-Bx5KK3VJ.js";
2
+ import { n as RPCMethod, t as Method } from "./serializable-faDkMCai.js";
3
+ import { i as StreamOptions } from "./client-BAQA84dr.js";
4
4
  import { PartySocket } from "partysocket";
5
5
  import { usePartySocket } from "partysocket/react";
6
6
 
@@ -51,24 +51,24 @@ type RequiredAgentMethods<T> = Omit<
51
51
  AgentMethods<T>,
52
52
  keyof OptionalAgentMethods<T>
53
53
  >;
54
- type AgentPromiseReturnType<T, K extends keyof AgentMethods<T>> =
55
- ReturnType<AgentMethods<T>[K]> extends Promise<any>
56
- ? ReturnType<AgentMethods<T>[K]>
57
- : Promise<ReturnType<AgentMethods<T>[K]>>;
54
+ type AgentPromiseReturnType<T, K$1 extends keyof AgentMethods<T>> =
55
+ ReturnType<AgentMethods<T>[K$1]> extends Promise<any>
56
+ ? ReturnType<AgentMethods<T>[K$1]>
57
+ : Promise<ReturnType<AgentMethods<T>[K$1]>>;
58
58
  type OptionalArgsAgentMethodCall<AgentT> = <
59
- K extends keyof OptionalAgentMethods<AgentT>
59
+ K$1 extends keyof OptionalAgentMethods<AgentT>
60
60
  >(
61
- method: K,
62
- args?: Parameters<OptionalAgentMethods<AgentT>[K]>,
61
+ method: K$1,
62
+ args?: Parameters<OptionalAgentMethods<AgentT>[K$1]>,
63
63
  streamOptions?: StreamOptions
64
- ) => AgentPromiseReturnType<AgentT, K>;
64
+ ) => AgentPromiseReturnType<AgentT, K$1>;
65
65
  type RequiredArgsAgentMethodCall<AgentT> = <
66
- K extends keyof RequiredAgentMethods<AgentT>
66
+ K$1 extends keyof RequiredAgentMethods<AgentT>
67
67
  >(
68
- method: K,
69
- args: Parameters<RequiredAgentMethods<AgentT>[K]>,
68
+ method: K$1,
69
+ args: Parameters<RequiredAgentMethods<AgentT>[K$1]>,
70
70
  streamOptions?: StreamOptions
71
- ) => AgentPromiseReturnType<AgentT, K>;
71
+ ) => AgentPromiseReturnType<AgentT, K$1>;
72
72
  type AgentMethodCall<AgentT> = OptionalArgsAgentMethodCall<AgentT> &
73
73
  RequiredArgsAgentMethodCall<AgentT>;
74
74
  type UntypedAgentMethodCall = <T = unknown>(
@@ -109,5 +109,5 @@ declare function useAgent<
109
109
  stub: AgentStub<AgentT>;
110
110
  };
111
111
  //#endregion
112
- export { UseAgentOptions, useAgent };
113
- //# sourceMappingURL=react-B4e1rDid.d.ts.map
112
+ export { useAgent as n, UseAgentOptions as t };
113
+ //# sourceMappingURL=react-CbwD4fBf.d.ts.map
package/dist/react.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import "./client-C-nwz-3N.js";
2
- import "./mcp-BEwaCsxO.js";
3
- import "./do-oauth-client-provider-CCwGwnrA.js";
4
- import "./index-W4JUkafc.js";
5
- import "./ai-types-BWW4umHY.js";
6
- import "./index-CkQU40oY.js";
7
- import "./serializable-gtr9YMhp.js";
8
- import "./client-CmMi85Sj.js";
9
- import { UseAgentOptions, useAgent } from "./react-B4e1rDid.js";
1
+ import "./client-CsaP9Irq.js";
2
+ import "./mcp-BwPscEiF.js";
3
+ import "./do-oauth-client-provider-C2CHH5x-.js";
4
+ import "./index-BUle9RiP.js";
5
+ import "./ai-types-81H_-Uxh.js";
6
+ import "./index-Bx5KK3VJ.js";
7
+ import "./serializable-faDkMCai.js";
8
+ import "./client-BAQA84dr.js";
9
+ import { n as useAgent, t as UseAgentOptions } from "./react-CbwD4fBf.js";
10
10
  export { UseAgentOptions, useAgent };
package/dist/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { MessageType } from "./ai-types-UZlfLOYP.js";
1
+ import { t as MessageType } from "./ai-types-CrMqkwc_.js";
2
2
  import { use, useCallback, useEffect, useMemo, useRef } from "react";
3
3
  import { usePartySocket } from "partysocket/react";
4
4
 
@@ -61,7 +61,7 @@ function createCacheKey(agentNamespace, name, deps) {
61
61
  }
62
62
  function useAgent(options) {
63
63
  const agentNamespace = camelCaseToKebabCase(options.agent);
64
- const { query, queryDeps, cacheTtl,...restOptions } = options;
64
+ const { query, queryDeps, cacheTtl, ...restOptions } = options;
65
65
  const pendingCallsRef = useRef(/* @__PURE__ */ new Map());
66
66
  const cacheKey = useMemo(() => {
67
67
  const deps = queryDeps || [];
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","names":["resolvedQuery: QueryObject | undefined","parsedMessage: Record<string, unknown>","request: RPCRequest"],"sources":["../src/react.tsx"],"sourcesContent":["import type { PartySocket } from \"partysocket\";\nimport { usePartySocket } from \"partysocket/react\";\nimport { useCallback, useRef, use, useMemo, useEffect } from \"react\";\nimport type { Agent, MCPServersState, RPCRequest, RPCResponse } from \"./\";\nimport type { StreamOptions } from \"./client\";\nimport type { Method, RPCMethod } from \"./serializable\";\nimport { MessageType } from \"./ai-types\";\n\n/**\n * Convert a camelCase string to a kebab-case string\n * @param str The string to convert\n * @returns The kebab-case string\n */\nfunction camelCaseToKebabCase(str: string): string {\n // If string is all uppercase, convert to lowercase\n if (str === str.toUpperCase() && str !== str.toLowerCase()) {\n return str.toLowerCase().replace(/_/g, \"-\");\n }\n\n // Otherwise handle camelCase to kebab-case\n let kebabified = str.replace(\n /[A-Z]/g,\n (letter) => `-${letter.toLowerCase()}`\n );\n kebabified = kebabified.startsWith(\"-\") ? kebabified.slice(1) : kebabified;\n // Convert any remaining underscores to hyphens and remove trailing -'s\n return kebabified.replace(/_/g, \"-\").replace(/-$/, \"\");\n}\n\ntype QueryObject = Record<string, string | null>;\n\nconst queryCache = new Map<\n unknown[],\n {\n promise: Promise<QueryObject>;\n refCount: number;\n expiresAt: number;\n cacheTtl?: number;\n }\n>();\n\nfunction arraysEqual(a: unknown[], b: unknown[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) return false;\n }\n return true;\n}\n\nfunction findCacheEntry(\n targetKey: unknown[]\n): Promise<QueryObject> | undefined {\n for (const [existingKey, entry] of queryCache.entries()) {\n if (arraysEqual(existingKey, targetKey)) {\n // Check if entry has expired\n if (Date.now() > entry.expiresAt) {\n queryCache.delete(existingKey);\n return undefined;\n }\n entry.refCount++;\n return entry.promise;\n }\n }\n return undefined;\n}\n\nfunction setCacheEntry(\n key: unknown[],\n value: Promise<QueryObject>,\n cacheTtl?: number\n): void {\n // Remove any existing entry with matching members\n for (const [existingKey] of queryCache.entries()) {\n if (arraysEqual(existingKey, key)) {\n queryCache.delete(existingKey);\n break;\n }\n }\n\n const expiresAt = cacheTtl\n ? Date.now() + cacheTtl\n : Date.now() + 5 * 60 * 1000; // Default 5 minutes\n queryCache.set(key, { promise: value, refCount: 1, expiresAt, cacheTtl });\n}\n\nfunction decrementCacheEntry(targetKey: unknown[]): boolean {\n for (const [existingKey, entry] of queryCache.entries()) {\n if (arraysEqual(existingKey, targetKey)) {\n entry.refCount--;\n if (entry.refCount <= 0) {\n queryCache.delete(existingKey);\n }\n return true;\n }\n }\n return false;\n}\n\nfunction createCacheKey(\n agentNamespace: string,\n name: string | undefined,\n deps: unknown[]\n): unknown[] {\n return [agentNamespace, name || \"default\", ...deps];\n}\n\n/**\n * Options for the useAgent hook\n * @template State Type of the Agent's state\n */\nexport type UseAgentOptions<State = unknown> = Omit<\n Parameters<typeof usePartySocket>[0],\n \"party\" | \"room\" | \"query\"\n> & {\n /** Name of the agent to connect to */\n agent: string;\n /** Name of the specific Agent instance */\n name?: string;\n /** Query parameters - can be static object or async function */\n query?: QueryObject | (() => Promise<QueryObject>);\n /** Dependencies for async query caching */\n queryDeps?: unknown[];\n /** Cache TTL in milliseconds for auth tokens/time-sensitive data */\n cacheTtl?: number;\n /** Called when the Agent's state is updated */\n onStateUpdate?: (state: State, source: \"server\" | \"client\") => void;\n /** Called when MCP server state is updated */\n onMcpUpdate?: (mcpServers: MCPServersState) => void;\n};\n\ntype AllOptional<T> = T extends [infer A, ...infer R]\n ? undefined extends A\n ? AllOptional<R>\n : false\n : true; // no params means optional by default\n\ntype RPCMethods<T> = {\n [K in keyof T as T[K] extends RPCMethod<T[K]> ? K : never]: RPCMethod<T[K]>;\n};\n\ntype OptionalParametersMethod<T extends RPCMethod> =\n AllOptional<Parameters<T>> extends true ? T : never;\n\n// all methods of the Agent, excluding the ones that are declared in the base Agent class\n// biome-ignore lint: suppressions/parse\ntype AgentMethods<T> = Omit<RPCMethods<T>, keyof Agent<any, any>>;\n\ntype OptionalAgentMethods<T> = {\n [K in keyof AgentMethods<T> as AgentMethods<T>[K] extends OptionalParametersMethod<\n AgentMethods<T>[K]\n >\n ? K\n : never]: OptionalParametersMethod<AgentMethods<T>[K]>;\n};\n\ntype RequiredAgentMethods<T> = Omit<\n AgentMethods<T>,\n keyof OptionalAgentMethods<T>\n>;\n\ntype AgentPromiseReturnType<T, K extends keyof AgentMethods<T>> =\n // biome-ignore lint: suppressions/parse\n ReturnType<AgentMethods<T>[K]> extends Promise<any>\n ? ReturnType<AgentMethods<T>[K]>\n : Promise<ReturnType<AgentMethods<T>[K]>>;\n\ntype OptionalArgsAgentMethodCall<AgentT> = <\n K extends keyof OptionalAgentMethods<AgentT>\n>(\n method: K,\n args?: Parameters<OptionalAgentMethods<AgentT>[K]>,\n streamOptions?: StreamOptions\n) => AgentPromiseReturnType<AgentT, K>;\n\ntype RequiredArgsAgentMethodCall<AgentT> = <\n K extends keyof RequiredAgentMethods<AgentT>\n>(\n method: K,\n args: Parameters<RequiredAgentMethods<AgentT>[K]>,\n streamOptions?: StreamOptions\n) => AgentPromiseReturnType<AgentT, K>;\n\ntype AgentMethodCall<AgentT> = OptionalArgsAgentMethodCall<AgentT> &\n RequiredArgsAgentMethodCall<AgentT>;\n\ntype UntypedAgentMethodCall = <T = unknown>(\n method: string,\n args?: unknown[],\n streamOptions?: StreamOptions\n) => Promise<T>;\n\ntype AgentStub<T> = {\n [K in keyof AgentMethods<T>]: (\n ...args: Parameters<AgentMethods<T>[K]>\n ) => AgentPromiseReturnType<AgentMethods<T>, K>;\n};\n\n// we neet to use Method instead of RPCMethod here for retro-compatibility\ntype UntypedAgentStub = Record<string, Method>;\n\n/**\n * React hook for connecting to an Agent\n */\nexport function useAgent<State = unknown>(\n options: UseAgentOptions<State>\n): PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: UntypedAgentMethodCall;\n stub: UntypedAgentStub;\n};\nexport function useAgent<\n AgentT extends {\n get state(): State;\n },\n State\n>(\n options: UseAgentOptions<State>\n): PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: AgentMethodCall<AgentT>;\n stub: AgentStub<AgentT>;\n};\nexport function useAgent<State>(\n options: UseAgentOptions<unknown>\n): PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: UntypedAgentMethodCall | AgentMethodCall<unknown>;\n stub: UntypedAgentStub;\n} {\n const agentNamespace = camelCaseToKebabCase(options.agent);\n const { query, queryDeps, cacheTtl, ...restOptions } = options;\n\n // Keep track of pending RPC calls\n const pendingCallsRef = useRef(\n new Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n stream?: StreamOptions;\n }\n >()\n );\n\n // Handle both sync and async query patterns\n const cacheKey = useMemo(() => {\n const deps = queryDeps || [];\n return createCacheKey(agentNamespace, options.name, deps);\n }, [agentNamespace, options.name, queryDeps]);\n\n const queryPromise = useMemo(() => {\n if (!query || typeof query !== \"function\") {\n return null;\n }\n\n const existingPromise = findCacheEntry(cacheKey);\n if (existingPromise) {\n return existingPromise;\n }\n\n const promise = query().catch((error) => {\n console.error(\n `[useAgent] Query failed for agent \"${options.agent}\":`,\n error\n );\n decrementCacheEntry(cacheKey); // Remove failed promise from cache\n throw error; // Re-throw for Suspense error boundary\n });\n\n setCacheEntry(cacheKey, promise, cacheTtl);\n\n return promise;\n }, [cacheKey, query, options.agent, cacheTtl]);\n\n let resolvedQuery: QueryObject | undefined;\n\n if (query) {\n if (typeof query === \"function\") {\n // Use React's use() to resolve the promise\n const queryResult = use(queryPromise!);\n\n // Check for non-primitive values and warn\n if (queryResult) {\n for (const [key, value] of Object.entries(queryResult)) {\n if (\n value !== null &&\n value !== undefined &&\n typeof value !== \"string\" &&\n typeof value !== \"number\" &&\n typeof value !== \"boolean\"\n ) {\n console.warn(\n `[useAgent] Query parameter \"${key}\" is an object and will be converted to \"[object Object]\". ` +\n \"Query parameters should be string, number, boolean, or null.\"\n );\n }\n }\n resolvedQuery = queryResult;\n }\n } else {\n // Sync query - use directly\n resolvedQuery = query;\n }\n }\n\n // Cleanup cache on unmount\n useEffect(() => {\n return () => {\n if (queryPromise) {\n decrementCacheEntry(cacheKey);\n }\n };\n }, [cacheKey, queryPromise]);\n\n const agent = usePartySocket({\n party: agentNamespace,\n prefix: \"agents\",\n room: options.name || \"default\",\n query: resolvedQuery,\n ...restOptions,\n onMessage: (message) => {\n if (typeof message.data === \"string\") {\n let parsedMessage: Record<string, unknown>;\n try {\n parsedMessage = JSON.parse(message.data);\n } catch (_error) {\n // silently ignore invalid messages for now\n // TODO: log errors with log levels\n return options.onMessage?.(message);\n }\n if (parsedMessage.type === MessageType.CF_AGENT_STATE) {\n options.onStateUpdate?.(parsedMessage.state as State, \"server\");\n return;\n }\n if (parsedMessage.type === MessageType.CF_AGENT_MCP_SERVERS) {\n options.onMcpUpdate?.(parsedMessage.mcp as MCPServersState);\n return;\n }\n if (parsedMessage.type === MessageType.RPC) {\n const response = parsedMessage as RPCResponse;\n const pending = pendingCallsRef.current.get(response.id);\n if (!pending) return;\n\n if (!response.success) {\n pending.reject(new Error(response.error));\n pendingCallsRef.current.delete(response.id);\n pending.stream?.onError?.(response.error);\n return;\n }\n\n // Handle streaming responses\n if (\"done\" in response) {\n if (response.done) {\n pending.resolve(response.result);\n pendingCallsRef.current.delete(response.id);\n pending.stream?.onDone?.(response.result);\n } else {\n pending.stream?.onChunk?.(response.result);\n }\n } else {\n // Non-streaming response\n pending.resolve(response.result);\n pendingCallsRef.current.delete(response.id);\n }\n return;\n }\n }\n options.onMessage?.(message);\n }\n }) as PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: UntypedAgentMethodCall;\n stub: UntypedAgentStub;\n };\n // Create the call method\n const call = useCallback(\n <T = unknown,>(\n method: string,\n args: unknown[] = [],\n streamOptions?: StreamOptions\n ): Promise<T> => {\n return new Promise((resolve, reject) => {\n const id = Math.random().toString(36).slice(2);\n pendingCallsRef.current.set(id, {\n reject,\n resolve: resolve as (value: unknown) => void,\n stream: streamOptions\n });\n\n const request: RPCRequest = {\n args,\n id,\n method,\n type: MessageType.RPC\n };\n\n agent.send(JSON.stringify(request));\n });\n },\n [agent]\n );\n\n agent.setState = (state: State) => {\n agent.send(JSON.stringify({ state, type: MessageType.CF_AGENT_STATE }));\n options.onStateUpdate?.(state, \"client\");\n };\n\n agent.call = call;\n agent.agent = agentNamespace;\n agent.name = options.name || \"default\";\n // biome-ignore lint: suppressions/parse\n agent.stub = new Proxy<any>(\n {},\n {\n get: (_target, method) => {\n return (...args: unknown[]) => {\n return call(method as string, args);\n };\n }\n }\n );\n\n // warn if agent isn't in lowercase\n if (agent.agent !== agent.agent.toLowerCase()) {\n console.warn(\n `Agent name: ${agent.agent} should probably be in lowercase. Received: ${agent.agent}`\n );\n }\n\n return agent;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"react.js","names":["resolvedQuery: QueryObject | undefined","parsedMessage: Record<string, unknown>","request: RPCRequest"],"sources":["../src/react.tsx"],"sourcesContent":["import type { PartySocket } from \"partysocket\";\nimport { usePartySocket } from \"partysocket/react\";\nimport { useCallback, useRef, use, useMemo, useEffect } from \"react\";\nimport type { Agent, MCPServersState, RPCRequest, RPCResponse } from \"./\";\nimport type { StreamOptions } from \"./client\";\nimport type { Method, RPCMethod } from \"./serializable\";\nimport { MessageType } from \"./ai-types\";\n\n/**\n * Convert a camelCase string to a kebab-case string\n * @param str The string to convert\n * @returns The kebab-case string\n */\nfunction camelCaseToKebabCase(str: string): string {\n // If string is all uppercase, convert to lowercase\n if (str === str.toUpperCase() && str !== str.toLowerCase()) {\n return str.toLowerCase().replace(/_/g, \"-\");\n }\n\n // Otherwise handle camelCase to kebab-case\n let kebabified = str.replace(\n /[A-Z]/g,\n (letter) => `-${letter.toLowerCase()}`\n );\n kebabified = kebabified.startsWith(\"-\") ? kebabified.slice(1) : kebabified;\n // Convert any remaining underscores to hyphens and remove trailing -'s\n return kebabified.replace(/_/g, \"-\").replace(/-$/, \"\");\n}\n\ntype QueryObject = Record<string, string | null>;\n\nconst queryCache = new Map<\n unknown[],\n {\n promise: Promise<QueryObject>;\n refCount: number;\n expiresAt: number;\n cacheTtl?: number;\n }\n>();\n\nfunction arraysEqual(a: unknown[], b: unknown[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n\n for (let i = 0; i < a.length; i++) {\n if (!Object.is(a[i], b[i])) return false;\n }\n return true;\n}\n\nfunction findCacheEntry(\n targetKey: unknown[]\n): Promise<QueryObject> | undefined {\n for (const [existingKey, entry] of queryCache.entries()) {\n if (arraysEqual(existingKey, targetKey)) {\n // Check if entry has expired\n if (Date.now() > entry.expiresAt) {\n queryCache.delete(existingKey);\n return undefined;\n }\n entry.refCount++;\n return entry.promise;\n }\n }\n return undefined;\n}\n\nfunction setCacheEntry(\n key: unknown[],\n value: Promise<QueryObject>,\n cacheTtl?: number\n): void {\n // Remove any existing entry with matching members\n for (const [existingKey] of queryCache.entries()) {\n if (arraysEqual(existingKey, key)) {\n queryCache.delete(existingKey);\n break;\n }\n }\n\n const expiresAt = cacheTtl\n ? Date.now() + cacheTtl\n : Date.now() + 5 * 60 * 1000; // Default 5 minutes\n queryCache.set(key, { promise: value, refCount: 1, expiresAt, cacheTtl });\n}\n\nfunction decrementCacheEntry(targetKey: unknown[]): boolean {\n for (const [existingKey, entry] of queryCache.entries()) {\n if (arraysEqual(existingKey, targetKey)) {\n entry.refCount--;\n if (entry.refCount <= 0) {\n queryCache.delete(existingKey);\n }\n return true;\n }\n }\n return false;\n}\n\nfunction createCacheKey(\n agentNamespace: string,\n name: string | undefined,\n deps: unknown[]\n): unknown[] {\n return [agentNamespace, name || \"default\", ...deps];\n}\n\n/**\n * Options for the useAgent hook\n * @template State Type of the Agent's state\n */\nexport type UseAgentOptions<State = unknown> = Omit<\n Parameters<typeof usePartySocket>[0],\n \"party\" | \"room\" | \"query\"\n> & {\n /** Name of the agent to connect to */\n agent: string;\n /** Name of the specific Agent instance */\n name?: string;\n /** Query parameters - can be static object or async function */\n query?: QueryObject | (() => Promise<QueryObject>);\n /** Dependencies for async query caching */\n queryDeps?: unknown[];\n /** Cache TTL in milliseconds for auth tokens/time-sensitive data */\n cacheTtl?: number;\n /** Called when the Agent's state is updated */\n onStateUpdate?: (state: State, source: \"server\" | \"client\") => void;\n /** Called when MCP server state is updated */\n onMcpUpdate?: (mcpServers: MCPServersState) => void;\n};\n\ntype AllOptional<T> = T extends [infer A, ...infer R]\n ? undefined extends A\n ? AllOptional<R>\n : false\n : true; // no params means optional by default\n\ntype RPCMethods<T> = {\n [K in keyof T as T[K] extends RPCMethod<T[K]> ? K : never]: RPCMethod<T[K]>;\n};\n\ntype OptionalParametersMethod<T extends RPCMethod> =\n AllOptional<Parameters<T>> extends true ? T : never;\n\n// all methods of the Agent, excluding the ones that are declared in the base Agent class\n// biome-ignore lint: suppressions/parse\ntype AgentMethods<T> = Omit<RPCMethods<T>, keyof Agent<any, any>>;\n\ntype OptionalAgentMethods<T> = {\n [K in keyof AgentMethods<T> as AgentMethods<T>[K] extends OptionalParametersMethod<\n AgentMethods<T>[K]\n >\n ? K\n : never]: OptionalParametersMethod<AgentMethods<T>[K]>;\n};\n\ntype RequiredAgentMethods<T> = Omit<\n AgentMethods<T>,\n keyof OptionalAgentMethods<T>\n>;\n\ntype AgentPromiseReturnType<T, K extends keyof AgentMethods<T>> =\n // biome-ignore lint: suppressions/parse\n ReturnType<AgentMethods<T>[K]> extends Promise<any>\n ? ReturnType<AgentMethods<T>[K]>\n : Promise<ReturnType<AgentMethods<T>[K]>>;\n\ntype OptionalArgsAgentMethodCall<AgentT> = <\n K extends keyof OptionalAgentMethods<AgentT>\n>(\n method: K,\n args?: Parameters<OptionalAgentMethods<AgentT>[K]>,\n streamOptions?: StreamOptions\n) => AgentPromiseReturnType<AgentT, K>;\n\ntype RequiredArgsAgentMethodCall<AgentT> = <\n K extends keyof RequiredAgentMethods<AgentT>\n>(\n method: K,\n args: Parameters<RequiredAgentMethods<AgentT>[K]>,\n streamOptions?: StreamOptions\n) => AgentPromiseReturnType<AgentT, K>;\n\ntype AgentMethodCall<AgentT> = OptionalArgsAgentMethodCall<AgentT> &\n RequiredArgsAgentMethodCall<AgentT>;\n\ntype UntypedAgentMethodCall = <T = unknown>(\n method: string,\n args?: unknown[],\n streamOptions?: StreamOptions\n) => Promise<T>;\n\ntype AgentStub<T> = {\n [K in keyof AgentMethods<T>]: (\n ...args: Parameters<AgentMethods<T>[K]>\n ) => AgentPromiseReturnType<AgentMethods<T>, K>;\n};\n\n// we neet to use Method instead of RPCMethod here for retro-compatibility\ntype UntypedAgentStub = Record<string, Method>;\n\n/**\n * React hook for connecting to an Agent\n */\nexport function useAgent<State = unknown>(\n options: UseAgentOptions<State>\n): PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: UntypedAgentMethodCall;\n stub: UntypedAgentStub;\n};\nexport function useAgent<\n AgentT extends {\n get state(): State;\n },\n State\n>(\n options: UseAgentOptions<State>\n): PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: AgentMethodCall<AgentT>;\n stub: AgentStub<AgentT>;\n};\nexport function useAgent<State>(\n options: UseAgentOptions<unknown>\n): PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: UntypedAgentMethodCall | AgentMethodCall<unknown>;\n stub: UntypedAgentStub;\n} {\n const agentNamespace = camelCaseToKebabCase(options.agent);\n const { query, queryDeps, cacheTtl, ...restOptions } = options;\n\n // Keep track of pending RPC calls\n const pendingCallsRef = useRef(\n new Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n stream?: StreamOptions;\n }\n >()\n );\n\n // Handle both sync and async query patterns\n const cacheKey = useMemo(() => {\n const deps = queryDeps || [];\n return createCacheKey(agentNamespace, options.name, deps);\n }, [agentNamespace, options.name, queryDeps]);\n\n const queryPromise = useMemo(() => {\n if (!query || typeof query !== \"function\") {\n return null;\n }\n\n const existingPromise = findCacheEntry(cacheKey);\n if (existingPromise) {\n return existingPromise;\n }\n\n const promise = query().catch((error) => {\n console.error(\n `[useAgent] Query failed for agent \"${options.agent}\":`,\n error\n );\n decrementCacheEntry(cacheKey); // Remove failed promise from cache\n throw error; // Re-throw for Suspense error boundary\n });\n\n setCacheEntry(cacheKey, promise, cacheTtl);\n\n return promise;\n }, [cacheKey, query, options.agent, cacheTtl]);\n\n let resolvedQuery: QueryObject | undefined;\n\n if (query) {\n if (typeof query === \"function\") {\n // Use React's use() to resolve the promise\n const queryResult = use(queryPromise!);\n\n // Check for non-primitive values and warn\n if (queryResult) {\n for (const [key, value] of Object.entries(queryResult)) {\n if (\n value !== null &&\n value !== undefined &&\n typeof value !== \"string\" &&\n typeof value !== \"number\" &&\n typeof value !== \"boolean\"\n ) {\n console.warn(\n `[useAgent] Query parameter \"${key}\" is an object and will be converted to \"[object Object]\". ` +\n \"Query parameters should be string, number, boolean, or null.\"\n );\n }\n }\n resolvedQuery = queryResult;\n }\n } else {\n // Sync query - use directly\n resolvedQuery = query;\n }\n }\n\n // Cleanup cache on unmount\n useEffect(() => {\n return () => {\n if (queryPromise) {\n decrementCacheEntry(cacheKey);\n }\n };\n }, [cacheKey, queryPromise]);\n\n const agent = usePartySocket({\n party: agentNamespace,\n prefix: \"agents\",\n room: options.name || \"default\",\n query: resolvedQuery,\n ...restOptions,\n onMessage: (message) => {\n if (typeof message.data === \"string\") {\n let parsedMessage: Record<string, unknown>;\n try {\n parsedMessage = JSON.parse(message.data);\n } catch (_error) {\n // silently ignore invalid messages for now\n // TODO: log errors with log levels\n return options.onMessage?.(message);\n }\n if (parsedMessage.type === MessageType.CF_AGENT_STATE) {\n options.onStateUpdate?.(parsedMessage.state as State, \"server\");\n return;\n }\n if (parsedMessage.type === MessageType.CF_AGENT_MCP_SERVERS) {\n options.onMcpUpdate?.(parsedMessage.mcp as MCPServersState);\n return;\n }\n if (parsedMessage.type === MessageType.RPC) {\n const response = parsedMessage as RPCResponse;\n const pending = pendingCallsRef.current.get(response.id);\n if (!pending) return;\n\n if (!response.success) {\n pending.reject(new Error(response.error));\n pendingCallsRef.current.delete(response.id);\n pending.stream?.onError?.(response.error);\n return;\n }\n\n // Handle streaming responses\n if (\"done\" in response) {\n if (response.done) {\n pending.resolve(response.result);\n pendingCallsRef.current.delete(response.id);\n pending.stream?.onDone?.(response.result);\n } else {\n pending.stream?.onChunk?.(response.result);\n }\n } else {\n // Non-streaming response\n pending.resolve(response.result);\n pendingCallsRef.current.delete(response.id);\n }\n return;\n }\n }\n options.onMessage?.(message);\n }\n }) as PartySocket & {\n agent: string;\n name: string;\n setState: (state: State) => void;\n call: UntypedAgentMethodCall;\n stub: UntypedAgentStub;\n };\n // Create the call method\n const call = useCallback(\n <T = unknown,>(\n method: string,\n args: unknown[] = [],\n streamOptions?: StreamOptions\n ): Promise<T> => {\n return new Promise((resolve, reject) => {\n const id = Math.random().toString(36).slice(2);\n pendingCallsRef.current.set(id, {\n reject,\n resolve: resolve as (value: unknown) => void,\n stream: streamOptions\n });\n\n const request: RPCRequest = {\n args,\n id,\n method,\n type: MessageType.RPC\n };\n\n agent.send(JSON.stringify(request));\n });\n },\n [agent]\n );\n\n agent.setState = (state: State) => {\n agent.send(JSON.stringify({ state, type: MessageType.CF_AGENT_STATE }));\n options.onStateUpdate?.(state, \"client\");\n };\n\n agent.call = call;\n agent.agent = agentNamespace;\n agent.name = options.name || \"default\";\n // biome-ignore lint: suppressions/parse\n agent.stub = new Proxy<any>(\n {},\n {\n get: (_target, method) => {\n return (...args: unknown[]) => {\n return call(method as string, args);\n };\n }\n }\n );\n\n // warn if agent isn't in lowercase\n if (agent.agent !== agent.agent.toLowerCase()) {\n console.warn(\n `Agent name: ${agent.agent} should probably be in lowercase. Received: ${agent.agent}`\n );\n }\n\n return agent;\n}\n"],"mappings":"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"}
@@ -14,7 +14,7 @@ type SerializableReturnValue =
14
14
  | void
15
15
  | Promise<SerializableValue>
16
16
  | Promise<void>;
17
- type AllSerializableValues<A> = A extends [infer First, ...infer Rest]
17
+ type AllSerializableValues<A$1> = A$1 extends [infer First, ...infer Rest]
18
18
  ? First extends SerializableValue
19
19
  ? AllSerializableValues<Rest>
20
20
  : false
@@ -30,5 +30,10 @@ type RPCMethod<T = Method> = T extends Method
30
30
  : never
31
31
  : never;
32
32
  //#endregion
33
- export { Method, RPCMethod, SerializableReturnValue, SerializableValue };
34
- //# sourceMappingURL=serializable-gtr9YMhp.d.ts.map
33
+ export {
34
+ SerializableValue as i,
35
+ RPCMethod as n,
36
+ SerializableReturnValue as r,
37
+ Method as t
38
+ };
39
+ //# sourceMappingURL=serializable-faDkMCai.d.ts.map
@@ -1,7 +1,7 @@
1
1
  import {
2
- Method,
3
- RPCMethod,
4
- SerializableReturnValue,
5
- SerializableValue
6
- } from "./serializable-gtr9YMhp.js";
2
+ i as SerializableValue,
3
+ n as RPCMethod,
4
+ r as SerializableReturnValue,
5
+ t as Method
6
+ } from "./serializable-faDkMCai.js";
7
7
  export { Method, RPCMethod, SerializableReturnValue, SerializableValue };
@@ -1,7 +1,7 @@
1
- import { MessageType } from "./ai-types-UZlfLOYP.js";
2
- import { camelCaseToKebabCase } from "./client-DjR-lC16.js";
3
- import { DisposableStore, MCPClientManager } from "./client-CZBVDDoO.js";
4
- import { DurableObjectOAuthClientProvider } from "./do-oauth-client-provider-B2jr6UNq.js";
1
+ import { t as MessageType } from "./ai-types-CrMqkwc_.js";
2
+ import { r as camelCaseToKebabCase } from "./client-B3SR12TQ.js";
3
+ import { i as DisposableStore, r as MCPConnectionState, t as MCPClientManager } from "./client-BZq9qau2.js";
4
+ import { t as DurableObjectOAuthClientProvider } from "./do-oauth-client-provider-CwqK5SXm.js";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { parseCronExpression } from "cron-schedule";
7
7
  import { nanoid } from "nanoid";
@@ -153,8 +153,8 @@ var Agent = class Agent extends Server {
153
153
  super(ctx, env);
154
154
  this._state = DEFAULT_STATE;
155
155
  this._disposables = new DisposableStore();
156
+ this._destroyed = false;
156
157
  this._ParentClass = Object.getPrototypeOf(this).constructor;
157
- this.mcp = new MCPClientManager(this._ParentClass.name, "0.0.1");
158
158
  this.initialState = DEFAULT_STATE;
159
159
  this.observability = genericObservability;
160
160
  this._flushingQueue = false;
@@ -192,27 +192,37 @@ var Agent = class Agent extends Server {
192
192
  }
193
193
  });
194
194
  if (row.type === "cron") {
195
+ if (this._destroyed) return;
195
196
  const nextExecutionTime = getNextCronTime(row.cron);
196
197
  const nextTimestamp = Math.floor(nextExecutionTime.getTime() / 1e3);
197
198
  this.sql`
198
199
  UPDATE cf_agents_schedules SET time = ${nextTimestamp} WHERE id = ${row.id}
199
200
  `;
200
- } else this.sql`
201
+ } else {
202
+ if (this._destroyed) return;
203
+ this.sql`
201
204
  DELETE FROM cf_agents_schedules WHERE id = ${row.id}
202
205
  `;
206
+ }
203
207
  }
208
+ if (this._destroyed) return;
204
209
  await this._scheduleNextAlarm();
205
210
  };
206
211
  if (!wrappedClasses.has(this.constructor)) {
207
212
  this._autoWrapCustomMethods();
208
213
  wrappedClasses.add(this.constructor);
209
214
  }
210
- this._disposables.add(this.mcp.onConnected(async () => {
211
- this.broadcastMcpServers();
212
- }));
213
- this._disposables.add(this.mcp.onObservabilityEvent((event) => {
214
- this.observability?.emit(event);
215
- }));
215
+ this.sql`
216
+ CREATE TABLE IF NOT EXISTS cf_agents_mcp_servers (
217
+ id TEXT PRIMARY KEY NOT NULL,
218
+ name TEXT NOT NULL,
219
+ server_url TEXT NOT NULL,
220
+ callback_url TEXT NOT NULL,
221
+ client_id TEXT,
222
+ auth_url TEXT,
223
+ server_options TEXT
224
+ )
225
+ `;
216
226
  this.sql`
217
227
  CREATE TABLE IF NOT EXISTS cf_agents_state (
218
228
  id TEXT PRIMARY KEY NOT NULL,
@@ -227,34 +237,25 @@ var Agent = class Agent extends Server {
227
237
  created_at INTEGER DEFAULT (unixepoch())
228
238
  )
229
239
  `;
230
- this.ctx.blockConcurrencyWhile(async () => {
231
- return this._tryCatch(async () => {
232
- this.sql`
233
- CREATE TABLE IF NOT EXISTS cf_agents_schedules (
234
- id TEXT PRIMARY KEY NOT NULL DEFAULT (randomblob(9)),
235
- callback TEXT,
236
- payload TEXT,
237
- type TEXT NOT NULL CHECK(type IN ('scheduled', 'delayed', 'cron')),
238
- time INTEGER,
239
- delayInSeconds INTEGER,
240
- cron TEXT,
241
- created_at INTEGER DEFAULT (unixepoch())
242
- )
243
- `;
244
- await this.alarm();
245
- });
246
- });
247
240
  this.sql`
248
- CREATE TABLE IF NOT EXISTS cf_agents_mcp_servers (
249
- id TEXT PRIMARY KEY NOT NULL,
250
- name TEXT NOT NULL,
251
- server_url TEXT NOT NULL,
252
- callback_url TEXT NOT NULL,
253
- client_id TEXT,
254
- auth_url TEXT,
255
- server_options TEXT
241
+ CREATE TABLE IF NOT EXISTS cf_agents_schedules (
242
+ id TEXT PRIMARY KEY NOT NULL DEFAULT (randomblob(9)),
243
+ callback TEXT,
244
+ payload TEXT,
245
+ type TEXT NOT NULL CHECK(type IN ('scheduled', 'delayed', 'cron')),
246
+ time INTEGER,
247
+ delayInSeconds INTEGER,
248
+ cron TEXT,
249
+ created_at INTEGER DEFAULT (unixepoch())
256
250
  )
257
251
  `;
252
+ this.mcp = new MCPClientManager(this._ParentClass.name, "0.0.1", { storage: this.ctx.storage });
253
+ this._disposables.add(this.mcp.onServerStateChanged(async () => {
254
+ this.broadcastMcpServers();
255
+ }));
256
+ this._disposables.add(this.mcp.onObservabilityEvent((event) => {
257
+ this.observability?.emit(event);
258
+ }));
258
259
  const _onRequest = this.onRequest.bind(this);
259
260
  this.onRequest = (request) => {
260
261
  return agentContext.run({
@@ -263,16 +264,9 @@ var Agent = class Agent extends Server {
263
264
  request,
264
265
  email: void 0
265
266
  }, async () => {
266
- if (this.mcp.isCallbackRequest(request)) {
267
- const result = await this.mcp.handleCallbackRequest(request);
268
- this.broadcastMcpServers();
269
- if (result.authSuccess) this.mcp.establishConnection(result.serverId).catch((error) => {
270
- console.error("Background connection failed:", error);
271
- }).finally(() => {
272
- this.broadcastMcpServers();
273
- });
274
- return this.handleOAuthCallbackResponse(result, request);
275
- }
267
+ await this.mcp.ensureJsonSchema();
268
+ const oauthResponse = await this.handleMcpOAuthCallback(request);
269
+ if (oauthResponse) return oauthResponse;
276
270
  return this._tryCatch(() => _onRequest(request));
277
271
  });
278
272
  };
@@ -284,6 +278,7 @@ var Agent = class Agent extends Server {
284
278
  request: void 0,
285
279
  email: void 0
286
280
  }, async () => {
281
+ await this.mcp.ensureJsonSchema();
287
282
  if (typeof message !== "string") return this._tryCatch(() => _onMessage(connection, message));
288
283
  let parsed;
289
284
  try {
@@ -348,7 +343,7 @@ var Agent = class Agent extends Server {
348
343
  connection,
349
344
  request: ctx$1.request,
350
345
  email: void 0
351
- }, () => {
346
+ }, async () => {
352
347
  if (this.state) connection.send(JSON.stringify({
353
348
  state: this.state,
354
349
  type: MessageType.CF_AGENT_STATE
@@ -375,27 +370,9 @@ var Agent = class Agent extends Server {
375
370
  request: void 0,
376
371
  email: void 0
377
372
  }, async () => {
378
- await this._tryCatch(() => {
379
- const servers = this.sql`
380
- SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
381
- `;
373
+ await this._tryCatch(async () => {
374
+ await this.mcp.restoreConnectionsFromStorage(this.name);
382
375
  this.broadcastMcpServers();
383
- if (servers && Array.isArray(servers) && servers.length > 0) {
384
- servers.forEach((server) => {
385
- if (server.callback_url) this.mcp.registerCallbackUrl(`${server.callback_url}/${server.id}`);
386
- });
387
- servers.forEach((server) => {
388
- this._connectToMcpServerInternal(server.name, server.server_url, server.callback_url, server.server_options ? JSON.parse(server.server_options) : void 0, {
389
- id: server.id,
390
- oauthClientId: server.client_id ?? void 0
391
- }).then(() => {
392
- this.broadcastMcpServers();
393
- }).catch((error) => {
394
- console.error(`Error connecting to MCP server: ${server.name} (${server.server_url})`, error);
395
- this.broadcastMcpServers();
396
- });
397
- });
398
- }
399
376
  return _onStart(props);
400
377
  });
401
378
  });
@@ -801,7 +778,7 @@ var Agent = class Agent extends Server {
801
778
  async _scheduleNextAlarm() {
802
779
  const result = this.sql`
803
780
  SELECT time FROM cf_agents_schedules
804
- WHERE time > ${Math.floor(Date.now() / 1e3)}
781
+ WHERE time >= ${Math.floor(Date.now() / 1e3)}
805
782
  ORDER BY time ASC
806
783
  LIMIT 1
807
784
  `;
@@ -815,15 +792,18 @@ var Agent = class Agent extends Server {
815
792
  * Destroy the Agent, removing all state and scheduled tasks
816
793
  */
817
794
  async destroy() {
795
+ this.sql`DROP TABLE IF EXISTS cf_agents_mcp_servers`;
818
796
  this.sql`DROP TABLE IF EXISTS cf_agents_state`;
819
797
  this.sql`DROP TABLE IF EXISTS cf_agents_schedules`;
820
- this.sql`DROP TABLE IF EXISTS cf_agents_mcp_servers`;
821
798
  this.sql`DROP TABLE IF EXISTS cf_agents_queues`;
822
799
  await this.ctx.storage.deleteAlarm();
823
800
  await this.ctx.storage.deleteAll();
824
801
  this._disposables.dispose();
825
- await this.mcp.dispose?.();
826
- this.ctx.abort("destroyed");
802
+ await this.mcp.dispose();
803
+ this._destroyed = true;
804
+ setTimeout(() => {
805
+ this.ctx.abort("destroyed");
806
+ }, 0);
827
807
  this.observability?.emit({
828
808
  displayMessage: "Agent destroyed",
829
809
  id: nanoid(),
@@ -847,7 +827,8 @@ var Agent = class Agent extends Server {
847
827
  * @param callbackHost Base host for the agent, used for the redirect URI. If not provided, will be derived from the current request.
848
828
  * @param agentsPrefix agents routing prefix if not using `agents`
849
829
  * @param options MCP client and transport options
850
- * @returns authUrl
830
+ * @returns Server id and state - either "authenticating" with authUrl, or "ready"
831
+ * @throws If connection or discovery fails
851
832
  */
852
833
  async addMcpServer(serverName, url, callbackHost, agentsPrefix = "agents", options) {
853
834
  let resolvedCallbackHost = callbackHost;
@@ -858,29 +839,10 @@ var Agent = class Agent extends Server {
858
839
  resolvedCallbackHost = `${requestUrl.protocol}//${requestUrl.host}`;
859
840
  }
860
841
  const callbackUrl = `${resolvedCallbackHost}/${agentsPrefix}/${camelCaseToKebabCase(this._ParentClass.name)}/${this.name}/callback`;
861
- const result = await this._connectToMcpServerInternal(serverName, url, callbackUrl, options);
862
- this.sql`
863
- INSERT
864
- OR REPLACE INTO cf_agents_mcp_servers (id, name, server_url, client_id, auth_url, callback_url, server_options)
865
- VALUES (
866
- ${result.id},
867
- ${serverName},
868
- ${url},
869
- ${result.clientId ?? null},
870
- ${result.authUrl ?? null},
871
- ${callbackUrl},
872
- ${options ? JSON.stringify(options) : null}
873
- );
874
- `;
875
- this.broadcastMcpServers();
876
- return result;
877
- }
878
- async _connectToMcpServerInternal(_serverName, url, callbackUrl, options, reconnect) {
842
+ await this.mcp.ensureJsonSchema();
843
+ const id = nanoid(8);
879
844
  const authProvider = new DurableObjectOAuthClientProvider(this.ctx.storage, this.name, callbackUrl);
880
- if (reconnect) {
881
- authProvider.serverId = reconnect.id;
882
- if (reconnect.oauthClientId) authProvider.clientId = reconnect.oauthClientId;
883
- }
845
+ authProvider.serverId = id;
884
846
  const transportType = options?.transport?.type ?? "auto";
885
847
  let headerTransportOpts = {};
886
848
  if (options?.transport?.headers) headerTransportOpts = {
@@ -890,28 +852,33 @@ var Agent = class Agent extends Server {
890
852
  }) },
891
853
  requestInit: { headers: options?.transport?.headers }
892
854
  };
893
- const { id, authUrl, clientId } = await this.mcp.connect(url, {
855
+ await this.mcp.registerServer(id, {
856
+ url,
857
+ name: serverName,
858
+ callbackUrl,
894
859
  client: options?.client,
895
- reconnect,
896
860
  transport: {
897
861
  ...headerTransportOpts,
898
862
  authProvider,
899
863
  type: transportType
900
864
  }
901
865
  });
866
+ const result = await this.mcp.connectToServer(id);
867
+ if (result.state === MCPConnectionState.FAILED) throw new Error(`Failed to connect to MCP server at ${url}: ${result.error}`);
868
+ if (result.state === MCPConnectionState.AUTHENTICATING) return {
869
+ id,
870
+ state: result.state,
871
+ authUrl: result.authUrl
872
+ };
873
+ const discoverResult = await this.mcp.discoverIfConnected(id);
874
+ if (discoverResult && !discoverResult.success) throw new Error(`Failed to discover MCP server capabilities: ${discoverResult.error}`);
902
875
  return {
903
- authUrl,
904
- clientId,
905
- id
876
+ id,
877
+ state: MCPConnectionState.READY
906
878
  };
907
879
  }
908
880
  async removeMcpServer(id) {
909
- this.mcp.closeConnection(id);
910
- this.mcp.unregisterCallbackUrl(id);
911
- this.sql`
912
- DELETE FROM cf_agents_mcp_servers WHERE id = ${id};
913
- `;
914
- this.broadcastMcpServers();
881
+ await this.mcp.removeServer(id);
915
882
  }
916
883
  getMcpServers() {
917
884
  const mcpState = {
@@ -920,18 +887,18 @@ var Agent = class Agent extends Server {
920
887
  servers: {},
921
888
  tools: this.mcp.listTools()
922
889
  };
923
- const servers = this.sql`
924
- SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
925
- `;
890
+ const servers = this.mcp.listServers();
926
891
  if (servers && Array.isArray(servers) && servers.length > 0) for (const server of servers) {
927
892
  const serverConn = this.mcp.mcpConnections[server.id];
893
+ let defaultState = "not-connected";
894
+ if (!serverConn && server.auth_url) defaultState = "authenticating";
928
895
  mcpState.servers[server.id] = {
929
896
  auth_url: server.auth_url,
930
897
  capabilities: serverConn?.serverCapabilities ?? null,
931
898
  instructions: serverConn?.instructions ?? null,
932
899
  name: server.name,
933
900
  server_url: server.server_url,
934
- state: serverConn?.connectionState ?? "authenticating"
901
+ state: serverConn?.connectionState ?? defaultState
935
902
  };
936
903
  }
937
904
  return mcpState;
@@ -943,6 +910,28 @@ var Agent = class Agent extends Server {
943
910
  }));
944
911
  }
945
912
  /**
913
+ * Handle MCP OAuth callback request if it's an OAuth callback.
914
+ *
915
+ * This method encapsulates the entire OAuth callback flow:
916
+ * 1. Checks if the request is an MCP OAuth callback
917
+ * 2. Processes the OAuth code exchange
918
+ * 3. Establishes the connection if successful
919
+ * 4. Broadcasts MCP server state updates
920
+ * 5. Returns the appropriate HTTP response
921
+ *
922
+ * @param request The incoming HTTP request
923
+ * @returns Response if this was an OAuth callback, null otherwise
924
+ */
925
+ async handleMcpOAuthCallback(request) {
926
+ if (!this.mcp.isCallbackRequest(request)) return null;
927
+ const result = await this.mcp.handleCallbackRequest(request);
928
+ if (result.authSuccess) this.mcp.establishConnection(result.serverId).catch((error) => {
929
+ console.error("[Agent handleMcpOAuthCallback] Connection establishment failed:", error);
930
+ });
931
+ this.broadcastMcpServers();
932
+ return this.handleOAuthCallbackResponse(result, request);
933
+ }
934
+ /**
946
935
  * Handle OAuth callback response using MCPClientManager configuration
947
936
  * @param result OAuth callback result
948
937
  * @param request The original request (needed for base URL)
@@ -951,10 +940,21 @@ var Agent = class Agent extends Server {
951
940
  handleOAuthCallbackResponse(result, request) {
952
941
  const config = this.mcp.getOAuthCallbackConfig();
953
942
  if (config?.customHandler) return config.customHandler(result);
954
- if (config?.successRedirect && result.authSuccess) return Response.redirect(config.successRedirect);
955
- if (config?.errorRedirect && !result.authSuccess) return Response.redirect(`${config.errorRedirect}?error=${encodeURIComponent(result.authError || "Unknown error")}`);
956
- const baseUrl = new URL(request.url).origin;
957
- return Response.redirect(baseUrl);
943
+ const baseOrigin = new URL(request.url).origin;
944
+ if (config?.successRedirect && result.authSuccess) try {
945
+ return Response.redirect(new URL(config.successRedirect, baseOrigin).href);
946
+ } catch (e) {
947
+ console.error("Invalid successRedirect URL:", config.successRedirect, e);
948
+ return Response.redirect(baseOrigin);
949
+ }
950
+ if (config?.errorRedirect && !result.authSuccess) try {
951
+ const errorUrl = `${config.errorRedirect}?error=${encodeURIComponent(result.authError || "Unknown error")}`;
952
+ return Response.redirect(new URL(errorUrl, baseOrigin).href);
953
+ } catch (e) {
954
+ console.error("Invalid errorRedirect URL:", config.errorRedirect, e);
955
+ return Response.redirect(baseOrigin);
956
+ }
957
+ return Response.redirect(baseOrigin);
958
958
  }
959
959
  };
960
960
  const wrappedClasses = /* @__PURE__ */ new Set();
@@ -980,10 +980,15 @@ async function routeAgentRequest(request, env, options) {
980
980
  prefix: "agents",
981
981
  ...options
982
982
  });
983
- if (response && corsHeaders && request.headers.get("upgrade")?.toLowerCase() !== "websocket" && request.headers.get("Upgrade")?.toLowerCase() !== "websocket") response = new Response(response.body, { headers: {
984
- ...response.headers,
985
- ...corsHeaders
986
- } });
983
+ if (response && corsHeaders && request.headers.get("upgrade")?.toLowerCase() !== "websocket" && request.headers.get("Upgrade")?.toLowerCase() !== "websocket") {
984
+ const newHeaders = new Headers(response.headers);
985
+ for (const [key, value] of Object.entries(corsHeaders)) newHeaders.set(key, value);
986
+ response = new Response(response.body, {
987
+ status: response.status,
988
+ statusText: response.statusText,
989
+ headers: newHeaders
990
+ });
991
+ }
987
992
  return response;
988
993
  }
989
994
  /**
@@ -1175,5 +1180,5 @@ var StreamingResponse = class {
1175
1180
  };
1176
1181
 
1177
1182
  //#endregion
1178
- export { Agent, StreamingResponse, callable, createAddressBasedEmailResolver, createCatchAllEmailResolver, createHeaderBasedEmailResolver, genericObservability, getAgentByName, getCurrentAgent, routeAgentEmail, routeAgentRequest, unstable_callable };
1179
- //# sourceMappingURL=src-COfG--3R.js.map
1183
+ export { createCatchAllEmailResolver as a, getCurrentAgent as c, unstable_callable as d, genericObservability as f, createAddressBasedEmailResolver as i, routeAgentEmail as l, StreamingResponse as n, createHeaderBasedEmailResolver as o, callable as r, getAgentByName as s, Agent as t, routeAgentRequest as u };
1184
+ //# sourceMappingURL=src-D_KKH_4c.js.map