anyclaude-sdk 0.10.2 → 0.11.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/README.md CHANGED
@@ -224,6 +224,20 @@ const mailbox = await BroadcastChannelMailbox.crossTab({ channelName: 'team', or
224
224
  query({ prompt, workspace, llm, team: true, mailbox })
225
225
  ```
226
226
 
227
+ **Push delivery to a running agent.** Messages addressed to an agent are
228
+ auto-injected into its transcript at the next turn boundary — same model as the
229
+ message queue, but from the shared mailbox. So a coordinator (or peer, or another
230
+ worker) can redirect a **running** sub-agent mid-task and it lands on the
231
+ sub-agent's next tool round, no polling tool needed. `dispatch_tasks` names each
232
+ worker `worker:<taskId>` so you can target a specific one:
233
+
234
+ ```typescript
235
+ mailbox.send('coordinator', 'worker:task_1', 'while you work: also add logging')
236
+ // worker:task_1 sees "[Team messages] - from coordinator: ..." on its next step.
237
+ ```
238
+
239
+ On by default with `team: true`; opt out via `query({ deliverTeamMessages: false })`.
240
+
227
241
  ## Pluggable backends
228
242
 
229
243
  You aren't tied to WebContainer. A `Sandbox` is just a `FileSystem` plus a
package/dist/agent.d.ts CHANGED
@@ -119,6 +119,11 @@ export interface AgentOptions {
119
119
  board?: TaskBoard;
120
120
  /** This agent's name/label for messaging (default 'coordinator'). */
121
121
  agentName?: string;
122
+ /** Auto-deliver unread mailbox messages addressed to this agent into the
123
+ * transcript at each turn boundary (push delivery, like the message queue).
124
+ * Default true when `team` is enabled. Set false to require an explicit
125
+ * pull instead. */
126
+ deliverTeamMessages?: boolean;
122
127
  /** Persist the transcript to this store (keyed by sessionId) for resume. */
123
128
  sessionStore?: SessionStoreLike;
124
129
  /** Load the stored transcript for sessionId before the first turn. */
package/dist/agent.js CHANGED
@@ -212,6 +212,7 @@ export async function* runAgent(options) {
212
212
  const mailbox = teamEnabled ? options.mailbox ?? new Mailbox() : undefined;
213
213
  const board = teamEnabled ? options.board ?? new TaskBoard() : undefined;
214
214
  const agentName = options.agentName ?? 'coordinator';
215
+ const deliverTeamMessages = options.deliverTeamMessages ?? true;
215
216
  let localTools = subagentsEnabled && !baseTools.some((t) => t.def.function.name === 'task')
216
217
  ? [...baseTools, taskTool]
217
218
  : baseTools;
@@ -344,7 +345,7 @@ export async function* runAgent(options) {
344
345
  // Wire sub-agent spawning. Each call runs a fresh, isolated runAgent to
345
346
  // completion and returns only its final text.
346
347
  if (subagentsEnabled) {
347
- ctx.runSubagent = async ({ prompt: subPrompt, agentType, signal: subSignal, onProgress }) => {
348
+ ctx.runSubagent = async ({ prompt: subPrompt, agentType, name: subName, signal: subSignal, onProgress }) => {
348
349
  const def = agentType ? agents?.[agentType] : undefined;
349
350
  const subSystem = def?.prompt ?? defaultSubagentPrompt(cwd);
350
351
  const subTools = def?.tools
@@ -389,7 +390,8 @@ export async function* runAgent(options) {
389
390
  team: teamEnabled,
390
391
  mailbox,
391
392
  board,
392
- agentName: agentType || 'worker',
393
+ deliverTeamMessages,
394
+ agentName: subName || agentType || 'worker',
393
395
  memory,
394
396
  skills,
395
397
  });
@@ -626,6 +628,29 @@ export async function* runAgent(options) {
626
628
  };
627
629
  }
628
630
  }
631
+ // Team mailbox: push unread messages addressed to THIS agent into the
632
+ // transcript at the turn boundary — same delivery model as the queue, but
633
+ // sourced from the shared mailbox. This lets a coordinator (or any peer)
634
+ // dispatch a message to a *running* sub-agent and have it land on the
635
+ // sub-agent's next tool round, no polling tool required. Cross-worker too:
636
+ // a BroadcastChannelMailbox replicates the message before it's drained.
637
+ if (mailbox && deliverTeamMessages) {
638
+ const unread = mailbox.inbox(agentName, { unreadOnly: true });
639
+ if (unread.length) {
640
+ mailbox.markRead(agentName);
641
+ const body = '[Team messages]\n' +
642
+ unread.map((m) => `- from ${m.from}: ${m.text}`).join('\n');
643
+ history.push({ role: 'user', content: body });
644
+ yield {
645
+ type: 'user',
646
+ message: { role: 'user', content: body },
647
+ parent_tool_use_id: null,
648
+ timestamp: new Date().toISOString(),
649
+ uuid: uuid(),
650
+ session_id: sessionId,
651
+ };
652
+ }
653
+ }
629
654
  // Auto-compaction: summarize when the transcript nears the context limit.
630
655
  // Circuit-breaker: stop after 3 compactions (avoids a summarize loop).
631
656
  if (options.autoCompact && autoCompactCount < 3 && history.length > 3) {
package/dist/query.d.ts CHANGED
@@ -87,6 +87,10 @@ export interface QueryOptions {
87
87
  board?: import('./team/index.js').TaskBoard;
88
88
  /** This agent's name/label for messaging (default 'coordinator'). */
89
89
  agentName?: string;
90
+ /** Auto-deliver unread mailbox messages addressed to this agent into the
91
+ * transcript at each turn boundary (push delivery, like the message queue).
92
+ * Default true when `team` is enabled. */
93
+ deliverTeamMessages?: boolean;
90
94
  /** Persist the transcript to this store (keyed by sessionId) for resume. */
91
95
  sessionStore?: SessionStoreLike;
92
96
  /** Load the stored transcript for sessionId before the first turn. */
package/dist/query.js CHANGED
@@ -49,6 +49,7 @@ export function query(options) {
49
49
  includePartialMessages: options.includePartialMessages,
50
50
  team: options.team,
51
51
  mailbox: options.mailbox,
52
+ deliverTeamMessages: options.deliverTeamMessages,
52
53
  board: options.board,
53
54
  agentName: options.agentName,
54
55
  sessionStore: options.sessionStore,
@@ -23,11 +23,20 @@ export const dispatchTasks = {
23
23
  if (!board || !runSubagent) {
24
24
  return { content: 'Teammates/sub-agents are not enabled for this session.', isError: true };
25
25
  }
26
- const spawn = (task) => runSubagent({
27
- description: task.subject,
28
- prompt: `Complete this task:\n# ${task.subject}\n${task.description ?? ''}\n\n` +
29
- 'When done, your final message should report exactly what you did.',
30
- });
26
+ const spawn = (task) => {
27
+ // Give each worker a unique, addressable name and reflect it as the task
28
+ // owner, so the coordinator can dispatch a message to this specific
29
+ // running worker (delivered on its next tool round via the mailbox).
30
+ const name = `worker:${task.id}`;
31
+ board.update(task.id, { owner: name });
32
+ return runSubagent({
33
+ description: task.subject,
34
+ name,
35
+ prompt: `You are teammate "${name}". Complete this task:\n# ${task.subject}\n${task.description ?? ''}\n\n` +
36
+ 'New instructions from the coordinator may arrive mid-task as `[Team messages]` — adapt when they do. ' +
37
+ 'When done, your final message should report exactly what you did.',
38
+ });
39
+ };
31
40
  const summary = await runTeamLoop(board, spawn, {
32
41
  concurrency: typeof input.concurrency === 'number' ? input.concurrency : undefined,
33
42
  signal: ctx.signal,
@@ -6,7 +6,7 @@ You are the coordinator of a team of agents. Plan and delegate rather than doing
6
6
 
7
7
  - Decompose the work into discrete tasks on the shared board with \`task_create\`. When a task depends on another, set \`blocked_by\` to the prerequisite task ids so execution is correctly gated.
8
8
  - Spawn workers with the \`task\` tool to execute board tasks — give each worker a focused prompt and, when useful, run independent workers in parallel. Prefer parallelism over sequential work whenever tasks are independent.
9
- - Use \`send_message\` to direct workers, hand off context, or coordinate between teammates. Check the board with \`board_list\` and \`task_get\` to track progress, and keep task status current with \`task_update\` (mark in_progress when started, completed/failed when done).
9
+ - Use \`send_message\` to direct workers, hand off context, or coordinate between teammates. Dispatched workers are named \`worker:<taskId>\` (shown as the task owner in \`board_list\`); a message addressed to that name is delivered to that worker on its next step, even while it is still running — use this to redirect or add context mid-task. Check the board with \`board_list\` and \`task_get\` to track progress, and keep task status current with \`task_update\` (mark in_progress when started, completed/failed when done).
10
10
  - Synthesize workers' results yourself before continuing. NEVER fabricate or assume a worker's output — rely only on what they actually returned.
11
11
  - Keep the board the source of truth: every meaningful unit of work should be a task with an owner and a status.`;
12
12
  }
@@ -1,5 +1,5 @@
1
1
  /** Bump on release so adoption can be bucketed by version. */
2
- export declare const TELEMETRY_SDK_VERSION = "0.10.2";
2
+ export declare const TELEMETRY_SDK_VERSION = "0.11.0";
3
3
  export interface TelemetryOptions {
4
4
  /** Force-disable for this call (highest precedence besides the global opt-outs). */
5
5
  disabled?: boolean;
package/dist/telemetry.js CHANGED
@@ -16,7 +16,7 @@
16
16
  // See TELEMETRY.md for the full disclosure.
17
17
  import { uuid } from './util/ids.js';
18
18
  /** Bump on release so adoption can be bucketed by version. */
19
- export const TELEMETRY_SDK_VERSION = '0.10.2';
19
+ export const TELEMETRY_SDK_VERSION = '0.11.0';
20
20
  // Aggregate-only collector (Puter Worker; see examples/telemetry-collector).
21
21
  // Override with `ANYCLAUDE_TELEMETRY_URL` / `telemetry: { url }`, or disable
22
22
  // entirely with the opt-outs above. Set to '' to make telemetry a no-op.
@@ -33,6 +33,10 @@ export interface ToolContext {
33
33
  description: string;
34
34
  prompt: string;
35
35
  agentType?: string;
36
+ /** Unique name for this sub-agent in the shared mailbox, so peers can
37
+ * address messages to this specific running worker. Defaults to the
38
+ * agentType (or 'worker'). */
39
+ name?: string;
36
40
  /** Abort signal (e.g. a background task's stop) — cancels the sub-agent. */
37
41
  signal?: AbortSignal;
38
42
  /** Streamed progress (assistant text + tool names) as the sub-agent works. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anyclaude-sdk",
3
- "version": "0.10.2",
3
+ "version": "0.11.0",
4
4
  "description": "Standalone, browser-compatible SDK providing Claude Code agent capabilities (tools, tool loop, multi-turn, MCP, sub-agents, sessions) against any OpenAI/Anthropic-compatible LLM endpoint. Runs in the browser (WebContainer), Node, and Bun — no backend required.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",