agents 0.11.4 → 0.11.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -107,7 +107,7 @@ State changes sync to all connected clients automatically. Call methods like the
107
107
  ## Features
108
108
 
109
109
  ```
110
- Core State sync · Routing · HTTP & WebSockets · @callable RPC
110
+ Core State sync · Routing · HTTP & WebSockets · @callable RPC · Sub-agents (facets)
111
111
  Clients React hook · Vanilla JS · Real-time state sync
112
112
  Channels WebSocket · HTTP · Email · (coming: SMS, Voice, Messengers)
113
113
  Background Queue · Scheduling · Workflows · Human-in-the-loop
@@ -179,6 +179,49 @@ await this.queue("processUpload", { fileId: "abc" });
179
179
  // Returns immediately, task runs in background
180
180
  ```
181
181
 
182
+ ### Sub-agents
183
+
184
+ Spawn child Durable Objects (facets) from a parent agent. Each child has
185
+ its own SQLite storage and runs in parallel, but is addressed under the
186
+ parent's URL:
187
+
188
+ ```typescript
189
+ export class Inbox extends Agent {
190
+ @callable()
191
+ async createChat() {
192
+ const id = crypto.randomUUID();
193
+ await this.subAgent(Chat, id);
194
+ return id;
195
+ }
196
+
197
+ override async onBeforeSubAgent(_req, { className, name }) {
198
+ if (!this.hasSubAgent(className, name)) {
199
+ return new Response("Not found", { status: 404 });
200
+ }
201
+ }
202
+ }
203
+
204
+ export class Chat extends Agent {
205
+ async writePreview(text: string) {
206
+ const inbox = await this.parentAgent(Inbox);
207
+ await inbox.savePreview(this.name, text);
208
+ }
209
+ }
210
+ ```
211
+
212
+ Client-side, connect to a child with `useAgent({ sub: [...] })`:
213
+
214
+ ```tsx
215
+ const inbox = useAgent({ agent: "Inbox", name: userId });
216
+ const chat = useAgent({
217
+ agent: "Inbox",
218
+ name: userId,
219
+ sub: [{ agent: "Chat", name: chatId }]
220
+ });
221
+ ```
222
+
223
+ The routed URL becomes `/agents/inbox/{userId}/sub/chat/{chatId}`.
224
+
182
225
  ### WebSocket Connections
183
226
 
184
227
  Handle real-time communication:
