Skip to content

fix: make spawn model and effort handling honest - #351

Merged
EtanHey merged 4 commits into
mainfrom
fix/spawn-agent-effort-model
Aug 4, 2026
Merged

fix: make spawn model and effort handling honest#351
EtanHey merged 4 commits into
mainfrom
fix/spawn-agent-effort-model

Conversation

@EtanHey

@EtanHey EtanHey commented Aug 3, 2026

Copy link
Copy Markdown
Owner

Summary

  • expose spawn_agent.effort and pass medium|high|xhigh|ultra to repoGolem as -E
  • reject unsupported effort values before any surface is created; max fails loudly because the current launcher rejects it
  • reject unsupported/non-alias models before mutation, naming the requested model, the launcher default that would actually run, and the accepted set
  • preserve the omitted-model top-tier pin (claude-opus-5[1m]) and its effective-model response

Why

spawn_agent had no reasoning-effort path even though repoGolem supports one. Its model policy also reported arbitrary model strings as effective while the command builder silently dropped unknown aliases.

Verification

  • RED: 4 focused regressions failed before implementation (effort command, invalid effort, invalid model, command builder)
  • focused: 473/473 passed
  • typecheck: passed
  • build: passed
  • pre-PR harness: 63/63 passed
  • full suite: 106 files, 2,379/2,379 passed
  • pre-push gate: contract receipts plus 2,379/2,379 passed
  • real MCP client against the worktree build (CMUXLAYER_FORCE_INPROCESS=1): schema exposed the four-value effort enum; max and fable-5 returned errors without creating panes; a bounded effort:medium spawn returned ok:true and its probe surface was force-stopped and verified absent

Runtime note

The Codex footer rendered its effort label as default, so that footer is not claimed as evidence of medium. Pass-through is verified at the emitted launcher-command boundary; repoGolem's parser maps -E medium to model_reasoning_effort="medium".

Release

No release or reconnect sweep was run. Installed remains 0.4.19; deployment is lead-owned per the brief.


Note

Medium Risk
Stricter spawn validation changes behavior for callers that relied on silent model coercion or unlisted aliases; launch-command shape for Claude sonnet also changed.

Overview
Spawn paths now fail fast on bad model / effort before workspaces, worktrees, or panes are created, and the emitted launcher command matches what policy claims.

Model policy rejects explicit unknown aliases (non-Cursor CLIs) with an error that names the requested model, the default the launcher would run, and the accepted set—instead of reporting a bogus effective model or silently coercing. Claude sonnet is passed to repoGolem as -S rather than -m sonnet; gated Claude aliases no longer get a launcher flag without override.

Codex effort: optional effort on spawn_agent (medium|high|xhigh|ultra) is validated by resolveSpawnEffort and forwarded as -E <effort> on the Codex launch command. Effort on non-Codex CLIs is rejected.

Server tools (spawn_agent, new_worktree_split, spawn_in_workspace) call model/effort resolution up front so invalid spawns never mutate cmux state.

Reviewed by Cursor Bugbot for commit 6a24336. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by CodeRabbit

  • New Features
    • Added an optional effort setting for Codex agent launches.
    • Codex launches now support validated effort levels and pass the selected setting to the CLI.
  • Bug Fixes
    • Improved model validation so unsupported models and effort settings are rejected before launch.
    • Preserved correct model selection across supported CLI integrations.
  • Tests
    • Added coverage for effort forwarding, model validation, and preventing launches when settings are invalid.

Note

Fix spawn model validation and add effort flag support for Codex CLI

  • resolveSpawnModelPolicy in model-policy.ts now throws with a list of accepted models when an unsupported model alias is explicitly requested, instead of silently coercing to a default.
  • Claude launcher uses -S instead of -m sonnet when the model alias is sonnet; other Claude aliases are suppressed when model override is not permitted.
  • SpawnAgentParams and the MCP spawn_agent schema in server.ts accept an optional effort field (validated via resolveSpawnEffort); valid values are appended as -E <effort> to the Codex launch command.
  • Server-side model and effort validation now runs before any workspace or surface creation, so invalid inputs are rejected without side effects.
  • Risk: previously accepted model aliases that were silently coerced (e.g. haiku, opus for Claude without override) now throw errors.

Macroscope summarized 6a24336.

@cursor

