Tales runs AI coding CLIs — Claude Code, Codex, Open Code, and generic CLI rows like Gemini — side by side in your terminal. They argue through the implementation, recommend who should execute — and nothing runs until you say so.
❯ tales "add OAuth login"
▌ Claude Code DRAFTER
middleware layer — passport.js + the Google strategy, wired into the
existing session store. small, isolated change.
▌ Codex CRITIC
approach is right. Claude has the better read on the current auth flow —
let it execute. I'll review the diff after.
★ recommend Claude Code
▸ pick executor [1] Claude Code [2] Codex ← you decide
You ▸ 1
✓ Claude Code executing in an isolated git worktree…
✓ done — clean diff ready for your review.One model has one opinion. Two models have an argument.
A single agent commits to its first framing and runs with it. Tales puts two strong models with different priors in the same room: one drafts, the other critiques, and the disagreement surfaces the assumptions a solo run would have buried — before the diff, not after.
This isn't a hunch; the field keeps re-discovering it:
- OpenRouter model fusion blends several models for a stronger single answer.
- AWS Kiro splits spec-then-build across agents.
Tales applies the same bet — combine more than one model instead of trusting one — where you already work: your terminal. It does it for planning (the live drafter/critic discussion) and gives you the tools to do it for execution (git-worktree isolation), with a human on the gate the whole time.
| drafter | proposes the approach, writes the plan |
| critic | pokes holes, asks the questions, names the trade-offs |
| you | read the debate and pick the executor — a hard gate, nothing auto-runs |
Tales isn't locked to two models or one vendor. Any AI coding CLI can join behind one small adapter — Claude Code, Codex, Open Code, and generic CLI rows today — and the room doesn't have to be uniform.
The payoff is tiered execution: run your smart, expensive models on the part that matters — the plan and the argument — then hand the agreed plan to a cheaper, faster model to implement. You pay top dollar for judgment, not for typing.
# two strong models plan + argue, a cheap/fast one implements
tales run "add OAuth login" \
--drafter claude --drafter-model opus \
--critic codex --critic-model gpt-5 --critic-effort high \
--execute gemini --execute-model gemini-2.5-flashPick the model and the effort per seat. Every participant takes its own --<role>-model
and --<role>-effort (e.g. Codex low/medium/high), and in the interactive terminal the
connect screen cycles both inline — m for model, e for effort.
Hooking a new tool is a row, not an adapter. Tools with bespoke wiring (Claude Code, Codex,
Open Code) name their adapter; any other turn-based CLI that prints its reply to stdout rides one
shared generic adapter, configured from a registry row (run_args / model_flag /
prompt_flag). Gemini, GLM, and Kimi ship as rows today; the connect screen auto-detects which
CLIs are actually installed on every run. Adding Kiro, Aider, or your own is a one-line change.
The flags above let you assemble the room. TalesSML is the small model that does it for you. Tales is not just a harness that shuttles tasks between other models — it ships its own model whose entire job is to coordinate and orchestrate those models.
TalesSML isn't a coding model and it isn't an API wrapper: it's a tiny open base (Qwen2.5, 0.5–3B), LoRA-fine-tuned on Tales-generated coordination data and served locally — no cloud, no account, no per-token cost, ~0.18 s/decision. It's the same idea Sakana built Fugu's Conductor on — a coordination policy on top of existing models, not a foundation model from scratch. Given one task it reasons over the work and emits a full orchestration plan:
| field | what TalesSML decides |
|---|---|
| shape | solo (one strong model plans + executes) · debate (two planners argue) · tiered (strong plan, cheap execute) |
| difficulty | correctness risk, 0.0–1.0 — how unsafe it is to run cheap |
| roster | which agent in which role at which model: {role: drafter|critic|executor|reviewer|verifier, agent: claude|codex, model: opus|sonnet|haiku|gpt-5.x, why} |
| coordination | the order, whether it's parallelizable, the handoff |
| verify | whether to check, and how (tests / review / build) |
| escalate | when to promote to Opus (high difficulty, failed verification, security-sensitive) |
A keyword counter sees "migrate all the cron jobs" and routes mechanical-tiered at 99%
confidence — it can't tell that's a design decision. A model that reasons over the task can.
Measured on held-out corpora (training/):
| model | size | easy (18) | hard / mixed-signal (11) | game-dev (13) | speed |
|---|---|---|---|---|---|
| keyword coordinator | — | 100% | 63.6% | — | instant |
| prompted qwen3.5:9b | 6.6 GB | 100% | 90.9% | — | ~5 s/task |
| TalesSML (fine-tuned) | 398 MB | 100% | 100% | 92.3% | ~0.18 s/task |
TalesSML beats a prompted 9B on the mixed-signal corpus at 16× smaller and ~30× faster, fully offline. Use it as Tales' conductor:
# Tales' own model decides the orchestration plan — local, no cloud
cargo build --release --features llm-conductor
tales run "decide whether to migrate the cron jobs to the queue" \
--conductor llm --conductor-url http://localhost:8080/v1The pure-Rust keyword/MLP tales coordinator stays the zero-cost default and the hard fallback
when the model server is unreachable. The LlmConductor memoizes each deterministic decision
to .tales/conductor-cache.json (keyed by model+prompt+task), so a repeated task is instant and
free — the local analogue of provider prompt caching.
Honest status: the engine acts on TalesSML's shape+difficulty today (the LlmConductor
parses them; extra plan fields are forward-compatible). The v2 plan target — full
roster/coordination/verify/escalate on a 1.5B base — now scores 100% / 100% / 92% plan-validity
on the easy / mixed-signal / game-dev corpora with zero malformed output (see
training/ for the eval and the train→eval→refine flywheel that got there);
wiring the full plan into adaptive turn-taking is next. Train your own in training/.
No Electron, no cloud, no account. The whole thing is small, native Rust.
| 1.5 MB | the tales-tui binary (size-optimized release build; tales 1.9 MB, tales-web 1.8 MB) |
| ~18.9k | lines of Rust across a UI-agnostic core + three frontends |
| 0 | telemetry, cloud calls, or background daemons — runs on your machine, your keys |
| ∞ | models, eventually — add an AgentAdapter, add a row, done |
A single frontier model — the best one money can buy — is the bar. The bet behind Tales is that an orchestrated team of cheaper models can reach for that bar: two strong-but-not-top models argue out the plan, a cheap fast model does the typing, and a human holds the trigger. The aim is frontier-class results at a lower blended cost — approaching a model like Claude Fable 5, not a claim to beat it (we haven't benchmarked against Fable 5 — it wasn't available). What follows is the honest evidence so far: where this already pays off, and where one strong model is still the better tool.
A fair, end-to-end test: implement a regex engine (fullmatch(pattern, text) over
literals, ., * + ?, |, groups, character classes, escapes), scored against 400 hidden
cases with Python's re as the oracle (no import re). Two conditions, each producing a real
solution.py that gets scored:
| Condition | Wall-clock | Cost | Quality |
|---|---|---|---|
| Opus 4.8 — solo (plans + executes) | 355s | $1.53 | 100% |
| Tales — Opus+Codex plan → Haiku executes | 481s | $1.74 | 100% |
| └ planning (two smart models, in parallel) | 176s | $1.00 | |
└ Haiku execution (iterates against re until green) |
304s | $0.74 |
On this task the single model won on every axis — 36% faster, 13% cheaper, same quality. The cheap-executor thesis lost here, and the reason is the point.
Why it lost. A regex engine's difficulty lives in the implementation (greedy backtracking, empty-match termination, edge cases), not in separable boilerplate. So the cheap executor had two options, both bad: implement blind and ship a systematic bug (43.8%, 224 crashes), or iterate against tests until green — which it did (100%), but that took 47 tool-rounds and ~4.6M cached tokens, $0.74 and 304s. The iteration-to-correctness ate the per-token cost advantage. Meanwhile Opus-solo wrote a correct ~350-line engine in one pass — and hit 100% blind, because the sandbox denied it a Python interpreter too.
The deciding factor is the shape of the work, not its size:
- ✅ Mechanically voluminous execution — boilerplate, repetitive endpoints, broad migrations. The two-planner cost is roughly fixed, so it amortizes; the cheap executor applies its cheap rate to a lot of volume it doesn't need to be smart about. Here, bigger helps Tales.
- ✅ Ambiguous, architecture-defining work with no known-correct answer — where two strong models arguing, plus a human on the gate, catch a bad design before it becomes a costly diff. A quality/risk play more than a cost/speed one.
- ❌ Algorithmically hard, self-contained tasks where correctness is the implementation. The cheap executor's capability gap and the lossy plan handoff both compound — bigger makes it worse, and a single frontier model wins (our regex engine, scaled up).
Honesty notes: single trial per arm (the direction is structural; exact percentages wobble). Costs are each tool's own meter — Opus/Haiku via Tales' cost printer at Anthropic list prices (Opus 4.8 $5/$25, Haiku 4.5 $1/$5 per M in/out), Codex from its
~/.codex/sessionstoken ledger × gpt-5.5 rates ($5 / $0.50 cached / $30). The Haiku executor ran through an agent harness that re-sends context aggressively; a leaner executor iterates cheaper, but the dynamic holds. Both models were denied a Python interpreter, so Opus-solo's one-pass 100% is despite not being able to test.
That first run exposed two costs in planning: the two planners ran sequentially (latency = the sum of their turns) and each turn re-pasted the whole transcript. Both are fixed:
- Parallel rounds — planners draft concurrently (round 1 independent, then one synthesizes a
merged plan while the other cross-reviews), so a round costs
max, notsum. - Delta-only context — resumable adapters get only the unseen tail each turn, not the whole transcript re-pasted.
Live A/B on the same planning task (Opus drafter + Codex critic): 250.8s sequential → 176.5s
parallel — a 30% speedup. (The synthesis step adds some Opus output, so parallel planning runs
~20% pricier — a speed-for-cost trade, tunable by moving the merge onto the cheaper model.)
Default for tales run/discuss; --sequential opts out.
# 1. build (needs Rust + the claude / codex CLIs installed & authenticated)
git clone https://github.com/cesarfrancots/tales && cd tales
cargo build --release # → target/release: tales, tales-tui, tales-web
# 2. check local tools and cached project context
tales doctor --all
tales context
tales profile refresh
# 3. open the terminal — connect your tools, then discuss
tales
# 4. or go straight in, scriptable:
tales run "add OAuth login" --drafter claude --critic codex --execute claude
# 5. compare collaboration shapes without model calls
tales eval compare "add OAuth login"Platform notes:
- macOS/Linux: run
./target/release/talesfrom the repo, or addtarget/releasetoPATH. - Windows PowerShell: run
.\target\release\tales.exefrom the repo, or addtarget\releasetoPATH. tales openlaunches a new terminal window on macOS, Windows, and common Linux desktop terminals; plaintalesworks inside any existing terminal.- Release checks:
scripts/release-check.shon macOS/Linux,.\scripts\release-check.ps1on Windows.
Try the whole flow with no API calls: tales-tui --demo or tales-web --demo.
- Connect — Tales opens with a workspace folder browser and a permission prompt, then you pick which CLIs join: Claude Code, Codex, Open Code, Gemini, GLM, Kimi, or another registry row. Bring two; bring three.
- Discuss (default) — they argue through the implementation. Type to interject — you're a participant. A formal plan is only requested when both AIs say one is needed.
- Pick — they recommend an executor; you confirm, override (
/confirm <n>), or reject. This gate can't be skipped. - Execute — the chosen tool builds from the discussion or agreed plan in an isolated git worktree. You get a clean, reviewable diff.
The terminal is built for real prompts: a multi-line editor (Alt+Enter for a newline, edit anywhere, paste multi-line blocks as one edit), PageUp/PageDown scrollback through the discussion, and slash-command type-ahead — press / to see the matching commands filter as you type.
/tales from inside Claude Code or Codex opens the same terminal with that tool pre-connected.
A Cargo workspace with a strictly UI-agnostic core — frontends talk to it only through the bus.
tales-core— the orchestrator. Every tool is oneAgentAdapteremitting normalizedAgentEvents; the wildly different CLIs (Claude's bidirectionalstream-jsonvs Codex's turn-basedexec/resume) differ only throughAgentCapsflags — never anif claude {…}.tales-cli— thetalesbinary: baretalesopens the interactive terminal;run/discuss/soloare the scriptable counterparts;doctor,context,profile, andevalpreflight tools/cache/memory/evaluation state with no model calls.tales-tui— the interactive terminal: connect → discuss → pick → execute.tales-web— a local browser view (axum + WebSocket) of the same session, with a pre-session workspace/task picker so you do not need tocdfirst.
Tales caches a compact repo map/manifest context outside the project and injects it into first planning prompts. It also keeps an opt-in local workspace profile under the Tales cache tree with metadata only: commands, preferred tools, warnings, report paths, and run summaries. Reports include prompt telemetry, provider token/cost data when adapters expose it, local-change handoff summaries, deterministic optimization hints, and recommendation inputs.
The shared SessionConfig contract now describes task, cwd, seats, prompt budget, report paths, and the approval policy used by CLI/web preflight. --dry-run --json includes that config, workspace profile status, and deterministic smarter/faster/cheaper tool recommendation chips.
Adding a tool (Gemini, Aider, …) is one adapter impl or one generic row in KNOWN_TOOLS; the picker,
CLI, and orchestrator all read that registry. Full details in the
documentation.
This repo dogfoods itself. The landing/ website and its
documentation were produced with Tales —
Claude Code and Codex drafting and reviewing each other through tales discuss, finalized
against the source. Eat your own cooking.
Live today: multi-agent discussion, parallel planning, cached project context, local workspace profiles, prompt forecasts, deterministic eval comparisons,
recommendation + a hard confirmation gate, git-worktree execution & merge, the interactive
terminal workspace (folder-browser onboarding, a multi-line prompt editor, transcript scrollback, and slash-command type-ahead),
browser supervision UI with workspace picker and command palette, report writers, and bespoke/generic tool adapters.
A learned orchestration coordinator (tales coordinator) routes each task to a collaboration shape (solo / debate / tiered) with a difficulty/tier estimate — and Tales' own small model, TalesSML, upgrades that decision from keyword-counting to reasoning over the task, emitting a full orchestration plan and served locally via --conductor llm (see Tales has a model of its own). An optional verify-and-iterate loop (tales run --verify "<cmd>") runs your check after execution and feeds failures back to the executor until it passes or hits the cap — the check runs unsandboxed in the executor's tree, so scope it (use --worktree to isolate). All local, dependency-free, and keep the human gate.
Runs on macOS, Linux, and Windows (all three covered by CI). Hardened against deadlocks and zombie processes; the test suite and strict clippy pass before push.