agents 0.0.0-956c772 → 0.0.0-9688c15
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/dist/ai-chat-agent.d.ts +22 -3
- package/dist/ai-chat-agent.js +94 -26
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-react.d.ts +12 -0
- package/dist/ai-react.js +25 -16
- package/dist/ai-react.js.map +1 -1
- package/dist/ai-types.d.ts +5 -0
- package/dist/chunk-25YDMV4H.js +464 -0
- package/dist/chunk-25YDMV4H.js.map +1 -0
- package/dist/chunk-D6UOOELW.js +106 -0
- package/dist/chunk-D6UOOELW.js.map +1 -0
- package/dist/chunk-RN4SNE73.js +133 -0
- package/dist/chunk-RN4SNE73.js.map +1 -0
- package/dist/{chunk-YMUU7QHV.js → chunk-YFPCCSZO.js} +245 -53
- package/dist/chunk-YFPCCSZO.js.map +1 -0
- package/dist/client.d.ts +7 -0
- package/dist/client.js +7 -126
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +74 -15
- package/dist/index.js +8 -7
- package/dist/mcp/client.d.ts +101 -32
- package/dist/mcp/client.js +4 -465
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/do-oauth-client-provider.d.ts +41 -0
- package/dist/mcp/do-oauth-client-provider.js +8 -0
- package/dist/mcp/do-oauth-client-provider.js.map +1 -0
- package/dist/mcp/index.d.ts +34 -4
- package/dist/mcp/index.js +573 -104
- package/dist/mcp/index.js.map +1 -1
- package/dist/react.d.ts +14 -0
- package/dist/react.js +4 -0
- package/dist/react.js.map +1 -1
- package/package.json +25 -5
- package/src/index.ts +344 -19
- package/dist/chunk-YMUU7QHV.js.map +0 -1
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__privateAdd,
|
|
3
|
+
__privateGet,
|
|
4
|
+
__privateSet
|
|
5
|
+
} from "./chunk-HMLY7DHA.js";
|
|
6
|
+
|
|
7
|
+
// src/client.ts
|
|
8
|
+
import {
|
|
9
|
+
PartySocket
|
|
10
|
+
} from "partysocket";
|
|
11
|
+
function camelCaseToKebabCase(str) {
|
|
12
|
+
if (str === str.toUpperCase() && str !== str.toLowerCase()) {
|
|
13
|
+
return str.toLowerCase().replace(/_/g, "-");
|
|
14
|
+
}
|
|
15
|
+
let kebabified = str.replace(
|
|
16
|
+
/[A-Z]/g,
|
|
17
|
+
(letter) => `-${letter.toLowerCase()}`
|
|
18
|
+
);
|
|
19
|
+
kebabified = kebabified.startsWith("-") ? kebabified.slice(1) : kebabified;
|
|
20
|
+
return kebabified.replace(/_/g, "-").replace(/-$/, "");
|
|
21
|
+
}
|
|
22
|
+
var _options, _pendingCalls;
|
|
23
|
+
var AgentClient = class extends PartySocket {
|
|
24
|
+
constructor(options) {
|
|
25
|
+
const agentNamespace = camelCaseToKebabCase(options.agent);
|
|
26
|
+
super({
|
|
27
|
+
prefix: "agents",
|
|
28
|
+
party: agentNamespace,
|
|
29
|
+
room: options.name || "default",
|
|
30
|
+
...options
|
|
31
|
+
});
|
|
32
|
+
__privateAdd(this, _options);
|
|
33
|
+
__privateAdd(this, _pendingCalls, /* @__PURE__ */ new Map());
|
|
34
|
+
this.agent = agentNamespace;
|
|
35
|
+
this.name = options.name || "default";
|
|
36
|
+
__privateSet(this, _options, options);
|
|
37
|
+
this.addEventListener("message", (event) => {
|
|
38
|
+
if (typeof event.data === "string") {
|
|
39
|
+
let parsedMessage;
|
|
40
|
+
try {
|
|
41
|
+
parsedMessage = JSON.parse(event.data);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (parsedMessage.type === "cf_agent_state") {
|
|
46
|
+
__privateGet(this, _options).onStateUpdate?.(parsedMessage.state, "server");
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (parsedMessage.type === "rpc") {
|
|
50
|
+
const response = parsedMessage;
|
|
51
|
+
const pending = __privateGet(this, _pendingCalls).get(response.id);
|
|
52
|
+
if (!pending) return;
|
|
53
|
+
if (!response.success) {
|
|
54
|
+
pending.reject(new Error(response.error));
|
|
55
|
+
__privateGet(this, _pendingCalls).delete(response.id);
|
|
56
|
+
pending.stream?.onError?.(response.error);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if ("done" in response) {
|
|
60
|
+
if (response.done) {
|
|
61
|
+
pending.resolve(response.result);
|
|
62
|
+
__privateGet(this, _pendingCalls).delete(response.id);
|
|
63
|
+
pending.stream?.onDone?.(response.result);
|
|
64
|
+
} else {
|
|
65
|
+
pending.stream?.onChunk?.(response.result);
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
pending.resolve(response.result);
|
|
69
|
+
__privateGet(this, _pendingCalls).delete(response.id);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* @deprecated Use agentFetch instead
|
|
77
|
+
*/
|
|
78
|
+
static fetch(_opts) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
"AgentClient.fetch is not implemented, use agentFetch instead"
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
setState(state) {
|
|
84
|
+
this.send(JSON.stringify({ type: "cf_agent_state", state }));
|
|
85
|
+
__privateGet(this, _options).onStateUpdate?.(state, "client");
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Call a method on the Agent
|
|
89
|
+
* @param method Name of the method to call
|
|
90
|
+
* @param args Arguments to pass to the method
|
|
91
|
+
* @param streamOptions Options for handling streaming responses
|
|
92
|
+
* @returns Promise that resolves with the method's return value
|
|
93
|
+
*/
|
|
94
|
+
async call(method, args = [], streamOptions) {
|
|
95
|
+
return new Promise((resolve, reject) => {
|
|
96
|
+
const id = Math.random().toString(36).slice(2);
|
|
97
|
+
__privateGet(this, _pendingCalls).set(id, {
|
|
98
|
+
resolve: (value) => resolve(value),
|
|
99
|
+
reject,
|
|
100
|
+
stream: streamOptions,
|
|
101
|
+
type: null
|
|
102
|
+
});
|
|
103
|
+
const request = {
|
|
104
|
+
type: "rpc",
|
|
105
|
+
id,
|
|
106
|
+
method,
|
|
107
|
+
args
|
|
108
|
+
};
|
|
109
|
+
this.send(JSON.stringify(request));
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
_options = new WeakMap();
|
|
114
|
+
_pendingCalls = new WeakMap();
|
|
115
|
+
function agentFetch(opts, init) {
|
|
116
|
+
const agentNamespace = camelCaseToKebabCase(opts.agent);
|
|
117
|
+
return PartySocket.fetch(
|
|
118
|
+
{
|
|
119
|
+
prefix: "agents",
|
|
120
|
+
party: agentNamespace,
|
|
121
|
+
room: opts.name || "default",
|
|
122
|
+
...opts
|
|
123
|
+
},
|
|
124
|
+
init
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export {
|
|
129
|
+
camelCaseToKebabCase,
|
|
130
|
+
AgentClient,
|
|
131
|
+
agentFetch
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=chunk-RN4SNE73.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 \"./\";\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 #options: AgentClientOptions<State>;\n #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":[]}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DurableObjectOAuthClientProvider
|
|
3
|
+
} from "./chunk-D6UOOELW.js";
|
|
4
|
+
import {
|
|
5
|
+
camelCaseToKebabCase
|
|
6
|
+
} from "./chunk-RN4SNE73.js";
|
|
7
|
+
import {
|
|
8
|
+
MCPClientManager
|
|
9
|
+
} from "./chunk-25YDMV4H.js";
|
|
1
10
|
import {
|
|
2
11
|
__privateAdd,
|
|
3
12
|
__privateGet,
|
|
@@ -14,7 +23,6 @@ import {
|
|
|
14
23
|
import { parseCronExpression } from "cron-schedule";
|
|
15
24
|
import { nanoid } from "nanoid";
|
|
16
25
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
17
|
-
import { WorkflowEntrypoint as CFWorkflowEntrypoint } from "cloudflare:workers";
|
|
18
26
|
function isRPCRequest(msg) {
|
|
19
27
|
return typeof msg === "object" && msg !== null && "type" in msg && msg.type === "rpc" && "id" in msg && typeof msg.id === "string" && "method" in msg && typeof msg.method === "string" && "args" in msg && Array.isArray(msg.args);
|
|
20
28
|
}
|
|
@@ -30,8 +38,6 @@ function unstable_callable(metadata = {}) {
|
|
|
30
38
|
return target;
|
|
31
39
|
};
|
|
32
40
|
}
|
|
33
|
-
var WorkflowEntrypoint = class extends CFWorkflowEntrypoint {
|
|
34
|
-
};
|
|
35
41
|
function getNextCronTime(cron) {
|
|
36
42
|
const interval = parseCronExpression(cron);
|
|
37
43
|
return interval.getNextDate();
|
|
@@ -39,18 +45,74 @@ function getNextCronTime(cron) {
|
|
|
39
45
|
var STATE_ROW_ID = "cf_state_row_id";
|
|
40
46
|
var STATE_WAS_CHANGED = "cf_state_was_changed";
|
|
41
47
|
var DEFAULT_STATE = {};
|
|
42
|
-
var
|
|
43
|
-
|
|
48
|
+
var agentContext = new AsyncLocalStorage();
|
|
49
|
+
function getCurrentAgent() {
|
|
50
|
+
const store = agentContext.getStore();
|
|
51
|
+
if (!store) {
|
|
52
|
+
return {
|
|
53
|
+
agent: void 0,
|
|
54
|
+
connection: void 0,
|
|
55
|
+
request: void 0
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return store;
|
|
59
|
+
}
|
|
60
|
+
var _state, _ParentClass, _Agent_instances, setStateInternal_fn, tryCatch_fn, scheduleNextAlarm_fn, isCallable_fn, connectToMcpServerInternal_fn, getMcpServerStateInternal_fn;
|
|
44
61
|
var Agent = class extends Server {
|
|
45
62
|
constructor(ctx, env) {
|
|
46
63
|
super(ctx, env);
|
|
47
64
|
__privateAdd(this, _Agent_instances);
|
|
48
65
|
__privateAdd(this, _state, DEFAULT_STATE);
|
|
66
|
+
__privateAdd(this, _ParentClass, Object.getPrototypeOf(this).constructor);
|
|
67
|
+
this.mcp = new MCPClientManager(__privateGet(this, _ParentClass).name, "0.0.1");
|
|
49
68
|
/**
|
|
50
69
|
* Initial state for the Agent
|
|
51
70
|
* Override to provide default state values
|
|
52
71
|
*/
|
|
53
72
|
this.initialState = DEFAULT_STATE;
|
|
73
|
+
/**
|
|
74
|
+
* Method called when an alarm fires.
|
|
75
|
+
* Executes any scheduled tasks that are due.
|
|
76
|
+
*
|
|
77
|
+
* @remarks
|
|
78
|
+
* To schedule a task, please use the `this.schedule` method instead.
|
|
79
|
+
* See {@link https://developers.cloudflare.com/agents/api-reference/schedule-tasks/}
|
|
80
|
+
*/
|
|
81
|
+
this.alarm = async () => {
|
|
82
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
83
|
+
const result = this.sql`
|
|
84
|
+
SELECT * FROM cf_agents_schedules WHERE time <= ${now}
|
|
85
|
+
`;
|
|
86
|
+
for (const row of result || []) {
|
|
87
|
+
const callback = this[row.callback];
|
|
88
|
+
if (!callback) {
|
|
89
|
+
console.error(`callback ${row.callback} not found`);
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
await agentContext.run(
|
|
93
|
+
{ agent: this, connection: void 0, request: void 0 },
|
|
94
|
+
async () => {
|
|
95
|
+
try {
|
|
96
|
+
await callback.bind(this)(JSON.parse(row.payload), row);
|
|
97
|
+
} catch (e) {
|
|
98
|
+
console.error(`error executing callback "${row.callback}"`, e);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
);
|
|
102
|
+
if (row.type === "cron") {
|
|
103
|
+
const nextExecutionTime = getNextCronTime(row.cron);
|
|
104
|
+
const nextTimestamp = Math.floor(nextExecutionTime.getTime() / 1e3);
|
|
105
|
+
this.sql`
|
|
106
|
+
UPDATE cf_agents_schedules SET time = ${nextTimestamp} WHERE id = ${row.id}
|
|
107
|
+
`;
|
|
108
|
+
} else {
|
|
109
|
+
this.sql`
|
|
110
|
+
DELETE FROM cf_agents_schedules WHERE id = ${row.id}
|
|
111
|
+
`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
await __privateMethod(this, _Agent_instances, scheduleNextAlarm_fn).call(this);
|
|
115
|
+
};
|
|
54
116
|
this.sql`
|
|
55
117
|
CREATE TABLE IF NOT EXISTS cf_agents_state (
|
|
56
118
|
id TEXT PRIMARY KEY NOT NULL,
|
|
@@ -74,9 +136,42 @@ var Agent = class extends Server {
|
|
|
74
136
|
await this.alarm();
|
|
75
137
|
});
|
|
76
138
|
});
|
|
139
|
+
this.sql`
|
|
140
|
+
CREATE TABLE IF NOT EXISTS cf_agents_mcp_servers (
|
|
141
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
142
|
+
name TEXT NOT NULL,
|
|
143
|
+
server_url TEXT NOT NULL,
|
|
144
|
+
callback_url TEXT NOT NULL,
|
|
145
|
+
client_id TEXT,
|
|
146
|
+
auth_url TEXT,
|
|
147
|
+
server_options TEXT
|
|
148
|
+
)
|
|
149
|
+
`;
|
|
150
|
+
const _onRequest = this.onRequest.bind(this);
|
|
151
|
+
this.onRequest = (request) => {
|
|
152
|
+
return agentContext.run(
|
|
153
|
+
{ agent: this, connection: void 0, request },
|
|
154
|
+
async () => {
|
|
155
|
+
if (this.mcp.isCallbackRequest(request)) {
|
|
156
|
+
await this.mcp.handleCallbackRequest(request);
|
|
157
|
+
this.broadcast(
|
|
158
|
+
JSON.stringify({
|
|
159
|
+
type: "cf_agent_mcp_servers",
|
|
160
|
+
mcp: __privateMethod(this, _Agent_instances, getMcpServerStateInternal_fn).call(this)
|
|
161
|
+
})
|
|
162
|
+
);
|
|
163
|
+
return new Response("<script>window.close();</script>", {
|
|
164
|
+
status: 200,
|
|
165
|
+
headers: { "content-type": "text/html" }
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return __privateMethod(this, _Agent_instances, tryCatch_fn).call(this, () => _onRequest(request));
|
|
169
|
+
}
|
|
170
|
+
);
|
|
171
|
+
};
|
|
77
172
|
const _onMessage = this.onMessage.bind(this);
|
|
78
173
|
this.onMessage = async (connection, message) => {
|
|
79
|
-
return
|
|
174
|
+
return agentContext.run(
|
|
80
175
|
{ agent: this, connection, request: void 0 },
|
|
81
176
|
async () => {
|
|
82
177
|
if (typeof message !== "string") {
|
|
@@ -135,7 +230,7 @@ var Agent = class extends Server {
|
|
|
135
230
|
};
|
|
136
231
|
const _onConnect = this.onConnect.bind(this);
|
|
137
232
|
this.onConnect = (connection, ctx2) => {
|
|
138
|
-
return
|
|
233
|
+
return agentContext.run(
|
|
139
234
|
{ agent: this, connection, request: ctx2.request },
|
|
140
235
|
async () => {
|
|
141
236
|
setTimeout(() => {
|
|
@@ -147,11 +242,43 @@ var Agent = class extends Server {
|
|
|
147
242
|
})
|
|
148
243
|
);
|
|
149
244
|
}
|
|
245
|
+
connection.send(
|
|
246
|
+
JSON.stringify({
|
|
247
|
+
type: "cf_agent_mcp_servers",
|
|
248
|
+
mcp: __privateMethod(this, _Agent_instances, getMcpServerStateInternal_fn).call(this)
|
|
249
|
+
})
|
|
250
|
+
);
|
|
150
251
|
return __privateMethod(this, _Agent_instances, tryCatch_fn).call(this, () => _onConnect(connection, ctx2));
|
|
151
252
|
}, 20);
|
|
152
253
|
}
|
|
153
254
|
);
|
|
154
255
|
};
|
|
256
|
+
const _onStart = this.onStart.bind(this);
|
|
257
|
+
this.onStart = async () => {
|
|
258
|
+
return agentContext.run(
|
|
259
|
+
{ agent: this, connection: void 0, request: void 0 },
|
|
260
|
+
async () => {
|
|
261
|
+
const servers = this.sql`
|
|
262
|
+
SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
|
|
263
|
+
`;
|
|
264
|
+
await Promise.allSettled(
|
|
265
|
+
servers.map((server) => {
|
|
266
|
+
return __privateMethod(this, _Agent_instances, connectToMcpServerInternal_fn).call(this, server.name, server.server_url, server.callback_url, server.server_options ? JSON.parse(server.server_options) : void 0, {
|
|
267
|
+
id: server.id,
|
|
268
|
+
oauthClientId: server.client_id ?? void 0
|
|
269
|
+
});
|
|
270
|
+
})
|
|
271
|
+
);
|
|
272
|
+
this.broadcast(
|
|
273
|
+
JSON.stringify({
|
|
274
|
+
type: "cf_agent_mcp_servers",
|
|
275
|
+
mcp: __privateMethod(this, _Agent_instances, getMcpServerStateInternal_fn).call(this)
|
|
276
|
+
})
|
|
277
|
+
);
|
|
278
|
+
await __privateMethod(this, _Agent_instances, tryCatch_fn).call(this, () => _onStart());
|
|
279
|
+
}
|
|
280
|
+
);
|
|
281
|
+
};
|
|
155
282
|
}
|
|
156
283
|
/**
|
|
157
284
|
* Current state of the Agent
|
|
@@ -217,7 +344,7 @@ var Agent = class extends Server {
|
|
|
217
344
|
* @param email Email message to process
|
|
218
345
|
*/
|
|
219
346
|
onEmail(email) {
|
|
220
|
-
return
|
|
347
|
+
return agentContext.run(
|
|
221
348
|
{ agent: this, connection: void 0, request: void 0 },
|
|
222
349
|
async () => {
|
|
223
350
|
console.error("onEmail not implemented");
|
|
@@ -380,56 +507,51 @@ var Agent = class extends Server {
|
|
|
380
507
|
await __privateMethod(this, _Agent_instances, scheduleNextAlarm_fn).call(this);
|
|
381
508
|
return true;
|
|
382
509
|
}
|
|
383
|
-
/**
|
|
384
|
-
* Method called when an alarm fires
|
|
385
|
-
* Executes any scheduled tasks that are due
|
|
386
|
-
*/
|
|
387
|
-
async alarm() {
|
|
388
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
389
|
-
const result = this.sql`
|
|
390
|
-
SELECT * FROM cf_agents_schedules WHERE time <= ${now}
|
|
391
|
-
`;
|
|
392
|
-
for (const row of result || []) {
|
|
393
|
-
const callback = this[row.callback];
|
|
394
|
-
if (!callback) {
|
|
395
|
-
console.error(`callback ${row.callback} not found`);
|
|
396
|
-
continue;
|
|
397
|
-
}
|
|
398
|
-
await unstable_context.run(
|
|
399
|
-
{ agent: this, connection: void 0, request: void 0 },
|
|
400
|
-
async () => {
|
|
401
|
-
try {
|
|
402
|
-
await callback.bind(this)(JSON.parse(row.payload), row);
|
|
403
|
-
} catch (e) {
|
|
404
|
-
console.error(`error executing callback "${row.callback}"`, e);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
);
|
|
408
|
-
if (row.type === "cron") {
|
|
409
|
-
const nextExecutionTime = getNextCronTime(row.cron);
|
|
410
|
-
const nextTimestamp = Math.floor(nextExecutionTime.getTime() / 1e3);
|
|
411
|
-
this.sql`
|
|
412
|
-
UPDATE cf_agents_schedules SET time = ${nextTimestamp} WHERE id = ${row.id}
|
|
413
|
-
`;
|
|
414
|
-
} else {
|
|
415
|
-
this.sql`
|
|
416
|
-
DELETE FROM cf_agents_schedules WHERE id = ${row.id}
|
|
417
|
-
`;
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
await __privateMethod(this, _Agent_instances, scheduleNextAlarm_fn).call(this);
|
|
421
|
-
}
|
|
422
510
|
/**
|
|
423
511
|
* Destroy the Agent, removing all state and scheduled tasks
|
|
424
512
|
*/
|
|
425
513
|
async destroy() {
|
|
426
514
|
this.sql`DROP TABLE IF EXISTS cf_agents_state`;
|
|
427
515
|
this.sql`DROP TABLE IF EXISTS cf_agents_schedules`;
|
|
516
|
+
this.sql`DROP TABLE IF EXISTS cf_agents_mcp_servers`;
|
|
428
517
|
await this.ctx.storage.deleteAlarm();
|
|
429
518
|
await this.ctx.storage.deleteAll();
|
|
430
519
|
}
|
|
520
|
+
/**
|
|
521
|
+
* Connect to a new MCP Server
|
|
522
|
+
*
|
|
523
|
+
* @param url MCP Server SSE URL
|
|
524
|
+
* @param callbackHost Base host for the agent, used for the redirect URI.
|
|
525
|
+
* @param agentsPrefix agents routing prefix if not using `agents`
|
|
526
|
+
* @param options MCP client and transport (header) options
|
|
527
|
+
* @returns authUrl
|
|
528
|
+
*/
|
|
529
|
+
async addMcpServer(serverName, url, callbackHost, agentsPrefix = "agents", options) {
|
|
530
|
+
const callbackUrl = `${callbackHost}/${agentsPrefix}/${camelCaseToKebabCase(__privateGet(this, _ParentClass).name)}/${this.name}/callback`;
|
|
531
|
+
const result = await __privateMethod(this, _Agent_instances, connectToMcpServerInternal_fn).call(this, serverName, url, callbackUrl, options);
|
|
532
|
+
this.broadcast(
|
|
533
|
+
JSON.stringify({
|
|
534
|
+
type: "cf_agent_mcp_servers",
|
|
535
|
+
mcp: __privateMethod(this, _Agent_instances, getMcpServerStateInternal_fn).call(this)
|
|
536
|
+
})
|
|
537
|
+
);
|
|
538
|
+
return result;
|
|
539
|
+
}
|
|
540
|
+
async removeMcpServer(id) {
|
|
541
|
+
this.mcp.closeConnection(id);
|
|
542
|
+
this.sql`
|
|
543
|
+
DELETE FROM cf_agents_mcp_servers WHERE id = ${id};
|
|
544
|
+
`;
|
|
545
|
+
this.broadcast(
|
|
546
|
+
JSON.stringify({
|
|
547
|
+
type: "cf_agent_mcp_servers",
|
|
548
|
+
mcp: __privateMethod(this, _Agent_instances, getMcpServerStateInternal_fn).call(this)
|
|
549
|
+
})
|
|
550
|
+
);
|
|
551
|
+
}
|
|
431
552
|
};
|
|
432
553
|
_state = new WeakMap();
|
|
554
|
+
_ParentClass = new WeakMap();
|
|
433
555
|
_Agent_instances = new WeakSet();
|
|
434
556
|
setStateInternal_fn = function(state, source = "server") {
|
|
435
557
|
__privateSet(this, _state, state);
|
|
@@ -449,8 +571,8 @@ setStateInternal_fn = function(state, source = "server") {
|
|
|
449
571
|
source !== "server" ? [source.id] : []
|
|
450
572
|
);
|
|
451
573
|
return __privateMethod(this, _Agent_instances, tryCatch_fn).call(this, () => {
|
|
452
|
-
const { connection, request } =
|
|
453
|
-
return
|
|
574
|
+
const { connection, request } = agentContext.getStore() || {};
|
|
575
|
+
return agentContext.run(
|
|
454
576
|
{ agent: this, connection, request },
|
|
455
577
|
async () => {
|
|
456
578
|
return this.onStateUpdate(state, source);
|
|
@@ -485,6 +607,77 @@ scheduleNextAlarm_fn = async function() {
|
|
|
485
607
|
isCallable_fn = function(method) {
|
|
486
608
|
return callableMetadata.has(this[method]);
|
|
487
609
|
};
|
|
610
|
+
connectToMcpServerInternal_fn = async function(serverName, url, callbackUrl, options, reconnect) {
|
|
611
|
+
const authProvider = new DurableObjectOAuthClientProvider(
|
|
612
|
+
this.ctx.storage,
|
|
613
|
+
this.name,
|
|
614
|
+
callbackUrl
|
|
615
|
+
);
|
|
616
|
+
if (reconnect) {
|
|
617
|
+
authProvider.serverId = reconnect.id;
|
|
618
|
+
if (reconnect.oauthClientId) {
|
|
619
|
+
authProvider.clientId = reconnect.oauthClientId;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
let headerTransportOpts = {};
|
|
623
|
+
if (options?.transport?.headers) {
|
|
624
|
+
headerTransportOpts = {
|
|
625
|
+
eventSourceInit: {
|
|
626
|
+
fetch: (url2, init) => fetch(url2, {
|
|
627
|
+
...init,
|
|
628
|
+
headers: options?.transport?.headers
|
|
629
|
+
})
|
|
630
|
+
},
|
|
631
|
+
requestInit: {
|
|
632
|
+
headers: options?.transport?.headers
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
const { id, authUrl, clientId } = await this.mcp.connect(url, {
|
|
637
|
+
reconnect,
|
|
638
|
+
transport: {
|
|
639
|
+
...headerTransportOpts,
|
|
640
|
+
authProvider
|
|
641
|
+
},
|
|
642
|
+
client: options?.client
|
|
643
|
+
});
|
|
644
|
+
this.sql`
|
|
645
|
+
INSERT OR REPLACE INTO cf_agents_mcp_servers (id, name, server_url, client_id, auth_url, callback_url, server_options)
|
|
646
|
+
VALUES (
|
|
647
|
+
${id},
|
|
648
|
+
${serverName},
|
|
649
|
+
${url},
|
|
650
|
+
${clientId ?? null},
|
|
651
|
+
${authUrl ?? null},
|
|
652
|
+
${callbackUrl},
|
|
653
|
+
${options ? JSON.stringify(options) : null}
|
|
654
|
+
);
|
|
655
|
+
`;
|
|
656
|
+
return {
|
|
657
|
+
id,
|
|
658
|
+
authUrl
|
|
659
|
+
};
|
|
660
|
+
};
|
|
661
|
+
getMcpServerStateInternal_fn = function() {
|
|
662
|
+
const mcpState = {
|
|
663
|
+
servers: {},
|
|
664
|
+
tools: this.mcp.listTools(),
|
|
665
|
+
prompts: this.mcp.listPrompts(),
|
|
666
|
+
resources: this.mcp.listResources()
|
|
667
|
+
};
|
|
668
|
+
const servers = this.sql`
|
|
669
|
+
SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
|
|
670
|
+
`;
|
|
671
|
+
for (const server of servers) {
|
|
672
|
+
mcpState.servers[server.id] = {
|
|
673
|
+
name: server.name,
|
|
674
|
+
server_url: server.server_url,
|
|
675
|
+
auth_url: server.auth_url,
|
|
676
|
+
state: this.mcp.mcpConnections[server.id].connectionState
|
|
677
|
+
};
|
|
678
|
+
}
|
|
679
|
+
return mcpState;
|
|
680
|
+
};
|
|
488
681
|
/**
|
|
489
682
|
* Agent configuration options
|
|
490
683
|
*/
|
|
@@ -530,7 +723,7 @@ async function routeAgentRequest(request, env, options) {
|
|
|
530
723
|
}
|
|
531
724
|
async function routeAgentEmail(email, env, options) {
|
|
532
725
|
}
|
|
533
|
-
function getAgentByName(namespace, name, options) {
|
|
726
|
+
async function getAgentByName(namespace, name, options) {
|
|
534
727
|
return getServerByName(namespace, name, options);
|
|
535
728
|
}
|
|
536
729
|
var _connection, _id, _closed;
|
|
@@ -584,12 +777,11 @@ _closed = new WeakMap();
|
|
|
584
777
|
|
|
585
778
|
export {
|
|
586
779
|
unstable_callable,
|
|
587
|
-
|
|
588
|
-
unstable_context,
|
|
780
|
+
getCurrentAgent,
|
|
589
781
|
Agent,
|
|
590
782
|
routeAgentRequest,
|
|
591
783
|
routeAgentEmail,
|
|
592
784
|
getAgentByName,
|
|
593
785
|
StreamingResponse
|
|
594
786
|
};
|
|
595
|
-
//# sourceMappingURL=chunk-
|
|
787
|
+
//# sourceMappingURL=chunk-YFPCCSZO.js.map
|