cursor Bot commented Aug 3, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_3162dfae-e736-49fe-9e5f-aac41295f4dc)

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Spawn requests now support optional Codex effort values. Model and effort policies validate requests before spawning. Validated effort values reach Codex launch commands, while unsupported models and efforts are rejected.

Changes

Spawn policy and launch flow

Layer / File(s) Summary
Model and effort policy resolution
src/model-policy.ts
Defines supported Codex effort values. Validates CLI-specific efforts and model names during spawn policy resolution.
Effort-aware launch command generation
src/agent-engine.ts
Accepts optional typed effort settings, resolves them during spawning, and adds the Codex effort flag when present.
Server validation and regression coverage
src/server.ts, tests/agent-engine.test.ts, tests/server-agent-tools.test.ts
Adds the optional server argument, validates requests before surface creation, forwards effort, and tests valid and invalid requests.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant spawn_agent
  participant model-policy
  participant agent-engine
  participant CLI
  Client->>spawn_agent: Request model and optional effort
  spawn_agent->>model-policy: Validate model and effort
  model-policy-->>spawn_agent: Return validated policy
  spawn_agent->>agent-engine: Start agent with effort
  agent-engine->>CLI: Launch Codex with effort flag
Loading

Poem

A rabbit checked the effort row,
Then watched the launch command grow.
Models that failed stayed at the gate,
While medium flags made launch great.
“Hop!” said Bun, “the checks now flow.”

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes to spawn model validation and effort handling.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/spawn-agent-effort-model

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a1646e83a4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/model-policy.ts
Comment on lines +242 to +244
throw new Error(
`Unsupported model "${requestedModel}" for cli "${cli}": without a valid alias, the launcher would actually run "${defaultModel}". Accepted models: ${acceptedModels.join(", ")}. No agent was spawned.`,
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preflight all models before aggregate mutations

When spawn_in_workspace contains an unsupported model, this new exception is reached only from engine.spawnAgent() after src/server.ts has created the workspace, and if the invalid entry follows a valid one, earlier agents have already been spawned. The catch path reports the failure but does not roll those mutations back, so the error's claim that no agent was spawned is false and the nominally atomic tool leaves a partial team; new_worktree_split similarly prepares a worktree before reaching this validation. Validate every requested model at each tool boundary before creating workspaces/worktrees or starting the spawn loop.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5c38c8f. new_worktree_split now validates the requested model before worktree preparation, and spawn_in_workspace validates every normalized agent model before workspace/surface mutation. Added regressions proving no worktree command, workspace creation, or split occurs on invalid input. Exact-head verification: 2,381/2,381 full tests, 63/63 pre-PR checks, build and typecheck green.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/model-policy.ts`:
- Around line 231-251: The rejected-model path in the model policy flow must not
include override-only values in its accepted-model list. Update
acceptedModelNames or the logic around resolveLaunchModelFlag in the validation
block so the error lists only aliases passable without MODEL_OVERRIDE_ENV,
excluding values such as gpt-5.5-xhigh and sonnet while preserving valid
launcher-supported aliases.

In `@tests/server-agent-tools.test.ts`:
- Around line 670-709: Update the “spawn_agent rejects an unsupported effort”
test to validate the registered input schema via spawn.inputSchema.parse, then
assert the generic invalid-enum error for “max” without invoking the handler;
alternatively, use a reachable non-Codex handler case such as Claude or Gemini
with medium effort. Keep the assertion that no “new-split” command is created
only if the handler is actually invoked.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ef37364a-9df3-4b46-8fdb-a595395c2279

📥 Commits

Reviewing files that changed from the base of the PR and between 8a2ae0f and a1646e8.

📒 Files selected for processing (5)
  • src/agent-engine.ts
  • src/model-policy.ts
  • src/server.ts
  • tests/agent-engine.test.ts
  • tests/server-agent-tools.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (2)
  • GitHub Check: test
  • GitHub Check: Macroscope - Correctness Check
🧰 Additional context used
📓 Path-based instructions (5)
src/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

src/**/*.ts: Build the project with TypeScript (tsc) and keep source code compatible with Node 20+ and Zod-based typing.
Use the ok(data) and err(error) helpers for consistent MCP tool responses.
All MCP tool handlers must return { content: TextContent[], structuredContent?, isError? }.

Files:

  • src/model-policy.ts
  • src/server.ts
  • src/agent-engine.ts
tests/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

tests/**/*.test.ts: Mirror source layout in tests (src/foo.ts -> tests/foo.test.ts).
Do not add integration tests that require a running cmux instance; tests should be fully mocked.

Files:

  • tests/agent-engine.test.ts
  • tests/server-agent-tools.test.ts
tests/**/*agent-engine*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Agent engine tests should use 1-second timeouts for state-change detection.

Files:

  • tests/agent-engine.test.ts
src/server.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Register all MCP tools in server.ts, including the 33 tool handlers, and conditionally skip agent-lifecycle tools when skipAgentLifecycle: true.

Files:

  • src/server.ts
src/agent-engine.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Implement agent lifecycle behavior in agent-engine.ts, including spawning, monitoring, and quality tracking.

Files:

  • src/agent-engine.ts
🧠 Learnings (1)
📚 Learning: 2026-03-15T10:42:35.917Z
Learnt from: EtanHey
Repo: EtanHey/cmuxlayer PR: 1
File: tests/quality-tracking.test.ts:171-200
Timestamp: 2026-03-15T10:42:35.917Z
Learning: In tests/quality-tracking.test.ts for the cmuxlayer project, ensure that at or above 80% context quality degradation, behavior depends on depth: depth-0 agents receive a /compact command; depth > 0 agents are killed and logged (kill + log). Respawn of non-root agents is out of scope for v1. Treat the design doc quality tracking section as the authoritative source for this behavior, and align test expectations accordingly.

Applied to files:

  • tests/agent-engine.test.ts
  • tests/server-agent-tools.test.ts
🔇 Additional comments (7)
src/model-policy.ts (2)

4-10: LGTM!


139-164: LGTM!

src/agent-engine.ts (2)

98-100: LGTM!

Also applies to: 151-151, 738-743, 757-765, 4768-4768


4551-4558: 🗄️ Data Integrity & Integration

No change needed. The original launch command is captured in originalLaunchCommandsBySurface before boot-prompt delivery and passed into the post-update relaunch fallback, so the resolved Codex effort cannot be lost there. AgentRecord and SpawnAgentResult do not reserve an effort field.

src/server.ts (1)

26-30: LGTM!

Also applies to: 8589-8594, 8700-8701, 8803-8803

tests/agent-engine.test.ts (1)

4238-4280: LGTM!

Also applies to: 8536-8537, 10301-10308

tests/server-agent-tools.test.ts (1)

549-549: LGTM!

Also applies to: 563-563, 596-596, 711-734

Comment thread src/model-policy.ts
Comment thread tests/server-agent-tools.test.ts
@cursor

cursor Bot commented Aug 3, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_f691847f-e15e-4ed0-aa9b-42c3486ec2f8)

