Skip to content

About

Which model actually answered your coding agent, from your own machine: Claude Code and Codex transcripts read locally for model switches and the notices before them, reasoning-token spikes at fixed values, and context-ceiling changes. Sends nothing.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

which-model

Which model actually answered your coding agent, from your own machine.

npx --allow-git=root github:agentwares/which-model

which-model on synthetic history

The picture is the real output of npx --allow-git=root github:agentwares/which-model demo, which runs on synthetic history generated for the demo, not anyone's usage. It is regenerated by pnpm screenshot and a test fails if it drifts from what the CLI prints.

which-model reads the transcripts Claude Code and Codex already keep on your machine and tells you:

  • which model answered Codex, as far as Codex records it: its rollouts name only the model it requested, so which-model reads the one place Codex writes the model the server reported, its own log, and lists a Codex reroute only where that log shows one (see below);
  • which models answered, by day and by session;
  • switches nothing you did explains: a Claude Code session whose responses moved to another model with no /model from you, and what the transcript records just before it (a fallback notice the client wrote, a client update, or nothing), plus how many responses and hours the other model then served;
  • the reasoning-token distribution per model, with spikes at fixed values such as the 516 / 1,034 / 1,552 clusters people found in Codex;
  • step changes in reasoning tokens per response, tokens per task, the largest prompt of the day and Claude Code's auto-compaction point, and every change in the context window Codex reports, with the date and the client version where each starts.

It is MIT, makes no network request, has no telemetry and needs no account. Its output holds model ids, client versions, dates, counts and session ids, never a prompt, a response, a file path or a project name, so you can paste it into an issue as it is.

Commands

npx --allow-git=root github:agentwares/which-model                       # all history on this machine
npx --allow-git=root github:agentwares/which-model --since 30d           # or --since 2026-07-01, --since 12w
npx --allow-git=root github:agentwares/which-model --session 1a2b3c4d    # one session in order (any unique prefix of its id)
npx --allow-git=root github:agentwares/which-model --client claude-code  # or codex
npx --allow-git=root github:agentwares/which-model --json                # the whole report, machine-readable
npx --allow-git=root github:agentwares/which-model demo                  # the report on synthetic history (reads nothing of yours)

Also --claude-dir, --codex-dir, --no-cache and --quiet.

What each client records

