agents 0.15.0 → 0.16.0
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/{agent-tool-types-VPsjVYL0.d.ts → agent-tool-types-NofdbL9X.d.ts} +57 -4
- package/dist/agent-tool-types.d.ts +1 -1
- package/dist/{agent-tools-BGpgfpJT.d.ts → agent-tools-DLquv-dp.d.ts} +2 -2
- package/dist/agent-tools.d.ts +1 -1
- package/dist/browser/ai.d.ts +126 -7
- package/dist/browser/ai.js +73 -29
- package/dist/browser/ai.js.map +1 -1
- package/dist/browser/index.d.ts +81 -69
- package/dist/browser/index.js +3 -2
- package/dist/browser/tanstack-ai.d.ts +13 -7
- package/dist/browser/tanstack-ai.js +18 -19
- package/dist/browser/tanstack-ai.js.map +1 -1
- package/dist/chat/index.d.ts +111 -5
- package/dist/chat/index.js +207 -35
- package/dist/chat/index.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +1 -1
- package/dist/{classPrivateFieldGet2-Beqsfu2Z.js → classPrivateFieldGet2-CZ7QjTXN.js} +5 -5
- package/dist/{classPrivateMethodInitSpec-B5ko1s2R.js → classPrivateMethodInitSpec-D-0__zd9.js} +2 -2
- package/dist/client.d.ts +19 -2
- package/dist/client.js +31 -11
- package/dist/client.js.map +1 -1
- package/dist/{compaction-helpers-BEUILPss.d.ts → compaction-helpers-DVcu5lPN.d.ts} +91 -12
- package/dist/connector-D6yYzYHg.js +1080 -0
- package/dist/connector-D6yYzYHg.js.map +1 -0
- package/dist/connector-DXursxV5.d.ts +340 -0
- package/dist/experimental/memory/session/index.d.ts +75 -12
- package/dist/experimental/memory/session/index.js +226 -21
- package/dist/experimental/memory/session/index.js.map +1 -1
- package/dist/experimental/memory/utils/index.d.ts +2 -2
- package/dist/{index-CPe1OtI0.d.ts → index-B7IbEeze.d.ts} +32 -1
- package/dist/index.d.ts +8 -2
- package/dist/index.js +116 -45
- package/dist/index.js.map +1 -1
- package/dist/mcp/client.d.ts +1 -1
- package/dist/mcp/index.d.ts +1 -1
- package/dist/mcp/index.js +1 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/observability/index.d.ts +1 -1
- package/dist/react.d.ts +12 -1
- package/dist/react.js +101 -30
- package/dist/react.js.map +1 -1
- package/dist/{retries-CF_HKSlJ.d.ts → retries-CwlpAGet.d.ts} +35 -5
- package/dist/retries.d.ts +9 -5
- package/dist/retries.js +87 -1
- package/dist/retries.js.map +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/skills/index.js +2 -2
- package/dist/sub-routing.d.ts +1 -1
- package/dist/workflows.d.ts +1 -1
- package/package.json +10 -10
- package/dist/shared-4CAYLCTO.d.ts +0 -34
- package/dist/shared-wyII629d.js +0 -432
- package/dist/shared-wyII629d.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
P as SessionMessage,
|
|
3
3
|
a as alignBoundaryBackward,
|
|
4
4
|
c as computeSummaryBudget,
|
|
5
5
|
d as isCompactionMessage,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
s as buildSummaryPrompt,
|
|
13
13
|
t as COMPACTION_PREFIX,
|
|
14
14
|
u as findTailCutByTokens
|
|
15
|
-
} from "../../../compaction-helpers-
|
|
15
|
+
} from "../../../compaction-helpers-DVcu5lPN.js";
|
|
16
16
|
|
|
17
17
|
//#region src/experimental/memory/utils/tokens.d.ts
|
|
18
18
|
/** Approximate characters per token for English text */
|
|
@@ -408,6 +408,37 @@ type AgentObservabilityEvent =
|
|
|
408
408
|
toolCallIds?: string[];
|
|
409
409
|
}
|
|
410
410
|
>
|
|
411
|
+
| BaseEvent<
|
|
412
|
+
"chat:onstart:degraded",
|
|
413
|
+
{
|
|
414
|
+
/**
|
|
415
|
+
* Internal onStart step that failed and was skipped so the agent
|
|
416
|
+
* could still come up instead of bricking the DO (#1710).
|
|
417
|
+
*/
|
|
418
|
+
step:
|
|
419
|
+
| "transcript-hydration"
|
|
420
|
+
| "scheduled-task-reconcile"
|
|
421
|
+
| "durable-work-recovery";
|
|
422
|
+
error: string;
|
|
423
|
+
}
|
|
424
|
+
>
|
|
425
|
+
| BaseEvent<
|
|
426
|
+
"chat:hydration:windowed",
|
|
427
|
+
{
|
|
428
|
+
/** Stored size of the full active path, in bytes. */ totalContentBytes: number /** The configured `hydrationByteBudget`. */;
|
|
429
|
+
budgetBytes: number /** Number of recent messages hydrated into the in-memory window. */;
|
|
430
|
+
hydratedMessages: number;
|
|
431
|
+
}
|
|
432
|
+
>
|
|
433
|
+
| BaseEvent<
|
|
434
|
+
"chat:media:evicted",
|
|
435
|
+
{
|
|
436
|
+
/** Stored messages rewritten during this eviction pass. */ messages: number /** Individual oversized parts evicted across those messages. */;
|
|
437
|
+
parts: number /** Total bytes removed from the stored transcript. */;
|
|
438
|
+
bytes: number /** Bytes preserved as workspace files (≤ `bytes`). */;
|
|
439
|
+
externalizedBytes: number;
|
|
440
|
+
}
|
|
441
|
+
>
|
|
411
442
|
| BaseEvent<
|
|
412
443
|
"chat:stream:stalled",
|
|
413
444
|
{
|
|
@@ -730,4 +761,4 @@ export {
|
|
|
730
761
|
MCPObservabilityEvent as s,
|
|
731
762
|
ChannelEventMap as t
|
|
732
763
|
};
|
|
733
|
-
//# sourceMappingURL=index-
|
|
764
|
+
//# sourceMappingURL=index-B7IbEeze.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -71,9 +71,13 @@ import {
|
|
|
71
71
|
xt as normalizeServerId,
|
|
72
72
|
y as AddRpcMcpServerOptions,
|
|
73
73
|
z as MCPServer
|
|
74
|
-
} from "./agent-tool-types-
|
|
74
|
+
} from "./agent-tool-types-NofdbL9X.js";
|
|
75
75
|
import { n as camelCaseToKebabCase } from "./utils-CGtGDSgA.js";
|
|
76
|
-
import {
|
|
76
|
+
import {
|
|
77
|
+
i as isPlatformTransientError,
|
|
78
|
+
n as isDurableObjectCodeUpdateReset,
|
|
79
|
+
t as RetryOptions
|
|
80
|
+
} from "./retries-CwlpAGet.js";
|
|
77
81
|
import {
|
|
78
82
|
n as AgentsOAuthProvider,
|
|
79
83
|
r as DurableObjectOAuthClientProvider,
|
|
@@ -154,6 +158,8 @@ export {
|
|
|
154
158
|
getAgentByName,
|
|
155
159
|
getCurrentAgent,
|
|
156
160
|
getSubAgentByName,
|
|
161
|
+
isDurableObjectCodeUpdateReset,
|
|
162
|
+
isPlatformTransientError,
|
|
157
163
|
normalizeServerId,
|
|
158
164
|
parseSubAgentPath,
|
|
159
165
|
routeAgentEmail,
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,9 @@ import { __DO_NOT_USE_WILL_BREAK__agentContext } from "./internal_context.js";
|
|
|
2
2
|
import { MessageType } from "./types.js";
|
|
3
3
|
import { camelCaseToKebabCase, isInternalJsStubProp } from "./utils.js";
|
|
4
4
|
import { createHeaderBasedEmailResolver, signAgentHeaders } from "./email.js";
|
|
5
|
-
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-
|
|
5
|
+
import { i as _classPrivateFieldInitSpec, n as _classPrivateFieldSet2, t as _classPrivateFieldGet2 } from "./classPrivateFieldGet2-CZ7QjTXN.js";
|
|
6
6
|
import { SUB_PREFIX, getSubAgentByName, parseSubAgentPath, routeSubAgentRequest } from "./sub-routing.js";
|
|
7
|
-
import { isErrorRetryable, tryN, validateRetryOptions } from "./retries.js";
|
|
7
|
+
import { isDurableObjectCodeUpdateReset, isErrorRetryable, isPlatformTransientError, tryN, validateRetryOptions } from "./retries.js";
|
|
8
8
|
import { a as MCPConnectionState, c as RPC_DO_PREFIX, i as normalizeServerId, l as DisposableStore, n as MCP_SERVER_ID_MAX_LENGTH, t as MCPClientManager } from "./client-FUizKzj2.js";
|
|
9
9
|
import { DurableObjectOAuthClientProvider } from "./mcp/do-oauth-client-provider.js";
|
|
10
10
|
import { genericObservability } from "./observability/index.js";
|
|
@@ -16,6 +16,18 @@ import { RpcTarget, exports } from "cloudflare:workers";
|
|
|
16
16
|
import { Server, getServerByName, routePartykitRequest } from "partyserver";
|
|
17
17
|
//#region src/index.ts
|
|
18
18
|
let _Symbol$dispose;
|
|
19
|
+
function isClosedWebSocketSendError(error) {
|
|
20
|
+
return error instanceof TypeError && error.message.includes("WebSocket send() after close");
|
|
21
|
+
}
|
|
22
|
+
function sendRpcResponseIfOpen(connection, response) {
|
|
23
|
+
try {
|
|
24
|
+
connection.send(JSON.stringify(response));
|
|
25
|
+
return true;
|
|
26
|
+
} catch (error) {
|
|
27
|
+
if (isClosedWebSocketSendError(error)) return false;
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
19
31
|
/**
|
|
20
32
|
* Type guard for RPC request messages
|
|
21
33
|
*/
|
|
@@ -116,6 +128,10 @@ function getNextCronTime(cron) {
|
|
|
116
128
|
const DEFAULT_KEEP_ALIVE_INTERVAL_MS = 3e4;
|
|
117
129
|
const DEFAULT_AGENT_TOOL_RECOVERY_TIMEOUT_MS = 2e3;
|
|
118
130
|
const DEFAULT_AGENT_TOOL_RECOVERY_TOTAL_TIMEOUT_MS = 5e3;
|
|
131
|
+
const DESTROY_PENDING_KEY = "cf_agents_destroy_pending";
|
|
132
|
+
const DESTROY_ALARM_DELAY_MS = 1e3;
|
|
133
|
+
const FIBER_RECOVERY_MAX_BACKOFF_MS = 5 * 6e4;
|
|
134
|
+
const FIBER_RECOVERY_BACKOFF_MAX_EXP = 20;
|
|
119
135
|
const DEFAULT_AGENT_TOOL_REATTACH_NO_PROGRESS_TIMEOUT_MS = 12e4;
|
|
120
136
|
const DEFAULT_AGENT_TOOL_REATTACH_MAX_WINDOW_MS = Number.POSITIVE_INFINITY;
|
|
121
137
|
const SUB_AGENT_IDENTITY_VERSION_LEGACY = "legacy";
|
|
@@ -319,36 +335,6 @@ function resolveRetryConfig(taskRetry, defaults) {
|
|
|
319
335
|
maxDelayMs: taskRetry?.maxDelayMs ?? defaults.maxDelayMs
|
|
320
336
|
};
|
|
321
337
|
}
|
|
322
|
-
/**
|
|
323
|
-
* Whether an error is a transient "superseded isolate" failure — the invocation
|
|
324
|
-
* is running on an isolate the platform has replaced with a new version (a
|
|
325
|
-
* deploy / code update). For the rest of that invocation every operation throws
|
|
326
|
-
* the same error (code never reloads mid-invocation), so in-process retries are
|
|
327
|
-
* futile; but the next fresh invocation runs the new code and succeeds.
|
|
328
|
-
*
|
|
329
|
-
* workerd surfaces this as a plain `Error` with one of a few messages, all the
|
|
330
|
-
* same failure class — a message match is the only signal:
|
|
331
|
-
* - "Durable Object reset because its code was updated." (DO storage op on a
|
|
332
|
-
* superseded isolate / deploy bounce)
|
|
333
|
-
* - "This script has been upgraded. Please send a new request to connect to
|
|
334
|
-
* the new version." (a stub/connection to a superseded script; the message
|
|
335
|
-
* literally instructs the caller to retry on the new version)
|
|
336
|
-
*
|
|
337
|
-
* The match stays close to the verbatim platform strings (rather than a loose
|
|
338
|
-
* "upgraded"/"reset" substring) so an ordinary application error that happens
|
|
339
|
-
* to mention those words is NOT misclassified as a supersede — a false positive
|
|
340
|
-
* would defer + re-run a genuinely-failing callback on the platform's alarm
|
|
341
|
-
* retries instead of abandoning it.
|
|
342
|
-
*
|
|
343
|
-
* NOTE: "Network connection lost." is deliberately NOT included — it is a
|
|
344
|
-
* connection error, not an isolate replacement, and may succeed on in-process
|
|
345
|
-
* retry (it is gated by the CF `retryable` property via `isErrorRetryable`),
|
|
346
|
-
* so it stays on the normal retry path rather than the immediate-defer path.
|
|
347
|
-
*/
|
|
348
|
-
function isDurableObjectCodeUpdateReset(error) {
|
|
349
|
-
const message = error instanceof Error ? error.message : typeof error === "string" ? error : "";
|
|
350
|
-
return /reset because its code was updated|this script has been upgraded/i.test(message);
|
|
351
|
-
}
|
|
352
338
|
function getCurrentAgent() {
|
|
353
339
|
const store = __DO_NOT_USE_WILL_BREAK__agentContext.getStore();
|
|
354
340
|
if (!store) return {
|
|
@@ -720,6 +706,7 @@ var Agent = class Agent extends Server {
|
|
|
720
706
|
this._managedFiberExecutions = /* @__PURE__ */ new Map();
|
|
721
707
|
this._managedFiberTerminalWaiters = /* @__PURE__ */ new Map();
|
|
722
708
|
this._runFiberRecoveryInProgress = false;
|
|
709
|
+
this._recoveryNoProgressScans = 0;
|
|
723
710
|
this._ParentClass = Object.getPrototypeOf(this).constructor;
|
|
724
711
|
this.initialState = DEFAULT_STATE;
|
|
725
712
|
this.observability = genericObservability;
|
|
@@ -840,22 +827,20 @@ var Agent = class Agent extends Server {
|
|
|
840
827
|
method,
|
|
841
828
|
streaming: metadata?.streaming
|
|
842
829
|
});
|
|
843
|
-
|
|
830
|
+
sendRpcResponseIfOpen(connection, {
|
|
844
831
|
done: true,
|
|
845
832
|
id,
|
|
846
833
|
result,
|
|
847
834
|
success: true,
|
|
848
835
|
type: "rpc"
|
|
849
|
-
};
|
|
850
|
-
connection.send(JSON.stringify(response));
|
|
836
|
+
});
|
|
851
837
|
} catch (e) {
|
|
852
|
-
|
|
838
|
+
sendRpcResponseIfOpen(connection, {
|
|
853
839
|
error: e instanceof Error ? e.message : "Unknown error occurred",
|
|
854
840
|
id: parsed.id,
|
|
855
841
|
success: false,
|
|
856
842
|
type: "rpc"
|
|
857
|
-
};
|
|
858
|
-
connection.send(JSON.stringify(response));
|
|
843
|
+
});
|
|
859
844
|
console.error("RPC error:", e);
|
|
860
845
|
this._emit("rpc:error", {
|
|
861
846
|
method: parsed.method,
|
|
@@ -2324,6 +2309,9 @@ var Agent = class Agent extends Server {
|
|
|
2324
2309
|
if (disposed) return;
|
|
2325
2310
|
disposed = true;
|
|
2326
2311
|
this._keepAliveRefs = Math.max(0, this._keepAliveRefs - 1);
|
|
2312
|
+
if (this._keepAliveRefs === 0) this.ctx.waitUntil(this._scheduleNextAlarm().catch((e) => {
|
|
2313
|
+
console.error("[Agent] Failed to reschedule alarm after keepAlive dispose:", e);
|
|
2314
|
+
}));
|
|
2327
2315
|
};
|
|
2328
2316
|
}
|
|
2329
2317
|
/**
|
|
@@ -2925,6 +2913,7 @@ var Agent = class Agent extends Server {
|
|
|
2925
2913
|
const scanStartedAt = Date.now();
|
|
2926
2914
|
const scanDeadlineMs = this._resolvedOptions.fiberRecoveryScanDeadlineMs;
|
|
2927
2915
|
const fiberRecoveryMaxAgeMs = this._resolvedOptions.fiberRecoveryMaxAgeMs;
|
|
2916
|
+
let madeProgress = false;
|
|
2928
2917
|
try {
|
|
2929
2918
|
const rows = this.sql`SELECT id, name, snapshot, created_at FROM cf_agents_runs`;
|
|
2930
2919
|
for (const row of rows) {
|
|
@@ -2961,6 +2950,7 @@ var Agent = class Agent extends Server {
|
|
|
2961
2950
|
if (managedRow) {
|
|
2962
2951
|
if (this._isTerminalFiberStatus(managedRow.status)) {
|
|
2963
2952
|
this.sql`DELETE FROM cf_agents_runs WHERE id = ${row.id}`;
|
|
2953
|
+
madeProgress = true;
|
|
2964
2954
|
this._notifyManagedFiberTerminal(row.id);
|
|
2965
2955
|
continue;
|
|
2966
2956
|
}
|
|
@@ -2987,6 +2977,7 @@ var Agent = class Agent extends Server {
|
|
|
2987
2977
|
elapsedMs: Date.now() - row.created_at
|
|
2988
2978
|
});
|
|
2989
2979
|
this.sql`DELETE FROM cf_agents_runs WHERE id = ${row.id}`;
|
|
2980
|
+
madeProgress = true;
|
|
2990
2981
|
}
|
|
2991
2982
|
if (managedRow) this._notifyManagedFiberTerminal(row.id);
|
|
2992
2983
|
}
|
|
@@ -3042,10 +3033,13 @@ var Agent = class Agent extends Server {
|
|
|
3042
3033
|
elapsedMs: Date.now() - row.created_at
|
|
3043
3034
|
});
|
|
3044
3035
|
await this._runFiberRecoveryHook(ctx, row);
|
|
3036
|
+
madeProgress = true;
|
|
3045
3037
|
this._notifyManagedFiberTerminal(row.fiber_id);
|
|
3046
3038
|
}
|
|
3047
3039
|
} finally {
|
|
3048
3040
|
this._runFiberRecoveryInProgress = false;
|
|
3041
|
+
if (madeProgress) this._recoveryNoProgressScans = 0;
|
|
3042
|
+
else this._recoveryNoProgressScans = this._hasPendingFiberRecovery() ? this._recoveryNoProgressScans + 1 : 0;
|
|
3049
3043
|
}
|
|
3050
3044
|
}
|
|
3051
3045
|
/** @internal */
|
|
@@ -3201,6 +3195,7 @@ var Agent = class Agent extends Server {
|
|
|
3201
3195
|
}
|
|
3202
3196
|
const isOneShotSchedule = row.type === "delayed" || row.type === "scheduled";
|
|
3203
3197
|
const shouldDeferReset = (error) => isOneShotSchedule && isDurableObjectCodeUpdateReset(error);
|
|
3198
|
+
const shouldDeferOnExhaustion = (error) => isOneShotSchedule && isPlatformTransientError(error);
|
|
3204
3199
|
try {
|
|
3205
3200
|
this._emit("schedule:execute", {
|
|
3206
3201
|
callback: row.callback,
|
|
@@ -3224,6 +3219,10 @@ var Agent = class Agent extends Server {
|
|
|
3224
3219
|
console.warn(`Deferring scheduled callback "${row.callback}" to a fresh invocation after a Durable Object code-update reset; the one-shot row is preserved and the alarm will re-run on new code.`);
|
|
3225
3220
|
throw e;
|
|
3226
3221
|
}
|
|
3222
|
+
if (shouldDeferOnExhaustion(e)) {
|
|
3223
|
+
console.warn(`Deferring scheduled callback "${row.callback}" after exhausting in-process retries on a transient platform error; the one-shot row is preserved and the alarm will re-run once the platform recovers.`);
|
|
3224
|
+
throw e;
|
|
3225
|
+
}
|
|
3227
3226
|
console.error(`error executing callback "${row.callback}" after ${maxAttempts} attempts`, e);
|
|
3228
3227
|
this._emit("schedule:error", {
|
|
3229
3228
|
callback: row.callback,
|
|
@@ -3237,7 +3236,35 @@ var Agent = class Agent extends Server {
|
|
|
3237
3236
|
}
|
|
3238
3237
|
});
|
|
3239
3238
|
}
|
|
3239
|
+
/**
|
|
3240
|
+
* Whether any runFiber recovery work is still outstanding: orphaned
|
|
3241
|
+
* `cf_agents_runs` rows left by a dead process (excluding fibers currently
|
|
3242
|
+
* executing in memory, which already hold a keepAlive ref) or managed
|
|
3243
|
+
* ledger fibers stuck in a non-terminal state with no live run row.
|
|
3244
|
+
*
|
|
3245
|
+
* Used by `_scheduleNextAlarm` to arm a follow-up alarm so multi-pass
|
|
3246
|
+
* recovery (e.g. after a scan-deadline yield, or while retrying a throwing
|
|
3247
|
+
* recovery hook) resumes instead of starving.
|
|
3248
|
+
* @internal
|
|
3249
|
+
*/
|
|
3250
|
+
_hasPendingFiberRecovery() {
|
|
3251
|
+
const runRows = this.sql`
|
|
3252
|
+
SELECT id FROM cf_agents_runs
|
|
3253
|
+
`;
|
|
3254
|
+
for (const row of runRows) if (!this._runFiberActiveFibers.has(row.id)) return true;
|
|
3255
|
+
return (this.sql`
|
|
3256
|
+
SELECT COUNT(*) AS count
|
|
3257
|
+
FROM cf_agents_fibers f
|
|
3258
|
+
LEFT JOIN cf_agents_runs r ON r.id = f.fiber_id
|
|
3259
|
+
WHERE f.status IN ('pending', 'running')
|
|
3260
|
+
AND r.id IS NULL
|
|
3261
|
+
`[0]?.count ?? 0) > 0;
|
|
3262
|
+
}
|
|
3240
3263
|
async _scheduleNextAlarm() {
|
|
3264
|
+
if (await this._hasPendingDestroy()) {
|
|
3265
|
+
await this.ctx.storage.setAlarm(Date.now());
|
|
3266
|
+
return;
|
|
3267
|
+
}
|
|
3241
3268
|
const nowMs = Date.now();
|
|
3242
3269
|
const hungCutoffSeconds = Math.floor(nowMs / 1e3) - this._resolvedOptions.hungScheduleTimeoutSeconds;
|
|
3243
3270
|
const readySchedules = this.sql`
|
|
@@ -3266,6 +3293,12 @@ var Agent = class Agent extends Server {
|
|
|
3266
3293
|
const keepAliveMs = nowMs + this._resolvedOptions.keepAliveIntervalMs;
|
|
3267
3294
|
nextTimeMs = nextTimeMs === null ? keepAliveMs : Math.min(nextTimeMs, keepAliveMs);
|
|
3268
3295
|
}
|
|
3296
|
+
if (this._hasPendingFiberRecovery()) {
|
|
3297
|
+
const base = this._resolvedOptions.keepAliveIntervalMs;
|
|
3298
|
+
const exp = Math.min(this._recoveryNoProgressScans, FIBER_RECOVERY_BACKOFF_MAX_EXP);
|
|
3299
|
+
const recoveryMs = nowMs + Math.min(FIBER_RECOVERY_MAX_BACKOFF_MS, base * 2 ** exp);
|
|
3300
|
+
nextTimeMs = nextTimeMs === null ? recoveryMs : Math.min(nextTimeMs, recoveryMs);
|
|
3301
|
+
}
|
|
3269
3302
|
if ((this.sql`
|
|
3270
3303
|
SELECT COUNT(*) as count FROM cf_agents_facet_runs
|
|
3271
3304
|
`[0]?.count ?? 0) > 0) {
|
|
@@ -3297,6 +3330,10 @@ var Agent = class Agent extends Server {
|
|
|
3297
3330
|
* See {@link https://developers.cloudflare.com/agents/api-reference/schedule-tasks/}
|
|
3298
3331
|
*/
|
|
3299
3332
|
async alarm() {
|
|
3333
|
+
if (await this._hasPendingDestroy()) {
|
|
3334
|
+
await this.destroy();
|
|
3335
|
+
return;
|
|
3336
|
+
}
|
|
3300
3337
|
await super.alarm();
|
|
3301
3338
|
const now = Math.floor(Date.now() / 1e3);
|
|
3302
3339
|
const result = this.sql`
|
|
@@ -5167,6 +5204,7 @@ var Agent = class Agent extends Server {
|
|
|
5167
5204
|
await (await this._rootAlarmOwner())._cf_destroyDescendantFacet(this.selfPath);
|
|
5168
5205
|
return;
|
|
5169
5206
|
}
|
|
5207
|
+
await this.ctx.storage.put(DESTROY_PENDING_KEY, true);
|
|
5170
5208
|
this._dropInternalTablesForDestroy();
|
|
5171
5209
|
await this.ctx.storage.deleteAlarm();
|
|
5172
5210
|
await this.ctx.storage.deleteAll();
|
|
@@ -5178,6 +5216,42 @@ var Agent = class Agent extends Server {
|
|
|
5178
5216
|
}, 0);
|
|
5179
5217
|
this._emit("destroy");
|
|
5180
5218
|
}
|
|
5219
|
+
/**
|
|
5220
|
+
* @internal Defer this agent's destruction to its own alarm invocation
|
|
5221
|
+
* instead of running it inline (#1625).
|
|
5222
|
+
*
|
|
5223
|
+
* `destroy()` is a multi-step I/O sequence (drop tables, delete alarm,
|
|
5224
|
+
* delete all storage, dispose connections). Running it on the `waitUntil`
|
|
5225
|
+
* of a request whose client has already disconnected — the MCP
|
|
5226
|
+
* Streamable-HTTP session-DELETE path — gives it little to no
|
|
5227
|
+
* post-invocation grace, so the runtime routinely cancels it mid-flight.
|
|
5228
|
+
* This method instead performs two fast storage writes (a durable
|
|
5229
|
+
* "condemned" marker and an immediate alarm) that the caller can await
|
|
5230
|
+
* before responding; the alarm then fires as a fresh invocation with its
|
|
5231
|
+
* own full execution budget and runs `destroy()` there. If even that
|
|
5232
|
+
* invocation is interrupted, the marker survives and the next wake
|
|
5233
|
+
* finishes teardown — see the `alarm()` preamble.
|
|
5234
|
+
*
|
|
5235
|
+
* Unlike `destroy()`, this method does not abort the isolate, so RPC
|
|
5236
|
+
* callers don't need to swallow an abort error.
|
|
5237
|
+
*/
|
|
5238
|
+
async _cf_scheduleDestroy() {
|
|
5239
|
+
await this.__unsafe_ensureInitialized();
|
|
5240
|
+
if (this._isFacet) {
|
|
5241
|
+
await this.destroy();
|
|
5242
|
+
return;
|
|
5243
|
+
}
|
|
5244
|
+
await this.ctx.storage.put(DESTROY_PENDING_KEY, true);
|
|
5245
|
+
await this.ctx.storage.setAlarm(Date.now() + DESTROY_ALARM_DELAY_MS);
|
|
5246
|
+
}
|
|
5247
|
+
/**
|
|
5248
|
+
* Whether a (deferred or interrupted) destroy is pending. Reads the
|
|
5249
|
+
* durable marker directly — the in-memory `_isFacet` flag may not be
|
|
5250
|
+
* hydrated yet at the call sites, but facets never write the marker.
|
|
5251
|
+
*/
|
|
5252
|
+
async _hasPendingDestroy() {
|
|
5253
|
+
return await this.ctx.storage.get(DESTROY_PENDING_KEY) === true;
|
|
5254
|
+
}
|
|
5181
5255
|
/** @internal Drop every internal Agents SDK table during top-level destroy. */
|
|
5182
5256
|
_dropInternalTablesForDestroy() {
|
|
5183
5257
|
this.sql`DROP TABLE IF EXISTS cf_agents_mcp_servers`;
|
|
@@ -6334,8 +6408,7 @@ var StreamingResponse = class {
|
|
|
6334
6408
|
success: true,
|
|
6335
6409
|
type: "rpc"
|
|
6336
6410
|
};
|
|
6337
|
-
this._connection
|
|
6338
|
-
return true;
|
|
6411
|
+
return sendRpcResponseIfOpen(this._connection, response);
|
|
6339
6412
|
}
|
|
6340
6413
|
/**
|
|
6341
6414
|
* End the stream and send the final chunk (if any)
|
|
@@ -6352,8 +6425,7 @@ var StreamingResponse = class {
|
|
|
6352
6425
|
success: true,
|
|
6353
6426
|
type: "rpc"
|
|
6354
6427
|
};
|
|
6355
|
-
this._connection
|
|
6356
|
-
return true;
|
|
6428
|
+
return sendRpcResponseIfOpen(this._connection, response);
|
|
6357
6429
|
}
|
|
6358
6430
|
/**
|
|
6359
6431
|
* Send an error to the client and close the stream
|
|
@@ -6369,11 +6441,10 @@ var StreamingResponse = class {
|
|
|
6369
6441
|
success: false,
|
|
6370
6442
|
type: "rpc"
|
|
6371
6443
|
};
|
|
6372
|
-
this._connection
|
|
6373
|
-
return true;
|
|
6444
|
+
return sendRpcResponseIfOpen(this._connection, response);
|
|
6374
6445
|
}
|
|
6375
6446
|
};
|
|
6376
6447
|
//#endregion
|
|
6377
|
-
export { Agent, DEFAULT_AGENT_STATIC_OPTIONS, DurableObjectOAuthClientProvider, MCP_SERVER_ID_MAX_LENGTH, MessageType, SUB_PREFIX, SqlError, StreamingResponse, __DO_NOT_USE_WILL_BREAK__agentContext, callable, camelCaseToKebabCase, createHeaderBasedEmailResolver, getAgentByName, getCurrentAgent, getSubAgentByName, normalizeServerId, parseSubAgentPath, routeAgentEmail, routeAgentRequest, routeSubAgentRequest, unstable_callable };
|
|
6448
|
+
export { Agent, DEFAULT_AGENT_STATIC_OPTIONS, DurableObjectOAuthClientProvider, MCP_SERVER_ID_MAX_LENGTH, MessageType, SUB_PREFIX, SqlError, StreamingResponse, __DO_NOT_USE_WILL_BREAK__agentContext, callable, camelCaseToKebabCase, createHeaderBasedEmailResolver, getAgentByName, getCurrentAgent, getSubAgentByName, isDurableObjectCodeUpdateReset, isPlatformTransientError, normalizeServerId, parseSubAgentPath, routeAgentEmail, routeAgentRequest, routeSubAgentRequest, unstable_callable };
|
|
6378
6449
|
|
|
6379
6450
|
//# sourceMappingURL=index.js.map
|