Skip to content

Commit 3758a37

Browse files
committed
fix(tui): reject an unconfigured /workflow model alias
An alias the engine cannot resolve falls back to the session model when the subagent spawns, so accepting one reported a routing that never happened. Check it against the configured models and show an error instead.
1 parent 34a3c44 commit 3758a37

2 files changed

Lines changed: 23 additions & 0 deletions

File tree

apps/pythinker-code/src/tui/commands/dynamic-workflow.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@ function handleModelSubcommand(host: SlashCommandHost, input: string): boolean {
129129
host.showStatus('Dynamic Workflow subagents now use this session model.');
130130
return true;
131131
}
132+
// An alias the engine cannot resolve falls back to the session model at spawn
133+
// time, so accepting one here would report a routing that never happens.
134+
const configured = host.state.appState.availableModels;
135+
if (Object.keys(configured).length > 0 && !Object.hasOwn(configured, value)) {
136+
host.showError(`Unknown model: ${value}. Run /model to see the configured aliases.`);
137+
return true;
138+
}
132139
host.setAppState({ dynamicWorkflowModel: value });
133140
host.showStatus(`Dynamic Workflow subagents will use ${value}.`);
134141
return true;

apps/pythinker-code/test/tui/commands/dynamic-workflow.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ function makeHost(
2222
hasSession?: boolean;
2323
permissionMode?: 'manual' | 'auto' | 'yolo';
2424
dynamicWorkflowMode?: boolean;
25+
availableModels?: Record<string, unknown>;
2526
} = {},
2627
) {
2728
const session = {
@@ -35,6 +36,9 @@ function makeHost(
3536
model: overrides.model ?? 'pythinker-model',
3637
permissionMode: overrides.permissionMode ?? 'auto',
3738
dynamicWorkflowMode: overrides.dynamicWorkflowMode ?? false,
39+
availableModels: overrides.availableModels ?? {
40+
'deepseek-v4': { provider: 'deepseek', model: 'deepseek-v4' },
41+
},
3842
},
3943
theme: currentTheme,
4044
transcriptContainer: { addChild: vi.fn() },
@@ -365,6 +369,18 @@ describe('handleDynamicWorkflowCommand', () => {
365369
expect(host.sendNormalUserInput).not.toHaveBeenCalled();
366370
});
367371

372+
it('rejects a model alias that is not configured', async () => {
373+
const { host } = makeHost({ permissionMode: 'auto' });
374+
375+
await handleDynamicWorkflowCommand(host, 'model not-a-real-alias');
376+
377+
expect(host.showError).toHaveBeenCalledWith(
378+
expect.stringContaining('Unknown model: not-a-real-alias'),
379+
);
380+
expect(host.state.appState.dynamicWorkflowModel).toBeUndefined();
381+
expect(host.sendNormalUserInput).not.toHaveBeenCalled();
382+
});
383+
368384
it('asks the task to route subagents to the configured model', async () => {
369385
const { host } = makeHost({ permissionMode: 'auto' });
370386

0 commit comments

Comments
 (0)