agents 0.0.0-352d62c → 0.0.0-3667584
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 +126 -4
- package/dist/ai-chat-agent.d.ts +20 -22
- package/dist/ai-chat-agent.js +532 -256
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-chat-v5-migration-gdyLiTd8.js +155 -0
- package/dist/ai-chat-v5-migration-gdyLiTd8.js.map +1 -0
- package/dist/ai-chat-v5-migration.d.ts +155 -0
- package/dist/ai-chat-v5-migration.js +3 -0
- package/dist/ai-react.d.ts +73 -89
- package/dist/ai-react.js +260 -201
- package/dist/ai-react.js.map +1 -1
- package/dist/ai-types-BWW4umHY.d.ts +95 -0
- package/dist/ai-types-UZlfLOYP.js +20 -0
- package/dist/ai-types-UZlfLOYP.js.map +1 -0
- package/dist/ai-types.d.ts +6 -92
- package/dist/ai-types.js +3 -7
- package/dist/client-C-nwz-3N.d.ts +5313 -0
- package/dist/client-CZBVDDoO.js +786 -0
- package/dist/client-CZBVDDoO.js.map +1 -0
- package/dist/client-CmMi85Sj.d.ts +104 -0
- package/dist/client-DjR-lC16.js +117 -0
- package/dist/client-DjR-lC16.js.map +1 -0
- package/dist/client.d.ts +11 -92
- package/dist/client.js +4 -12
- package/dist/codemode/ai.d.ts +27 -0
- package/dist/codemode/ai.js +151 -0
- package/dist/codemode/ai.js.map +1 -0
- package/dist/do-oauth-client-provider-B2jr6UNq.js +93 -0
- package/dist/do-oauth-client-provider-B2jr6UNq.js.map +1 -0
- package/dist/do-oauth-client-provider-CCwGwnrA.d.ts +55 -0
- package/dist/index-CkQU40oY.d.ts +558 -0
- package/dist/index-W4JUkafc.d.ts +54 -0
- package/dist/index.d.ts +57 -535
- package/dist/index.js +7 -29
- package/dist/mcp/client.d.ts +4 -11
- package/dist/mcp/client.js +3 -9
- package/dist/mcp/do-oauth-client-provider.d.ts +2 -41
- package/dist/mcp/do-oauth-client-provider.js +3 -7
- package/dist/mcp/index.d.ts +73 -110
- package/dist/mcp/index.js +836 -945
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/x402.d.ts +34 -0
- package/dist/mcp/x402.js +194 -0
- package/dist/mcp/x402.js.map +1 -0
- package/dist/mcp-BEwaCsxO.d.ts +61 -0
- package/dist/observability/index.d.ts +3 -46
- package/dist/observability/index.js +7 -11
- package/dist/react-B4e1rDid.d.ts +113 -0
- package/dist/react.d.ts +10 -123
- package/dist/react.js +183 -112
- package/dist/react.js.map +1 -1
- package/dist/schedule.d.ts +84 -7
- package/dist/schedule.js +46 -21
- package/dist/schedule.js.map +1 -1
- package/dist/serializable-gtr9YMhp.d.ts +34 -0
- package/dist/serializable.d.ts +7 -32
- package/dist/serializable.js +1 -1
- package/dist/src-COfG--3R.js +1179 -0
- package/dist/src-COfG--3R.js.map +1 -0
- package/package.json +40 -9
- package/src/index.ts +226 -116
- package/dist/ai-types.js.map +0 -1
- package/dist/chunk-EEKLJYON.js +0 -17
- package/dist/chunk-EEKLJYON.js.map +0 -1
- package/dist/chunk-EM3J4KV7.js +0 -598
- package/dist/chunk-EM3J4KV7.js.map +0 -1
- package/dist/chunk-ID62XSAS.js +0 -1290
- package/dist/chunk-ID62XSAS.js.map +0 -1
- package/dist/chunk-PVQZBKN7.js +0 -106
- package/dist/chunk-PVQZBKN7.js.map +0 -1
- package/dist/chunk-QEVM4BVL.js +0 -116
- package/dist/chunk-QEVM4BVL.js.map +0 -1
- package/dist/client-DgyzBU_8.d.ts +0 -4601
- package/dist/client.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/mcp/client.js.map +0 -1
- package/dist/mcp/do-oauth-client-provider.js.map +0 -1
- package/dist/observability/index.js.map +0 -1
- package/dist/serializable.js.map +0 -1
package/src/index.ts
CHANGED
|
@@ -22,10 +22,12 @@ import {
|
|
|
22
22
|
routePartykitRequest
|
|
23
23
|
} from "partyserver";
|
|
24
24
|
import { camelCaseToKebabCase } from "./client";
|
|
25
|
-
import { MCPClientManager } from "./mcp/client";
|
|
26
|
-
|
|
25
|
+
import { MCPClientManager, type MCPClientOAuthResult } from "./mcp/client";
|
|
26
|
+
import type { MCPConnectionState } from "./mcp/client-connection";
|
|
27
27
|
import { DurableObjectOAuthClientProvider } from "./mcp/do-oauth-client-provider";
|
|
28
|
+
import type { TransportType } from "./mcp/types";
|
|
28
29
|
import { genericObservability, type Observability } from "./observability";
|
|
30
|
+
import { DisposableStore } from "./core/events";
|
|
29
31
|
import { MessageType } from "./ai-types";
|
|
30
32
|
|
|
31
33
|
export type { Connection, ConnectionContext, WSMessage } from "partyserver";
|
|
@@ -118,7 +120,7 @@ const callableMetadata = new Map<Function, CallableMetadata>();
|
|
|
118
120
|
* Decorator that marks a method as callable by clients
|
|
119
121
|
* @param metadata Optional metadata about the callable method
|
|
120
122
|
*/
|
|
121
|
-
export function
|
|
123
|
+
export function callable(metadata: CallableMetadata = {}) {
|
|
122
124
|
return function callableDecorator<This, Args extends unknown[], Return>(
|
|
123
125
|
target: (this: This, ...args: Args) => Return,
|
|
124
126
|
// biome-ignore lint/correctness/noUnusedFunctionParameters: later
|
|
@@ -132,6 +134,23 @@ export function unstable_callable(metadata: CallableMetadata = {}) {
|
|
|
132
134
|
};
|
|
133
135
|
}
|
|
134
136
|
|
|
137
|
+
let didWarnAboutUnstableCallable = false;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Decorator that marks a method as callable by clients
|
|
141
|
+
* @deprecated this has been renamed to callable, and unstable_callable will be removed in the next major version
|
|
142
|
+
* @param metadata Optional metadata about the callable method
|
|
143
|
+
*/
|
|
144
|
+
export const unstable_callable = (metadata: CallableMetadata = {}) => {
|
|
145
|
+
if (!didWarnAboutUnstableCallable) {
|
|
146
|
+
didWarnAboutUnstableCallable = true;
|
|
147
|
+
console.warn(
|
|
148
|
+
"unstable_callable is deprecated, use callable instead. unstable_callable will be removed in the next major version."
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
callable(metadata);
|
|
152
|
+
};
|
|
153
|
+
|
|
135
154
|
export type QueueItem<T = string> = {
|
|
136
155
|
id: string;
|
|
137
156
|
payload: T;
|
|
@@ -180,6 +199,8 @@ function getNextCronTime(cron: string) {
|
|
|
180
199
|
return interval.getNextDate();
|
|
181
200
|
}
|
|
182
201
|
|
|
202
|
+
export type { TransportType } from "./mcp/types";
|
|
203
|
+
|
|
183
204
|
/**
|
|
184
205
|
* MCP Server state update message from server -> Client
|
|
185
206
|
*/
|
|
@@ -204,7 +225,7 @@ export type MCPServer = {
|
|
|
204
225
|
// This state is specifically about the temporary process of getting a token (if needed).
|
|
205
226
|
// Scope outside of that can't be relied upon because when the DO sleeps, there's no way
|
|
206
227
|
// to communicate a change to a non-ready state.
|
|
207
|
-
state:
|
|
228
|
+
state: MCPConnectionState;
|
|
208
229
|
instructions: string | null;
|
|
209
230
|
capabilities: ServerCapabilities | null;
|
|
210
231
|
};
|
|
@@ -273,7 +294,13 @@ function withAgentContext<T extends (...args: any[]) => any>(
|
|
|
273
294
|
method: T
|
|
274
295
|
): (this: Agent<unknown, unknown>, ...args: Parameters<T>) => ReturnType<T> {
|
|
275
296
|
return function (...args: Parameters<T>): ReturnType<T> {
|
|
276
|
-
const { connection, request, email } = getCurrentAgent();
|
|
297
|
+
const { connection, request, email, agent } = getCurrentAgent();
|
|
298
|
+
|
|
299
|
+
if (agent === this) {
|
|
300
|
+
// already wrapped, so we can just call the method
|
|
301
|
+
return method.apply(this, args);
|
|
302
|
+
}
|
|
303
|
+
// not wrapped, so we need to wrap it
|
|
277
304
|
return agentContext.run({ agent: this, connection, request, email }, () => {
|
|
278
305
|
return method.apply(this, args);
|
|
279
306
|
});
|
|
@@ -285,13 +312,21 @@ function withAgentContext<T extends (...args: any[]) => any>(
|
|
|
285
312
|
* @template Env Environment type containing bindings
|
|
286
313
|
* @template State State type to store within the Agent
|
|
287
314
|
*/
|
|
288
|
-
export class Agent<
|
|
315
|
+
export class Agent<
|
|
316
|
+
Env = typeof env,
|
|
317
|
+
State = unknown,
|
|
318
|
+
Props extends Record<string, unknown> = Record<string, unknown>
|
|
319
|
+
> extends Server<Env, Props> {
|
|
289
320
|
private _state = DEFAULT_STATE as State;
|
|
321
|
+
private _disposables = new DisposableStore();
|
|
290
322
|
|
|
291
323
|
private _ParentClass: typeof Agent<Env, State> =
|
|
292
324
|
Object.getPrototypeOf(this).constructor;
|
|
293
325
|
|
|
294
|
-
mcp: MCPClientManager = new MCPClientManager(
|
|
326
|
+
readonly mcp: MCPClientManager = new MCPClientManager(
|
|
327
|
+
this._ParentClass.name,
|
|
328
|
+
"0.0.1"
|
|
329
|
+
);
|
|
295
330
|
|
|
296
331
|
/**
|
|
297
332
|
* Initial state for the Agent
|
|
@@ -384,8 +419,25 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
384
419
|
constructor(ctx: AgentContext, env: Env) {
|
|
385
420
|
super(ctx, env);
|
|
386
421
|
|
|
387
|
-
|
|
388
|
-
|
|
422
|
+
if (!wrappedClasses.has(this.constructor)) {
|
|
423
|
+
// Auto-wrap custom methods with agent context
|
|
424
|
+
this._autoWrapCustomMethods();
|
|
425
|
+
wrappedClasses.add(this.constructor);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Broadcast server state after background connects (for OAuth servers)
|
|
429
|
+
this._disposables.add(
|
|
430
|
+
this.mcp.onConnected(async () => {
|
|
431
|
+
this.broadcastMcpServers();
|
|
432
|
+
})
|
|
433
|
+
);
|
|
434
|
+
|
|
435
|
+
// Emit MCP observability events
|
|
436
|
+
this._disposables.add(
|
|
437
|
+
this.mcp.onObservabilityEvent((event) => {
|
|
438
|
+
this.observability?.emit(event);
|
|
439
|
+
})
|
|
440
|
+
);
|
|
389
441
|
|
|
390
442
|
this.sql`
|
|
391
443
|
CREATE TABLE IF NOT EXISTS cf_agents_state (
|
|
@@ -442,21 +494,24 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
442
494
|
{ agent: this, connection: undefined, request, email: undefined },
|
|
443
495
|
async () => {
|
|
444
496
|
if (this.mcp.isCallbackRequest(request)) {
|
|
445
|
-
await this.mcp.handleCallbackRequest(request);
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
497
|
+
const result = await this.mcp.handleCallbackRequest(request);
|
|
498
|
+
this.broadcastMcpServers();
|
|
499
|
+
|
|
500
|
+
if (result.authSuccess) {
|
|
501
|
+
// Start background connection if auth was successful
|
|
502
|
+
this.mcp
|
|
503
|
+
.establishConnection(result.serverId)
|
|
504
|
+
.catch((error) => {
|
|
505
|
+
console.error("Background connection failed:", error);
|
|
506
|
+
})
|
|
507
|
+
.finally(() => {
|
|
508
|
+
// Broadcast after background connection resolves (success/failure)
|
|
509
|
+
this.broadcastMcpServers();
|
|
510
|
+
});
|
|
511
|
+
}
|
|
454
512
|
|
|
455
|
-
//
|
|
456
|
-
return
|
|
457
|
-
headers: { "content-type": "text/html" },
|
|
458
|
-
status: 200
|
|
459
|
-
});
|
|
513
|
+
// Handle OAuth callback response using MCPClientManager configuration
|
|
514
|
+
return this.handleOAuthCallbackResponse(result, request);
|
|
460
515
|
}
|
|
461
516
|
|
|
462
517
|
return this._tryCatch(() => _onRequest(request));
|
|
@@ -560,44 +615,42 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
560
615
|
// must fix this
|
|
561
616
|
return agentContext.run(
|
|
562
617
|
{ 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: MessageType.CF_AGENT_STATE
|
|
570
|
-
})
|
|
571
|
-
);
|
|
572
|
-
}
|
|
573
|
-
|
|
618
|
+
() => {
|
|
619
|
+
if (this.state) {
|
|
574
620
|
connection.send(
|
|
575
621
|
JSON.stringify({
|
|
576
|
-
|
|
577
|
-
type: MessageType.
|
|
622
|
+
state: this.state,
|
|
623
|
+
type: MessageType.CF_AGENT_STATE
|
|
578
624
|
})
|
|
579
625
|
);
|
|
626
|
+
}
|
|
580
627
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
628
|
+
connection.send(
|
|
629
|
+
JSON.stringify({
|
|
630
|
+
mcp: this.getMcpServers(),
|
|
631
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
632
|
+
})
|
|
633
|
+
);
|
|
634
|
+
|
|
635
|
+
this.observability?.emit(
|
|
636
|
+
{
|
|
637
|
+
displayMessage: "Connection established",
|
|
638
|
+
id: nanoid(),
|
|
639
|
+
payload: {
|
|
640
|
+
connectionId: connection.id
|
|
590
641
|
},
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
642
|
+
timestamp: Date.now(),
|
|
643
|
+
type: "connect"
|
|
644
|
+
},
|
|
645
|
+
this.ctx
|
|
646
|
+
);
|
|
647
|
+
return this._tryCatch(() => _onConnect(connection, ctx));
|
|
595
648
|
}
|
|
596
649
|
);
|
|
597
650
|
};
|
|
598
651
|
|
|
599
652
|
const _onStart = this.onStart.bind(this);
|
|
600
|
-
this.onStart = async () => {
|
|
653
|
+
this.onStart = async (props?: Props) => {
|
|
601
654
|
return agentContext.run(
|
|
602
655
|
{
|
|
603
656
|
agent: this,
|
|
@@ -611,15 +664,20 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
611
664
|
SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
|
|
612
665
|
`;
|
|
613
666
|
|
|
614
|
-
this.
|
|
615
|
-
JSON.stringify({
|
|
616
|
-
mcp: this.getMcpServers(),
|
|
617
|
-
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
618
|
-
})
|
|
619
|
-
);
|
|
667
|
+
this.broadcastMcpServers();
|
|
620
668
|
|
|
621
669
|
// from DO storage, reconnect to all servers not currently in the oauth flow using our saved auth information
|
|
622
670
|
if (servers && Array.isArray(servers) && servers.length > 0) {
|
|
671
|
+
// Restore callback URLs for OAuth-enabled servers
|
|
672
|
+
servers.forEach((server) => {
|
|
673
|
+
if (server.callback_url) {
|
|
674
|
+
// Register the full redirect URL including serverId to avoid ambiguous matches
|
|
675
|
+
this.mcp.registerCallbackUrl(
|
|
676
|
+
`${server.callback_url}/${server.id}`
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
|
|
623
681
|
servers.forEach((server) => {
|
|
624
682
|
this._connectToMcpServerInternal(
|
|
625
683
|
server.name,
|
|
@@ -635,12 +693,7 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
635
693
|
)
|
|
636
694
|
.then(() => {
|
|
637
695
|
// Broadcast updated MCP servers state after each server connects
|
|
638
|
-
this.
|
|
639
|
-
JSON.stringify({
|
|
640
|
-
mcp: this.getMcpServers(),
|
|
641
|
-
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
642
|
-
})
|
|
643
|
-
);
|
|
696
|
+
this.broadcastMcpServers();
|
|
644
697
|
})
|
|
645
698
|
.catch((error) => {
|
|
646
699
|
console.error(
|
|
@@ -648,16 +701,11 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
648
701
|
error
|
|
649
702
|
);
|
|
650
703
|
// Still broadcast even if connection fails, so clients know about the failure
|
|
651
|
-
this.
|
|
652
|
-
JSON.stringify({
|
|
653
|
-
mcp: this.getMcpServers(),
|
|
654
|
-
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
655
|
-
})
|
|
656
|
-
);
|
|
704
|
+
this.broadcastMcpServers();
|
|
657
705
|
});
|
|
658
706
|
});
|
|
659
707
|
}
|
|
660
|
-
return _onStart();
|
|
708
|
+
return _onStart(props);
|
|
661
709
|
});
|
|
662
710
|
}
|
|
663
711
|
);
|
|
@@ -833,41 +881,37 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
833
881
|
while (proto && proto !== Object.prototype && depth < 10) {
|
|
834
882
|
const methodNames = Object.getOwnPropertyNames(proto);
|
|
835
883
|
for (const methodName of methodNames) {
|
|
836
|
-
|
|
884
|
+
const descriptor = Object.getOwnPropertyDescriptor(proto, methodName);
|
|
885
|
+
|
|
886
|
+
// Skip if it's a private method, a base method, a getter, or not a function,
|
|
837
887
|
if (
|
|
838
888
|
baseMethods.has(methodName) ||
|
|
839
889
|
methodName.startsWith("_") ||
|
|
840
|
-
|
|
890
|
+
!descriptor ||
|
|
891
|
+
!!descriptor.get ||
|
|
892
|
+
typeof descriptor.value !== "function"
|
|
841
893
|
) {
|
|
842
894
|
continue;
|
|
843
895
|
}
|
|
844
|
-
// If the method doesn't exist in base prototypes, it's a custom method
|
|
845
|
-
if (!baseMethods.has(methodName)) {
|
|
846
|
-
const descriptor = Object.getOwnPropertyDescriptor(proto, methodName);
|
|
847
|
-
if (descriptor && typeof descriptor.value === "function") {
|
|
848
|
-
// Wrap the custom method with context
|
|
849
|
-
|
|
850
|
-
const wrappedFunction = withAgentContext(
|
|
851
|
-
// biome-ignore lint/suspicious/noExplicitAny: I can't typescript
|
|
852
|
-
this[methodName as keyof this] as (...args: any[]) => any
|
|
853
|
-
// biome-ignore lint/suspicious/noExplicitAny: I can't typescript
|
|
854
|
-
) as any;
|
|
855
|
-
|
|
856
|
-
// if the method is callable, copy the metadata from the original method
|
|
857
|
-
if (this._isCallable(methodName)) {
|
|
858
|
-
callableMetadata.set(
|
|
859
|
-
wrappedFunction,
|
|
860
|
-
callableMetadata.get(
|
|
861
|
-
this[methodName as keyof this] as Function
|
|
862
|
-
)!
|
|
863
|
-
);
|
|
864
|
-
}
|
|
865
896
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
897
|
+
// Now, methodName is confirmed to be a custom method/function
|
|
898
|
+
// Wrap the custom method with context
|
|
899
|
+
const wrappedFunction = withAgentContext(
|
|
900
|
+
// biome-ignore lint/suspicious/noExplicitAny: I can't typescript
|
|
901
|
+
this[methodName as keyof this] as (...args: any[]) => any
|
|
902
|
+
// biome-ignore lint/suspicious/noExplicitAny: I can't typescript
|
|
903
|
+
) as any;
|
|
904
|
+
|
|
905
|
+
// if the method is callable, copy the metadata from the original method
|
|
906
|
+
if (this._isCallable(methodName)) {
|
|
907
|
+
callableMetadata.set(
|
|
908
|
+
wrappedFunction,
|
|
909
|
+
callableMetadata.get(this[methodName as keyof this] as Function)!
|
|
910
|
+
);
|
|
870
911
|
}
|
|
912
|
+
|
|
913
|
+
// set the wrapped function on the prototype
|
|
914
|
+
this.constructor.prototype[methodName as keyof this] = wrappedFunction;
|
|
871
915
|
}
|
|
872
916
|
|
|
873
917
|
proto = Object.getPrototypeOf(proto);
|
|
@@ -1350,6 +1394,8 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
1350
1394
|
// delete all alarms
|
|
1351
1395
|
await this.ctx.storage.deleteAlarm();
|
|
1352
1396
|
await this.ctx.storage.deleteAll();
|
|
1397
|
+
this._disposables.dispose();
|
|
1398
|
+
await this.mcp.dispose?.();
|
|
1353
1399
|
this.ctx.abort("destroyed"); // enforce that the agent is evicted
|
|
1354
1400
|
|
|
1355
1401
|
this.observability?.emit(
|
|
@@ -1375,25 +1421,42 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
1375
1421
|
/**
|
|
1376
1422
|
* Connect to a new MCP Server
|
|
1377
1423
|
*
|
|
1424
|
+
* @param serverName Name of the MCP server
|
|
1378
1425
|
* @param url MCP Server SSE URL
|
|
1379
|
-
* @param callbackHost Base host for the agent, used for the redirect URI.
|
|
1426
|
+
* @param callbackHost Base host for the agent, used for the redirect URI. If not provided, will be derived from the current request.
|
|
1380
1427
|
* @param agentsPrefix agents routing prefix if not using `agents`
|
|
1381
|
-
* @param options MCP client and transport
|
|
1428
|
+
* @param options MCP client and transport options
|
|
1382
1429
|
* @returns authUrl
|
|
1383
1430
|
*/
|
|
1384
1431
|
async addMcpServer(
|
|
1385
1432
|
serverName: string,
|
|
1386
1433
|
url: string,
|
|
1387
|
-
callbackHost
|
|
1434
|
+
callbackHost?: string,
|
|
1388
1435
|
agentsPrefix = "agents",
|
|
1389
1436
|
options?: {
|
|
1390
1437
|
client?: ConstructorParameters<typeof Client>[1];
|
|
1391
1438
|
transport?: {
|
|
1392
|
-
headers
|
|
1439
|
+
headers?: HeadersInit;
|
|
1440
|
+
type?: TransportType;
|
|
1393
1441
|
};
|
|
1394
1442
|
}
|
|
1395
1443
|
): Promise<{ id: string; authUrl: string | undefined }> {
|
|
1396
|
-
|
|
1444
|
+
// If callbackHost is not provided, derive it from the current request
|
|
1445
|
+
let resolvedCallbackHost = callbackHost;
|
|
1446
|
+
if (!resolvedCallbackHost) {
|
|
1447
|
+
const { request } = getCurrentAgent();
|
|
1448
|
+
if (!request) {
|
|
1449
|
+
throw new Error(
|
|
1450
|
+
"callbackHost is required when not called within a request context"
|
|
1451
|
+
);
|
|
1452
|
+
}
|
|
1453
|
+
|
|
1454
|
+
// Extract the origin from the request
|
|
1455
|
+
const requestUrl = new URL(request.url);
|
|
1456
|
+
resolvedCallbackHost = `${requestUrl.protocol}//${requestUrl.host}`;
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
const callbackUrl = `${resolvedCallbackHost}/${agentsPrefix}/${camelCaseToKebabCase(this._ParentClass.name)}/${this.name}/callback`;
|
|
1397
1460
|
|
|
1398
1461
|
const result = await this._connectToMcpServerInternal(
|
|
1399
1462
|
serverName,
|
|
@@ -1401,6 +1464,7 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
1401
1464
|
callbackUrl,
|
|
1402
1465
|
options
|
|
1403
1466
|
);
|
|
1467
|
+
|
|
1404
1468
|
this.sql`
|
|
1405
1469
|
INSERT
|
|
1406
1470
|
OR REPLACE INTO cf_agents_mcp_servers (id, name, server_url, client_id, auth_url, callback_url, server_options)
|
|
@@ -1415,17 +1479,12 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
1415
1479
|
);
|
|
1416
1480
|
`;
|
|
1417
1481
|
|
|
1418
|
-
this.
|
|
1419
|
-
JSON.stringify({
|
|
1420
|
-
mcp: this.getMcpServers(),
|
|
1421
|
-
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
1422
|
-
})
|
|
1423
|
-
);
|
|
1482
|
+
this.broadcastMcpServers();
|
|
1424
1483
|
|
|
1425
1484
|
return result;
|
|
1426
1485
|
}
|
|
1427
1486
|
|
|
1428
|
-
async _connectToMcpServerInternal(
|
|
1487
|
+
private async _connectToMcpServerInternal(
|
|
1429
1488
|
_serverName: string,
|
|
1430
1489
|
url: string,
|
|
1431
1490
|
callbackUrl: string,
|
|
@@ -1441,6 +1500,7 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
1441
1500
|
*/
|
|
1442
1501
|
transport?: {
|
|
1443
1502
|
headers?: HeadersInit;
|
|
1503
|
+
type?: TransportType;
|
|
1444
1504
|
};
|
|
1445
1505
|
},
|
|
1446
1506
|
reconnect?: {
|
|
@@ -1465,6 +1525,9 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
1465
1525
|
}
|
|
1466
1526
|
}
|
|
1467
1527
|
|
|
1528
|
+
// Use the transport type specified in options, or default to "auto"
|
|
1529
|
+
const transportType: TransportType = options?.transport?.type ?? "auto";
|
|
1530
|
+
|
|
1468
1531
|
// allows passing through transport headers if necessary
|
|
1469
1532
|
// this handles some non-standard bearer auth setups (i.e. MCP server behind CF access instead of OAuth)
|
|
1470
1533
|
let headerTransportOpts: SSEClientTransportOptions = {};
|
|
@@ -1488,7 +1551,8 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
1488
1551
|
reconnect,
|
|
1489
1552
|
transport: {
|
|
1490
1553
|
...headerTransportOpts,
|
|
1491
|
-
authProvider
|
|
1554
|
+
authProvider,
|
|
1555
|
+
type: transportType
|
|
1492
1556
|
}
|
|
1493
1557
|
});
|
|
1494
1558
|
|
|
@@ -1501,15 +1565,11 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
1501
1565
|
|
|
1502
1566
|
async removeMcpServer(id: string) {
|
|
1503
1567
|
this.mcp.closeConnection(id);
|
|
1568
|
+
this.mcp.unregisterCallbackUrl(id);
|
|
1504
1569
|
this.sql`
|
|
1505
1570
|
DELETE FROM cf_agents_mcp_servers WHERE id = ${id};
|
|
1506
1571
|
`;
|
|
1507
|
-
this.
|
|
1508
|
-
JSON.stringify({
|
|
1509
|
-
mcp: this.getMcpServers(),
|
|
1510
|
-
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
1511
|
-
})
|
|
1512
|
-
);
|
|
1572
|
+
this.broadcastMcpServers();
|
|
1513
1573
|
}
|
|
1514
1574
|
|
|
1515
1575
|
getMcpServers(): MCPServersState {
|
|
@@ -1541,8 +1601,53 @@ export class Agent<Env = typeof env, State = unknown> extends Server<Env> {
|
|
|
1541
1601
|
|
|
1542
1602
|
return mcpState;
|
|
1543
1603
|
}
|
|
1604
|
+
|
|
1605
|
+
private broadcastMcpServers() {
|
|
1606
|
+
this.broadcast(
|
|
1607
|
+
JSON.stringify({
|
|
1608
|
+
mcp: this.getMcpServers(),
|
|
1609
|
+
type: MessageType.CF_AGENT_MCP_SERVERS
|
|
1610
|
+
})
|
|
1611
|
+
);
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
/**
|
|
1615
|
+
* Handle OAuth callback response using MCPClientManager configuration
|
|
1616
|
+
* @param result OAuth callback result
|
|
1617
|
+
* @param request The original request (needed for base URL)
|
|
1618
|
+
* @returns Response for the OAuth callback
|
|
1619
|
+
*/
|
|
1620
|
+
private handleOAuthCallbackResponse(
|
|
1621
|
+
result: MCPClientOAuthResult,
|
|
1622
|
+
request: Request
|
|
1623
|
+
): Response {
|
|
1624
|
+
const config = this.mcp.getOAuthCallbackConfig();
|
|
1625
|
+
|
|
1626
|
+
// Use custom handler if configured
|
|
1627
|
+
if (config?.customHandler) {
|
|
1628
|
+
return config.customHandler(result);
|
|
1629
|
+
}
|
|
1630
|
+
|
|
1631
|
+
// Use redirect URLs if configured
|
|
1632
|
+
if (config?.successRedirect && result.authSuccess) {
|
|
1633
|
+
return Response.redirect(config.successRedirect);
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1636
|
+
if (config?.errorRedirect && !result.authSuccess) {
|
|
1637
|
+
return Response.redirect(
|
|
1638
|
+
`${config.errorRedirect}?error=${encodeURIComponent(result.authError || "Unknown error")}`
|
|
1639
|
+
);
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
// Default behavior - redirect to base URL
|
|
1643
|
+
const baseUrl = new URL(request.url).origin;
|
|
1644
|
+
return Response.redirect(baseUrl);
|
|
1645
|
+
}
|
|
1544
1646
|
}
|
|
1545
1647
|
|
|
1648
|
+
// A set of classes that have been wrapped with agent context
|
|
1649
|
+
const wrappedClasses = new Set<typeof Agent.prototype.constructor>();
|
|
1650
|
+
|
|
1546
1651
|
/**
|
|
1547
1652
|
* Namespace for creating Agent instances
|
|
1548
1653
|
* @template Agentic Type of the Agent class
|
|
@@ -1858,12 +1963,17 @@ export type EmailSendOptions = {
|
|
|
1858
1963
|
* @param options Options for Agent creation
|
|
1859
1964
|
* @returns Promise resolving to an Agent instance stub
|
|
1860
1965
|
*/
|
|
1861
|
-
export async function getAgentByName<
|
|
1966
|
+
export async function getAgentByName<
|
|
1967
|
+
Env,
|
|
1968
|
+
T extends Agent<Env>,
|
|
1969
|
+
Props extends Record<string, unknown> = Record<string, unknown>
|
|
1970
|
+
>(
|
|
1862
1971
|
namespace: AgentNamespace<T>,
|
|
1863
1972
|
name: string,
|
|
1864
1973
|
options?: {
|
|
1865
1974
|
jurisdiction?: DurableObjectJurisdiction;
|
|
1866
1975
|
locationHint?: DurableObjectLocationHint;
|
|
1976
|
+
props?: Props;
|
|
1867
1977
|
}
|
|
1868
1978
|
) {
|
|
1869
1979
|
return getServerByName<Env, T>(namespace, name, options);
|
package/dist/ai-types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/chunk-EEKLJYON.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
// src/ai-types.ts
|
|
2
|
-
var MessageType = /* @__PURE__ */ ((MessageType2) => {
|
|
3
|
-
MessageType2["CF_AGENT_CHAT_MESSAGES"] = "cf_agent_chat_messages";
|
|
4
|
-
MessageType2["CF_AGENT_USE_CHAT_RESPONSE"] = "cf_agent_use_chat_response";
|
|
5
|
-
MessageType2["CF_AGENT_CHAT_CLEAR"] = "cf_agent_chat_clear";
|
|
6
|
-
MessageType2["CF_AGENT_USE_CHAT_REQUEST"] = "cf_agent_use_chat_request";
|
|
7
|
-
MessageType2["CF_AGENT_CHAT_REQUEST_CANCEL"] = "cf_agent_chat_request_cancel";
|
|
8
|
-
MessageType2["CF_AGENT_MCP_SERVERS"] = "cf_agent_mcp_servers";
|
|
9
|
-
MessageType2["CF_AGENT_STATE"] = "cf_agent_state";
|
|
10
|
-
MessageType2["RPC"] = "rpc";
|
|
11
|
-
return MessageType2;
|
|
12
|
-
})(MessageType || {});
|
|
13
|
-
|
|
14
|
-
export {
|
|
15
|
-
MessageType
|
|
16
|
-
};
|
|
17
|
-
//# sourceMappingURL=chunk-EEKLJYON.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ai-types.ts"],"sourcesContent":["import type { Message as ChatMessage } from \"ai\";\n\n/**\n * Enum for message types used in Agent communication\n */\nexport enum MessageType {\n /** Indicates this message contains updated chat messages */\n CF_AGENT_CHAT_MESSAGES = \"cf_agent_chat_messages\",\n /** Indicates this message is a response to a chat request */\n CF_AGENT_USE_CHAT_RESPONSE = \"cf_agent_use_chat_response\",\n /** Indicates this message is a command to clear chat history */\n CF_AGENT_CHAT_CLEAR = \"cf_agent_chat_clear\",\n /** Indicates this message is a request to the chat API */\n CF_AGENT_USE_CHAT_REQUEST = \"cf_agent_use_chat_request\",\n /** Indicates the user wants to stop generation of this message */\n CF_AGENT_CHAT_REQUEST_CANCEL = \"cf_agent_chat_request_cancel\",\n\n CF_AGENT_MCP_SERVERS = \"cf_agent_mcp_servers\",\n CF_AGENT_STATE = \"cf_agent_state\",\n RPC = \"rpc\"\n}\n\n/**\n * Types of messages sent from the Agent to clients\n */\nexport type OutgoingMessage =\n | {\n /** Indicates this message contains updated chat messages */\n type: MessageType.CF_AGENT_CHAT_MESSAGES;\n /** Array of chat messages */\n messages: ChatMessage[];\n }\n | {\n /** Indicates this message is a response to a chat request */\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE;\n /** Unique ID of the request this response corresponds to */\n id: string;\n /** Content body of the response */\n body: string;\n /** Whether this is the final chunk of the response */\n done: boolean;\n }\n | {\n /** Indicates this message contains updated chat messages */\n type: MessageType.CF_AGENT_CHAT_MESSAGES;\n /** Array of chat messages */\n messages: ChatMessage[];\n }\n | {\n /** Indicates this message is a command to clear chat history */\n type: MessageType.CF_AGENT_CHAT_CLEAR;\n };\n\n/**\n * Types of messages sent from clients to the Agent\n */\nexport type IncomingMessage =\n | {\n /** Indicates this message is a request to the chat API */\n type: MessageType.CF_AGENT_USE_CHAT_REQUEST;\n /** Unique ID for this request */\n id: string;\n /** Request initialization options */\n init: Pick<\n RequestInit,\n | \"method\"\n | \"keepalive\"\n | \"headers\"\n | \"body\"\n | \"redirect\"\n | \"integrity\"\n | \"credentials\"\n | \"mode\"\n | \"referrer\"\n | \"referrerPolicy\"\n | \"window\"\n >;\n }\n | {\n /** Indicates this message is a command to clear chat history */\n type: MessageType.CF_AGENT_CHAT_CLEAR;\n }\n | {\n /** Indicates this message contains updated chat messages */\n type: MessageType.CF_AGENT_CHAT_MESSAGES;\n /** Array of chat messages */\n messages: ChatMessage[];\n }\n | {\n /** Indicates the user wants to stop generation of this message */\n type: MessageType.CF_AGENT_CHAT_REQUEST_CANCEL;\n id: string;\n };\n"],"mappings":";AAKO,IAAK,cAAL,kBAAKA,iBAAL;AAEL,EAAAA,aAAA,4BAAyB;AAEzB,EAAAA,aAAA,gCAA6B;AAE7B,EAAAA,aAAA,yBAAsB;AAEtB,EAAAA,aAAA,+BAA4B;AAE5B,EAAAA,aAAA,kCAA+B;AAE/B,EAAAA,aAAA,0BAAuB;AACvB,EAAAA,aAAA,oBAAiB;AACjB,EAAAA,aAAA,SAAM;AAdI,SAAAA;AAAA,GAAA;","names":["MessageType"]}
|