agents 0.0.0-ed3f94d → 0.0.0-edd3357
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/dist/ai-chat-agent.d.ts +1 -2
- package/dist/ai-chat-agent.js +57 -350
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-chat-v5-migration.js +0 -1
- package/dist/ai-react.d.ts +1 -8
- package/dist/ai-react.js +111 -157
- package/dist/ai-react.js.map +1 -1
- package/dist/ai-types.d.ts +0 -1
- package/dist/ai-types.js +1 -2
- package/dist/{chunk-BER7KXUJ.js → chunk-AVYJQSLW.js} +1 -2
- package/dist/chunk-AVYJQSLW.js.map +1 -0
- package/dist/{chunk-Z44WASMA.js → chunk-LL2AFX7V.js} +2 -7
- package/dist/{chunk-Z44WASMA.js.map → chunk-LL2AFX7V.js.map} +1 -1
- package/dist/{chunk-3OT2NNEW.js → chunk-MH46VMM4.js} +67 -396
- package/dist/chunk-MH46VMM4.js.map +1 -0
- package/dist/{chunk-254F4GDT.js → chunk-YDUDMOL6.js} +50 -97
- package/dist/chunk-YDUDMOL6.js.map +1 -0
- package/dist/{client-DVoPb3-C.d.ts → client-CvaJdLQA.d.ts} +26 -131
- package/dist/client.js +1 -2
- package/dist/index.d.ts +32 -25
- package/dist/index.js +4 -5
- package/dist/mcp/client.d.ts +1 -2
- package/dist/mcp/client.js +1 -2
- package/dist/mcp/do-oauth-client-provider.js +1 -2
- package/dist/mcp/index.d.ts +31 -13
- package/dist/mcp/index.js +163 -233
- package/dist/mcp/index.js.map +1 -1
- package/dist/observability/index.d.ts +24 -12
- package/dist/observability/index.js +4 -5
- package/dist/react.d.ts +6 -10
- package/dist/react.js +3 -101
- package/dist/react.js.map +1 -1
- package/dist/schedule.js +0 -2
- package/dist/schedule.js.map +1 -1
- package/package.json +6 -19
- package/src/index.ts +57 -141
- package/dist/_esm-LV5FJ3HK.js +0 -3922
- package/dist/_esm-LV5FJ3HK.js.map +0 -1
- package/dist/ccip-CMBYN64O.js +0 -15
- package/dist/ccip-CMBYN64O.js.map +0 -1
- package/dist/chunk-254F4GDT.js.map +0 -1
- package/dist/chunk-3OT2NNEW.js.map +0 -1
- package/dist/chunk-5Y6BEZDY.js +0 -276
- package/dist/chunk-5Y6BEZDY.js.map +0 -1
- package/dist/chunk-BER7KXUJ.js.map +0 -1
- package/dist/chunk-JJBFIGUC.js +0 -5202
- package/dist/chunk-JJBFIGUC.js.map +0 -1
- package/dist/chunk-PR4QN5HX.js +0 -43
- package/dist/chunk-PR4QN5HX.js.map +0 -1
- package/dist/chunk-TYAY6AU6.js +0 -159
- package/dist/chunk-TYAY6AU6.js.map +0 -1
- package/dist/codemode/ai.d.ts +0 -25
- package/dist/codemode/ai.js +0 -5112
- package/dist/codemode/ai.js.map +0 -1
- package/dist/mcp/x402.d.ts +0 -39
- package/dist/mcp/x402.js +0 -3195
- package/dist/mcp/x402.js.map +0 -1
- package/dist/mcp-BH1fJeiU.d.ts +0 -58
- package/dist/secp256k1-M22GZP2U.js +0 -2193
- package/dist/secp256k1-M22GZP2U.js.map +0 -1
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"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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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/react.tsx"],"sourcesContent":["import type { PartySocket } from \"partysocket\";\nimport { usePartySocket } from \"partysocket/react\";\nimport { useCallback, useRef } 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\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\"\n> & {\n /** Name of the agent to connect to */\n agent: string;\n /** Name of the specific Agent instance */\n name?: string;\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 * @template State Type of the Agent's state\n * @template Agent Type of the Agent\n * @param options Connection options\n * @returns WebSocket connection with setState and call methods\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 // 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 // TODO: if options.query is a function, then use\n // \"use()\" to get the value and pass it\n // as a query parameter to usePartySocket\n const agent = usePartySocket({\n party: agentNamespace,\n prefix: \"agents\",\n room: options.name || \"default\",\n ...options,\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":";;;AACA,SAAS,sBAAsB;AAC/B,SAAS,aAAa,cAAc;AAWpC,SAAS,qBAAqB,KAAqB;AAEjD,MAAI,QAAQ,IAAI,YAAY,KAAK,QAAQ,IAAI,YAAY,GAAG;AAC1D,WAAO,IAAI,YAAY,EAAE,QAAQ,MAAM,GAAG;AAAA,EAC5C;AAGA,MAAI,aAAa,IAAI;AAAA,IACnB;AAAA,IACA,CAAC,WAAW,IAAI,OAAO,YAAY,CAAC;AAAA,EACtC;AACA,eAAa,WAAW,WAAW,GAAG,IAAI,WAAW,MAAM,CAAC,IAAI;AAEhE,SAAO,WAAW,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,EAAE;AACvD;AAwHO,SAAS,SACd,SAOA;AACA,QAAM,iBAAiB,qBAAqB,QAAQ,KAAK;AAEzD,QAAM,kBAAkB;AAAA,IACtB,oBAAI,IAOF;AAAA,EACJ;AAKA,QAAM,QAAQ,eAAe;AAAA,IAC3B,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM,QAAQ,QAAQ;AAAA,IACtB,GAAG;AAAA,IACH,WAAW,CAAC,YAAY;AACtB,UAAI,OAAO,QAAQ,SAAS,UAAU;AACpC,YAAI;AACJ,YAAI;AACF,0BAAgB,KAAK,MAAM,QAAQ,IAAI;AAAA,QACzC,SAAS,QAAQ;AAGf,iBAAO,QAAQ,YAAY,OAAO;AAAA,QACpC;AACA,YAAI,cAAc,gDAAqC;AACrD,kBAAQ,gBAAgB,cAAc,OAAgB,QAAQ;AAC9D;AAAA,QACF;AACA,YAAI,cAAc,4DAA2C;AAC3D,kBAAQ,cAAc,cAAc,GAAsB;AAC1D;AAAA,QACF;AACA,YAAI,cAAc,0BAA0B;AAC1C,gBAAM,WAAW;AACjB,gBAAM,UAAU,gBAAgB,QAAQ,IAAI,SAAS,EAAE;AACvD,cAAI,CAAC,QAAS;AAEd,cAAI,CAAC,SAAS,SAAS;AACrB,oBAAQ,OAAO,IAAI,MAAM,SAAS,KAAK,CAAC;AACxC,4BAAgB,QAAQ,OAAO,SAAS,EAAE;AAC1C,oBAAQ,QAAQ,UAAU,SAAS,KAAK;AACxC;AAAA,UACF;AAGA,cAAI,UAAU,UAAU;AACtB,gBAAI,SAAS,MAAM;AACjB,sBAAQ,QAAQ,SAAS,MAAM;AAC/B,8BAAgB,QAAQ,OAAO,SAAS,EAAE;AAC1C,sBAAQ,QAAQ,SAAS,SAAS,MAAM;AAAA,YAC1C,OAAO;AACL,sBAAQ,QAAQ,UAAU,SAAS,MAAM;AAAA,YAC3C;AAAA,UACF,OAAO;AAEL,oBAAQ,QAAQ,SAAS,MAAM;AAC/B,4BAAgB,QAAQ,OAAO,SAAS,EAAE;AAAA,UAC5C;AACA;AAAA,QACF;AAAA,MACF;AACA,cAAQ,YAAY,OAAO;AAAA,IAC7B;AAAA,EACF,CAAC;AAQD,QAAM,OAAO;AAAA,IACX,CACE,QACA,OAAkB,CAAC,GACnB,kBACe;AACf,aAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,cAAM,KAAK,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC;AAC7C,wBAAgB,QAAQ,IAAI,IAAI;AAAA,UAC9B;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,QACV,CAAC;AAED,cAAM,UAAsB;AAAA,UAC1B;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,cAAM,KAAK,KAAK,UAAU,OAAO,CAAC;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,IACA,CAAC,KAAK;AAAA,EACR;AAEA,QAAM,WAAW,CAAC,UAAiB;AACjC,UAAM,KAAK,KAAK,UAAU,EAAE,OAAO,4CAAiC,CAAC,CAAC;AACtE,YAAQ,gBAAgB,OAAO,QAAQ;AAAA,EACzC;AAEA,QAAM,OAAO;AACb,QAAM,QAAQ;AACd,QAAM,OAAO,QAAQ,QAAQ;AAE7B,QAAM,OAAO,IAAI;AAAA,IACf,CAAC;AAAA,IACD;AAAA,MACE,KAAK,CAAC,SAAS,WAAW;AACxB,eAAO,IAAI,SAAoB;AAC7B,iBAAO,KAAK,QAAkB,IAAI;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,MAAM,UAAU,MAAM,MAAM,YAAY,GAAG;AAC7C,YAAQ;AAAA,MACN,eAAe,MAAM,KAAK,+CAA+C,MAAM,KAAK;AAAA,IACtF;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
|
package/dist/schedule.js
CHANGED
package/dist/schedule.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schedule.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/**\n * Get the schedule prompt for a given event\n * @param event - The event to get the schedule prompt for\n * @returns The schedule prompt\n */\nexport function getSchedulePrompt(event: { date: Date }) {\n return `\n[Schedule Parser Component]\n\nCurrent time: ${event.date.toUTCString()}\n\nThis component parses natural language scheduling requests into a structured format. It extracts:\n1. A clean task description (without timing information)\n2. Scheduling details in one of these formats:\n - scheduled: Specific date/time events\n - delayed: Relative time delays (in seconds)\n - cron: Recurring patterns\n - no-schedule: Tasks without timing\n\nRules:\n- Task descriptions should be clean and focused on the action\n- Use numbers (0-6) for days in cron patterns (0=Sunday)\n- For recurring tasks, use standard cron syntax\n- For relative times, convert to seconds\n- For specific dates, use the current time as reference\n\nExample outputs:\n{\n \"description\": \"meeting with team\",\n \"when\": {\n \"type\": \"scheduled\",\n \"date\": \"tomorrow at 14:00\"\n }\n}\n\n{\n \"description\": \"backup database\",\n \"when\": {\n \"type\": \"cron\",\n \"cron\": \"0 0 * * *\"\n }\n}\n\n{\n \"description\": \"send report\",\n \"when\": {\n \"type\": \"delayed\",\n \"delayInSeconds\": 1800\n }\n}\n\n[End Schedule Parser Component]\n`;\n}\n\nlet didWarnAboutUnstableGetSchedulePrompt = false;\n\n/**\n * @deprecated this has been renamed to getSchedulePrompt, and unstable_getSchedulePrompt will be removed in the next major version\n * @param event - The event to get the schedule prompt for\n * @returns The schedule prompt\n */\nexport function unstable_getSchedulePrompt(event: { date: Date }) {\n if (!didWarnAboutUnstableGetSchedulePrompt) {\n didWarnAboutUnstableGetSchedulePrompt = true;\n console.warn(\n \"unstable_getSchedulePrompt is deprecated, use getSchedulePrompt instead. unstable_getSchedulePrompt will be removed in the next major version.\"\n );\n }\n return getSchedulePrompt(event);\n}\n\n/**\n * The schema for the schedule prompt\n */\nexport const scheduleSchema = z.object({\n description: z.string().describe(\"A description of the task\"),\n when: z.object({\n cron: z\n .string()\n .optional()\n .describe(\n \"execute task on a recurring interval specified as cron syntax (only use if the type is cron)\"\n ),\n date: z.coerce\n .date()\n .optional()\n .describe(\n \"execute task at the specified date and time (only use if the type is scheduled)\"\n ),\n delayInSeconds: z\n .number()\n .optional()\n .describe(\n \"execute task after a delay in seconds (only use if the type is delayed)\"\n ),\n type: z\n .enum([\"scheduled\", \"delayed\", \"cron\", \"no-schedule\"])\n .describe(\"The type of scheduling details\")\n })\n});\n\n/**\n * The type for the schedule prompt\n */\nexport type Schedule = z.infer<typeof scheduleSchema>;\n\n/**\n * @deprecated this has been renamed to scheduleSchema, and unstable_scheduleSchema will be removed in the next major version\n * @returns The schedule schema\n */\nexport const unstable_scheduleSchema = scheduleSchema;\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/schedule.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/**\n * Get the schedule prompt for a given event\n * @param event - The event to get the schedule prompt for\n * @returns The schedule prompt\n */\nexport function getSchedulePrompt(event: { date: Date }) {\n return `\n[Schedule Parser Component]\n\nCurrent time: ${event.date.toUTCString()}\n\nThis component parses natural language scheduling requests into a structured format. It extracts:\n1. A clean task description (without timing information)\n2. Scheduling details in one of these formats:\n - scheduled: Specific date/time events\n - delayed: Relative time delays (in seconds)\n - cron: Recurring patterns\n - no-schedule: Tasks without timing\n\nRules:\n- Task descriptions should be clean and focused on the action\n- Use numbers (0-6) for days in cron patterns (0=Sunday)\n- For recurring tasks, use standard cron syntax\n- For relative times, convert to seconds\n- For specific dates, use the current time as reference\n\nExample outputs:\n{\n \"description\": \"meeting with team\",\n \"when\": {\n \"type\": \"scheduled\",\n \"date\": \"tomorrow at 14:00\"\n }\n}\n\n{\n \"description\": \"backup database\",\n \"when\": {\n \"type\": \"cron\",\n \"cron\": \"0 0 * * *\"\n }\n}\n\n{\n \"description\": \"send report\",\n \"when\": {\n \"type\": \"delayed\",\n \"delayInSeconds\": 1800\n }\n}\n\n[End Schedule Parser Component]\n`;\n}\n\nlet didWarnAboutUnstableGetSchedulePrompt = false;\n\n/**\n * @deprecated this has been renamed to getSchedulePrompt, and unstable_getSchedulePrompt will be removed in the next major version\n * @param event - The event to get the schedule prompt for\n * @returns The schedule prompt\n */\nexport function unstable_getSchedulePrompt(event: { date: Date }) {\n if (!didWarnAboutUnstableGetSchedulePrompt) {\n didWarnAboutUnstableGetSchedulePrompt = true;\n console.warn(\n \"unstable_getSchedulePrompt is deprecated, use getSchedulePrompt instead. unstable_getSchedulePrompt will be removed in the next major version.\"\n );\n }\n return getSchedulePrompt(event);\n}\n\n/**\n * The schema for the schedule prompt\n */\nexport const scheduleSchema = z.object({\n description: z.string().describe(\"A description of the task\"),\n when: z.object({\n cron: z\n .string()\n .optional()\n .describe(\n \"execute task on a recurring interval specified as cron syntax (only use if the type is cron)\"\n ),\n date: z.coerce\n .date()\n .optional()\n .describe(\n \"execute task at the specified date and time (only use if the type is scheduled)\"\n ),\n delayInSeconds: z\n .number()\n .optional()\n .describe(\n \"execute task after a delay in seconds (only use if the type is delayed)\"\n ),\n type: z\n .enum([\"scheduled\", \"delayed\", \"cron\", \"no-schedule\"])\n .describe(\"The type of scheduling details\")\n })\n});\n\n/**\n * The type for the schedule prompt\n */\nexport type Schedule = z.infer<typeof scheduleSchema>;\n\n/**\n * @deprecated this has been renamed to scheduleSchema, and unstable_scheduleSchema will be removed in the next major version\n * @returns The schedule schema\n */\nexport const unstable_scheduleSchema = scheduleSchema;\n"],"mappings":";AAAA,SAAS,SAAS;AAOX,SAAS,kBAAkB,OAAuB;AACvD,SAAO;AAAA;AAAA;AAAA,gBAGO,MAAM,KAAK,YAAY,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4CxC;AAEA,IAAI,wCAAwC;AAOrC,SAAS,2BAA2B,OAAuB;AAChE,MAAI,CAAC,uCAAuC;AAC1C,4CAAwC;AACxC,YAAQ;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,SAAO,kBAAkB,KAAK;AAChC;AAKO,IAAM,iBAAiB,EAAE,OAAO;AAAA,EACrC,aAAa,EAAE,OAAO,EAAE,SAAS,2BAA2B;AAAA,EAC5D,MAAM,EAAE,OAAO;AAAA,IACb,MAAM,EACH,OAAO,EACP,SAAS,EACT;AAAA,MACC;AAAA,IACF;AAAA,IACF,MAAM,EAAE,OACL,KAAK,EACL,SAAS,EACT;AAAA,MACC;AAAA,IACF;AAAA,IACF,gBAAgB,EACb,OAAO,EACP,SAAS,EACT;AAAA,MACC;AAAA,IACF;AAAA,IACF,MAAM,EACH,KAAK,CAAC,aAAa,WAAW,QAAQ,aAAa,CAAC,EACpD,SAAS,gCAAgC;AAAA,EAC9C,CAAC;AACH,CAAC;AAWM,IAAM,0BAA0B;","names":[]}
|
package/package.json
CHANGED
|
@@ -4,24 +4,21 @@
|
|
|
4
4
|
"url": "https://github.com/cloudflare/agents/issues"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@modelcontextprotocol/sdk": "^1.18.
|
|
8
|
-
"ai": "5.0.
|
|
7
|
+
"@modelcontextprotocol/sdk": "^1.18.0",
|
|
8
|
+
"ai": "5.0.44",
|
|
9
9
|
"cron-schedule": "^5.0.4",
|
|
10
|
-
"json-schema-to-typescript": "^15.0.4",
|
|
11
10
|
"mimetext": "^3.0.27",
|
|
12
|
-
"nanoid": "^5.1.
|
|
11
|
+
"nanoid": "^5.1.5",
|
|
13
12
|
"partyserver": "^0.0.74",
|
|
14
13
|
"partysocket": "1.1.5",
|
|
15
|
-
"
|
|
16
|
-
"zod": "^3.25.76",
|
|
17
|
-
"zod-to-ts": "^1.2.0"
|
|
14
|
+
"zod": "^3.25.76"
|
|
18
15
|
},
|
|
19
16
|
"publishConfig": {
|
|
20
17
|
"access": "public"
|
|
21
18
|
},
|
|
22
19
|
"description": "A home for your AI agents",
|
|
23
20
|
"devDependencies": {
|
|
24
|
-
"@cloudflare/workers-oauth-provider": "^0.0.
|
|
21
|
+
"@cloudflare/workers-oauth-provider": "^0.0.8",
|
|
25
22
|
"react": "*",
|
|
26
23
|
"vitest-browser-react": "^1.0.1"
|
|
27
24
|
},
|
|
@@ -56,11 +53,6 @@
|
|
|
56
53
|
"import": "./dist/client.js",
|
|
57
54
|
"require": "./dist/client.js"
|
|
58
55
|
},
|
|
59
|
-
"./codemode/ai": {
|
|
60
|
-
"types": "./dist/codemode/ai.d.ts",
|
|
61
|
-
"import": "./dist/codemode/ai.js",
|
|
62
|
-
"require": "./dist/codemode/ai.js"
|
|
63
|
-
},
|
|
64
56
|
"./mcp": {
|
|
65
57
|
"types": "./dist/mcp/index.d.ts",
|
|
66
58
|
"import": "./dist/mcp/index.js",
|
|
@@ -90,11 +82,6 @@
|
|
|
90
82
|
"types": "./dist/schedule.d.ts",
|
|
91
83
|
"import": "./dist/schedule.js",
|
|
92
84
|
"require": "./dist/schedule.js"
|
|
93
|
-
},
|
|
94
|
-
"./x402": {
|
|
95
|
-
"types": "./dist/mcp/x402.d.ts",
|
|
96
|
-
"import": "./dist/mcp/x402.js",
|
|
97
|
-
"require": "./dist/mcp/x402.js"
|
|
98
85
|
}
|
|
99
86
|
},
|
|
100
87
|
"files": [
|
|
@@ -125,5 +112,5 @@
|
|
|
125
112
|
},
|
|
126
113
|
"type": "module",
|
|
127
114
|
"types": "dist/index.d.ts",
|
|
128
|
-
"version": "0.0.0-
|
|
115
|
+
"version": "0.0.0-edd3357"
|
|
129
116
|
}
|
package/src/index.ts
CHANGED
|
@@ -22,12 +22,10 @@ import {
|
|
|
22
22
|
routePartykitRequest
|
|
23
23
|
} from "partyserver";
|
|
24
24
|
import { camelCaseToKebabCase } from "./client";
|
|
25
|
-
import { MCPClientManager
|
|
26
|
-
import type {
|
|
25
|
+
import { MCPClientManager } from "./mcp/client";
|
|
26
|
+
// import type { MCPClientConnection } from "./mcp/client-connection";
|
|
27
27
|
import { DurableObjectOAuthClientProvider } from "./mcp/do-oauth-client-provider";
|
|
28
|
-
import type { TransportType } from "./mcp/types";
|
|
29
28
|
import { genericObservability, type Observability } from "./observability";
|
|
30
|
-
import { DisposableStore } from "./core/events";
|
|
31
29
|
import { MessageType } from "./ai-types";
|
|
32
30
|
|
|
33
31
|
export type { Connection, ConnectionContext, WSMessage } from "partyserver";
|
|
@@ -199,8 +197,6 @@ function getNextCronTime(cron: string) {
|
|
|
199
197
|
return interval.getNextDate();
|
|
200
198
|
}
|
|
201
199
|
|
|
202
|
-
export type { TransportType } from "./mcp/types";
|
|
203
|
-
|
|
204
200
|
/**
|
|
205
201
|
* MCP Server state update message from server -> Client
|
|
206
202
|
*/
|
|
@@ -225,7 +221,7 @@ export type MCPServer = {
|
|
|
225
221
|
// This state is specifically about the temporary process of getting a token (if needed).
|
|
226
222
|
// Scope outside of that can't be relied upon because when the DO sleeps, there's no way
|
|
227
223
|
// to communicate a change to a non-ready state.
|
|
228
|
-
state:
|
|
224
|
+
state: "authenticating" | "connecting" | "ready" | "discovering" | "failed";
|
|
229
225
|
instructions: string | null;
|
|
230
226
|
capabilities: ServerCapabilities | null;
|
|
231
227
|
};
|
|
@@ -318,15 +314,11 @@ export class Agent<
|
|
|
318
314
|
Props extends Record<string, unknown> = Record<string, unknown>
|
|
319
315
|
> extends Server<Env, Props> {
|
|
320
316
|
private _state = DEFAULT_STATE as State;
|
|
321
|
-
private _disposables = new DisposableStore();
|
|
322
317
|
|
|
323
318
|
private _ParentClass: typeof Agent<Env, State> =
|
|
324
319
|
Object.getPrototypeOf(this).constructor;
|
|
325
320
|
|
|
326
|
-
|
|
327
|
-
this._ParentClass.name,
|
|
328
|
-
"0.0.1"
|
|
329
|
-
);
|
|
321
|
+
mcp: MCPClientManager = new MCPClientManager(this._ParentClass.name, "0.0.1");
|
|
330
322
|
|
|
331
323
|
/**
|
|
332
324
|
* Initial state for the Agent
|
|
@@ -419,25 +411,8 @@ export class Agent<
|
|
|
419
411
|
constructor(ctx: AgentContext, env: Env) {
|
|
420
412
|
super(ctx, env);
|
|
421
413
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
this._autoWrapCustomMethods();
|
|
425
|
-
wrappedClasses.add(this.constructor);
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
// Broadcast server state after background connects (for OAuth servers)
|
|
429
|
-
this._disposables.add(
|
|
430
|
-
this.mcp.onConnected(async () => {
|
|
431
|
-
this.broadcastMcpServers();
|
|
432
|
-
})
|
|
433
|
-
);
|
|
434
|
-
|
|
435
|
-
// Emit MCP observability events
|
|
436
|
-
this._disposables.add(
|
|
437
|
-
this.mcp.onObservabilityEvent((event) => {
|
|
438
|
-
this.observability?.emit(event);
|
|
439
|
-
})
|
|
440
|
-
);
|
|
414
|
+
// Auto-wrap custom methods with agent context
|
|
415
|
+
this._autoWrapCustomMethods();
|
|
441
416
|
|
|
442
417
|
this.sql`
|
|
443
418
|
CREATE TABLE IF NOT EXISTS cf_agents_state (
|
|
@@ -494,24 +469,21 @@ export class Agent<
|
|
|
494
469
|
{ agent: this, connection: undefined, request, email: undefined },
|
|
495
470
|
async () => {
|
|
496
471
|
if (this.mcp.isCallbackRequest(request)) {
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
.
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
})
|
|
507
|
-
.finally(() => {
|
|
508
|
-
// Broadcast after background connection resolves (success/failure)
|
|
509
|
-
this.broadcastMcpServers();
|
|
510
|
-
});
|
|
511
|
-
}
|
|
472
|
+
await this.mcp.handleCallbackRequest(request);
|
|
473
|
+
|
|
474
|
+
// after the MCP connection handshake, we can send updated mcp state
|
|
475
|
+
this.broadcast(
|
|
476
|
+
JSON.stringify({
|
|
477
|
+
mcp: this.getMcpServers(),
|
|
478
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
479
|
+
})
|
|
480
|
+
);
|
|
512
481
|
|
|
513
|
-
//
|
|
514
|
-
return
|
|
482
|
+
// We probably should let the user configure this response/redirect, but this is fine for now.
|
|
483
|
+
return new Response("<script>window.close();</script>", {
|
|
484
|
+
headers: { "content-type": "text/html" },
|
|
485
|
+
status: 200
|
|
486
|
+
});
|
|
515
487
|
}
|
|
516
488
|
|
|
517
489
|
return this._tryCatch(() => _onRequest(request));
|
|
@@ -664,20 +636,15 @@ export class Agent<
|
|
|
664
636
|
SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
|
|
665
637
|
`;
|
|
666
638
|
|
|
667
|
-
this.
|
|
639
|
+
this.broadcast(
|
|
640
|
+
JSON.stringify({
|
|
641
|
+
mcp: this.getMcpServers(),
|
|
642
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
643
|
+
})
|
|
644
|
+
);
|
|
668
645
|
|
|
669
646
|
// from DO storage, reconnect to all servers not currently in the oauth flow using our saved auth information
|
|
670
647
|
if (servers && Array.isArray(servers) && servers.length > 0) {
|
|
671
|
-
// Restore callback URLs for OAuth-enabled servers
|
|
672
|
-
servers.forEach((server) => {
|
|
673
|
-
if (server.callback_url) {
|
|
674
|
-
// Register the full redirect URL including serverId to avoid ambiguous matches
|
|
675
|
-
this.mcp.registerCallbackUrl(
|
|
676
|
-
`${server.callback_url}/${server.id}`
|
|
677
|
-
);
|
|
678
|
-
}
|
|
679
|
-
});
|
|
680
|
-
|
|
681
648
|
servers.forEach((server) => {
|
|
682
649
|
this._connectToMcpServerInternal(
|
|
683
650
|
server.name,
|
|
@@ -693,7 +660,12 @@ export class Agent<
|
|
|
693
660
|
)
|
|
694
661
|
.then(() => {
|
|
695
662
|
// Broadcast updated MCP servers state after each server connects
|
|
696
|
-
this.
|
|
663
|
+
this.broadcast(
|
|
664
|
+
JSON.stringify({
|
|
665
|
+
mcp: this.getMcpServers(),
|
|
666
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
667
|
+
})
|
|
668
|
+
);
|
|
697
669
|
})
|
|
698
670
|
.catch((error) => {
|
|
699
671
|
console.error(
|
|
@@ -701,7 +673,12 @@ export class Agent<
|
|
|
701
673
|
error
|
|
702
674
|
);
|
|
703
675
|
// Still broadcast even if connection fails, so clients know about the failure
|
|
704
|
-
this.
|
|
676
|
+
this.broadcast(
|
|
677
|
+
JSON.stringify({
|
|
678
|
+
mcp: this.getMcpServers(),
|
|
679
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
680
|
+
})
|
|
681
|
+
);
|
|
705
682
|
});
|
|
706
683
|
});
|
|
707
684
|
}
|
|
@@ -1394,8 +1371,6 @@ export class Agent<
|
|
|
1394
1371
|
// delete all alarms
|
|
1395
1372
|
await this.ctx.storage.deleteAlarm();
|
|
1396
1373
|
await this.ctx.storage.deleteAll();
|
|
1397
|
-
this._disposables.dispose();
|
|
1398
|
-
await this.mcp.dispose?.();
|
|
1399
1374
|
this.ctx.abort("destroyed"); // enforce that the agent is evicted
|
|
1400
1375
|
|
|
1401
1376
|
this.observability?.emit(
|
|
@@ -1421,42 +1396,25 @@ export class Agent<
|
|
|
1421
1396
|
/**
|
|
1422
1397
|
* Connect to a new MCP Server
|
|
1423
1398
|
*
|
|
1424
|
-
* @param serverName Name of the MCP server
|
|
1425
1399
|
* @param url MCP Server SSE URL
|
|
1426
|
-
* @param callbackHost Base host for the agent, used for the redirect URI.
|
|
1400
|
+
* @param callbackHost Base host for the agent, used for the redirect URI.
|
|
1427
1401
|
* @param agentsPrefix agents routing prefix if not using `agents`
|
|
1428
|
-
* @param options MCP client and transport options
|
|
1402
|
+
* @param options MCP client and transport (header) options
|
|
1429
1403
|
* @returns authUrl
|
|
1430
1404
|
*/
|
|
1431
1405
|
async addMcpServer(
|
|
1432
1406
|
serverName: string,
|
|
1433
1407
|
url: string,
|
|
1434
|
-
callbackHost
|
|
1408
|
+
callbackHost: string,
|
|
1435
1409
|
agentsPrefix = "agents",
|
|
1436
1410
|
options?: {
|
|
1437
1411
|
client?: ConstructorParameters<typeof Client>[1];
|
|
1438
1412
|
transport?: {
|
|
1439
|
-
headers
|
|
1440
|
-
type?: TransportType;
|
|
1413
|
+
headers: HeadersInit;
|
|
1441
1414
|
};
|
|
1442
1415
|
}
|
|
1443
1416
|
): Promise<{ id: string; authUrl: string | undefined }> {
|
|
1444
|
-
|
|
1445
|
-
let resolvedCallbackHost = callbackHost;
|
|
1446
|
-
if (!resolvedCallbackHost) {
|
|
1447
|
-
const { request } = getCurrentAgent();
|
|
1448
|
-
if (!request) {
|
|
1449
|
-
throw new Error(
|
|
1450
|
-
"callbackHost is required when not called within a request context"
|
|
1451
|
-
);
|
|
1452
|
-
}
|
|
1453
|
-
|
|
1454
|
-
// Extract the origin from the request
|
|
1455
|
-
const requestUrl = new URL(request.url);
|
|
1456
|
-
resolvedCallbackHost = `${requestUrl.protocol}//${requestUrl.host}`;
|
|
1457
|
-
}
|
|
1458
|
-
|
|
1459
|
-
const callbackUrl = `${resolvedCallbackHost}/${agentsPrefix}/${camelCaseToKebabCase(this._ParentClass.name)}/${this.name}/callback`;
|
|
1417
|
+
const callbackUrl = `${callbackHost}/${agentsPrefix}/${camelCaseToKebabCase(this._ParentClass.name)}/${this.name}/callback`;
|
|
1460
1418
|
|
|
1461
1419
|
const result = await this._connectToMcpServerInternal(
|
|
1462
1420
|
serverName,
|
|
@@ -1464,7 +1422,6 @@ export class Agent<
|
|
|
1464
1422
|
callbackUrl,
|
|
1465
1423
|
options
|
|
1466
1424
|
);
|
|
1467
|
-
|
|
1468
1425
|
this.sql`
|
|
1469
1426
|
INSERT
|
|
1470
1427
|
OR REPLACE INTO cf_agents_mcp_servers (id, name, server_url, client_id, auth_url, callback_url, server_options)
|
|
@@ -1479,12 +1436,17 @@ export class Agent<
|
|
|
1479
1436
|
);
|
|
1480
1437
|
`;
|
|
1481
1438
|
|
|
1482
|
-
this.
|
|
1439
|
+
this.broadcast(
|
|
1440
|
+
JSON.stringify({
|
|
1441
|
+
mcp: this.getMcpServers(),
|
|
1442
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
1443
|
+
})
|
|
1444
|
+
);
|
|
1483
1445
|
|
|
1484
1446
|
return result;
|
|
1485
1447
|
}
|
|
1486
1448
|
|
|
1487
|
-
|
|
1449
|
+
async _connectToMcpServerInternal(
|
|
1488
1450
|
_serverName: string,
|
|
1489
1451
|
url: string,
|
|
1490
1452
|
callbackUrl: string,
|
|
@@ -1500,7 +1462,6 @@ export class Agent<
|
|
|
1500
1462
|
*/
|
|
1501
1463
|
transport?: {
|
|
1502
1464
|
headers?: HeadersInit;
|
|
1503
|
-
type?: TransportType;
|
|
1504
1465
|
};
|
|
1505
1466
|
},
|
|
1506
1467
|
reconnect?: {
|
|
@@ -1525,9 +1486,6 @@ export class Agent<
|
|
|
1525
1486
|
}
|
|
1526
1487
|
}
|
|
1527
1488
|
|
|
1528
|
-
// Use the transport type specified in options, or default to "auto"
|
|
1529
|
-
const transportType: TransportType = options?.transport?.type ?? "auto";
|
|
1530
|
-
|
|
1531
1489
|
// allows passing through transport headers if necessary
|
|
1532
1490
|
// this handles some non-standard bearer auth setups (i.e. MCP server behind CF access instead of OAuth)
|
|
1533
1491
|
let headerTransportOpts: SSEClientTransportOptions = {};
|
|
@@ -1551,8 +1509,7 @@ export class Agent<
|
|
|
1551
1509
|
reconnect,
|
|
1552
1510
|
transport: {
|
|
1553
1511
|
...headerTransportOpts,
|
|
1554
|
-
authProvider
|
|
1555
|
-
type: transportType
|
|
1512
|
+
authProvider
|
|
1556
1513
|
}
|
|
1557
1514
|
});
|
|
1558
1515
|
|
|
@@ -1565,11 +1522,15 @@ export class Agent<
|
|
|
1565
1522
|
|
|
1566
1523
|
async removeMcpServer(id: string) {
|
|
1567
1524
|
this.mcp.closeConnection(id);
|
|
1568
|
-
this.mcp.unregisterCallbackUrl(id);
|
|
1569
1525
|
this.sql`
|
|
1570
1526
|
DELETE FROM cf_agents_mcp_servers WHERE id = ${id};
|
|
1571
1527
|
`;
|
|
1572
|
-
this.
|
|
1528
|
+
this.broadcast(
|
|
1529
|
+
JSON.stringify({
|
|
1530
|
+
mcp: this.getMcpServers(),
|
|
1531
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
1532
|
+
})
|
|
1533
|
+
);
|
|
1573
1534
|
}
|
|
1574
1535
|
|
|
1575
1536
|
getMcpServers(): MCPServersState {
|
|
@@ -1601,53 +1562,8 @@ export class Agent<
|
|
|
1601
1562
|
|
|
1602
1563
|
return mcpState;
|
|
1603
1564
|
}
|
|
1604
|
-
|
|
1605
|
-
private broadcastMcpServers() {
|
|
1606
|
-
this.broadcast(
|
|
1607
|
-
JSON.stringify({
|
|
1608
|
-
mcp: this.getMcpServers(),
|
|
1609
|
-
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
1610
|
-
})
|
|
1611
|
-
);
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
/**
|
|
1615
|
-
* Handle OAuth callback response using MCPClientManager configuration
|
|
1616
|
-
* @param result OAuth callback result
|
|
1617
|
-
* @param request The original request (needed for base URL)
|
|
1618
|
-
* @returns Response for the OAuth callback
|
|
1619
|
-
*/
|
|
1620
|
-
private handleOAuthCallbackResponse(
|
|
1621
|
-
result: MCPClientOAuthResult,
|
|
1622
|
-
request: Request
|
|
1623
|
-
): Response {
|
|
1624
|
-
const config = this.mcp.getOAuthCallbackConfig();
|
|
1625
|
-
|
|
1626
|
-
// Use custom handler if configured
|
|
1627
|
-
if (config?.customHandler) {
|
|
1628
|
-
return config.customHandler(result);
|
|
1629
|
-
}
|
|
1630
|
-
|
|
1631
|
-
// Use redirect URLs if configured
|
|
1632
|
-
if (config?.successRedirect && result.authSuccess) {
|
|
1633
|
-
return Response.redirect(config.successRedirect);
|
|
1634
|
-
}
|
|
1635
|
-
|
|
1636
|
-
if (config?.errorRedirect && !result.authSuccess) {
|
|
1637
|
-
return Response.redirect(
|
|
1638
|
-
`${config.errorRedirect}?error=${encodeURIComponent(result.authError || "Unknown error")}`
|
|
1639
|
-
);
|
|
1640
|
-
}
|
|
1641
|
-
|
|
1642
|
-
// Default behavior - redirect to base URL
|
|
1643
|
-
const baseUrl = new URL(request.url).origin;
|
|
1644
|
-
return Response.redirect(baseUrl);
|
|
1645
|
-
}
|
|
1646
1565
|
}
|
|
1647
1566
|
|
|
1648
|
-
// A set of classes that have been wrapped with agent context
|
|
1649
|
-
const wrappedClasses = new Set<typeof Agent.prototype.constructor>();
|
|
1650
|
-
|
|
1651
1567
|
/**
|
|
1652
1568
|
* Namespace for creating Agent instances
|
|
1653
1569
|
* @template Agentic Type of the Agent class
|