// Copyright (c) 2025 Bytedance Ltd. and/or its affiliates // SPDX-License-Identifier: MIT import { zodResolver } from "@hookform/resolvers/zod"; import { Settings } from "lucide-react"; import { useTranslations } from "next-intl"; import { useEffect, useMemo } from "react"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "~/components/ui/form"; import { Input } from "~/components/ui/input"; import { Label } from "~/components/ui/label"; import { Switch } from "~/components/ui/switch"; import type { SettingsState } from "~/core/store"; import type { Tab } from "./types"; const generalFormSchema = z.object({ autoAcceptedPlan: z.boolean(), maxPlanIterations: z.number().min(1, { message: "Max plan iterations must be at least 1.", }), maxStepNum: z.number().min(1, { message: "Max step number must be at least 1.", }), maxSearchResults: z.number().min(1, { message: "Max search results must be at least 1.", }), // Others enableBackgroundInvestigation: z.boolean(), enableDeepThinking: z.boolean(), reportStyle: z.enum(["academic", "popular_science", "news", "social_media","strategic_investment"]), }); export const GeneralTab: Tab = ({ settings, onChange, }: { settings: SettingsState; onChange: (changes: Partial) => void; }) => { const t = useTranslations("settings.general"); const generalSettings = useMemo(() => settings.general, [settings]); const form = useForm>({ resolver: zodResolver(generalFormSchema, undefined, undefined), defaultValues: generalSettings, mode: "all", reValidateMode: "onBlur", }); const currentSettings = form.watch(); useEffect(() => { let hasChanges = false; for (const key in currentSettings) { if ( currentSettings[key as keyof typeof currentSettings] !== settings.general[key as keyof SettingsState["general"]] ) { hasChanges = true; break; } } if (hasChanges) { onChange({ general: currentSettings }); } }, [currentSettings, onChange, settings]); return (

{t("title")}

(
)} /> ( {t("maxPlanIterations")} field.onChange(parseInt(event.target.value || "0")) } /> {t("maxPlanIterationsDescription")} )} /> ( {t("maxStepsOfPlan")} field.onChange(parseInt(event.target.value || "0")) } /> {t("maxStepsDescription")} )} /> ( {t("maxSearchResults")} field.onChange(parseInt(event.target.value || "0")) } /> {t("maxSearchResultsDescription")} )} />
); }; GeneralTab.displayName = "General"; GeneralTab.icon = Settings;