fix(subagent): 实验开关改为滑动开关,修复开启态因 bg-primary 未定义而隐形
- Toggle 开启态改用已定义的 bg-blue-600(tailwind 配置无 primary 背景色, 导致开启态滑轨透明、白色滑块在白底上不可见) - 子代理开关移至模型下拉之后,统一使用滑动开关
This commit is contained in:
1 parent
8aed04898c
commit
90cc4a16d2
3 files changed
+86
-21
No files matched your search
@@ -0,0 +1,18 @@
|
||||
## v0.7.1
|
||||
|
||||
### 实验功能设置:子代理模型配置
|
||||
|
||||
- 新增「子代理模型(次主力模型)」设置:选择次主力模型后,子代理默认绑定该模型,不再继承主模型
|
||||
- 仅保存模型引用,子代理直接继承所选模型的上下文长度与思考模式,无需补丁配置
|
||||
- 界面只读展示继承的上下文长度与思考模式
|
||||
|
||||
### 仪表盘用量统计
|
||||
|
||||
- 识别子代理请求(`__secondary__`):归为「子代理模型(估算)」独立展示,并缓存次主力模型定价,删除配置后历史记录仍稳定估算
|
||||
- 自定义网关模型(未收录 models.dev)按官方同名模型跨 provider 匹配价格,不再落入兜底估算
|
||||
|
||||
### Downloads by platform
|
||||
|
||||
- **Windows**: `.msi` installer
|
||||
- **macOS**: `.dmg` (unsigned — first launch needs right-click → Open) + `.app`
|
||||
- **Linux**: `.deb` / `.AppImage` / `.rpm`
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
setSecondaryModelOnly,
|
||||
type ExperimentalFlagDef,
|
||||
} from "../lib/subagent-settings";
|
||||
import { Card, Checkbox } from "./ui/controls";
|
||||
import { Card, Toggle } from "./ui/controls";
|
||||
|
||||
interface SubagentSettingsPageProps {
|
||||
/** config.raw_other — hosts the `[experimental]` and `[secondary_model]` sections. */
|
||||
@@ -71,6 +71,7 @@ export function SubagentSettingsPage({
|
||||
: isFlagLockedByEnv(env, secondaryFlag)
|
||||
? forcedEnvValue(env, secondaryFlag)
|
||||
: flags["secondary-model"] === true;
|
||||
const secondaryLocked = masterOn || isFlagLockedByEnv(env, secondaryFlag);
|
||||
|
||||
const aliasList = Object.keys(models).sort();
|
||||
|
||||
@@ -127,10 +128,10 @@ export function SubagentSettingsPage({
|
||||
🔒 {t("lockedByEnv")}
|
||||
</span>
|
||||
)}
|
||||
<Checkbox
|
||||
label=""
|
||||
<Toggle
|
||||
checked={on}
|
||||
disabled={locked}
|
||||
ariaLabel={t(labels.name)}
|
||||
onChange={(checked) =>
|
||||
onChange(setExperimentalFlag(rawOther, flag.id, checked))
|
||||
}
|
||||
@@ -160,17 +161,8 @@ export function SubagentSettingsPage({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Subagent: experimental flag + secondary model in one card */}
|
||||
{/* Subagent: secondary model picker + inherited settings */}
|
||||
<Card title={t("secondaryModelSection")}>
|
||||
{renderFlagRow(secondaryFlag)}
|
||||
<div className="border-t border-border" />
|
||||
|
||||
{!secondaryEnabled && (
|
||||
<div className="bg-amber-100 dark:bg-amber-900/20 border border-amber-300 dark:border-amber-500/30 rounded-lg px-3 py-2 text-sm text-amber-800 dark:text-amber-400">
|
||||
{t("secondaryModelDisabledHint")}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<label className="flex items-center gap-3 text-sm text-content-primary">
|
||||
<span className="text-content-muted">{t("secondaryModelLabel")}</span>
|
||||
<select
|
||||
@@ -200,21 +192,44 @@ export function SubagentSettingsPage({
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<div className="border-t border-border" />
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="text-xs text-content-muted">
|
||||
{t(FLAG_LABELS[secondaryFlag.id].desc)}
|
||||
<code className="ml-2">{secondaryFlag.envVar}</code>
|
||||
</div>
|
||||
</div>
|
||||
{secondaryLocked && (
|
||||
<span className="text-xs text-content-muted shrink-0">
|
||||
🔒 {t("lockedByEnv")}
|
||||
</span>
|
||||
)}
|
||||
<Toggle
|
||||
checked={secondaryEnabled}
|
||||
disabled={secondaryLocked}
|
||||
ariaLabel={t(FLAG_LABELS[secondaryFlag.id].name)}
|
||||
onChange={(checked) =>
|
||||
onChange(setExperimentalFlag(rawOther, secondaryFlag.id, checked))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{secondary.model !== undefined && (
|
||||
<div className="rounded-lg border border-border bg-input/40 px-3 py-2 space-y-1.5">
|
||||
<div className="flex items-center gap-3 text-sm">
|
||||
<span className="text-content-muted w-24 shrink-0">
|
||||
<div className="rounded-lg border border-border bg-input/40 px-3 py-2.5 space-y-2">
|
||||
<div className="flex items-baseline gap-2 text-sm">
|
||||
<span className="shrink-0 text-content-muted">
|
||||
{t("secondaryModelInheritedContext")}
|
||||
</span>
|
||||
<span className="text-content-primary">
|
||||
<span className="font-medium text-content-primary">
|
||||
{inheritedContext ? fmtContext(inheritedContext) : "—"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-3 text-sm">
|
||||
<span className="text-content-muted w-24 shrink-0">
|
||||
<div className="flex items-baseline gap-2 text-sm">
|
||||
<span className="shrink-0 text-content-muted">
|
||||
{t("secondaryModelInheritedEffort")}
|
||||
</span>
|
||||
<span className="text-content-primary">
|
||||
<span className="font-medium text-content-primary">
|
||||
{inheritedEffort ? effortLabel(inheritedEffort) : "—"}
|
||||
</span>
|
||||
</div>
|
||||
@@ -224,7 +239,6 @@ export function SubagentSettingsPage({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<p className="text-xs text-content-muted">{t("secondaryModelHint")}</p>
|
||||
<p className="text-xs text-content-muted">{t("secondaryModelPriorityHint")}</p>
|
||||
</Card>
|
||||
|
||||
|
||||
@@ -42,6 +42,39 @@ export function Checkbox({
|
||||
);
|
||||
}
|
||||
|
||||
/** Pill-style toggle switch with a sliding knob. */
|
||||
export function Toggle({
|
||||
checked,
|
||||
disabled,
|
||||
onChange,
|
||||
ariaLabel,
|
||||
}: {
|
||||
checked: boolean;
|
||||
disabled?: boolean;
|
||||
onChange: (checked: boolean) => void;
|
||||
ariaLabel?: string;
|
||||
}) {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
role="switch"
|
||||
aria-checked={checked}
|
||||
aria-label={ariaLabel}
|
||||
disabled={disabled}
|
||||
onClick={() => onChange(!checked)}
|
||||
className={`relative h-5 w-9 shrink-0 rounded-full transition-colors duration-200 focus:ring-2 focus:ring-blue-500 focus:outline-none ${
|
||||
checked ? "bg-blue-600" : "bg-border"
|
||||
} ${disabled ? "cursor-not-allowed opacity-50" : ""}`}
|
||||
>
|
||||
<span
|
||||
className={`absolute left-0.5 top-0.5 h-4 w-4 rounded-full bg-white shadow-sm transition-transform duration-200 ${
|
||||
checked ? "translate-x-4" : "translate-x-0"
|
||||
}`}
|
||||
/>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export function NumberField({
|
||||
label,
|
||||
value,
|
||||
|
||||
Reference in new issue
Block a user