anyclaude-sdk 0.10.1 → 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 +23 -3
- package/dist/agent.d.ts +5 -0
- package/dist/agent.js +27 -2
- package/dist/query.d.ts +4 -0
- package/dist/query.js +1 -0
- package/dist/team/broadcast-mailbox.d.ts +14 -0
- package/dist/team/broadcast-mailbox.js +17 -0
- package/dist/team/dispatch.js +14 -5
- package/dist/team/prompt.js +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/telemetry.js +1 -1
- package/dist/tools/types.d.ts +4 -0
- package/package.json +2 -6
package/README.md
CHANGED
|
@@ -214,9 +214,29 @@ query({ prompt, workspace, llm, team: true, mailbox })
|
|
|
214
214
|
// messages sent by one worker land in the addressed agent's inbox in another.
|
|
215
215
|
```
|
|
216
216
|
|
|
217
|
-
Uses the global `BroadcastChannel` by default
|
|
218
|
-
|
|
219
|
-
|
|
217
|
+
Uses the global `BroadcastChannel` by default. For durable cross-tab delivery
|
|
218
|
+
(IndexedDB/localStorage fallbacks, older browsers, Node) use the one-call helper
|
|
219
|
+
— it's backed by the bundled [`broadcast-channel`](https://www.npmjs.com/package/broadcast-channel)
|
|
220
|
+
package, lazy-imported so it stays out of bundles that don't use it:
|
|
221
|
+
|
|
222
|
+
```typescript
|
|
223
|
+
const mailbox = await BroadcastChannelMailbox.crossTab({ channelName: 'team', origin: 'planner' })
|
|
224
|
+
query({ prompt, workspace, llm, team: true, mailbox })
|
|
225
|
+
```
|
|
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 })`.
|
|
220
240
|
|
|
221
241
|
## Pluggable backends
|
|
222
242
|
|
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
|
-
|
|
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,
|
|
@@ -27,6 +27,20 @@ export declare class BroadcastChannelMailbox extends Mailbox {
|
|
|
27
27
|
private readonly origin;
|
|
28
28
|
private closed;
|
|
29
29
|
constructor(opts?: BroadcastChannelMailboxOptions);
|
|
30
|
+
/**
|
|
31
|
+
* Cross-tab/cross-context mailbox in one call, backed by the bundled
|
|
32
|
+
* `broadcast-channel` package (durable across tabs via IndexedDB/localStorage
|
|
33
|
+
* fallbacks, and works in older browsers + Node). Async because the package
|
|
34
|
+
* is lazy-imported so it stays out of bundles that don't use it.
|
|
35
|
+
*
|
|
36
|
+
* const mb = await BroadcastChannelMailbox.crossTab({ channelName: 'team', origin: 'planner' })
|
|
37
|
+
* query({ prompt, workspace, llm, team: true, mailbox: mb })
|
|
38
|
+
*/
|
|
39
|
+
static crossTab(opts?: {
|
|
40
|
+
channelName?: string;
|
|
41
|
+
origin?: string;
|
|
42
|
+
channelOptions?: unknown;
|
|
43
|
+
}): Promise<BroadcastChannelMailbox>;
|
|
30
44
|
/** Send a message: append to the local replica and broadcast to peers. */
|
|
31
45
|
send(from: string, to: string, text: string): string;
|
|
32
46
|
/** Stop listening and release the channel. Safe to call more than once. */
|
|
@@ -63,6 +63,23 @@ export class BroadcastChannelMailbox extends Mailbox {
|
|
|
63
63
|
this.channel.onmessage = (ev) => handle(ev);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Cross-tab/cross-context mailbox in one call, backed by the bundled
|
|
68
|
+
* `broadcast-channel` package (durable across tabs via IndexedDB/localStorage
|
|
69
|
+
* fallbacks, and works in older browsers + Node). Async because the package
|
|
70
|
+
* is lazy-imported so it stays out of bundles that don't use it.
|
|
71
|
+
*
|
|
72
|
+
* const mb = await BroadcastChannelMailbox.crossTab({ channelName: 'team', origin: 'planner' })
|
|
73
|
+
* query({ prompt, workspace, llm, team: true, mailbox: mb })
|
|
74
|
+
*/
|
|
75
|
+
static async crossTab(opts = {}) {
|
|
76
|
+
const mod = (await import('broadcast-channel'));
|
|
77
|
+
const BC = mod.BroadcastChannel ?? mod.default?.BroadcastChannel;
|
|
78
|
+
if (!BC)
|
|
79
|
+
throw new Error('broadcast-channel package did not export BroadcastChannel');
|
|
80
|
+
const channel = new BC(opts.channelName ?? 'anyclaude-team', opts.channelOptions);
|
|
81
|
+
return new BroadcastChannelMailbox({ channel, origin: opts.origin });
|
|
82
|
+
}
|
|
66
83
|
/** Send a message: append to the local replica and broadcast to peers. */
|
|
67
84
|
send(from, to, text) {
|
|
68
85
|
// Globally-unique id: origin-scoped so two workers never collide.
|
package/dist/team/dispatch.js
CHANGED
|
@@ -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) =>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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,
|
package/dist/team/prompt.js
CHANGED
|
@@ -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
|
}
|
package/dist/telemetry.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Bump on release so adoption can be bucketed by version. */
|
|
2
|
-
export declare const TELEMETRY_SDK_VERSION = "0.
|
|
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.
|
|
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.
|
package/dist/tools/types.d.ts
CHANGED
|
@@ -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.
|
|
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",
|
|
@@ -115,6 +115,7 @@
|
|
|
115
115
|
"url": "https://github.com/pipilot-dev/anyclaude-sdk/issues"
|
|
116
116
|
},
|
|
117
117
|
"dependencies": {
|
|
118
|
+
"broadcast-channel": "^7.0.0",
|
|
118
119
|
"comlink": "^4.4.2"
|
|
119
120
|
},
|
|
120
121
|
"peerDependencies": {
|
|
@@ -122,7 +123,6 @@
|
|
|
122
123
|
"@daytonaio/sdk": "*",
|
|
123
124
|
"@vercel/sandbox": "*",
|
|
124
125
|
"@webcontainer/api": ">=1.1.0",
|
|
125
|
-
"broadcast-channel": ">=4.0.0",
|
|
126
126
|
"dexie": ">=3.2.0",
|
|
127
127
|
"e2b": "*"
|
|
128
128
|
},
|
|
@@ -130,9 +130,6 @@
|
|
|
130
130
|
"@webcontainer/api": {
|
|
131
131
|
"optional": true
|
|
132
132
|
},
|
|
133
|
-
"broadcast-channel": {
|
|
134
|
-
"optional": true
|
|
135
|
-
},
|
|
136
133
|
"dexie": {
|
|
137
134
|
"optional": true
|
|
138
135
|
},
|
|
@@ -151,7 +148,6 @@
|
|
|
151
148
|
},
|
|
152
149
|
"devDependencies": {
|
|
153
150
|
"@types/node": "^26.0.0",
|
|
154
|
-
"broadcast-channel": "^7.0.0",
|
|
155
151
|
"dexie": "^4.4.4",
|
|
156
152
|
"typescript": "^5.4.0"
|
|
157
153
|
}
|