agents 0.0.0-f6c26e4 → 0.0.0-f7bd395
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 +136 -6
- package/dist/ai-chat-agent.d.ts +12 -9
- package/dist/ai-chat-agent.js +142 -59
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-chat-v5-migration.d.ts +152 -0
- package/dist/ai-chat-v5-migration.js +19 -0
- package/dist/ai-chat-v5-migration.js.map +1 -0
- package/dist/ai-react.d.ts +62 -71
- package/dist/ai-react.js +144 -37
- package/dist/ai-react.js.map +1 -1
- package/dist/ai-types.d.ts +36 -19
- package/dist/ai-types.js +6 -0
- package/dist/chunk-AVYJQSLW.js +17 -0
- package/dist/chunk-AVYJQSLW.js.map +1 -0
- package/dist/{chunk-5YIRLLUX.js → chunk-IJPBZOSS.js} +137 -105
- package/dist/chunk-IJPBZOSS.js.map +1 -0
- package/dist/{chunk-PVQZBKN7.js → chunk-LL2AFX7V.js} +5 -2
- package/dist/chunk-LL2AFX7V.js.map +1 -0
- package/dist/{chunk-KUH345EY.js → chunk-QEVM4BVL.js} +5 -5
- package/dist/chunk-QEVM4BVL.js.map +1 -0
- package/dist/chunk-UJVEAURM.js +150 -0
- package/dist/chunk-UJVEAURM.js.map +1 -0
- package/dist/{chunk-MW5BQ2FW.js → chunk-VYENMKFS.js} +163 -20
- package/dist/chunk-VYENMKFS.js.map +1 -0
- package/dist/client-CcIORE73.d.ts +4607 -0
- package/dist/client.js +2 -1
- package/dist/index.d.ts +557 -32
- package/dist/index.js +7 -4
- package/dist/mcp/client.d.ts +9 -1053
- package/dist/mcp/client.js +1 -1
- package/dist/mcp/do-oauth-client-provider.d.ts +1 -0
- package/dist/mcp/do-oauth-client-provider.js +1 -1
- package/dist/mcp/index.d.ts +66 -53
- package/dist/mcp/index.js +850 -604
- package/dist/mcp/index.js.map +1 -1
- package/dist/observability/index.d.ts +46 -12
- package/dist/observability/index.js +5 -4
- package/dist/react.d.ts +7 -3
- package/dist/react.js +7 -5
- package/dist/react.js.map +1 -1
- package/dist/schedule.d.ts +83 -9
- package/dist/schedule.js +15 -2
- package/dist/schedule.js.map +1 -1
- package/package.json +19 -8
- package/src/index.ts +192 -123
- package/dist/chunk-5YIRLLUX.js.map +0 -1
- package/dist/chunk-KUH345EY.js.map +0 -1
- package/dist/chunk-MW5BQ2FW.js.map +0 -1
- package/dist/chunk-PVQZBKN7.js.map +0 -1
- package/dist/index-BIJvkfYt.d.ts +0 -614
package/src/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { env } from "cloudflare:workers";
|
|
1
2
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
3
|
import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
3
4
|
import type { SSEClientTransportOptions } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
@@ -25,6 +26,7 @@ import { MCPClientManager } from "./mcp/client";
|
|
|
25
26
|
// import type { MCPClientConnection } from "./mcp/client-connection";
|
|
26
27
|
import { DurableObjectOAuthClientProvider } from "./mcp/do-oauth-client-provider";
|
|
27
28
|
import { genericObservability, type Observability } from "./observability";
|
|
29
|
+
import { MessageType } from "./ai-types";
|
|
28
30
|
|
|
29
31
|
export type { Connection, ConnectionContext, WSMessage } from "partyserver";
|
|
30
32
|
|
|
@@ -42,7 +44,7 @@ export type RPCRequest = {
|
|
|
42
44
|
* State update message from client
|
|
43
45
|
*/
|
|
44
46
|
export type StateUpdateMessage = {
|
|
45
|
-
type:
|
|
47
|
+
type: MessageType.CF_AGENT_STATE;
|
|
46
48
|
state: unknown;
|
|
47
49
|
};
|
|
48
50
|
|
|
@@ -50,7 +52,7 @@ export type StateUpdateMessage = {
|
|
|
50
52
|
* RPC response message to client
|
|
51
53
|
*/
|
|
52
54
|
export type RPCResponse = {
|
|
53
|
-
type:
|
|
55
|
+
type: MessageType.RPC;
|
|
54
56
|
id: string;
|
|
55
57
|
} & (
|
|
56
58
|
| {
|
|
@@ -77,7 +79,7 @@ function isRPCRequest(msg: unknown): msg is RPCRequest {
|
|
|
77
79
|
typeof msg === "object" &&
|
|
78
80
|
msg !== null &&
|
|
79
81
|
"type" in msg &&
|
|
80
|
-
msg.type ===
|
|
82
|
+
msg.type === MessageType.RPC &&
|
|
81
83
|
"id" in msg &&
|
|
82
84
|
typeof msg.id === "string" &&
|
|
83
85
|
"method" in msg &&
|
|
@@ -95,7 +97,7 @@ function isStateUpdateMessage(msg: unknown): msg is StateUpdateMessage {
|
|
|
95
97
|
typeof msg === "object" &&
|
|
96
98
|
msg !== null &&
|
|
97
99
|
"type" in msg &&
|
|
98
|
-
msg.type ===
|
|
100
|
+
msg.type === MessageType.CF_AGENT_STATE &&
|
|
99
101
|
"state" in msg
|
|
100
102
|
);
|
|
101
103
|
}
|
|
@@ -116,7 +118,7 @@ const callableMetadata = new Map<Function, CallableMetadata>();
|
|
|
116
118
|
* Decorator that marks a method as callable by clients
|
|
117
119
|
* @param metadata Optional metadata about the callable method
|
|
118
120
|
*/
|
|
119
|
-
export function
|
|
121
|
+
export function callable(metadata: CallableMetadata = {}) {
|
|
120
122
|
return function callableDecorator<This, Args extends unknown[], Return>(
|
|
121
123
|
target: (this: This, ...args: Args) => Return,
|
|
122
124
|
// biome-ignore lint/correctness/noUnusedFunctionParameters: later
|
|
@@ -130,6 +132,23 @@ export function unstable_callable(metadata: CallableMetadata = {}) {
|
|
|
130
132
|
};
|
|
131
133
|
}
|
|
132
134
|
|
|
135
|
+
let didWarnAboutUnstableCallable = false;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Decorator that marks a method as callable by clients
|
|
139
|
+
* @deprecated this has been renamed to callable, and unstable_callable will be removed in the next major version
|
|
140
|
+
* @param metadata Optional metadata about the callable method
|
|
141
|
+
*/
|
|
142
|
+
export const unstable_callable = (metadata: CallableMetadata = {}) => {
|
|
143
|
+
if (!didWarnAboutUnstableCallable) {
|
|
144
|
+
didWarnAboutUnstableCallable = true;
|
|
145
|
+
console.warn(
|
|
146
|
+
"unstable_callable is deprecated, use callable instead. unstable_callable will be removed in the next major version."
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
callable(metadata);
|
|
150
|
+
};
|
|
151
|
+
|
|
133
152
|
export type QueueItem<T = string> = {
|
|
134
153
|
id: string;
|
|
135
154
|
payload: T;
|
|
@@ -182,7 +201,7 @@ function getNextCronTime(cron: string) {
|
|
|
182
201
|
* MCP Server state update message from server -> Client
|
|
183
202
|
*/
|
|
184
203
|
export type MCPServerMessage = {
|
|
185
|
-
type:
|
|
204
|
+
type: MessageType.CF_AGENT_MCP_SERVERS;
|
|
186
205
|
mcp: MCPServersState;
|
|
187
206
|
};
|
|
188
207
|
|
|
@@ -271,7 +290,13 @@ function withAgentContext<T extends (...args: any[]) => any>(
|
|
|
271
290
|
method: T
|
|
272
291
|
): (this: Agent<unknown, unknown>, ...args: Parameters<T>) => ReturnType<T> {
|
|
273
292
|
return function (...args: Parameters<T>): ReturnType<T> {
|
|
274
|
-
const { connection, request, email } = getCurrentAgent();
|
|
293
|
+
const { connection, request, email, agent } = getCurrentAgent();
|
|
294
|
+
|
|
295
|
+
if (agent === this) {
|
|
296
|
+
// already wrapped, so we can just call the method
|
|
297
|
+
return method.apply(this, args);
|
|
298
|
+
}
|
|
299
|
+
// not wrapped, so we need to wrap it
|
|
275
300
|
return agentContext.run({ agent: this, connection, request, email }, () => {
|
|
276
301
|
return method.apply(this, args);
|
|
277
302
|
});
|
|
@@ -283,7 +308,11 @@ function withAgentContext<T extends (...args: any[]) => any>(
|
|
|
283
308
|
* @template Env Environment type containing bindings
|
|
284
309
|
* @template State State type to store within the Agent
|
|
285
310
|
*/
|
|
286
|
-
export class Agent<
|
|
311
|
+
export class Agent<
|
|
312
|
+
Env = typeof env,
|
|
313
|
+
State = unknown,
|
|
314
|
+
Props extends Record<string, unknown> = Record<string, unknown>
|
|
315
|
+
> extends Server<Env, Props> {
|
|
287
316
|
private _state = DEFAULT_STATE as State;
|
|
288
317
|
|
|
289
318
|
private _ParentClass: typeof Agent<Env, State> =
|
|
@@ -446,7 +475,7 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
446
475
|
this.broadcast(
|
|
447
476
|
JSON.stringify({
|
|
448
477
|
mcp: this.getMcpServers(),
|
|
449
|
-
type:
|
|
478
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
450
479
|
})
|
|
451
480
|
);
|
|
452
481
|
|
|
@@ -515,10 +544,8 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
515
544
|
displayMessage: `RPC call to ${method}`,
|
|
516
545
|
id: nanoid(),
|
|
517
546
|
payload: {
|
|
518
|
-
args,
|
|
519
547
|
method,
|
|
520
|
-
streaming: metadata?.streaming
|
|
521
|
-
success: true
|
|
548
|
+
streaming: metadata?.streaming
|
|
522
549
|
},
|
|
523
550
|
timestamp: Date.now(),
|
|
524
551
|
type: "rpc"
|
|
@@ -531,7 +558,7 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
531
558
|
id,
|
|
532
559
|
result,
|
|
533
560
|
success: true,
|
|
534
|
-
type:
|
|
561
|
+
type: MessageType.RPC
|
|
535
562
|
};
|
|
536
563
|
connection.send(JSON.stringify(response));
|
|
537
564
|
} catch (e) {
|
|
@@ -541,7 +568,7 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
541
568
|
e instanceof Error ? e.message : "Unknown error occurred",
|
|
542
569
|
id: parsed.id,
|
|
543
570
|
success: false,
|
|
544
|
-
type:
|
|
571
|
+
type: MessageType.RPC
|
|
545
572
|
};
|
|
546
573
|
connection.send(JSON.stringify(response));
|
|
547
574
|
console.error("RPC error:", e);
|
|
@@ -560,44 +587,42 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
560
587
|
// must fix this
|
|
561
588
|
return agentContext.run(
|
|
562
589
|
{ agent: this, connection, request: ctx.request, email: undefined },
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
if (this.state) {
|
|
566
|
-
connection.send(
|
|
567
|
-
JSON.stringify({
|
|
568
|
-
state: this.state,
|
|
569
|
-
type: "cf_agent_state"
|
|
570
|
-
})
|
|
571
|
-
);
|
|
572
|
-
}
|
|
573
|
-
|
|
590
|
+
() => {
|
|
591
|
+
if (this.state) {
|
|
574
592
|
connection.send(
|
|
575
593
|
JSON.stringify({
|
|
576
|
-
|
|
577
|
-
type:
|
|
594
|
+
state: this.state,
|
|
595
|
+
type: MessageType.CF_AGENT_STATE
|
|
578
596
|
})
|
|
579
597
|
);
|
|
598
|
+
}
|
|
580
599
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
600
|
+
connection.send(
|
|
601
|
+
JSON.stringify({
|
|
602
|
+
mcp: this.getMcpServers(),
|
|
603
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
604
|
+
})
|
|
605
|
+
);
|
|
606
|
+
|
|
607
|
+
this.observability?.emit(
|
|
608
|
+
{
|
|
609
|
+
displayMessage: "Connection established",
|
|
610
|
+
id: nanoid(),
|
|
611
|
+
payload: {
|
|
612
|
+
connectionId: connection.id
|
|
590
613
|
},
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
614
|
+
timestamp: Date.now(),
|
|
615
|
+
type: "connect"
|
|
616
|
+
},
|
|
617
|
+
this.ctx
|
|
618
|
+
);
|
|
619
|
+
return this._tryCatch(() => _onConnect(connection, ctx));
|
|
595
620
|
}
|
|
596
621
|
);
|
|
597
622
|
};
|
|
598
623
|
|
|
599
624
|
const _onStart = this.onStart.bind(this);
|
|
600
|
-
this.onStart = async () => {
|
|
625
|
+
this.onStart = async (props?: Props) => {
|
|
601
626
|
return agentContext.run(
|
|
602
627
|
{
|
|
603
628
|
agent: this,
|
|
@@ -606,15 +631,22 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
606
631
|
email: undefined
|
|
607
632
|
},
|
|
608
633
|
async () => {
|
|
609
|
-
|
|
634
|
+
await this._tryCatch(() => {
|
|
635
|
+
const servers = this.sql<MCPServerRow>`
|
|
610
636
|
SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
|
|
611
637
|
`;
|
|
612
638
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
639
|
+
this.broadcast(
|
|
640
|
+
JSON.stringify({
|
|
641
|
+
mcp: this.getMcpServers(),
|
|
642
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
643
|
+
})
|
|
644
|
+
);
|
|
645
|
+
|
|
646
|
+
// from DO storage, reconnect to all servers not currently in the oauth flow using our saved auth information
|
|
647
|
+
if (servers && Array.isArray(servers) && servers.length > 0) {
|
|
648
|
+
servers.forEach((server) => {
|
|
649
|
+
this._connectToMcpServerInternal(
|
|
618
650
|
server.name,
|
|
619
651
|
server.server_url,
|
|
620
652
|
server.callback_url,
|
|
@@ -625,18 +657,33 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
625
657
|
id: server.id,
|
|
626
658
|
oauthClientId: server.client_id ?? undefined
|
|
627
659
|
}
|
|
628
|
-
)
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
660
|
+
)
|
|
661
|
+
.then(() => {
|
|
662
|
+
// Broadcast updated MCP servers state after each server connects
|
|
663
|
+
this.broadcast(
|
|
664
|
+
JSON.stringify({
|
|
665
|
+
mcp: this.getMcpServers(),
|
|
666
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
667
|
+
})
|
|
668
|
+
);
|
|
669
|
+
})
|
|
670
|
+
.catch((error) => {
|
|
671
|
+
console.error(
|
|
672
|
+
`Error connecting to MCP server: ${server.name} (${server.server_url})`,
|
|
673
|
+
error
|
|
674
|
+
);
|
|
675
|
+
// Still broadcast even if connection fails, so clients know about the failure
|
|
676
|
+
this.broadcast(
|
|
677
|
+
JSON.stringify({
|
|
678
|
+
mcp: this.getMcpServers(),
|
|
679
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
680
|
+
})
|
|
681
|
+
);
|
|
682
|
+
});
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
return _onStart(props);
|
|
686
|
+
});
|
|
640
687
|
}
|
|
641
688
|
);
|
|
642
689
|
};
|
|
@@ -646,7 +693,6 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
646
693
|
state: State,
|
|
647
694
|
source: Connection | "server" = "server"
|
|
648
695
|
) {
|
|
649
|
-
const previousState = this._state;
|
|
650
696
|
this._state = state;
|
|
651
697
|
this.sql`
|
|
652
698
|
INSERT OR REPLACE INTO cf_agents_state (id, state)
|
|
@@ -659,7 +705,7 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
659
705
|
this.broadcast(
|
|
660
706
|
JSON.stringify({
|
|
661
707
|
state: state,
|
|
662
|
-
type:
|
|
708
|
+
type: MessageType.CF_AGENT_STATE
|
|
663
709
|
}),
|
|
664
710
|
source !== "server" ? [source.id] : []
|
|
665
711
|
);
|
|
@@ -672,10 +718,7 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
672
718
|
{
|
|
673
719
|
displayMessage: "State updated",
|
|
674
720
|
id: nanoid(),
|
|
675
|
-
payload: {
|
|
676
|
-
previousState,
|
|
677
|
-
state
|
|
678
|
-
},
|
|
721
|
+
payload: {},
|
|
679
722
|
timestamp: Date.now(),
|
|
680
723
|
type: "state:update"
|
|
681
724
|
},
|
|
@@ -815,41 +858,37 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
815
858
|
while (proto && proto !== Object.prototype && depth < 10) {
|
|
816
859
|
const methodNames = Object.getOwnPropertyNames(proto);
|
|
817
860
|
for (const methodName of methodNames) {
|
|
818
|
-
|
|
861
|
+
const descriptor = Object.getOwnPropertyDescriptor(proto, methodName);
|
|
862
|
+
|
|
863
|
+
// Skip if it's a private method, a base method, a getter, or not a function,
|
|
819
864
|
if (
|
|
820
865
|
baseMethods.has(methodName) ||
|
|
821
866
|
methodName.startsWith("_") ||
|
|
822
|
-
|
|
867
|
+
!descriptor ||
|
|
868
|
+
!!descriptor.get ||
|
|
869
|
+
typeof descriptor.value !== "function"
|
|
823
870
|
) {
|
|
824
871
|
continue;
|
|
825
872
|
}
|
|
826
|
-
// If the method doesn't exist in base prototypes, it's a custom method
|
|
827
|
-
if (!baseMethods.has(methodName)) {
|
|
828
|
-
const descriptor = Object.getOwnPropertyDescriptor(proto, methodName);
|
|
829
|
-
if (descriptor && typeof descriptor.value === "function") {
|
|
830
|
-
// Wrap the custom method with context
|
|
831
|
-
|
|
832
|
-
const wrappedFunction = withAgentContext(
|
|
833
|
-
// biome-ignore lint/suspicious/noExplicitAny: I can't typescript
|
|
834
|
-
this[methodName as keyof this] as (...args: any[]) => any
|
|
835
|
-
// biome-ignore lint/suspicious/noExplicitAny: I can't typescript
|
|
836
|
-
) as any;
|
|
837
|
-
|
|
838
|
-
// if the method is callable, copy the metadata from the original method
|
|
839
|
-
if (this._isCallable(methodName)) {
|
|
840
|
-
callableMetadata.set(
|
|
841
|
-
wrappedFunction,
|
|
842
|
-
callableMetadata.get(
|
|
843
|
-
this[methodName as keyof this] as Function
|
|
844
|
-
)!
|
|
845
|
-
);
|
|
846
|
-
}
|
|
847
873
|
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
874
|
+
// Now, methodName is confirmed to be a custom method/function
|
|
875
|
+
// Wrap the custom method with context
|
|
876
|
+
const wrappedFunction = withAgentContext(
|
|
877
|
+
// biome-ignore lint/suspicious/noExplicitAny: I can't typescript
|
|
878
|
+
this[methodName as keyof this] as (...args: any[]) => any
|
|
879
|
+
// biome-ignore lint/suspicious/noExplicitAny: I can't typescript
|
|
880
|
+
) as any;
|
|
881
|
+
|
|
882
|
+
// if the method is callable, copy the metadata from the original method
|
|
883
|
+
if (this._isCallable(methodName)) {
|
|
884
|
+
callableMetadata.set(
|
|
885
|
+
wrappedFunction,
|
|
886
|
+
callableMetadata.get(this[methodName as keyof this] as Function)!
|
|
887
|
+
);
|
|
852
888
|
}
|
|
889
|
+
|
|
890
|
+
// set the wrapped function on the prototype
|
|
891
|
+
this.constructor.prototype[methodName as keyof this] = wrappedFunction;
|
|
853
892
|
}
|
|
854
893
|
|
|
855
894
|
proto = Object.getPrototypeOf(proto);
|
|
@@ -927,7 +966,6 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
927
966
|
}
|
|
928
967
|
this._flushingQueue = true;
|
|
929
968
|
while (true) {
|
|
930
|
-
const executed: string[] = [];
|
|
931
969
|
const result = this.sql<QueueItem<string>>`
|
|
932
970
|
SELECT * FROM cf_agents_queues
|
|
933
971
|
ORDER BY created_at ASC
|
|
@@ -959,13 +997,10 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
959
997
|
queueItem: QueueItem<string>
|
|
960
998
|
) => Promise<void>
|
|
961
999
|
).bind(this)(JSON.parse(row.payload as string), row);
|
|
962
|
-
|
|
1000
|
+
await this.dequeue(row.id);
|
|
963
1001
|
}
|
|
964
1002
|
);
|
|
965
1003
|
}
|
|
966
|
-
for (const id of executed) {
|
|
967
|
-
await this.dequeue(id);
|
|
968
|
-
}
|
|
969
1004
|
}
|
|
970
1005
|
this._flushingQueue = false;
|
|
971
1006
|
}
|
|
@@ -1040,7 +1075,10 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
1040
1075
|
{
|
|
1041
1076
|
displayMessage: `Schedule ${schedule.id} created`,
|
|
1042
1077
|
id: nanoid(),
|
|
1043
|
-
payload:
|
|
1078
|
+
payload: {
|
|
1079
|
+
callback: callback as string,
|
|
1080
|
+
id: id
|
|
1081
|
+
},
|
|
1044
1082
|
timestamp: Date.now(),
|
|
1045
1083
|
type: "schedule:create"
|
|
1046
1084
|
},
|
|
@@ -1210,7 +1248,10 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
1210
1248
|
{
|
|
1211
1249
|
displayMessage: `Schedule ${id} cancelled`,
|
|
1212
1250
|
id: nanoid(),
|
|
1213
|
-
payload:
|
|
1251
|
+
payload: {
|
|
1252
|
+
callback: schedule.callback,
|
|
1253
|
+
id: schedule.id
|
|
1254
|
+
},
|
|
1214
1255
|
timestamp: Date.now(),
|
|
1215
1256
|
type: "schedule:cancel"
|
|
1216
1257
|
},
|
|
@@ -1226,9 +1267,9 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
1226
1267
|
private async _scheduleNextAlarm() {
|
|
1227
1268
|
// Find the next schedule that needs to be executed
|
|
1228
1269
|
const result = this.sql`
|
|
1229
|
-
SELECT time FROM cf_agents_schedules
|
|
1270
|
+
SELECT time FROM cf_agents_schedules
|
|
1230
1271
|
WHERE time > ${Math.floor(Date.now() / 1000)}
|
|
1231
|
-
ORDER BY time ASC
|
|
1272
|
+
ORDER BY time ASC
|
|
1232
1273
|
LIMIT 1
|
|
1233
1274
|
`;
|
|
1234
1275
|
if (!result) return;
|
|
@@ -1275,7 +1316,10 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
1275
1316
|
{
|
|
1276
1317
|
displayMessage: `Schedule ${row.id} executed`,
|
|
1277
1318
|
id: nanoid(),
|
|
1278
|
-
payload:
|
|
1319
|
+
payload: {
|
|
1320
|
+
callback: row.callback,
|
|
1321
|
+
id: row.id
|
|
1322
|
+
},
|
|
1279
1323
|
timestamp: Date.now(),
|
|
1280
1324
|
type: "schedule:execute"
|
|
1281
1325
|
},
|
|
@@ -1395,7 +1439,7 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
1395
1439
|
this.broadcast(
|
|
1396
1440
|
JSON.stringify({
|
|
1397
1441
|
mcp: this.getMcpServers(),
|
|
1398
|
-
type:
|
|
1442
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
1399
1443
|
})
|
|
1400
1444
|
);
|
|
1401
1445
|
|
|
@@ -1484,7 +1528,7 @@ export class Agent<Env, State = unknown> extends Server<Env> {
|
|
|
1484
1528
|
this.broadcast(
|
|
1485
1529
|
JSON.stringify({
|
|
1486
1530
|
mcp: this.getMcpServers(),
|
|
1487
|
-
type:
|
|
1531
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
1488
1532
|
})
|
|
1489
1533
|
);
|
|
1490
1534
|
}
|
|
@@ -1696,6 +1740,13 @@ export type EmailRoutingOptions<Env> = AgentOptions<Env> & {
|
|
|
1696
1740
|
resolver: EmailResolver<Env>;
|
|
1697
1741
|
};
|
|
1698
1742
|
|
|
1743
|
+
// Cache the agent namespace map for email routing
|
|
1744
|
+
// This maps both kebab-case and original names to namespaces
|
|
1745
|
+
const agentMapCache = new WeakMap<
|
|
1746
|
+
Record<string, unknown>,
|
|
1747
|
+
Record<string, unknown>
|
|
1748
|
+
>();
|
|
1749
|
+
|
|
1699
1750
|
/**
|
|
1700
1751
|
* Route an email to the appropriate Agent
|
|
1701
1752
|
* @param email The email to route
|
|
@@ -1715,28 +1766,41 @@ export async function routeAgentEmail<Env>(
|
|
|
1715
1766
|
return;
|
|
1716
1767
|
}
|
|
1717
1768
|
|
|
1718
|
-
|
|
1719
|
-
if (!
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1769
|
+
// Build a map that includes both original names and kebab-case versions
|
|
1770
|
+
if (!agentMapCache.has(env as Record<string, unknown>)) {
|
|
1771
|
+
const map: Record<string, unknown> = {};
|
|
1772
|
+
for (const [key, value] of Object.entries(env as Record<string, unknown>)) {
|
|
1773
|
+
if (
|
|
1774
|
+
value &&
|
|
1775
|
+
typeof value === "object" &&
|
|
1776
|
+
"idFromName" in value &&
|
|
1777
|
+
typeof value.idFromName === "function"
|
|
1778
|
+
) {
|
|
1779
|
+
// Add both the original name and kebab-case version
|
|
1780
|
+
map[key] = value;
|
|
1781
|
+
map[camelCaseToKebabCase(key)] = value;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
agentMapCache.set(env as Record<string, unknown>, map);
|
|
1723
1785
|
}
|
|
1724
1786
|
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1787
|
+
const agentMap = agentMapCache.get(env as Record<string, unknown>)!;
|
|
1788
|
+
const namespace = agentMap[routingInfo.agentName];
|
|
1789
|
+
|
|
1790
|
+
if (!namespace) {
|
|
1791
|
+
// Provide helpful error message listing available agents
|
|
1792
|
+
const availableAgents = Object.keys(agentMap)
|
|
1793
|
+
.filter((key) => !key.includes("-")) // Show only original names, not kebab-case duplicates
|
|
1794
|
+
.join(", ");
|
|
1731
1795
|
throw new Error(
|
|
1732
|
-
`
|
|
1796
|
+
`Agent namespace '${routingInfo.agentName}' not found in environment. Available agents: ${availableAgents}`
|
|
1733
1797
|
);
|
|
1734
1798
|
}
|
|
1735
1799
|
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1800
|
+
const agent = await getAgentByName(
|
|
1801
|
+
namespace as unknown as AgentNamespace<Agent<Env>>,
|
|
1802
|
+
routingInfo.agentId
|
|
1803
|
+
);
|
|
1740
1804
|
|
|
1741
1805
|
// let's make a serialisable version of the email
|
|
1742
1806
|
const serialisableEmail: AgentEmail = {
|
|
@@ -1815,12 +1879,17 @@ export type EmailSendOptions = {
|
|
|
1815
1879
|
* @param options Options for Agent creation
|
|
1816
1880
|
* @returns Promise resolving to an Agent instance stub
|
|
1817
1881
|
*/
|
|
1818
|
-
export async function getAgentByName<
|
|
1882
|
+
export async function getAgentByName<
|
|
1883
|
+
Env,
|
|
1884
|
+
T extends Agent<Env>,
|
|
1885
|
+
Props extends Record<string, unknown> = Record<string, unknown>
|
|
1886
|
+
>(
|
|
1819
1887
|
namespace: AgentNamespace<T>,
|
|
1820
1888
|
name: string,
|
|
1821
1889
|
options?: {
|
|
1822
1890
|
jurisdiction?: DurableObjectJurisdiction;
|
|
1823
1891
|
locationHint?: DurableObjectLocationHint;
|
|
1892
|
+
props?: Props;
|
|
1824
1893
|
}
|
|
1825
1894
|
) {
|
|
1826
1895
|
return getServerByName<Env, T>(namespace, name, options);
|
|
@@ -1852,7 +1921,7 @@ export class StreamingResponse {
|
|
|
1852
1921
|
id: this._id,
|
|
1853
1922
|
result: chunk,
|
|
1854
1923
|
success: true,
|
|
1855
|
-
type:
|
|
1924
|
+
type: MessageType.RPC
|
|
1856
1925
|
};
|
|
1857
1926
|
this._connection.send(JSON.stringify(response));
|
|
1858
1927
|
}
|
|
@@ -1871,7 +1940,7 @@ export class StreamingResponse {
|
|
|
1871
1940
|
id: this._id,
|
|
1872
1941
|
result: finalChunk,
|
|
1873
1942
|
success: true,
|
|
1874
|
-
type:
|
|
1943
|
+
type: MessageType.RPC
|
|
1875
1944
|
};
|
|
1876
1945
|
this._connection.send(JSON.stringify(response));
|
|
1877
1946
|
}
|