@@ -599,5 +599,77 @@ type ChatProtocolEvent = {
599
599
  */
600
600
  declare function parseProtocolMessage(raw: string): ChatProtocolEvent | null;
601
601
  //#endregion
602
- export { AbortRegistry, type BroadcastStreamEvent, type BroadcastStreamState, type TransitionResult as BroadcastTransitionResult, CHAT_MESSAGE_TYPES, type ChatProtocolEvent, type ChunkAction, type ChunkResult, type ClientToolSchema, type ContinuationConnection, type ContinuationDeferred, type ContinuationPending, ContinuationState, type EnqueueOptions, type MessagePart, type MessageParts, ROW_MAX_BYTES, ResumableStream, type SqlTaggedTemplate, StreamAccumulator, type StreamAccumulatorOptions, type StreamChunkData, type ToolPartUpdate, TurnQueue, type TurnResult, applyChunkToParts, applyToolUpdate, transition as broadcastTransition, byteLength, createToolsFromClientSchemas, enforceRowSizeLimit, parseProtocolMessage, sanitizeMessage, toolApprovalUpdate, toolResultUpdate };
602
+ //#region src/chat/lifecycle.d.ts
603
+ /**
604
+ * Result passed to the `onChatResponse` lifecycle hook after a chat
605
+ * turn completes.
606
+ */
607
+ type ChatResponseResult = {
608
+ /** The finalized assistant message from this turn. */message: UIMessage; /** The request ID associated with this turn. */
609
+ requestId: string; /** Whether this turn was a continuation of a previous assistant turn. */
610
+ continuation: boolean; /** How the turn ended. */
611
+ status: "completed" | "error" | "aborted"; /** Error message when `status` is `"error"`. */
612
+ error?: string;
613
+ };
614
+ /**
615
+ * Result returned by programmatic entry points that may skip execution
616
+ * when the chat state has been invalidated mid-flight (e.g. by a
617
+ * `CHAT_CLEAR` protocol message).
618
+ */
619
+ type SaveMessagesResult = {
620
+ /** Server-generated request ID for the chat turn. */requestId: string; /** Whether the turn ran or was skipped (e.g. because the chat was cleared). */
621
+ status: "completed" | "skipped";
622
+ };
623
+ /**
624
+ * Context passed to the `onChatRecovery` hook when an interrupted chat
625
+ * stream is detected after DO restart.
626
+ */
627
+ type ChatRecoveryContext = {
628
+ /** Stream ID from the interrupted stream. */streamId: string; /** Request ID from the interrupted stream. */
629
+ requestId: string; /** Partial text extracted from stored chunks. */
630
+ partialText: string; /** Partial message parts reconstructed from chunks. */
631
+ partialParts: MessagePart[]; /** Checkpoint data from `this.stash()` during the interrupted stream. */
632
+ recoveryData: unknown | null; /** Current persisted messages. */
633
+ messages: UIMessage[]; /** Custom body from the last chat request. */
634
+ lastBody?: Record<string, unknown>; /** Client tool schemas from the last chat request. */
635
+ lastClientTools?: ClientToolSchema[];
636
+ /**
637
+ * Epoch milliseconds when the underlying fiber was started. Compare
638
+ * against `Date.now()` to suppress continuations for turns that have
639
+ * been orphaned too long to safely replay.
640
+ */
641
+ createdAt: number;
642
+ };
643
+ /**
644
+ * Options returned from `onChatRecovery` to control recovery behavior.
645
+ */
646
+ type ChatRecoveryOptions = {
647
+ /** Save the partial response from stored chunks. Default: true. */persist?: boolean; /** Schedule a continuation via `continueLastTurn()`. Default: true. */
648
+ continue?: boolean;
649
+ };
650
+ /**
651
+ * Controls how overlapping user submit requests behave while another
652
+ * chat turn is already active or queued.
653
+ *
654
+ * - `"queue"` (default) — queue every submit and process them in order.
655
+ * - `"latest"` — keep only the latest overlapping submit; superseded
656
+ * submits still persist their user messages, but do not start their
657
+ * own model turn.
658
+ * - `"merge"` — like `latest`, but all overlapping user messages remain
659
+ * in the conversation history. The model sees them all in one turn.
660
+ * - `"drop"` — ignore overlapping submits entirely (messages not
661
+ * persisted).
662
+ * - `{ strategy: "debounce", debounceMs? }` — trailing-edge latest with
663
+ * a quiet window.
664
+ *
665
+ * Only applies to `submit-message` requests. Regenerations, tool
666
+ * continuations, approvals, clears, programmatic `saveMessages`, and
667
+ * `continueLastTurn` keep their existing serialized behavior.
668
+ */
669
+ type MessageConcurrency = "queue" | "latest" | "merge" | "drop" | {
670
+ strategy: "debounce";
671
+ debounceMs?: number;
672
+ };
673
+ //#endregion
674
+ export { AbortRegistry, type BroadcastStreamEvent, type BroadcastStreamState, type TransitionResult as BroadcastTransitionResult, CHAT_MESSAGE_TYPES, type ChatProtocolEvent, type ChatRecoveryContext, type ChatRecoveryOptions, type ChatResponseResult, type ChunkAction, type ChunkResult, type ClientToolSchema, type ContinuationConnection, type ContinuationDeferred, type ContinuationPending, ContinuationState, type EnqueueOptions, type MessageConcurrency, type MessagePart, type MessageParts, ROW_MAX_BYTES, ResumableStream, type SaveMessagesResult, type SqlTaggedTemplate, StreamAccumulator, type StreamAccumulatorOptions, type StreamChunkData, type ToolPartUpdate, TurnQueue, type TurnResult, applyChunkToParts, applyToolUpdate, transition as broadcastTransition, byteLength, createToolsFromClientSchemas, enforceRowSizeLimit, parseProtocolMessage, sanitizeMessage, toolApprovalUpdate, toolResultUpdate };
603
675
  //# sourceMappingURL=index.d.ts.map
@@ -1446,8 +1446,10 @@ var MCPClientManager = class {
1446
1446
  const entries = [];
1447
1447
  for (const tool of getNamespacedData(connections, "tools")) try {
1448
1448
  const toolKey = `tool_${tool.serverId.replace(/-/g, "")}_${tool.name}`;
1449
+ const title = tool.title ?? tool.annotations?.title;
1449
1450
  entries.push([toolKey, {
1450
1451
  description: tool.description,
1452
+ title,
1451
1453
  execute: async (args) => {
1452
1454
  const result = await this.callTool({
1453
1455
  arguments: args,
@@ -1617,4 +1619,4 @@ function getNamespacedData(mcpClients, type) {
1617
1619
  //#endregion
1618
1620
  export { RPCServerTransport as a, RPCClientTransport as i, getNamespacedData as n, RPC_DO_PREFIX as o, MCPConnectionState as r, DisposableStore as s, MCPClientManager as t };
1619
1621
 
1620
- //# sourceMappingURL=client-B_xdiZbn.js.map
1622
+ //# sourceMappingURL=client-BYF13FDD.js.map