@cursor

cursor Bot commented Aug 3, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_ba9c2b6a-e85c-4e65-8dcf-07ec29db9ddd)

@cursor

cursor Bot commented Aug 3, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_16789ec5-fff9-4abc-828c-92c068493b84)

@EtanHey
EtanHey force-pushed the fix/spawn-agent-effort-model branch from 8839906 to 6a24336 Compare August 4, 2026 13:58
@cursor

cursor Bot commented Aug 4, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_795357ea-7c5a-4dd5-b782-b71e8e257b54)

@EtanHey
EtanHey merged commit a27ab74 into main Aug 4, 2026
4 of 5 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6a243369c0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/model-policy.ts
Comment on lines +277 to +281
launcherModel === null
) {
const acceptedModels = acceptedModelNames(cli, overrideAllowed);
throw new Error(
`Unsupported model "${requestedModel}" for cli "${cli}": without a valid alias, the launcher would actually run "${defaultModel}". Accepted models: ${acceptedModels.join(", ")}. No agent was spawned.`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the public opus spawn alias

When REPOGOLEM_ALLOW_MODEL is unset, callers that explicitly request Claude model: "opus" now reach this branch and fail, even though opus was accepted before this commit and the deployed Pages demo still presents successful spawn_agent(..., model="opus") calls in landing/index.html:1074 and landing/index.html:1538. This is especially disruptive for the legacy aggregate tools whose nested model remains required; normalize opus to the default Claude launch with no model flag rather than rejecting an established tool input.

AGENTS.md reference: AGENTS.md:L44-L47

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant