Skip to content

Commit e905cd9

Browse files
fix: resolve ESLint padding and Prettier formatting issues
1 parent c7f7afa commit e905cd9

2 files changed

Lines changed: 161 additions & 1 deletion

File tree

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import { describe, it, expect } from 'vitest';
2+
import { LLMManager } from '~/lib/modules/llm/manager';
3+
4+
describe('Provider Validation', () => {
5+
const manager = LLMManager.getInstance();
6+
const providers = manager.getAllProviders();
7+
8+
describe('Provider Structure', () => {
9+
it('should have all required provider properties', () => {
10+
providers.forEach((provider) => {
11+
expect(provider).toHaveProperty('name');
12+
expect(provider).toHaveProperty('staticModels');
13+
expect(provider).toHaveProperty('config');
14+
15+
expect(typeof provider.name).toBe('string');
16+
expect(provider.name.length).toBeGreaterThan(0);
17+
expect(Array.isArray(provider.staticModels)).toBe(true);
18+
19+
// Optional properties
20+
if (provider.getApiKeyLink) {
21+
expect(typeof provider.getApiKeyLink).toBe('string');
22+
}
23+
24+
if (provider.icon) {
25+
expect(typeof provider.icon).toBe('string');
26+
}
27+
});
28+
});
29+
});
30+
31+
describe('Model Structure', () => {
32+
it('should have valid models in all providers', () => {
33+
providers.forEach((provider) => {
34+
provider.staticModels.forEach((model) => {
35+
expect(model).toHaveProperty('name');
36+
expect(model).toHaveProperty('label');
37+
expect(model).toHaveProperty('provider');
38+
expect(model).toHaveProperty('maxTokenAllowed');
39+
40+
expect(typeof model.name).toBe('string');
41+
expect(model.name.length).toBeGreaterThan(0);
42+
expect(typeof model.label).toBe('string');
43+
expect(model.label.length).toBeGreaterThan(0);
44+
expect(typeof model.provider).toBe('string');
45+
expect(typeof model.maxTokenAllowed).toBe('number');
46+
47+
// Provider name should match
48+
expect(model.provider).toBe(provider.name);
49+
});
50+
});
51+
});
52+
53+
it('should have reasonable token limits', () => {
54+
providers.forEach((provider) => {
55+
provider.staticModels.forEach((model) => {
56+
// Context window should be at least 2048 (reasonable minimum)
57+
expect(model.maxTokenAllowed).toBeGreaterThanOrEqual(2048);
58+
59+
// Context window should be less than 10 million tokens
60+
expect(model.maxTokenAllowed).toBeLessThan(10_000_000);
61+
62+
// Completion tokens should be less than context window
63+
if (model.maxCompletionTokens) {
64+
expect(model.maxCompletionTokens).toBeGreaterThan(0);
65+
expect(model.maxCompletionTokens).toBeLessThanOrEqual(model.maxTokenAllowed);
66+
}
67+
});
68+
});
69+
});
70+
});
71+
72+
describe('Duplicate Detection', () => {
73+
it('should not have duplicate model names within a provider', () => {
74+
providers.forEach((provider) => {
75+
const modelNames = provider.staticModels.map((m) => m.name);
76+
const uniqueNames = new Set(modelNames);
77+
78+
if (modelNames.length !== uniqueNames.size) {
79+
const duplicates = modelNames.filter((name, idx) => modelNames.indexOf(name) !== idx);
80+
throw new Error(`Provider ${provider.name} has duplicate models: ${duplicates}`);
81+
}
82+
83+
expect(modelNames.length).toBe(uniqueNames.size);
84+
});
85+
});
86+
87+
it('should not have duplicate labels within a provider', () => {
88+
providers.forEach((provider) => {
89+
const modelLabels = provider.staticModels.map((m) => m.label);
90+
const uniqueLabels = new Set(modelLabels);
91+
92+
if (modelLabels.length !== uniqueLabels.size) {
93+
const duplicates = modelLabels.filter((label, idx) => modelLabels.indexOf(label) !== idx);
94+
throw new Error(`Provider ${provider.name} has duplicate labels: ${duplicates}`);
95+
}
96+
97+
expect(modelLabels.length).toBe(uniqueLabels.size);
98+
});
99+
});
100+
});
101+
102+
describe('Provider Coverage', () => {
103+
it('should have at least 3 models per provider', () => {
104+
providers.forEach((provider) => {
105+
// Some smaller providers might have fewer models, but major ones should have at least 2
106+
if (['OpenAI', 'Anthropic', 'Google', 'Groq', 'Mistral', 'DeepSeek', 'xAI'].includes(provider.name)) {
107+
expect(provider.staticModels.length).toBeGreaterThanOrEqual(2);
108+
}
109+
});
110+
});
111+
});
112+
113+
describe('Model Name Validation', () => {
114+
it('should have valid model names (no empty strings)', () => {
115+
providers.forEach((provider) => {
116+
provider.staticModels.forEach((model) => {
117+
expect(model.name).toBeTruthy();
118+
expect(model.name).not.toMatch(/^\s*$/);
119+
expect(model.label).toBeTruthy();
120+
expect(model.label).not.toMatch(/^\s*$/);
121+
});
122+
});
123+
});
124+
125+
it('should not have null or undefined token values', () => {
126+
providers.forEach((provider) => {
127+
provider.staticModels.forEach((model) => {
128+
expect(model.maxTokenAllowed).toBeDefined();
129+
expect(model.maxTokenAllowed).not.toBeNull();
130+
131+
if (model.maxCompletionTokens !== undefined) {
132+
expect(model.maxCompletionTokens).not.toBeNull();
133+
}
134+
});
135+
});
136+
});
137+
});
138+
139+
describe('Provider Count', () => {
140+
it('should have at least 10 providers', () => {
141+
expect(providers.length).toBeGreaterThanOrEqual(10);
142+
});
143+
144+
it('should have all major providers registered', () => {
145+
const providerNames = providers.map((p) => p.name);
146+
const majorProviders = ['OpenAI', 'Anthropic', 'Google', 'Groq', 'Deepseek'];
147+
148+
majorProviders.forEach((providerName) => {
149+
expect(providerNames).toContain(providerName);
150+
});
151+
});
152+
});
153+
154+
describe('Static Models Count', () => {
155+
it('should have at least 50 total static models across all providers', () => {
156+
const totalModels = providers.reduce((sum, p) => sum + p.staticModels.length, 0);
157+
expect(totalModels).toBeGreaterThanOrEqual(50);
158+
});
159+
});
160+
});

app/lib/modules/llm/providers/deepseek.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export default class DeepseekProvider extends BaseProvider {
6565
try {
6666
const response = await fetch('https://api.deepseek.com/models', {
6767
headers: {
68-
'Authorization': `Bearer ${apiKey}`,
68+
Authorization: `Bearer ${apiKey}`,
6969
},
7070
});
7171

0 commit comments

Comments
 (0)