Fix sessions_spawn Google/Gemini model routing#36154
Fix sessions_spawn Google/Gemini model routing#36154Octane0411 wants to merge 1 commit intoopenclaw:mainfrom
Conversation
Greptile SummaryThis PR fixes Gemini/Google model routing in the Key changes:
Issues found:
Confidence Score: 2/5
Last reviewed commit: c91556c |
| const resolvedModelOverride = params.modelOverride | ||
| ? normalizeSubagentSpawnModelSelection({ | ||
| cfg: params.cfg, | ||
| model: normalizeModelSelection(params.modelOverride) ?? "", | ||
| defaultProvider: runtimeDefault.provider, | ||
| }) | ||
| : undefined; |
There was a problem hiding this comment.
Empty string short-circuits the ?? fallback chain. When params.modelOverride is whitespace-only (e.g. " "), normalizeModelSelection returns undefined, then ?? "" converts it to "". Since normalizeSubagentSpawnModelSelection returns "" for empty input, resolvedModelOverride becomes "" — a truthy-but-empty string that bypasses the ?? operator's fallback logic (which only skips null/undefined). This causes the function to return "" instead of falling through to normalizedConfiguredModel or normalizedPrimaryModel.
To fix, check the normalizeModelSelection result before passing to normalizeSubagentSpawnModelSelection:
| const resolvedModelOverride = params.modelOverride | |
| ? normalizeSubagentSpawnModelSelection({ | |
| cfg: params.cfg, | |
| model: normalizeModelSelection(params.modelOverride) ?? "", | |
| defaultProvider: runtimeDefault.provider, | |
| }) | |
| : undefined; | |
| const resolvedModelOverride = (() => { | |
| const m = normalizeModelSelection(params.modelOverride); | |
| if (!m) return undefined; | |
| return normalizeSubagentSpawnModelSelection({ | |
| cfg: params.cfg, | |
| model: m, | |
| defaultProvider: runtimeDefault.provider, | |
| }); | |
| })(); |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/model-selection.ts
Line: 417-423
Comment:
Empty string short-circuits the `??` fallback chain. When `params.modelOverride` is whitespace-only (e.g. `" "`), `normalizeModelSelection` returns `undefined`, then `?? ""` converts it to `""`. Since `normalizeSubagentSpawnModelSelection` returns `""` for empty input, `resolvedModelOverride` becomes `""` — a truthy-but-empty string that bypasses the `??` operator's fallback logic (which only skips `null`/`undefined`). This causes the function to return `""` instead of falling through to `normalizedConfiguredModel` or `normalizedPrimaryModel`.
To fix, check the `normalizeModelSelection` result before passing to `normalizeSubagentSpawnModelSelection`:
```suggestion
const resolvedModelOverride = (() => {
const m = normalizeModelSelection(params.modelOverride);
if (!m) return undefined;
return normalizeSubagentSpawnModelSelection({
cfg: params.cfg,
model: m,
defaultProvider: runtimeDefault.provider,
});
})();
```
How can I resolve this? If you propose a fix, please make it concise.| const normalizedPrimaryModel = resolveAgentModelPrimaryValue(params.cfg.agents?.defaults?.model) | ||
| ? normalizeSubagentSpawnModelSelection({ | ||
| cfg: params.cfg, | ||
| model: | ||
| normalizeModelSelection( | ||
| resolveAgentModelPrimaryValue(params.cfg.agents?.defaults?.model), | ||
| ) ?? "", | ||
| defaultProvider: runtimeDefault.provider, | ||
| }) | ||
| : undefined; |
There was a problem hiding this comment.
resolveAgentModelPrimaryValue(params.cfg.agents?.defaults?.model) is evaluated twice — once in the guard condition (line 435) and once inside the normalizeSubagentSpawnModelSelection call (lines 440-441). Extract it to a variable to avoid the redundant call and improve clarity:
| const normalizedPrimaryModel = resolveAgentModelPrimaryValue(params.cfg.agents?.defaults?.model) | |
| ? normalizeSubagentSpawnModelSelection({ | |
| cfg: params.cfg, | |
| model: | |
| normalizeModelSelection( | |
| resolveAgentModelPrimaryValue(params.cfg.agents?.defaults?.model), | |
| ) ?? "", | |
| defaultProvider: runtimeDefault.provider, | |
| }) | |
| : undefined; | |
| const primaryModelValue = resolveAgentModelPrimaryValue(params.cfg.agents?.defaults?.model); | |
| const normalizedPrimaryModel = primaryModelValue | |
| ? normalizeSubagentSpawnModelSelection({ | |
| cfg: params.cfg, | |
| model: normalizeModelSelection(primaryModelValue) ?? "", | |
| defaultProvider: runtimeDefault.provider, | |
| }) | |
| : undefined; |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/model-selection.ts
Line: 435-444
Comment:
`resolveAgentModelPrimaryValue(params.cfg.agents?.defaults?.model)` is evaluated twice — once in the guard condition (line 435) and once inside the `normalizeSubagentSpawnModelSelection` call (lines 440-441). Extract it to a variable to avoid the redundant call and improve clarity:
```suggestion
const primaryModelValue = resolveAgentModelPrimaryValue(params.cfg.agents?.defaults?.model);
const normalizedPrimaryModel = primaryModelValue
? normalizeSubagentSpawnModelSelection({
cfg: params.cfg,
model: normalizeModelSelection(primaryModelValue) ?? "",
defaultProvider: runtimeDefault.provider,
})
: undefined;
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c91556c06d
ℹ️ About Codex in GitHub
Codex has been enabled to automatically 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 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const selectedProvider = normalizeProviderId(inferredProvider ?? params.defaultProvider); | ||
| const selectedModel = normalizeProviderModelId(selectedProvider, trimmed); | ||
| return `${selectedProvider}/${selectedModel}`; |
There was a problem hiding this comment.
Preserve alias model names in subagent spawn selection
Do not unconditionally prefix bare model strings with a provider here, because this rewrites aliases (for example fast) into provider-qualified refs (for example anthropic/fast) before sessions.patch. Alias resolution in resolveModelRefFromString only runs for values without /, so provider-prefixing causes valid alias-based sessions_spawn overrides/defaults to bypass alias lookup and fail allowlist checks as model not allowed.
Useful? React with 👍 / 👎.
Fixes #36134 by resolving sessions_spawn model routing for bare Gemini model names and surfacing unavailable model overrides.
Changes:
modelApplied: falseon sessions.patch model patch failures so unavailable overrides are not reported as successfully applied.Tests:
pnpm test src/agents/openclaw-tools.subagents.sessions-spawn.model.test.tspnpm test src/agents/model-selection.test.ts