A TypeScript library for building reliable agentic systems from specialized sub-agents. Deterministic runtime where LLMs fill only the gaps that cannot be codified.
- π§© Three axioms β Sequence, Signal, Condition. Everything else is derived
- β‘ Reactive runtime β agents trigger on cabinet state until convergence
- π Dual modes β sequential pipelines or reactive execution, same agent contract
- ποΈ Deterministic orchestration β pipeline order, reflexes, lessons are code, not LLM decisions
- π¦ Cabinet protocol β namespaced key-value store for inter-agent communication
- π§ Learning system β skills (permanent) and lessons (decay after quiet runs)
- π Condition engine β pure queries against scope state, no side effects
npm install composable-agentsimport { Controller, ConditionEngine, builtinEvaluators } from 'composable-agents';
// Create agents
const agents = new Map();
agents.set('greeter', {
id: 'greeter',
manifest: { id: 'greeter', type: 'code', version: '0.1.0', purpose: 'Greets user' },
execute: async (scope) => {
scope.blackboard.setTaskOutput('Hello, World!');
return { status: 'success', output: 'Hello, World!' };
},
});
// Run pipeline
const controller = new Controller();
const result = await controller.run('Say hello', {
pipeline: [{ agent: 'greeter' }],
agents,
conditionEngine: new ConditionEngine(),
});
console.log(result.output); // "Hello, World!"Agents run in declared order. Steps can be singular, sequential, or parallel.
const pipeline = [
{ agent: 'input-agent' }, // singular
{ sequence: [ // sequential
{ agent: 'validator' },
{ agent: 'transformer' },
]},
{ parallel: [ // parallel branches
{ agent: 'frontend-check' },
{ agent: 'backend-check' },
], join: 'all', merge: 'latest' },
];Reflexes and lessons flow alongside execution, not through it.
const reflexes = [{
timing: 'post-cycle',
condition: 'has-error',
action: 'abort-agent',
}];No side effects. Just check state.
const conditionEngine = new ConditionEngine();
conditionEngine.registerAll(builtinEvaluators);
// cabinet-exists(path=bug/classification)
// blackboard-equals(key=task.status, value="ready")Agents declare triggers on cabinet state. Runtime evaluates until convergence.
// Agent manifest
{
reactive: {
when: 'cabinet-exists(path=bug/classification)',
priority: 10,
},
}
// Run reactively
const result = await controller.run(task, {
pipeline: [{ agent: 'classify' }, { agent: 'fix' }],
agents,
conditionEngine,
runtime: { mode: 'reactive', maxIterations: 50 },
});Uses rising-edge semantics β agents run only when their trigger transitions from false β true.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β SHIPPED PATTERNS β
β pipeline Β· reactive runtime Β· reflexes Β· learning β
β foreman approval loops Β· user-defined compositions β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β AXIOMS β
β Sequence ordered and parallel execution β
β Signal events orthogonal to execution β
β Condition synchronous state queries β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β CONTROLLER MODES β
β sequence explicit pipeline order β
β reactive trigger-driven until convergence β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β STORAGE β
β Blackboard typed working state β
β Cabinet namespaced artifact protocol β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
interface Agent {
id: string;
manifest: AgentManifest;
execute(scope: ExecutionScope, signal?: AbortSignal): Promise<AgentResult>;
}{
id: string;
type: 'llm' | 'code' | 'composite';
version: string;
purpose: string;
reactive?: { when: string; priority?: number };
learning?: { channels: string[] };
visibility?: { expose: { cabinet: string[] } };
}Namespaced key-value store for inter-agent communication.
scope.cabinet.put('bug/classification', 'frontend');
const classification = scope.cabinet.get('bug/classification');Typed working state per agent.
scope.blackboard.task.input; // what the agent received
scope.blackboard.setTaskOutput('result');| Agent | Purpose |
|---|---|
id |
Identity agent β declares constraints and values |
job |
Job tracking agent |
reflexes |
Reflex evaluation agent |
learning |
Learning loop agent |
memory |
Memory persistence agent |
foreman |
Approval gate agent |
- Specification β full design contract
- Architecture β runtime model and axioms
- API Reference β public exports
- Condition Language β condition expressions
- Pipeline Format β pipeline YAML syntax
- Agent Format β agent YAML syntax
cd packages/core
npm test # 146 tests passing
npm run build # TypeScript compile
npm run lint # Biome checkcomposable-agents/
βββ packages/
β βββ core/ # The library
β β βββ src/
β β β βββ runtime/ # Controller, engines, signal bus
β β β βββ context/ # Scope, cabinet, blackboard
β β β βββ types/ # TypeScript interfaces
β β β βββ agents/ # Built-in agents
β β β βββ conditions/ # Built-in condition evaluators
β β β βββ loader/ # YAML/JSON agent loading
β β βββ tests/ # 146 tests
β βββ cli/ # CLI tools
βββ examples/
β βββ image-resizer/ # Multi-agent image processing
β βββ story-writer/ # LLM story generation pipeline
βββ schemas/ # JSON Schemas
βββ skills/ # Pi skills
βββ SPEC.md # Implementation contract
βββ AGENTS.md # Session instructions
See AGENTS.md for project conventions.
MIT