feat(agents): expose thinking variant configuration in agent settings (#1715)

* feat(agents): expose thinking variant configuration in agent settings

Fix #1425: add variant field to agent config UI so users can configure
thinking/reasoning depth per agent without editing opencode.json.

Changes:
- Added variant to AgentConfig and AgentDraft types in useAgentsStore
- Pass variant in createAgent and updateAgent API calls
- Support null for temperature, top_p, and variant to clear overrides
- Added variant input field in AgentsPage 'Model & Parameters' section
- Added variant to settings search registry
- Added i18n strings for variant field in all 8 non-English locales

The variant field maps to provider-specific parameters (e.g. Anthropic
high/max variant, OpenAI reasoning effort). Users can enter any string
value; the SDK passes it through to the model provider.

Clearing temperature/topP/variant now sends null to the server instead
of omitting the field, which properly removes the override in
opencode.json.

* fix(sync): preserve tool state.time in materialization merge

* chore: trigger re-review

* fix(agents): use thinking variant selector in settings

* fix(agents): preserve thinking variant values

---------

Co-authored-by: Leonid Skorobogatyy <bash@opencode.itc.local>
This commit is contained in:
bashrusakh
2026-06-23 23:22:59 +03:00
committed by GitHub
co-authored by Leonid Skorobogatyy
parent 3d3674d4dd
commit e44efa97d6
13 changed files with 155 additions and 2 deletions
@@ -16,6 +16,7 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip
import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay'; import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay';
import { useI18n } from '@/lib/i18n'; import { useI18n } from '@/lib/i18n';
import { parseModelIdentifier } from '@/lib/modelIdentifier'; import { parseModelIdentifier } from '@/lib/modelIdentifier';
import { useConfigStore } from '@/stores/useConfigStore';
import { import {
Select, Select,
SelectContent, SelectContent,
@@ -23,7 +24,7 @@ import {
SelectTrigger, SelectTrigger,
SelectValue, SelectValue,
} from '@/components/ui/select'; } from '@/components/ui/select';
import { Icon } from "@/components/icon/Icon"; import { Icon } from '@/components/icon/Icon';
type PermissionAction = 'allow' | 'ask' | 'deny'; type PermissionAction = 'allow' | 'ask' | 'deny';
type PermissionRule = { permission: string; pattern: string; action: PermissionAction }; type PermissionRule = { permission: string; pattern: string; action: PermissionAction };
@@ -192,9 +193,31 @@ const buildPermissionConfigWithGlobal = (
return result as AgentConfig['permission']; return result as AgentConfig['permission'];
}; };
type AgentVariantProvider = {
id: string;
models?: Array<{
id?: string;
variants?: Record<string, unknown>;
}>;
};
const getVariantOptionsForModel = (
providers: AgentVariantProvider[],
modelValue: string,
): string[] => {
const parsedModel = parseModelIdentifier(modelValue);
if (!parsedModel) {
return [];
}
const provider = providers.find((item) => item.id === parsedModel.providerId);
const model = provider?.models?.find((item) => item.id === parsedModel.modelId);
return model?.variants ? Object.keys(model.variants) : [];
};
export const AgentsPage: React.FC = () => { export const AgentsPage: React.FC = () => {
const { t } = useI18n(); const { t } = useI18n();
const { isMobile } = useDeviceInfo(); const { isMobile } = useDeviceInfo();
const providers = useConfigStore((state) => state.providers) as AgentVariantProvider[];
const { const {
selectedAgentName, selectedAgentName,
getAgentByName, getAgentByName,
@@ -221,6 +244,7 @@ export const AgentsPage: React.FC = () => {
const [description, setDescription] = React.useState(''); const [description, setDescription] = React.useState('');
const [mode, setMode] = React.useState<'primary' | 'subagent' | 'all'>('subagent'); const [mode, setMode] = React.useState<'primary' | 'subagent' | 'all'>('subagent');
const [model, setModel] = React.useState(''); const [model, setModel] = React.useState('');
const [variant, setVariant] = React.useState('');
const [temperature, setTemperature] = React.useState<number | undefined>(undefined); const [temperature, setTemperature] = React.useState<number | undefined>(undefined);
const [topP, setTopP] = React.useState<number | undefined>(undefined); const [topP, setTopP] = React.useState<number | undefined>(undefined);
const [prompt, setPrompt] = React.useState(''); const [prompt, setPrompt] = React.useState('');
@@ -237,6 +261,7 @@ export const AgentsPage: React.FC = () => {
description: string; description: string;
mode: 'primary' | 'subagent' | 'all'; mode: 'primary' | 'subagent' | 'all';
model: string; model: string;
variant: string;
temperature: number | undefined; temperature: number | undefined;
topP: number | undefined; topP: number | undefined;
prompt: string; prompt: string;
@@ -246,6 +271,15 @@ export const AgentsPage: React.FC = () => {
const currentDirectory = useDirectoryStore((state) => state.currentDirectory ?? null); const currentDirectory = useDirectoryStore((state) => state.currentDirectory ?? null);
const [toolIds, setToolIds] = React.useState<string[]>([]); const [toolIds, setToolIds] = React.useState<string[]>([]);
const variantOptions = React.useMemo(() => getVariantOptionsForModel(providers, model), [model, providers]);
const hasVariantOptions = variantOptions.length > 0;
const selectedVariantValue = React.useMemo(() => {
if (!variant || !variantOptions.includes(variant)) {
return '__default';
}
return variant;
}, [variant, variantOptions]);
const shouldUseVariantSelect = hasVariantOptions && (!variant || variantOptions.includes(variant));
const permissionsBySession = useDirectorySync((state) => state.permission); const permissionsBySession = useDirectorySync((state) => state.permission);
@@ -469,6 +503,7 @@ export const AgentsPage: React.FC = () => {
const descriptionValue = agentDraft.description || ''; const descriptionValue = agentDraft.description || '';
const modeValue = agentDraft.mode || 'subagent'; const modeValue = agentDraft.mode || 'subagent';
const modelValue = agentDraft.model || ''; const modelValue = agentDraft.model || '';
const variantValue = agentDraft.variant || '';
const temperatureValue = agentDraft.temperature; const temperatureValue = agentDraft.temperature;
const topPValue = agentDraft.top_p; const topPValue = agentDraft.top_p;
const promptValue = agentDraft.prompt || ''; const promptValue = agentDraft.prompt || '';
@@ -478,6 +513,7 @@ export const AgentsPage: React.FC = () => {
setDescription(descriptionValue); setDescription(descriptionValue);
setMode(modeValue); setMode(modeValue);
setModel(modelValue); setModel(modelValue);
setVariant(variantValue);
setTemperature(temperatureValue); setTemperature(temperatureValue);
setTopP(topPValue); setTopP(topPValue);
setPrompt(promptValue); setPrompt(promptValue);
@@ -491,6 +527,7 @@ export const AgentsPage: React.FC = () => {
description: descriptionValue, description: descriptionValue,
mode: modeValue, mode: modeValue,
model: modelValue, model: modelValue,
variant: variantValue,
temperature: temperatureValue, temperature: temperatureValue,
topP: topPValue, topP: topPValue,
prompt: promptValue, prompt: promptValue,
@@ -506,6 +543,7 @@ export const AgentsPage: React.FC = () => {
const modelValue = selectedAgent.model?.providerID && selectedAgent.model?.modelID const modelValue = selectedAgent.model?.providerID && selectedAgent.model?.modelID
? `${selectedAgent.model.providerID}/${selectedAgent.model.modelID}` ? `${selectedAgent.model.providerID}/${selectedAgent.model.modelID}`
: ''; : '';
const variantValue = selectedAgent.variant || '';
const temperatureValue = selectedAgent.temperature; const temperatureValue = selectedAgent.temperature;
const topPValue = selectedAgent.topP; const topPValue = selectedAgent.topP;
const promptValue = selectedAgent.prompt || ''; const promptValue = selectedAgent.prompt || '';
@@ -514,6 +552,7 @@ export const AgentsPage: React.FC = () => {
setMode(modeValue); setMode(modeValue);
setModel(modelValue); setModel(modelValue);
setVariant(variantValue);
setTemperature(temperatureValue); setTemperature(temperatureValue);
setTopP(topPValue); setTopP(topPValue);
setPrompt(promptValue); setPrompt(promptValue);
@@ -528,6 +567,7 @@ export const AgentsPage: React.FC = () => {
description: descriptionValue, description: descriptionValue,
mode: modeValue, mode: modeValue,
model: modelValue, model: modelValue,
variant: variantValue,
temperature: temperatureValue, temperature: temperatureValue,
topP: topPValue, topP: topPValue,
prompt: promptValue, prompt: promptValue,
@@ -551,6 +591,7 @@ export const AgentsPage: React.FC = () => {
if (description !== initial.description) return true; if (description !== initial.description) return true;
if (mode !== initial.mode) return true; if (mode !== initial.mode) return true;
if (model !== initial.model) return true; if (model !== initial.model) return true;
if (variant !== initial.variant) return true;
if (temperature !== initial.temperature) return true; if (temperature !== initial.temperature) return true;
if (topP !== initial.topP) return true; if (topP !== initial.topP) return true;
if (prompt !== initial.prompt) return true; if (prompt !== initial.prompt) return true;
@@ -558,7 +599,7 @@ export const AgentsPage: React.FC = () => {
if (!areRulesEqual(permissionRules, initial.permissionRules)) return true; if (!areRulesEqual(permissionRules, initial.permissionRules)) return true;
return false; return false;
}, [description, draftName, draftScope, globalPermission, isNewAgent, mode, model, permissionRules, prompt, temperature, topP]); }, [description, draftName, draftScope, globalPermission, isNewAgent, mode, model, permissionRules, prompt, temperature, topP, variant]);
const handleSave = async () => { const handleSave = async () => {
const agentName = isNewAgent ? draftName.trim().replace(/\s+/g, '-') : selectedAgentName?.trim(); const agentName = isNewAgent ? draftName.trim().replace(/\s+/g, '-') : selectedAgentName?.trim();
@@ -578,6 +619,7 @@ export const AgentsPage: React.FC = () => {
try { try {
const trimmedModel = model.trim(); const trimmedModel = model.trim();
const trimmedVariant = variant.trim();
const trimmedPrompt = prompt.trim(); const trimmedPrompt = prompt.trim();
const permissionConfig = buildPermissionConfigWithGlobal(globalPermission, permissionRules); const permissionConfig = buildPermissionConfigWithGlobal(globalPermission, permissionRules);
const config: AgentConfig = { const config: AgentConfig = {
@@ -585,6 +627,7 @@ export const AgentsPage: React.FC = () => {
description: description.trim() || undefined, description: description.trim() || undefined,
mode, mode,
model: trimmedModel === '' ? null : trimmedModel, model: trimmedModel === '' ? null : trimmedModel,
variant: trimmedVariant === '' ? null : trimmedVariant || undefined,
temperature, temperature,
top_p: topP, top_p: topP,
prompt: trimmedPrompt || (isNewAgent ? undefined : null), prompt: trimmedPrompt || (isNewAgent ? undefined : null),
@@ -777,11 +820,72 @@ export const AgentsPage: React.FC = () => {
} else { } else {
setModel(''); setModel('');
} }
setVariant('');
}} }}
/> />
</div> </div>
</div> </div>
<div data-settings-item="agents.variant" className={cn("py-1.5", isMobile ? "flex flex-col gap-3" : "flex items-center gap-8")}>
<div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "sm:w-56 shrink-0")}>
<div className="flex items-center gap-1.5">
<span className="typography-ui-label text-foreground">{t('settings.agents.page.field.variant')}</span>
<Tooltip>
<TooltipTrigger asChild>
<Icon name="information" className="h-3.5 w-3.5 text-muted-foreground/60 cursor-help" />
</TooltipTrigger>
<TooltipContent sideOffset={8} className="max-w-xs">
{t('settings.agents.page.field.variantTooltip')}
</TooltipContent>
</Tooltip>
</div>
<span className="typography-meta text-muted-foreground">{t('settings.agents.page.field.variantHint')}</span>
</div>
<div className={cn('flex items-center gap-2', isMobile ? 'w-full' : 'w-fit')}>
{shouldUseVariantSelect ? (
<Select
value={selectedVariantValue}
onValueChange={(value) => setVariant(value === '__default' ? '' : value)}
>
<SelectTrigger className={cn('max-w-full', isMobile ? 'w-full' : 'w-fit min-w-[10rem]')}>
<SelectValue placeholder={t('settings.agents.page.field.variantPlaceholder')}>
{(value) => value === '__default' ? t('chat.modelControls.default') : value}
</SelectValue>
</SelectTrigger>
<SelectContent>
<SelectItem value="__default">{t('chat.modelControls.default')}</SelectItem>
{variantOptions.map((variantOption) => (
<SelectItem key={variantOption} value={variantOption}>{variantOption}</SelectItem>
))}
</SelectContent>
</Select>
) : (
<>
<Input
value={variant}
onChange={(event) => setVariant(event.target.value)}
placeholder={t('settings.agents.page.field.variantPlaceholder')}
disabled={!model && !variant}
className={cn('h-7 w-40', isMobile && 'w-full')}
/>
{variant && (
<Button
size="sm"
type="button"
variant="ghost"
onClick={() => setVariant('')}
className="h-7 w-7 px-0 text-muted-foreground hover:text-foreground"
aria-label={t('settings.common.actions.clear')}
title={t('settings.common.actions.clear')}
>
<Icon name="close" className="h-3.5 w-3.5" />
</Button>
)}
</>
)}
</div>
</div>
<div data-settings-item="agents.temperature" className={cn("py-1.5", isMobile ? "flex flex-col gap-3" : "flex items-center gap-8")}> <div data-settings-item="agents.temperature" className={cn("py-1.5", isMobile ? "flex flex-col gap-3" : "flex items-center gap-8")}>
<div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "sm:w-56 shrink-0")}> <div className={cn("flex min-w-0 flex-col", isMobile ? "w-full" : "sm:w-56 shrink-0")}>
<div className="flex items-center gap-1.5"> <div className="flex items-center gap-1.5">
@@ -232,6 +232,7 @@ export const AgentsSidebar: React.FC<AgentsSidebarProps> = ({ onItemSelect }) =>
scope: extAgent.scope || 'user', scope: extAgent.scope || 'user',
description: agent.description, description: agent.description,
model: modelStr, model: modelStr,
variant: agent.variant,
temperature: agent.temperature, temperature: agent.temperature,
top_p: agent.topP, top_p: agent.topP,
prompt: agent.prompt, prompt: agent.prompt,
@@ -277,6 +278,7 @@ export const AgentsSidebar: React.FC<AgentsSidebarProps> = ({ onItemSelect }) =>
name: sanitizedName, name: sanitizedName,
description: renameDialogAgent.description, description: renameDialogAgent.description,
model: renameModelStr, model: renameModelStr,
variant: renameDialogAgent.variant,
temperature: renameDialogAgent.temperature, temperature: renameDialogAgent.temperature,
top_p: renameDialogAgent.topP, top_p: renameDialogAgent.topP,
prompt: renameDialogAgent.prompt, prompt: renameDialogAgent.prompt,
@@ -428,6 +428,10 @@ export const settingsDict = {
'settings.agents.page.field.topPTooltip': 'Nucleus sampling diversity. Lower = likely tokens only.', 'settings.agents.page.field.topPTooltip': 'Nucleus sampling diversity. Lower = likely tokens only.',
'settings.agents.page.field.topPRange': '0.0 to 1.0', 'settings.agents.page.field.topPRange': '0.0 to 1.0',
'settings.agents.page.field.clearTopPAria': 'Clear top p override', 'settings.agents.page.field.clearTopPAria': 'Clear top p override',
'settings.agents.page.field.variant': 'Thinking Variant',
'settings.agents.page.field.variantTooltip': 'Controls the thinking/reasoning depth for this agent. Maps to provider-specific parameters (e.g. Anthropic variant, OpenAI reasoning effort).',
'settings.agents.page.field.variantHint': 'e.g. high, max, low',
'settings.agents.page.field.variantPlaceholder': 'default',
'settings.agents.page.field.systemPromptPlaceholder': 'You are an expert coding assistant...', 'settings.agents.page.field.systemPromptPlaceholder': 'You are an expert coding assistant...',
'settings.agents.page.mode.primary': 'Primary', 'settings.agents.page.mode.primary': 'Primary',
'settings.agents.page.mode.subagent': 'Subagent', 'settings.agents.page.mode.subagent': 'Subagent',
@@ -387,6 +387,10 @@ export const settingsDict = {
"settings.agents.page.field.mode": "Modo", "settings.agents.page.field.mode": "Modo",
"settings.agents.page.field.modeTooltip": "Visibilidad principal vs subagente", "settings.agents.page.field.modeTooltip": "Visibilidad principal vs subagente",
"settings.agents.page.field.overrideModel": "Sobrescribir modelo", "settings.agents.page.field.overrideModel": "Sobrescribir modelo",
"settings.agents.page.field.variant": "Variante de pensamiento",
"settings.agents.page.field.variantTooltip": "Opcional. Si el modelo admite razonamiento, la variante controla la profundidad del razonamiento.",
"settings.agents.page.field.variantHint": "Específico del modelo (p. ej. variante de Anthropic)",
"settings.agents.page.field.variantPlaceholder": "p. ej. high, max, low, none",
"settings.agents.page.field.temperature": "Temperatura", "settings.agents.page.field.temperature": "Temperatura",
"settings.agents.page.field.temperatureTooltip": "Controla la aleatoriedad. Mayor = más creativo, menor = más enfocado.", "settings.agents.page.field.temperatureTooltip": "Controla la aleatoriedad. Mayor = más creativo, menor = más enfocado.",
"settings.agents.page.field.temperatureRange": "0.0 a 2.0", "settings.agents.page.field.temperatureRange": "0.0 a 2.0",
@@ -376,6 +376,10 @@ export const settingsDict = {
'settings.agents.page.field.mode': 'Mode', 'settings.agents.page.field.mode': 'Mode',
'settings.agents.page.field.modeTooltip': 'Visibilité principale et sous-agent', 'settings.agents.page.field.modeTooltip': 'Visibilité principale et sous-agent',
'settings.agents.page.field.overrideModel': 'Remplacer le modèle', 'settings.agents.page.field.overrideModel': 'Remplacer le modèle',
'settings.agents.page.field.variant': 'Variante de réflexion',
'settings.agents.page.field.variantTooltip': 'Optionnel. Si le modèle prend en charge le raisonnement, la variante contrôle la profondeur du raisonnement.',
'settings.agents.page.field.variantHint': 'Spécifique au modèle (par ex. variante Anthropic)',
'settings.agents.page.field.variantPlaceholder': 'par ex. high, max, low, none',
'settings.agents.page.field.temperature': 'Température', 'settings.agents.page.field.temperature': 'Température',
'settings.agents.page.field.temperatureTooltip': 'Contrôle le caractère aléatoire. Plus élevé = créatif, Inférieur = concentré.', 'settings.agents.page.field.temperatureTooltip': 'Contrôle le caractère aléatoire. Plus élevé = créatif, Inférieur = concentré.',
'settings.agents.page.field.temperatureRange': '0.0 à 2.0', 'settings.agents.page.field.temperatureRange': '0.0 à 2.0',
@@ -387,6 +387,10 @@ export const settingsDict = {
'settings.agents.page.field.mode': '모드', 'settings.agents.page.field.mode': '모드',
'settings.agents.page.field.modeTooltip': '주 에이전트/보조 에이전트로 표시할지 선택합니다', 'settings.agents.page.field.modeTooltip': '주 에이전트/보조 에이전트로 표시할지 선택합니다',
'settings.agents.page.field.overrideModel': '모델 오버라이드', 'settings.agents.page.field.overrideModel': '모델 오버라이드',
'settings.agents.page.field.variant': '사고 변형',
'settings.agents.page.field.variantTooltip': '선택 사항. 모델이 추론을 지원하는 경우, 변형은 추론 깊이를 제어합니다.',
'settings.agents.page.field.variantHint': '모델별 (예: Anthropic variant)',
'settings.agents.page.field.variantPlaceholder': '예: high, max, low, none',
'settings.agents.page.field.temperature': '온도', 'settings.agents.page.field.temperature': '온도',
'settings.agents.page.field.temperatureTooltip': '무작위성을 제어합니다. 높을수록 창의적이고 낮을수록 집중적입니다.', 'settings.agents.page.field.temperatureTooltip': '무작위성을 제어합니다. 높을수록 창의적이고 낮을수록 집중적입니다.',
'settings.agents.page.field.temperatureRange': '0.0 ~ 2.0', 'settings.agents.page.field.temperatureRange': '0.0 ~ 2.0',
@@ -28,6 +28,10 @@ export const settingsDict = {
'settings.agents.page.field.overrideModel': 'Nadpisz model', 'settings.agents.page.field.overrideModel': 'Nadpisz model',
'settings.agents.page.field.scopePlaceholder': 'Zakres', 'settings.agents.page.field.scopePlaceholder': 'Zakres',
'settings.agents.page.field.systemPromptPlaceholder': 'Jesteś ekspertem w asystowaniu przy kodowaniu...', 'settings.agents.page.field.systemPromptPlaceholder': 'Jesteś ekspertem w asystowaniu przy kodowaniu...',
'settings.agents.page.field.variant': 'Wariant myślenia',
'settings.agents.page.field.variantTooltip': 'Opcjonalne. Jeśli model obsługuje rozumowanie, wariant kontroluje głębokość rozumowania.',
'settings.agents.page.field.variantHint': 'Zależne od modelu (np. wariant Anthropic)',
'settings.agents.page.field.variantPlaceholder': 'np. high, max, low, none',
'settings.agents.page.field.temperature': 'Temperatura', 'settings.agents.page.field.temperature': 'Temperatura',
'settings.agents.page.field.temperatureRange': 'od 0.0 do 2.0', 'settings.agents.page.field.temperatureRange': 'od 0.0 do 2.0',
'settings.agents.page.field.temperatureTooltip': 'Kontroluje losowość. Wyższa = bardziej kreatywny, niższa = bardziej skupiony.', 'settings.agents.page.field.temperatureTooltip': 'Kontroluje losowość. Wyższa = bardziej kreatywny, niższa = bardziej skupiony.',
@@ -387,6 +387,10 @@ export const settingsDict = {
"settings.agents.page.field.mode": "Modo", "settings.agents.page.field.mode": "Modo",
"settings.agents.page.field.modeTooltip": "Visibilidade principal vs subagente", "settings.agents.page.field.modeTooltip": "Visibilidade principal vs subagente",
"settings.agents.page.field.overrideModel": "Sobrescrever modelo", "settings.agents.page.field.overrideModel": "Sobrescrever modelo",
"settings.agents.page.field.variant": "Variante de pensamento",
"settings.agents.page.field.variantTooltip": "Opcional. Se o modelo suportar raciocínio, a variante controla a profundidade do raciocínio.",
"settings.agents.page.field.variantHint": "Específico do modelo (ex.: variante Anthropic)",
"settings.agents.page.field.variantPlaceholder": "ex.: high, max, low, none",
"settings.agents.page.field.temperature": "Temperatura", "settings.agents.page.field.temperature": "Temperatura",
"settings.agents.page.field.temperatureTooltip": "Controla a aleatoriedade. Maior = mais criativo, menor = mais focado.", "settings.agents.page.field.temperatureTooltip": "Controla a aleatoriedade. Maior = mais criativo, menor = mais focado.",
"settings.agents.page.field.temperatureRange": "0.0 a 2.0", "settings.agents.page.field.temperatureRange": "0.0 a 2.0",
@@ -387,6 +387,10 @@ export const settingsDict = {
"settings.agents.page.field.mode": "Режим", "settings.agents.page.field.mode": "Режим",
"settings.agents.page.field.modeTooltip": "Видимість основного або субагента", "settings.agents.page.field.modeTooltip": "Видимість основного або субагента",
"settings.agents.page.field.overrideModel": "Перевизначити модель", "settings.agents.page.field.overrideModel": "Перевизначити модель",
"settings.agents.page.field.variant": "Варіант мислення",
"settings.agents.page.field.variantTooltip": "Необов'язково. Якщо модель підтримує міркування, варіант контролює глибину міркування.",
"settings.agents.page.field.variantHint": "Специфічно для моделі (напр. варіант Anthropic)",
"settings.agents.page.field.variantPlaceholder": "напр. high, max, low, none",
"settings.agents.page.field.temperature": "Температура", "settings.agents.page.field.temperature": "Температура",
"settings.agents.page.field.temperatureTooltip": "Контролює випадковість. Вищий = творчий, нижчий = зосереджений.", "settings.agents.page.field.temperatureTooltip": "Контролює випадковість. Вищий = творчий, нижчий = зосереджений.",
"settings.agents.page.field.temperatureRange": "0,0 до 2,0", "settings.agents.page.field.temperatureRange": "0,0 до 2,0",
@@ -387,6 +387,10 @@ export const settingsDict = {
'settings.agents.page.field.mode': '模式', 'settings.agents.page.field.mode': '模式',
'settings.agents.page.field.modeTooltip': '主智能体与子智能体可见性', 'settings.agents.page.field.modeTooltip': '主智能体与子智能体可见性',
'settings.agents.page.field.overrideModel': '覆盖模型', 'settings.agents.page.field.overrideModel': '覆盖模型',
'settings.agents.page.field.variant': '思考变体',
'settings.agents.page.field.variantTooltip': '可选。如果模型支持推理,变体控制推理深度。',
'settings.agents.page.field.variantHint': '模型特定(如 Anthropic variant)',
'settings.agents.page.field.variantPlaceholder': '例如 high, max, low, none',
'settings.agents.page.field.temperature': 'Temperature', 'settings.agents.page.field.temperature': 'Temperature',
'settings.agents.page.field.temperatureTooltip': '控制随机性。越高越有创造性,越低越聚焦。', 'settings.agents.page.field.temperatureTooltip': '控制随机性。越高越有创造性,越低越聚焦。',
'settings.agents.page.field.temperatureRange': '0.0 到 2.0', 'settings.agents.page.field.temperatureRange': '0.0 到 2.0',
@@ -384,6 +384,10 @@
'settings.agents.page.field.mode': '模式', 'settings.agents.page.field.mode': '模式',
'settings.agents.page.field.modeTooltip': 'Primary 與 Subagent 可見性', 'settings.agents.page.field.modeTooltip': 'Primary 與 Subagent 可見性',
'settings.agents.page.field.overrideModel': '覆寫模型', 'settings.agents.page.field.overrideModel': '覆寫模型',
'settings.agents.page.field.variant': '思考變體',
'settings.agents.page.field.variantTooltip': '選填。如果模型支援推理,變體控制推理深度。',
'settings.agents.page.field.variantHint': '模型特定(如 Anthropic variant)',
'settings.agents.page.field.variantPlaceholder': '例如 high, max, low, none',
'settings.agents.page.field.temperature': 'Temperature', 'settings.agents.page.field.temperature': 'Temperature',
'settings.agents.page.field.temperatureTooltip': '控制隨機性。越高越有創造力,越低越聚焦。', 'settings.agents.page.field.temperatureTooltip': '控制隨機性。越高越有創造力,越低越聚焦。',
'settings.agents.page.field.temperatureRange': '0.0 到 2.0', 'settings.agents.page.field.temperatureRange': '0.0 到 2.0',
+7
View File
@@ -428,6 +428,13 @@ export const SETTINGS_SEARCH_ITEMS: readonly SettingsSearchItem[] = [
titleKey: 'settings.agents.page.field.overrideModel', titleKey: 'settings.agents.page.field.overrideModel',
keywords: ['model', 'provider'], keywords: ['model', 'provider'],
}, },
{
id: 'agents.variant',
page: 'agents',
titleKey: 'settings.agents.page.field.variant',
descriptionKey: 'settings.agents.page.field.variantTooltip',
keywords: ['thinking', 'reasoning', 'variant', 'depth'],
},
{ {
id: 'agents.temperature', id: 'agents.temperature',
page: 'agents', page: 'agents',
+4
View File
@@ -104,6 +104,7 @@ export interface AgentConfig {
name: string; name: string;
description?: string; description?: string;
model?: string | null; model?: string | null;
variant?: string | null;
temperature?: number; temperature?: number;
top_p?: number; top_p?: number;
prompt?: string | null; prompt?: string | null;
@@ -170,6 +171,7 @@ export interface AgentDraft {
scope: AgentScope; scope: AgentScope;
description?: string; description?: string;
model?: string | null; model?: string | null;
variant?: string;
temperature?: number; temperature?: number;
top_p?: number; top_p?: number;
prompt?: string; prompt?: string;
@@ -331,6 +333,7 @@ export const useAgentsStore = create<AgentsStore>()(
if (config.description) agentConfig.description = config.description; if (config.description) agentConfig.description = config.description;
if (config.model) agentConfig.model = config.model; if (config.model) agentConfig.model = config.model;
if (config.variant) agentConfig.variant = config.variant;
if (config.temperature !== undefined) agentConfig.temperature = config.temperature; if (config.temperature !== undefined) agentConfig.temperature = config.temperature;
if (config.top_p !== undefined) agentConfig.top_p = config.top_p; if (config.top_p !== undefined) agentConfig.top_p = config.top_p;
if (config.prompt) agentConfig.prompt = config.prompt; if (config.prompt) agentConfig.prompt = config.prompt;
@@ -395,6 +398,7 @@ export const useAgentsStore = create<AgentsStore>()(
if (config.mode !== undefined) agentConfig.mode = config.mode; if (config.mode !== undefined) agentConfig.mode = config.mode;
if (config.description !== undefined) agentConfig.description = config.description; if (config.description !== undefined) agentConfig.description = config.description;
if (config.model !== undefined) agentConfig.model = config.model; if (config.model !== undefined) agentConfig.model = config.model;
if ('variant' in config) agentConfig.variant = config.variant ?? null;
if (config.temperature !== undefined) agentConfig.temperature = config.temperature; if (config.temperature !== undefined) agentConfig.temperature = config.temperature;
if (config.top_p !== undefined) agentConfig.top_p = config.top_p; if (config.top_p !== undefined) agentConfig.top_p = config.top_p;
if (config.prompt !== undefined) agentConfig.prompt = config.prompt; if (config.prompt !== undefined) agentConfig.prompt = config.prompt;