Open Thalamus Protocol · v1.0 · DraftOrchestration Pipeline
A deterministic five-stage protocol for coordinating complex AI workloads across a decentralized network of heterogeneous LLM providers. Every stage dispatches standard sub-jobs — no proprietary transport, no message broker.
T3 SupervisorT2 WorkerT1 ExecutorRewrite Loop
Pipeline Call Sequence
Stage 1Classify— Heuristics + optional T1
Stage 2Decompose— T3 Supervisor
Stage 3Execute Waves— T1 / T2 Workers (parallel)
Stage 4Synthesise— T3 Supervisor
Stage 5Rewrite Loop— T3 Supervisor (× N iterations)
Stage Reference
01Complexity Classification
Stage 1 — Heuristics — Prompt length, keyword patterns, and explicit step count are evaluated synchronously in < 1 ms. Output: simple | complex | agentic | uncertain.
Stage 2 — Classifier (optional) — When Stage 1 returns uncertain, a short prompt is sent to the fastest T1 Executor. Returns simple, complex, or agentic. Adds ~200–500 ms.
Routing decision — simple → Fast Path (direct dispatch). complex / agentic → Slow Path (full pipeline). The minimum threshold is admin-configurable.
02Decomposition
T3 Supervisor Input — Original user prompt.
Output — DecompositionPlan: a dependency graph of up to 3 subtasks, each with id, type, prompt, target tier, and depends_on list.
Synthesis field — "supervisor" — T3 writes the final answer in Stage 4. "rule" — results are concatenated in order, skipping Stage 4.
Fail-open — If the JSON cannot be parsed, the raw Supervisor output is returned immediately as the final answer. No response is ever discarded.
{
"subtasks": [
{ "id": "1", "type": "research", "prompt": "…", "tier": 2, "depends_on": [] },
{ "id": "2", "type": "analyze", "prompt": "…", "tier": 2, "depends_on": ["1"] },
{ "id": "3", "type": "summarize", "prompt": "…", "tier": 1, "depends_on": ["1","2"] }
],
"synthesis": "supervisor"
}03Wave Execution
T1 / T2 Workers Wave planning — Subtasks are topologically sorted into parallel waves. All tasks in a wave are independent and run concurrently (bounded by max_parallel_subtasks, default 5).
Provider spread — Before a wave launches, one provider is pre-assigned per task. The algorithm favours different providers for different tasks to prevent queue pile-up on a single node.
Capability- & throughput-aware selection — Candidates are ranked by an effective score blending quality (benchmark score + a static family-affinity bonus) and speed (rolling tokens/sec, reinforced by hedge win-rate). throughput_alpha controls the blend — default 1.0 is quality-only (unchanged ranking); lower values weight speed more. Applies to worker subtasks only — the final synthesis/generation step always stays quality-first.
Domain anchoring — Every subtask prompt is prefixed with the original request so Workers never drift off-topic.
Race Mode — When enabled, the same subtask is sent to N providers simultaneously. First success wins; others are cancelled and not billed.
Input — Original prompt + all subtask results.
Three tasks in one call — 1. Synthesise — write a coherent final answer. 2. Cover gaps — address any requirement not covered by subtask results. 3. Fact-check — prefix unsupported claims with ⚠️ [unverified].
Fallback — If DecompositionPlan.synthesis is "rule", results are concatenated in dependency order without an extra LLM call.
05Quality Validation & Rewrite Loop
T3 Supervisor Quality Validator — The Supervisor scores the current result 0.0–1.0 and lists specific issues. On any parse failure it returns score=1.0 (fail-open) and the loop terminates.
Rewriter — When score < threshold, the Supervisor rewrites the answer — targeting only the listed issues. It is also told which issues were already fixed in prior iterations to prevent regressions.
Termination — Loop ends when score ≥ threshold (default 0.7), no issues remain, or max_rewrite_iterations (default 3) is reached.
Issue diffing — Each iteration tracks which issues were resolved and which are new, using prefix matching to tolerate minor rephrasing.
Iteration log — Every pass is persisted: score, issues, fixed, new_issues. Initial and final scores are stored on the root job for analytics.
// Per-iteration log entry
{
"iteration": 1,
"score": 0.78,
"issues": ["Contradictory conclusion"],
"fixed": ["Missing latency figures"],
"new_issues": []
}Sub-Job Dispatch Mechanism
Every pipeline stage communicates through a single primitive — the sub-job. This decouples the orchestrator from the transport layer and reuses the existing job lifecycle.
pendingJob created in DB, SSE notification sent to provider node
runningProvider accepted the job via GET /api/v1/providers/{id}/jobs
doneProvider posted result to POST /api/v1/jobs/{id}/result
failedTimeout, provider error, or explicit failure
Pending-Accept Timeout
| Online providers | Timeout | Reasoning |
|---|
| 1 | 10 min | All jobs queue sequentially — long waits are expected |
| 2 – 3 | 3 min | Some queueing still possible with limited providers |
| ≥ 4 | 90 s | Long pending = stale SSE connection, fail fast |
Slow-Subtask Hedge
A subtask running past a 75 s deadline gets one parallel copy on an alternate provider. First success wins; the other job is cancelled and marked superseded — not failed.
| Rung | Target |
|---|
| 1 | Fastest different model, same tier, different provider |
| 2 | One tier lower (worker roles only, if throughput_hedge_tierdown is on) |
| 3 | Same model, different provider — last resort |
Each race tags its jobs hedge_role = winner / loser, feeding a rolling per-model speed signal used by the selection above. Final-answer roles stop at rung 1 — no tier-down.
Configuration Reference
enabledbool · falseActivate the orchestration pipeline
min_complexityint 0–2 · 10 = always, 1 = complex+, 2 = agentic only
classifier_enabledbool · trueStage-2 classifier for uncertain requests
supervisor_fallback_tierint 2–3 · 2Tier used when no T3 is available
max_parallel_subtasksint 1–20 · 5Max concurrent subtasks per wave
race_modebool · falseEnable race mode globally
race_replicasint 1–5 · 2Number of providers per race
race_tierslist · 1, 2Tiers on which race mode applies
max_rewrite_iterationsint 0–10 · 30 = rewrite loop disabled
rewrite_score_thresholdfloat 0–1 · 0.7Stop rewriting when score ≥ this value
throughput_alphafloat 0–1 · 1.0Quality/speed blend for worker selection — 1.0 = quality-only
throughput_floorfloat 0–1 · 0.1Minimum speed_norm — a model is never fully excluded
throughput_window_hoursint 1–168 · 24Rolling window for tokens/sec + hedge win-rate
throughput_hedge_tierdownbool · trueAllow the hedge to fall back one tier for worker roles
Error Handling
The pipeline never returns an empty response. Every failure has a defined fallback.
Decomposition parse errorReturn raw Supervisor output as final answer
Subtask failsLog error, continue with empty result for that subtask
All subtasks in wave failSynthesis proceeds with available results
Synthesis failsReturn concatenated subtask results (rule fallback)
Validator parse errorReturn score = 1.0, terminate loop (fail-open)
Rewriter failsKeep current result, terminate loop
No models availableReturn HTTP 503 to caller