agents 0.13.2 → 0.14.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.
Files changed (74) hide show
  1. package/README.md +6 -4
  2. package/dist/{agent-tool-types-Dn9n-3SI.d.ts → agent-tool-types-LInzZfLo.d.ts} +511 -124
  3. package/dist/agent-tool-types.d.ts +13 -11
  4. package/dist/{agent-tools-B1ttU-pq.d.ts → agent-tools-BE9xosUG.d.ts} +2 -2
  5. package/dist/agent-tools.d.ts +14 -20
  6. package/dist/agent-tools.js +10 -6
  7. package/dist/agent-tools.js.map +1 -1
  8. package/dist/browser/ai.d.ts +1 -1
  9. package/dist/browser/ai.js +1 -1
  10. package/dist/browser/index.d.ts +1 -1
  11. package/dist/browser/index.js +1 -1
  12. package/dist/browser/tanstack-ai.d.ts +1 -1
  13. package/dist/browser/tanstack-ai.js +1 -1
  14. package/dist/chat/index.d.ts +194 -22
  15. package/dist/chat/index.js +144 -11
  16. package/dist/chat/index.js.map +1 -1
  17. package/dist/chat-sdk/index.d.ts +4 -4
  18. package/dist/classPrivateMethodInitSpec-bG0tD96O.js +7 -0
  19. package/dist/{client-D1kFXo80.js → client-NradHZZz.js} +206 -75
  20. package/dist/client-NradHZZz.js.map +1 -0
  21. package/dist/client.d.ts +1 -1
  22. package/dist/{compaction-helpers-DvcZnvQ1.js → compaction-helpers-BjT2NKRZ.js} +37 -9
  23. package/dist/compaction-helpers-BjT2NKRZ.js.map +1 -0
  24. package/dist/{compaction-helpers-DAe-xiVY.d.ts → compaction-helpers-DpP_XP9J.d.ts} +86 -29
  25. package/dist/{do-oauth-client-provider-4OKQU9rT.d.ts → do-oauth-client-provider-CPm9rK5I.d.ts} +1 -1
  26. package/dist/{email-J0GGS3sa.d.ts → email-1fTSJwPm.d.ts} +1 -1
  27. package/dist/email.d.ts +2 -2
  28. package/dist/experimental/memory/session/index.d.ts +58 -23
  29. package/dist/experimental/memory/session/index.js +98 -9
  30. package/dist/experimental/memory/session/index.js.map +1 -1
  31. package/dist/experimental/memory/utils/index.d.ts +13 -11
  32. package/dist/experimental/memory/utils/index.js +2 -2
  33. package/dist/{index-DKey3P4s.d.ts → index-Brdu5nMI.d.ts} +270 -1
  34. package/dist/index.d.ts +74 -67
  35. package/dist/index.js +607 -97
  36. package/dist/index.js.map +1 -1
  37. package/dist/{internal_context-BZrMS0B5.d.ts → internal_context-CcZy2Em7.d.ts} +1 -1
  38. package/dist/internal_context.d.ts +1 -1
  39. package/dist/mcp/client.d.ts +17 -13
  40. package/dist/mcp/client.js +2 -2
  41. package/dist/mcp/do-oauth-client-provider.d.ts +1 -1
  42. package/dist/mcp/index.d.ts +35 -27
  43. package/dist/mcp/index.js +402 -69
  44. package/dist/mcp/index.js.map +1 -1
  45. package/dist/observability/index.d.ts +1 -1
  46. package/dist/observability/index.js +15 -1
  47. package/dist/observability/index.js.map +1 -1
  48. package/dist/react.d.ts +3 -3
  49. package/dist/{retries-BVdRl5ZE.d.ts → retries-ClWwxADl.d.ts} +1 -1
  50. package/dist/retries.d.ts +1 -1
  51. package/dist/serializable.d.ts +1 -1
  52. package/dist/{shared-Cvj92byG.d.ts → shared-CpY1FLvm.d.ts} +1 -1
  53. package/dist/{shared-CiKaIK4h.js → shared-DdOn6sp4.js} +3 -7
  54. package/dist/{shared-CiKaIK4h.js.map → shared-DdOn6sp4.js.map} +1 -1
  55. package/dist/skills/index.d.ts +236 -0
  56. package/dist/skills/index.js +1326 -0
  57. package/dist/skills/index.js.map +1 -0
  58. package/dist/sub-routing.d.ts +6 -6
  59. package/dist/{tool-output-truncation-CH-khbZ3.js → tool-output-truncation-BF4AZQlw.js} +1 -1
  60. package/dist/{tool-output-truncation-CH-khbZ3.js.map → tool-output-truncation-BF4AZQlw.js.map} +1 -1
  61. package/dist/{types-_JjKmv-l.d.ts → types-B0GymtN_.d.ts} +1 -1
  62. package/dist/types.d.ts +1 -1
  63. package/dist/vite.d.ts +1 -1
  64. package/dist/vite.js +248 -2
  65. package/dist/vite.js.map +1 -1
  66. package/dist/{workflow-types-Dkzg4hAx.d.ts → workflow-types-DPkuBi--.d.ts} +1 -1
  67. package/dist/workflow-types.d.ts +1 -1
  68. package/dist/workflows.d.ts +13 -3
  69. package/dist/workflows.js +10 -1
  70. package/dist/workflows.js.map +1 -1
  71. package/package.json +21 -3
  72. package/skills-module.d.ts +22 -0
  73. package/dist/client-D1kFXo80.js.map +0 -1
  74. package/dist/compaction-helpers-DvcZnvQ1.js.map +0 -1
