feat(settings): 适配 kimi-code 0.42.0 —— 实验 flag 镜像 9→6
- 删除已转正/移除的 4 个 flag:secondary-model(模型池恒开)、 persistence_minidb_readmodel(改由 [database] 配置节)、remote-control、 search_worker;env 探测清单同步 11→8 - 新增 notify_user flag(KIMI_CODE_EXPERIMENTAL_NOTIFY_USER,实验性 Updates 面板,默认关闭) - 设置页移除 secondary-model 专属卡片与「默认开启」徽章,6 个 flag 统一渲染; [secondary_model] 模型池配置逻辑不变 - 残留旧键上游 schema 宽容忽略,无需迁移
This commit is contained in:
1 parent
33a27ba31b
commit
9ce1ed65b0
7 files changed
+70
-138
No files matched your search
Generated
+1
-1
@@ -1978,7 +1978,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kimiswitch"
|
name = "kimiswitch"
|
||||||
version = "0.7.14"
|
version = "0.7.15"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
|||||||
@@ -1335,7 +1335,7 @@ pub async fn kimi_oauth_poll(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Experimental feature env-var probe (Kimi Code secondary model etc.)
|
// Experimental feature env-var probe (Kimi Code experimental flags)
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Read the Kimi Code environment variables that are currently set (non-empty)
|
/// Read the Kimi Code environment variables that are currently set (non-empty)
|
||||||
@@ -1348,6 +1348,11 @@ pub async fn kimi_oauth_poll(
|
|||||||
/// are probed too — the latter lets AgentSettingsPanel decide whether to
|
/// are probed too — the latter lets AgentSettingsPanel decide whether to
|
||||||
/// dual-write the v1 engine's loop_control keys.
|
/// dual-write the v1 engine's loop_control keys.
|
||||||
///
|
///
|
||||||
|
/// As of Kimi Code 0.42.0 the upstream registry holds 6 experimental flags;
|
||||||
|
/// `secondary-model`, `persistence_minidb_readmodel`, `remote-control` and
|
||||||
|
/// `search_worker` have been promoted or removed upstream and are no longer
|
||||||
|
/// probed here.
|
||||||
|
///
|
||||||
/// The flag id → env var mapping mirrors `EXPERIMENTAL_FLAGS` in
|
/// The flag id → env var mapping mirrors `EXPERIMENTAL_FLAGS` in
|
||||||
/// src/lib/subagent-settings.ts; keep both lists in sync.
|
/// src/lib/subagent-settings.ts; keep both lists in sync.
|
||||||
///
|
///
|
||||||
@@ -1355,19 +1360,13 @@ pub async fn kimi_oauth_poll(
|
|||||||
/// the raw values are returned and the truthy check happens on the frontend.
|
/// the raw values are returned and the truthy check happens on the frontend.
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn get_experimental_env_status() -> HashMap<String, String> {
|
pub fn get_experimental_env_status() -> HashMap<String, String> {
|
||||||
const VARS: [(&str, &str); 11] = [
|
const VARS: [(&str, &str); 8] = [
|
||||||
("secondary-model", "KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL"),
|
|
||||||
("tool-select", "KIMI_CODE_EXPERIMENTAL_TOOL_SELECT"),
|
("tool-select", "KIMI_CODE_EXPERIMENTAL_TOOL_SELECT"),
|
||||||
(
|
|
||||||
"persistence_minidb_readmodel",
|
|
||||||
"KIMI_CODE_EXPERIMENTAL_PERSISTENCE_MINIDB_READMODEL",
|
|
||||||
),
|
|
||||||
("tower", "KIMI_CODE_EXPERIMENTAL_TOWER"),
|
("tower", "KIMI_CODE_EXPERIMENTAL_TOWER"),
|
||||||
("subagent_fork", "KIMI_CODE_EXPERIMENTAL_SUBAGENT_FORK"),
|
("subagent_fork", "KIMI_CODE_EXPERIMENTAL_SUBAGENT_FORK"),
|
||||||
("wait_for", "KIMI_CODE_EXPERIMENTAL_WAIT_FOR"),
|
("wait_for", "KIMI_CODE_EXPERIMENTAL_WAIT_FOR"),
|
||||||
("auto_session_title", "KIMI_CODE_EXPERIMENTAL_AUTO_SESSION_TITLE"),
|
("auto_session_title", "KIMI_CODE_EXPERIMENTAL_AUTO_SESSION_TITLE"),
|
||||||
("remote-control", "KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL"),
|
("notify_user", "KIMI_CODE_EXPERIMENTAL_NOTIFY_USER"),
|
||||||
("search_worker", "KIMI_CODE_EXPERIMENTAL_SEARCH_WORKER"),
|
|
||||||
// Non-flag probes consumed by the frontend:
|
// Non-flag probes consumed by the frontend:
|
||||||
("master", "KIMI_CODE_EXPERIMENTAL_FLAG"),
|
("master", "KIMI_CODE_EXPERIMENTAL_FLAG"),
|
||||||
("legacy", "KIMI_CODE_LEGACY_FLAG"),
|
("legacy", "KIMI_CODE_LEGACY_FLAG"),
|
||||||
|
|||||||
@@ -43,21 +43,15 @@ const EFFORT_LABELS: Record<(typeof EFFORTS)[number], TranslationKey> = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const FLAG_LABELS: Record<string, { name: TranslationKey; desc: TranslationKey }> = {
|
const FLAG_LABELS: Record<string, { name: TranslationKey; desc: TranslationKey }> = {
|
||||||
"secondary-model": { name: "flagSecondaryModel", desc: "flagSecondaryModelDesc" },
|
wait_for: { name: "flagWaitFor", desc: "flagWaitForDesc" },
|
||||||
"tool-select": { name: "flagToolSelect", desc: "flagToolSelectDesc" },
|
"tool-select": { name: "flagToolSelect", desc: "flagToolSelectDesc" },
|
||||||
persistence_minidb_readmodel: {
|
notify_user: { name: "flagNotifyUser", desc: "flagNotifyUserDesc" },
|
||||||
name: "flagMinidbReadmodel",
|
|
||||||
desc: "flagMinidbReadmodelDesc",
|
|
||||||
},
|
|
||||||
tower: { name: "flagTower", desc: "flagTowerDesc" },
|
tower: { name: "flagTower", desc: "flagTowerDesc" },
|
||||||
subagent_fork: { name: "flagSubagentFork", desc: "flagSubagentForkDesc" },
|
subagent_fork: { name: "flagSubagentFork", desc: "flagSubagentForkDesc" },
|
||||||
wait_for: { name: "flagWaitFor", desc: "flagWaitForDesc" },
|
|
||||||
auto_session_title: {
|
auto_session_title: {
|
||||||
name: "flagAutoSessionTitle",
|
name: "flagAutoSessionTitle",
|
||||||
desc: "flagAutoSessionTitleDesc",
|
desc: "flagAutoSessionTitleDesc",
|
||||||
},
|
},
|
||||||
"remote-control": { name: "flagRemoteControl", desc: "flagRemoteControlDesc" },
|
|
||||||
search_worker: { name: "flagSearchWorker", desc: "flagSearchWorkerDesc" },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Validation-error i18n key per engine rule, for the pre-write self-check. */
|
/** Validation-error i18n key per engine rule, for the pre-write self-check. */
|
||||||
@@ -185,21 +179,6 @@ export function SubagentSettingsPage({
|
|||||||
// off — upgrading with force would create an invalid force+pool-table combo.
|
// off — upgrading with force would create an invalid force+pool-table combo.
|
||||||
const canUpgrade = !!pool && !isPoolView && pool.model !== undefined && !pool.force;
|
const canUpgrade = !!pool && !isPoolView && pool.model !== undefined && !pool.force;
|
||||||
const masterOn = isMasterEnvOn(env);
|
const masterOn = isMasterEnvOn(env);
|
||||||
const secondaryFlag = EXPERIMENTAL_FLAGS[0]; // "secondary-model"
|
|
||||||
const otherFlags = EXPERIMENTAL_FLAGS.slice(1);
|
|
||||||
|
|
||||||
/** Effective state of the secondary-model flag. Mirrors the kimi-code
|
|
||||||
* 0.40.1 priority: single-flag env > explicit [experimental] value >
|
|
||||||
* master env (force-on only) > upstream default. The master env no
|
|
||||||
* longer locks the toggle — only the flag's own env var does. */
|
|
||||||
const secondaryEnabled = isFlagLockedByEnv(env, secondaryFlag)
|
|
||||||
? forcedEnvValue(env, secondaryFlag)
|
|
||||||
: isExperimentalFlagSet(rawOther, secondaryFlag.id)
|
|
||||||
? flags["secondary-model"] === true
|
|
||||||
: masterOn
|
|
||||||
? true
|
|
||||||
: (secondaryFlag.defaultEnabled ?? false);
|
|
||||||
const secondaryLocked = isFlagLockedByEnv(env, secondaryFlag);
|
|
||||||
|
|
||||||
const aliasList = Object.keys(models).sort();
|
const aliasList = Object.keys(models).sort();
|
||||||
|
|
||||||
@@ -573,41 +552,6 @@ export function SubagentSettingsPage({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="border-t border-border" />
|
<div className="border-t border-border" />
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<div className="flex-1 min-w-0">
|
|
||||||
<div className="flex items-center gap-2 text-sm text-content-primary">
|
|
||||||
{t(FLAG_LABELS[secondaryFlag.id].name)}
|
|
||||||
{!secondaryLocked &&
|
|
||||||
!isExperimentalFlagSet(rawOther, secondaryFlag.id) &&
|
|
||||||
secondaryFlag.defaultEnabled && (
|
|
||||||
<span className="shrink-0 text-xs text-blue-600 dark:text-blue-400 border border-blue-500/30 rounded px-1">
|
|
||||||
{t("flagDefaultOn")}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<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, {
|
|
||||||
explicitFalse: masterOn || secondaryFlag.defaultEnabled === true,
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{effectiveDefault !== undefined && (
|
{effectiveDefault !== undefined && (
|
||||||
<div className="rounded-lg border border-border bg-input/40 px-3 py-2.5 space-y-2">
|
<div className="rounded-lg border border-border bg-input/40 px-3 py-2.5 space-y-2">
|
||||||
@@ -636,9 +580,9 @@ export function SubagentSettingsPage({
|
|||||||
<p className="text-xs text-content-muted">{t("secondaryModelPriorityHint")}</p>
|
<p className="text-xs text-content-muted">{t("secondaryModelPriorityHint")}</p>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
{/* Other experimental features (not subagent-related) */}
|
{/* Experimental feature flags — one unified list */}
|
||||||
<Card title={t("otherExperimentalFlags")}>
|
<Card title={t("experimentalFlags")}>
|
||||||
{otherFlags.map(renderFlagRow)}
|
{EXPERIMENTAL_FLAGS.map(renderFlagRow)}
|
||||||
<p className="text-xs text-content-muted">{t("experimentalFlagsHint")}</p>
|
<p className="text-xs text-content-muted">{t("experimentalFlagsHint")}</p>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+2
-11
@@ -463,15 +463,10 @@ export const enTranslations: Record<TranslationKey, string> = {
|
|||||||
// Advanced settings page (WebUI quick open + experimental flags + secondary model)
|
// Advanced settings page (WebUI quick open + experimental flags + secondary model)
|
||||||
subagentSettings: "Advanced Settings",
|
subagentSettings: "Advanced Settings",
|
||||||
experimentalFlags: "Experimental Features",
|
experimentalFlags: "Experimental Features",
|
||||||
otherExperimentalFlags: "Other Experimental Features",
|
|
||||||
experimentalFlagsHint:
|
experimentalFlagsHint:
|
||||||
"Toggles are written to the [experimental] section of config.toml; env vars take precedence and locked toggles cannot be changed here",
|
"Toggles are written to the [experimental] section of config.toml; env vars take precedence and locked toggles cannot be changed here",
|
||||||
flagSecondaryModel: "Subagent Secondary Model",
|
|
||||||
flagSecondaryModelDesc: "Newly spawned subagents bind a second (usually cheaper) model config",
|
|
||||||
flagToolSelect: "Tool Select",
|
flagToolSelect: "Tool Select",
|
||||||
flagToolSelectDesc: "Enable the experimental tool selection feature",
|
flagToolSelectDesc: "Enable the experimental tool selection feature",
|
||||||
flagMinidbReadmodel: "MiniDB Read Model",
|
|
||||||
flagMinidbReadmodelDesc: "Enable the v2 engine MiniDB read-model backend",
|
|
||||||
flagTower: "Tower Mode",
|
flagTower: "Tower Mode",
|
||||||
flagTowerDesc: "Enable tower mode: coordinate multiple agents on a shared objective (/tower command)",
|
flagTowerDesc: "Enable tower mode: coordinate multiple agents on a shared objective (/tower command)",
|
||||||
flagSubagentFork: "Subagent Fork Context",
|
flagSubagentFork: "Subagent Fork Context",
|
||||||
@@ -480,17 +475,13 @@ export const enTranslations: Record<TranslationKey, string> = {
|
|||||||
flagWaitForDesc: "The agent can wait for background tasks to finish within the current turn",
|
flagWaitForDesc: "The agent can wait for background tasks to finish within the current turn",
|
||||||
flagAutoSessionTitle: "Auto Session Title",
|
flagAutoSessionTitle: "Auto Session Title",
|
||||||
flagAutoSessionTitleDesc: "Generate session titles automatically via the managed chat_title tool",
|
flagAutoSessionTitleDesc: "Generate session titles automatically via the managed chat_title tool",
|
||||||
flagRemoteControl: "Remote Control",
|
flagNotifyUser: "NotifyUser tool",
|
||||||
flagRemoteControlDesc: "Enable the experimental remote control feature",
|
flagNotifyUserDesc: "Experimental Updates panel: paginated progress messages from the main agent and subagents (off by default)",
|
||||||
flagSearchWorker: "Search Worker",
|
|
||||||
flagSearchWorkerDesc: "Run the kap-server global search backend in a background worker host",
|
|
||||||
flagDefaultOn: "On by default",
|
flagDefaultOn: "On by default",
|
||||||
lockedByEnv: "Locked by env var",
|
lockedByEnv: "Locked by env var",
|
||||||
masterEnvOnHint:
|
masterEnvOnHint:
|
||||||
"KIMI_CODE_EXPERIMENTAL_FLAG is set: flags without an explicit [experimental] entry are forced on; explicit entries in config.toml still win",
|
"KIMI_CODE_EXPERIMENTAL_FLAG is set: flags without an explicit [experimental] entry are forced on; explicit entries in config.toml still win",
|
||||||
secondaryModelSection: "Subagent Model (Secondary Model)",
|
secondaryModelSection: "Subagent Model (Secondary Model)",
|
||||||
secondaryModelDisabledHint:
|
|
||||||
"The experimental flag \"Subagent Secondary Model\" is off and this config will not take effect — enable the toggle above first",
|
|
||||||
secondaryModelLabel: "Secondary model",
|
secondaryModelLabel: "Secondary model",
|
||||||
secondaryModelUnset: "Not configured",
|
secondaryModelUnset: "Not configured",
|
||||||
secondaryModelInheritedContext: "Inherited context",
|
secondaryModelInheritedContext: "Inherited context",
|
||||||
|
|||||||
+2
-11
@@ -458,15 +458,10 @@ export const zhTranslations = {
|
|||||||
// Advanced settings page (WebUI quick open + experimental flags + secondary model)
|
// Advanced settings page (WebUI quick open + experimental flags + secondary model)
|
||||||
subagentSettings: "高级设置",
|
subagentSettings: "高级设置",
|
||||||
experimentalFlags: "实验功能开关",
|
experimentalFlags: "实验功能开关",
|
||||||
otherExperimentalFlags: "其他实验功能",
|
|
||||||
experimentalFlagsHint:
|
experimentalFlagsHint:
|
||||||
"开关写入 config.toml 的 [experimental] 节;环境变量优先级更高,被锁定的开关无法在此修改",
|
"开关写入 config.toml 的 [experimental] 节;环境变量优先级更高,被锁定的开关无法在此修改",
|
||||||
flagSecondaryModel: "子代理次主力模型",
|
|
||||||
flagSecondaryModelDesc: "子代理派发时绑定第二份(通常更便宜的)模型配置",
|
|
||||||
flagToolSelect: "工具选择",
|
flagToolSelect: "工具选择",
|
||||||
flagToolSelectDesc: "启用实验性工具选择功能",
|
flagToolSelectDesc: "启用实验性工具选择功能",
|
||||||
flagMinidbReadmodel: "MiniDB 读模型",
|
|
||||||
flagMinidbReadmodelDesc: "启用 v2 引擎 MiniDB 读模型后端",
|
|
||||||
flagTower: "Tower 模式",
|
flagTower: "Tower 模式",
|
||||||
flagTowerDesc: "启用 Tower 多智能体协同模式(/tower 命令切换)",
|
flagTowerDesc: "启用 Tower 多智能体协同模式(/tower 命令切换)",
|
||||||
flagSubagentFork: "子代理 Fork 上下文",
|
flagSubagentFork: "子代理 Fork 上下文",
|
||||||
@@ -475,17 +470,13 @@ export const zhTranslations = {
|
|||||||
flagWaitForDesc: "代理可在当前回合内等待后台任务完成,而无需结束回合再被唤醒",
|
flagWaitForDesc: "代理可在当前回合内等待后台任务完成,而无需结束回合再被唤醒",
|
||||||
flagAutoSessionTitle: "自动会话标题",
|
flagAutoSessionTitle: "自动会话标题",
|
||||||
flagAutoSessionTitleDesc: "通过托管 chat_title 工具自动生成会话标题",
|
flagAutoSessionTitleDesc: "通过托管 chat_title 工具自动生成会话标题",
|
||||||
flagRemoteControl: "远程控制",
|
flagNotifyUser: "NotifyUser 工具",
|
||||||
flagRemoteControlDesc: "启用实验性远程控制功能",
|
flagNotifyUserDesc: "实验性 Updates 面板:分页展示主代理与子代理的进度消息(默认关闭)",
|
||||||
flagSearchWorker: "搜索 Worker",
|
|
||||||
flagSearchWorkerDesc: "kap-server 全局搜索的后台 worker 宿主服务",
|
|
||||||
flagDefaultOn: "默认开启",
|
flagDefaultOn: "默认开启",
|
||||||
lockedByEnv: "被环境变量锁定",
|
lockedByEnv: "被环境变量锁定",
|
||||||
masterEnvOnHint:
|
masterEnvOnHint:
|
||||||
"KIMI_CODE_EXPERIMENTAL_FLAG 已设置:未显式配置的实验项将被强制开启;config.toml 中的显式配置优先生效",
|
"KIMI_CODE_EXPERIMENTAL_FLAG 已设置:未显式配置的实验项将被强制开启;config.toml 中的显式配置优先生效",
|
||||||
secondaryModelSection: "子代理模型(次主力模型)",
|
secondaryModelSection: "子代理模型(次主力模型)",
|
||||||
secondaryModelDisabledHint:
|
|
||||||
"实验开关「子代理次主力模型」未启用,本配置不会生效——请先在上方打开对应开关",
|
|
||||||
secondaryModelLabel: "次主力模型",
|
secondaryModelLabel: "次主力模型",
|
||||||
secondaryModelUnset: "未配置",
|
secondaryModelUnset: "未配置",
|
||||||
secondaryModelInheritedContext: "继承上下文长度",
|
secondaryModelInheritedContext: "继承上下文长度",
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import {
|
import {
|
||||||
EXPERIMENTAL_FLAGS,
|
EXPERIMENTAL_FLAGS,
|
||||||
|
forcedEnvValue,
|
||||||
getExperimentalFlags,
|
getExperimentalFlags,
|
||||||
getSecondaryModel,
|
getSecondaryModel,
|
||||||
getSubagentModelPool,
|
getSubagentModelPool,
|
||||||
isExperimentalFlagSet,
|
isExperimentalFlagSet,
|
||||||
|
isFlagLockedByEnv,
|
||||||
removeSubagentPoolEntry,
|
removeSubagentPoolEntry,
|
||||||
setExperimentalFlag,
|
setExperimentalFlag,
|
||||||
setSecondaryModelOnly,
|
setSecondaryModelOnly,
|
||||||
@@ -163,13 +165,13 @@ describe("setSecondaryModelOnly", () => {
|
|||||||
|
|
||||||
it("preserves other top-level raw_other sections", () => {
|
it("preserves other top-level raw_other sections", () => {
|
||||||
const raw = {
|
const raw = {
|
||||||
experimental: { "secondary-model": true },
|
experimental: { wait_for: true },
|
||||||
secondary_model: { model: "kimi-k1" },
|
secondary_model: { model: "kimi-k1" },
|
||||||
};
|
};
|
||||||
const next = setSecondaryModelOnly(raw, "kimi-k2") as {
|
const next = setSecondaryModelOnly(raw, "kimi-k2") as {
|
||||||
experimental?: unknown;
|
experimental?: unknown;
|
||||||
};
|
};
|
||||||
expect(next.experimental).toEqual({ "secondary-model": true });
|
expect(next.experimental).toEqual({ wait_for: true });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -455,31 +457,49 @@ describe("validateSubagentPool", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// [experimental] — flag registry (kimi-code 0.41.0) + write semantics
|
// [experimental] — flag registry (kimi-code 0.42.0) + write semantics
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
describe("experimental flag registry", () => {
|
describe("experimental flag registry", () => {
|
||||||
it("mirrors the 0.41.0 v2 registry (9 flags, file_history removed)", () => {
|
it("mirrors the 0.42.0 v2 registry (6 flags)", () => {
|
||||||
expect(EXPERIMENTAL_FLAGS.map((f) => f.id)).toEqual([
|
expect(EXPERIMENTAL_FLAGS.map((f) => f.id)).toEqual([
|
||||||
"secondary-model",
|
"wait_for",
|
||||||
"tool-select",
|
"tool-select",
|
||||||
"persistence_minidb_readmodel",
|
"notify_user",
|
||||||
"tower",
|
"tower",
|
||||||
"subagent_fork",
|
"subagent_fork",
|
||||||
"wait_for",
|
|
||||||
"auto_session_title",
|
"auto_session_title",
|
||||||
|
]);
|
||||||
|
// Removed upstream: file_history (0.41.0, turn-level file history is
|
||||||
|
// always on) plus secondary-model / persistence_minidb_readmodel /
|
||||||
|
// remote-control / search_worker (0.42.0 — promoted or moved to
|
||||||
|
// dedicated config, the minidb read-model now lives under [database]),
|
||||||
|
// so the adapter must not mirror them either.
|
||||||
|
for (const id of [
|
||||||
|
"file_history",
|
||||||
|
"secondary-model",
|
||||||
|
"persistence_minidb_readmodel",
|
||||||
"remote-control",
|
"remote-control",
|
||||||
"search_worker",
|
"search_worker",
|
||||||
]);
|
]) {
|
||||||
// Upstream removed the flag in 0.41.0 (turn-level file history is
|
expect(EXPERIMENTAL_FLAGS.some((f) => f.id === id)).toBe(false);
|
||||||
// always on), so the adapter must not mirror it either.
|
}
|
||||||
expect(EXPERIMENTAL_FLAGS.some((f) => f.id === "file_history")).toBe(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("secondary-model is on by default since 0.40.1", () => {
|
it("notify_user is opt-in: no upstream default, own env var", () => {
|
||||||
expect(
|
const flag = EXPERIMENTAL_FLAGS.find((f) => f.id === "notify_user");
|
||||||
EXPERIMENTAL_FLAGS.find((f) => f.id === "secondary-model")?.defaultEnabled
|
expect(flag?.envVar).toBe("KIMI_CODE_EXPERIMENTAL_NOTIFY_USER");
|
||||||
).toBe(true);
|
expect(flag?.defaultEnabled).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("notify_user is locked by its env var and forced to the env value", () => {
|
||||||
|
const flag = EXPERIMENTAL_FLAGS.find((f) => f.id === "notify_user")!;
|
||||||
|
expect(isFlagLockedByEnv({}, flag)).toBe(false);
|
||||||
|
// A set env var locks the toggle even when it is falsy — it can force
|
||||||
|
// the flag on *or* off.
|
||||||
|
expect(isFlagLockedByEnv({ [flag.envVar]: "0" }, flag)).toBe(true);
|
||||||
|
expect(forcedEnvValue({ [flag.envVar]: "0" }, flag)).toBe(false);
|
||||||
|
expect(forcedEnvValue({ [flag.envVar]: "true" }, flag)).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -514,13 +534,13 @@ describe("setExperimentalFlag", () => {
|
|||||||
|
|
||||||
it("an explicit false coexists with other flags and keeps the section", () => {
|
it("an explicit false coexists with other flags and keeps the section", () => {
|
||||||
const next = setExperimentalFlag(
|
const next = setExperimentalFlag(
|
||||||
rawExp({ "secondary-model": false }),
|
rawExp({ wait_for: false }),
|
||||||
"tower",
|
"tower",
|
||||||
true,
|
true,
|
||||||
{ explicitFalse: true }
|
{ explicitFalse: true }
|
||||||
) as { experimental: Record<string, unknown> };
|
) as { experimental: Record<string, unknown> };
|
||||||
expect(next.experimental).toEqual({
|
expect(next.experimental).toEqual({
|
||||||
"secondary-model": false,
|
wait_for: false,
|
||||||
tower: true,
|
tower: true,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ function isTruthyEnv(value: string | undefined): boolean {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
export interface ExperimentalFlagDef {
|
export interface ExperimentalFlagDef {
|
||||||
/** Flag id as stored in config.toml `[experimental]` (e.g. "secondary-model"). */
|
/** Flag id as stored in config.toml `[experimental]` (e.g. "wait_for"). */
|
||||||
id: string;
|
id: string;
|
||||||
/** Single-feature env var that can force the flag (locks the UI toggle). */
|
/** Single-feature env var that can force the flag (locks the UI toggle). */
|
||||||
envVar: string;
|
envVar: string;
|
||||||
@@ -33,43 +33,30 @@ export interface ExperimentalFlagDef {
|
|||||||
defaultEnabled?: boolean;
|
defaultEnabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Known experimental flags — mirrors the kimi-code v2 flag registry
|
/** Known experimental flags — mirrors the kimi-code 0.42.0 v2 flag registry
|
||||||
* (the per-feature flag.ts files under packages/agent-core-v2/src:
|
* (the per-feature flag.ts files under packages/agent-core-v2/src):
|
||||||
* secondary-model, tool-select, persistence_minidb_readmodel, tower,
|
* wait_for, tool-select, notify_user, tower, subagent_fork,
|
||||||
* subagent_fork, wait_for, auto_session_title, remote-control,
|
* auto_session_title. Removed in 0.42.0: secondary-model, remote-control
|
||||||
* search_worker). `acp-v2` was removed upstream and is dropped here;
|
* and search_worker (promoted or dropped upstream — no flag left), and
|
||||||
* `file_history` was removed in kimi-code 0.41.0 (turn-level file
|
* persistence_minidb_readmodel (now controlled by the `[database]` config
|
||||||
* history is always on, no flag). Keep the env-var list in sync with
|
* section). `acp-v2` was removed upstream earlier; `file_history` was
|
||||||
* `get_experimental_env_status` in src-tauri/src/commands.rs. */
|
* removed in kimi-code 0.41.0 (turn-level file history is always on, no
|
||||||
|
* flag). Keep the env-var list in sync with `get_experimental_env_status`
|
||||||
|
* in src-tauri/src/commands.rs. */
|
||||||
export const EXPERIMENTAL_FLAGS: ExperimentalFlagDef[] = [
|
export const EXPERIMENTAL_FLAGS: ExperimentalFlagDef[] = [
|
||||||
{
|
|
||||||
id: "secondary-model",
|
|
||||||
envVar: "KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL",
|
|
||||||
defaultEnabled: true, // on by default since kimi-code 0.40.1
|
|
||||||
},
|
|
||||||
{ id: "tool-select", envVar: "KIMI_CODE_EXPERIMENTAL_TOOL_SELECT" },
|
|
||||||
{
|
|
||||||
id: "persistence_minidb_readmodel",
|
|
||||||
envVar: "KIMI_CODE_EXPERIMENTAL_PERSISTENCE_MINIDB_READMODEL",
|
|
||||||
defaultEnabled: true,
|
|
||||||
},
|
|
||||||
{ id: "tower", envVar: "KIMI_CODE_EXPERIMENTAL_TOWER" },
|
|
||||||
{ id: "subagent_fork", envVar: "KIMI_CODE_EXPERIMENTAL_SUBAGENT_FORK" },
|
|
||||||
{
|
{
|
||||||
id: "wait_for",
|
id: "wait_for",
|
||||||
envVar: "KIMI_CODE_EXPERIMENTAL_WAIT_FOR",
|
envVar: "KIMI_CODE_EXPERIMENTAL_WAIT_FOR",
|
||||||
defaultEnabled: true,
|
defaultEnabled: true,
|
||||||
},
|
},
|
||||||
|
{ id: "tool-select", envVar: "KIMI_CODE_EXPERIMENTAL_TOOL_SELECT" },
|
||||||
|
{ id: "notify_user", envVar: "KIMI_CODE_EXPERIMENTAL_NOTIFY_USER" },
|
||||||
|
{ id: "tower", envVar: "KIMI_CODE_EXPERIMENTAL_TOWER" },
|
||||||
|
{ id: "subagent_fork", envVar: "KIMI_CODE_EXPERIMENTAL_SUBAGENT_FORK" },
|
||||||
{
|
{
|
||||||
id: "auto_session_title",
|
id: "auto_session_title",
|
||||||
envVar: "KIMI_CODE_EXPERIMENTAL_AUTO_SESSION_TITLE",
|
envVar: "KIMI_CODE_EXPERIMENTAL_AUTO_SESSION_TITLE",
|
||||||
},
|
},
|
||||||
{ id: "remote-control", envVar: "KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL" },
|
|
||||||
{
|
|
||||||
id: "search_worker",
|
|
||||||
envVar: "KIMI_CODE_EXPERIMENTAL_SEARCH_WORKER",
|
|
||||||
defaultEnabled: true,
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export const EXPERIMENTAL_MASTER_ENV = "KIMI_CODE_EXPERIMENTAL_FLAG";
|
export const EXPERIMENTAL_MASTER_ENV = "KIMI_CODE_EXPERIMENTAL_FLAG";
|
||||||
|
|||||||
Reference in new issue
Block a user