agents 0.7.4 → 0.7.6
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.js +3 -4
- package/dist/ai-chat-agent.js.map +1 -1
- package/dist/ai-chat-v5-migration.js +3 -4
- package/dist/ai-chat-v5-migration.js.map +1 -1
- package/dist/ai-react.js +3 -4
- package/dist/ai-react.js.map +1 -1
- package/dist/ai-types.js +1 -2
- package/dist/ai-types.js.map +1 -1
- package/dist/cli/index.js +2 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/client-K8Z-u76l.js +1468 -0
- package/dist/client-K8Z-u76l.js.map +1 -0
- package/dist/client.js +1 -2
- package/dist/client.js.map +1 -1
- package/dist/codemode/ai.js +2 -2
- package/dist/do-oauth-client-provider-C2jurFjW.d.ts +78 -0
- package/dist/email-U_MG7UET.d.ts +157 -0
- package/dist/email.d.ts +16 -146
- package/dist/email.js +2 -2
- package/dist/email.js.map +1 -1
- package/dist/experimental/forever.d.ts +26 -71
- package/dist/experimental/forever.js +2 -3
- package/dist/experimental/forever.js.map +1 -1
- package/dist/experimental/memory/session/index.js +3 -12
- package/dist/experimental/memory/session/index.js.map +1 -1
- package/dist/experimental/workspace.d.ts +273 -0
- package/dist/experimental/workspace.js +1265 -0
- package/dist/experimental/workspace.js.map +1 -0
- package/dist/index-BS_jL8MI.d.ts +492 -0
- package/dist/index-WBy5hmm3.d.ts +2840 -0
- package/dist/index.d.ts +49 -1320
- package/dist/index.js +281 -138
- package/dist/index.js.map +1 -1
- package/dist/internal_context-DgcmHqS1.d.ts +37 -0
- package/dist/internal_context.d.ts +5 -32
- package/dist/internal_context.js +1 -2
- package/dist/internal_context.js.map +1 -1
- package/dist/mcp/client.d.ts +2 -575
- package/dist/mcp/client.js +1 -847
- package/dist/mcp/do-oauth-client-provider.d.ts +2 -61
- package/dist/mcp/do-oauth-client-provider.js +1 -2
- package/dist/mcp/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/index.d.ts +2 -95
- package/dist/mcp/index.js +60 -57
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/x402.js +1 -2
- package/dist/mcp/x402.js.map +1 -1
- package/dist/observability/index.d.ts +2 -93
- package/dist/observability/index.js +4 -3
- package/dist/observability/index.js.map +1 -1
- package/dist/react.d.ts +1 -2
- package/dist/react.js +1 -2
- package/dist/react.js.map +1 -1
- package/dist/retries-DXMQGhG3.d.ts +79 -0
- package/dist/retries.d.ts +7 -72
- package/dist/retries.js +1 -1
- package/dist/retries.js.map +1 -1
- package/dist/schedule.js +1 -2
- package/dist/schedule.js.map +1 -1
- package/dist/serializable.js +1 -1
- package/dist/types-BB1plA51.d.ts +15 -0
- package/dist/types.d.ts +1 -14
- package/dist/types.js +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils.js +1 -1
- package/dist/workflow-types-CZNXKj_D.d.ts +260 -0
- package/dist/workflow-types.d.ts +23 -235
- package/dist/workflow-types.js +1 -1
- package/dist/workflow-types.js.map +1 -1
- package/dist/workflows.d.ts +22 -23
- package/dist/workflows.js +5 -6
- package/dist/workflows.js.map +1 -1
- package/package.json +25 -13
- package/dist/agent-eZnMHidZ.d.ts +0 -273
- package/dist/client-connection-D3Wcd6Q6.js +0 -603
- package/dist/client-connection-D3Wcd6Q6.js.map +0 -1
- package/dist/client-storage-BPjfP_is.d.ts +0 -604
- package/dist/experimental/sub-agent.d.ts +0 -205
- package/dist/experimental/sub-agent.js +0 -191
- package/dist/experimental/sub-agent.js.map +0 -1
- package/dist/mcp/client.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -3,15 +3,13 @@ import { camelCaseToKebabCase } from "./utils.js";
|
|
|
3
3
|
import { createHeaderBasedEmailResolver, signAgentHeaders } from "./email.js";
|
|
4
4
|
import { __DO_NOT_USE_WILL_BREAK__agentContext } from "./internal_context.js";
|
|
5
5
|
import { isErrorRetryable, tryN, validateRetryOptions } from "./retries.js";
|
|
6
|
-
import {
|
|
6
|
+
import { o as RPC_DO_PREFIX, r as MCPConnectionState, s as DisposableStore, t as MCPClientManager } from "./client-K8Z-u76l.js";
|
|
7
7
|
import { DurableObjectOAuthClientProvider } from "./mcp/do-oauth-client-provider.js";
|
|
8
|
-
import { MCPClientManager } from "./mcp/client.js";
|
|
9
8
|
import { genericObservability } from "./observability/index.js";
|
|
10
9
|
import { parseCronExpression } from "cron-schedule";
|
|
11
10
|
import { nanoid } from "nanoid";
|
|
12
11
|
import { EmailMessage } from "cloudflare:email";
|
|
13
12
|
import { Server, getServerByName, routePartykitRequest } from "partyserver";
|
|
14
|
-
|
|
15
13
|
//#region src/index.ts
|
|
16
14
|
/**
|
|
17
15
|
* Type guard for RPC request messages
|
|
@@ -67,6 +65,14 @@ function getNextCronTime(cron) {
|
|
|
67
65
|
return parseCronExpression(cron).getNextDate();
|
|
68
66
|
}
|
|
69
67
|
const KEEP_ALIVE_INTERVAL_MS = 3e4;
|
|
68
|
+
/**
|
|
69
|
+
* Schema version for the Agent's internal SQLite tables.
|
|
70
|
+
* Bump this when adding new tables, columns, or migrations.
|
|
71
|
+
* The constructor stores this as a row in cf_agents_state and checks it
|
|
72
|
+
* on wake to skip DDL on established DOs.
|
|
73
|
+
*/
|
|
74
|
+
const CURRENT_SCHEMA_VERSION = 1;
|
|
75
|
+
const SCHEMA_VERSION_ROW_ID = "cf_schema_version";
|
|
70
76
|
const STATE_ROW_ID = "cf_state_row_id";
|
|
71
77
|
const STATE_WAS_CHANGED = "cf_state_was_changed";
|
|
72
78
|
const DEFAULT_STATE = {};
|
|
@@ -85,7 +91,11 @@ const CF_NO_PROTOCOL_KEY = "_cf_no_protocol";
|
|
|
85
91
|
* The set of all internal keys stored in connection state that must be
|
|
86
92
|
* hidden from user code and preserved across setState calls.
|
|
87
93
|
*/
|
|
88
|
-
const CF_INTERNAL_KEYS = new Set([
|
|
94
|
+
const CF_INTERNAL_KEYS = new Set([
|
|
95
|
+
CF_READONLY_KEY,
|
|
96
|
+
CF_NO_PROTOCOL_KEY,
|
|
97
|
+
"_cf_voiceInCall"
|
|
98
|
+
]);
|
|
89
99
|
/** Check if a raw connection state object contains any internal keys. */
|
|
90
100
|
function rawHasInternalKeys(raw) {
|
|
91
101
|
for (const key of Object.keys(raw)) if (CF_INTERNAL_KEYS.has(key)) return true;
|
|
@@ -207,14 +217,11 @@ var Agent = class Agent extends Server {
|
|
|
207
217
|
*/
|
|
208
218
|
get state() {
|
|
209
219
|
if (this._state !== DEFAULT_STATE) return this._state;
|
|
210
|
-
const wasChanged = this.sql`
|
|
211
|
-
SELECT state FROM cf_agents_state WHERE id = ${STATE_WAS_CHANGED}
|
|
212
|
-
`;
|
|
213
220
|
const result = this.sql`
|
|
214
221
|
SELECT state FROM cf_agents_state WHERE id = ${STATE_ROW_ID}
|
|
215
222
|
`;
|
|
216
|
-
if (
|
|
217
|
-
const state = result[0]
|
|
223
|
+
if (result.length > 0) {
|
|
224
|
+
const state = result[0].state;
|
|
218
225
|
try {
|
|
219
226
|
this._state = JSON.parse(state);
|
|
220
227
|
} catch (e) {
|
|
@@ -224,7 +231,6 @@ var Agent = class Agent extends Server {
|
|
|
224
231
|
this._setStateInternal(this.initialState);
|
|
225
232
|
} else {
|
|
226
233
|
this.sql`DELETE FROM cf_agents_state WHERE id = ${STATE_ROW_ID}`;
|
|
227
|
-
this.sql`DELETE FROM cf_agents_state WHERE id = ${STATE_WAS_CHANGED}`;
|
|
228
234
|
return;
|
|
229
235
|
}
|
|
230
236
|
}
|
|
@@ -234,9 +240,6 @@ var Agent = class Agent extends Server {
|
|
|
234
240
|
this._setStateInternal(this.initialState);
|
|
235
241
|
return this.initialState;
|
|
236
242
|
}
|
|
237
|
-
static {
|
|
238
|
-
this.options = { hibernate: true };
|
|
239
|
-
}
|
|
240
243
|
get _resolvedOptions() {
|
|
241
244
|
if (this._cachedOptions) return this._cachedOptions;
|
|
242
245
|
const ctor = this.constructor;
|
|
@@ -282,6 +285,138 @@ var Agent = class Agent extends Server {
|
|
|
282
285
|
throw new SqlError(query, e);
|
|
283
286
|
}
|
|
284
287
|
}
|
|
288
|
+
/**
|
|
289
|
+
* Create all internal tables and run migrations if needed.
|
|
290
|
+
* Called by the constructor on every wake. Idempotent — skips DDL when
|
|
291
|
+
* the stored schema version matches CURRENT_SCHEMA_VERSION.
|
|
292
|
+
*
|
|
293
|
+
* Protected so that test agents can re-run the real migration path
|
|
294
|
+
* after manipulating DB state (since ctx.abort() is unavailable in
|
|
295
|
+
* local dev and the constructor only runs once per DO instance).
|
|
296
|
+
*/
|
|
297
|
+
_ensureSchema() {
|
|
298
|
+
this.sql`
|
|
299
|
+
CREATE TABLE IF NOT EXISTS cf_agents_state (
|
|
300
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
301
|
+
state TEXT
|
|
302
|
+
)
|
|
303
|
+
`;
|
|
304
|
+
const versionRow = this.sql`
|
|
305
|
+
SELECT state FROM cf_agents_state WHERE id = ${SCHEMA_VERSION_ROW_ID}
|
|
306
|
+
`;
|
|
307
|
+
if ((versionRow.length > 0 ? Number(versionRow[0].state) : 0) < CURRENT_SCHEMA_VERSION) {
|
|
308
|
+
this.sql`
|
|
309
|
+
CREATE TABLE IF NOT EXISTS cf_agents_mcp_servers (
|
|
310
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
311
|
+
name TEXT NOT NULL,
|
|
312
|
+
server_url TEXT NOT NULL,
|
|
313
|
+
callback_url TEXT NOT NULL,
|
|
314
|
+
client_id TEXT,
|
|
315
|
+
auth_url TEXT,
|
|
316
|
+
server_options TEXT
|
|
317
|
+
)
|
|
318
|
+
`;
|
|
319
|
+
this.sql`
|
|
320
|
+
CREATE TABLE IF NOT EXISTS cf_agents_queues (
|
|
321
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
322
|
+
payload TEXT,
|
|
323
|
+
callback TEXT,
|
|
324
|
+
created_at INTEGER DEFAULT (unixepoch())
|
|
325
|
+
)
|
|
326
|
+
`;
|
|
327
|
+
this.sql`
|
|
328
|
+
CREATE TABLE IF NOT EXISTS cf_agents_schedules (
|
|
329
|
+
id TEXT PRIMARY KEY NOT NULL DEFAULT (randomblob(9)),
|
|
330
|
+
callback TEXT,
|
|
331
|
+
payload TEXT,
|
|
332
|
+
type TEXT NOT NULL CHECK(type IN ('scheduled', 'delayed', 'cron', 'interval')),
|
|
333
|
+
time INTEGER,
|
|
334
|
+
delayInSeconds INTEGER,
|
|
335
|
+
cron TEXT,
|
|
336
|
+
intervalSeconds INTEGER,
|
|
337
|
+
running INTEGER DEFAULT 0,
|
|
338
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
339
|
+
execution_started_at INTEGER,
|
|
340
|
+
retry_options TEXT
|
|
341
|
+
)
|
|
342
|
+
`;
|
|
343
|
+
const addColumnIfNotExists = (sql) => {
|
|
344
|
+
try {
|
|
345
|
+
this.ctx.storage.sql.exec(sql);
|
|
346
|
+
} catch (e) {
|
|
347
|
+
if (!(e instanceof Error ? e.message : String(e)).toLowerCase().includes("duplicate column")) throw e;
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
addColumnIfNotExists("ALTER TABLE cf_agents_schedules ADD COLUMN intervalSeconds INTEGER");
|
|
351
|
+
addColumnIfNotExists("ALTER TABLE cf_agents_schedules ADD COLUMN running INTEGER DEFAULT 0");
|
|
352
|
+
addColumnIfNotExists("ALTER TABLE cf_agents_schedules ADD COLUMN execution_started_at INTEGER");
|
|
353
|
+
addColumnIfNotExists("ALTER TABLE cf_agents_schedules ADD COLUMN retry_options TEXT");
|
|
354
|
+
addColumnIfNotExists("ALTER TABLE cf_agents_queues ADD COLUMN retry_options TEXT");
|
|
355
|
+
{
|
|
356
|
+
const rows = this.ctx.storage.sql.exec("SELECT sql FROM sqlite_master WHERE type='table' AND name='cf_agents_schedules'").toArray();
|
|
357
|
+
if (rows.length > 0) {
|
|
358
|
+
if (!String(rows[0].sql).includes("'interval'")) {
|
|
359
|
+
this.ctx.storage.sql.exec("DROP TABLE IF EXISTS cf_agents_schedules_new");
|
|
360
|
+
this.ctx.storage.sql.exec(`
|
|
361
|
+
CREATE TABLE cf_agents_schedules_new (
|
|
362
|
+
id TEXT PRIMARY KEY NOT NULL DEFAULT (randomblob(9)),
|
|
363
|
+
callback TEXT,
|
|
364
|
+
payload TEXT,
|
|
365
|
+
type TEXT NOT NULL CHECK(type IN ('scheduled', 'delayed', 'cron', 'interval')),
|
|
366
|
+
time INTEGER,
|
|
367
|
+
delayInSeconds INTEGER,
|
|
368
|
+
cron TEXT,
|
|
369
|
+
intervalSeconds INTEGER,
|
|
370
|
+
running INTEGER DEFAULT 0,
|
|
371
|
+
created_at INTEGER DEFAULT (unixepoch()),
|
|
372
|
+
execution_started_at INTEGER,
|
|
373
|
+
retry_options TEXT
|
|
374
|
+
)
|
|
375
|
+
`);
|
|
376
|
+
this.ctx.storage.sql.exec(`
|
|
377
|
+
INSERT INTO cf_agents_schedules_new
|
|
378
|
+
(id, callback, payload, type, time, delayInSeconds, cron,
|
|
379
|
+
intervalSeconds, running, created_at, execution_started_at, retry_options)
|
|
380
|
+
SELECT id, callback, payload, type, time, delayInSeconds, cron,
|
|
381
|
+
intervalSeconds, running, created_at, execution_started_at, retry_options
|
|
382
|
+
FROM cf_agents_schedules
|
|
383
|
+
`);
|
|
384
|
+
this.ctx.storage.sql.exec("DROP TABLE cf_agents_schedules");
|
|
385
|
+
this.ctx.storage.sql.exec("ALTER TABLE cf_agents_schedules_new RENAME TO cf_agents_schedules");
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
this.sql`
|
|
390
|
+
CREATE TABLE IF NOT EXISTS cf_agents_workflows (
|
|
391
|
+
id TEXT PRIMARY KEY NOT NULL,
|
|
392
|
+
workflow_id TEXT NOT NULL UNIQUE,
|
|
393
|
+
workflow_name TEXT NOT NULL,
|
|
394
|
+
status TEXT NOT NULL CHECK(status IN (
|
|
395
|
+
'queued', 'running', 'paused', 'errored',
|
|
396
|
+
'terminated', 'complete', 'waiting',
|
|
397
|
+
'waitingForPause', 'unknown'
|
|
398
|
+
)),
|
|
399
|
+
metadata TEXT,
|
|
400
|
+
error_name TEXT,
|
|
401
|
+
error_message TEXT,
|
|
402
|
+
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
403
|
+
updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
404
|
+
completed_at INTEGER
|
|
405
|
+
)
|
|
406
|
+
`;
|
|
407
|
+
this.sql`
|
|
408
|
+
CREATE INDEX IF NOT EXISTS idx_workflows_status ON cf_agents_workflows(status)
|
|
409
|
+
`;
|
|
410
|
+
this.sql`
|
|
411
|
+
CREATE INDEX IF NOT EXISTS idx_workflows_name ON cf_agents_workflows(workflow_name)
|
|
412
|
+
`;
|
|
413
|
+
this.ctx.storage.sql.exec("DELETE FROM cf_agents_state WHERE id = ?", STATE_WAS_CHANGED);
|
|
414
|
+
this.sql`
|
|
415
|
+
INSERT OR REPLACE INTO cf_agents_state (id, state)
|
|
416
|
+
VALUES (${SCHEMA_VERSION_ROW_ID}, ${String(CURRENT_SCHEMA_VERSION)})
|
|
417
|
+
`;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
285
420
|
constructor(ctx, env) {
|
|
286
421
|
super(ctx, env);
|
|
287
422
|
this._state = DEFAULT_STATE;
|
|
@@ -289,6 +424,7 @@ var Agent = class Agent extends Server {
|
|
|
289
424
|
this._destroyed = false;
|
|
290
425
|
this._rawStateAccessors = /* @__PURE__ */ new WeakMap();
|
|
291
426
|
this._persistenceHookMode = "none";
|
|
427
|
+
this._isFacet = false;
|
|
292
428
|
this._ParentClass = Object.getPrototypeOf(this).constructor;
|
|
293
429
|
this.initialState = DEFAULT_STATE;
|
|
294
430
|
this.observability = genericObservability;
|
|
@@ -297,117 +433,7 @@ var Agent = class Agent extends Server {
|
|
|
297
433
|
this._autoWrapCustomMethods();
|
|
298
434
|
wrappedClasses.add(this.constructor);
|
|
299
435
|
}
|
|
300
|
-
this.
|
|
301
|
-
CREATE TABLE IF NOT EXISTS cf_agents_mcp_servers (
|
|
302
|
-
id TEXT PRIMARY KEY NOT NULL,
|
|
303
|
-
name TEXT NOT NULL,
|
|
304
|
-
server_url TEXT NOT NULL,
|
|
305
|
-
callback_url TEXT NOT NULL,
|
|
306
|
-
client_id TEXT,
|
|
307
|
-
auth_url TEXT,
|
|
308
|
-
server_options TEXT
|
|
309
|
-
)
|
|
310
|
-
`;
|
|
311
|
-
this.sql`
|
|
312
|
-
CREATE TABLE IF NOT EXISTS cf_agents_state (
|
|
313
|
-
id TEXT PRIMARY KEY NOT NULL,
|
|
314
|
-
state TEXT
|
|
315
|
-
)
|
|
316
|
-
`;
|
|
317
|
-
this.sql`
|
|
318
|
-
CREATE TABLE IF NOT EXISTS cf_agents_queues (
|
|
319
|
-
id TEXT PRIMARY KEY NOT NULL,
|
|
320
|
-
payload TEXT,
|
|
321
|
-
callback TEXT,
|
|
322
|
-
created_at INTEGER DEFAULT (unixepoch())
|
|
323
|
-
)
|
|
324
|
-
`;
|
|
325
|
-
this.sql`
|
|
326
|
-
CREATE TABLE IF NOT EXISTS cf_agents_schedules (
|
|
327
|
-
id TEXT PRIMARY KEY NOT NULL DEFAULT (randomblob(9)),
|
|
328
|
-
callback TEXT,
|
|
329
|
-
payload TEXT,
|
|
330
|
-
type TEXT NOT NULL CHECK(type IN ('scheduled', 'delayed', 'cron', 'interval')),
|
|
331
|
-
time INTEGER,
|
|
332
|
-
delayInSeconds INTEGER,
|
|
333
|
-
cron TEXT,
|
|
334
|
-
intervalSeconds INTEGER,
|
|
335
|
-
running INTEGER DEFAULT 0,
|
|
336
|
-
created_at INTEGER DEFAULT (unixepoch()),
|
|
337
|
-
execution_started_at INTEGER,
|
|
338
|
-
retry_options TEXT
|
|
339
|
-
)
|
|
340
|
-
`;
|
|
341
|
-
const addColumnIfNotExists = (sql) => {
|
|
342
|
-
try {
|
|
343
|
-
this.ctx.storage.sql.exec(sql);
|
|
344
|
-
} catch (e) {
|
|
345
|
-
if (!(e instanceof Error ? e.message : String(e)).toLowerCase().includes("duplicate column")) throw e;
|
|
346
|
-
}
|
|
347
|
-
};
|
|
348
|
-
addColumnIfNotExists("ALTER TABLE cf_agents_schedules ADD COLUMN intervalSeconds INTEGER");
|
|
349
|
-
addColumnIfNotExists("ALTER TABLE cf_agents_schedules ADD COLUMN running INTEGER DEFAULT 0");
|
|
350
|
-
addColumnIfNotExists("ALTER TABLE cf_agents_schedules ADD COLUMN execution_started_at INTEGER");
|
|
351
|
-
addColumnIfNotExists("ALTER TABLE cf_agents_schedules ADD COLUMN retry_options TEXT");
|
|
352
|
-
addColumnIfNotExists("ALTER TABLE cf_agents_queues ADD COLUMN retry_options TEXT");
|
|
353
|
-
{
|
|
354
|
-
const rows = this.ctx.storage.sql.exec("SELECT sql FROM sqlite_master WHERE type='table' AND name='cf_agents_schedules'").toArray();
|
|
355
|
-
if (rows.length > 0) {
|
|
356
|
-
if (!String(rows[0].sql).includes("'interval'")) {
|
|
357
|
-
this.ctx.storage.sql.exec("DROP TABLE IF EXISTS cf_agents_schedules_new");
|
|
358
|
-
this.ctx.storage.sql.exec(`
|
|
359
|
-
CREATE TABLE cf_agents_schedules_new (
|
|
360
|
-
id TEXT PRIMARY KEY NOT NULL DEFAULT (randomblob(9)),
|
|
361
|
-
callback TEXT,
|
|
362
|
-
payload TEXT,
|
|
363
|
-
type TEXT NOT NULL CHECK(type IN ('scheduled', 'delayed', 'cron', 'interval')),
|
|
364
|
-
time INTEGER,
|
|
365
|
-
delayInSeconds INTEGER,
|
|
366
|
-
cron TEXT,
|
|
367
|
-
intervalSeconds INTEGER,
|
|
368
|
-
running INTEGER DEFAULT 0,
|
|
369
|
-
created_at INTEGER DEFAULT (unixepoch()),
|
|
370
|
-
execution_started_at INTEGER,
|
|
371
|
-
retry_options TEXT
|
|
372
|
-
)
|
|
373
|
-
`);
|
|
374
|
-
this.ctx.storage.sql.exec(`
|
|
375
|
-
INSERT INTO cf_agents_schedules_new
|
|
376
|
-
(id, callback, payload, type, time, delayInSeconds, cron,
|
|
377
|
-
intervalSeconds, running, created_at, execution_started_at, retry_options)
|
|
378
|
-
SELECT id, callback, payload, type, time, delayInSeconds, cron,
|
|
379
|
-
intervalSeconds, running, created_at, execution_started_at, retry_options
|
|
380
|
-
FROM cf_agents_schedules
|
|
381
|
-
`);
|
|
382
|
-
this.ctx.storage.sql.exec("DROP TABLE cf_agents_schedules");
|
|
383
|
-
this.ctx.storage.sql.exec("ALTER TABLE cf_agents_schedules_new RENAME TO cf_agents_schedules");
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
this.sql`
|
|
388
|
-
CREATE TABLE IF NOT EXISTS cf_agents_workflows (
|
|
389
|
-
id TEXT PRIMARY KEY NOT NULL,
|
|
390
|
-
workflow_id TEXT NOT NULL UNIQUE,
|
|
391
|
-
workflow_name TEXT NOT NULL,
|
|
392
|
-
status TEXT NOT NULL CHECK(status IN (
|
|
393
|
-
'queued', 'running', 'paused', 'errored',
|
|
394
|
-
'terminated', 'complete', 'waiting',
|
|
395
|
-
'waitingForPause', 'unknown'
|
|
396
|
-
)),
|
|
397
|
-
metadata TEXT,
|
|
398
|
-
error_name TEXT,
|
|
399
|
-
error_message TEXT,
|
|
400
|
-
created_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
401
|
-
updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
|
402
|
-
completed_at INTEGER
|
|
403
|
-
)
|
|
404
|
-
`;
|
|
405
|
-
this.sql`
|
|
406
|
-
CREATE INDEX IF NOT EXISTS idx_workflows_status ON cf_agents_workflows(status)
|
|
407
|
-
`;
|
|
408
|
-
this.sql`
|
|
409
|
-
CREATE INDEX IF NOT EXISTS idx_workflows_name ON cf_agents_workflows(workflow_name)
|
|
410
|
-
`;
|
|
436
|
+
this._ensureSchema();
|
|
411
437
|
this.mcp = new MCPClientManager(this._ParentClass.name, "0.0.1", {
|
|
412
438
|
storage: this.ctx.storage,
|
|
413
439
|
createAuthProvider: (callbackUrl) => this.createMcpOAuthProvider(callbackUrl)
|
|
@@ -607,6 +633,7 @@ var Agent = class Agent extends Server {
|
|
|
607
633
|
request: void 0,
|
|
608
634
|
email: void 0
|
|
609
635
|
}, async () => {
|
|
636
|
+
if (await this.ctx.storage.get("cf_agents_is_facet")) this._isFacet = true;
|
|
610
637
|
await this._tryCatch(async () => {
|
|
611
638
|
await this.mcp.restoreConnectionsFromStorage(this.name);
|
|
612
639
|
await this._restoreRpcMcpServers();
|
|
@@ -657,10 +684,6 @@ var Agent = class Agent extends Server {
|
|
|
657
684
|
this.sql`
|
|
658
685
|
INSERT OR REPLACE INTO cf_agents_state (id, state)
|
|
659
686
|
VALUES (${STATE_ROW_ID}, ${JSON.stringify(nextState)})
|
|
660
|
-
`;
|
|
661
|
-
this.sql`
|
|
662
|
-
INSERT OR REPLACE INTO cf_agents_state (id, state)
|
|
663
|
-
VALUES (${STATE_WAS_CHANGED}, ${JSON.stringify(true)})
|
|
664
687
|
`;
|
|
665
688
|
this._broadcastProtocol(JSON.stringify({
|
|
666
689
|
state: nextState,
|
|
@@ -788,6 +811,44 @@ var Agent = class Agent extends Server {
|
|
|
788
811
|
return !!this._rawStateAccessors.get(connection).getRaw()?.[CF_READONLY_KEY];
|
|
789
812
|
}
|
|
790
813
|
/**
|
|
814
|
+
* ⚠️ INTERNAL — DO NOT USE IN APPLICATION CODE. ⚠️
|
|
815
|
+
*
|
|
816
|
+
* Read an internal `_cf_`-prefixed flag from the raw connection state,
|
|
817
|
+
* bypassing the user-facing state wrapper that strips internal keys.
|
|
818
|
+
*
|
|
819
|
+
* This exists for framework mixins (e.g. voice) that need to persist
|
|
820
|
+
* flags in the connection attachment across hibernation. Application
|
|
821
|
+
* code should use `connection.state` and `connection.setState()` instead.
|
|
822
|
+
*
|
|
823
|
+
* @internal
|
|
824
|
+
*/
|
|
825
|
+
_unsafe_getConnectionFlag(connection, key) {
|
|
826
|
+
this._ensureConnectionWrapped(connection);
|
|
827
|
+
return this._rawStateAccessors.get(connection).getRaw()?.[key];
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* ⚠️ INTERNAL — DO NOT USE IN APPLICATION CODE. ⚠️
|
|
831
|
+
*
|
|
832
|
+
* Write an internal `_cf_`-prefixed flag to the raw connection state,
|
|
833
|
+
* bypassing the user-facing state wrapper. The key must be registered
|
|
834
|
+
* in `CF_INTERNAL_KEYS` so it is preserved across user `setState` calls
|
|
835
|
+
* and hidden from `connection.state`.
|
|
836
|
+
*
|
|
837
|
+
* @internal
|
|
838
|
+
*/
|
|
839
|
+
_unsafe_setConnectionFlag(connection, key, value) {
|
|
840
|
+
this._ensureConnectionWrapped(connection);
|
|
841
|
+
const accessors = this._rawStateAccessors.get(connection);
|
|
842
|
+
const raw = accessors.getRaw() ?? {};
|
|
843
|
+
if (value === void 0) {
|
|
844
|
+
const { [key]: _, ...rest } = raw;
|
|
845
|
+
accessors.setRaw(Object.keys(rest).length > 0 ? rest : null);
|
|
846
|
+
} else accessors.setRaw({
|
|
847
|
+
...raw,
|
|
848
|
+
[key]: value
|
|
849
|
+
});
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
791
852
|
* Override this method to determine if a connection should be readonly on connect
|
|
792
853
|
* @param _connection The connection that is being established
|
|
793
854
|
* @param _ctx Connection context
|
|
@@ -1187,6 +1248,7 @@ var Agent = class Agent extends Server {
|
|
|
1187
1248
|
* @returns Schedule object representing the scheduled task
|
|
1188
1249
|
*/
|
|
1189
1250
|
async schedule(when, callback, payload, options) {
|
|
1251
|
+
if (this._isFacet) throw new Error("Scheduling is not supported in sub-agents. Schedule from the parent agent instead.");
|
|
1190
1252
|
const id = nanoid(9);
|
|
1191
1253
|
if (options?.retry) validateRetryOptions(options.retry, this._resolvedOptions.retry);
|
|
1192
1254
|
const retryJson = options?.retry ? JSON.stringify(options.retry) : null;
|
|
@@ -1283,6 +1345,7 @@ var Agent = class Agent extends Server {
|
|
|
1283
1345
|
* @returns Schedule object representing the scheduled task
|
|
1284
1346
|
*/
|
|
1285
1347
|
async scheduleEvery(intervalSeconds, callback, payload, options) {
|
|
1348
|
+
if (this._isFacet) throw new Error("Scheduling is not supported in sub-agents. Schedule from the parent agent instead.");
|
|
1286
1349
|
const MAX_INTERVAL_SECONDS = 720 * 60 * 60;
|
|
1287
1350
|
if (typeof intervalSeconds !== "number" || intervalSeconds <= 0) throw new Error("intervalSeconds must be a positive number");
|
|
1288
1351
|
if (intervalSeconds > MAX_INTERVAL_SECONDS) throw new Error(`intervalSeconds cannot exceed ${MAX_INTERVAL_SECONDS} seconds (30 days)`);
|
|
@@ -1390,6 +1453,7 @@ var Agent = class Agent extends Server {
|
|
|
1390
1453
|
* @returns true if the task was cancelled, false if the task was not found
|
|
1391
1454
|
*/
|
|
1392
1455
|
async cancelSchedule(id) {
|
|
1456
|
+
if (this._isFacet) throw new Error("Scheduling is not supported in sub-agents. Schedule from the parent agent instead.");
|
|
1393
1457
|
const schedule = this.getSchedule(id);
|
|
1394
1458
|
if (!schedule) return false;
|
|
1395
1459
|
this._emit("schedule:cancel", {
|
|
@@ -1421,6 +1485,7 @@ var Agent = class Agent extends Server {
|
|
|
1421
1485
|
* ```
|
|
1422
1486
|
*/
|
|
1423
1487
|
async keepAlive() {
|
|
1488
|
+
if (this._isFacet) throw new Error("keepAlive() is not supported in sub-agents. Use keepAlive() from the parent agent instead.");
|
|
1424
1489
|
const heartbeatSeconds = Math.ceil(KEEP_ALIVE_INTERVAL_MS / 1e3);
|
|
1425
1490
|
const schedule = await this.scheduleEvery(heartbeatSeconds, "_cf_keepAliveHeartbeat", void 0, { _idempotent: false });
|
|
1426
1491
|
let disposed = false;
|
|
@@ -1471,10 +1536,10 @@ var Agent = class Agent extends Server {
|
|
|
1471
1536
|
LIMIT 1
|
|
1472
1537
|
`;
|
|
1473
1538
|
if (!result) return;
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1539
|
+
let nextTimeMs = null;
|
|
1540
|
+
if (result.length > 0 && "time" in result[0]) nextTimeMs = result[0].time * 1e3;
|
|
1541
|
+
if (nextTimeMs !== null) await this.ctx.storage.setAlarm(nextTimeMs);
|
|
1542
|
+
else await this.ctx.storage.deleteAlarm();
|
|
1478
1543
|
}
|
|
1479
1544
|
/**
|
|
1480
1545
|
* Override PartyServer's onAlarm hook as a no-op.
|
|
@@ -1575,6 +1640,81 @@ var Agent = class Agent extends Server {
|
|
|
1575
1640
|
await this._scheduleNextAlarm();
|
|
1576
1641
|
}
|
|
1577
1642
|
/**
|
|
1643
|
+
* Marks this agent as running inside a facet (sub-agent). Once set,
|
|
1644
|
+
* scheduling methods throw a clear error instead of crashing on
|
|
1645
|
+
* `setAlarm()` (which is not supported in facets).
|
|
1646
|
+
* @internal
|
|
1647
|
+
*/
|
|
1648
|
+
async _cf_markAsFacet() {
|
|
1649
|
+
this._isFacet = true;
|
|
1650
|
+
await this.ctx.storage.put("cf_agents_is_facet", true);
|
|
1651
|
+
}
|
|
1652
|
+
/**
|
|
1653
|
+
* Get or create a named sub-agent — a child Durable Object (facet)
|
|
1654
|
+
* with its own isolated SQLite storage running on the same machine.
|
|
1655
|
+
*
|
|
1656
|
+
* The child class must extend `Agent` and be exported from the worker
|
|
1657
|
+
* entry point. The first call for a given name triggers the child's
|
|
1658
|
+
* `onStart()`. Subsequent calls return the existing instance.
|
|
1659
|
+
*
|
|
1660
|
+
* @experimental Requires the `"experimental"` compatibility flag.
|
|
1661
|
+
*
|
|
1662
|
+
* @param cls The Agent subclass (must be exported from the worker)
|
|
1663
|
+
* @param name Unique name for this child instance
|
|
1664
|
+
* @returns A typed RPC stub for calling methods on the child
|
|
1665
|
+
*
|
|
1666
|
+
* @example
|
|
1667
|
+
* ```typescript
|
|
1668
|
+
* const searcher = await this.subAgent(SearchAgent, "main-search");
|
|
1669
|
+
* const results = await searcher.search("cloudflare agents");
|
|
1670
|
+
* ```
|
|
1671
|
+
*/
|
|
1672
|
+
async subAgent(cls, name) {
|
|
1673
|
+
const ctx = this.ctx;
|
|
1674
|
+
if (!ctx.facets || !ctx.exports) throw new Error("subAgent() requires the \"experimental\" compatibility flag. Add it to your wrangler.jsonc compatibility_flags.");
|
|
1675
|
+
if (!ctx.exports[cls.name]) throw new Error(`Sub-agent class "${cls.name}" not found in worker exports. Make sure the class is exported from your worker entry point and that the export name matches the class name.`);
|
|
1676
|
+
const facetKey = `${cls.name}\0${name}`;
|
|
1677
|
+
const stub = ctx.facets.get(facetKey, () => ({ class: ctx.exports[cls.name] }));
|
|
1678
|
+
const req = new Request("http://dummy-example.cloudflare.com/cdn-cgi/partyserver/set-name/");
|
|
1679
|
+
req.headers.set("x-partykit-room", name);
|
|
1680
|
+
await stub.fetch(req).then((res) => res.text());
|
|
1681
|
+
await stub._cf_markAsFacet();
|
|
1682
|
+
return stub;
|
|
1683
|
+
}
|
|
1684
|
+
/**
|
|
1685
|
+
* Forcefully abort a running sub-agent. The child stops executing
|
|
1686
|
+
* immediately and will be restarted on next {@link subAgent} call.
|
|
1687
|
+
* Pending RPC calls receive the reason as an error.
|
|
1688
|
+
* Transitively aborts the child's own children.
|
|
1689
|
+
*
|
|
1690
|
+
* @experimental Requires the `"experimental"` compatibility flag.
|
|
1691
|
+
*
|
|
1692
|
+
* @param cls The Agent subclass used when creating the child
|
|
1693
|
+
* @param name Name of the child to abort
|
|
1694
|
+
* @param reason Error thrown to pending/future RPC callers
|
|
1695
|
+
*/
|
|
1696
|
+
abortSubAgent(cls, name, reason) {
|
|
1697
|
+
const ctx = this.ctx;
|
|
1698
|
+
if (!ctx.facets) throw new Error("abortSubAgent() requires the \"experimental\" compatibility flag.");
|
|
1699
|
+
const facetKey = `${cls.name}\0${name}`;
|
|
1700
|
+
ctx.facets.abort(facetKey, reason);
|
|
1701
|
+
}
|
|
1702
|
+
/**
|
|
1703
|
+
* Delete a sub-agent: abort it if running, then permanently wipe its
|
|
1704
|
+
* storage. Transitively deletes the child's own children.
|
|
1705
|
+
*
|
|
1706
|
+
* @experimental Requires the `"experimental"` compatibility flag.
|
|
1707
|
+
*
|
|
1708
|
+
* @param cls The Agent subclass used when creating the child
|
|
1709
|
+
* @param name Name of the child to delete
|
|
1710
|
+
*/
|
|
1711
|
+
deleteSubAgent(cls, name) {
|
|
1712
|
+
const ctx = this.ctx;
|
|
1713
|
+
if (!ctx.facets) throw new Error("deleteSubAgent() requires the \"experimental\" compatibility flag.");
|
|
1714
|
+
const facetKey = `${cls.name}\0${name}`;
|
|
1715
|
+
ctx.facets.delete(facetKey);
|
|
1716
|
+
}
|
|
1717
|
+
/**
|
|
1578
1718
|
* Destroy the Agent, removing all state and scheduled tasks
|
|
1579
1719
|
*/
|
|
1580
1720
|
async destroy() {
|
|
@@ -1583,7 +1723,7 @@ var Agent = class Agent extends Server {
|
|
|
1583
1723
|
this.sql`DROP TABLE IF EXISTS cf_agents_schedules`;
|
|
1584
1724
|
this.sql`DROP TABLE IF EXISTS cf_agents_queues`;
|
|
1585
1725
|
this.sql`DROP TABLE IF EXISTS cf_agents_workflows`;
|
|
1586
|
-
await this.ctx.storage.deleteAlarm();
|
|
1726
|
+
if (!this._isFacet) await this.ctx.storage.deleteAlarm();
|
|
1587
1727
|
await this.ctx.storage.deleteAll();
|
|
1588
1728
|
this._disposables.dispose();
|
|
1589
1729
|
await this.mcp.dispose();
|
|
@@ -2319,7 +2459,7 @@ var Agent = class Agent extends Server {
|
|
|
2319
2459
|
* @param workflowId - ID of the workflow
|
|
2320
2460
|
* @param progress - Typed progress data (default: DefaultProgress)
|
|
2321
2461
|
*/
|
|
2322
|
-
async onWorkflowProgress(
|
|
2462
|
+
async onWorkflowProgress(workflowName, workflowId, progress) {}
|
|
2323
2463
|
/**
|
|
2324
2464
|
* Called when a workflow completes successfully.
|
|
2325
2465
|
* Override to handle completion.
|
|
@@ -2328,7 +2468,7 @@ var Agent = class Agent extends Server {
|
|
|
2328
2468
|
* @param workflowId - ID of the workflow
|
|
2329
2469
|
* @param result - Optional result data
|
|
2330
2470
|
*/
|
|
2331
|
-
async onWorkflowComplete(
|
|
2471
|
+
async onWorkflowComplete(workflowName, workflowId, result) {}
|
|
2332
2472
|
/**
|
|
2333
2473
|
* Called when a workflow encounters an error.
|
|
2334
2474
|
* Override to handle errors.
|
|
@@ -2337,7 +2477,9 @@ var Agent = class Agent extends Server {
|
|
|
2337
2477
|
* @param workflowId - ID of the workflow
|
|
2338
2478
|
* @param error - Error message
|
|
2339
2479
|
*/
|
|
2340
|
-
async onWorkflowError(
|
|
2480
|
+
async onWorkflowError(workflowName, workflowId, error) {
|
|
2481
|
+
console.error(`Workflow error [${workflowName}/${workflowId}]: ${error}\nOverride onWorkflowError() in your Agent to handle workflow errors.`);
|
|
2482
|
+
}
|
|
2341
2483
|
/**
|
|
2342
2484
|
* Called when a workflow sends a custom event.
|
|
2343
2485
|
* Override to handle custom events.
|
|
@@ -2346,7 +2488,7 @@ var Agent = class Agent extends Server {
|
|
|
2346
2488
|
* @param workflowId - ID of the workflow
|
|
2347
2489
|
* @param event - Custom event payload
|
|
2348
2490
|
*/
|
|
2349
|
-
async onWorkflowEvent(
|
|
2491
|
+
async onWorkflowEvent(workflowName, workflowId, event) {}
|
|
2350
2492
|
/**
|
|
2351
2493
|
* Handle a workflow callback via RPC.
|
|
2352
2494
|
* @internal - Called by AgentWorkflow, do not call directly
|
|
@@ -2603,6 +2745,7 @@ var Agent = class Agent extends Server {
|
|
|
2603
2745
|
return Response.redirect(baseOrigin);
|
|
2604
2746
|
}
|
|
2605
2747
|
};
|
|
2748
|
+
Agent.options = { hibernate: true };
|
|
2606
2749
|
const wrappedClasses = /* @__PURE__ */ new Set();
|
|
2607
2750
|
/**
|
|
2608
2751
|
* Route a request to the appropriate Agent
|
|
@@ -2772,7 +2915,7 @@ var StreamingResponse = class {
|
|
|
2772
2915
|
return true;
|
|
2773
2916
|
}
|
|
2774
2917
|
};
|
|
2775
|
-
|
|
2776
2918
|
//#endregion
|
|
2777
2919
|
export { Agent, DEFAULT_AGENT_STATIC_OPTIONS, DurableObjectOAuthClientProvider, SqlError, StreamingResponse, __DO_NOT_USE_WILL_BREAK__agentContext, callable, createHeaderBasedEmailResolver, getAgentByName, getCurrentAgent, routeAgentEmail, routeAgentRequest, unstable_callable };
|
|
2920
|
+
|
|
2778
2921
|
//# sourceMappingURL=index.js.map
|