[Feature] Set reasoning effort per subagent in rlm() #1506
CEOofSaturdays
started this conversation in
Feature requests
Replies: 1 comment
|
Good idea to add effort here! I'll get that in. |
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Area
Agent core, Coding agent and CLI
Problem
I fan work out from one parent turn: a cheap repo scout, a deep architecture review, a mechanical edit. Every one of those children runs at whatever thinking level the parent session happens to be on, and I can't change that per child.
rlm.run takes two kwargs, name and model. Anything else fails at admission:
await rlm("review the auth flow", name="auth-reviewer", model="openai-codex/gpt-5.6-luna", effort="max")
RuntimeError: Unsupported rlm.run kwargs: effort
I got the same rejection for reasoning_effort, reasoningEffort, effort_level, thinking, verbosity, and model_effort. The allowlist is in packages/coding-agent/src/core/agent-session.ts, _startRlmChildRun:
const { name: rawName, model: rawModel, ...unsupported } = kwargs;
const unsupportedKwargs = Object.keys(unsupported);
if (unsupportedKwargs.length > 0) {
throw new Error(
Unsupported rlm.run kwargs: ${unsupportedKwargs.sort().join(", ")});}
The child's effort is the parent's level, clamped to the child model, in _createRlmSubagentRuntimeOptions in the same file:
thinkingLevel: clampThinkingLevel(options.model, this.thinkingLevel) as ThinkingLevel,
So model selection is per child and effort is per session. The only way to get a max-effort child today is to move the whole parent session with /effort first. That changes the parent's own reasoning, and it can't give two children spawned in the same turn different levels.
Two costs I hit in practice. Delegating from a max-effort parent makes trivial children think hard and burn reasoning tokens. Delegating from a low-effort parent starves the one child that needed the depth.
Agents View already prints name . model/effort per subagent since #1479. That effort column can never differ from the parent's, which is what made me go looking for the kwarg in the first place.
I checked both the installed 0.7.3 bundle and current main. Same code in both.
Proposed direction
One optional kwarg on rlm.run:
handle = await rlm(
"Review the auth flow for security issues",
name="auth-reviewer",
model="openai-codex/gpt-5.6-luna",
thinking="max",
)
What I'd want from it:
Accept the canonical ThinkingLevel names already behind /effort: off, minimal, low, medium, high, xhigh, max.
Validate against the resolved child model's levels at admission, and fail the spawn on an unsupported one instead of quietly clamping. That matches how an unavailable model= already fails, and a silent clamp would be worse than an error because the parent has no way to see it.
Leave the default alone. No thinking= means today's behavior, inherit from the parent and clamp to the child model.
Echo the resolved level back on RLMSpawnHandle next to model, and expose each model's supported levels from rlm.find_models(), so a parent can pick a valid level in code rather than guess.
This rides the same admission path that already resolves model=. No daemon protocol change, no new resolver, no change to ModelRegistry or the provider layer.
On naming: I've written thinking= because ThinkingLevel is the internal type, but the user-facing command is /effort, so effort= may read better from the kernel. I don't have a strong preference.
Alternatives considered
Switch the parent with /effort before each spawn. This is what I do now. It doesn't work for parallel fan-out in a single turn, and it drags the parent's own reasoning along with it.
Pick a heavier model as a stand-in for effort, say openrouter/openai/gpt-5.6-luna-pro instead of gpt-5.6-luna. That confuses capability with compute, and the equivalent pairing doesn't exist for every provider.
Route or virtual-model resolution, as proposed in #1065 and #1138. I'm not asking for that. Both were closed, and I think correctly: a semantic router is a second model-routing abstraction, while this is one field on a call that already resolves a model.
Reusable harness subagent specs carrying a canonical thinking preference, as in #1059. Useful, but it's a bigger surface than I need, and none of it helps an ad hoc spawn.
Additional context
Environment: prime-agent 0.7.3 from npm, Node 22, macOS on Apple Silicon, daemon plus TUI, parent session on openai-codex/gpt-5.6-sol.
The model= half works well. A child spawned from that Sol parent with model="openai-codex/gpt-5.6-luna" ran on Luna, replied over agent_message, and completed. Effort is the only piece I couldn't reach.
Related:
#1479 added the per-subagent model/effort display that can't vary today.
#1059 was a closed PR bundling per-task thinking with harness specs, Markdown profile frontmatter, and an rlmAllowedThinkingLevels setting. That setting doesn't exist on main. This request is only the spawn kwarg and the handle echo.
#1065 and #1138 were closed proposals for route and virtual-model resolution.
#1011 is the same gap for child model choice, with the same "switch the parent chat" workaround, now solved by model=.
If this lands, packages/coding-agent/docs/rlm.md and docs/rlm-runtime.md both need a line, since both currently describe the child as inheriting the parent's thinking configuration.
Happy to post the full probe transcript, the kwarg rejections, the model catalog, and the Luna child run.
All reactions