feat: add support for OPENAI_LIKE_API_MODELS

- Add OPENAI_LIKE_API_MODELS environment variable support
- Enable fallback model parsing when /models endpoint fails
- Support providers like Fireworks AI that don't allow /models requests
- Format: path/to/model1:limit;path/to/model2:limit;path/to/model3:limit
- Update IProviderSetting interface to include OPENAI_LIKE_API_MODELS property
- Fix all linting errors and code formatting issues
This commit is contained in:
Stijnus
2025-09-07 01:02:04 +02:00
parent a44de8addc
commit 9e01e5c0bc
5 changed files with 111 additions and 12 deletions

View File

@@ -10,6 +10,7 @@ export default class OpenAILikeProvider extends BaseProvider {
config = {
baseUrlKey: 'OPENAI_LIKE_API_BASE_URL',
apiTokenKey: 'OPENAI_LIKE_API_KEY',
modelsKey: 'OPENAI_LIKE_API_MODELS',
};
staticModels: ModelInfo[] = [];
@@ -31,20 +32,114 @@ export default class OpenAILikeProvider extends BaseProvider {
return [];
}
const response = await fetch(`${baseUrl}/models`, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
try {
const response = await fetch(`${baseUrl}/models`, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
const res = (await response.json()) as any;
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return res.data.map((model: any) => ({
name: model.id,
label: model.id,
provider: this.name,
maxTokenAllowed: 8000,
}));
const res = (await response.json()) as any;
return res.data.map((model: any) => ({
name: model.id,
label: model.id,
provider: this.name,
maxTokenAllowed: 8000,
}));
} catch (error) {
console.log(`${this.name}: Not allowed to GET /models endpoint for provider`, error);
// Fallback to OPENAI_LIKE_API_MODELS if available
// eslint-disable-next-line dot-notation
const modelsEnv = serverEnv['OPENAI_LIKE_API_MODELS'] || settings?.OPENAI_LIKE_API_MODELS;
if (modelsEnv) {
console.log(`${this.name}: OPENAI_LIKE_API_MODELS=${modelsEnv}`);
return this._parseModelsFromEnv(modelsEnv);
}
return [];
}
}
/**
* Parse OPENAI_LIKE_API_MODELS environment variable
* Format: path/to/model1:limit;path/to/model2:limit;path/to/model3:limit
*/
private _parseModelsFromEnv(modelsEnv: string): ModelInfo[] {
if (!modelsEnv) {
return [];
}
try {
const models: ModelInfo[] = [];
const modelEntries = modelsEnv.split(';');
for (const entry of modelEntries) {
const trimmedEntry = entry.trim();
if (!trimmedEntry) {
continue;
}
const [modelPath, limitStr] = trimmedEntry.split(':');
if (!modelPath) {
continue;
}
const limit = limitStr ? parseInt(limitStr.trim(), 10) : 8000;
const modelName = modelPath.trim();
// Generate a readable label from the model path
const label = this._generateModelLabel(modelName);
models.push({
name: modelName,
label,
provider: this.name,
maxTokenAllowed: limit,
});
}
console.log(`${this.name}: Parsed Models:`, models);
return models;
} catch (error) {
console.error(`${this.name}: Error parsing OPENAI_LIKE_API_MODELS:`, error);
return [];
}
}
/**
* Generate a readable label from model path
*/
private _generateModelLabel(modelPath: string): string {
// Extract the last part of the path and clean it up
const parts = modelPath.split('/');
const lastPart = parts[parts.length - 1];
// Remove common prefixes and clean up the name
let label = lastPart
.replace(/^accounts\//, '')
.replace(/^fireworks\/models\//, '')
.replace(/^models\//, '')
// Capitalize first letter of each word
.replace(/\b\w/g, (l) => l.toUpperCase())
// Replace spaces with hyphens for a cleaner look
.replace(/\s+/g, '-');
// Add provider suffix if not already present
if (!label.includes('Fireworks') && !label.includes('OpenAI')) {
label += ' (OpenAI Compatible)';
}
return label;
}
getModelInstance(options: {

View File

@@ -17,6 +17,7 @@ export type ProviderInfo = {
export interface IProviderSetting {
enabled?: boolean;
baseUrl?: string;
OPENAI_LIKE_API_MODELS?: string;
}
export type IProviderConfig = ProviderInfo & {

View File

@@ -60,6 +60,7 @@ export default defineConfig((config) => {
envPrefix: [
'VITE_',
'OPENAI_LIKE_API_BASE_URL',
'OPENAI_LIKE_API_MODELS',
'OLLAMA_API_BASE_URL',
'LMSTUDIO_API_BASE_URL',
'TOGETHER_API_BASE_URL',

View File

@@ -60,6 +60,7 @@ export default defineConfig((config) => {
envPrefix: [
'VITE_',
'OPENAI_LIKE_API_BASE_URL',
'OPENAI_LIKE_API_MODELS',
'OLLAMA_API_BASE_URL',
'LMSTUDIO_API_BASE_URL',
'TOGETHER_API_BASE_URL',

View File

@@ -9,6 +9,7 @@ interface Env {
OLLAMA_API_BASE_URL: string;
OPENAI_LIKE_API_KEY: string;
OPENAI_LIKE_API_BASE_URL: string;
OPENAI_LIKE_API_MODELS: string;
TOGETHER_API_KEY: string;
TOGETHER_API_BASE_URL: string;
DEEPSEEK_API_KEY: string;