fix: provider-aware model routing with fallback visibility

- Extract createClientFromConfig() to dispatch on provider field instead
  of hardcoding all tiers as AnthropicClient
- Add fallback/fallbackReason metadata to ChatResponse and ChatStreamEvent
  so callers know when a fallback model was used
- Enhance doctor check to report full model stack and warn on missing
  API keys for cloud providers
- Log fallback warnings in NativeAgent and display them in TUI
- Support tier names and local_providers entries in fallback_chain
- Add 8 tests for createClientFromConfig covering all provider types
This commit is contained in:
William Valentin
2026-02-06 09:58:56 -08:00
parent c9b1c607d5
commit e4b7f96d33
9 changed files with 334 additions and 56 deletions
+7
View File
@@ -41,6 +41,8 @@ describe('ModelRouter', () => {
const response = await router.chat({ messages: [{ role: 'user', content: 'Hi' }] });
expect(response.content).toBe('Response from fallback');
expect(response.fallback).toBe(true);
expect(response.fallbackReason).toMatch(/Primary model failed/);
expect(failingClient.chat).toHaveBeenCalled();
expect(fallbackClient.chat).toHaveBeenCalled();
});
@@ -132,13 +134,18 @@ describe('ModelRouter streaming', () => {
});
const chunks: string[] = [];
let fallbackWarning: string | undefined;
for await (const event of router.chatStream({ messages: [] })) {
if (event.type === 'content' && event.content) {
chunks.push(event.content);
}
if (event.type === 'fallback_warning') {
fallbackWarning = event.fallbackReason;
}
}
expect(chunks).toEqual(['Fallback']);
expect(fallbackWarning).toMatch(/Primary model failed/);
});
});