@ddse/acm-planner
@ddse/acm-planner turns goals, context packets, and capability maps into structured plans that comply with ACM v0.5.0.
Installation
pnpm add @ddse/acm-planner @ddse/acm-llm @ddse/acm-sdk
Structured planning loop
- Normalise goal/context and compute
contextRef(SHA-256). - Prompt the LLM with capability names and guard grammar.
- Request Plan-A and Plan-B in JSON.
- Validate JSON schema; fallback to a safe linear plan if parsing fails.
- Emit telemetry and rationale to the ledger.
Usage
import {StructuredLLMPlanner} from '@ddse/acm-planner';
import {createVLLMClient} from '@ddse/acm-llm';
const planner = new StructuredLLMPlanner({ planCount: 2 });
const llm = createVLLMClient('Qwen/Qwen3-Coder-30B-A3B-Instruct-FP8', 'http://localhost:8001/v1');
const result = await planner.plan({
goal,
context,
capabilities: capabilityRegistry.list(),
llm,
capabilityMapVersion: 'v0.5.0'
});
Inspect plans and their rationale:
result.plans.forEach((plan) => {
console.log(plan.id, plan.tasks.length, plan.rationale);
});
Telemetry
plans.length— Typically 2 (Plan-A and Plan-B)contextRef— Bind plan to contextrationale— Planner justificationalternatives— Cross references to other plans in the set
Safe fallback
When the LLM output cannot be parsed, the planner emits plan-fallback, a linear plan containing only safe, preconfigured steps. This keeps systems running while signalling that operator attention is required.
Custom selectors
Choose which plan to execute:
const planner = new StructuredLLMPlanner({
planCount: 3,
selector: ({ plans }) => plans.find((plan) => plan.id === 'plan-b') ?? plans[0]
});
Streaming tokens
Attach a stream sink to surface reasoning in real time:
stream.attach('planner', (chunk) => {
if (chunk.delta) process.stdout.write(chunk.delta);
});
References
- Package README
- Core Concepts → Structured Planning
- Governance → Policies for guard and verification strategies