Skip to main content
Stoneforge provides several high-level services that orchestrate complex workflows by composing QuarryAPI and OrchestratorAPI operations. These services implement key orchestration patterns for multi-agent task execution.

Overview

Services are located in:
  • packages/smithy/src/services/ - Orchestration services
  • packages/quarry/src/services/ - Core services

DispatchService

Combines task assignment with agent notification. Implemented in dispatch-service.ts.

dispatch()

Dispatches a task to an agent (assigns + notifies).
taskId
ElementId
required
Task to dispatch
agentId
EntityId
required
Agent to dispatch to
options
DispatchOptions
result
DispatchResult
import { createDispatchService } from '@stoneforge/smithy';

const dispatchService = createDispatchService(api, taskAssignment, agentRegistry);

const result = await dispatchService.dispatch(taskId, workerId, {
  markAsStarted: true,
  priority: 5,
  dispatchedBy: directorId,
});

console.log(`Task dispatched to ${result.agent.name} at ${result.dispatchedAt}`);

notifyAgent()

Sends a notification without assigning a task.
agentId
EntityId
required
Agent to notify
messageType
'task-assignment' | 'task-reassignment' | 'restart-signal'
required
Notification type
content
string
required
Message content
metadata
object
Additional metadata
message
Message
Sent notification message
await dispatchService.notifyAgent(
  workerId,
  'restart-signal',
  'Please restart your session to pick up new configuration'
);

WorkerTaskService

Orchestrates the complete worker task workflow: dispatch → worktree → spawn → context. Implemented in worker-task-service.ts.

startWorkerOnTask()

Starts a worker on a task with full worktree isolation.
taskId
ElementId
required
Task to start
agentId
EntityId
required
Worker agent ID
options
StartWorkerOnTaskOptions
result
StartWorkerOnTaskResult
import { createWorkerTaskService } from '@stoneforge/smithy';

const workerTaskService = createWorkerTaskService(
  api,
  taskAssignment,
  agentRegistry,
  dispatchService,
  spawnerService,
  sessionManager,
  worktreeManager
);

const result = await workerTaskService.startWorkerOnTask(taskId, workerId, {
  additionalPrompt: 'Focus on test coverage',
  priority: 5,
});

console.log(`Worker started in ${result.worktree.path}`);
console.log(`Session ID: ${result.session.id}`);

completeTask()

Marks a task as completed and ready for merge.
taskId
ElementId
required
Task to complete
options
CompleteTaskOptions
result
CompleteTaskResult
const result = await workerTaskService.completeTask(taskId, {
  summary: 'Implemented feature X with tests',
  commitHash: 'abc123',
});

console.log(`Task completed and ready for merge: ${result.readyForMerge}`);

buildTaskContextPrompt()

Builds a formatted task context prompt for a worker.
taskId
ElementId
required
Task ID
workerId
EntityId
required
Worker entity ID
additionalInstructions
string
Additional instructions to include
prompt
string
Formatted task context prompt
const prompt = await workerTaskService.buildTaskContextPrompt(
  taskId,
  workerId,
  'Focus on error handling'
);

console.log(prompt);
// Output:
// # Task Assignment
//
// **Worker ID:** el-worker123
// **Task ID:** el-task456
// **Title:** Implement feature X
// ...

MergeStewardService

Automates the merge workflow: test → merge → cleanup. Implemented in merge-steward-service.ts.

processTask()

Processes a single task for merge (test + merge + cleanup).
taskId
ElementId
required
Task to process
options
ProcessTaskOptions
result
MergeProcessResult
import { createMergeStewardService } from '@stoneforge/smithy';

const mergeSteward = createMergeStewardService(
  api,
  taskAssignment,
  dispatchService,
  agentRegistry,
  {
    workspaceRoot: process.cwd(),
    testCommand: 'bun test',
    autoMerge: true,
    autoCleanup: true,
    deleteBranchAfterMerge: true,
  },
  worktreeManager
);

const result = await mergeSteward.processTask(taskId);

if (result.merged) {
  console.log(`✓ Merged: ${result.mergeCommitHash}`);
} else if (result.fixTaskId) {
  console.log(`✗ Created fix task: ${result.fixTaskId}`);
}

getTasksAwaitingMerge()

Retrieves tasks ready for merge processing.
tasks
TaskAssignment[]
Tasks awaiting merge
const pending = await mergeSteward.getTasksAwaitingMerge();
console.log(`${pending.length} tasks awaiting merge`);

processAllPending()

Processes all tasks awaiting merge.
options
ProcessTaskOptions
Processing options
result
BatchProcessResult
const result = await mergeSteward.processAllPending();
console.log(`Processed ${result.totalProcessed} tasks in ${result.durationMs}ms`);
console.log(`✓ Merged: ${result.mergedCount}`);
console.log(`✗ Failed: ${result.testFailedCount + result.conflictCount}`);

runTests()

Runs tests on a task’s branch.
taskId
ElementId
required
Task ID
result
TestRunResult
const testResult = await mergeSteward.runTests(taskId);
if (!testResult.passed) {
  console.error(`Tests failed with exit code ${testResult.exitCode}`);
  console.error(testResult.output);
}

createFixTask()

Creates a fix task for test failures or merge conflicts.
originalTaskId
ElementId
required
Original task that failed
options
CreateFixTaskOptions
required
fixTaskId
ElementId
Created fix task ID
const fixTaskId = await mergeSteward.createFixTask(taskId, {
  type: 'test_failure',
  errorDetails: 'Tests failed: 3 errors in authentication module',
});

DependencyService

Low-level dependency management with cycle detection. Implemented in packages/quarry/src/services/dependency.ts.

detectCycle()

Checks if adding a dependency would create a cycle.
blockedId
ElementId
required
Blocked element ID
blockerId
ElementId
required
Blocker element ID
type
DependencyType
required
Dependency type
config
CycleDetectionConfig
result
CycleDetectionResult
import { createDependencyService } from '@stoneforge/quarry';

const depService = createDependencyService(backend);

const result = depService.detectCycle(taskAId, taskBId, 'blocks');
if (result.hasCycle) {
  console.error(`Cycle detected: ${result.cyclePath.join(' → ')}`);
}

InboxService

Manages agent inbox items for notifications. Implemented in packages/quarry/src/services/inbox.ts.

getInbox()

Retrieves inbox items for an entity.
recipientId
EntityId
required
Recipient entity ID
unreadOnly
boolean
Only return unread items (default: false)
items
InboxItem[]
Inbox items
import { createInboxService } from '@stoneforge/quarry';

const inboxService = createInboxService(backend);

const unread = await inboxService.getInbox(workerId, true);
console.log(`${unread.length} unread notifications`);

Build docs developers (and LLMs) love