feat: allow setting openai base path (#1369)
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
"name": "OpenAI",
|
"name": "OpenAI",
|
||||||
"description": "Use GPT-4 and other OpenAI models",
|
"description": "Use GPT-4 and other OpenAI models",
|
||||||
"models": ["gpt-4o", "gpt-4-turbo","o1"],
|
"models": ["gpt-4o", "gpt-4-turbo","o1"],
|
||||||
"required_keys": ["OPENAI_API_KEY", "OPENAI_HOST"]
|
"required_keys": ["OPENAI_API_KEY", "OPENAI_HOST", "OPENAI_BASE_PATH"]
|
||||||
},
|
},
|
||||||
"anthropic": {
|
"anthropic": {
|
||||||
"name": "Anthropic",
|
"name": "Anthropic",
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ pub struct OpenAiProvider {
|
|||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
client: Client,
|
client: Client,
|
||||||
host: String,
|
host: String,
|
||||||
|
base_path: String,
|
||||||
api_key: String,
|
api_key: String,
|
||||||
organization: Option<String>,
|
organization: Option<String>,
|
||||||
project: Option<String>,
|
project: Option<String>,
|
||||||
@@ -48,6 +49,9 @@ impl OpenAiProvider {
|
|||||||
let host: String = config
|
let host: String = config
|
||||||
.get("OPENAI_HOST")
|
.get("OPENAI_HOST")
|
||||||
.unwrap_or_else(|_| "https://api.openai.com".to_string());
|
.unwrap_or_else(|_| "https://api.openai.com".to_string());
|
||||||
|
let base_path: String = config
|
||||||
|
.get("OPENAI_BASE_PATH")
|
||||||
|
.unwrap_or_else(|_| "v1/chat/completions".to_string());
|
||||||
let organization: Option<String> = config.get("OPENAI_ORGANIZATION").ok();
|
let organization: Option<String> = config.get("OPENAI_ORGANIZATION").ok();
|
||||||
let project: Option<String> = config.get("OPENAI_PROJECT").ok();
|
let project: Option<String> = config.get("OPENAI_PROJECT").ok();
|
||||||
let client = Client::builder()
|
let client = Client::builder()
|
||||||
@@ -57,6 +61,7 @@ impl OpenAiProvider {
|
|||||||
Ok(Self {
|
Ok(Self {
|
||||||
client,
|
client,
|
||||||
host,
|
host,
|
||||||
|
base_path,
|
||||||
api_key,
|
api_key,
|
||||||
organization,
|
organization,
|
||||||
project,
|
project,
|
||||||
@@ -67,7 +72,7 @@ impl OpenAiProvider {
|
|||||||
async fn post(&self, payload: Value) -> Result<Value, ProviderError> {
|
async fn post(&self, payload: Value) -> Result<Value, ProviderError> {
|
||||||
let base_url = url::Url::parse(&self.host)
|
let base_url = url::Url::parse(&self.host)
|
||||||
.map_err(|e| ProviderError::RequestFailed(format!("Invalid base URL: {e}")))?;
|
.map_err(|e| ProviderError::RequestFailed(format!("Invalid base URL: {e}")))?;
|
||||||
let url = base_url.join("v1/chat/completions").map_err(|e| {
|
let url = base_url.join(&self.base_path).map_err(|e| {
|
||||||
ProviderError::RequestFailed(format!("Failed to construct endpoint URL: {e}"))
|
ProviderError::RequestFailed(format!("Failed to construct endpoint URL: {e}"))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -108,6 +113,7 @@ impl Provider for OpenAiProvider {
|
|||||||
vec![
|
vec![
|
||||||
ConfigKey::new("OPENAI_API_KEY", true, true, None),
|
ConfigKey::new("OPENAI_API_KEY", true, true, None),
|
||||||
ConfigKey::new("OPENAI_HOST", true, false, Some("https://api.openai.com")),
|
ConfigKey::new("OPENAI_HOST", true, false, Some("https://api.openai.com")),
|
||||||
|
ConfigKey::new("OPENAI_BASE_PATH", true, false, Some("v1/chat/completions")),
|
||||||
ConfigKey::new("OPENAI_ORGANIZATION", false, false, None),
|
ConfigKey::new("OPENAI_ORGANIZATION", false, false, None),
|
||||||
ConfigKey::new("OPENAI_PROJECT", false, false, None),
|
ConfigKey::new("OPENAI_PROJECT", false, false, None),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ export function isSecretKey(keyName: string): boolean {
|
|||||||
'DATABRICKS_HOST',
|
'DATABRICKS_HOST',
|
||||||
'OLLAMA_HOST',
|
'OLLAMA_HOST',
|
||||||
'OPENAI_HOST',
|
'OPENAI_HOST',
|
||||||
|
'OPENAI_BASE_PATH',
|
||||||
'AZURE_OPENAI_ENDPOINT',
|
'AZURE_OPENAI_ENDPOINT',
|
||||||
'AZURE_OPENAI_DEPLOYMENT_NAME',
|
'AZURE_OPENAI_DEPLOYMENT_NAME',
|
||||||
];
|
];
|
||||||
@@ -24,22 +25,22 @@ export async function getActiveProviders(): Promise<string[]> {
|
|||||||
const configSettings = await getConfigSettings();
|
const configSettings = await getConfigSettings();
|
||||||
|
|
||||||
const activeProviders = Object.values(configSettings)
|
const activeProviders = Object.values(configSettings)
|
||||||
.filter((provider) => {
|
.filter((provider) => {
|
||||||
// 1. Get provider's config_status
|
// 1. Get provider's config_status
|
||||||
const configStatus = provider.config_status ?? {};
|
const configStatus = provider.config_status ?? {};
|
||||||
|
|
||||||
// 2. Collect only the keys *not* in default_key_value
|
// 2. Collect only the keys *not* in default_key_value
|
||||||
const requiredKeyEntries = Object.entries(configStatus).filter(([k]) => isRequiredKey(k));
|
const requiredKeyEntries = Object.entries(configStatus).filter(([k]) => isRequiredKey(k));
|
||||||
|
|
||||||
// 3. If there are *no* non-default keys, it is NOT active
|
// 3. If there are *no* non-default keys, it is NOT active
|
||||||
if (requiredKeyEntries.length === 0) {
|
if (requiredKeyEntries.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Otherwise, all non-default keys must be `is_set`
|
// 4. Otherwise, all non-default keys must be `is_set`
|
||||||
return requiredKeyEntries.every(([_, value]) => value?.is_set);
|
return requiredKeyEntries.every(([_, value]) => value?.is_set);
|
||||||
})
|
})
|
||||||
.map((provider) => provider.name || 'Unknown Provider');
|
.map((provider) => provider.name || 'Unknown Provider');
|
||||||
|
|
||||||
console.log('[GET ACTIVE PROVIDERS]:', activeProviders);
|
console.log('[GET ACTIVE PROVIDERS]:', activeProviders);
|
||||||
return activeProviders;
|
return activeProviders;
|
||||||
@@ -93,4 +94,4 @@ export async function getProvidersList(): Promise<Provider[]> {
|
|||||||
models: item.details?.models || [], // Nested models array
|
models: item.details?.models || [], // Nested models array
|
||||||
requiredKeys: item.details?.required_keys || [], // Nested required keys array
|
requiredKeys: item.details?.required_keys || [], // Nested required keys array
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export function getDefaultModel(key: string): string | undefined {
|
|||||||
export const short_list = ['gpt-4o', 'claude-3-5-sonnet-latest'];
|
export const short_list = ['gpt-4o', 'claude-3-5-sonnet-latest'];
|
||||||
|
|
||||||
export const required_keys = {
|
export const required_keys = {
|
||||||
OpenAI: ['OPENAI_API_KEY', 'OPENAI_HOST'],
|
OpenAI: ['OPENAI_API_KEY', 'OPENAI_HOST', 'OPENAI_BASE_PATH'],
|
||||||
Anthropic: ['ANTHROPIC_API_KEY'],
|
Anthropic: ['ANTHROPIC_API_KEY'],
|
||||||
Databricks: ['DATABRICKS_HOST'],
|
Databricks: ['DATABRICKS_HOST'],
|
||||||
Groq: ['GROQ_API_KEY'],
|
Groq: ['GROQ_API_KEY'],
|
||||||
@@ -77,6 +77,7 @@ export const required_keys = {
|
|||||||
|
|
||||||
export const default_key_value = {
|
export const default_key_value = {
|
||||||
OPENAI_HOST: 'https://api.openai.com',
|
OPENAI_HOST: 'https://api.openai.com',
|
||||||
|
OPENAI_BASE_PATH: 'v1/chat/completions',
|
||||||
OLLAMA_HOST: 'localhost',
|
OLLAMA_HOST: 'localhost',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user