diff --git a/evals/packages/types/src/roo-code.ts b/evals/packages/types/src/roo-code.ts index 4470d2c3ec..911bad8b58 100644 --- a/evals/packages/types/src/roo-code.ts +++ b/evals/packages/types/src/roo-code.ts @@ -358,6 +358,7 @@ export const providerSettingsSchema = z.object({ googleGeminiBaseUrl: z.string().optional(), // OpenAI Native openAiNativeApiKey: z.string().optional(), + openAiNativeBaseUrl: z.string().optional(), // XAI xaiApiKey: z.string().optional(), // Mistral @@ -445,6 +446,7 @@ const providerSettingsRecord: ProviderSettingsRecord = { googleGeminiBaseUrl: undefined, // OpenAI Native openAiNativeApiKey: undefined, + openAiNativeBaseUrl: undefined, // Mistral mistralApiKey: undefined, mistralCodestralUrl: undefined, diff --git a/src/api/providers/openai-native.ts b/src/api/providers/openai-native.ts index 37eb924d13..62782b3d4f 100644 --- a/src/api/providers/openai-native.ts +++ b/src/api/providers/openai-native.ts @@ -29,7 +29,7 @@ export class OpenAiNativeHandler extends BaseProvider implements SingleCompletio super() this.options = options const apiKey = this.options.openAiNativeApiKey ?? "not-provided" - this.client = new OpenAI({ apiKey }) + this.client = new OpenAI({ baseURL: this.options.openAiNativeBaseUrl, apiKey }) } override async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream { diff --git a/src/exports/roo-code.d.ts b/src/exports/roo-code.d.ts index 04d713005e..71902841b0 100644 --- a/src/exports/roo-code.d.ts +++ b/src/exports/roo-code.d.ts @@ -105,6 +105,7 @@ type ProviderSettings = { geminiApiKey?: string | undefined googleGeminiBaseUrl?: string | undefined openAiNativeApiKey?: string | undefined + openAiNativeBaseUrl?: string | undefined mistralApiKey?: string | undefined mistralCodestralUrl?: string | undefined deepSeekBaseUrl?: string | undefined diff --git a/src/exports/types.ts b/src/exports/types.ts index 7eee7d3cdf..d3e7059f7c 100644 --- a/src/exports/types.ts +++ b/src/exports/types.ts @@ -106,6 +106,7 @@ type ProviderSettings = { geminiApiKey?: string | undefined googleGeminiBaseUrl?: string | undefined openAiNativeApiKey?: string | undefined + openAiNativeBaseUrl?: string | undefined mistralApiKey?: string | undefined mistralCodestralUrl?: string | undefined deepSeekBaseUrl?: string | undefined diff --git a/src/schemas/index.ts b/src/schemas/index.ts index 00c7919018..202dbff01a 100644 --- a/src/schemas/index.ts +++ b/src/schemas/index.ts @@ -401,6 +401,7 @@ export const providerSettingsSchema = z.object({ googleGeminiBaseUrl: z.string().optional(), // OpenAI Native openAiNativeApiKey: z.string().optional(), + openAiNativeBaseUrl: z.string().optional(), // Mistral mistralApiKey: z.string().optional(), mistralCodestralUrl: z.string().optional(), @@ -492,6 +493,7 @@ const providerSettingsRecord: ProviderSettingsRecord = { googleGeminiBaseUrl: undefined, // OpenAI Native openAiNativeApiKey: undefined, + openAiNativeBaseUrl: undefined, // Mistral mistralApiKey: undefined, mistralCodestralUrl: undefined, diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 917947ac05..3682b46842 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -75,6 +75,9 @@ const ApiOptions = ({ const [openAiModels, setOpenAiModels] = useState | null>(null) const [anthropicBaseUrlSelected, setAnthropicBaseUrlSelected] = useState(!!apiConfiguration?.anthropicBaseUrl) + const [openAiNativeBaseUrlSelected, setOpenAiNativeBaseUrlSelected] = useState( + !!apiConfiguration?.openAiNativeBaseUrl, + ) const [azureApiVersionSelected, setAzureApiVersionSelected] = useState(!!apiConfiguration?.azureApiVersion) const [openRouterBaseUrlSelected, setOpenRouterBaseUrlSelected] = useState(!!apiConfiguration?.openRouterBaseUrl) const [openAiHostHeaderSelected, setOpenAiHostHeaderSelected] = useState(!!apiConfiguration?.openAiHostHeader) @@ -490,6 +493,28 @@ const ApiOptions = ({ {selectedProvider === "openai-native" && ( <> + { + setOpenAiNativeBaseUrlSelected(checked) + + if (!checked) { + setApiConfigurationField("openAiNativeBaseUrl", "") + } + }}> + {t("settings:providers.useCustomBaseUrl")} + + {openAiNativeBaseUrlSelected && ( + <> + + + )}