agents 0.0.0-7d72faa → 0.0.0-7e0777b

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/package.json CHANGED
@@ -1,101 +1,101 @@
1
1
  {
2
- "name": "agents",
3
- "version": "0.0.0-7d72faa",
4
- "main": "src/index.ts",
5
- "types": "dist/index.d.ts",
6
- "type": "module",
7
- "scripts": {
8
- "check:test": "npm run check:test:workers && npm run check:test:react",
9
- "check:test:workers": "vitest -r src/tests --watch false",
10
- "check:test:react": "vitest -r src/react-tests --watch false",
11
- "test": "vitest -r src/tests",
12
- "test:react": "vitest -r src/react-tests",
13
- "evals": "(cd evals; evalite)",
14
- "build": "tsx ./scripts/build.ts"
2
+ "author": "Cloudflare Inc.",
3
+ "bugs": {
4
+ "url": "https://github.com/cloudflare/agents/issues"
5
+ },
6
+ "dependencies": {
7
+ "@modelcontextprotocol/sdk": "^1.13.0",
8
+ "ai": "^4.3.16",
9
+ "cron-schedule": "^5.0.4",
10
+ "nanoid": "^5.1.5",
11
+ "partyserver": "^0.0.72",
12
+ "partysocket": "1.1.4",
13
+ "zod": "^3.25.67"
14
+ },
15
+ "description": "A home for your AI agents",
16
+ "devDependencies": {
17
+ "@cloudflare/vitest-pool-workers": "^0.8.43",
18
+ "react": "*",
19
+ "vitest-browser-react": "^0.3.0"
15
20
  },
16
- "files": [
17
- "dist",
18
- "README.md"
19
- ],
20
21
  "exports": {
21
22
  ".": {
22
- "types": "./dist/index.d.ts",
23
+ "import": "./dist/index.js",
23
24
  "require": "./dist/index.js",
24
- "import": "./dist/index.js"
25
+ "types": "./dist/index.d.ts"
25
26
  },
26
- "./client": {
27
- "types": "./dist/client.d.ts",
28
- "require": "./dist/client.js",
29
- "import": "./dist/client.js"
30
- },
31
- "./react": {
32
- "types": "./dist/react.d.ts",
33
- "require": "./dist/react.js",
34
- "import": "./dist/react.js"
27
+ "./ai-chat-agent": {
28
+ "import": "./dist/ai-chat-agent.js",
29
+ "require": "./dist/ai-chat-agent.js",
30
+ "types": "./dist/ai-chat-agent.d.ts"
35
31
  },
36
32
  "./ai-react": {
37
- "types": "./dist/ai-react.d.ts",
33
+ "import": "./dist/ai-react.js",
38
34
  "require": "./dist/ai-react.js",
39
- "import": "./dist/ai-react.js"
40
- },
41
- "./ai-chat-agent": {
42
- "types": "./dist/ai-chat-agent.d.ts",
43
- "require": "./dist/ai-chat-agent.js",
44
- "import": "./dist/ai-chat-agent.js"
35
+ "types": "./dist/ai-react.d.ts"
45
36
  },
46
37
  "./ai-types": {
47
- "types": "./dist/ai-types.d.ts",
38
+ "import": "./dist/ai-types.js",
48
39
  "require": "./dist/ai-types.js",
49
- "import": "./dist/ai-types.js"
40
+ "types": "./dist/ai-types.d.ts"
50
41
  },
51
- "./schedule": {
52
- "types": "./dist/schedule.d.ts",
53
- "require": "./dist/schedule.js",
54
- "import": "./dist/schedule.js"
42
+ "./client": {
43
+ "import": "./dist/client.js",
44
+ "require": "./dist/client.js",
45
+ "types": "./dist/client.d.ts"
55
46
  },
56
47
  "./mcp": {
57
- "types": "./dist/mcp/index.d.ts",
48
+ "import": "./dist/mcp/index.js",
58
49
  "require": "./dist/mcp/index.js",
59
- "import": "./dist/mcp/index.js"
50
+ "types": "./dist/mcp/index.d.ts"
60
51
  },
61
52
  "./mcp/client": {
62
- "types": "./dist/mcp/client.d.ts",
53
+ "import": "./dist/mcp/client.js",
63
54
  "require": "./dist/mcp/client.js",
64
- "import": "./dist/mcp/client.js"
55
+ "types": "./dist/mcp/client.d.ts"
65
56
  },
66
57
  "./mcp/do-oauth-client-provider": {
67
- "types": "./dist/mcp/do-oauth-client-provider.d.ts",
58
+ "import": "./dist/mcp/do-oauth-client-provider.js",
68
59
  "require": "./dist/mcp/do-oauth-client-provider.js",
69
- "import": "./dist/mcp/do-oauth-client-provider.js"
60
+ "types": "./dist/mcp/do-oauth-client-provider.d.ts"
61
+ },
62
+ "./react": {
63
+ "import": "./dist/react.js",
64
+ "require": "./dist/react.js",
65
+ "types": "./dist/react.d.ts"
66
+ },
67
+ "./schedule": {
68
+ "import": "./dist/schedule.js",
69
+ "require": "./dist/schedule.js",
70
+ "types": "./dist/schedule.d.ts"
70
71
  }
71
72
  },
73
+ "files": [
74
+ "dist",
75
+ "README.md"
76
+ ],
72
77
  "keywords": [],
73
- "repository": {
74
- "type": "git",
75
- "url": "git+https://github.com/cloudflare/agents.git",
76
- "directory": "packages/agents"
77
- },
78
- "bugs": {
79
- "url": "https://github.com/cloudflare/agents/issues"
80
- },
81
- "author": "Cloudflare Inc.",
82
78
  "license": "MIT",
83
- "description": "A home for your AI agents",
84
- "dependencies": {
85
- "@modelcontextprotocol/sdk": "^1.11.3",
86
- "ai": "^4.3.15",
87
- "cron-schedule": "^5.0.4",
88
- "nanoid": "^5.1.5",
89
- "partyserver": "^0.0.71",
90
- "partysocket": "1.1.4",
91
- "zod": "^3.24.4"
92
- },
79
+ "main": "src/index.ts",
80
+ "name": "agents",
93
81
  "peerDependencies": {
94
82
  "react": "*"
95
83
  },
96
- "devDependencies": {
97
- "@cloudflare/vitest-pool-workers": "^0.8.30",
98
- "react": "*",
99
- "vitest-browser-react": "^0.1.1"
100
- }
84
+ "repository": {
85
+ "directory": "packages/agents",
86
+ "type": "git",
87
+ "url": "git+https://github.com/cloudflare/agents.git"
88
+ },
89
+ "scripts": {
90
+ "build": "tsx ./scripts/build.ts",
91
+ "check:test": "npm run check:test:workers && npm run check:test:react",
92
+ "check:test:react": "vitest -r src/react-tests --watch false",
93
+ "check:test:workers": "vitest -r src/tests --watch false",
94
+ "evals": "(cd evals; evalite)",
95
+ "test": "vitest -r src/tests",
96
+ "test:react": "vitest -r src/react-tests"
97
+ },
98
+ "type": "module",
99
+ "types": "dist/index.d.ts",
100
+ "version": "0.0.0-7e0777b"
101
101
  }
package/src/index.ts CHANGED
@@ -1,35 +1,30 @@
1
- import {
2
- Server,
3
- routePartykitRequest,
4
- type PartyServerOptions,
5
- getServerByName,
6
- type Connection,
7
- type ConnectionContext,
8
- type WSMessage,
9
- } from "partyserver";
10
-
11
- import { parseCronExpression } from "cron-schedule";
12
- import { nanoid } from "nanoid";
13
-
14
1
  import { AsyncLocalStorage } from "node:async_hooks";
15
- import { MCPClientManager } from "./mcp/client";
16
- import {
17
- DurableObjectOAuthClientProvider,
18
- type AgentsOAuthProvider,
19
- } from "./mcp/do-oauth-client-provider";
2
+ import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import type { SSEClientTransportOptions } from "@modelcontextprotocol/sdk/client/sse.js";
4
+
20
5
  import type {
21
- Tool,
22
- Resource,
23
6
  Prompt,
7
+ Resource,
24
8
  ServerCapabilities,
9
+ Tool,
25
10
  } from "@modelcontextprotocol/sdk/types.js";
26
-
27
- import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
28
- import type { SSEClientTransportOptions } from "@modelcontextprotocol/sdk/client/sse.js";
29
-
11
+ import { parseCronExpression } from "cron-schedule";
12
+ import { nanoid } from "nanoid";
13
+ import {
14
+ type Connection,
15
+ type ConnectionContext,
16
+ getServerByName,
17
+ type PartyServerOptions,
18
+ routePartykitRequest,
19
+ Server,
20
+ type WSMessage,
21
+ } from "partyserver";
30
22
  import { camelCaseToKebabCase } from "./client";
23
+ import { MCPClientManager } from "./mcp/client";
24
+ // import type { MCPClientConnection } from "./mcp/client-connection";
25
+ import { DurableObjectOAuthClientProvider } from "./mcp/do-oauth-client-provider";
31
26
 
32
- export type { Connection, WSMessage, ConnectionContext } from "partyserver";
27
+ export type { Connection, ConnectionContext, WSMessage } from "partyserver";
33
28
 
34
29
  /**
35
30
  * RPC request message from client
@@ -122,6 +117,7 @@ const callableMetadata = new Map<Function, CallableMetadata>();
122
117
  export function unstable_callable(metadata: CallableMetadata = {}) {
123
118
  return function callableDecorator<This, Args extends unknown[], Return>(
124
119
  target: (this: This, ...args: Args) => Return,
120
+ // biome-ignore lint/correctness/noUnusedFunctionParameters: later
125
121
  context: ClassMethodDecoratorContext
126
122
  ) {
127
123
  if (!callableMetadata.has(target)) {
@@ -194,6 +190,9 @@ export type MCPServer = {
194
190
  name: string;
195
191
  server_url: string;
196
192
  auth_url: string | null;
193
+ // This state is specifically about the temporary process of getting a token (if needed).
194
+ // Scope outside of that can't be relied upon because when the DO sleeps, there's no way
195
+ // to communicate a change to a non-ready state.
197
196
  state: "authenticating" | "connecting" | "ready" | "discovering" | "failed";
198
197
  instructions: string | null;
199
198
  capabilities: ServerCapabilities | null;
@@ -397,15 +396,15 @@ export class Agent<Env, State = unknown> extends Server<Env> {
397
396
  // after the MCP connection handshake, we can send updated mcp state
398
397
  this.broadcast(
399
398
  JSON.stringify({
400
- type: "cf_agent_mcp_servers",
401
399
  mcp: this.getMcpServers(),
400
+ type: "cf_agent_mcp_servers",
402
401
  })
403
402
  );
404
403
 
405
404
  // We probably should let the user configure this response/redirect, but this is fine for now.
406
405
  return new Response("<script>window.close();</script>", {
407
- status: 200,
408
406
  headers: { "content-type": "text/html" },
407
+ status: 200,
409
408
  });
410
409
  }
411
410
 
@@ -426,7 +425,7 @@ export class Agent<Env, State = unknown> extends Server<Env> {
426
425
  let parsed: unknown;
427
426
  try {
428
427
  parsed = JSON.parse(message);
429
- } catch (e) {
428
+ } catch (_e) {
430
429
  // silently fail and let the onMessage handler handle it
431
430
  return this._tryCatch(() => _onMessage(connection, message));
432
431
  }
@@ -462,21 +461,21 @@ export class Agent<Env, State = unknown> extends Server<Env> {
462
461
  // For regular methods, execute and send response
463
462
  const result = await methodFn.apply(this, args);
464
463
  const response: RPCResponse = {
465
- type: "rpc",
464
+ done: true,
466
465
  id,
467
- success: true,
468
466
  result,
469
- done: true,
467
+ success: true,
468
+ type: "rpc",
470
469
  };
471
470
  connection.send(JSON.stringify(response));
472
471
  } catch (e) {
473
472
  // Send error response
474
473
  const response: RPCResponse = {
475
- type: "rpc",
476
- id: parsed.id,
477
- success: false,
478
474
  error:
479
475
  e instanceof Error ? e.message : "Unknown error occurred",
476
+ id: parsed.id,
477
+ success: false,
478
+ type: "rpc",
480
479
  };
481
480
  connection.send(JSON.stringify(response));
482
481
  console.error("RPC error:", e);
@@ -500,16 +499,16 @@ export class Agent<Env, State = unknown> extends Server<Env> {
500
499
  if (this.state) {
501
500
  connection.send(
502
501
  JSON.stringify({
503
- type: "cf_agent_state",
504
502
  state: this.state,
503
+ type: "cf_agent_state",
505
504
  })
506
505
  );
507
506
  }
508
507
 
509
508
  connection.send(
510
509
  JSON.stringify({
511
- type: "cf_agent_mcp_servers",
512
510
  mcp: this.getMcpServers(),
511
+ type: "cf_agent_mcp_servers",
513
512
  })
514
513
  );
515
514
 
@@ -528,28 +527,30 @@ export class Agent<Env, State = unknown> extends Server<Env> {
528
527
  SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
529
528
  `;
530
529
 
531
- // from DO storage, reconnect to all servers using our saved auth information
530
+ // from DO storage, reconnect to all servers not currently in the oauth flow using our saved auth information
532
531
  await Promise.allSettled(
533
- servers.map((server) => {
534
- return this._connectToMcpServerInternal(
535
- server.name,
536
- server.server_url,
537
- server.callback_url,
538
- server.server_options
539
- ? JSON.parse(server.server_options)
540
- : undefined,
541
- {
542
- id: server.id,
543
- oauthClientId: server.client_id ?? undefined,
544
- }
545
- );
546
- })
532
+ servers
533
+ .filter((server) => server.auth_url === null)
534
+ .map((server) => {
535
+ return this._connectToMcpServerInternal(
536
+ server.name,
537
+ server.server_url,
538
+ server.callback_url,
539
+ server.server_options
540
+ ? JSON.parse(server.server_options)
541
+ : undefined,
542
+ {
543
+ id: server.id,
544
+ oauthClientId: server.client_id ?? undefined,
545
+ }
546
+ );
547
+ })
547
548
  );
548
549
 
549
550
  this.broadcast(
550
551
  JSON.stringify({
551
- type: "cf_agent_mcp_servers",
552
552
  mcp: this.getMcpServers(),
553
+ type: "cf_agent_mcp_servers",
553
554
  })
554
555
  );
555
556
 
@@ -574,8 +575,8 @@ export class Agent<Env, State = unknown> extends Server<Env> {
574
575
  `;
575
576
  this.broadcast(
576
577
  JSON.stringify({
577
- type: "cf_agent_state",
578
578
  state: state,
579
+ type: "cf_agent_state",
579
580
  }),
580
581
  source !== "server" ? [source.id] : []
581
582
  );
@@ -603,6 +604,7 @@ export class Agent<Env, State = unknown> extends Server<Env> {
603
604
  * @param state Updated state
604
605
  * @param source Source of the state update ("server" or a client connection)
605
606
  */
607
+ // biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later
606
608
  onStateUpdate(state: State | undefined, source: Connection | "server") {
607
609
  // override this to handle state updates
608
610
  }
@@ -611,6 +613,7 @@ export class Agent<Env, State = unknown> extends Server<Env> {
611
613
  * Called when the Agent receives an email
612
614
  * @param email Email message to process
613
615
  */
616
+ // biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later
614
617
  onEmail(email: ForwardableEmailMessage) {
615
618
  return agentContext.run(
616
619
  { agent: this, connection: undefined, request: undefined },
@@ -697,8 +700,8 @@ export class Agent<Env, State = unknown> extends Server<Env> {
697
700
  await this._scheduleNextAlarm();
698
701
 
699
702
  return {
700
- id,
701
703
  callback: callback,
704
+ id,
702
705
  payload: payload as T,
703
706
  time: timestamp,
704
707
  type: "scheduled",
@@ -718,10 +721,10 @@ export class Agent<Env, State = unknown> extends Server<Env> {
718
721
  await this._scheduleNextAlarm();
719
722
 
720
723
  return {
721
- id,
722
724
  callback: callback,
723
- payload: payload as T,
724
725
  delayInSeconds: when,
726
+ id,
727
+ payload: payload as T,
725
728
  time: timestamp,
726
729
  type: "delayed",
727
730
  };
@@ -740,10 +743,10 @@ export class Agent<Env, State = unknown> extends Server<Env> {
740
743
  await this._scheduleNextAlarm();
741
744
 
742
745
  return {
743
- id,
744
746
  callback: callback,
745
- payload: payload as T,
746
747
  cron: when,
748
+ id,
749
+ payload: payload as T,
747
750
  time: timestamp,
748
751
  type: "cron",
749
752
  };
@@ -913,6 +916,7 @@ export class Agent<Env, State = unknown> extends Server<Env> {
913
916
  // delete all alarms
914
917
  await this.ctx.storage.deleteAlarm();
915
918
  await this.ctx.storage.deleteAll();
919
+ this.ctx.abort("destroyed"); // enforce that the agent is evicted
916
920
  }
917
921
 
918
922
  /**
@@ -955,8 +959,8 @@ export class Agent<Env, State = unknown> extends Server<Env> {
955
959
 
956
960
  this.broadcast(
957
961
  JSON.stringify({
958
- type: "cf_agent_mcp_servers",
959
962
  mcp: this.getMcpServers(),
963
+ type: "cf_agent_mcp_servers",
960
964
  })
961
965
  );
962
966
 
@@ -1018,12 +1022,12 @@ export class Agent<Env, State = unknown> extends Server<Env> {
1018
1022
  }
1019
1023
 
1020
1024
  const { id, authUrl, clientId } = await this.mcp.connect(url, {
1025
+ client: options?.client,
1021
1026
  reconnect,
1022
1027
  transport: {
1023
1028
  ...headerTransportOpts,
1024
1029
  authProvider,
1025
1030
  },
1026
- client: options?.client,
1027
1031
  });
1028
1032
 
1029
1033
  this.sql`
@@ -1040,8 +1044,8 @@ export class Agent<Env, State = unknown> extends Server<Env> {
1040
1044
  `;
1041
1045
 
1042
1046
  return {
1043
- id,
1044
1047
  authUrl,
1048
+ id,
1045
1049
  };
1046
1050
  }
1047
1051
 
@@ -1052,18 +1056,18 @@ export class Agent<Env, State = unknown> extends Server<Env> {
1052
1056
  `;
1053
1057
  this.broadcast(
1054
1058
  JSON.stringify({
1055
- type: "cf_agent_mcp_servers",
1056
1059
  mcp: this.getMcpServers(),
1060
+ type: "cf_agent_mcp_servers",
1057
1061
  })
1058
1062
  );
1059
1063
  }
1060
1064
 
1061
1065
  getMcpServers(): MCPServersState {
1062
1066
  const mcpState: MCPServersState = {
1063
- servers: {},
1064
- tools: this.mcp.listTools(),
1065
1067
  prompts: this.mcp.listPrompts(),
1066
1068
  resources: this.mcp.listResources(),
1069
+ servers: {},
1070
+ tools: this.mcp.listTools(),
1067
1071
  };
1068
1072
 
1069
1073
  const servers = this.sql<MCPServerRow>`
@@ -1071,14 +1075,15 @@ export class Agent<Env, State = unknown> extends Server<Env> {
1071
1075
  `;
1072
1076
 
1073
1077
  for (const server of servers) {
1078
+ const serverConn = this.mcp.mcpConnections[server.id];
1074
1079
  mcpState.servers[server.id] = {
1080
+ auth_url: server.auth_url,
1081
+ capabilities: serverConn?.serverCapabilities ?? null,
1082
+ instructions: serverConn?.instructions ?? null,
1075
1083
  name: server.name,
1076
1084
  server_url: server.server_url,
1077
- auth_url: server.auth_url,
1078
- state: this.mcp.mcpConnections[server.id].connectionState,
1079
- instructions: this.mcp.mcpConnections[server.id].instructions ?? null,
1080
- capabilities:
1081
- this.mcp.mcpConnections[server.id].serverCapabilities ?? null,
1085
+ // mark as "authenticating" because the server isn't automatically connected, so it's pending authenticating
1086
+ state: serverConn?.connectionState ?? "authenticating",
1082
1087
  };
1083
1088
  }
1084
1089
 
@@ -1123,9 +1128,9 @@ export async function routeAgentRequest<Env>(
1123
1128
  const corsHeaders =
1124
1129
  options?.cors === true
1125
1130
  ? {
1126
- "Access-Control-Allow-Origin": "*",
1127
- "Access-Control-Allow-Methods": "GET, POST, HEAD, OPTIONS",
1128
1131
  "Access-Control-Allow-Credentials": "true",
1132
+ "Access-Control-Allow-Methods": "GET, POST, HEAD, OPTIONS",
1133
+ "Access-Control-Allow-Origin": "*",
1129
1134
  "Access-Control-Max-Age": "86400",
1130
1135
  }
1131
1136
  : options?.cors;
@@ -1173,9 +1178,9 @@ export async function routeAgentRequest<Env>(
1173
1178
  * @param options Routing options
1174
1179
  */
1175
1180
  export async function routeAgentEmail<Env>(
1176
- email: ForwardableEmailMessage,
1177
- env: Env,
1178
- options?: AgentOptions<Env>
1181
+ _email: ForwardableEmailMessage,
1182
+ _env: Env,
1183
+ _options?: AgentOptions<Env>
1179
1184
  ): Promise<void> {}
1180
1185
 
1181
1186
  /**
@@ -1220,11 +1225,11 @@ export class StreamingResponse {
1220
1225
  throw new Error("StreamingResponse is already closed");
1221
1226
  }
1222
1227
  const response: RPCResponse = {
1223
- type: "rpc",
1228
+ done: false,
1224
1229
  id: this._id,
1225
- success: true,
1226
1230
  result: chunk,
1227
- done: false,
1231
+ success: true,
1232
+ type: "rpc",
1228
1233
  };
1229
1234
  this._connection.send(JSON.stringify(response));
1230
1235
  }
@@ -1239,11 +1244,11 @@ export class StreamingResponse {
1239
1244
  }
1240
1245
  this._closed = true;
1241
1246
  const response: RPCResponse = {
1242
- type: "rpc",
1247
+ done: true,
1243
1248
  id: this._id,
1244
- success: true,
1245
1249
  result: finalChunk,
1246
- done: true,
1250
+ success: true,
1251
+ type: "rpc",
1247
1252
  };
1248
1253
  this._connection.send(JSON.stringify(response));
1249
1254
  }