A Claude Code mod that picks the model and reasoning effort of every subagent, so a review runs on Opus and a file search doesn't.
Recorded from a real Claude Code 2.1.295 session on Windows 11 with the mod installed from this repo (frames cropped, captions added). The band, full size:
When the agent starts a subagent, the tuner settles its model and effort: by asking you, by a recommendation for the kind of task, or by your saved default.
Inside Claude Code (2.1.295 or later):
/plugin install subagent-tuner --marketplace Kruhlikau/subagent-tuner
Answer y to add the marketplace and pick the user scope. It starts working in that session.
Other ways: two steps, the shell, or a local clone
/plugin marketplace add Kruhlikau/subagent-tuner
/plugin install subagent-tuner@subagent-tuner
claude plugin install subagent-tuner --marketplace Kruhlikau/subagent-tunergit clone https://github.com/Kruhlikau/subagent-tuner
claude --plugin-dir ./subagent-tunerUpdate with /plugin marketplace update subagent-tuner, then /plugin update subagent-tuner@subagent-tuner.
Remove with /plugin uninstall subagent-tuner@subagent-tuner.
The band above the prompt holds the mode and your saved default. Click Manual or Auto to
switch, click the model or the effort to cycle it (rec. means "use the recommendation"),
Reset to clear the default. Both are kept across sessions.
Manual (the default after install) asks before a subagent starts. On a terminal 144 columns wide or more the question is a pane beside the transcript:
general-purpose · explore wide
Model: haiku ▾ Effort: low ▾
r: Run d: Run and save as default c: Cancel
On a narrower terminal it is a short chain of dialogs. A dismissed question starts the subagent with what was shown; nothing is ever held back.
Manual is the mode right after install, so every subagent launch asks first. The pane goes ahead with the live selection after ten minutes without an answer; the dialogs wait until you answer or dismiss them. Switch to Auto before you leave a session to run on its own.
Auto never asks. Your saved default wins, even over a model or effort the agent set itself
(say, a rule in CLAUDE.md that makes it pass model: "opus"). A field left at rec. keeps
what the call set, else takes the recommendation (for a custom agent, see below: none). A toast says what was applied:
Subagent (overridden) -> sonnet/high.
For built-in agents (general-purpose, Explore, Plan and the like):
| Task kind (from the subagent's type, else its description) | Model | Effort |
|---|---|---|
| review, audit, verify, adversarial, security | opus |
high |
| implement, build, fix | sonnet |
medium |
| explore, search, research | haiku |
low |
A prompt longer than 4,000 characters gets one step more effort. Any other task gets no recommendation and inherits the session's model and effort.
A custom agent is left to its own definition. The mod sees only the Agent call, not the agent's
definition file, so a model or effort set in its frontmatter is invisible to it. It does see which agent
types Claude Code offers, and whether each is built in. For an agent you or a plugin defined, with no
saved default, it recommends nothing, so a custom code-reviewer pinned to sonnet stays on sonnet:
Auto leaves the call untouched, and Manual's pane starts on inherit. It does not read the pinned
value, so the pane shows inherit, not sonnet. A saved default still applies to it, and so does
a model or effort you pick in Manual's pane. Built-in agents such as general-purpose get the
recommendation above. Claude Code can announce a type after the call has been made; if the type then
turns out to be built in, Auto still recommends the model for it (not the effort, which the spawn
cannot take), so a late announcement costs only the effort recommendation.
claude -pand SDK hosts: nothing is changed, so scripted runs and evals measure what they ask for.- Forks: never touched; a fork ignores model and effort anyway.
- VS Code extension: it can't show the band there, so it never asks and behaves as Auto.
- Custom agents: with no saved default their model and effort are left to the agent's own definition.
- Manual: a call that already set both its model and its effort goes through as set.
- Reads each Agent call's subagent type, description, model and effort, and the length of its prompt, and which agent types Claude Code offers and whether each is built in (never the agent definitions). It never sends anything anywhere: no network calls.
- Changes only the
modelandeffortfields of Agent calls. - Stores the mode and the saved default in Claude Code's own plugin store.
- Runs
sh(macOS, Linux) orpowershell.exe(Windows), only to wait for your answer in the pane: once to check which shell exists, then per open pane one process to remove the probe file below and one to wait. - Writes an empty sentinel file to
.waits/in the plugin's own folder when you answer in the pane; the waiting process deletes it. Before a pane opens it writes and removes an empty.probefile there, to be sure the folder takes a write.
Claude Code 2.1.295 or later (mods). Tested on 2.1.295, 2.1.296 and 2.1.300 on macOS and on Windows 11 with Git for Windows' default settings.
- Dialogs instead of the pane: the terminal is narrower than 144 columns (widen it or zoom out), or the plugin's
.waits/folder cannot be written (the toast says why). - Subagents still on Opus: you are in Manual and the agent set the model itself, or Auto has no saved default for the model. Switch to Auto and set the default.
- An update didn't change anything: run the update commands above. Claude Code runs the installed copy from its cache, keyed by version.
- Two bands or two toasts: the mod is loaded twice, for example installed and also passed with
--plugin-dir. Keep one.
git clone https://github.com/Kruhlikau/subagent-tuner && cd subagent-tuner
claude plugin validate --strict .
claude plugin test .
claude --plugin-dir .hooks/register.tsx holds every call on $; the other modules are pure. The tests run against a
fake $ in hooks/harness.ts. Once Claude Code has loaded the mod, .claude-plugin/types/ holds
the API types and npx tsc -p . type-checks it. Bump version in .claude-plugin/plugin.json with
every change: installed copies are cached by version.

