diff --git a/surfsense_backend/app/schemas/search_space.py b/surfsense_backend/app/schemas/search_space.py index 00bfdc0f6..49b5cd094 100644 --- a/surfsense_backend/app/schemas/search_space.py +++ b/surfsense_backend/app/schemas/search_space.py @@ -24,4 +24,4 @@ class SearchSpaceRead(SearchSpaceBase, IDModel, TimestampModel): created_at: datetime user_id: uuid.UUID - model_config = ConfigDict(from_attributes=True) + model_config = ConfigDict(from_attributes=True) \ No newline at end of file diff --git a/surfsense_web/components/inference-params-editor.tsx b/surfsense_web/components/inference-params-editor.tsx new file mode 100644 index 000000000..df198cfa0 --- /dev/null +++ b/surfsense_web/components/inference-params-editor.tsx @@ -0,0 +1,138 @@ +"use client"; + +import { useState } from "react"; +import { Plus, Trash2 } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; + +interface InferenceParamsEditorProps { + params: Record; + setParams: (newParams: Record) => void; +} + +const PARAM_KEYS = ["temperature", "max_tokens", "top_k", "top_p"] as const; + +export default function InferenceParamsEditor({ + params, + setParams, +}: InferenceParamsEditorProps) { + const [selectedKey, setSelectedKey] = useState(""); + const [value, setValue] = useState(""); + + const handleAdd = () => { + if (!selectedKey || value === "") return; + + if (params[selectedKey]) { + alert(`${selectedKey} already exists`); + return; + } + + const numericValue = Number(value); + + if ((selectedKey === "temperature" || selectedKey === "top_p") && (isNaN(numericValue) || numericValue < 0 || numericValue > 1)) { + alert("Value must be a number between 0 and 1"); + return; + } + + if ((selectedKey === "max_tokens" || selectedKey === "top_k") && (!Number.isInteger(numericValue) || numericValue < 0)) { + alert("Value must be a non-negative integer"); + return; + } + + setParams({ + ...params, + [selectedKey]: isNaN(numericValue) ? value : numericValue, + }); + + setSelectedKey(""); + setValue(""); + }; + + const handleDelete = (key: string) => { + const newParams = { ...params }; + delete newParams[key]; + setParams(newParams); + }; + + return ( +
+
+
+ + +
+ +
+ + setValue(e.target.value)} + className="w-full" + /> +
+ + +
+ +
+ + {Object.keys(params).length > 0 && ( +
+ + + + + + + + + + {Object.entries(params).map(([key, val]) => ( + + + + + + ))} + +
KeyValueActions
{key}{val.toString()} + +
+
+ )} +
+ ); +} diff --git a/surfsense_web/components/onboard/add-provider-step.tsx b/surfsense_web/components/onboard/add-provider-step.tsx index 62f5bc3b1..f582000a3 100644 --- a/surfsense_web/components/onboard/add-provider-step.tsx +++ b/surfsense_web/components/onboard/add-provider-step.tsx @@ -20,6 +20,8 @@ import { import { LLM_PROVIDERS } from "@/contracts/enums/llm-providers"; import { type CreateLLMConfig, useLLMConfigs } from "@/hooks/use-llm-configs"; +import InferenceParamsEditor from "../inference-params-editor"; + interface AddProviderStepProps { onConfigCreated?: () => void; onConfigDeleted?: () => void; @@ -72,6 +74,10 @@ export function AddProviderStep({ onConfigCreated, onConfigDeleted }: AddProvide const selectedProvider = LLM_PROVIDERS.find((p) => p.value === formData.provider); + const handleParamsChange = (newParams: Record) => { + setFormData((prev) => ({ ...prev, litellm_params: newParams })); + }; + return (
{/* Info Alert */} @@ -239,6 +245,15 @@ export function AddProviderStep({ onConfigCreated, onConfigDeleted }: AddProvide />
+ {/* Optional Inference Parameters */} +
+ +
+ +
+ {/* Optional Inference Parameters */} +
+ + setFormData((prev) => ({ ...prev, litellm_params: newParams })) + } + /> +
+