feat(ui): Ollama parameter catalog (defaults/ranges/help) as single source of truth

This commit is contained in:
iamdoubz committed 2026-07-04 09:21:28 -05:00
1 parent b980c833c4
commit a0ce2e2321
1 file changed
+317
+317
View File
@@ -0,0 +1,317 @@
// Ollama advanced `options` parameters (T5.2) — the single source of truth that
// drives the Settings ▸ AI advanced form: rendering, defaults, per-field reset,
// and only-send-if-changed. System prompt / think / keep_alive are top-level
// request fields handled separately in the UI; everything here goes in `options`.
//
// Defaults + ranges per the Ollama Modelfile/API reference.
export type OllamaGroup = "sampling" | "repetition" | "mirostat" | "context" | "hardware";
export interface OllamaOption {
key: string;
group: OllamaGroup;
label: string;
kind: "number" | "bool" | "enum" | "tags";
/** Undefined = "auto" (no fixed default): the field is empty until set. */
default?: number | boolean;
min?: number;
max?: number;
step?: number;
enumOptions?: { value: number; label: string }[];
help: string;
/** Dimmed unless Mirostat is enabled (mirostat != 0). */
needsMirostat?: boolean;
}
export const OLLAMA_OPTIONS: OllamaOption[] = [
// ── Sampling ──────────────────────────────────────────────────────────────
{
key: "temperature",
group: "sampling",
label: "Temperature",
kind: "number",
default: 0.8,
min: 0,
max: 2,
step: 0.05,
help: "Randomness / creativity. Higher is more creative.",
},
{
key: "top_k",
group: "sampling",
label: "Top K",
kind: "number",
default: 40,
min: 0,
max: 200,
step: 1,
help: "Sample only from the K most likely tokens.",
},
{
key: "top_p",
group: "sampling",
label: "Top P",
kind: "number",
default: 0.9,
min: 0,
max: 1,
step: 0.05,
help: "Nucleus sampling cumulative probability.",
},
{
key: "min_p",
group: "sampling",
label: "Min P",
kind: "number",
default: 0.0,
min: 0,
max: 1,
step: 0.01,
help: "Minimum probability relative to the top token.",
},
{
key: "typical_p",
group: "sampling",
label: "Typical P",
kind: "number",
default: 1.0,
min: 0,
max: 1,
step: 0.05,
help: "Locally-typical sampling.",
},
{
key: "tfs_z",
group: "sampling",
label: "Tail-free (tfs_z)",
kind: "number",
default: 1.0,
min: 0,
max: 2,
step: 0.05,
help: "Tail-free sampling. 1.0 disables it (legacy).",
},
{
key: "seed",
group: "sampling",
label: "Seed",
kind: "number",
default: 0,
min: 0,
step: 1,
help: "Fixed seed → reproducible output. 0 = random.",
},
{
key: "num_predict",
group: "sampling",
label: "Max tokens (num_predict)",
kind: "number",
default: -1,
min: -2,
step: 1,
help: "Max tokens to generate. -1 = unlimited, -2 = fill context.",
},
// ── Repetition ────────────────────────────────────────────────────────────
{
key: "repeat_penalty",
group: "repetition",
label: "Repeat penalty",
kind: "number",
default: 1.1,
min: 0,
max: 2,
step: 0.05,
help: "How strongly to penalize repetition.",
},
{
key: "repeat_last_n",
group: "repetition",
label: "Repeat lookback",
kind: "number",
default: 64,
min: -1,
step: 1,
help: "Tokens to look back for repetition. 0 = off, -1 = num_ctx.",
},
{
key: "presence_penalty",
group: "repetition",
label: "Presence penalty",
kind: "number",
default: 0.0,
min: -2,
max: 2,
step: 0.1,
help: "Penalize tokens that already appeared.",
},
{
key: "frequency_penalty",
group: "repetition",
label: "Frequency penalty",
kind: "number",
default: 0.0,
min: -2,
max: 2,
step: 0.1,
help: "Penalize tokens by how often they appear.",
},
{
key: "penalize_newline",
group: "repetition",
label: "Penalize newlines",
kind: "bool",
default: true,
help: "Apply the repeat penalty to newline tokens.",
},
// ── Mirostat ──────────────────────────────────────────────────────────────
{
key: "mirostat",
group: "mirostat",
label: "Mirostat",
kind: "enum",
default: 0,
enumOptions: [
{ value: 0, label: "Off" },
{ value: 1, label: "Mirostat 1" },
{ value: 2, label: "Mirostat 2" },
],
help: "Adaptive perplexity control.",
},
{
key: "mirostat_tau",
group: "mirostat",
label: "Mirostat τ (tau)",
kind: "number",
default: 5.0,
min: 0,
max: 10,
step: 0.1,
help: "Balance of coherence vs diversity.",
needsMirostat: true,
},
{
key: "mirostat_eta",
group: "mirostat",
label: "Mirostat η (eta)",
kind: "number",
default: 0.1,
min: 0,
max: 1,
step: 0.01,
help: "How fast it adapts to feedback.",
needsMirostat: true,
},
// ── Context & session ─────────────────────────────────────────────────────
{
key: "num_ctx",
group: "context",
label: "Context size (num_ctx)",
kind: "number",
default: 4096,
min: 256,
step: 256,
help: "Context window in tokens.",
},
{
key: "num_keep",
group: "context",
label: "Keep tokens (num_keep)",
kind: "number",
default: 4,
min: 0,
step: 1,
help: "Tokens kept from the start of the prompt when truncating.",
},
{
key: "stop",
group: "context",
label: "Stop sequences",
kind: "tags",
help: "Comma-separated strings that end generation.",
},
// ── Runtime & hardware (rarely needed) ────────────────────────────────────
{
key: "num_batch",
group: "hardware",
label: "Batch size (num_batch)",
kind: "number",
default: 512,
min: 1,
step: 1,
help: "Prompt processing batch size.",
},
{
key: "num_gpu",
group: "hardware",
label: "GPU layers (num_gpu)",
kind: "number",
min: 0,
step: 1,
help: "Layers to offload to the GPU. Blank = auto.",
},
{
key: "main_gpu",
group: "hardware",
label: "Main GPU",
kind: "number",
default: 0,
min: 0,
step: 1,
help: "Which GPU to use for a single-GPU offload.",
},
{
key: "num_thread",
group: "hardware",
label: "CPU threads (num_thread)",
kind: "number",
min: 1,
step: 1,
help: "Threads for computation. Blank = auto.",
},
{
key: "low_vram",
group: "hardware",
label: "Low VRAM",
kind: "bool",
default: false,
help: "Reduce VRAM use at the cost of speed.",
},
{
key: "numa",
group: "hardware",
label: "NUMA",
kind: "bool",
default: false,
help: "Enable NUMA support.",
},
{
key: "use_mmap",
group: "hardware",
label: "Use mmap",
kind: "bool",
default: true,
help: "Memory-map the model file.",
},
{
key: "use_mlock",
group: "hardware",
label: "Use mlock",
kind: "bool",
default: false,
help: "Lock the model in RAM (no swap).",
},
];
export const THINK_OPTIONS = ["off", "low", "medium", "high", "max"] as const;
export const OLLAMA_GROUP_LABELS: Record<OllamaGroup, string> = {
sampling: "Sampling",
repetition: "Repetition",
mirostat: "Mirostat",
context: "Context & session",
hardware: "Runtime & hardware",
};