Client Where Model it writes Also read
Claude Code ~/.claude/projects/**/*.jsonl (or $CLAUDE_CONFIG_DIR/projects) message.model: the model that answered each response output_tokens_details.thinking_tokens; isSidechain/agentId (subagents); your /model output; model_refusal_fallback notices; compact_boundary points
Codex CLI ~/.codex/sessions/** and archived_sessions/ (or $CODEX_HOME) turn_context.model: the model it requested, never the answer's reasoning_output_tokens; model_context_window; a model_reroute event, should a version ever write one to a rollout
Codex's log ~/.codex/logs_*.sqlite (read-only; Node 22.13 or later) server reported model X, and while requested model was Y only those lines: the two model ids, the time and the thread id

Checked on 8 October 2026 against Claude Code transcripts written by 2.1.170–2.1.286, Codex rollouts written by 0.144–0.159 and Codex's source at rust-v0.162.0, reading key names, model ids, counts and dates only. The usage, models, versions and sessions come from seatledger's readers, which which-model depends on rather than copies; which-model adds only the fields in the last column. The Claude Agent SDK writes its sessions into the same transcripts as Claude Code (entrypoint sdk-ts, sdk-py or sdk-cli), so they are read and counted the same way.

Three things follow:

  • A Claude Code reroute is visible: the model field changes between two responses of one session. Subagents run on their own models by design, so only the main thread counts. The same holds for the Claude Agent SDK's sessions.
  • A Codex reroute is not visible in a rollout. Codex 0.162.0 has a reroute event (model_reroute: the model requested, the model that answered, and the reason, high_risk_cyber_activity), but its rollout policy drops it as transient. What Codex keeps is one log line per turn in its log database: server reported model X (matches requested model), or, when they differ, server reported model X while requested model was Y. which-model reads only those lines, keeps their model ids past Codex's pruning, and lists a reroute only where one is logged. When the log has none, or cannot be read, it says so.
  • The OpenAI Agents SDK keeps no local log by default: its default exporter sends traces to OpenAI's dashboard (@openai/agents 0.20, openai-agents 0.23), so there is nothing to read.

What the vendors show (8 October 2026)

  • Claude Code documents that a session can fall back to another model, and shows a notice naming both models when it does (model configuration). Recent versions improved that notice (2.1.286: it says when a fallback dropped the context window from 1M to 200K tokens). There is no documented per-response label of the model that answered, and nothing that counts how long a session stayed on the other model. anthropics/claude-code#78888 (18 July 2026, open on 8 October) asks for a persistent indicator.
  • Codex records the model it requested and the context window it was given in its rollouts. It checks the model the server reports on every turn, warns you when it differs, and logs that line to its own log database, which it prunes; it writes no answering model to a rollout.

which-model adds the history: when, on which version, for how many responses, across every session on the machine.

How it decides

  • A switch is two consecutive main-thread responses in one Claude Code session answered by different models. It is labelled by what the transcript records between them: your /model (not listed as a finding), a fallback notice, a client relaunch on another version, or nothing. "Nothing recorded" is not proof of a reroute: a model picked in a way the transcript does not record looks the same, and the output says so.
  • Answered by a different model than requested counts responses after a requested model is recorded (your /model, or a fallback notice's original model) whose model differs from it.
  • A reasoning spike is an exact count of at least 64 tokens that holds at least 1% of a model's responses (and at least 10) and at least 8x the average count of the values within 5% either side. It is consistent with a cap or budget at that value; it cannot show that reasoning was cut short.
  • Step changes use seatledger's rolling baseline (detectSteps, the method behind seatledger rates): complete days with at least 20 responses, the median of up to 7 active days before against up to 7 from the day, at least 30% apart, three quarters of the days on their own side, and more than 3x the day-to-day spread. Each says what moved and what it is consistent with, and whether it started on the first day of a new client version. It never names a cause: it sees your machine, not the vendor's servers.

What people reported

  • openai/codex#30364, opened 27 June 2026: a user aggregated Codex's own token metadata and found gpt-5.5 reasoning output clustered at exactly 516, 1,034 and 1,552 tokens. Closed as completed on 23 August 2026; later comments ask why. 289 👍 and 188 comments on 8 October.
  • anthropics/claude-code#78888, opened 18 July 2026: after a fallback notice a session moved from claude-fable-5 to claude-opus-4-8 for about 840 messages over about 23 hours while the UI still showed Fable 5, found from the transcripts' per-message model field. Open on 8 October.
  • openai/codex#32806, 13 July 2026: the context window Codex reported for gpt-5.6-sol fell from 353,400 to 258,400 tokens.
  • anthropics/claude-code#83510, 3 August 2026: a measured quality-regression report that includes under-disclosed fallback from Fable 5 to Opus 4.8. #68780, 16 June 2026: a reasoning-degradation report on Opus 4.8 and 5.

Each was found by hand from the same fields which-model reads.

Your whole team

which-model is one machine. seatledger's hosted team ledger shows the whole team's model mix, by model and by day, free for up to 3 developers. After the human output a terminal shows one dim line pointing there, at most once a day per machine, never with --json or --session. --quiet or WHICH_MODEL_QUIET=1 turns it off. It is text printed on your screen: nothing is sent.

What it keeps

  • Writes only to ~/.which-model (or $WHICH_MODEL_HOME): cache-v1/ (seatledger's counts per transcript), signals-v2/ (reasoning counts, model ids, each session's entrypoint and the times of model changes and fallback notices per transcript), codex-served-v1.json (the model ids, times and thread ids of Codex's "server reported model" lines, kept past Codex's pruning) and hint.json (the day the team line was last shown). The caches mean a second run reads only what changed, and keep history the clients have since deleted. Delete the directory to forget it.
  • Never stores or prints prompt, response, tool or file content.

As a library

import { collect, analyze, whichModelHome } from "which-model";
import { sourceDirs } from "seatledger";

const input = await collect({ dirs: sourceDirs(), home: whichModelHome(), now: Date.now() });
const { switches, reasoning, steps, windows } = analyze(input);

Develop

pnpm install && pnpm test
node dist/cli.js demo
pnpm screenshot   # regenerate docs/screenshot.svg after changing the output
pnpm icon         # redraw the plugin icon after changing distribution/icon.svg

MIT © agentwares contributors.

About

Which model actually answered your coding agent, from your own machine: Claude Code and Codex transcripts read locally for model switches and the notices before them, reasoning-token spikes at fixed values, and context-ceiling changes. Sends nothing.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages