fiemwl / src /app /(dashboard) /dashboard /settings /components /CompressionSettingsTab.tsx
automindy's picture
Upload 1980 files
6111b2b verified
Raw
History Blame Contribute Delete
36.7 kB
"use client";
import { useState, useEffect } from "react";
import { Card, Button } from "@/shared/components";
import { useTranslations } from "next-intl";
type CompressionMode = "off" | "lite" | "standard" | "aggressive" | "ultra" | "rtk" | "stacked";
type CavemanIntensity = "lite" | "full" | "ultra";
interface CavemanConfig {
enabled: boolean;
compressRoles: ("user" | "assistant" | "system")[];
skipRules: string[];
minMessageLength: number;
preservePatterns: string[];
intensity: CavemanIntensity;
}
interface CavemanOutputModeConfig {
enabled: boolean;
intensity: CavemanIntensity;
autoClarity: boolean;
}
interface AggressiveConfig {
thresholds: {
fullSummary: number;
moderate: number;
light: number;
verbatim: number;
};
toolStrategies: {
fileContent: boolean;
grepSearch: boolean;
shellOutput: boolean;
json: boolean;
errorMessage: boolean;
};
summarizerEnabled: boolean;
maxTokensPerMessage: number;
minSavingsThreshold: number;
}
interface UltraConfig {
enabled: boolean;
compressionRate: number;
minScoreThreshold: number;
slmFallbackToAggressive: boolean;
modelPath?: string;
maxTokensPerMessage: number;
}
interface CompressionConfig {
enabled: boolean;
defaultMode: CompressionMode;
autoTriggerMode?: CompressionMode;
autoTriggerTokens: number;
cacheMinutes: number;
preserveSystemPrompt: boolean;
mcpDescriptionCompressionEnabled?: boolean;
comboOverrides: Record<string, CompressionMode>;
cavemanConfig?: CavemanConfig;
cavemanOutputMode?: CavemanOutputModeConfig;
aggressive?: AggressiveConfig;
ultra?: UltraConfig;
}
interface RuleMetadata {
name: string;
category: string;
context: string;
minIntensity: CavemanIntensity;
intensities?: CavemanIntensity[];
description: string;
}
const MODES: { value: CompressionMode; labelKey: string; descKey: string; icon: string }[] = [
{
value: "off",
labelKey: "compressionModeOff",
descKey: "compressionModeOffDesc",
icon: "block",
},
{
value: "lite",
labelKey: "compressionModeLite",
descKey: "compressionModeLiteDesc",
icon: "compress",
},
{
value: "standard",
labelKey: "compressionModeStandard",
descKey: "compressionModeStandardDesc",
icon: "speed",
},
{
value: "aggressive",
labelKey: "compressionModeAggressive",
descKey: "compressionModeAggressiveDesc",
icon: "bolt",
},
{
value: "ultra",
labelKey: "compressionModeUltra",
descKey: "compressionModeUltraDesc",
icon: "filter_alt",
},
{
value: "rtk",
labelKey: "compressionModeRtk",
descKey: "compressionModeRtkDesc",
icon: "filter_list",
},
{
value: "stacked",
labelKey: "compressionModeStacked",
descKey: "compressionModeStackedDesc",
icon: "hub",
},
];
const ROLE_OPTIONS: { value: "user" | "assistant" | "system"; labelKey: string }[] = [
{ value: "user", labelKey: "compressionRoleUser" },
{ value: "assistant", labelKey: "compressionRoleAssistant" },
{ value: "system", labelKey: "compressionRoleSystem" },
];
export default function CompressionSettingsTab() {
const t = useTranslations("settings");
const [config, setConfig] = useState<CompressionConfig>({
enabled: false,
defaultMode: "off",
autoTriggerTokens: 0,
cacheMinutes: 5,
preserveSystemPrompt: true,
comboOverrides: {},
cavemanConfig: {
enabled: true,
compressRoles: ["user"],
skipRules: [],
minMessageLength: 50,
preservePatterns: [],
intensity: "full",
},
cavemanOutputMode: {
enabled: false,
intensity: "full",
autoClarity: true,
},
aggressive: {
thresholds: { fullSummary: 5, moderate: 3, light: 2, verbatim: 2 },
toolStrategies: {
fileContent: true,
grepSearch: true,
shellOutput: true,
json: true,
errorMessage: true,
},
summarizerEnabled: true,
maxTokensPerMessage: 2048,
minSavingsThreshold: 0.05,
},
ultra: {
enabled: false,
compressionRate: 0.5,
minScoreThreshold: 0.3,
slmFallbackToAggressive: true,
maxTokensPerMessage: 0,
},
});
const [saving, setSaving] = useState(false);
const [loading, setLoading] = useState(true);
const [status, setStatus] = useState<"" | "saved" | "error">("");
const [ruleMetadata, setRuleMetadata] = useState<RuleMetadata[]>([]);
useEffect(() => {
fetch("/api/settings/compression")
.then((r) => (r.ok ? r.json() : null))
.then((data) => {
if (data) setConfig(data);
})
.catch(() => {})
.finally(() => setLoading(false));
fetch("/api/compression/rules")
.then((r) => (r.ok ? r.json() : null))
.then((data) => {
if (Array.isArray(data?.rules)) setRuleMetadata(data.rules);
})
.catch(() => {});
}, []);
const save = async (updates: Partial<CompressionConfig>) => {
const newConfig = { ...config, ...updates };
setConfig(newConfig);
setSaving(true);
setStatus("");
try {
const res = await fetch("/api/settings/compression", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(newConfig),
});
if (res.ok) {
setStatus("saved");
setTimeout(() => setStatus(""), 2000);
} else {
setStatus("error");
}
} catch {
setStatus("error");
} finally {
setSaving(false);
}
};
const toggleCavemanRole = (role: "user" | "assistant" | "system") => {
const currentRoles = config.cavemanConfig?.compressRoles ?? ["user"];
const newRoles = currentRoles.includes(role)
? currentRoles.filter((r) => r !== role)
: [...currentRoles, role];
save({
cavemanConfig: { ...config.cavemanConfig!, compressRoles: newRoles },
});
};
const toggleCavemanRule = (rule: string) => {
const currentSkip = config.cavemanConfig?.skipRules ?? [];
const newSkip = currentSkip.includes(rule)
? currentSkip.filter((r) => r !== rule)
: [...currentSkip, rule];
save({
cavemanConfig: { ...config.cavemanConfig!, skipRules: newSkip },
});
};
if (loading) {
return (
<Card className="p-6">
<p className="text-sm text-text-muted">{t("loading")}</p>
</Card>
);
}
return (
<Card className="p-6">
<div className="flex items-center gap-3 mb-5">
<div className="p-2 rounded-lg bg-blue-500/10 text-blue-500">
<span className="material-symbols-outlined text-[20px]" aria-hidden="true">
compress
</span>
</div>
<div>
<h3 className="text-lg font-semibold">{t("compressionTitle")}</h3>
<p className="text-sm text-text-muted">{t("compressionDesc")}</p>
</div>
{status === "saved" && (
<span className="ml-auto text-xs font-medium text-emerald-500 flex items-center gap-1">
<span className="material-symbols-outlined text-[14px]">check_circle</span> {t("saved")}
</span>
)}
{status === "error" && (
<span className="ml-auto text-xs font-medium text-red-500 flex items-center gap-1">
<span className="material-symbols-outlined text-[14px]">error</span> {t("saveFailed")}
</span>
)}
</div>
<div className="space-y-6">
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("enabled")}</span>
<button
onClick={() => save({ enabled: !config.enabled })}
className={`relative w-10 h-5 rounded-full transition-colors ${
config.enabled ? "bg-green-500" : "bg-border"
}`}
>
<span
className={`absolute top-0.5 w-4 h-4 rounded-full bg-white transition-transform ${
config.enabled ? "left-5" : "left-0.5"
}`}
/>
</button>
</label>
{config.enabled && (
<div className="space-y-3">
<h4 className="text-sm font-medium text-text-main">{t("compressionMode")}</h4>
<div className="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-7 gap-2">
{MODES.map((m) => (
<button
key={m.value}
onClick={() => save({ defaultMode: m.value })}
disabled={saving}
className={`flex items-start gap-3 p-3 rounded-lg border text-left transition-all ${
config.defaultMode === m.value
? "border-blue-500/50 bg-blue-500/5 ring-1 ring-blue-500/20"
: "border-border/50 hover:border-border hover:bg-surface/30"
}`}
>
<span
className={`material-symbols-outlined text-[20px] mt-0.5 ${
config.defaultMode === m.value ? "text-blue-500" : "text-text-muted"
}`}
>
{m.icon}
</span>
<div className="min-w-0">
<p
className={`text-sm font-medium ${
config.defaultMode === m.value ? "text-blue-400" : ""
}`}
>
{t(m.labelKey)}
</p>
<p className="text-xs text-text-muted mt-0.5 leading-relaxed">{t(m.descKey)}</p>
</div>
</button>
))}
</div>
</div>
)}
{config.enabled && (
<div className="space-y-3 pt-4 border-t border-border/30">
<h4 className="text-sm font-medium text-text-main">{t("compressionGeneral")}</h4>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("compressionAutoTrigger")}</span>
<div className="flex items-center gap-2">
<input
type="number"
min={0}
max={100000}
value={config.autoTriggerTokens}
onChange={(e) => save({ autoTriggerTokens: parseInt(e.target.value) || 0 })}
className="w-24 px-2 py-1 text-sm rounded border border-border bg-surface text-text-main"
/>
<span className="text-xs text-text-muted">{t("tokens")}</span>
</div>
</label>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">
{t("compressionSettingsAutoTriggerMode")}
</span>
<select
value={config.autoTriggerMode ?? "lite"}
onChange={(e) => save({ autoTriggerMode: e.target.value as CompressionMode })}
className="w-36 px-2 py-1 text-sm rounded border border-border bg-surface text-text-main"
>
{MODES.filter((mode) => mode.value !== "off").map((mode) => (
<option key={mode.value} value={mode.value}>
{mode.value}
</option>
))}
</select>
</label>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("compressionCacheTTL")}</span>
<div className="flex items-center gap-2">
<input
type="number"
min={0}
max={1440}
value={config.cacheMinutes}
onChange={(e) => save({ cacheMinutes: parseInt(e.target.value) || 5 })}
className="w-24 px-2 py-1 text-sm rounded border border-border bg-surface text-text-main"
/>
<span className="text-xs text-text-muted">{t("minutes")}</span>
</div>
</label>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("compressionPreserveSystem")}</span>
<button
onClick={() => save({ preserveSystemPrompt: !config.preserveSystemPrompt })}
className={`relative w-10 h-5 rounded-full transition-colors ${
config.preserveSystemPrompt ? "bg-green-500" : "bg-border"
}`}
>
<span
className={`absolute top-0.5 w-4 h-4 rounded-full bg-white transition-transform ${
config.preserveSystemPrompt ? "left-5" : "left-0.5"
}`}
/>
</button>
</label>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">
{t("compressionSettingsMcpDescriptionCompression")}
</span>
<button
onClick={() =>
save({
mcpDescriptionCompressionEnabled:
config.mcpDescriptionCompressionEnabled === false,
})
}
className={`relative w-10 h-5 rounded-full transition-colors ${
config.mcpDescriptionCompressionEnabled !== false ? "bg-green-500" : "bg-border"
}`}
>
<span
className={`absolute top-0.5 w-4 h-4 rounded-full bg-white transition-transform ${
config.mcpDescriptionCompressionEnabled !== false ? "left-5" : "left-0.5"
}`}
/>
</button>
</label>
</div>
)}
{config.enabled &&
config.defaultMode !== "off" &&
config.defaultMode !== "lite" &&
config.cavemanConfig && (
<div className="space-y-3 pt-4 border-t border-border/30">
<div className="flex items-center justify-between">
<div>
<h4 className="text-sm font-medium text-text-main">
{t("compressionCavemanConfig")}
</h4>
<p className="text-xs text-text-muted mt-0.5">
{t("compressionCavemanConfigDesc")}
</p>
</div>
<button
onClick={() =>
save({
cavemanConfig: {
...config.cavemanConfig!,
enabled: !config.cavemanConfig!.enabled,
},
})
}
className={`relative w-10 h-5 rounded-full transition-colors ${
config.cavemanConfig.enabled ? "bg-green-500" : "bg-border"
}`}
>
<span
className={`absolute top-0.5 w-4 h-4 rounded-full bg-white transition-transform ${
config.cavemanConfig.enabled ? "left-5" : "left-0.5"
}`}
/>
</button>
</div>
{config.cavemanConfig.enabled && (
<>
<div className="space-y-2">
<p className="text-sm text-text-muted">{t("compressionRoles")}</p>
<div className="flex flex-wrap gap-2">
{ROLE_OPTIONS.map((opt) => (
<button
key={opt.value}
onClick={() => toggleCavemanRole(opt.value)}
className={`px-3 py-1.5 rounded-lg text-xs font-medium border transition-all ${
config.cavemanConfig!.compressRoles.includes(opt.value)
? "border-blue-500/50 bg-blue-500/10 text-blue-400"
: "border-border/50 text-text-muted hover:border-border"
}`}
>
{t(opt.labelKey)}
</button>
))}
</div>
</div>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("compressionMinLength")}</span>
<input
type="number"
min={0}
max={100000}
value={config.cavemanConfig.minMessageLength}
onChange={(e) =>
save({
cavemanConfig: {
...config.cavemanConfig!,
minMessageLength: parseInt(e.target.value) || 50,
},
})
}
className="w-24 px-2 py-1 text-sm rounded border border-border bg-surface text-text-main"
/>
</label>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">
{t("compressionSettingsCavemanIntensity")}
</span>
<select
value={config.cavemanConfig.intensity}
onChange={(e) =>
save({
cavemanConfig: {
...config.cavemanConfig!,
intensity: e.target.value as CavemanIntensity,
},
})
}
className="w-28 px-2 py-1 text-sm rounded border border-border bg-surface text-text-main"
>
<option value="lite">lite</option>
<option value="full">full</option>
<option value="ultra">ultra</option>
</select>
</label>
<div className="space-y-2">
<p className="text-sm text-text-muted">{t("compressionSkipRules")}</p>
<p className="text-xs text-text-muted">{t("compressionSkipRulesDesc")}</p>
<div className="grid grid-cols-2 sm:grid-cols-3 gap-1.5">
{ruleMetadata.map((rule) => (
<button
key={rule.name}
onClick={() => toggleCavemanRule(rule.name)}
title={`${rule.category} · ${rule.context} · ${(rule.intensities ?? [rule.minIntensity]).join("/")}`}
className={`px-2 py-1 rounded text-xs border transition-all ${
config.cavemanConfig!.skipRules.includes(rule.name)
? "border-red-500/50 bg-red-500/10 text-red-400 line-through"
: "border-border/50 text-text-muted hover:border-border"
}`}
>
{rule.name.replace(/_/g, " ")}
</button>
))}
</div>
</div>
<div className="space-y-2">
<p className="text-sm text-text-muted">{t("compressionPreservePatterns")}</p>
<p className="text-xs text-text-muted">
{t("compressionPreservePatternsDesc")}
</p>
<textarea
value={(config.cavemanConfig.preservePatterns ?? []).join("\n")}
onChange={(e) => {
const patterns = e.target.value
.split("\n")
.map((p) => p.trim())
.filter(Boolean);
save({
cavemanConfig: {
...config.cavemanConfig!,
preservePatterns: patterns,
},
});
}}
placeholder="https?://\S+\n```[\s\S]*?```"
className="w-full min-h-[80px] px-3 py-2 text-sm rounded-lg border border-border bg-surface text-text-main font-mono resize-y"
/>
</div>
</>
)}
</div>
)}
{config.enabled && config.cavemanOutputMode && (
<div className="space-y-3 pt-4 border-t border-border/30">
<div className="flex items-center justify-between">
<div>
<h4 className="text-sm font-medium text-text-main">
{t("compressionSettingsCavemanOutputMode")}
</h4>
<p className="text-xs text-text-muted mt-0.5">
Injects terse response instructions without rewriting provider output.
</p>
</div>
<button
onClick={() =>
save({
cavemanOutputMode: {
...config.cavemanOutputMode!,
enabled: !config.cavemanOutputMode!.enabled,
},
})
}
className={`relative w-10 h-5 rounded-full transition-colors ${
config.cavemanOutputMode.enabled ? "bg-green-500" : "bg-border"
}`}
>
<span
className={`absolute top-0.5 w-4 h-4 rounded-full bg-white transition-transform ${
config.cavemanOutputMode.enabled ? "left-5" : "left-0.5"
}`}
/>
</button>
</div>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">
{t("compressionSettingsOutputIntensity")}
</span>
<select
value={config.cavemanOutputMode.intensity}
onChange={(e) =>
save({
cavemanOutputMode: {
...config.cavemanOutputMode!,
intensity: e.target.value as CavemanIntensity,
},
})
}
className="w-28 px-2 py-1 text-sm rounded border border-border bg-surface text-text-main"
>
<option value="lite">lite</option>
<option value="full">full</option>
<option value="ultra">ultra</option>
</select>
</label>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">
{t("compressionSettingsAutoClarityBypass")}
</span>
<button
onClick={() =>
save({
cavemanOutputMode: {
...config.cavemanOutputMode!,
autoClarity: !config.cavemanOutputMode!.autoClarity,
},
})
}
className={`relative w-10 h-5 rounded-full transition-colors ${
config.cavemanOutputMode.autoClarity ? "bg-green-500" : "bg-border"
}`}
>
<span
className={`absolute top-0.5 w-4 h-4 rounded-full bg-white transition-transform ${
config.cavemanOutputMode.autoClarity ? "left-5" : "left-0.5"
}`}
/>
</button>
</label>
</div>
)}
{config.enabled && config.defaultMode === "aggressive" && config.aggressive && (
<div className="space-y-3 pt-4 border-t border-border/30">
<div className="flex items-center justify-between">
<div>
<h4 className="text-sm font-medium text-text-main">
{t("compressionAggressiveConfig")}
</h4>
<p className="text-xs text-text-muted mt-0.5">
{t("compressionAggressiveConfigDesc")}
</p>
</div>
</div>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("compressionSummarizerEnabled")}</span>
<button
onClick={() =>
save({
aggressive: {
...config.aggressive!,
summarizerEnabled: !config.aggressive!.summarizerEnabled,
},
})
}
className={`relative w-10 h-5 rounded-full transition-colors ${
config.aggressive.summarizerEnabled ? "bg-green-500" : "bg-border"
}`}
>
<span
className={`absolute top-0.5 w-4 h-4 rounded-full bg-white transition-transform ${
config.aggressive.summarizerEnabled ? "left-5" : "left-0.5"
}`}
/>
</button>
</label>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("compressionMaxTokensPerMessage")}</span>
<div className="flex items-center gap-2">
<input
type="number"
min={256}
max={32768}
value={config.aggressive.maxTokensPerMessage}
onChange={(e) =>
save({
aggressive: {
...config.aggressive!,
maxTokensPerMessage: parseInt(e.target.value) || 2048,
},
})
}
className="w-24 px-2 py-1 text-sm rounded border border-border bg-surface text-text-main"
/>
<span className="text-xs text-text-muted">{t("tokens")}</span>
</div>
</label>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("compressionMinSavings")}</span>
<div className="flex items-center gap-2">
<input
type="number"
min={0}
max={1}
step={0.01}
value={config.aggressive.minSavingsThreshold}
onChange={(e) =>
save({
aggressive: {
...config.aggressive!,
minSavingsThreshold: parseFloat(e.target.value) || 0.05,
},
})
}
className="w-24 px-2 py-1 text-sm rounded border border-border bg-surface text-text-main"
/>
<span className="text-xs text-text-muted">%</span>
</div>
</label>
<div className="space-y-2 pt-2">
<p className="text-sm font-medium text-text-main">
{t("compressionAgingThresholds")}
</p>
<p className="text-xs text-text-muted">{t("compressionAgingThresholdsDesc")}</p>
<div className="grid grid-cols-2 gap-2">
{(["fullSummary", "moderate", "light", "verbatim"] as const).map((tier) => (
<label
key={tier}
className="flex items-center justify-between p-2 rounded border border-border/50"
>
<span className="text-xs text-text-muted capitalize">
{tier.replace(/([A-Z])/g, " $1").trim()}
</span>
<input
type="number"
min={1}
max={100}
value={config.aggressive!.thresholds[tier]}
onChange={(e) =>
save({
aggressive: {
...config.aggressive!,
thresholds: {
...config.aggressive!.thresholds,
[tier]: parseInt(e.target.value) || 2,
},
},
})
}
className="w-16 px-2 py-1 text-xs rounded border border-border bg-surface text-text-main"
/>
</label>
))}
</div>
</div>
<div className="space-y-2 pt-2">
<p className="text-sm font-medium text-text-main">{t("compressionToolStrategies")}</p>
<p className="text-xs text-text-muted">{t("compressionToolStrategiesDesc")}</p>
<div className="flex flex-wrap gap-2">
{(
["fileContent", "grepSearch", "shellOutput", "json", "errorMessage"] as const
).map((strategy) => (
<button
key={strategy}
onClick={() =>
save({
aggressive: {
...config.aggressive!,
toolStrategies: {
...config.aggressive!.toolStrategies,
[strategy]: !config.aggressive!.toolStrategies[strategy],
},
},
})
}
className={`px-3 py-1.5 rounded-lg text-xs font-medium border transition-all ${
config.aggressive!.toolStrategies[strategy]
? "border-blue-500/50 bg-blue-500/10 text-blue-400"
: "border-border/50 text-text-muted hover:border-border"
}`}
>
{strategy.replace(/([A-Z])/g, " $1").trim()}
</button>
))}
</div>
</div>
</div>
)}
{config.enabled && config.defaultMode === "ultra" && config.ultra && (
<div className="space-y-3 pt-4 border-t border-border/30">
<div>
<h4 className="text-sm font-medium text-text-main">{t("compressionUltraConfig")}</h4>
<p className="text-xs text-text-muted mt-0.5">{t("compressionUltraConfigDesc")}</p>
</div>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("enabled")}</span>
<button
onClick={() =>
save({
ultra: {
...config.ultra!,
enabled: !config.ultra!.enabled,
},
})
}
className={`relative w-10 h-5 rounded-full transition-colors ${
config.ultra.enabled ? "bg-green-500" : "bg-border"
}`}
>
<span
className={`absolute top-0.5 w-4 h-4 rounded-full bg-white transition-transform ${
config.ultra.enabled ? "left-5" : "left-0.5"
}`}
/>
</button>
</label>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("compressionUltraRate")}</span>
<input
type="number"
min={0}
max={1}
step={0.05}
value={config.ultra.compressionRate}
onChange={(e) =>
save({
ultra: {
...config.ultra!,
compressionRate: parseFloat(e.target.value) || 0,
},
})
}
className="w-24 px-2 py-1 text-sm rounded border border-border bg-surface text-text-main"
/>
</label>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("compressionUltraMinScore")}</span>
<input
type="number"
min={0}
max={1}
step={0.05}
value={config.ultra.minScoreThreshold}
onChange={(e) =>
save({
ultra: {
...config.ultra!,
minScoreThreshold: parseFloat(e.target.value) || 0,
},
})
}
className="w-24 px-2 py-1 text-sm rounded border border-border bg-surface text-text-main"
/>
</label>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("compressionMaxTokensPerMessage")}</span>
<div className="flex items-center gap-2">
<input
type="number"
min={0}
max={32768}
value={config.ultra.maxTokensPerMessage}
onChange={(e) =>
save({
ultra: {
...config.ultra!,
maxTokensPerMessage: parseInt(e.target.value) || 0,
},
})
}
className="w-24 px-2 py-1 text-sm rounded border border-border bg-surface text-text-main"
/>
<span className="text-xs text-text-muted">{t("tokens")}</span>
</div>
</label>
<label className="flex items-center justify-between">
<span className="text-sm text-text-muted">{t("compressionUltraSlmFallback")}</span>
<button
onClick={() =>
save({
ultra: {
...config.ultra!,
slmFallbackToAggressive: !config.ultra!.slmFallbackToAggressive,
},
})
}
className={`relative w-10 h-5 rounded-full transition-colors ${
config.ultra.slmFallbackToAggressive ? "bg-green-500" : "bg-border"
}`}
>
<span
className={`absolute top-0.5 w-4 h-4 rounded-full bg-white transition-transform ${
config.ultra.slmFallbackToAggressive ? "left-5" : "left-0.5"
}`}
/>
</button>
</label>
<label className="block space-y-1">
<span className="text-sm text-text-muted">{t("compressionUltraModelPath")}</span>
<input
type="text"
value={config.ultra.modelPath ?? ""}
onChange={(e) =>
save({
ultra: {
...config.ultra!,
modelPath: e.target.value.trim() || undefined,
},
})
}
placeholder="/path/to/model.onnx"
className="w-full px-2 py-1 text-sm rounded border border-border bg-surface text-text-main font-mono"
/>
</label>
</div>
)}
</div>
</Card>
);
}