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.
- package/README.md +5 -3
- package/dist/ai-chat-agent.d.ts +86 -13
- package/dist/ai-chat-agent.js +340 -74
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/{ai-chat-v5-migration-gdyLiTd8.js → ai-chat-v5-migration-BSiGZmYU.js} +2 -2
- package/dist/{ai-chat-v5-migration-gdyLiTd8.js.map → ai-chat-v5-migration-BSiGZmYU.js.map} +1 -1
- package/dist/ai-chat-v5-migration.js +1 -1
- package/dist/ai-react.d.ts +14 -9
- package/dist/ai-react.js +172 -36
- package/dist/ai-react.js.map +1 -1
- package/dist/{ai-types-BWW4umHY.d.ts → ai-types-81H_-Uxh.d.ts} +16 -8
- package/dist/{ai-types-UZlfLOYP.js → ai-types-CrMqkwc_.js} +6 -2
- package/dist/ai-types-CrMqkwc_.js.map +1 -0
- package/dist/ai-types.d.ts +4 -4
- package/dist/ai-types.js +1 -1
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +27 -0
- package/dist/cli.js.map +1 -0
- package/dist/{client-DjR-lC16.js → client-B3SR12TQ.js} +3 -3
- package/dist/{client-DjR-lC16.js.map → client-B3SR12TQ.js.map} +1 -1
- package/dist/{client-CmMi85Sj.d.ts → client-BAQA84dr.d.ts} +10 -10
- package/dist/client-BZq9qau2.js +1093 -0
- package/dist/client-BZq9qau2.js.map +1 -0
- package/dist/client-CsaP9Irq.d.ts +1528 -0
- package/dist/client.d.ts +8 -8
- package/dist/client.js +2 -2
- package/dist/codemode/ai.js +5 -5
- package/dist/{do-oauth-client-provider-CCwGwnrA.d.ts → do-oauth-client-provider-C2CHH5x-.d.ts} +2 -2
- package/dist/{do-oauth-client-provider-B2jr6UNq.js → do-oauth-client-provider-CwqK5SXm.js} +3 -2
- package/dist/do-oauth-client-provider-CwqK5SXm.js.map +1 -0
- package/dist/{index-W4JUkafc.d.ts → index-BUle9RiP.d.ts} +7 -3
- package/dist/{index-CkQU40oY.d.ts → index-Bx5KK3VJ.d.ts} +75 -46
- package/dist/index.d.ts +36 -36
- package/dist/index.js +5 -5
- package/dist/mcp/client.d.ts +4 -4
- package/dist/mcp/client.js +2 -1
- package/dist/mcp/do-oauth-client-provider.d.ts +1 -1
- package/dist/mcp/do-oauth-client-provider.js +1 -1
- package/dist/mcp/index.d.ts +129 -11
- package/dist/mcp/index.js +632 -32
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/x402.js +10 -6
- package/dist/mcp/x402.js.map +1 -1
- package/dist/{mcp-BEwaCsxO.d.ts → mcp-BwPscEiF.d.ts} +2 -2
- package/dist/observability/index.d.ts +2 -2
- package/dist/observability/index.js +5 -5
- package/dist/{react-B4e1rDid.d.ts → react-CbwD4fBf.d.ts} +17 -17
- package/dist/react.d.ts +9 -9
- package/dist/react.js +2 -2
- package/dist/react.js.map +1 -1
- package/dist/{serializable-gtr9YMhp.d.ts → serializable-faDkMCai.d.ts} +8 -3
- package/dist/serializable.d.ts +5 -5
- package/dist/{src-COfG--3R.js → src-D_KKH_4c.js} +125 -120
- package/dist/src-D_KKH_4c.js.map +1 -0
- package/package.json +55 -40
- package/dist/ai-types-UZlfLOYP.js.map +0 -1
- package/dist/client-C-nwz-3N.d.ts +0 -5313
- package/dist/client-CZBVDDoO.js +0 -786
- package/dist/client-CZBVDDoO.js.map +0 -1
- package/dist/do-oauth-client-provider-B2jr6UNq.js.map +0 -1
- package/dist/src-COfG--3R.js.map +0 -1
- package/src/index.ts +0 -2031
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { StreamOptions } from "./client-
|
|
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 {
|
|
113
|
-
//# sourceMappingURL=react-
|
|
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-
|
|
2
|
-
import "./mcp-
|
|
3
|
-
import "./do-oauth-client-provider-
|
|
4
|
-
import "./index-
|
|
5
|
-
import "./ai-types-
|
|
6
|
-
import "./index-
|
|
7
|
-
import "./serializable-
|
|
8
|
-
import "./client-
|
|
9
|
-
import {
|
|
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-
|
|
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
|
|
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 {
|
|
34
|
-
|
|
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
|
package/dist/serializable.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
RPCMethod,
|
|
4
|
-
SerializableReturnValue,
|
|
5
|
-
|
|
6
|
-
} from "./serializable-
|
|
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-
|
|
2
|
-
import { camelCaseToKebabCase } from "./client-
|
|
3
|
-
import { DisposableStore, MCPClientManager } from "./client-
|
|
4
|
-
import { DurableObjectOAuthClientProvider } from "./do-oauth-client-provider-
|
|
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
|
|
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.
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
|
249
|
-
id TEXT PRIMARY KEY NOT NULL,
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
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
|
-
|
|
267
|
-
|
|
268
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|
-
|
|
862
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
904
|
-
|
|
905
|
-
id
|
|
876
|
+
id,
|
|
877
|
+
state: MCPConnectionState.READY
|
|
906
878
|
};
|
|
907
879
|
}
|
|
908
880
|
async removeMcpServer(id) {
|
|
909
|
-
this.mcp.
|
|
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.
|
|
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 ??
|
|
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
|
-
|
|
955
|
-
if (config?.
|
|
956
|
-
|
|
957
|
-
|
|
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")
|
|
984
|
-
|
|
985
|
-
|
|
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 {
|
|
1179
|
-
//# sourceMappingURL=src-
|
|
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
|