@stoneforge/smithy
v1.16.1
Published
Orchestrator SDK for Stoneforge - AI agent orchestration library extending the core SDK
Maintainers
Readme
@stoneforge/smithy
Multi-agent orchestration for Stoneforge — directors, workers, and stewards with provider-agnostic session management.
Overview
@stoneforge/smithy adds AI agent orchestration on top of @stoneforge/quarry. It defines three agent roles (director, worker, steward), manages their sessions across multiple providers, dispatches tasks automatically, and isolates work in Git worktrees. Agents communicate through Stoneforge channels.
Installation
npm install @stoneforge/smithyThe default Claude provider is included. For additional providers, install the corresponding optional dependency:
# OpenCode provider
npm install @opencode-ai/sdkQuick Start
import { createOrchestratorAPI } from '@stoneforge/smithy';
import { createStorage, initializeSchema } from '@stoneforge/storage';
// Create a storage backend and initialize the schema
const storage = createStorage({ path: '.stoneforge/db.sqlite' });
initializeSchema(storage);
// Create the OrchestratorAPI (extends QuarryAPI)
const api = createOrchestratorAPI(storage);
// Register a director agent
const director = await api.registerDirector({
name: 'lead',
createdBy: humanEntityId,
});
// Register an ephemeral worker
const worker = await api.registerWorker({
name: 'dev-1',
workerMode: 'ephemeral',
createdBy: director.id,
reportsTo: director.id,
});
// Assign a task to the worker (auto-generates branch and worktree names)
await api.assignTaskToAgent(taskId, worker.id);Agent Roles
| Role | Session | Description | |------|---------|-------------| | Director | Persistent | Creates tasks and plans, sets priorities, coordinates workers | | Worker (ephemeral) | Task-scoped | Executes one task in an isolated Git worktree, exits on completion | | Worker (persistent) | Interactive | Long-lived session for real-time collaboration with a human | | Steward | Workflow-scoped | Merge review, branch cleanup, and documentation scanning/fixes |
OrchestratorAPI
The OrchestratorAPI extends QuarryAPI (from @stoneforge/quarry) with agent-specific operations. Create one with createOrchestratorAPI(backend) where backend is a StorageBackend from @stoneforge/storage.
Agent Registration
// Director — one per workspace
const director = await api.registerDirector({
name: 'MainDirector',
createdBy: humanEntityId,
maxConcurrentTasks: 1, // optional
provider: 'claude', // optional, default: 'claude'
model: 'claude-sonnet-4-20250514', // optional
});
// Ephemeral worker
const worker = await api.registerWorker({
name: 'Worker-1',
workerMode: 'ephemeral', // 'ephemeral' | 'persistent'
createdBy: directorId,
reportsTo: directorId, // optional
maxConcurrentTasks: 1, // optional
roleDefinitionRef: roleDefId, // optional
});
// Steward
const steward = await api.registerSteward({
name: 'MergeSteward',
stewardFocus: 'merge', // 'merge' | 'docs' | 'recovery' | 'custom'
triggers: [{ type: 'event', event: 'task_completed' }],
createdBy: directorId,
});Agent Queries
const agent = await api.getAgent(entityId);
const agentByName = await api.getAgentByName('Worker-1');
const allAgents = await api.listAgents();
const workers = await api.listAgents({ role: 'worker' });
const director = await api.getDirector();
const stewards = await api.getStewards();
const available = await api.getAvailableWorkers();Task Assignment
// Assign a task — auto-generates branch and worktree paths
const task = await api.assignTaskToAgent(taskId, workerId);
// With explicit options
const task = await api.assignTaskToAgent(taskId, workerId, {
branch: 'agent/worker-1/task-feat-auth',
worktree: '.stoneforge/.worktrees/worker-1-feat-auth',
sessionId: 'session-123',
markAsStarted: true,
});
// Read/update orchestrator metadata on a task
const meta = await api.getTaskOrchestratorMeta(taskId);
await api.updateTaskOrchestratorMeta(taskId, { mergeStatus: 'pending' });Session Management
await api.updateAgentSession(agentId, 'session-123', 'running');
// Session states: 'idle' | 'running' | 'suspended' | 'terminated'
const channelId = await api.getAgentChannel(agentId);Providers
| Provider | Package | Notes |
|----------|---------|-------|
| claude | @anthropic-ai/claude-agent-sdk | Default, included as a dependency |
| opencode | @opencode-ai/sdk | Optional dependency |
| codex | Built-in | JSON-RPC over stdio |
Each provider implements the AgentProvider interface with headless and interactive sub-providers for non-interactive and interactive sessions respectively.
Scaling with Multiple Plans
To run 10+ agents concurrently, split them across multiple Claude Code MAX or Pro plans:
- Create a profile wrapper for each plan — set
CLAUDE_CONFIG_DIRto a separate directory and authenticate each one - In the Stoneforge dashboard (Settings > Agent Defaults), set the executable path per provider, or set it per-agent when creating/editing agents
See the Claude Code profiles discussion for wrapper script examples.
Key Services
| Service | Description |
|---------|-------------|
| AgentRegistry | Register and look up agents by role/name |
| RoleDefinitionService | Store and retrieve agent role definitions |
| TaskAssignmentService | Assign tasks with orchestrator metadata |
| DispatchService | Match ready tasks to available workers |
| DispatchDaemon | Continuous polling loop for auto-dispatch |
| WorkerTaskService | Worker-side task operations (complete, hand off) |
| MergeStewardService | Review and merge completed work branches |
| DocsStewardService | Documentation scanning and fixes |
| StewardScheduler | Run stewards on cron-like schedules |
| AgentPoolService | Manage pools of workers with auto-scaling |
| PluginExecutor | Execute steward plugins (playbooks, scripts, commands) |
Git Worktree Isolation
Workers operate in isolated Git worktrees to prevent conflicts:
- Ephemeral workers:
agent/{worker-name}/{task-id}-{slug} - Persistent workers:
agent/{worker-name}/session-{timestamp}
Utilities for creating, listing, and cleaning up worktrees are available in the ./git entry point.
Entry Points
| Import | Contents |
|--------|----------|
| @stoneforge/smithy | Everything (re-exports all subpaths) |
| @stoneforge/smithy/types | Agent roles, metadata, message types, naming utilities |
| @stoneforge/smithy/services | All orchestration services |
| @stoneforge/smithy/runtime | Runtime utilities for agent execution, session management, providers |
| @stoneforge/smithy/git | Git worktree management |
| @stoneforge/smithy/providers | AgentProvider interface, provider registry, all providers |
| @stoneforge/smithy/testing | Test helpers, mocks, and orchestration test definitions |
| @stoneforge/smithy/server | HTTP/WebSocket server for agent orchestration |
Part of Stoneforge — Apache-2.0
