This commit is contained in:
parent
c0939063aa
commit
58521527fd
|
|
@ -28,23 +28,43 @@ import {
|
|||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import type { AnalysisRequest } from "@/lib/types";
|
||||
|
||||
const formSchema = z.object({
|
||||
ticker: z.string().min(1, "股票代碼為必填").max(10),
|
||||
analysis_date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "日期格式必須為 YYYY-MM-DD"),
|
||||
analysis_date: z
|
||||
.string()
|
||||
.regex(/^\d{4}-\d{2}-\d{2}$/, "日期格式必須為 YYYY-MM-DD"),
|
||||
analysts: z.array(z.string()).min(1, "請至少選擇一位分析師"),
|
||||
research_depth: z.number().int().min(1).max(5),
|
||||
shallow_thinking_agent: z.string().min(1, "請選擇快速思維模型"),
|
||||
shallow_thinking_agent: z.string().min(1, "請選擇快速思維模型"),
|
||||
deep_thinking_agent: z.string().min(1, "請選擇深層思維模型"),
|
||||
|
||||
|
||||
// API Configuration
|
||||
quick_think_base_url: z.string().url("請輸入有效的 URL").optional().or(z.literal("")),
|
||||
deep_think_base_url: z.string().url("請輸入有效的 URL").optional().or(z.literal("")),
|
||||
quick_think_base_url: z
|
||||
.string()
|
||||
.url("請輸入有效的 URL")
|
||||
.optional()
|
||||
.or(z.literal("")),
|
||||
deep_think_base_url: z
|
||||
.string()
|
||||
.url("請輸入有效的 URL")
|
||||
.optional()
|
||||
.or(z.literal("")),
|
||||
quick_think_api_key: z.string().optional().or(z.literal("")),
|
||||
deep_think_api_key: z.string().optional().or(z.literal("")),
|
||||
embedding_base_url: z.string().url("請輸入有效的 URL").optional().or(z.literal("")),
|
||||
embedding_base_url: z
|
||||
.string()
|
||||
.url("請輸入有效的 URL")
|
||||
.optional()
|
||||
.or(z.literal("")),
|
||||
embedding_api_key: z.string().optional().or(z.literal("")),
|
||||
alpha_vantage_api_key: z.string().min(1, "請輸入 Alpha Vantage API Key"),
|
||||
});
|
||||
|
|
@ -87,7 +107,10 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
if (currentAnalysts.length === ANALYSTS.length) {
|
||||
form.setValue("analysts", []);
|
||||
} else {
|
||||
form.setValue("analysts", ANALYSTS.map(a => a.value));
|
||||
form.setValue(
|
||||
"analysts",
|
||||
ANALYSTS.map((a) => a.value)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -102,19 +125,26 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
<Card className="shadow-lg">
|
||||
<CardContent className="pt-6">
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(handleSubmit)} className="space-y-6">
|
||||
<form
|
||||
onSubmit={form.handleSubmit(handleSubmit)}
|
||||
className="space-y-6"
|
||||
>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{/* 分析師選擇區塊 - 全寬 */}
|
||||
<div className="md:col-span-2 border-b pb-6">
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<FormLabel className="text-base font-semibold">分析師團隊</FormLabel>
|
||||
<FormLabel className="text-base font-semibold">
|
||||
分析師團隊
|
||||
</FormLabel>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={toggleSelectAll}
|
||||
>
|
||||
{form.watch("analysts").length === ANALYSTS.length ? "取消全選" : "全選"}
|
||||
{form.watch("analysts").length === ANALYSTS.length
|
||||
? "取消全選"
|
||||
: "全選"}
|
||||
</Button>
|
||||
</div>
|
||||
<FormField
|
||||
|
|
@ -136,13 +166,19 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
>
|
||||
<FormControl>
|
||||
<Checkbox
|
||||
checked={field.value?.includes(analyst.value)}
|
||||
checked={field.value?.includes(
|
||||
analyst.value
|
||||
)}
|
||||
onCheckedChange={(checked) => {
|
||||
return checked
|
||||
? field.onChange([...field.value, analyst.value])
|
||||
? field.onChange([
|
||||
...field.value,
|
||||
analyst.value,
|
||||
])
|
||||
: field.onChange(
|
||||
field.value?.filter(
|
||||
(value: string) => value !== analyst.value
|
||||
(value: string) =>
|
||||
value !== analyst.value
|
||||
)
|
||||
);
|
||||
}}
|
||||
|
|
@ -191,9 +227,7 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
<FormControl>
|
||||
<Input type="date" {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
選擇分析日期
|
||||
</FormDescription>
|
||||
<FormDescription>選擇分析日期</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
|
@ -209,7 +243,9 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
<FormItem>
|
||||
<FormLabel>研究深度</FormLabel>
|
||||
<Select
|
||||
onValueChange={(value) => field.onChange(parseInt(value))}
|
||||
onValueChange={(value) =>
|
||||
field.onChange(parseInt(value))
|
||||
}
|
||||
defaultValue={field.value.toString()}
|
||||
>
|
||||
<FormControl>
|
||||
|
|
@ -218,14 +254,18 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent className="max-h-80">
|
||||
<SelectItem value="1" className="py-3 cursor-pointer">淺層 - 快速研究</SelectItem>
|
||||
<SelectItem value="3" className="py-3 cursor-pointer">中等 - 適度討論</SelectItem>
|
||||
<SelectItem value="5" className="py-3 cursor-pointer">深層 - 深入研究</SelectItem>
|
||||
<SelectItem value="1" className="py-3 cursor-pointer">
|
||||
淺層 - 快速研究
|
||||
</SelectItem>
|
||||
<SelectItem value="3" className="py-3 cursor-pointer">
|
||||
中等 - 適度討論
|
||||
</SelectItem>
|
||||
<SelectItem value="5" className="py-3 cursor-pointer">
|
||||
深層 - 深入研究
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormDescription>
|
||||
選擇分析深度
|
||||
</FormDescription>
|
||||
<FormDescription>選擇分析深度</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
|
@ -237,8 +277,8 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>快速思維模型</FormLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
defaultValue={field.value}
|
||||
>
|
||||
<FormControl>
|
||||
|
|
@ -248,42 +288,75 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
</FormControl>
|
||||
<SelectContent>
|
||||
{/* OpenAI */}
|
||||
<SelectItem value="gpt-5.1-2025-11-13">OpenAI: GPT-5.1</SelectItem>
|
||||
<SelectItem value="gpt-5-mini-2025-08-07">OpenAI: GPT-5 Mini</SelectItem>
|
||||
<SelectItem value="gpt-5-nano-2025-08-07">OpenAI: GPT-5 Nano</SelectItem>
|
||||
<SelectItem value="gpt-4.1-mini">OpenAI: GPT-4.1 Mini</SelectItem>
|
||||
<SelectItem value="gpt-4.1-nano">OpenAI: GPT-4.1 Nano</SelectItem>
|
||||
<SelectItem value="o4-mini-2025-04-16">OpenAI: o4-mini</SelectItem>
|
||||
|
||||
{/* Anthropic */}
|
||||
<SelectItem value="claude-haiku-4-5-20251001">Anthropic: Claude Haiku 4.5</SelectItem>
|
||||
<SelectItem value="claude-sonnet-4-5-20250929">Anthropic: Claude Sonnet 4.5</SelectItem>
|
||||
<SelectItem value="claude-sonnet-4-0">Anthropic: Claude Sonnet 4</SelectItem>
|
||||
<SelectItem value="claude-3-5-haiku-20241022">Anthropic: Claude 3.5 Haiku</SelectItem>
|
||||
<SelectItem value="claude-3-haiku-20240307">Anthropic: Claude 3 Haiku</SelectItem>
|
||||
<SelectItem value="gpt-5.1-2025-11-13">
|
||||
OpenAI: GPT-5.1
|
||||
</SelectItem>
|
||||
<SelectItem value="gpt-5-mini-2025-08-07">
|
||||
OpenAI: GPT-5 Mini
|
||||
</SelectItem>
|
||||
<SelectItem value="gpt-5-nano-2025-08-07">
|
||||
OpenAI: GPT-5 Nano
|
||||
</SelectItem>
|
||||
<SelectItem value="gpt-4.1-mini">
|
||||
OpenAI: GPT-4.1 Mini
|
||||
</SelectItem>
|
||||
<SelectItem value="gpt-4.1-nano">
|
||||
OpenAI: GPT-4.1 Nano
|
||||
</SelectItem>
|
||||
<SelectItem value="o4-mini-2025-04-16">
|
||||
OpenAI: o4-mini
|
||||
</SelectItem>
|
||||
|
||||
{/* Anthropic */}
|
||||
<SelectItem value="claude-haiku-4-5-20251001">
|
||||
Anthropic: Claude Haiku 4.5
|
||||
</SelectItem>
|
||||
<SelectItem value="claude-sonnet-4-5-20250929">
|
||||
Anthropic: Claude Sonnet 4.5
|
||||
</SelectItem>
|
||||
<SelectItem value="claude-sonnet-4-0">
|
||||
Anthropic: Claude Sonnet 4
|
||||
</SelectItem>
|
||||
<SelectItem value="claude-3-5-haiku-20241022">
|
||||
Anthropic: Claude 3.5 Haiku
|
||||
</SelectItem>
|
||||
<SelectItem value="claude-3-haiku-20240307">
|
||||
Anthropic: Claude 3 Haiku
|
||||
</SelectItem>
|
||||
|
||||
{/* Grok */}
|
||||
<SelectItem value="grok-4-1-fast-reasoning">Grok: 4.1 Fast Reasoning</SelectItem>
|
||||
<SelectItem value="grok-4-1-fast-non-reasoning">Grok: 4.1 Fast Non Reasoning</SelectItem>
|
||||
<SelectItem value="grok-4-fast-reasoning">Grok: 4 Fast Reasoning</SelectItem>
|
||||
<SelectItem value="grok-4-fast-non-reasoning">Grok: 4 Fast Non Reasoning</SelectItem>
|
||||
<SelectItem value="grok-4-1-fast-reasoning">
|
||||
Grok: 4.1 Fast Reasoning
|
||||
</SelectItem>
|
||||
<SelectItem value="grok-4-1-fast-non-reasoning">
|
||||
Grok: 4.1 Fast Non Reasoning
|
||||
</SelectItem>
|
||||
<SelectItem value="grok-4-fast-reasoning">
|
||||
Grok: 4 Fast Reasoning
|
||||
</SelectItem>
|
||||
<SelectItem value="grok-4-fast-non-reasoning">
|
||||
Grok: 4 Fast Non Reasoning
|
||||
</SelectItem>
|
||||
<SelectItem value="grok-4-0709">Grok: 4</SelectItem>
|
||||
<SelectItem value="grok-3">Grok: 3</SelectItem>
|
||||
<SelectItem value="grok-3-mini">Grok: 3 Mini</SelectItem>
|
||||
<SelectItem value="grok-3-mini">
|
||||
Grok: 3 Mini
|
||||
</SelectItem>
|
||||
|
||||
{/* DeepSeek */}
|
||||
<SelectItem value="deepseek-reasoner">DeepSeek: Reasoner</SelectItem>
|
||||
<SelectItem value="deepseek-chat">DeepSeek: Chat</SelectItem>
|
||||
<SelectItem value="deepseek-reasoner">
|
||||
DeepSeek: Reasoner
|
||||
</SelectItem>
|
||||
<SelectItem value="deepseek-chat">
|
||||
DeepSeek: Chat
|
||||
</SelectItem>
|
||||
|
||||
{/* Qwen */}
|
||||
<SelectItem value="qwen3-max">Qwen: 3 Max</SelectItem>
|
||||
<SelectItem value="qwen-plus">Qwen: Plus</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormDescription>
|
||||
快速回應模型
|
||||
</FormDescription>
|
||||
<FormDescription>快速回應模型</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
|
@ -295,7 +368,7 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>深層思維模型</FormLabel>
|
||||
<Select
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
defaultValue={field.value}
|
||||
>
|
||||
|
|
@ -306,42 +379,75 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
</FormControl>
|
||||
<SelectContent>
|
||||
{/* OpenAI */}
|
||||
<SelectItem value="gpt-5.1-2025-11-13">OpenAI: GPT-5.1</SelectItem>
|
||||
<SelectItem value="gpt-5-mini-2025-08-07">OpenAI: GPT-5 Mini</SelectItem>
|
||||
<SelectItem value="gpt-5-nano-2025-08-07">OpenAI: GPT-5 Nano</SelectItem>
|
||||
<SelectItem value="gpt-4.1-mini">OpenAI: GPT-4.1 Mini</SelectItem>
|
||||
<SelectItem value="gpt-4.1-nano">OpenAI: GPT-4.1 Nano</SelectItem>
|
||||
<SelectItem value="o4-mini-2025-04-16">OpenAI: o4-mini</SelectItem>
|
||||
|
||||
{/* Anthropic */}
|
||||
<SelectItem value="claude-haiku-4-5-20251001">Anthropic: Claude Haiku 4.5</SelectItem>
|
||||
<SelectItem value="claude-sonnet-4-5-20250929">Anthropic: Claude Sonnet 4.5</SelectItem>
|
||||
<SelectItem value="claude-sonnet-4-0">Anthropic: Claude Sonnet 4</SelectItem>
|
||||
<SelectItem value="claude-3-5-haiku-20241022">Anthropic: Claude 3.5 Haiku</SelectItem>
|
||||
<SelectItem value="claude-3-haiku-20240307">Anthropic: Claude 3 Haiku</SelectItem>
|
||||
<SelectItem value="gpt-5.1-2025-11-13">
|
||||
OpenAI: GPT-5.1
|
||||
</SelectItem>
|
||||
<SelectItem value="gpt-5-mini-2025-08-07">
|
||||
OpenAI: GPT-5 Mini
|
||||
</SelectItem>
|
||||
<SelectItem value="gpt-5-nano-2025-08-07">
|
||||
OpenAI: GPT-5 Nano
|
||||
</SelectItem>
|
||||
<SelectItem value="gpt-4.1-mini">
|
||||
OpenAI: GPT-4.1 Mini
|
||||
</SelectItem>
|
||||
<SelectItem value="gpt-4.1-nano">
|
||||
OpenAI: GPT-4.1 Nano
|
||||
</SelectItem>
|
||||
<SelectItem value="o4-mini-2025-04-16">
|
||||
OpenAI: o4-mini
|
||||
</SelectItem>
|
||||
|
||||
{/* Anthropic */}
|
||||
<SelectItem value="claude-haiku-4-5-20251001">
|
||||
Anthropic: Claude Haiku 4.5
|
||||
</SelectItem>
|
||||
<SelectItem value="claude-sonnet-4-5-20250929">
|
||||
Anthropic: Claude Sonnet 4.5
|
||||
</SelectItem>
|
||||
<SelectItem value="claude-sonnet-4-0">
|
||||
Anthropic: Claude Sonnet 4
|
||||
</SelectItem>
|
||||
<SelectItem value="claude-3-5-haiku-20241022">
|
||||
Anthropic: Claude 3.5 Haiku
|
||||
</SelectItem>
|
||||
<SelectItem value="claude-3-haiku-20240307">
|
||||
Anthropic: Claude 3 Haiku
|
||||
</SelectItem>
|
||||
|
||||
{/* Grok */}
|
||||
<SelectItem value="grok-4-1-fast-reasoning">Grok: 4.1 Fast Reasoning</SelectItem>
|
||||
<SelectItem value="grok-4-1-fast-non-reasoning">Grok: 4.1 Fast Non Reasoning</SelectItem>
|
||||
<SelectItem value="grok-4-fast-reasoning">Grok: 4 Fast Reasoning</SelectItem>
|
||||
<SelectItem value="grok-4-fast-non-reasoning">Grok: 4 Fast Non Reasoning</SelectItem>
|
||||
<SelectItem value="grok-4-1-fast-reasoning">
|
||||
Grok: 4.1 Fast Reasoning
|
||||
</SelectItem>
|
||||
<SelectItem value="grok-4-1-fast-non-reasoning">
|
||||
Grok: 4.1 Fast Non Reasoning
|
||||
</SelectItem>
|
||||
<SelectItem value="grok-4-fast-reasoning">
|
||||
Grok: 4 Fast Reasoning
|
||||
</SelectItem>
|
||||
<SelectItem value="grok-4-fast-non-reasoning">
|
||||
Grok: 4 Fast Non Reasoning
|
||||
</SelectItem>
|
||||
<SelectItem value="grok-4-0709">Grok: 4</SelectItem>
|
||||
<SelectItem value="grok-3">Grok: 3</SelectItem>
|
||||
<SelectItem value="grok-3-mini">Grok: 3 Mini</SelectItem>
|
||||
<SelectItem value="grok-3-mini">
|
||||
Grok: 3 Mini
|
||||
</SelectItem>
|
||||
|
||||
{/* DeepSeek */}
|
||||
<SelectItem value="deepseek-reasoner">DeepSeek: Reasoner</SelectItem>
|
||||
<SelectItem value="deepseek-chat">DeepSeek: Chat</SelectItem>
|
||||
<SelectItem value="deepseek-reasoner">
|
||||
DeepSeek: Reasoner
|
||||
</SelectItem>
|
||||
<SelectItem value="deepseek-chat">
|
||||
DeepSeek: Chat
|
||||
</SelectItem>
|
||||
|
||||
{/* Qwen */}
|
||||
<SelectItem value="qwen3-max">Qwen: 3 Max</SelectItem>
|
||||
<SelectItem value="qwen-plus">Qwen: Plus</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormDescription>
|
||||
複雜推理模型
|
||||
</FormDescription>
|
||||
<FormDescription>複雜推理模型</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
|
|
@ -349,10 +455,9 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{/* API Configuration Section */}
|
||||
<div className="space-y-4 border-t pt-6 mt-6">
|
||||
<h3 className="text-lg font-semibold">API 配置</h3>
|
||||
|
||||
{/* API Configuration Section */}
|
||||
<div className="space-y-4 border-t pt-6 mt-6">
|
||||
<h3 className="text-lg font-semibold">API 配置</h3>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
|
|
@ -372,12 +477,11 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
[
|
||||
"https://api.openai.com/v1",
|
||||
"https://api.anthropic.com/",
|
||||
"https://generativelanguage.googleapis.com/v1",
|
||||
"https://api.x.ai/v1",
|
||||
"https://api.deepseek.com",
|
||||
"https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
|
||||
].includes(field.value || "")
|
||||
? field.value
|
||||
"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
||||
].includes(field.value || "")
|
||||
? field.value
|
||||
: "custom"
|
||||
}
|
||||
>
|
||||
|
|
@ -387,35 +491,45 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="https://api.openai.com/v1">OpenAI (預設)</SelectItem>
|
||||
<SelectItem value="https://api.anthropic.com/">Anthropic</SelectItem>
|
||||
<SelectItem value="https://generativelanguage.googleapis.com/v1">Google Gemini</SelectItem>
|
||||
<SelectItem value="https://api.x.ai/v1">Grok (xAI)</SelectItem>
|
||||
<SelectItem value="https://api.deepseek.com">DeepSeek</SelectItem>
|
||||
<SelectItem value="https://dashscope-intl.aliyuncs.com/compatible-mode/v1">Qwen (Alibaba)</SelectItem>
|
||||
<SelectItem value="https://api.openai.com/v1">
|
||||
OpenAI (預設)
|
||||
</SelectItem>
|
||||
<SelectItem value="https://api.anthropic.com/">
|
||||
Anthropic
|
||||
</SelectItem>
|
||||
<SelectItem value="https://api.x.ai/v1">
|
||||
Grok (xAI)
|
||||
</SelectItem>
|
||||
<SelectItem value="https://api.deepseek.com">
|
||||
DeepSeek
|
||||
</SelectItem>
|
||||
<SelectItem value="https://dashscope-intl.aliyuncs.com/compatible-mode/v1">
|
||||
Qwen (Alibaba)
|
||||
</SelectItem>
|
||||
<SelectItem value="custom">自訂端點</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
|
||||
{(![
|
||||
"https://api.openai.com/v1",
|
||||
"https://api.anthropic.com/",
|
||||
"https://generativelanguage.googleapis.com/v1",
|
||||
"https://api.x.ai/v1",
|
||||
"https://api.deepseek.com",
|
||||
"https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
|
||||
].includes(field.value || "") || field.value === "") && (
|
||||
"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
||||
].includes(field.value || "") ||
|
||||
field.value === "") && (
|
||||
<div className="mt-2">
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder="請輸入自訂 Base URL"
|
||||
value={field.value || ""}
|
||||
onChange={field.onChange}
|
||||
<Input
|
||||
placeholder="請輸入自訂 Base URL"
|
||||
value={field.value || ""}
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
<FormDescription>
|
||||
快速思維模型的 API 基礎網址
|
||||
</FormDescription>
|
||||
|
|
@ -459,12 +573,11 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
[
|
||||
"https://api.openai.com/v1",
|
||||
"https://api.anthropic.com/",
|
||||
"https://generativelanguage.googleapis.com/v1",
|
||||
"https://api.x.ai/v1",
|
||||
"https://api.deepseek.com",
|
||||
"https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
|
||||
].includes(field.value || "")
|
||||
? field.value
|
||||
"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
||||
].includes(field.value || "")
|
||||
? field.value
|
||||
: "custom"
|
||||
}
|
||||
>
|
||||
|
|
@ -474,35 +587,45 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="https://api.openai.com/v1">OpenAI (預設)</SelectItem>
|
||||
<SelectItem value="https://api.anthropic.com/">Anthropic</SelectItem>
|
||||
<SelectItem value="https://generativelanguage.googleapis.com/v1">Google Gemini</SelectItem>
|
||||
<SelectItem value="https://api.x.ai/v1">Grok (xAI)</SelectItem>
|
||||
<SelectItem value="https://api.deepseek.com">DeepSeek</SelectItem>
|
||||
<SelectItem value="https://dashscope-intl.aliyuncs.com/compatible-mode/v1">Qwen (Alibaba)</SelectItem>
|
||||
<SelectItem value="https://api.openai.com/v1">
|
||||
OpenAI (預設)
|
||||
</SelectItem>
|
||||
<SelectItem value="https://api.anthropic.com/">
|
||||
Anthropic
|
||||
</SelectItem>
|
||||
<SelectItem value="https://api.x.ai/v1">
|
||||
Grok (xAI)
|
||||
</SelectItem>
|
||||
<SelectItem value="https://api.deepseek.com">
|
||||
DeepSeek
|
||||
</SelectItem>
|
||||
<SelectItem value="https://dashscope-intl.aliyuncs.com/compatible-mode/v1">
|
||||
Qwen (Alibaba)
|
||||
</SelectItem>
|
||||
<SelectItem value="custom">自訂端點</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
|
||||
{(![
|
||||
"https://api.openai.com/v1",
|
||||
"https://api.anthropic.com/",
|
||||
"https://generativelanguage.googleapis.com/v1",
|
||||
"https://api.x.ai/v1",
|
||||
"https://api.deepseek.com",
|
||||
"https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
|
||||
].includes(field.value || "") || field.value === "") && (
|
||||
"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
||||
].includes(field.value || "") ||
|
||||
field.value === "") && (
|
||||
<div className="mt-2">
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder="請輸入自訂 Base URL"
|
||||
value={field.value || ""}
|
||||
onChange={field.onChange}
|
||||
<Input
|
||||
placeholder="請輸入自訂 Base URL"
|
||||
value={field.value || ""}
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
<FormDescription>
|
||||
深層思維模型的 API 基礎網址
|
||||
</FormDescription>
|
||||
|
|
@ -543,7 +666,8 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
}
|
||||
}}
|
||||
defaultValue={
|
||||
field.value === "https://api.openai.com/v1" || !field.value
|
||||
field.value === "https://api.openai.com/v1" ||
|
||||
!field.value
|
||||
? "https://api.openai.com/v1"
|
||||
: "custom"
|
||||
}
|
||||
|
|
@ -554,23 +678,25 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="https://api.openai.com/v1">OpenAI (預設)</SelectItem>
|
||||
<SelectItem value="https://api.openai.com/v1">
|
||||
OpenAI (預設)
|
||||
</SelectItem>
|
||||
<SelectItem value="custom">自訂端點</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
|
||||
|
||||
{field.value !== "https://api.openai.com/v1" && (
|
||||
<div className="mt-2">
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder="請輸入自訂 Base URL"
|
||||
value={field.value || ""}
|
||||
onChange={field.onChange}
|
||||
<Input
|
||||
placeholder="請輸入自訂 Base URL"
|
||||
value={field.value || ""}
|
||||
onChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
<FormDescription>
|
||||
嵌入向量生成的 API 端點(用於記憶體系統)
|
||||
</FormDescription>
|
||||
|
|
@ -603,7 +729,11 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
<FormItem>
|
||||
<FormLabel>Alpha Vantage API Key *</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="password" placeholder="輸入 Alpha Vantage API Key(必填)" {...field} />
|
||||
<Input
|
||||
type="password"
|
||||
placeholder="輸入 Alpha Vantage API Key(必填)"
|
||||
{...field}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
用於獲取市場基本面數據(必填)
|
||||
|
|
@ -614,7 +744,12 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
/>
|
||||
</div>
|
||||
|
||||
<Button type="submit" className="w-full" disabled={loading} size="lg">
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-full"
|
||||
disabled={loading}
|
||||
size="lg"
|
||||
>
|
||||
{loading ? "執行分析中..." : "執行分析"}
|
||||
</Button>
|
||||
</form>
|
||||
|
|
|
|||
Loading…
Reference in New Issue