@@ -1,11 +1,11 @@
1
- import { n as AgentEmail } from "./internal_context-BZrMS0B5.js";
2
- import { t as RetryOptions } from "./retries-BVdRl5ZE.js";
1
+ import { n as AgentEmail } from "./internal_context-CcZy2Em7.js";
2
+ import { t as RetryOptions } from "./retries-ClWwxADl.js";
3
3
  import {
4
4
  n as Observability,
5
5
  r as ObservabilityEvent,
6
6
  s as MCPObservabilityEvent
7
- } from "./index-DKey3P4s.js";
8
- import { t as AgentMcpOAuthProvider } from "./do-oauth-client-provider-4OKQU9rT.js";
7
+ } from "./index-Brdu5nMI.js";
8
+ import { t as AgentMcpOAuthProvider } from "./do-oauth-client-provider-CPm9rK5I.js";
9
9
  import {
10
10
  _ as WorkflowPage,
11
11
  g as WorkflowInfo,
@@ -13,9 +13,9 @@ import {
13
13
  l as WorkflowCallback,
14
14
  s as RunWorkflowOptions,
15
15
  y as WorkflowQueryCriteria
16
- } from "./workflow-types-Dkzg4hAx.js";
17
- import { t as MessageType } from "./types-_JjKmv-l.js";
18
- import { r as EmailResolver } from "./email-J0GGS3sa.js";
16
+ } from "./workflow-types-DPkuBi--.js";
17
+ import { t as MessageType } from "./types-B0GymtN_.js";
18
+ import { r as EmailResolver } from "./email-1fTSJwPm.js";
19
19
  import { ToolSet, UIMessage } from "ai";
20
20
  import { RpcTarget } from "cloudflare:workers";
