Merge pull request #3483 from radioflyer28/feat/agent-launch-reasoning-transport-3474
feat: transport resolved reasoning effort to agent launches
This commit is contained in:
@@ -155,7 +155,7 @@ From `read-only-parity.integration.test.ts` (full `toEqual` on this repo):
|
||||
|
||||
| SDK dispatch (canonical) | Notes |
|
||||
| ------------------------ | ----- |
|
||||
| `resolve-model` | Args e.g. `gsd-planner`. |
|
||||
| `resolve-model` | Args e.g. `gsd-planner`; returns `reasoning_effort` when the selected runtime tier defines one. |
|
||||
| `phase-plan-index` | Phase number arg. |
|
||||
| `roadmap.get-phase` | Phase number arg. |
|
||||
| `list.todos` | No args. |
|
||||
|
||||
@@ -208,8 +208,55 @@ describe('resolveModel', () => {
|
||||
const planner = (await resolveModel(['gsd-planner'], tmpDir)).data as Record<string, unknown>;
|
||||
const executor = (await resolveModel(['gsd-executor'], tmpDir)).data as Record<string, unknown>;
|
||||
|
||||
expect(planner).toMatchObject({ model: 'gpt-5.5', profile: 'balanced' });
|
||||
expect(executor).toMatchObject({ model: 'gpt-5.3-codex', profile: 'balanced' });
|
||||
expect(planner).toMatchObject({ model: 'gpt-5.5', profile: 'balanced', reasoning_effort: 'high' });
|
||||
expect(executor).toMatchObject({ model: 'gpt-5.3-codex', profile: 'balanced', reasoning_effort: 'medium' });
|
||||
});
|
||||
|
||||
it('returns runtime reasoning_effort from the same phase-tier source as model', async () => {
|
||||
const { resolveModel } = await import('./config-query.js');
|
||||
const { resolveRuntimeTierDefault } = await import('../model-catalog.js');
|
||||
const opusCodexTier = resolveRuntimeTierDefault('codex', 'opus');
|
||||
await writeFile(
|
||||
join(tmpDir, '.planning', 'config.json'),
|
||||
JSON.stringify({
|
||||
model_profile: 'budget',
|
||||
runtime: 'codex',
|
||||
models: { execution: 'opus' },
|
||||
}),
|
||||
);
|
||||
|
||||
const executor = (await resolveModel(['gsd-executor'], tmpDir)).data as Record<string, unknown>;
|
||||
|
||||
expect(executor).toMatchObject({
|
||||
model: 'gpt-5.4',
|
||||
profile: 'budget',
|
||||
reasoning_effort: opusCodexTier?.reasoning_effort,
|
||||
});
|
||||
});
|
||||
|
||||
it('does not leak reasoning_effort from overrides for unsupported runtimes', async () => {
|
||||
const { resolveModel } = await import('./config-query.js');
|
||||
await writeFile(
|
||||
join(tmpDir, '.planning', 'config.json'),
|
||||
JSON.stringify({
|
||||
model_profile: 'balanced',
|
||||
runtime: 'opencode',
|
||||
models: { planning: 'opus' },
|
||||
model_profile_overrides: {
|
||||
opencode: {
|
||||
opus: { model: 'openrouter/openai/gpt-5.5', reasoning_effort: 'high' },
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const planner = (await resolveModel(['gsd-planner'], tmpDir)).data as Record<string, unknown>;
|
||||
|
||||
expect(planner).toMatchObject({
|
||||
model: 'openrouter/openai/gpt-5.5',
|
||||
profile: 'balanced',
|
||||
});
|
||||
expect(planner).not.toHaveProperty('reasoning_effort');
|
||||
});
|
||||
|
||||
it('resolveModel uses workstream config when --ws is specified', async () => {
|
||||
|
||||
@@ -30,8 +30,11 @@ import {
|
||||
VALID_PROFILES,
|
||||
getAgentToModelMapForProfile,
|
||||
resolveRuntimeTierDefault,
|
||||
runtimesWithReasoningEffort,
|
||||
} from '../model-catalog.js';
|
||||
|
||||
const RUNTIMES_WITH_REASONING_EFFORT = runtimesWithReasoningEffort();
|
||||
|
||||
// ─── configGet ──────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
@@ -151,7 +154,11 @@ function resolveRuntimeTier(config: Record<string, unknown>, tier: string): Runt
|
||||
const userEntry = normalizeRuntimeTierEntry(runtimeOverrides?.[tier]);
|
||||
|
||||
if (!builtin && !userEntry) return null;
|
||||
return { ...(builtin ?? {}), ...(userEntry ?? {}) };
|
||||
const merged = { ...(builtin ?? {}), ...(userEntry ?? {}) };
|
||||
if (!RUNTIMES_WITH_REASONING_EFFORT.has(runtime)) {
|
||||
delete merged.reasoning_effort;
|
||||
}
|
||||
return merged;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,7 +229,11 @@ export const resolveModel: QueryHandler = async (args, projectDir, workstream) =
|
||||
const tier = typeof phaseTier === 'string' ? phaseTier : alias;
|
||||
const runtimeTier = resolveRuntimeTier(config as Record<string, unknown>, tier);
|
||||
if (runtimeTier?.model) {
|
||||
return { data: { model: runtimeTier.model, profile } };
|
||||
const result: Record<string, unknown> = { model: runtimeTier.model, profile };
|
||||
if (runtimeTier.reasoning_effort) {
|
||||
result.reasoning_effort = runtimeTier.reasoning_effort;
|
||||
}
|
||||
return { data: result };
|
||||
}
|
||||
|
||||
if (resolveModelIds === 'omit') {
|
||||
|
||||
Reference in New Issue
Block a user