Pass spawn model through MCP, SDK, and broker to the launched CLI#1076
Conversation
The add_agent MCP `model` arg was cosmetic: it was stuffed into agent metadata and never reached the broker, so relay-spawned workers always booted with the session default regardless of the requested model. - agent-relay-mcp.ts: pass `model` as a first-class spawn field instead of burying it in metadata. - sdk messaging types/normalize: carry `model` on the agentSpawnRequested event so TS consumers see it. - broker relaycast_events.rs: build AgentSpec with the event's `model` (blank treated as unset) instead of hardcoding `None`. worker.rs already renders `--model` from spec.model, so this is the last gap. BLOCKED ON: a relaycast release. relay consumes the published @relaycast/sdk (^2.5.1) and the `relaycast` crate, whose spawn types do not yet carry `model`. The companion change is AgentWorkforce/relaycast PR (branch fix/spawn-model-passthrough). Once relaycast is published with `model`, bump @relaycast/sdk + the `relaycast` crate pin here; the CLI typecheck and broker build pass after that. Draft until then. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR threads an optional ChangesAgent spawn model parameter threading
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsGit: Failed to clone repository. Please run the 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. Comment |
There was a problem hiding this comment.
Code Review
This pull request updates the agent relay and broker to propagate the requested model as a first-class field from the CLI and SDK through to the launched CLI. Feedback points out that the JSON fallback path for agent.spawn_requested in the broker runtime still hardcodes model: None and needs to be updated to extract and propagate the model consistently.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| model, | ||
| cwd: None, | ||
| team: None, | ||
| shadow_of: None, |
There was a problem hiding this comment.
While this primary path now correctly propagates the model field to AgentSpec, the JSON fallback path for agent.spawn_requested (around line 494) still hardcodes model: None and does not extract the model from the raw JSON. To ensure consistency and prevent the requested model from being lost when the fallback path is triggered, we should also extract model from agent_obj in the fallback block and pass it to AgentSpec.
relaycast shipped the spawn `model` passthrough: - npm @relaycast/sdk + @relaycast/types at 2.6.0 - relaycast crate at 2.4.0 Bump packages/cli to @relaycast/sdk ^2.6.0 and the broker crate pin to =2.4.0 so `model` is available end-to-end. Verified: packages/cli tsc clean (the prior `TS2353: 'model' does not exist` is gone) and `cargo check -p agent-relay-broker` builds against relaycast 2.4.0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@crates/broker/src/runtime/relaycast_events.rs`:
- Around line 207-210: The fallback path for agent.spawn_requested currently
drops the requested model and the primary path doesn't trim whitespace; ensure
the model is normalized (trim whitespace and treat empty/blank as None) and
propagated into AgentSpec on both paths. Specifically, compute a single
normalized model value from event.agent.model (e.g., map to trimmed string then
filter out empty strings) and use that normalized value when constructing
AgentSpec in the normal branch and in the raw JSON fallback branch so the model
is not lost; update the code that builds AgentSpec (the AgentSpec.model field)
to use this shared normalized model. Also apply the same fix to the other
occurrence around the 484-492 region.
🪄 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: CHILL
Plan: Pro Plus
Run ID: fe884e55-a4af-48d2-b3ca-5c3a4fa7875b
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.lockpackage-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (6)
crates/broker/Cargo.tomlcrates/broker/src/runtime/relaycast_events.rspackages/cli/package.jsonpackages/cli/src/cli/agent-relay-mcp.tspackages/sdk/src/messaging/normalize.tspackages/sdk/src/messaging/types.ts
| // Carry the requested model through so the launched CLI is | ||
| // started with `--model` (see worker.rs). An empty/blank | ||
| // model is treated as unset. | ||
| let model = event.agent.model.filter(|value| !value.trim().is_empty()); |
There was a problem hiding this comment.
Fallback spawn path drops model, and model values are not normalized consistently.
When agent.spawn_requested falls back to raw JSON parsing, AgentSpec is still built with model: None, so the requested model is lost on that path. Also, the primary path only checks blankness but does not trim whitespace before forwarding. This breaks model pass-through for fallback events and can pass malformed model args.
Suggested fix
- let model = event.agent.model.filter(|value| !value.trim().is_empty());
+ let model = event
+ .agent
+ .model
+ .and_then(|value| {
+ let trimmed = value.trim();
+ (!trimmed.is_empty()).then(|| trimmed.to_string())
+ });
...
let channel = agent_obj
.and_then(|a| a.get("channel"))
.and_then(Value::as_str)
.map(String::from);
+ let model = agent_obj
+ .and_then(|a| a.get("model"))
+ .and_then(Value::as_str)
+ .map(str::trim)
+ .filter(|value| !value.is_empty())
+ .map(String::from);
...
- model: None,
+ model,Also applies to: 484-492
🤖 Prompt for 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.
In `@crates/broker/src/runtime/relaycast_events.rs` around lines 207 - 210, The
fallback path for agent.spawn_requested currently drops the requested model and
the primary path doesn't trim whitespace; ensure the model is normalized (trim
whitespace and treat empty/blank as None) and propagated into AgentSpec on both
paths. Specifically, compute a single normalized model value from
event.agent.model (e.g., map to trimmed string then filter out empty strings)
and use that normalized value when constructing AgentSpec in the normal branch
and in the raw JSON fallback branch so the model is not lost; update the code
that builds AgentSpec (the AgentSpec.model field) to use this shared normalized
model. Also apply the same fix to the other occurrence around the 484-492
region.
Problem
The
add_agentMCPmodelarg was cosmetic. It was stuffed into agent metadata and never reached the broker, so relay-spawned workers always booted with the session default (e.g. Opus) regardless of the requested model. Verified 2026-06-10: spawning withmodel: "haiku"(and the full id) still booted Opus.Change
agent-relay-mcp.ts— passmodelas a first-class spawn field instead of burying it inmetadata.sdk/messaging(types + normalize) — carrymodelon theagentSpawnRequestedevent so TS consumers see it.broker/runtime/relaycast_events.rs— buildAgentSpecwith the event'smodel(blank treated as unset) instead of hardcodingmodel: None.worker.rsalready renders--modelfromspec.model, so this closes the last gap.@relaycast/sdk→^2.6.0(packages/cli) and therelaycastcrate →=2.4.0(broker), the published versions that carrymodel.Companion / dependency (now landed)
Gating change AgentWorkforce/relaycast#180 is merged + published:
@relaycast/types+@relaycast/sdkat 2.6.0relaycastcrate at 2.4.0Verified
packages/clitsc --noEmitclean — the priorTS2353: 'model' does not existis gone now that@relaycast/sdk@2.6.0is resolved.cargo check -p agent-relay-brokerbuilds againstrelaycast 2.4.0.Note
Main-process/broker change — takes effect after the broker is rebuilt. Post-merge sanity: spawn a worker via
add_agentwithmodelset and confirm--modelreaches the launched CLI.🤖 Generated with Claude Code