From 5dca683b8854d6399cb9a5e41dad6c9e0a3a23ce Mon Sep 17 00:00:00 2001 From: Henry Winkel Date: Sat, 16 May 2026 20:50:33 +0200 Subject: [PATCH] feat: add LlmSettings component with model, temperature, debate rounds --- app/components/LlmSettings.tsx | 101 +++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 app/components/LlmSettings.tsx diff --git a/app/components/LlmSettings.tsx b/app/components/LlmSettings.tsx new file mode 100644 index 0000000..e52a467 --- /dev/null +++ b/app/components/LlmSettings.tsx @@ -0,0 +1,101 @@ +import React, { useState, useEffect } from "react"; + +interface LlmSettingsProps { + settings: Record; + onSave: (key: string, value: any) => Promise; + saveError: string | null; +} + +const AVAILABLE_MODELS = [ + "openai/gpt-oss-120b:free", + "openrouter/free", + "deepseek/deepseek-chat:free", + "meta/llama-3.3-70b-instruct:free", +]; + +export default function LlmSettings({ settings, onSave, saveError }: LlmSettingsProps) { + const [model, setModel] = useState(settings["llm.model"] ?? "openai/gpt-oss-120b:free"); + const [temperature, setTemperature] = useState(settings["llm.temperature"] ?? 0.7); + const [maxDebateRounds, setMaxDebateRounds] = useState(settings["llm.maxDebateRounds"] ?? 3); + + useEffect(() => { + setModel(settings["llm.model"] ?? "openai/gpt-oss-120b:free"); + setTemperature(settings["llm.temperature"] ?? 0.7); + setMaxDebateRounds(settings["llm.maxDebateRounds"] ?? 3); + }, [settings]); + + const saveModel = async (value: string) => { + setModel(value); + await onSave("llm.model", value); + }; + + const saveTemperature = async (value: number) => { + setTemperature(value); + await onSave("llm.temperature", value); + }; + + const saveMaxDebateRounds = async (value: number) => { + const clamped = Math.min(10, Math.max(1, value)); + setMaxDebateRounds(clamped); + await onSave("llm.maxDebateRounds", clamped); + }; + + return ( +
+
+

LLM & Agents

+

Configure the language model and agent behavior for trading analysis.

+
+ + {saveError && ( +
{saveError}
+ )} + +
+
+ + +
+ +
+ + saveTemperature(parseFloat(e.target.value))} + className="w-full" + /> +
+ 0.0 (deterministic) + 2.0 (creative) +
+
+ +
+ + saveMaxDebateRounds(parseInt(e.target.value) || 1)} + className="w-32 border border-gray-300 rounded-lg px-4 py-2.5 text-gray-900 focus:ring-2 focus:ring-blue-500" + /> +
+
+
+ ); +}