21
21
  import {
@@ -67,7 +67,15 @@ import {
67
67
  } from "@modelcontextprotocol/sdk/shared/transport.js";
68
68
  import { Server as Server$1 } from "@modelcontextprotocol/sdk/server/index.js";
69
69
  import { Client as Client$1 } from "@modelcontextprotocol/sdk/client";
70
- import { EventStore } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
70
+ import {
71
+ EventId,
72
+ EventStore,
73
+ StreamId
74
+ } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
75
+ import {
76
+ EventStore as EventStore$1,
77
+ StreamId as StreamId$1
78
+ } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
71
79
 
72
80
  //#region src/sub-routing.d.ts
73
81
  /**
@@ -268,8 +276,30 @@ interface WorkerTransportOptions {
268
276
  */
269
277
  storage?: MCPStorageApi;
270
278
  /**
271
- * Event store for resumability support.
272
- * If provided, enables clients to reconnect and resume messages using Last-Event-ID.
279
+ * Event store for SSE resumability.
280
+ *
281
+ * When set, the transport assigns a globally-unique `id:` to each SSE
282
+ * event and replays missed events when a client reconnects with the
283
+ * `Last-Event-ID` header. Both GET (standalone listen stream) and POST
284
+ * (tool response stream) events are stored and replayable per the
285
+ * MCP 2025-03-26 spec.
286
+ *
287
+ * Configuring an event store **disables the server-side keepalive**
288
+ * on the standalone GET stream — idle drops are recovered by
289
+ * reconnect rather than prevented by writing bytes. Without an event
290
+ * store, the GET stream still gets the 25s comment-frame keepalive
291
+ * so long-lived idle listeners aren't closed by the Cloudflare edge
292
+ * ~5min watchdog.
293
+ *
294
+ * POST response streams always get the keepalive regardless of this
295
+ * setting: in-progress tool calls have no way to recover
296
+ * mid-execution without staying connected, so we don't let the
297
+ * stream drop in the first place.
298
+ *
299
+ * Bring your own {@link EventStore} implementation — e.g.
300
+ * `new DurableObjectEventStore(this.ctx.storage)` when embedding
301
+ * `WorkerTransport` inside a Durable Object / Agent. See
302
+ * cloudflare/agents#1583.
273
303
  */
274
304
  eventStore?: EventStore;
275
305
  /**
@@ -379,6 +409,94 @@ declare function experimental_createMcpHandler(
379
409
  options?: CreateMcpHandlerOptions
380
410
  ): (request: Request, env: unknown, ctx: ExecutionContext) => Promise<Response>;
381
411
  //#endregion
412
+ //#region src/mcp/event-store.d.ts
413
+ /**
414
+ * Durable Object–backed {@link EventStore} for SSE resumability.
415
+ *
416
+ * Default for `McpAgent`. Override `McpAgent.getEventStore()` to swap
417
+ * or disable.
418
+ *
419
+ * ## Storage layout
420
+ *
421
+ * Events are stored under `__mcp_event__:<streamId>:<seqHex>`, where
422
+ * `<seqHex>` is a 16-char zero-padded counter so events in a stream
423
+ * sort lexicographically and `getStreamIdForEventId` can recover the
424
+ * stream from `eventId` without a storage hit.
425
+ *
426
+ * ## Lifecycle
427
+ *
428
+ * Each POST tool-call stream's events live only until the final
429
+ * response is delivered. The transport calls {@link clearStream}
430
+ * immediately after writing the close frame, so storage growth is
431
+ * bounded by the in-flight POST streams plus the standalone GET
432
+ * stream. There is no background sweep — quiescent agents do no work,
433
+ * and the DO itself dies with the session.
434
+ *
435
+ * Standalone GET stream events (`_GET_stream`) are *not* cleared
436
+ * automatically; they accumulate for the lifetime of the DO. Bounded
437
+ * by session length in practice.
438
+ *
439
+ * Trade-off: if the client TCP connection dies *after* the close
440
+ * frame has been enqueued on the WS but before the bytes reach the
441
+ * client, the final message is unreplayable. Every earlier event in
442
+ * the stream is still replayable while the in-flight stream is open.
443
+ *
444
+ * ## Stream id constraints
445
+ *
446
+ * `streamId` MUST NOT contain `:`. `storeEvent` asserts this so
447
+ * embedders using custom stream ids fail loudly rather than risk
448
+ * prefix-scan collisions (e.g. clearing `a` accidentally hitting
449
+ * `a:b`). Default ids (`connection.id` UUIDs and the literal
450
+ * `_GET_stream`) already satisfy this.
451
+ */
452
+ declare class DurableObjectEventStore implements EventStore {
453
+ private static readonly EVENT_KEY_PREFIX;
454
+ private static readonly SEQ_PAD;
455
+ /** DO storage caps multi-key delete at 128. */
456
+ private static readonly DELETE_CHUNK;
457
+ /** Defensive ceiling on a single replay batch. A live stream's
458
+ * event count is small (progress notifications + final result);
459
+ * this is here so a pathological history can't OOM the DO. */
460
+ private static readonly REPLAY_LIMIT;
461
+ private readonly storage;
462
+ /** In-memory seq counters per stream, rehydrated lazily from storage. */
463
+ private readonly seqByStream;
464
+ private readonly seqInit;
465
+ constructor(storage: DurableObjectStorage);
466
+ storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId>;
467
+ getStreamIdForEventId(eventId: EventId): Promise<StreamId | undefined>;
468
+ replayEventsAfter(
469
+ lastEventId: EventId,
470
+ {
471
+ send
472
+ }: {
473
+ send: (eventId: EventId, message: JSONRPCMessage) => Promise<void>;
474
+ }
475
+ ): Promise<StreamId>;
476
+ /**
477
+ * Drop the event log for a single stream. Called by the transport
478
+ * immediately after a POST's final response has been written to the
479
+ * wire — no future `Last-Event-ID` for this stream is expected to
480
+ * resolve.
481
+ *
482
+ * Lists and deletes in chunks of {@link DELETE_CHUNK} (128, the DO
483
+ * storage cap) so we never load the entire event log into memory.
484
+ * After deleting, the next `list` call won't see the deleted keys,
485
+ * so passing `start: <prefix>` again is enough — no cursor bookkeeping.
486
+ */
487
+ clearStream(streamId: StreamId): Promise<void>;
488
+ private ensureSeqLoaded;
489
+ }
490
+ //#endregion
491
+ //#region src/mcp/transport.d.ts
492
+ /**
493
+ * An {@link EventStore} that supports dropping all events for a single
494
+ * stream id. Implemented by {@link DurableObjectEventStore}.
495
+ */
496
+ interface ClearableEventStore extends EventStore$1 {
497
+ clearStream(streamId: StreamId$1): Promise<void>;
498
+ }
499
+ //#endregion
382
500
  //#region src/mcp/index.d.ts
383
501
  declare abstract class McpAgent<
384
502
  Env extends Cloudflare.Env = Cloudflare.Env,
@@ -396,6 +514,45 @@ declare abstract class McpAgent<
396
514
  abstract init(): Promise<void>;
397
515
  setInitializeRequest(initializeRequest: JSONRPCMessage): Promise<void>;
398
516
  getInitializeRequest(): Promise<JSONRPCMessage | undefined>;
517
+ /**
518
+ * Storage key prefix for the `streamId -> requestIds` mapping used
519
+ * to support POST stream resumption across WebSocket reconnects.
520
+ *
521
+ * @internal
522
+ */
523
+ private static readonly STREAM_REQS_KEY_PREFIX;
524
+ /** Persist the `requestIds` for a POST stream. @internal */
525
+ setStreamRequestIds(streamId: string, requestIds: RequestId[]): Promise<void>;
526
+ /** Read the persisted `requestIds` for a POST stream. @internal */
527
+ getStreamRequestIds(streamId: string): Promise<RequestId[] | undefined>;
528
+ /** Drop the persisted `requestIds` for a POST stream. @internal */
529
+ deleteStreamRequestIds(streamId: string): Promise<void>;
530
+ /**
531
+ * Reverse lookup: find which POST stream a given `requestId` belongs
532
+ * to, and return the stream's full `requestIds` list in the same
533
+ * pass. Used by the transport when the originating WS has dropped,
534
+ * so `send()` can still record events for replay and decide whether
535
+ * the stream is fully responded — mirrors the SDK's
536
+ * `_requestToStreamMapping` which outlives connection loss.
537
+ *
538
+ * Returning `requestIds` alongside `streamId` lets `send()` skip a
539
+ * second `getStreamRequestIds` read on the same key.
540
+ *
541
+ * O(n) in the number of in-flight POST streams — single-digit in
542
+ * practice since each stream is cleaned up on its final response.
543
+ * The `limit` is a defensive ceiling so an abandoned-POST leak can't
544
+ * unbounded-load this scan; if you hit it, something else has gone
545
+ * wrong and `send()` will throw `No active stream found`.
546
+ *
547
+ * @internal
548
+ */
549
+ getStreamForRequestId(requestId: RequestId): Promise<
550
+ | {
551
+ streamId: string;
552
+ requestIds: RequestId[];
553
+ }
554
+ | undefined
555
+ >;
399
556
  /** Read the transport type for this agent.
400
557
  * This relies on the naming scheme being `sse:${sessionId}`,
401
558
  * `streamable-http:${sessionId}`, or `rpc:${sessionId}`.
@@ -422,6 +579,21 @@ declare abstract class McpAgent<
422
579
  * ```
423
580
  */
424
581
  protected getRpcTransportOptions(): RPCServerTransportOptions;
582
+ /**
583
+ * Returns the {@link EventStore} for SSE resumability. Defaults to a
584
+ * {@link DurableObjectEventStore} backed by this agent's storage,
585
+ * letting clients reconnect with `Last-Event-ID` after the Cloudflare
586
+ * edge closes an idle SSE stream (~5 minute watchdog) instead of
587
+ * relying on a server-side keepalive that would block hibernation.
588
+ *
589
+ * Per-stream events are cleared by the transport immediately after
590
+ * the final response is written to the wire, so there's no
591
+ * background cleanup — storage cost is bounded by the in-flight
592
+ * streams alone.
593
+ *
594
+ * Override to disable (`return undefined`) or swap implementations.
595
+ */
596
+ protected getEventStore(): EventStore | undefined;
425
597
  /** Returns a new transport matching the type of the Agent. */
426
598
  private initTransport;
427
599
  /** Update and store the props */
@@ -535,10 +707,10 @@ interface RPCServerTransportOptions {
535
707
  }
536
708
  declare class RPCServerTransport implements Transport {
537
709
  private _started;
538
- private _pendingResponse;
539
- private _responseResolver;
540
710
  private _protocolVersion?;
541
711
  private _timeout;
712
+ private _pendingRequests;
713
+ private _pendingContinuations;
542
714
  sessionId?: string;
543
715
  onclose?: () => void;
544
716
  onerror?: (error: Error) => void;
@@ -548,17 +720,25 @@ declare class RPCServerTransport implements Transport {
548
720
  getProtocolVersion(): string | undefined;
549
721
  start(): Promise<void>;
550
722
  close(): Promise<void>;
551
- send(message: JSONRPCMessage, _options?: TransportSendOptions): Promise<void>;
723
+ private _makeTimeout;
724
+ private _appendPending;
725
+ private _completePending;
726
+ private _completeRequest;
727
+ private _appendRequest;
728
+ private _completeContinuation;
729
+ private _appendContinuation;
730
+ send(message: JSONRPCMessage, options?: TransportSendOptions): Promise<void>;
552
731
  /**
553
732
  * @internal Called by McpAgent.handleMcpMessage() — not for external use.
554
733
  *
555
- * Wait for the next send() call and return whatever it produces.
734
+ * Wait for the next unmatched send() call that expects a client response or
735
+ * completes a resumed tool call.
556
736
  *
557
- * Used after resolving an elicitation response: the tool handler is still
558
- * running and will eventually call send() with either another elicitation
559
- * request or the final tool result. This method captures that send() using
560
- * the same _responseResolver / _pendingResponse / timeout mechanism as
561
- * handle().
737
+ * Used after resolving an elicitation response: the original tool call has
738
+ * already returned the elicitation request to the RPC client, and the resumed
739
+ * tool handler will eventually send the final tool result. That final response
740
+ * has the original tool request id, so there is no active handle() waiter left
741
+ * for id-based routing; this continuation waiter receives it instead.
562
742
  */
563
743
  _awaitPendingResponse(): Promise<
564
744
  JSONRPCMessage | JSONRPCMessage[] | undefined
@@ -872,6 +1052,31 @@ type MCPServerRow = {
872
1052
  };
873
1053
  //#endregion
874
1054
  //#region src/mcp/client.d.ts
1055
+ /** Maximum length of a normalized MCP server id. */
1056
+ declare const MCP_SERVER_ID_MAX_LENGTH = 64;
1057
+ /**
1058
+ * Normalize a caller-supplied MCP server id into a stable, storage- and
1059
+ * tool-name-safe form.
1060
+ *
1061
+ * The id is surfaced in several places where the character set matters:
1062
+ * - as the primary key in the `cf_agents_mcp_servers` SQLite table
1063
+ * - embedded in AI SDK tool names as `` `tool_${id.replace(/-/g, "")}_${tool}` ``
1064
+ * (tool names must match `/^[A-Za-z0-9_]+$/`)
1065
+ * - as a key on the `mcpConnections` map and OAuth provider storage
1066
+ *
1067
+ * Rules:
1068
+ * 1. Lowercase.
1069
+ * 2. Replace any run of disallowed characters with a single `-`.
1070
+ * 3. Collapse repeated `-` and trim leading/trailing `-`/`_`.
1071
+ * 4. Prefix with `id-` if the result is empty or doesn't start with a letter.
1072
+ * 5. Truncate to {@link MCP_SERVER_ID_MAX_LENGTH} characters.
1073
+ *
1074
+ * @example
1075
+ * normalizeServerId("my-supplied-id"); // "my-supplied-id"
1076
+ * normalizeServerId("GitHub MCP!"); // "github-mcp"
1077
+ * normalizeServerId("42-things"); // "id-42-things"
1078
+ */
1079
+ declare function normalizeServerId(input: string): string;
875
1080
  /**
876
1081
  * Options that can be stored in the server_options column
877
1082
  * This is what gets JSON.stringify'd and stored in the database
@@ -1009,6 +1214,31 @@ declare class MCPClientManager {
1009
1214
  private sql;
1010
1215
  private saveServerToStorage;
1011
1216
  private removeServerFromStorage;
1217
+ /**
1218
+ * Rename a server's id, in-place, across every place the id is used as a
1219
+ * key. Used to JIT-migrate servers that were originally registered under an
1220
+ * auto-generated nanoid to a caller-supplied stable id (see
1221
+ * `Agent.addMcpServer`'s `{ id }` option).
1222
+ *
1223
+ * Migrates:
1224
+ * - the `cf_agents_mcp_servers` row (primary key)
1225
+ * - the in-memory `mcpConnections` map key
1226
+ * - the connection disposables map key
1227
+ * - the attached `authProvider.serverId`, if any
1228
+ * - OAuth-related storage keys under `/{clientName}/{oldId}/...`
1229
+ *
1230
+ * Safe to call when no OAuth keys exist (RPC / bearer-token HTTP servers).
1231
+ * If `oldId === newId` this is a no-op. If a row already exists under
1232
+ * `newId`, throws — the caller is expected to have verified uniqueness.
1233
+ *
1234
+ * @internal Exposed for `Agent.addMcpServer` JIT-migration.
1235
+ */
1236
+ migrateServerId(
1237
+ oldId: string,
1238
+ newId: string,
1239
+ clientName: string
1240
+ ): Promise<void>;
1241
+ private _renameInMemoryConnection;
1012
1242
  private getServersFromStorage;
1013
1243
  private filterConnections;
1014
1244
  /**
@@ -1909,9 +2139,26 @@ type FiberRecoveryContext = {
1909
2139
  * Epoch milliseconds when the fiber row was inserted (when `runFiber`
1910
2140
  * started). Use `Date.now() - createdAt` to gate stale recoveries.
1911
2141
  */
1912
- createdAt: number;
2142
+ createdAt: number /** Why this recovery hook is running. */;
2143
+ recoveryReason: "interrupted";
1913
2144
  [key: string]: unknown;
1914
2145
  };
2146
+ type InternalFiberOptions = {
2147
+ signal?: AbortSignal;
2148
+ managed?: boolean;
2149
+ initialSnapshot?: unknown;
2150
+ wrapStash?: (data: unknown) => unknown;
2151
+ beforeRunCleanup?: (
2152
+ outcome:
2153
+ | {
2154
+ ok: true;
2155
+ }
2156
+ | {
2157
+ ok: false;
2158
+ error: unknown;
2159
+ }
2160
+ ) => void;
2161
+ };
1915
2162
  /**
1916
2163
  * MCP Server state update message from server -> Client
1917
2164
  */
@@ -1946,7 +2193,18 @@ type MCPServer = {
1946
2193
  * Options for adding an MCP server
1947
2194
  */
1948
2195
  type AddMcpServerOptions = {
1949
- /** OAuth callback host (auto-derived from request if omitted) */ callbackHost?: string;
2196
+ /**
2197
+ * Optional caller-supplied stable server id. When provided, this id is used
2198
+ * for storage, restore, and tool-name namespacing instead of a generated
2199
+ * `nanoid`. The value is normalized via {@link normalizeServerId} — for
2200
+ * connector-style integrations this lets `addMcpServer` keep producing
2201
+ * keys like `tool_github_create_pull_request`.
2202
+ *
2203
+ * Throws if an existing server already uses the same (normalized) id but a
2204
+ * different name or url.
2205
+ */
2206
+ id?: string /** OAuth callback host (auto-derived from request if omitted) */;
2207
+ callbackHost?: string;
1950
2208
  /**
1951
2209
  * Custom callback URL path — bypasses the default `/agents/{class}/{name}/callback` construction.
1952
2210
  * Required when `sendIdentityOnConnect` is `false` to prevent leaking the instance name.
@@ -1967,7 +2225,16 @@ type AddMcpServerOptions = {
1967
2225
  * Options for adding an MCP server via RPC (Durable Object binding)
1968
2226
  */
1969
2227
  type AddRpcMcpServerOptions = {
1970
- /** Props to pass to the McpAgent instance */ props?: Record<string, unknown>;
2228
+ /**
2229
+ * Optional caller-supplied stable server id. When provided, this id is used
2230
+ * for storage, restore, and tool-name namespacing instead of a generated
2231
+ * `nanoid`. The value is normalized via {@link normalizeServerId}.
2232
+ *
2233
+ * Throws if an existing server already uses the same (normalized) id but a
2234
+ * different name or url.
2235
+ */
2236
+ id?: string /** Props to pass to the McpAgent instance */;
2237
+ props?: Record<string, unknown>;
1971
2238
  };
1972
2239
  /**
1973
2240
  * Default options for Agent configuration.
@@ -1991,7 +2258,15 @@ declare const DEFAULT_AGENT_STATIC_OPTIONS: {
1991
2258
  maxAttempts: number;
1992
2259
  baseDelayMs: number;
1993
2260
  maxDelayMs: number;
1994
- };
2261
+ } /** Timeout for internal framework fiber recovery hooks. */;
2262
+ fiberRecoveryHookTimeoutMs: number /** Soft deadline for one interrupted-fiber recovery scan. */;
2263
+ fiberRecoveryScanDeadlineMs: number;
2264
+ /**
2265
+ * Maximum age of an unmanaged interrupted-fiber row before recovery gives
2266
+ * up. Bounds repeated retries of a `onFiberRecovered()` hook that keeps
2267
+ * throwing so a poison row cannot re-trigger forever across boots.
2268
+ */
2269
+ fiberRecoveryMaxAgeMs: number;
1995
2270
  };
1996
2271
  /**
1997
2272
  * Configuration options for the Agent.
@@ -2011,6 +2286,19 @@ interface AgentStaticOptions {
2011
2286
  keepAliveIntervalMs?: number;
2012
2287
  /** Default retry options for schedule(), queue(), and this.retry(). */
2013
2288
  retry?: RetryOptions;
2289
+ /**
2290
+ * Timeout in milliseconds for internal framework fiber recovery hooks.
2291
+ * User-defined `onFiberRecovered()` hooks are not timed out by default.
2292
+ */
2293
+ fiberRecoveryHookTimeoutMs?: number;
2294
+ /** Soft deadline in milliseconds for one interrupted-fiber recovery scan. */
2295
+ fiberRecoveryScanDeadlineMs?: number;
2296
+ /**
2297
+ * Maximum age in milliseconds of an unmanaged interrupted-fiber row before
2298
+ * recovery stops retrying a repeatedly-throwing `onFiberRecovered()` hook
2299
+ * and discards the row. Set to `0` to retain rows indefinitely.
2300
+ */
2301
+ fiberRecoveryMaxAgeMs?: number;
2014
2302
  }
2015
2303
  declare function getCurrentAgent<
2016
2304
  T extends Agent<Cloudflare.Env> = Agent<Cloudflare.Env>
@@ -2071,6 +2359,13 @@ declare class Agent<
2071
2359
  private _protocolBroadcastExcludeIds;
2072
2360
  private _cf_currentSubAgentBridge?;
2073
2361
  private _cf_virtualSubAgentConnections;
2362
+ /**
2363
+ * User-facing facet name. For legacy facets this is the same as
2364
+ * `ctx.id.name`; path-scoped facets use an internal routing id and
2365
+ * keep the logical name here instead.
2366
+ * @internal
2367
+ */
2368
+ private _facetName?;
2074
2369
  /**
2075
2370
  * Ancestor chain, root-first. Empty for top-level DOs; populated at
2076
2371
  * facet init time from the parent's own `selfPath`. Exposed publicly
@@ -2107,6 +2402,8 @@ declare class Agent<
2107
2402
  private _managedFiberTerminalWaiters;
2108
2403
  /** @internal Prevents re-entrant recovery from overlapping alarm ticks. */
2109
2404
  private _runFiberRecoveryInProgress;
2405
+ /** @internal Single-flight background recovery for parent agent-tool rows. */
2406
+ private _agentToolRunRecoveryPromise;
2110
2407
  private _ParentClass;
2111
2408
  readonly mcp: MCPClientManager;
2112
2409
  /**
@@ -2483,6 +2780,7 @@ declare class Agent<
2483
2780
  private _facetRunRowsForPrefix;
2484
2781
  private _deleteFacetRunRowsForPrefix;
2485
2782
  private _rootAlarmOwner;
2783
+ private _cf_rootResolvesToSelf;
2486
2784
  private _validateScheduleCallback;
2487
2785
  /**
2488
2786
  * Insert (or, for idempotent calls, return the existing row for) a
@@ -2799,6 +3097,9 @@ declare class Agent<
2799
3097
  private _applyManagedFiberRecoveryResult;
2800
3098
  private _settleManagedFiberExecution;
2801
3099
  private _parseFiberRecoverySnapshot;
3100
+ private _fiberRecoveryPayload;
3101
+ private _withFiberRecoveryTimeout;
3102
+ private _recordFiberRecoveryFailure;
2802
3103
  private _runFiberRecoveryHook;
2803
3104
  private _fiberInspectionFromRow;
2804
3105
  private _waitForManagedFiber;
@@ -2828,6 +3129,20 @@ declare class Agent<
2828
3129
  * @returns The return value of fn
2829
3130
  */
2830
3131
  runFiber<T>(name: string, fn: (ctx: FiberContext) => Promise<T>): Promise<T>;
3132
+ /**
3133
+ * Internal framework entry point for fibers that need to compose their own
3134
+ * recovery metadata with user checkpoint data while preserving the public
3135
+ * `this.stash()` behavior.
3136
+ *
3137
+ * This deliberately stays protected/internal rather than becoming a public
3138
+ * `runFiber()` option until the durable execution API needs this generality.
3139
+ * @internal
3140
+ */
3141
+ protected _runFiberWithStashWrapper<T>(
3142
+ name: string,
3143
+ fn: (ctx: FiberContext) => Promise<T>,
3144
+ options: Pick<InternalFiberOptions, "initialSnapshot" | "wrapStash">
3145
+ ): Promise<T>;
2831
3146
  startFiber(
2832
3147
  name: string,
2833
3148
  fn: (ctx: FiberContext) => Promise<void>,
@@ -3128,13 +3443,9 @@ declare class Agent<
3128
3443
  * broadcast to their own WebSocket clients reached via sub-agent
3129
3444
  * routing.
3130
3445
  *
3131
- * The facet's name (and `this.name` getter) is handled entirely by
3132
- * partyserver via `ctx.id.name`, which is populated because the
3133
- * parent passed an explicit named Durable Object id to
3134
- * `ctx.facets.get()` — see {@link _cf_resolveSubAgent}. No
3135
- * `setName()` call or `__ps_name` storage write is needed; the
3136
- * facet's name survives cold wake automatically because the factory
3137
- * re-runs and `idFromName` is deterministic.
3446
+ * The facet's logical name is persisted separately from its routing id.
3447
+ * Legacy facets used the logical name directly as `ctx.id.name`; newer
3448
+ * facets can use path-scoped routing ids while preserving `this.name`.
3138
3449
  *
3139
3450
  * @internal Called by {@link subAgent}.
3140
3451
  */
@@ -3143,8 +3454,10 @@ declare class Agent<
3143
3454
  parentPath?: ReadonlyArray<{
3144
3455
  className: string;
3145
3456
  name: string;
3146
- }>
3457
+ }>,
3458
+ identityName?: string
3147
3459
  ): Promise<void>;
3460
+ get name(): string;
3148
3461
  /**
3149
3462
  * Ancestor chain for this agent, root-first. Empty for top-level
3150
3463
  * DOs. Populated at facet init time; survives hibernation.
@@ -3290,13 +3603,58 @@ declare class Agent<
3290
3603
  private _broadcastAgentToolEvent;
3291
3604
  private _broadcastAgentToolChunks;
3292
3605
  private _broadcastAgentToolStoredChunks;
3606
+ private _broadcastAgentToolStoredChunksFromAdapter;
3293
3607
  private _forwardAgentToolStream;
3608
+ /**
3609
+ * Hook invoked by `_forwardAgentToolStream` after a child produces output that
3610
+ * was forwarded to the parent's connections. Forwarding a sub-agent's stream
3611
+ * is genuine forward progress for the *parent* turn (the parent is
3612
+ * orchestrating the child), so chat-recovery subclasses (Think / AIChatAgent)
3613
+ * override this to advance their recovery progress marker.
3614
+ *
3615
+ * Without it, a parent whose turn merely `await`s a sub-agent banks zero
3616
+ * progress of its own, so under deploy churn the parent's no-progress recovery
3617
+ * window exhausts and abandons the turn as `interrupted` — even though the
3618
+ * child is healthily streaming and ultimately completes (observed in the
3619
+ * `deploy-churn --mode subagent` harness: `attempt 6/6, stable_timeout,
3620
+ * progress: 1`).
3621
+ *
3622
+ * Called ONLY after at least one chunk was actually forwarded — never merely
3623
+ * because a child is attached — so a silent / hung child still lets the parent
3624
+ * exhaust on its own timer. The base Agent has no recovery budget, so this is
3625
+ * a no-op; subclasses should throttle the (durable) bump since this can be
3626
+ * called repeatedly while a child streams.
3627
+ */
3628
+ protected _onAgentToolStreamProgress(): Promise<void>;
3294
3629
  private _broadcastAgentToolTerminal;
3295
3630
  private _asAgentToolChildAdapter;
3296
3631
  private _agentToolClassByName;
3297
3632
  private _replayAndInterruptAgentToolRun;
3633
+ /**
3634
+ * Re-attach to a still-running child agent-tool run and tail it to its real
3635
+ * terminal result, instead of abandoning it as `interrupted` (#1630). The
3636
+ * child is a separate facet with its own `chatRecovery`, so resolving it via
3637
+ * the adapter wakes it and lets it self-complete the interrupted turn; we tail
3638
+ * its live stream (forwarding chunks to the parent's connections) until it
3639
+ * reaches terminal, then inspect for the collected result.
3640
+ *
3641
+ * Bounded by {@link DEFAULT_AGENT_TOOL_REATTACH_TIMEOUT_MS}: a child that keeps
3642
+ * advancing toward terminal within the window is collected; a genuinely hung
3643
+ * child returns `{ result: undefined }` once the budget elapses so the caller
3644
+ * falls back to `interrupted` and recovery can never block forever.
3645
+ *
3646
+ * Returns the terminal `result` (and `completedAt`) when the child reaches a
3647
+ * terminal status within the budget, plus the advanced broadcast `sequence`.
3648
+ * Returns `{ result: undefined }` when there is no `tailAgentToolRun` adapter,
3649
+ * the budget is exhausted, or the child is still non-terminal.
3650
+ */
3651
+ private _reattachAgentToolRunToTerminal;
3298
3652
  private _replayAgentToolRuns;
3299
3653
  private _reconcileAgentToolRuns;
3654
+ private _inspectAgentToolRunForRecovery;
3655
+ private _scheduleAgentToolRunRecovery;
3656
+ private _agentToolRunRecoveryRunIds;
3657
+ private _getAgentToolChunksForRecovery;
3300
3658
  /**
3301
3659
  * Shared facet resolution — takes a CamelCase class name string
3302
3660
  * (matching `ctx.exports`) rather than a class reference. Both
@@ -3332,11 +3690,15 @@ declare class Agent<
3332
3690
  deleteSubAgent(cls: SubAgentClass, name: string): Promise<void>;
3333
3691
  /** @internal */
3334
3692
  private _subAgentRegistryReady;
3693
+ private _addColumnIfNotExists;
3335
3694
  /** @internal */
3336
3695
  private _ensureSubAgentRegistry;
3337
3696
  /** @internal */
3338
3697
  private _recordSubAgent;
3339
3698
  /** @internal */
3699
+ private _subAgentRegistryRow;
3700
+ private _cf_subAgentIdentity;
3701
+ /** @internal */
3340
3702
  private _forgetSubAgent;
3341
3703
  /**
3342
3704
  * Whether this agent has previously spawned (and not deleted) a
@@ -3996,6 +4358,26 @@ type AgentToolTerminalStatus = Extract<
3996
4358
  AgentToolRunStatus,
3997
4359
  "completed" | "error" | "aborted" | "interrupted"
3998
4360
  >;
4361
+ /**
4362
+ * Structured failure envelope an `agentTool()` returns when a sub-agent run
4363
+ * does not complete. Instead of an opaque error string the parent model would
4364
+ * parrot back to the user, the caller (or an orchestration harness) gets a
4365
+ * machine-readable signal:
4366
+ *
4367
+ * - `status` mirrors the underlying terminal status (`error` | `aborted` |
4368
+ * `interrupted`).
4369
+ * - `retryable` is `true` only for a transient interruption — the child was
4370
+ * reset or superseded by a deploy / parent recovery and never reached a
4371
+ * logical outcome, so re-dispatching the same run is the right move. A
4372
+ * genuine `error` or an intentional `aborted` is `false`.
4373
+ * - `error` stays human-readable for logs and UI.
4374
+ */
4375
+ type AgentToolFailure = {
4376
+ ok: false;
4377
+ status: Exclude<AgentToolTerminalStatus, "completed">;
4378
+ error: string;
4379
+ retryable: boolean;
4380
+ };
3999
4381
  type AgentToolDisplayMetadata = {
4000
4382
  name?: string;
4001
4383
  icon?: string;
@@ -4139,102 +4521,107 @@ type AgentToolEventState = {
4139
4521
  };
4140
4522
  //#endregion
4141
4523
  export {
4142
- SubAgentStub as $,
4143
- EmailSendBinding as A,
4144
- McpAuthContext as At,
4145
- QueueItem as B,
4146
- SubAgentPathMatch as Bt,
4147
- AgentStaticOptions as C,
4148
- ElicitRequest$1 as Ct,
4149
- DEFAULT_AGENT_STATIC_OPTIONS as D,
4150
- CreateMcpHandlerOptions as Dt,
4151
- ConnectionContext$1 as E,
4152
- McpAgent as Et,
4153
- FiberStatus as F,
4154
- SSEEdgeClientTransport as Ft,
4155
- ScheduleCriteria as G,
4156
- RPCResponse as H,
4157
- parseSubAgentPath as Ht,
4158
- ListFibersOptions as I,
4159
- StreamableHTTPEdgeClientTransport as It,
4160
- StartFiberOptions as J,
4161
- SendEmailOptions as K,
4162
- MCPServer as L,
4163
- McpClientOptions as Lt,
4164
- FiberInspection as M,
4165
- TransportState as Mt,
4166
- FiberRecoveryContext as N,
4167
- WorkerTransport as Nt,
4168
- DeleteFibersOptions as O,
4169
- createMcpHandler as Ot,
4170
- FiberRecoveryResult as P,
4171
- WorkerTransportOptions as Pt,
4172
- SubAgentClass as Q,
4173
- MCPServerMessage as R,
4174
- TransportType as Rt,
4175
- AgentOptions as S,
4176
- RPC_DO_PREFIX as St,
4177
- Connection$1 as T,
4178
- ElicitResult$1 as Tt,
4179
- RoutingRetryOptions as U,
4180
- routeSubAgentRequest as Ut,
4181
- RPCRequest as V,
4182
- getSubAgentByName as Vt,
4183
- Schedule as W,
4184
- StateUpdateMessage as X,
4185
- StartFiberResult as Y,
4186
- StreamingResponse as Z,
4187
- AddRpcMcpServerOptions as _,
4188
- getNamespacedData as _t,
4524
+ SubAgentClass as $,
4525
+ EmailRoutingOptions as A,
4526
+ ClearableEventStore as At,
4527
+ MCPServersState as B,
4528
+ SSEEdgeClientTransport as Bt,
4529
+ AgentOptions as C,
4530
+ RPCServerTransport as Ct,
4531
+ ConnectionContext$1 as D,
4532
+ ElicitRequestSchema$1 as Dt,
4533
+ Connection$1 as E,
4534
+ ElicitRequest$1 as Et,
4535
+ FiberRecoveryResult as F,
4536
+ McpAuthContext as Ft,
4537
+ Schedule as G,
4538
+ SubAgentPathMatch as Gt,
4539
+ RPCRequest as H,
4540
+ McpClientOptions as Ht,
4541
+ FiberStatus as I,
4542
+ getMcpAuthContext as It,
4543
+ SqlError as J,
4544
+ routeSubAgentRequest as Jt,
4545
+ ScheduleCriteria as K,
4546
+ getSubAgentByName as Kt,
4547
+ ListFibersOptions as L,
4548
+ TransportState as Lt,
4549
+ FiberContext as M,
4550
+ CreateMcpHandlerOptions as Mt,
4551
+ FiberInspection as N,
4552
+ createMcpHandler as Nt,
4553
+ DEFAULT_AGENT_STATIC_OPTIONS as O,
4554
+ ElicitResult$1 as Ot,
4555
+ FiberRecoveryContext as P,
4556
+ experimental_createMcpHandler as Pt,
4557
+ StreamingResponse as Q,
4558
+ MCPServer as R,
4559
+ WorkerTransport as Rt,
4560
+ AgentNamespace as S,
4561
+ RPCClientTransportOptions as St,
4562
+ CallableMetadata as T,
4563
+ RPC_DO_PREFIX as Tt,
4564
+ RPCResponse as U,
4565
+ TransportType as Ut,
4566
+ QueueItem as V,
4567
+ StreamableHTTPEdgeClientTransport as Vt,
4568
+ RoutingRetryOptions as W,
4569
+ SUB_PREFIX as Wt,
4570
+ StartFiberResult as X,
4571
+ StartFiberOptions as Y,
4572
+ StateUpdateMessage as Z,
4573
+ AddMcpServerOptions as _,
4574
+ MCP_SERVER_ID_MAX_LENGTH as _t,
4189
4575
  AgentToolEventState as a,
4190
- routeAgentRequest as at,
4191
- AgentGetOptions as b,
4192
- RPCServerTransport as bt,
4193
- AgentToolRunInspection as c,
4194
- MCPClientManagerOptions as ct,
4195
- AgentToolStoredChunk as d,
4196
- MCPConnectionResult as dt,
4197
- WSMessage$1 as et,
4198
- AgentToolTerminalStatus as f,
4199
- MCPDiscoverResult as ft,
4200
- AddMcpServerOptions as g,
4201
- RegisterServerOptions as gt,
4202
- RunAgentToolResult as h,
4203
- MCPServerOptions as ht,
4576
+ routeAgentEmail as at,
4577
+ AgentContext as b,
4578
+ normalizeServerId as bt,
4579
+ AgentToolRunInfo as c,
4580
+ MCPClientManager as ct,
4581
+ AgentToolRunStatus as d,
4582
+ MCPClientOAuthResult as dt,
4583
+ SubAgentStub as et,
4584
+ AgentToolStoredChunk as f,
4585
+ MCPConnectionResult as ft,
4586
+ RunAgentToolResult as g,
4587
+ MCPServerOptions as gt,
4588
+ RunAgentToolOptions as h,
4589
+ MCPServerFilter as ht,
4204
4590
  AgentToolEventMessage as i,
4205
- routeAgentEmail as it,
4206
- FiberContext as j,
4207
- getMcpAuthContext as jt,
4208
- EmailRoutingOptions as k,
4209
- experimental_createMcpHandler as kt,
4210
- AgentToolRunState as l,
4211
- MCPClientOAuthCallbackConfig as lt,
4212
- RunAgentToolOptions as m,
4213
- MCPServerFilter as mt,
4591
+ getCurrentAgent as it,
4592
+ EmailSendBinding as j,
4593
+ DurableObjectEventStore as jt,
4594
+ DeleteFibersOptions as k,
4595
+ McpAgent as kt,
4596
+ AgentToolRunInspection as l,
4597
+ MCPClientManagerOptions as lt,
4598
+ ChatCapableAgentClass as m,
4599
+ MCPOAuthCallbackResult as mt,
4214
4600
  AgentToolDisplayMetadata as n,
4215
- getAgentByName as nt,
4216
- AgentToolLifecycleResult as o,
4217
- unstable_callable as ot,
4218
- ChatCapableAgentClass as p,
4219
- MCPOAuthCallbackResult as pt,
4220
- SqlError as q,
4601
+ callable as nt,
4602
+ AgentToolFailure as o,
4603
+ routeAgentRequest as ot,
4604
+ AgentToolTerminalStatus as p,
4605
+ MCPDiscoverResult as pt,
4606
+ SendEmailOptions as q,
4607
+ parseSubAgentPath as qt,
4221
4608
  AgentToolEvent as r,
4222
- getCurrentAgent as rt,
4223
- AgentToolRunInfo as s,
4224
- MCPClientManager as st,
4609
+ getAgentByName as rt,
4610
+ AgentToolLifecycleResult as s,
4611
+ unstable_callable as st,
4225
4612
  AgentToolChildAdapter as t,
4226
- callable as tt,
4227
- AgentToolRunStatus as u,
4228
- MCPClientOAuthResult as ut,
4229
- Agent as v,
4230
- RPCClientTransport as vt,
4231
- CallableMetadata as w,
4232
- ElicitRequestSchema$1 as wt,
4233
- AgentNamespace as x,
4234
- RPCServerTransportOptions as xt,
4235
- AgentContext as y,
4236
- RPCClientTransportOptions as yt,
4237
- MCPServersState as z,
4238
- SUB_PREFIX as zt
4613
+ WSMessage$1 as tt,
4614
+ AgentToolRunState as u,
4615
+ MCPClientOAuthCallbackConfig as ut,
4616
+ AddRpcMcpServerOptions as v,
4617
+ RegisterServerOptions as vt,
4618
+ AgentStaticOptions as w,
4619
+ RPCServerTransportOptions as wt,
4620
+ AgentGetOptions as x,
4621
+ RPCClientTransport as xt,
4622
+ Agent as y,
4623
+ getNamespacedData as yt,
4624
+ MCPServerMessage as z,
4625
+ WorkerTransportOptions as zt
4239
4626
  };
4240
- //# sourceMappingURL=agent-tool-types-Dn9n-3SI.d.ts.map
4627
+ //# sourceMappingURL=agent-tool-types-LInzZfLo.d.ts.map