{messages.map((msg, i) => (
diff --git a/src/components/chat/chat.panels.tsx b/src/components/chat/chat.panels.tsx
index bb6b1e4..c52b508 100644
--- a/src/components/chat/chat.panels.tsx
+++ b/src/components/chat/chat.panels.tsx
@@ -1,5 +1,5 @@
-import { useState } from 'react';
import { SidebarPanel } from '../Sidebar';
+import { Slider, NumberInput, TextInput, Toggle } from '../Inputs';
// ─── Example panels ───────────────────────────────────────────────────────────
@@ -24,43 +24,55 @@ function ConversationHistoryPanel() {
);
}
-function SettingsPanel() {
- const [temp, setTemp] = useState(0.7);
- const [stream, setStream] = useState(true);
+type PanelProps = {
+ settings: Settings;
+ setSettings: React.Dispatch>;
+};
+
+export type Settings = {
+ temp: number;
+ topP: number;
+ topK: number | undefined;
+ maxTokens: number | undefined;
+ numCtx: number | undefined;
+ stop: string[] | undefined;
+ repeatPenalty: number;
+ seed: number | undefined;
+ stream: boolean;
+ keepAlive: string | undefined;
+};
+
+function SettingsPanel({ settings, setSettings }: PanelProps) {
+ const set =
+ (key: K) =>
+ (val: Settings[K]) =>
+ setSettings((prev) => ({ ...prev, [key]: val }));
return (
-
-
-
-
- setTemp(Number(e.target.value))}
- className="flex-1 accent-violet-400"
- />
- {temp}
-
+
+ ,
+ component: ,
},
{
id: 'info',
diff --git a/src/types/chat-api.tsx b/src/types/chat-api.tsx
index b38e5a6..52983da 100644
--- a/src/types/chat-api.tsx
+++ b/src/types/chat-api.tsx
@@ -15,3 +15,45 @@ export type Message = {
role: Role;
content: string;
};
+
+export type ChatRequest = {
+ model: string;
+ stream?: boolean;
+ temperature?: number;
+ top_p?: number;
+ top_k?: number;
+ repeat_penalty?: number;
+ seed?: number;
+ num_ctx?: number;
+ num_predict?: number;
+ stop?: string[];
+ keep_alive?: string;
+ messages: Message[];
+};
+
+export type ChatCompletionResponse = {
+ id: string;
+ object: string;
+ created: number;
+ model: string;
+ choices: ChatChoice[];
+ usage?: Usage;
+};
+
+export type FinishReason =
+ | 'Stop'
+ | 'Length'
+ | 'ContentFilter'
+ | 'ToolCalls';
+
+export type ChatChoice = {
+ index: number;
+ message: Message;
+ finish_reason: FinishReason;
+};
+
+export type Usage = {
+ prompt_tokens: number;
+ completion_tokens: number;
+ total_tokens: number;
+};
\ No newline at end of file
+
+
+
- Sampling
+
- Streaming
-
+
);
@@ -90,7 +102,7 @@ function InfoPanel() {
// ─── Panel registry — add yours here ─────────────────────────────────────────
-export const SIDEBAR_PANELS: SidebarPanel[] = [
+export const SIDEBAR_PANELS = ({ settings, setSettings }: PanelProps): SidebarPanel[] => [
{
id: 'history',
label: 'History',
@@ -117,7 +129,7 @@ export const SIDEBAR_PANELS: SidebarPanel[] = [
/>
),
- component:
+
+
+
+ set('stop')(val ? val.split(',').map((s) => s.trim()) : undefined)
+ } placeholder="Comma separated" />
+
+ Generation
+
+
+
+
+ Control
+
+
+