This commit is contained in:
parent
a0e4365fc3
commit
43658df2a0
|
|
@ -113,15 +113,15 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
const quickThinkLlm = form.getValues("quick_think_llm");
|
||||
const deepThinkLlm = form.getValues("deep_think_llm");
|
||||
|
||||
// Set base URLs based on selected models
|
||||
form.setValue("quick_think_base_url", getBaseUrlForModel(quickThinkLlm));
|
||||
form.setValue("deep_think_base_url", getBaseUrlForModel(deepThinkLlm));
|
||||
form.setValue("embedding_base_url", "https://api.openai.com/v1");
|
||||
// Set base URLs based on selected models (custom URL takes precedence)
|
||||
form.setValue("quick_think_base_url", getBaseUrlForModel(quickThinkLlm, savedSettings.custom_base_url));
|
||||
form.setValue("deep_think_base_url", getBaseUrlForModel(deepThinkLlm, savedSettings.custom_base_url));
|
||||
form.setValue("embedding_base_url", savedSettings.custom_base_url || "https://api.openai.com/v1");
|
||||
|
||||
// Set API keys based on selected models
|
||||
form.setValue("quick_think_api_key", getApiKeyForModel(quickThinkLlm, savedSettings));
|
||||
form.setValue("deep_think_api_key", getApiKeyForModel(deepThinkLlm, savedSettings));
|
||||
form.setValue("embedding_api_key", savedSettings.openai_api_key);
|
||||
form.setValue("embedding_api_key", savedSettings.custom_api_key || savedSettings.openai_api_key);
|
||||
form.setValue("alpha_vantage_api_key", savedSettings.alpha_vantage_api_key);
|
||||
}, [form, form.watch("quick_think_llm"), form.watch("deep_think_llm")]);
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ const formSchema = z.object({
|
|||
grok_api_key: z.string().optional().or(z.literal("")),
|
||||
deepseek_api_key: z.string().optional().or(z.literal("")),
|
||||
qwen_api_key: z.string().optional().or(z.literal("")),
|
||||
|
||||
// Custom endpoint
|
||||
custom_base_url: z.string().optional().or(z.literal("")),
|
||||
custom_api_key: z.string().optional().or(z.literal("")),
|
||||
});
|
||||
|
||||
type FormValues = z.infer<typeof formSchema>;
|
||||
|
|
@ -90,6 +94,7 @@ export function ApiSettingsDialog() {
|
|||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
{/* @ts-ignore - React 19 type compatibility issue with Radix UI */}
|
||||
<DialogTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
|
|
@ -242,6 +247,57 @@ export function ApiSettingsDialog() {
|
|||
/>
|
||||
</div>
|
||||
|
||||
{/* Custom Endpoint Section */}
|
||||
<div className="space-y-4 border-t pt-4">
|
||||
<h3 className="text-lg font-semibold text-muted-foreground">
|
||||
自訂端點(進階選項)
|
||||
</h3>
|
||||
|
||||
{/* Custom Base URL */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="custom_base_url"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>自訂 Base URL</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="https://your-custom-endpoint.com/v1"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
若設定此項,將覆蓋所有模型的預設端點
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* Custom API Key */}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="custom_api_key"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>自訂端點 API Key</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
type="password"
|
||||
placeholder="輸入自訂端點的 API Key"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
配合自訂 Base URL 使用的 API Key
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{saveSuccess && (
|
||||
<div className="bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 rounded-lg p-3 text-green-800 dark:text-green-300 text-sm">
|
||||
✓ 設定已成功儲存
|
||||
|
|
|
|||
|
|
@ -6,8 +6,14 @@ import { ApiSettings } from "./storage";
|
|||
|
||||
/**
|
||||
* Get the base URL for a given LLM model
|
||||
* If custom_base_url is set, it takes precedence
|
||||
*/
|
||||
export function getBaseUrlForModel(model: string): string {
|
||||
export function getBaseUrlForModel(model: string, customBaseUrl?: string): string {
|
||||
// If custom base URL is provided, use it
|
||||
if (customBaseUrl && customBaseUrl.trim() !== "") {
|
||||
return customBaseUrl;
|
||||
}
|
||||
|
||||
// OpenAI models
|
||||
if (
|
||||
model.startsWith("gpt-") ||
|
||||
|
|
@ -48,11 +54,19 @@ export function getBaseUrlForModel(model: string): string {
|
|||
|
||||
/**
|
||||
* Get the API key for a given LLM model from saved settings
|
||||
* If custom_base_url is set and custom_api_key exists, use custom key
|
||||
*/
|
||||
export function getApiKeyForModel(
|
||||
model: string,
|
||||
settings: ApiSettings
|
||||
): string {
|
||||
// If custom base URL is configured and has a key, use the custom key
|
||||
if (settings.custom_base_url && settings.custom_base_url.trim() !== "") {
|
||||
if (settings.custom_api_key && settings.custom_api_key.trim() !== "") {
|
||||
return settings.custom_api_key;
|
||||
}
|
||||
}
|
||||
|
||||
// OpenAI models
|
||||
if (
|
||||
model.startsWith("gpt-") ||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ export interface ApiSettings {
|
|||
grok_api_key: string;
|
||||
deepseek_api_key: string;
|
||||
qwen_api_key: string;
|
||||
|
||||
// Custom endpoint
|
||||
custom_base_url: string;
|
||||
custom_api_key: string;
|
||||
}
|
||||
|
||||
const STORAGE_KEY = "tradingagents_api_settings";
|
||||
|
|
@ -25,6 +29,8 @@ export const DEFAULT_API_SETTINGS: ApiSettings = {
|
|||
grok_api_key: "",
|
||||
deepseek_api_key: "",
|
||||
qwen_api_key: "",
|
||||
custom_base_url: "",
|
||||
custom_api_key: "",
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue