From 99fc4e8480ebeb6c95539263ed95f450ce45e6ad Mon Sep 17 00:00:00 2001 From: ted Date: Mon, 19 Oct 2026 17:18:08 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat(protocol):=20=E6=8C=89=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=92=8C=E8=AF=B7=E6=B1=82=E4=BF=9D=E7=95=99=20auto?= =?UTF-8?q?=20compact=20=E7=AA=97=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 默认跟随请求模型,调用方窗口经内部字段送到当前 job,面板值可热配置。 --- src/lib/admin/panel-api.mjs | 9 +++++ src/lib/protocol/outbound-attempt.mjs | 3 ++ src/lib/protocol/seed-policy.mjs | 10 ++++++ src/lib/transport/rust-kernel-supervisor.mjs | 13 +++++++ test/unit/go-worker-client.test.mjs | 20 +++++++++++ test/unit/kernel-router.test.mjs | 2 ++ web/src/features/settings/protocol-pane.tsx | 37 ++++++++++++++++++-- 7 files changed, 92 insertions(+), 2 deletions(-) diff --git a/src/lib/admin/panel-api.mjs b/src/lib/admin/panel-api.mjs index fa2e77202..f5177d621 100644 --- a/src/lib/admin/panel-api.mjs +++ b/src/lib/admin/panel-api.mjs @@ -475,6 +475,12 @@ export function validatePersonaRoutingPatch(body = {}) { if (Object.prototype.hasOwnProperty.call(compat, 'cch_enabled') && typeof compat.cch_enabled !== 'boolean') { problems.push('cch_enabled 必须是布尔') } + if (Object.prototype.hasOwnProperty.call(compat, 'auto_compact_window') && compat.auto_compact_window != null) { + const windowTokens = Number(compat.auto_compact_window) + if (!Number.isInteger(windowTokens) || windowTokens < 100_000 || windowTokens > 1_000_000) { + problems.push('auto_compact_window 必须是 100000–1000000 的整数') + } + } if ( compat.thinking_display != null && compat.thinking_display !== '' && @@ -1406,6 +1412,9 @@ function presentCompatibility(compat) { .trim() .toLowerCase() out.thinking_display = display === 'passthrough' ? 'passthrough' : 'summarized' + const windowTokens = Number(out.auto_compact_window) + out.auto_compact_window = + Number.isInteger(windowTokens) && windowTokens >= 100_000 && windowTokens <= 1_000_000 ? windowTokens : null return out } diff --git a/src/lib/protocol/outbound-attempt.mjs b/src/lib/protocol/outbound-attempt.mjs index 95326c71b..48388bded 100644 --- a/src/lib/protocol/outbound-attempt.mjs +++ b/src/lib/protocol/outbound-attempt.mjs @@ -3,6 +3,7 @@ * Tests compare envelopes from this module so admin paths cannot drift. */ import { officialMessagesBody } from './anthropic-messages.mjs' +import { callerAutoCompactWindow } from './seed-policy.mjs' import { prepareAnthropicRequest, rewriteToolNames, @@ -195,6 +196,8 @@ export function prepareCliHopBody( if (requestContext?.purpose === 'auto_mode_classifier') return prepareClassifierBody(canonicalBody, { stream }) if (preserveSystem) validateCacheBreakpoints(canonicalBody) let body = officialMessagesBody(canonicalBody, { stream }) + const autoCompactWindow = callerAutoCompactWindow(canonicalBody) + if (autoCompactWindow != null) body.auto_compact_window = autoCompactWindow delete body.metadata if (!preserveSystem) { const leftover = stripCliOwnedSystem(body.system, { preserveCallerEnvironment }) diff --git a/src/lib/protocol/seed-policy.mjs b/src/lib/protocol/seed-policy.mjs index 81b73c80c..6b51a34c5 100644 --- a/src/lib/protocol/seed-policy.mjs +++ b/src/lib/protocol/seed-policy.mjs @@ -118,6 +118,16 @@ export function buildSlotSettingsEnv(pol = {}, { timezone, locale, extra } = {}) return out } +export function callerAutoCompactWindow(body = {}) { + const sources = [body?.settings?.env, body?.claude_settings?.env, body?.env] + for (const source of sources) { + if (!source || typeof source !== 'object' || Array.isArray(source)) continue + const value = Number(source.CLAUDE_CODE_AUTO_COMPACT_WINDOW) + if (Number.isInteger(value) && value >= 100_000 && value <= 1_000_000) return value + } + return null +} + export function buildSeedSettingsEnv(pol = {}, extra = {}) { return buildSlotSettingsEnv(pol, { extra }) } diff --git a/src/lib/transport/rust-kernel-supervisor.mjs b/src/lib/transport/rust-kernel-supervisor.mjs index 3c70bf3e4..4dd986d56 100644 --- a/src/lib/transport/rust-kernel-supervisor.mjs +++ b/src/lib/transport/rust-kernel-supervisor.mjs @@ -37,6 +37,11 @@ import { } from '../oauth/oauth-credentials.mjs' import { slotHost } from '../vm/slot-host.mjs' +function normalizeAutoCompactWindow(value) { + const windowTokens = Number(value) + return Number.isInteger(windowTokens) && windowTokens >= 100_000 && windowTokens <= 1_000_000 ? windowTokens : null +} + const starts = new Map() const KVM_HEALTH_MS = { kvm: 120_000, tcg: 480_000 } @@ -693,6 +698,13 @@ export function writeKernelConfig( const previousMax = Number(previous.max_request_bytes) const requestBytes = routing == null && previousMax > 0 ? previousMax : maxRequestBytes(routing) const cchEnabled = routing == null ? previous.cch_enabled !== false : routing?.compatibility?.cch_enabled !== false + const previousWindow = Number(previous.auto_compact_window) + const autoCompactWindow = + routing == null + ? Number.isInteger(previousWindow) && previousWindow >= 100_000 && previousWindow <= 1_000_000 + ? previousWindow + : null + : normalizeAutoCompactWindow(routing?.compatibility?.auto_compact_window) const sessionIdleTtlSeconds = routing == null ? normalizeSessionIdleTtlSeconds(previous.session_idle_ttl_seconds) @@ -726,6 +738,7 @@ export function writeKernelConfig( cli_version: OFFICIAL_CLI_VERSION, default_cache_ttl: defaultCacheTtl, cch_enabled: cchEnabled, + auto_compact_window: autoCompactWindow, } if (tz) config.timezone = tz diff --git a/test/unit/go-worker-client.test.mjs b/test/unit/go-worker-client.test.mjs index 43a1a32e1..98024a15a 100644 --- a/test/unit/go-worker-client.test.mjs +++ b/test/unit/go-worker-client.test.mjs @@ -14,6 +14,7 @@ import { restoreUncommittedHop, semanticStatusForStreamError, } from '../../src/lib/transport/go-worker-client.mjs' +import { prepareCliHopBody } from '../../src/lib/protocol/outbound-attempt.mjs' import { extractOpenaiUsage } from '../../src/lib/protocol/openai-usage.mjs' import { callRustKernel, rustKernelHealth } from '../../src/lib/transport/rust-kernel-client.mjs' import { forwardApi, readApiJson } from '../../src/lib/transport/api-kernel-client.mjs' @@ -164,6 +165,25 @@ test('cli-hop envelope keeps role=system turns that the VM betas do not declare' assert.deepEqual(out.body.system, body.system) }) +test('cli-hop keeps the caller compact window outside settings', () => { + const prepared = prepareCliHopBody({ + model: 'claude-opus-5-5', + messages: [{ role: 'user', content: 'hi' }], + settings: { theme: 'light', env: { CLAUDE_CODE_AUTO_COMPACT_WINDOW: '1000000', TZ: 'UTC' } }, + }) + const out = finalizeWorkerPayload({ + body: prepared, + reqHeaders: {}, + exec: { homeDir: '', vm: { claude: { mode: 'setup-token', scope: 'user:inference' } } }, + identity: null, + cliHop: true, + }) + assert.equal(prepared.settings, undefined) + assert.equal(out.body.settings, undefined) + assert.equal(out.body.env, undefined) + assert.equal(out.body.auto_compact_window, 1000000) +}) + test('setup-token cli-hop summarizes hidden thinking by default and keeps updates when passthrough', () => { const exec = { homeDir: '', vm: { claude: { mode: 'setup-token', scope: 'user:inference' } } } const updates = finalizeWorkerPayload({ diff --git a/test/unit/kernel-router.test.mjs b/test/unit/kernel-router.test.mjs index cc7d880c9..4d6706486 100644 --- a/test/unit/kernel-router.test.mjs +++ b/test/unit/kernel-router.test.mjs @@ -631,6 +631,7 @@ test('writeKernelConfig separates container paths from host socket paths', () => assert.equal(doc.https_proxy, undefined) assert.equal(doc.slots_per_worker, WRAP_SLOT_MAX) assert.equal(doc.default_cache_ttl, '1h') + assert.equal(doc.auto_compact_window, null) assert.match(written.socketPath.replace(/\\/g, '/'), /vms\/vm-09\/run\/kernel\.sock$/) assert.equal(fs.readFileSync(written.tokenPath, 'utf8').trim(), 'tok') const exec = { vmId: 'vm-09', homeDir: path.join(root, 'vms', 'vm-09', 'cli-home'), vm: { id: 'vm-09' } } @@ -702,6 +703,7 @@ test('writeKernelConfig cli-hop writes local_cli without secrets', () => { assert.equal(doc.system_layout, 'identity') assert.equal(doc.cli_version, OFFICIAL_CLI_VERSION) assert.equal(doc.default_cache_ttl, '5m') + assert.equal(doc.auto_compact_window, null) assert.equal(doc.timezone, 'America/New_York') assert.equal(doc.proxy_url, '') assert.equal(doc.proxy_required, false) diff --git a/web/src/features/settings/protocol-pane.tsx b/web/src/features/settings/protocol-pane.tsx index 1e38d8cf7..1ccbcdd26 100644 --- a/web/src/features/settings/protocol-pane.tsx +++ b/web/src/features/settings/protocol-pane.tsx @@ -3,7 +3,7 @@ import { SESSION_IDLE_TTL_SECONDS_MAX, SESSION_IDLE_TTL_SECONDS_MIN, } from '@/types/panel-routing' -import { Brain, Check, Clock3, Database, Hash, ShieldCheck } from 'lucide-react' +import { Brain, Check, Clock3, Database, Hash, Scaling, ShieldCheck } from 'lucide-react' import { cacheTtlFromCompat, detectProxiedOfficialCcFromCompat, @@ -32,6 +32,12 @@ const CLAUDE_CODE_FINGERPRINT: [string, string][] = [ ['计费块', 'cc_version = UA 版本'], ] +function autoCompactWindowValue(value: unknown) { + const tokens = Number(value) + if (tokens === 200_000 || tokens === 500_000 || tokens === 1_000_000) return String(tokens) + return 'model' +} + export function ProtocolPane({ compat, inference, @@ -188,7 +194,34 @@ export function ProtocolPane({ + + + onCompatChange({ + ...compat, + auto_compact_window: value === 'model' ? null : Number(value), + }) + } + /> + + + From 6958efbb1ae635337a485af28781c0f890bd186c Mon Sep 17 00:00:00 2001 From: ted Date: Mon, 19 Oct 2026 17:21:41 +0800 Subject: [PATCH 2/6] =?UTF-8?q?fix(protocol):=20=E6=B8=85=E7=90=86=20setti?= =?UTF-8?q?ngs=20=E5=89=8D=E4=BF=9D=E7=95=99=20auto=20compact=20=E7=AA=97?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 窗口在入站清理前提取,再经内部字段进入 native body。 --- src/lib/protocol/handle-protocol.mjs | 5 ++++- src/lib/protocol/outbound-attempt.mjs | 8 +++++--- test/unit/go-worker-client.test.mjs | 10 +++++++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/lib/protocol/handle-protocol.mjs b/src/lib/protocol/handle-protocol.mjs index 65c8fe438..ad30b11f3 100644 --- a/src/lib/protocol/handle-protocol.mjs +++ b/src/lib/protocol/handle-protocol.mjs @@ -35,7 +35,7 @@ import { createClaudeMessageAssembler, applyClaudeSSELineToMessage, } from './convert.mjs' -import { sanitizeInboundBody, defaultSeedPolicy } from './seed-policy.mjs' +import { sanitizeInboundBody, defaultSeedPolicy, callerAutoCompactWindow } from './seed-policy.mjs' import { fingerprintRequest } from './client-fingerprint.mjs' import { validateOfficialModel } from './models.mjs' import { handleCodexProtocol, handleCodexSearch } from './handle-codex.mjs' @@ -619,11 +619,13 @@ export function createHandleProtocol(deps) { ) } + const autoCompactWindow = callerAutoCompactWindow(inbound) let ctx = { path: pathName, protocol, body: sanitizeInboundBody(inbound, defaultSeedPolicy()), headers: { ...req.headers }, + autoCompactWindow, } ctx = applyIntercept(cfg.intercept.rules, 'before_convert', ctx) const bodyCheck = validateRequestBody(protocol, ctx.body) @@ -1291,6 +1293,7 @@ export function createHandleProtocol(deps) { preserveSystem: officialPassthrough, preserveThinkingBlocks: preserveCliHopThinkingBlocks, preserveCallerEnvironment, + autoCompactWindow: ctx.autoCompactWindow, }) hopBody = await materializeRemoteImageSources(hopBody) if (panelRewrite) { diff --git a/src/lib/protocol/outbound-attempt.mjs b/src/lib/protocol/outbound-attempt.mjs index 48388bded..7e9be7668 100644 --- a/src/lib/protocol/outbound-attempt.mjs +++ b/src/lib/protocol/outbound-attempt.mjs @@ -3,7 +3,6 @@ * Tests compare envelopes from this module so admin paths cannot drift. */ import { officialMessagesBody } from './anthropic-messages.mjs' -import { callerAutoCompactWindow } from './seed-policy.mjs' import { prepareAnthropicRequest, rewriteToolNames, @@ -191,13 +190,16 @@ export function prepareCliHopBody( preserveSystem = false, preserveThinkingBlocks = false, preserveCallerEnvironment = false, + autoCompactWindow = null, } = {}, ) { if (requestContext?.purpose === 'auto_mode_classifier') return prepareClassifierBody(canonicalBody, { stream }) if (preserveSystem) validateCacheBreakpoints(canonicalBody) let body = officialMessagesBody(canonicalBody, { stream }) - const autoCompactWindow = callerAutoCompactWindow(canonicalBody) - if (autoCompactWindow != null) body.auto_compact_window = autoCompactWindow + const windowTokens = Number(autoCompactWindow) + if (Number.isInteger(windowTokens) && windowTokens >= 100_000 && windowTokens <= 1_000_000) { + body.auto_compact_window = windowTokens + } delete body.metadata if (!preserveSystem) { const leftover = stripCliOwnedSystem(body.system, { preserveCallerEnvironment }) diff --git a/test/unit/go-worker-client.test.mjs b/test/unit/go-worker-client.test.mjs index 98024a15a..f82cf787b 100644 --- a/test/unit/go-worker-client.test.mjs +++ b/test/unit/go-worker-client.test.mjs @@ -15,6 +15,7 @@ import { semanticStatusForStreamError, } from '../../src/lib/transport/go-worker-client.mjs' import { prepareCliHopBody } from '../../src/lib/protocol/outbound-attempt.mjs' +import { callerAutoCompactWindow, defaultSeedPolicy, sanitizeInboundBody } from '../../src/lib/protocol/seed-policy.mjs' import { extractOpenaiUsage } from '../../src/lib/protocol/openai-usage.mjs' import { callRustKernel, rustKernelHealth } from '../../src/lib/transport/rust-kernel-client.mjs' import { forwardApi, readApiJson } from '../../src/lib/transport/api-kernel-client.mjs' @@ -166,11 +167,14 @@ test('cli-hop envelope keeps role=system turns that the VM betas do not declare' }) test('cli-hop keeps the caller compact window outside settings', () => { - const prepared = prepareCliHopBody({ + const inbound = { model: 'claude-opus-5-5', messages: [{ role: 'user', content: 'hi' }], settings: { theme: 'light', env: { CLAUDE_CODE_AUTO_COMPACT_WINDOW: '1000000', TZ: 'UTC' } }, - }) + } + const autoCompactWindow = callerAutoCompactWindow(inbound) + const sanitized = sanitizeInboundBody(inbound, defaultSeedPolicy()) + const prepared = prepareCliHopBody(sanitized, { autoCompactWindow }) const out = finalizeWorkerPayload({ body: prepared, reqHeaders: {}, @@ -178,7 +182,7 @@ test('cli-hop keeps the caller compact window outside settings', () => { identity: null, cliHop: true, }) - assert.equal(prepared.settings, undefined) + assert.equal(sanitized.settings, undefined) assert.equal(out.body.settings, undefined) assert.equal(out.body.env, undefined) assert.equal(out.body.auto_compact_window, 1000000) From 20bc6b9de699e7eaf00e27b484df7e7a3a4ab07e Mon Sep 17 00:00:00 2001 From: ted Date: Mon, 19 Oct 2026 17:27:10 +0800 Subject: [PATCH 3/6] =?UTF-8?q?fix(web):=20=E5=8E=BB=E6=8E=89=E5=8D=8F?= =?UTF-8?q?=E8=AE=AE=E9=A1=B5=E6=9C=AA=E4=BD=BF=E7=94=A8=E7=9A=84=E5=9B=BE?= =?UTF-8?q?=E6=A0=87=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/features/settings/protocol-pane.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/features/settings/protocol-pane.tsx b/web/src/features/settings/protocol-pane.tsx index 1ccbcdd26..4a2b13e4f 100644 --- a/web/src/features/settings/protocol-pane.tsx +++ b/web/src/features/settings/protocol-pane.tsx @@ -3,7 +3,7 @@ import { SESSION_IDLE_TTL_SECONDS_MAX, SESSION_IDLE_TTL_SECONDS_MIN, } from '@/types/panel-routing' -import { Brain, Check, Clock3, Database, Hash, Scaling, ShieldCheck } from 'lucide-react' +import { Brain, Check, Clock3, Database, Scaling, ShieldCheck } from 'lucide-react' import { cacheTtlFromCompat, detectProxiedOfficialCcFromCompat, From aa01742f83b74641dc5b9f0b3ad86ff4f7f9cb9f Mon Sep 17 00:00:00 2001 From: ted Date: Mon, 19 Oct 2026 17:38:34 +0800 Subject: [PATCH 4/6] =?UTF-8?q?test(protocol):=20=E7=A1=AE=E8=AE=A4?= =?UTF-8?q?=E6=B8=85=E7=90=86=E5=90=8E=E7=9A=84=20body=20=E4=B8=8D?= =?UTF-8?q?=E5=86=8D=E6=90=BA=E5=B8=A6=20compact=20=E7=AA=97=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 窗口必须在 settings 删除前提取,再传给 native body。 --- test/unit/go-worker-client.test.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/go-worker-client.test.mjs b/test/unit/go-worker-client.test.mjs index f82cf787b..388d601a8 100644 --- a/test/unit/go-worker-client.test.mjs +++ b/test/unit/go-worker-client.test.mjs @@ -174,6 +174,7 @@ test('cli-hop keeps the caller compact window outside settings', () => { } const autoCompactWindow = callerAutoCompactWindow(inbound) const sanitized = sanitizeInboundBody(inbound, defaultSeedPolicy()) + assert.equal(callerAutoCompactWindow(sanitized), null) const prepared = prepareCliHopBody(sanitized, { autoCompactWindow }) const out = finalizeWorkerPayload({ body: prepared, From 3b1b7af21d96599ded22e84b9eceb65ef45fecdf Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 19 Oct 2026 12:54:55 +0000 Subject: [PATCH 5/6] =?UTF-8?q?docs(changelog):=20=E6=9C=AA=E5=8F=91?= =?UTF-8?q?=E5=B8=83=E6=9D=A1=E7=9B=AE=20=E2=80=94=20auto=20compact=20?= =?UTF-8?q?=E7=AA=97=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ted --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d7dbbea4..e5e69ad66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - 槽位种子页默认锁定:需确认解锁后才能改配置,播种前再次确认;时区/语言提供 en、cn、jp 基础选项。时区跟随当前 SOCKS5(空/非手动钉住)时展示出口时区,播种经 `timezone_follow_proxy` 写入;可改固定 IANA 时区或改回跟随。TZ/LANG/LC_ALL 仍不经 `extra_env` 覆盖契约键。 - 槽位种子页:`settings.json` 的 env 行与 `theme` 可直接编辑并随播种写入;`autoUpdates`、`grove_enabled` 只读且播种时固定为 `false`;TZ/LANG/LC_ALL、遥测 kill-switch、Bedrock/Vertex、gateway hint 等同理只读(播种由契约重写)。缺 `CLAUDE_CODE_ATTRIBUTION_HEADER` 时默认 `0`。调试上传默认关,独立 query 拉最近 40 条上传,切换开关不重置未保存编辑;Go sidecar 写 `vms//run/telemetry-upload.log`,面板 `GET seed-settings?debug=1` 返回 `telemetry_log`。 +- 协议页可配置 `routing.compatibility.auto_compact_window`(100K–1M 或跟随模型);入站在清理 settings 前提取调用方 `CLAUDE_CODE_AUTO_COMPACT_WINDOW`,经内部 `auto_compact_window` 字段进入当前 job,清理后的 body 不再携带该 env。 - 槽位种子页按当前槽 `settings.json` 列出真实配置;`claude.setting` 可编辑播种;缺失文件返回 `null`、空文件返回空串,不用策略默认冒充槽内文件;遥测开关与 sidecar 进程状态分开展示,保存不因遥测进程刷新失败而 502。 - fleet 遥测刷新在 kin-egress 二进制被替换(含 `(deleted)` 旧进程与脏 pidfile)时,会按 egress 配置扫停全部 helper、等待 `/proc/` 消失后再绑定新二进制;同一 SOCKS 出口的 stop/start 与 `ensureProxyEgress` 共用 per-proxy 锁,避免并发 telemetry 互相 SIGTERM。(#604) - 面板:侧栏「GitHub / 文档」两枚链接不再折行,字体偏宽时「文档」不会逐字竖排,空间不够先缩箭头再省略文字;VM 列表搜索框关闭浏览器自动填充,不再被回填成登录邮箱。 From aa0810787b00bc58afa2df665534426ac8cfa2e9 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 19 Oct 2026 13:04:27 +0000 Subject: [PATCH 6/6] =?UTF-8?q?style(web):=20prettier=20=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E9=A1=B5=20auto=20compact=20=E5=8C=BA=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ted --- web/src/features/settings/protocol-pane.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/web/src/features/settings/protocol-pane.tsx b/web/src/features/settings/protocol-pane.tsx index 4a2b13e4f..253373c29 100644 --- a/web/src/features/settings/protocol-pane.tsx +++ b/web/src/features/settings/protocol-pane.tsx @@ -3,7 +3,14 @@ import { SESSION_IDLE_TTL_SECONDS_MAX, SESSION_IDLE_TTL_SECONDS_MIN, } from '@/types/panel-routing' -import { Brain, Check, Clock3, Database, Scaling, ShieldCheck } from 'lucide-react' +import { + Brain, + Check, + Clock3, + Database, + Scaling, + ShieldCheck, +} from 'lucide-react' import { cacheTtlFromCompat, detectProxiedOfficialCcFromCompat, @@ -34,7 +41,8 @@ const CLAUDE_CODE_FINGERPRINT: [string, string][] = [ function autoCompactWindowValue(value: unknown) { const tokens = Number(value) - if (tokens === 200_000 || tokens === 500_000 || tokens === 1_000_000) return String(tokens) + if (tokens === 200_000 || tokens === 500_000 || tokens === 1_000_000) + return String(tokens) return 'model' }