agents 0.0.87 → 0.0.88

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.
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  Agent
3
- } from "./chunk-J6T74FUS.js";
4
- import "./chunk-BZXOAZUX.js";
5
- import "./chunk-QSGN3REV.js";
3
+ } from "./chunk-VNSFDJYL.js";
6
4
  import "./chunk-Y67CHZBI.js";
5
+ import "./chunk-BZXOAZUX.js";
6
+ import "./chunk-VCSB47AK.js";
7
7
 
8
8
  // src/ai-chat-agent.ts
9
9
  import { appendResponseMessages } from "ai";
@@ -16,6 +16,7 @@ import "@modelcontextprotocol/sdk/client/auth.js";
16
16
  import "@modelcontextprotocol/sdk/shared/auth.js";
17
17
  import "@modelcontextprotocol/sdk/shared/protocol.js";
18
18
  import "./client.js";
19
+ import "./serializable.js";
19
20
 
20
21
  type GetInitialMessagesOptions = {
21
22
  agent: string;
@@ -76,13 +76,6 @@ var AgentClient = class extends PartySocket {
76
76
  this.send(JSON.stringify({ type: "cf_agent_state", state }));
77
77
  this.options.onStateUpdate?.(state, "client");
78
78
  }
79
- /**
80
- * Call a method on the Agent
81
- * @param method Name of the method to call
82
- * @param args Arguments to pass to the method
83
- * @param streamOptions Options for handling streaming responses
84
- * @returns Promise that resolves with the method's return value
85
- */
86
79
  async call(method, args = [], streamOptions) {
87
80
  return new Promise((resolve, reject) => {
88
81
  const id = Math.random().toString(36).slice(2);
@@ -120,4 +113,4 @@ export {
120
113
  AgentClient,
121
114
  agentFetch
122
115
  };
123
- //# sourceMappingURL=chunk-QSGN3REV.js.map
116
+ //# sourceMappingURL=chunk-VCSB47AK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"sourcesContent":["import {\n PartySocket,\n type PartySocketOptions,\n type PartyFetchOptions,\n} from \"partysocket\";\nimport type { RPCRequest, RPCResponse } from \"./\";\nimport type {\n SerializableReturnValue,\n SerializableValue,\n} from \"./serializable\";\n\n/**\n * Options for creating an AgentClient\n */\nexport type AgentClientOptions<State = unknown> = Omit<\n PartySocketOptions,\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};\n\n/**\n * Options for streaming RPC calls\n */\nexport type StreamOptions = {\n /** Called when a chunk of data is received */\n onChunk?: (chunk: unknown) => void;\n /** Called when the stream ends */\n onDone?: (finalChunk: unknown) => void;\n /** Called when an error occurs */\n onError?: (error: string) => void;\n};\n\n/**\n * Options for the agentFetch function\n */\nexport type AgentClientFetchOptions = Omit<\n PartyFetchOptions,\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};\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 */\nexport function 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 * WebSocket client for connecting to an Agent\n */\nexport class AgentClient<State = unknown> extends PartySocket {\n /**\n * @deprecated Use agentFetch instead\n */\n static fetch(_opts: PartyFetchOptions): Promise<Response> {\n throw new Error(\n \"AgentClient.fetch is not implemented, use agentFetch instead\"\n );\n }\n agent: string;\n name: string;\n private options: AgentClientOptions<State>;\n private _pendingCalls = new Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n stream?: StreamOptions;\n type?: unknown;\n }\n >();\n\n constructor(options: AgentClientOptions<State>) {\n const agentNamespace = camelCaseToKebabCase(options.agent);\n super({\n prefix: \"agents\",\n party: agentNamespace,\n room: options.name || \"default\",\n ...options,\n });\n this.agent = agentNamespace;\n this.name = options.name || \"default\";\n this.options = options;\n\n this.addEventListener(\"message\", (event) => {\n if (typeof event.data === \"string\") {\n let parsedMessage: Record<string, unknown>;\n try {\n parsedMessage = JSON.parse(event.data);\n } catch (error) {\n // silently ignore invalid messages for now\n // TODO: log errors with log levels\n return;\n }\n if (parsedMessage.type === \"cf_agent_state\") {\n this.options.onStateUpdate?.(parsedMessage.state as State, \"server\");\n return;\n }\n if (parsedMessage.type === \"rpc\") {\n const response = parsedMessage as RPCResponse;\n const pending = this._pendingCalls.get(response.id);\n if (!pending) return;\n\n if (!response.success) {\n pending.reject(new Error(response.error));\n this._pendingCalls.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 this._pendingCalls.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 this._pendingCalls.delete(response.id);\n }\n }\n }\n });\n }\n\n setState(state: State) {\n this.send(JSON.stringify({ type: \"cf_agent_state\", state }));\n this.options.onStateUpdate?.(state, \"client\");\n }\n\n /**\n * Call a method on the Agent\n * @param method Name of the method to call\n * @param args Arguments to pass to the method\n * @param streamOptions Options for handling streaming responses\n * @returns Promise that resolves with the method's return value\n */\n call<T extends SerializableReturnValue>(\n method: string,\n args?: SerializableValue[],\n streamOptions?: StreamOptions\n ): Promise<T>;\n call<T = unknown>(\n method: string,\n args?: unknown[],\n streamOptions?: StreamOptions\n ): Promise<T>;\n async call<T>(\n method: string,\n args: unknown[] = [],\n streamOptions?: StreamOptions\n ): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const id = Math.random().toString(36).slice(2);\n this._pendingCalls.set(id, {\n resolve: (value: unknown) => resolve(value as T),\n reject,\n stream: streamOptions,\n type: null as T,\n });\n\n const request: RPCRequest = {\n type: \"rpc\",\n id,\n method,\n args,\n };\n\n this.send(JSON.stringify(request));\n });\n }\n}\n\n/**\n * Make an HTTP request to an Agent\n * @param opts Connection options\n * @param init Request initialization options\n * @returns Promise resolving to a Response\n */\nexport function agentFetch(opts: AgentClientFetchOptions, init?: RequestInit) {\n const agentNamespace = camelCaseToKebabCase(opts.agent);\n\n return PartySocket.fetch(\n {\n prefix: \"agents\",\n party: agentNamespace,\n room: opts.name || \"default\",\n ...opts,\n },\n init\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,12 +1,12 @@
1
+ import {
2
+ MCPClientManager
3
+ } from "./chunk-Y67CHZBI.js";
1
4
  import {
2
5
  DurableObjectOAuthClientProvider
3
6
  } from "./chunk-BZXOAZUX.js";
4
7
  import {
5
8
  camelCaseToKebabCase
6
- } from "./chunk-QSGN3REV.js";
7
- import {
8
- MCPClientManager
9
- } from "./chunk-Y67CHZBI.js";
9
+ } from "./chunk-VCSB47AK.js";
10
10
 
11
11
  // src/index.ts
12
12
  import {
@@ -780,4 +780,4 @@ export {
780
780
  getAgentByName,
781
781
  StreamingResponse
782
782
  };
783
- //# sourceMappingURL=chunk-J6T74FUS.js.map
783
+ //# sourceMappingURL=chunk-VNSFDJYL.js.map
package/dist/client.d.ts CHANGED
@@ -3,6 +3,7 @@ import {
3
3
  PartyFetchOptions,
4
4
  PartySocket,
5
5
  } from "partysocket";
6
+ import { SerializableReturnValue, SerializableValue } from "./serializable.js";
6
7
 
7
8
  /**
8
9
  * Options for creating an AgentClient
@@ -65,6 +66,11 @@ declare class AgentClient<State = unknown> extends PartySocket {
65
66
  * @param streamOptions Options for handling streaming responses
66
67
  * @returns Promise that resolves with the method's return value
67
68
  */
69
+ call<T extends SerializableReturnValue>(
70
+ method: string,
71
+ args?: SerializableValue[],
72
+ streamOptions?: StreamOptions
73
+ ): Promise<T>;
68
74
  call<T = unknown>(
69
75
  method: string,
70
76
  args?: unknown[],
package/dist/client.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  AgentClient,
3
3
  agentFetch,
4
4
  camelCaseToKebabCase
5
- } from "./chunk-QSGN3REV.js";
5
+ } from "./chunk-VCSB47AK.js";
6
6
  export {
7
7
  AgentClient,
8
8
  agentFetch,
package/dist/index.js CHANGED
@@ -6,10 +6,10 @@ import {
6
6
  routeAgentEmail,
7
7
  routeAgentRequest,
8
8
  unstable_callable
9
- } from "./chunk-J6T74FUS.js";
10
- import "./chunk-BZXOAZUX.js";
11
- import "./chunk-QSGN3REV.js";
9
+ } from "./chunk-VNSFDJYL.js";
12
10
  import "./chunk-Y67CHZBI.js";
11
+ import "./chunk-BZXOAZUX.js";
12
+ import "./chunk-VCSB47AK.js";
13
13
  export {
14
14
  Agent,
15
15
  StreamingResponse,
package/dist/mcp/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  Agent
3
- } from "../chunk-J6T74FUS.js";
4
- import "../chunk-BZXOAZUX.js";
5
- import "../chunk-QSGN3REV.js";
3
+ } from "../chunk-VNSFDJYL.js";
6
4
  import "../chunk-Y67CHZBI.js";
5
+ import "../chunk-BZXOAZUX.js";
6
+ import "../chunk-VCSB47AK.js";
7
7
 
8
8
  // src/mcp/index.ts
9
9
  import { DurableObject } from "cloudflare:workers";
package/dist/react.d.ts CHANGED
@@ -2,6 +2,7 @@ import { PartySocket } from "partysocket";
2
2
  import { usePartySocket } from "partysocket/react";
3
3
  import { MCPServersState, Agent } from "./index.js";
4
4
  import { StreamOptions } from "./client.js";
5
+ import { Method, RPCMethod } from "./serializable.js";
5
6
  import "partyserver";
6
7
  import "./mcp/client.js";
7
8
  import "zod";
@@ -36,34 +37,54 @@ type AllOptional<T> = T extends [infer A, ...infer R]
36
37
  ? AllOptional<R>
37
38
  : false
38
39
  : true;
39
- type Method = (...args: any) => any;
40
- type Methods<T> = {
41
- [K in keyof T as T[K] extends Method ? K : never]: T[K];
40
+ type RPCMethods<T> = {
41
+ [K in keyof T as T[K] extends RPCMethod<T[K]> ? K : never]: RPCMethod<T[K]>;
42
42
  };
43
- type OptionalParametersMethod<T> = T extends Method
44
- ? AllOptional<Parameters<T>> extends true
45
- ? T
46
- : never
47
- : never;
48
- type AgentMethods<T> = Omit<Methods<T>, keyof Agent<any, any>>;
43
+ type OptionalParametersMethod<T extends RPCMethod> =
44
+ AllOptional<Parameters<T>> extends true ? T : never;
45
+ type AgentMethods<T> = Omit<RPCMethods<T>, keyof Agent<any, any>>;
49
46
  type OptionalAgentMethods<T> = {
50
- [K in keyof AgentMethods<T> as T[K] extends OptionalParametersMethod<T[K]>
47
+ [K in keyof AgentMethods<T> as AgentMethods<T>[K] extends OptionalParametersMethod<
48
+ AgentMethods<T>[K]
49
+ >
51
50
  ? K
52
- : never]: OptionalParametersMethod<T[K]>;
51
+ : never]: OptionalParametersMethod<AgentMethods<T>[K]>;
53
52
  };
54
53
  type RequiredAgentMethods<T> = Omit<
55
54
  AgentMethods<T>,
56
55
  keyof OptionalAgentMethods<T>
57
56
  >;
58
- type AgentPromiseReturnType<T extends AgentMethods<T>, K extends keyof T> =
59
- ReturnType<T[K]> extends Promise<any>
60
- ? ReturnType<T[K]>
61
- : Promise<ReturnType<T[K]>>;
62
- type AgentStub<T extends AgentMethods<T>> = {
57
+ type AgentPromiseReturnType<T, K extends keyof AgentMethods<T>> =
58
+ ReturnType<AgentMethods<T>[K]> extends Promise<any>
59
+ ? ReturnType<AgentMethods<T>[K]>
60
+ : Promise<ReturnType<AgentMethods<T>[K]>>;
61
+ type OptionalArgsAgentMethodCall<AgentT> = <
62
+ K extends keyof OptionalAgentMethods<AgentT>,
63
+ >(
64
+ method: K,
65
+ args?: Parameters<OptionalAgentMethods<AgentT>[K]>,
66
+ streamOptions?: StreamOptions
67
+ ) => AgentPromiseReturnType<AgentT, K>;
68
+ type RequiredArgsAgentMethodCall<AgentT> = <
69
+ K extends keyof RequiredAgentMethods<AgentT>,
70
+ >(
71
+ method: K,
72
+ args: Parameters<RequiredAgentMethods<AgentT>[K]>,
73
+ streamOptions?: StreamOptions
74
+ ) => AgentPromiseReturnType<AgentT, K>;
75
+ type AgentMethodCall<AgentT> = OptionalArgsAgentMethodCall<AgentT> &
76
+ RequiredArgsAgentMethodCall<AgentT>;
77
+ type UntypedAgentMethodCall = <T = unknown>(
78
+ method: string,
79
+ args?: unknown[],
80
+ streamOptions?: StreamOptions
81
+ ) => Promise<T>;
82
+ type AgentStub<T> = {
63
83
  [K in keyof AgentMethods<T>]: (
64
- ...args: Parameters<T[K]>
84
+ ...args: Parameters<AgentMethods<T>[K]>
65
85
  ) => AgentPromiseReturnType<AgentMethods<T>, K>;
66
86
  };
87
+ type UntypedAgentStub = Record<string, Method>;
67
88
  /**
68
89
  * React hook for connecting to an Agent
69
90
  * @template State Type of the Agent's state
@@ -77,12 +98,8 @@ declare function useAgent<State = unknown>(
77
98
  agent: string;
78
99
  name: string;
79
100
  setState: (state: State) => void;
80
- call: <T = unknown>(
81
- method: string,
82
- args?: unknown[],
83
- streamOptions?: StreamOptions
84
- ) => Promise<T>;
85
- stub: Record<string, Method>;
101
+ call: UntypedAgentMethodCall;
102
+ stub: UntypedAgentStub;
86
103
  };
87
104
  declare function useAgent<
88
105
  AgentT extends {
@@ -95,16 +112,7 @@ declare function useAgent<
95
112
  agent: string;
96
113
  name: string;
97
114
  setState: (state: State) => void;
98
- call: (<T extends keyof OptionalAgentMethods<AgentT>>(
99
- method: T,
100
- args?: Parameters<OptionalAgentMethods<AgentT>[T]>,
101
- streamOptions?: StreamOptions
102
- ) => AgentPromiseReturnType<AgentT, T>) &
103
- (<T extends keyof RequiredAgentMethods<AgentT>>(
104
- method: T,
105
- args: Parameters<RequiredAgentMethods<AgentT>[T]>,
106
- streamOptions?: StreamOptions
107
- ) => AgentPromiseReturnType<AgentT, T>);
115
+ call: AgentMethodCall<AgentT>;
108
116
  stub: AgentStub<AgentT>;
109
117
  };
110
118
 
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 } from \"react\";\nimport type { MCPServersState, RPCRequest, RPCResponse, Agent } from \"./\";\nimport type { StreamOptions } from \"./client\";\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\n// biome-ignore lint: suppressions/parse\ntype Method = (...args: any) => any;\n\ntype Methods<T> = {\n [K in keyof T as T[K] extends Method ? K : never]: T[K];\n};\n\ntype OptionalParametersMethod<T> = T extends Method\n ? AllOptional<Parameters<T>> extends true\n ? T\n : never\n : 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<Methods<T>, keyof Agent<any, any>>;\n\ntype OptionalAgentMethods<T> = {\n [K in keyof AgentMethods<T> as T[K] extends OptionalParametersMethod<T[K]>\n ? K\n : never]: OptionalParametersMethod<T[K]>;\n};\n\ntype RequiredAgentMethods<T> = Omit<\n AgentMethods<T>,\n keyof OptionalAgentMethods<T>\n>;\n\ntype AgentPromiseReturnType<T extends AgentMethods<T>, K extends keyof T> =\n // biome-ignore lint: suppressions/parse\n ReturnType<T[K]> extends Promise<any>\n ? ReturnType<T[K]>\n : Promise<ReturnType<T[K]>>;\n\ntype AgentStub<T extends AgentMethods<T>> = {\n [K in keyof AgentMethods<T>]: (\n ...args: Parameters<T[K]>\n ) => AgentPromiseReturnType<AgentMethods<T>, K>;\n};\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: <T = unknown>(\n method: string,\n args?: unknown[],\n streamOptions?: StreamOptions\n ) => Promise<T>;\n stub: Record<string, Method>;\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: (<T extends keyof OptionalAgentMethods<AgentT>>(\n method: T,\n args?: Parameters<OptionalAgentMethods<AgentT>[T]>,\n streamOptions?: StreamOptions\n ) => AgentPromiseReturnType<AgentT, T>) &\n (<T extends keyof RequiredAgentMethods<AgentT>>(\n method: T,\n args: Parameters<RequiredAgentMethods<AgentT>[T]>,\n streamOptions?: StreamOptions\n ) => AgentPromiseReturnType<AgentT, T>);\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: <T = unknown>(\n method: string,\n args?: unknown[],\n streamOptions?: StreamOptions\n ) => Promise<T>;\n stub: Record<string, Method>;\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 prefix: \"agents\",\n party: agentNamespace,\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 === \"cf_agent_state\") {\n options.onStateUpdate?.(parsedMessage.state as State, \"server\");\n return;\n }\n if (parsedMessage.type === \"cf_agent_mcp_servers\") {\n options.onMcpUpdate?.(parsedMessage.mcp as MCPServersState);\n return;\n }\n if (parsedMessage.type === \"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: <T = unknown>(\n method: string,\n args?: unknown[],\n streamOptions?: StreamOptions\n ) => Promise<T>;\n stub: Record<string, Method>;\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 resolve: resolve as (value: unknown) => void,\n reject,\n stream: streamOptions,\n });\n\n const request: RPCRequest = {\n type: \"rpc\",\n id,\n method,\n args,\n };\n\n agent.send(JSON.stringify(request));\n });\n },\n [agent]\n );\n\n agent.setState = (state: State) => {\n agent.send(JSON.stringify({ type: \"cf_agent_state\", 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 { MCPServersState, RPCRequest, RPCResponse, Agent } from \"./\";\nimport type { StreamOptions } from \"./client\";\nimport type { Method, RPCMethod } from \"./serializable\";\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 prefix: \"agents\",\n party: agentNamespace,\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 === \"cf_agent_state\") {\n options.onStateUpdate?.(parsedMessage.state as State, \"server\");\n return;\n }\n if (parsedMessage.type === \"cf_agent_mcp_servers\") {\n options.onMcpUpdate?.(parsedMessage.mcp as MCPServersState);\n return;\n }\n if (parsedMessage.type === \"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 resolve: resolve as (value: unknown) => void,\n reject,\n stream: streamOptions,\n });\n\n const request: RPCRequest = {\n type: \"rpc\",\n id,\n method,\n args,\n };\n\n agent.send(JSON.stringify(request));\n });\n },\n [agent]\n );\n\n agent.setState = (state: State) => {\n agent.send(JSON.stringify({ type: \"cf_agent_state\", 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":[]}
@@ -0,0 +1,32 @@
1
+ type SerializableValue =
2
+ | undefined
3
+ | null
4
+ | string
5
+ | number
6
+ | boolean
7
+ | {
8
+ [key: string]: SerializableValue;
9
+ }
10
+ | SerializableValue[];
11
+ type SerializableReturnValue =
12
+ | SerializableValue
13
+ | void
14
+ | Promise<SerializableValue>
15
+ | Promise<void>;
16
+ type AllSerializableValues<A> = A extends [infer First, ...infer Rest]
17
+ ? First extends SerializableValue
18
+ ? AllSerializableValues<Rest>
19
+ : false
20
+ : true;
21
+ type Method = (...args: any[]) => any;
22
+ type RPCMethod<T = Method> = T extends Method
23
+ ? T extends (...arg: infer A) => infer R
24
+ ? AllSerializableValues<A> extends true
25
+ ? R extends SerializableReturnValue
26
+ ? T
27
+ : never
28
+ : never
29
+ : never
30
+ : never;
31
+
32
+ export type { Method, RPCMethod, SerializableReturnValue, SerializableValue };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=serializable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agents",
3
- "version": "0.0.87",
3
+ "version": "0.0.88",
4
4
  "main": "src/index.ts",
5
5
  "types": "dist/index.d.ts",
6
6
  "type": "module",
@@ -8,9 +8,8 @@
8
8
  "check:test": "npm run check:test:workers && npm run check:test:react",
9
9
  "check:test:workers": "vitest -r src/tests --watch false",
10
10
  "check:test:react": "vitest -r src/react-tests --watch false",
11
- "test": "vitest -r src/tests && npm run test:types",
11
+ "test": "vitest -r src/tests",
12
12
  "test:react": "vitest -r src/react-tests",
13
- "test:types": "tsc",
14
13
  "evals": "(cd evals; evalite)",
15
14
  "build": "tsx ./scripts/build.ts"
16
15
  },
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/client.ts"],"sourcesContent":["import {\n PartySocket,\n type PartySocketOptions,\n type PartyFetchOptions,\n} from \"partysocket\";\nimport type { RPCRequest, RPCResponse } from \"./\";\n\n/**\n * Options for creating an AgentClient\n */\nexport type AgentClientOptions<State = unknown> = Omit<\n PartySocketOptions,\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};\n\n/**\n * Options for streaming RPC calls\n */\nexport type StreamOptions = {\n /** Called when a chunk of data is received */\n onChunk?: (chunk: unknown) => void;\n /** Called when the stream ends */\n onDone?: (finalChunk: unknown) => void;\n /** Called when an error occurs */\n onError?: (error: string) => void;\n};\n\n/**\n * Options for the agentFetch function\n */\nexport type AgentClientFetchOptions = Omit<\n PartyFetchOptions,\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};\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 */\nexport function 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 * WebSocket client for connecting to an Agent\n */\nexport class AgentClient<State = unknown> extends PartySocket {\n /**\n * @deprecated Use agentFetch instead\n */\n static fetch(_opts: PartyFetchOptions): Promise<Response> {\n throw new Error(\n \"AgentClient.fetch is not implemented, use agentFetch instead\"\n );\n }\n agent: string;\n name: string;\n private options: AgentClientOptions<State>;\n private _pendingCalls = new Map<\n string,\n {\n resolve: (value: unknown) => void;\n reject: (error: Error) => void;\n stream?: StreamOptions;\n type?: unknown;\n }\n >();\n\n constructor(options: AgentClientOptions<State>) {\n const agentNamespace = camelCaseToKebabCase(options.agent);\n super({\n prefix: \"agents\",\n party: agentNamespace,\n room: options.name || \"default\",\n ...options,\n });\n this.agent = agentNamespace;\n this.name = options.name || \"default\";\n this.options = options;\n\n this.addEventListener(\"message\", (event) => {\n if (typeof event.data === \"string\") {\n let parsedMessage: Record<string, unknown>;\n try {\n parsedMessage = JSON.parse(event.data);\n } catch (error) {\n // silently ignore invalid messages for now\n // TODO: log errors with log levels\n return;\n }\n if (parsedMessage.type === \"cf_agent_state\") {\n this.options.onStateUpdate?.(parsedMessage.state as State, \"server\");\n return;\n }\n if (parsedMessage.type === \"rpc\") {\n const response = parsedMessage as RPCResponse;\n const pending = this._pendingCalls.get(response.id);\n if (!pending) return;\n\n if (!response.success) {\n pending.reject(new Error(response.error));\n this._pendingCalls.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 this._pendingCalls.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 this._pendingCalls.delete(response.id);\n }\n }\n }\n });\n }\n\n setState(state: State) {\n this.send(JSON.stringify({ type: \"cf_agent_state\", state }));\n this.options.onStateUpdate?.(state, \"client\");\n }\n\n /**\n * Call a method on the Agent\n * @param method Name of the method to call\n * @param args Arguments to pass to the method\n * @param streamOptions Options for handling streaming responses\n * @returns Promise that resolves with the method's return value\n */\n async call<T = unknown>(\n method: string,\n args: unknown[] = [],\n streamOptions?: StreamOptions\n ): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const id = Math.random().toString(36).slice(2);\n this._pendingCalls.set(id, {\n resolve: (value: unknown) => resolve(value as T),\n reject,\n stream: streamOptions,\n type: null as T,\n });\n\n const request: RPCRequest = {\n type: \"rpc\",\n id,\n method,\n args,\n };\n\n this.send(JSON.stringify(request));\n });\n }\n}\n\n/**\n * Make an HTTP request to an Agent\n * @param opts Connection options\n * @param init Request initialization options\n * @returns Promise resolving to a Response\n */\nexport function agentFetch(opts: AgentClientFetchOptions, init?: RequestInit) {\n const agentNamespace = camelCaseToKebabCase(opts.agent);\n\n return PartySocket.fetch(\n {\n prefix: \"agents\",\n party: agentNamespace,\n room: opts.name || \"default\",\n ...opts,\n },\n init\n );\n}\n"],"mappings":"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","names":[]}