feat: add support for custom provider configuration in the user config (#537)
### What - Add support for loading and merging custom provider configurations from a local `providers.json` file. - Allow users to override or extend default providers with their own settings. ### Why This change enables users to flexibly customize and extend provider endpoints and API keys without modifying the codebase, making the CLI more adaptable for various LLM backends and enterprise use cases. ### How - Introduced `loadProvidersFromFile` and `getMergedProviders` in config logic. - Added/updated related tests in [tests/config.test.tsx] ### Checklist - [x] Lint passes for changed files - [x] Tests pass for all files - [x] Documentation/comments updated as needed --------- Co-authored-by: Thibault Sottiaux <tibo@openai.com>
This commit is contained in:
@@ -42,33 +42,33 @@ export function setApiKey(apiKey: string): void {
|
||||
}
|
||||
|
||||
export function getBaseUrl(provider: string = "openai"): string | undefined {
|
||||
// If the provider is `openai` and `OPENAI_BASE_URL` is set, use it
|
||||
if (provider === "openai" && OPENAI_BASE_URL !== "") {
|
||||
return OPENAI_BASE_URL;
|
||||
}
|
||||
|
||||
// Check for a PROVIDER-specific override: e.g. OLLAMA_BASE_URL
|
||||
// Check for a PROVIDER-specific override: e.g. OPENAI_BASE_URL or OLLAMA_BASE_URL.
|
||||
const envKey = `${provider.toUpperCase()}_BASE_URL`;
|
||||
if (process.env[envKey]) {
|
||||
return process.env[envKey];
|
||||
}
|
||||
|
||||
// Use the default URL from providers if available
|
||||
const providerInfo = providers[provider.toLowerCase()];
|
||||
// Get providers config from config file.
|
||||
const config = loadConfig();
|
||||
const providersConfig = config.providers ?? providers;
|
||||
const providerInfo = providersConfig[provider.toLowerCase()];
|
||||
if (providerInfo) {
|
||||
return providerInfo.baseURL;
|
||||
}
|
||||
|
||||
// If the provider not found in the providers list and `OPENAI_BASE_URL` is set, use it
|
||||
// If the provider not found in the providers list and `OPENAI_BASE_URL` is set, use it.
|
||||
if (OPENAI_BASE_URL !== "") {
|
||||
return OPENAI_BASE_URL;
|
||||
}
|
||||
|
||||
// We tried.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getApiKey(provider: string = "openai"): string | undefined {
|
||||
const providerInfo = providers[provider.toLowerCase()];
|
||||
const config = loadConfig();
|
||||
const providersConfig = config.providers ?? providers;
|
||||
const providerInfo = providersConfig[provider.toLowerCase()];
|
||||
if (providerInfo) {
|
||||
if (providerInfo.name === "Ollama") {
|
||||
return process.env[providerInfo.envKey] ?? "dummy";
|
||||
@@ -81,12 +81,10 @@ export function getApiKey(provider: string = "openai"): string | undefined {
|
||||
return OPENAI_API_KEY;
|
||||
}
|
||||
|
||||
// We tried.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Formatting (quiet mode-only).
|
||||
export const PRETTY_PRINT = Boolean(process.env["PRETTY_PRINT"] || "");
|
||||
|
||||
// Represents config as persisted in config.json.
|
||||
export type StoredConfig = {
|
||||
model?: string;
|
||||
@@ -98,6 +96,7 @@ export type StoredConfig = {
|
||||
notify?: boolean;
|
||||
/** Disable server-side response storage (send full transcript each request) */
|
||||
disableResponseStorage?: boolean;
|
||||
providers?: Record<string, { name: string; baseURL: string; envKey: string }>;
|
||||
history?: {
|
||||
maxSize?: number;
|
||||
saveHistory?: boolean;
|
||||
@@ -134,6 +133,7 @@ export type AppConfig = {
|
||||
|
||||
/** Enable the "flex-mode" processing mode for supported models (o3, o4-mini) */
|
||||
flexMode?: boolean;
|
||||
providers?: Record<string, { name: string; baseURL: string; envKey: string }>;
|
||||
history?: {
|
||||
maxSize: number;
|
||||
saveHistory: boolean;
|
||||
@@ -141,6 +141,9 @@ export type AppConfig = {
|
||||
};
|
||||
};
|
||||
|
||||
// Formatting (quiet mode-only).
|
||||
export const PRETTY_PRINT = Boolean(process.env["PRETTY_PRINT"] || "");
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Project doc support (codex.md)
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -399,6 +402,9 @@ export const loadConfig = (
|
||||
};
|
||||
}
|
||||
|
||||
// Merge default providers with user configured providers in the config.
|
||||
config.providers = { ...providers, ...storedConfig.providers };
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
@@ -431,6 +437,7 @@ export const saveConfig = (
|
||||
const configToSave: StoredConfig = {
|
||||
model: config.model,
|
||||
provider: config.provider,
|
||||
providers: config.providers,
|
||||
approvalMode: config.approvalMode,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user