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:
@@ -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: {
|
||||
|
||||
@@ -17,6 +17,7 @@ export type ProviderInfo = {
|
||||
export interface IProviderSetting {
|
||||
enabled?: boolean;
|
||||
baseUrl?: string;
|
||||
OPENAI_LIKE_API_MODELS?: string;
|
||||
}
|
||||
|
||||
export type IProviderConfig = ProviderInfo & {
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
1
worker-configuration.d.ts
vendored
1
worker-configuration.d.ts
vendored
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user