@claw-orchestra/sdk
v0.1.0
Published
Claw Orchestra — Multi-Agent Orchestration SDK — define, deploy, and orchestrate teams of specialist AI agents
Maintainers
Readme
@claw-orchestra/sdk
Claw Orchestra — Multi-Agent Orchestration SDK — define, deploy, and orchestrate teams of specialist AI agents through a declarative TypeScript API.
Built on top of OpenClaw's native multi-agent routing, sessions_spawn, sessions_send, and skills system.
Quick Start
npm install @claw-orchestra/sdkimport { Orchestra, defineAgents } from "@claw-orchestra/sdk";
const team = defineAgents({
principal: {
id: "lead",
name: "Team Lead",
soul: "You coordinate tasks between specialists.",
canDelegateTo: ["dev", "writer"],
},
specialists: [
{ id: "dev", name: "Developer", soul: "You write clean TypeScript code." },
{ id: "writer", name: "Writer", soul: "You write clear documentation." },
],
});
const orch = new Orchestra(team);
await orch.connect();
// Auto-classify and route to the right agent(s)
const result = await orch.send("Build a REST API with documentation");
console.log(result.status); // "completed"
console.log(result.aggregatedOutput); // combined output from all agents
console.log(result.totalCost); // USD spent
orch.disconnect();How It Works
Your Message
│
▼
┌─────────────────────┐
│ Task Classifier │ ← LLM-based routing decision
│ (which agents?) │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ Execution Scheduler │ ← single / parallel / sequential / pipeline
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ OpenClaw Gateway │ ← sessions_spawn / sessions_send
│ ┌─────┐ ┌─────┐ │
│ │Dev │ │Write│ │ Isolated workspaces, sandboxes, tools
│ └─────┘ └─────┘ │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ Result Aggregator │ ← merge / synthesize outputs
└─────────────────────┘The SDK maps directly to OpenClaw primitives:
| SDK Component | OpenClaw Primitive |
|---|---|
| Agent Registry | agents.list[] + workspace files (SOUL.md, AGENTS.md) |
| Task Classifier | LLM call via Gateway for intent detection |
| Parallel execution | sessions_spawn (non-blocking) |
| Sequential execution | sessions_send (blocking, with context passing) |
| Agent isolation | Per-agent workspace, sandbox, tool allow/deny |
| Cost tracking | Token estimation from response lengths |
Core API
defineAgents(config) → AgentTeamConfig
Define your agent team with validation and defaults:
const team = defineAgents({
defaultModel: "claude-sonnet-4-5-20250929",
principal: {
id: "coordinator",
name: "Coordinator",
soul: "You are a PM who delegates effectively.",
canDelegateTo: ["coder", "writer", "analyst"],
capabilities: ["planning", "delegation"],
},
specialists: [
{
id: "coder",
name: "Developer",
soul: "You write clean TypeScript.",
capabilities: ["typescript", "react", "api"],
tools: { allow: ["group:fs", "group:runtime"], deny: ["message"] },
sandbox: { mode: "all", scope: "agent" },
},
// ...more specialists
],
});new Orchestra(team, options?)
Create the orchestra:
const orch = new Orchestra(team, {
gateway: { url: "ws://127.0.0.1:18789", token: "your-token" },
classifier: { model: "claude-haiku-4-5-20251001", cache: true },
});
await orch.connect();orch.send(message) → ExecutionResult
Auto-classify and execute:
const result = await orch.send("Build a landing page and write copy for it");
// Classifier decides: pipeline strategy, coder → writerorch.sendTo(agentId, task) → StepResult
Send directly to a specific agent:
const result = await orch.sendTo("coder", "Fix the login bug in auth.ts");orch.pipeline(name, config) → PipelineHandle
Define a reusable pipeline:
const pipe = orch.pipeline("feature-build", {
steps: [
{ agent: "analyst", task: "Research {feature}", timeout: "3m" },
{ agent: "coder", task: "Implement based on: {prev.output}", timeout: "10m" },
{ agent: "writer", task: "Write docs for: {prev.output}", timeout: "5m" },
],
maxTotalCost: 2.0,
onError: (step, err) => ({ retry: true, maxAttempts: 2 }),
});
const result = await pipe.run({ feature: "WebSocket notifications" });orch.router(name, config) → RouterHandle
Dynamic routing with escalation:
const support = orch.router("support", {
entry: "tier1-general",
escalation: {
rules: [
{ when: "billing", to: "tier2-billing" },
{ when: "technical", to: "tier2-technical" },
],
preserveContext: true,
maxEscalations: 3,
},
});
const result = await support.route("I'm getting API errors on the /users endpoint");orch.cron(name, config)
Scheduled pipeline execution:
const weekly = orch.cron("weekly-report", {
schedule: "0 8 * * MON",
steps: [
{ agent: "researcher", task: "Scan this week's industry news" },
{ agent: "writer", task: "Write a summary from: {prev.output}" },
],
notify: { channel: "telegram", to: "@team" },
});Pre-Built Templates
Skip team definition with ready-made templates:
import { Orchestra, createDevTeam, createContentStudio, createSupportDesk } from "@claw-orchestra/sdk";
// Software development team
const dev = new Orchestra(createDevTeam());
// Content production pipeline
const content = new Orchestra(createContentStudio());
// Customer support desk with escalation
const support = new Orchestra(createSupportDesk({ tier1Model: "claude-haiku-4-5-20251001" }));Execution Strategies
| Strategy | When to Use | OpenClaw Mechanism |
|---|---|---|
| single | One agent handles everything | sessions_send |
| parallel | Independent subtasks | Multiple sessions_spawn |
| sequential | Tasks depend on previous results | Chained sessions_send |
| pipeline | Data transforms through agents | Sequential with output injection |
Observability
Tracing
const result = await orch.send("...");
console.log(orch.tracer.formatTimeline(result.traceId));Output:
Trace: orch-1707350400000-1
Pipeline: auto
Started: 2026-02-08T00:00:00.000Z
+0.0s ████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ step_start [analyst]
+4.2s ████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░ step_end [analyst]
+4.3s ████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░ step_start [coder]
+15.1s ████████████████████████████████████████████ step_end [coder]
Status: completed
Total: 15.1s | $0.0342 | 12450 tokensCost Tracking
console.log(orch.costTracker.formatSummary());
// === Cost Report ===
// By Agent:
// analyst: $0.0045 | 3 runs | 4200 tokens
// coder: $0.0189 | 2 runs | 8100 tokens
// writer: $0.0022 | 1 runs | 2300 tokens
// Total: $0.0256 | 14600 tokensPlugins
Human-in-the-Loop
import { HumanInTheLoop } from "@claw-orchestra/sdk";
const hil = new HumanInTheLoop(orch.gateway);
const approval = await hil.requestApproval({
agentId: "coder",
action: "Deploy to production",
details: "Deploying v2.1.0 with 3 new endpoints",
channel: "telegram",
to: "@devops-lead",
timeoutMs: 300_000,
});
if (approval.approved) {
await orch.sendTo("coder", "Run the deploy script");
}Webhook Triggers
import { WebhookServer } from "@claw-orchestra/sdk";
const webhooks = new WebhookServer(orch, {
port: 18800,
routes: [
{
path: "/trigger/deploy",
pipeline: "deploy-pipeline",
secret: "my-secret",
extractVariables: (body) => ({ branch: body.ref as string }),
},
],
});
await webhooks.start();Config Generation
Generate OpenClaw configuration files from your SDK definitions:
// Generate openclaw.json
const config = orch.generateConfig();
fs.writeFileSync("openclaw.json", JSON.stringify(config, null, 2));
// Generate workspace files (SOUL.md, AGENTS.md per agent)
const files = orch.generateWorkspaceFiles();
for (const [path, content] of files) {
fs.mkdirSync(dirname(path), { recursive: true });
fs.writeFileSync(path, content);
}Events
orch.on("task:classified", (decision) => { /* routing decision made */ });
orch.on("step:start", (agentId, task) => { /* agent starting work */ });
orch.on("step:complete", (result) => { /* agent finished */ });
orch.on("pipeline:complete", (result) => { /* full pipeline done */ });
orch.on("cost:threshold", (current, limit) => { /* budget warning */ });
orch.on("gateway:connected", () => { /* connected to OpenClaw */ });
orch.on("gateway:disconnected", (reason) => { /* lost connection */ });Requirements
- Node.js 22+
- OpenClaw Gateway running with multi-agent routing configured
- API keys for your LLM provider(s) configured in OpenClaw
Project Structure
@claw-orchestra/sdk/
├── src/
│ ├── core/
│ │ ├── orchestrator.ts # Main Orchestra class
│ │ ├── classifier.ts # Task → agent routing
│ │ ├── scheduler.ts # Execution strategies
│ │ ├── aggregator.ts # Result synthesis
│ │ └── registry.ts # Agent management
│ ├── adapters/
│ │ ├── gateway.ts # WebSocket client
│ │ ├── sessions.ts # sessions_* tool wrappers
│ │ └── config-generator.ts # openclaw.json builder
│ ├── observability/
│ │ ├── tracer.ts # Distributed tracing
│ │ └── cost-tracker.ts # Token & cost monitoring
│ ├── plugins/
│ │ ├── human-in-loop.ts # Approval gates
│ │ └── webhook.ts # HTTP webhook triggers
│ ├── templates/
│ │ ├── dev-team/ # Software dev team
│ │ ├── content-studio/ # Content production
│ │ └── support-desk/ # Customer support
│ ├── types/
│ │ └── index.ts # All type definitions
│ ├── helpers.ts # defineAgents()
│ └── index.ts # Public exports
├── examples/
│ ├── quickstart.ts
│ └── full-usage.ts
├── tests/
│ └── core.test.ts
├── package.json
└── tsconfig.jsonLicense
MIT
