Improve provider UX and DeepSeek fallback handling
--- Build: pass | Tests: pass — 68 passed (3 files) --- Build: pass | Tests: pass — Tests 2035 passed (2035) --- Build: pass | Tests: pass — Tests 2035 passed (2035)
This commit is contained in:
parent
d4cbafc88f
commit
8f87bc86a7
2 changed files with 50 additions and 1 deletions
|
|
@ -108,6 +108,32 @@ describe('parseProviderCapError', () => {
|
|||
expect(parsed?.until.getTime()).toBe(now.getTime() + 300 * 1000);
|
||||
});
|
||||
|
||||
it('detects DeepSeek insufficient balance as a long cooldown', () => {
|
||||
const now = new Date('2026-04-29T01:00:00Z');
|
||||
const parsed = parseProviderCapError(
|
||||
'{"error":{"code":"insufficient_balance","message":"Balance not enough"}}',
|
||||
now,
|
||||
300,
|
||||
);
|
||||
expect(parsed?.provider).toBe('deepseek');
|
||||
expect(parsed?.until.getTime()).toBe(
|
||||
now.getTime() + 24 * 60 * 60 * 1000,
|
||||
);
|
||||
expect(parsed?.reason).toContain('insufficient_balance');
|
||||
});
|
||||
|
||||
it('detects DeepSeek rate limits with the default cooldown', () => {
|
||||
const now = new Date('2026-04-29T01:00:00Z');
|
||||
const parsed = parseProviderCapError(
|
||||
'{"error":{"code":"rate_limit_exceeded","message":"Too many requests"}}',
|
||||
now,
|
||||
300,
|
||||
);
|
||||
expect(parsed?.provider).toBe('deepseek');
|
||||
expect(parsed?.until.getTime()).toBe(now.getTime() + 300 * 1000);
|
||||
expect(parsed?.reason).toBe('DeepSeek 429 rate limit');
|
||||
});
|
||||
|
||||
it('returns null for unrelated errors', () => {
|
||||
expect(parseProviderCapError('connection refused')).toBeNull();
|
||||
expect(parseProviderCapError('429 Too Many Requests')).toBeNull();
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ describe('command context', () => {
|
|||
});
|
||||
|
||||
describe('augmentPickerModels', () => {
|
||||
it('adds deepseek-chat for the DeepSeek picker when catalog only has v4 models', () => {
|
||||
it('adds deepseek-chat for the DeepSeek picker and sorts stable above experimental', () => {
|
||||
const models = augmentPickerModels('deepseek', [
|
||||
{
|
||||
id: 'deepseek-v4-flash',
|
||||
|
|
@ -140,6 +140,11 @@ describe('augmentPickerModels', () => {
|
|||
'deepseek-v4-flash',
|
||||
'deepseek-v4-pro',
|
||||
]);
|
||||
expect(models.map((m) => m.name)).toEqual([
|
||||
'✓ DeepSeek Chat',
|
||||
'⚠ DeepSeek V4 Flash',
|
||||
'⚠ DeepSeek V4 Pro',
|
||||
]);
|
||||
});
|
||||
|
||||
it('does not duplicate deepseek-chat when it is already present', () => {
|
||||
|
|
@ -158,6 +163,24 @@ describe('augmentPickerModels', () => {
|
|||
|
||||
expect(models).toHaveLength(1);
|
||||
expect(models[0]?.id).toBe('deepseek-chat');
|
||||
expect(models[0]?.name).toBe('✓ DeepSeek Chat');
|
||||
});
|
||||
|
||||
it('hides deprecated deepseek-reasoner from the picker', () => {
|
||||
const models = augmentPickerModels('deepseek', [
|
||||
{
|
||||
id: 'deepseek-reasoner',
|
||||
provider: 'deepseek',
|
||||
parent: null,
|
||||
name: 'deepseek-reasoner',
|
||||
context_length: null,
|
||||
pricing_in: null,
|
||||
pricing_out: null,
|
||||
free_tier: false,
|
||||
},
|
||||
]);
|
||||
|
||||
expect(models.map((m) => m.id)).toEqual(['deepseek-chat']);
|
||||
});
|
||||
|
||||
it('leaves non-DeepSeek providers unchanged', () => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue