auto-reasoning is a small, dependency-free TypeScript harness that decides how much reasoning effort an
agentic task deserves — minimal, low, medium, high, or xhigh — without ever changing the model. It
classifies the task with a deterministic scorer, selects an effort from an auditable policy, runs the task through a
pluggable adapter (Codex CLI or the
OpenAI Responses API), verifies the result, and
escalates effort only when a run or verification fails.
Think of it as a thermostat for reasoning budget: cheap, fast, and shallow for a typo fix; deep and careful for an auth migration or a flaky-test investigation — and every decision is recorded in a machine-readable audit trail.
npx auto-reasoning "fix the typo in the README"
# difficulty: trivial score: 0 effort: low
npx auto-reasoning "investigate an intermittent production incident where the payment
service double-charges customers during a database migration; find the root cause and
implement a safe fix"
# difficulty: complex score: 7 effort: high- Why auto-reasoning?
- Features
- How it works
- Install
- Quick start (CLI)
- Library usage
- Adapters
- Reasoning efforts
- Policy configuration
- How routing works
- Audit trail
- CLI reference
- Codex / agent skill
- Requirements
- FAQ
- Limitations
- Contributing
- License
Most teams do not want every task to run at the deepest reasoning setting. A typo fix, a focused summary, a risky auth
migration, and a flaky-test investigation each deserve a different reasoning budget. Running everything at xhigh
wastes tokens, latency, and money; running everything at minimal produces shallow work on the tasks that matter most.
auto-reasoning makes that trade-off explicit, testable, and auditable. Instead of hard-coding an effort per
call site or picking a different model for hard tasks, you route on task signals and let the harness escalate on
evidence — a failed test, a failed verifier, or an adapter error.
Model routing vs. effort routing. Model routers swap a small model for a large one and change accuracy, pricing, and behavior all at once.
auto-reasoningholds the model constant and moves a single dial — reasoning effort — so results stay comparable and reproducible.
- 🎯 Reasoning-only routing — selects
minimal→xhigheffort; the model is fixed adapter configuration and is never mutated. - 🧮 Deterministic classifier — a transparent, rule-based scorer (no LLM call) turns task signals into a difficulty and effort.
- 🔌 Pluggable adapters — ships with Codex CLI, OpenAI Responses API, and a dry-run adapter; implement
RunnerAdapterfor your own. - ✅ Built-in verification — attach shell verifiers (
npm test,tsc --noEmit, …) that gate success and trigger escalation. - ⬆️ Evidence-based escalation — bumps to the next effort and retries only when a run or verifier fails, up to
maxAttempts. - 📜 Full audit trail — every classification, selection, escalation, adapter run, and verification is captured as timestamped events.
- 🧩 Configurable policy — score thresholds, escalation order, confidence floor, and retry budget live in JSON (with a JSON Schema).
- 🪶 Zero runtime dependencies — strict TypeScript, ESM, Node 18+.
- 🤖 Agent skill included — a drop-in Codex/agent skill so agents know when and how to route.
- Classify the task into a score, difficulty, effort, and confidence.
- Select a reasoning effort from the policy thresholds.
- Raise the initial effort if classifier confidence is below the floor.
- Run the adapter with only that effort setting (the model never changes).
- Verify the result with any attached verifiers.
- Escalate to the next effort and retry if the run or verification fails.
- Return the output plus a complete audit trail.
npm install auto-reasoningOr run it ad hoc without installing:
npx auto-reasoning "summarize this repo"Local development in this repo:
npm install
npm run verify # builds, then runs the test suiteDry-run the classifier (no model call — inspect the routing decision):
auto-reasoning "fix the typo in README"Run through Codex CLI without changing the model, gated by tests:
auto-reasoning \
--adapter codex \
--verify "npm test" \
"fix the failing tests"Run through the OpenAI Responses API with a fixed model:
OPENAI_API_KEY=... auto-reasoning \
--adapter openai \
--fixed-model gpt-5.5 \
"review this migration plan"Print the full audit trail as JSON:
auto-reasoning --json "investigate the flaky checkout test"You can also pipe the prompt on stdin: echo "review this patch" | auto-reasoning --json.
Codex CLI adapter:
import { CodexCliAdapter, createReasoningHarness } from "auto-reasoning";
const harness = createReasoningHarness({
adapter: new CodexCliAdapter({ ephemeral: true }),
});
const result = await harness.run({
prompt: "Fix the failing tests",
testCommands: ["npm test"],
tags: ["debugging"],
});
console.log(result.finalEffort); // e.g. "high"
console.log(result.audit); // timestamped event logOpenAI Responses API adapter (the model stays fixed for every run):
import { OpenAIResponsesAdapter, createReasoningHarness } from "auto-reasoning";
const harness = createReasoningHarness({
adapter: new OpenAIResponsesAdapter({
model: "gpt-5.5", // fixed for every run — auto-reasoning never changes it
}),
});
await harness.run({
prompt: "Analyze this production incident and propose next steps",
risk: "high",
});Attach shell verifiers so success is gated on real checks:
import { CodexCliAdapter, createReasoningHarness, createShellVerifier } from "auto-reasoning";
const harness = createReasoningHarness({
adapter: new CodexCliAdapter(),
verifiers: [createShellVerifier("npm test"), createShellVerifier("npx tsc --noEmit")],
});| Adapter | Import / --adapter |
What it does | Model source |
|---|---|---|---|
| Dry run | DryRunAdapter / dry-run (default) |
Classifies and reports the selected effort without calling any model. Ideal for testing policies and CI. | — |
| Codex CLI | CodexCliAdapter / codex |
Shells out to codex exec -c model_reasoning_effort="<effort>" "<task>". |
Codex configuration |
| OpenAI Responses | OpenAIResponsesAdapter / openai |
Calls the Responses API with reasoning.effort set to the selected effort. Requires --fixed-model / OPENAI_API_KEY. |
--fixed-model (fixed) |
The router never chooses or mutates the model — the model is always adapter configuration supplied by you or your
environment. Implement the RunnerAdapter interface ({ name, run(input) }) to target any other agent or API.
auto-reasoning selects one of five effort levels, in ascending order:
| Effort | Typical use |
|---|---|
minimal |
Trivial, mechanical edits — typos, renames, formatting. |
low |
Simple, well-scoped changes with little ambiguity. |
medium |
Normal multi-step tasks that need interpretation. |
high |
Complex or wide-scope work, debugging, unclear root cause. |
xhigh |
Critical / high-risk work — auth, payments, migrations, production. |
Effort maps to model_reasoning_effort for Codex and to reasoning.effort for the OpenAI Responses API.
The default policy maps a deterministic task score to an effort:
{
"confidenceFloor": 0.55,
"maxAttempts": 3,
"escalationOrder": ["minimal", "low", "medium", "high", "xhigh"],
"thresholds": [
{ "maxScore": 1, "difficulty": "trivial", "effort": "minimal" },
{ "maxScore": 3, "difficulty": "simple", "effort": "low" },
{ "maxScore": 6, "difficulty": "normal", "effort": "medium" },
{ "maxScore": 9, "difficulty": "complex", "effort": "high" },
{ "maxScore": 999, "difficulty": "critical", "effort": "xhigh" }
]
}| Field | Meaning |
|---|---|
confidenceFloor |
If classifier confidence is below this, the initial effort is bumped up one level (0–1). |
maxAttempts |
Maximum adapter runs, including escalations (positive integer). |
escalationOrder |
The ordered ladder of efforts used when escalating. |
thresholds |
Score cutoffs (ascending maxScore) mapping to a difficulty and effort. |
Use a custom policy from the CLI:
auto-reasoning --policy ./config/default.policy.json "review the patch"Policy files are validated against docs/policy.schema.json, so editors can autocomplete
and lint them.
The default classifier scores task signals without calling a model. Signals include:
| Signal | Effect on score |
|---|---|
| Prompt length & detail (empty, short, medium, long) | +1 → +3 |
| File / changed-file scope (single, multi, wide) | +1 → +3 |
| Presence of verification commands | +1 |
Debugging / ambiguity language (debug, investigate, flaky, race condition, regression) |
+2 |
Implementation language (build, implement, fix, refactor, migrate) |
+1 |
High-risk domains (auth, security, payment, database, migration, production, privacy, concurrency) |
+3 |
Explicit risk (medium / high / critical) |
+1 / +3 / +5 |
High-risk tags (auth, payments, pii, compliance, …) |
up to +3 |
Simple-task language (typo, rename, format, summarize, quick) |
−1 |
The score selects a difficulty and effort via the policy thresholds; a separate confidence estimate can bump the initial effort when the task is too vague to classify reliably.
Every run returns a HarnessResult whose audit array records what happened and why — ideal for logging,
dashboards, and post-hoc review. Event types include:
classified— the task score, difficulty, effort, confidence, and matched signals.effort_selected— the effort chosen for the first attempt.effort_escalated— a low-confidence bump or a post-failure escalation, withfrom/to.adapter_completed— adapter name, attempt, effort, success, and token usage (when available).verification_completed— how many verifiers ran and which failed.run_completed— the terminal outcome.
Pass --json on the CLI (or read result.audit in the library) to capture it.
auto-reasoning [options] "task prompt"
| Option | Description |
|---|---|
--adapter <dry-run|codex|openai> |
Execution adapter. Defaults to dry-run. |
--fixed-model <model> |
Fixed model for the OpenAI Responses adapter (required for openai). |
--policy <path> |
Path to a JSON policy file. |
--verify <command> |
Shell verifier command. Repeat the flag for multiple verifiers. |
--cwd <path> |
Working directory for adapters and verifiers. |
--json |
Print the full harness result (including the audit trail) as JSON. |
--help |
Show help. |
The prompt may be passed as arguments or piped on stdin. Exit code is 0 on success and 1 on failure.
This repo ships an optional agent skill at skills/auto-reasoning/SKILL.md. It
tells a coding agent (such as Codex) when and how to use the harness, and it keeps the same boundary as the package:
automatic routing may change only reasoning effort, never the model.
For concrete tasks, the skill defaults to adapter-backed Codex execution:
auto-reasoning --adapter codex --json "review this patch for risky edge cases"Classify-only dry-run is reserved for policy inspection, debugging, and meta questions.
- Node.js ≥ 18 (developed and tested on Node 22).
- Codex CLI installed and on
PATHfor thecodexadapter. - An
OPENAI_API_KEY(and a--fixed-model) for theopenaiadapter.
What is auto-reasoning?
A TypeScript harness/CLI that routes an agentic task to a reasoning-effort level (minimal–xhigh) while keeping the
model fixed, then verifies the result and escalates effort only when needed.
Does it switch models? No. It changes only reasoning effort. The model is fixed adapter configuration and is never chosen or mutated by the router.
Can it change reasoning effort mid-response? No. Effort is selected before a run. If a run or verification fails, the harness retries at a higher effort — which keeps behavior observable and reproducible instead of hidden inside a single response.
Which providers does it support?
Out of the box: Codex CLI (model_reasoning_effort) and the OpenAI Responses API (reasoning.effort), plus a dry-run
adapter for classification-only testing. Any other backend can be added via the RunnerAdapter interface.
Does classification call an LLM? No. The default classifier is a deterministic, rule-based scorer, so routing is fast, free, and reproducible.
How is this different from a model router / LLM router?
Model routers change the model (and therefore accuracy, price, and behavior). auto-reasoning holds the model
constant and moves only reasoning depth, so outputs stay comparable across efforts.
Is it production-ready?
It is an early (0.1.x), zero-dependency library with a passing test suite. The API may still change before 1.0.
- It cannot change reasoning effort in the middle of a single model response. It routes before a run and can escalate by retrying at a higher effort.
- The default classifier is heuristic. Tune the policy thresholds and tags for your workload, or supply your own classifier function.
- Codex supports
model_reasoning_effortin configuration and per-run overrides via-c. - The OpenAI Responses API supports
reasoning.effort.
Relevant docs: Codex config · Codex non-interactive · Responses API parameters
Contributions are welcome! Please read CONTRIBUTING.md and our Code of Conduct before opening an issue or pull request. Security reports go through SECURITY.md.
MIT © luckeyfaraday
Keywords: reasoning effort router · agentic AI task routing · reasoning budget · Codex CLI model_reasoning_effort ·
OpenAI Responses API reasoning.effort · task difficulty classifier · automatic effort escalation · audit trail ·
fixed-model routing · TypeScript · Node.js
