fix(#4270): forward Codex spawn model routing (#4281)

Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
This commit is contained in:
Michel Moreira
2026-09-05 15:20:26 -03:00
committed by GitHub
parent 7ff196c505
commit 86b745b48b
8 changed files with 114 additions and 45 deletions

View File

@@ -220,9 +220,16 @@ describe('getCodexSkillAdapterHeader', () => {
const result = getCodexSkillAdapterHeader('gsd-execute-phase');
assert.ok(result.includes('spawn_agent'), 'maps to spawn_agent');
assert.ok(result.includes('agent_type'), 'maps subagent_type to agent_type');
// #4270: resolve-model exposes the portable field as `effort`; the Codex
// adapter must fetch it and translate it to spawn_agent.reasoning_effort.
assert.match(
result,
/Resolved `reasoning_effort="low\|medium\|high\|xhigh"` \(`xhigh` is a GSD\/Codex tier, not a generic runtime enum\) → pass `reasoning_effort`\s+to `spawn_agent` when the runtime\/tool supports it/,
/query resolve-model <subagent_type> --pick effort/,
'retrieves the unified effort for the dispatched role',
);
assert.match(
result,
/unified `effort` field maps to the Codex spawn argument\s+`reasoning_effort`/,
'documents reasoning_effort transport',
);
assert.ok(result.includes('do not invent one-off effort literals'), 'keeps effort policy centralized');

View File

@@ -2347,15 +2347,30 @@ describe('bug #2256 — OpenCode adapter embeds per-project override', () => {
});
describe('bug #2256 — Codex skill adapter header documents transport', () => {
test('Task(model=...) line no longer says "omit" without explanation', () => {
test('documents static model_overrides as a fallback transport', () => {
const header = getCodexSkillAdapterHeader('gsd-plan-phase');
// Header must mention that per-agent model_overrides are embedded in agent
// TOML so spawn_agent picks them up automatically — the old text said
// "Codex uses per-role config, not inline model selection" which left
// users thinking their model_overrides were silently ignored.
assert.match(header, /model_overrides/);
});
});
describe('bug #4270 — Codex adapter forwards resolved spawn routing', () => {
test('forwards model and reasoning_effort when spawn_agent advertises each field', () => {
const header = getCodexSkillAdapterHeader('gsd-plan-phase');
assert.match(header, /Task\(model="\{resolved_model\}"\).*pass `model="\{resolved_model\}"`/s);
assert.match(header, /This is how `model_profile`.*including `adaptive`.*reaches the child agent/s);
assert.match(header, /query resolve-model <subagent_type> --pick effort/);
assert.match(header, /unified `effort`.*spawn argument\s+`reasoning_effort`/s);
});
test('keeps inheritance fallback for absent fields and sentinel values', () => {
const header = getCodexSkillAdapterHeader('gsd-plan-phase');
assert.match(header, /Omit `model` only when.*does not advertise `model`.*empty.*`"inherit"`/s);
assert.match(header, /Detect optional fields independently/s);
assert.doesNotMatch(header, /spawn_agent` has no inline `model` parameter/);
});
});
});
}