fix(models): align GetDefaultModel's defaultOn test with AvailableModels - #18
Open
245678000000 wants to merge 1 commit into
Open
Conversation
The two sites that read ProviderModel.defaultOn disagreed on what a
missing field means:
byokModelBuilder.ts defaultOn: model.defaultOn ?? false -> off
AiService.ts filter(x => x.model.defaultOn !== false) -> on
So a model with no defaultOn (a hand-written providers.json, or a config
predating the sidebar writing the flag) is reported to the client as off
in the picker, yet GetDefaultModel would happily push it as the default
model for Composer and Cmd+K.
Introduce a single predicate isModelDefaultOn() next to the ProviderModel
type and route all four reads through it. It keeps the builder's meaning
(only an explicit true counts as on), which is the one that actually
shapes the AvailableModels response; GetDefaultModel now returns {} when
nothing is enabled, and per the existing contract the client keeps its
previous selection.
GetDefaultModel's body is lifted into a named handleGetDefaultModel,
mirroring handleAvailableModels in the same file, so the behaviour is
reachable from tests.
Adds defaultModelSelection.test.ts. Three of its four cases fail on the
old predicate.
Rogers-F
added a commit
to Rogers-F/CCursor
that referenced
this pull request
Aug 29, 2026
- getAutoCompactThreshold 改新公式: 窗口 − min(40K, 15%×窗口) (签名兼容保留 maxOutputTokens 形参但不再参与计算); 逐档值 32K→27,200 / 64K→54,400 / 96K→81,600 / 128K→108,800 / 258.4K→219,640 / 1M→960,000 — 32K/64K 死带消除; 净增长门槛 15K 与 熔断判定不动 - 错误驱动压缩重试: isContextLengthLimitError 白名单分类 (context_length_exceeded / maximum context length / prompt is too long / input token count exceeds 等 9 模式, 普通故障不误判) → performInlineAutoSummarize(budgetOverride=基准预算/2^retry) aggressive 压缩 → 重发本轮请求 (round--), ≤CONTEXT_LENGTH_RETRY_MAX=3 轮硬封顶; 基准预算由首次压缩的 plan.diagnostics.budgetTokens 回填 (未压缩过时按 targetFloor=25%×窗口估计) - 观测补全 ([AUTOCOMPACT] 结构化 log, 无 metrics 依赖): 压缩间隔样本 (事故签名 4-5 分钟/次的直接检出器)、升级链/违约事件 (阶段 3 已含)、 keepTail 构成含占位命中 (阶段 3 已含)、首次消费损失恒 0 计数 (阶段 3 已含)、互斥争用计数 (阶段 3 已含) - 测试: CometixSpace#15 错误分类白名单+aggressive 预算减半单调性 / CometixSpace#18 六档逐值 断言 (含 32K/64K 死带消除); autoSummarize 存量阈值断言更新为新公式
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The two places that read
ProviderModel.defaultOndisagreed on what a missing field means:defaultOn: undefinedhandlers/models/byokModelBuilder.tsmodel.defaultOn ?? falseservices/core/AiService.ts(GetDefaultModel)x.model.defaultOn !== falseSo a model with no
defaultOn— a hand-writtenproviders.json, or a config predating the sidebar writing the flag — is reported to the client as off in the picker, yetGetDefaultModelwould push it as the default model for Composer and Cmd+K.DEFAULT_PROVIDERSseeds no models, so every model comes from user config and can hit this.Change
A single
isModelDefaultOn()predicate next to theProviderModeltype, with all four reads routed through it. It keeps the builder's meaning (only an explicittruecounts as on) because that is the one that actually shapes theAvailableModelsresponse the picker renders.Consequence worth calling out: when nothing is enabled,
GetDefaultModelnow returns{}instead of picking the first model. That is the documented "don't push, client keeps its previous selection" path already in the handler's contract — but if you'd rather have the opposite fix (undefined meaning on everywhere, changing the wire response), say so and I'll flip it.GetDefaultModel's body is lifted into a namedhandleGetDefaultModel, mirroringhandleAvailableModelsin the same file, so the behaviour is reachable from tests. It is exported for that reason.Test plan
New
Cursor++/src/server/tests/defaultModelSelection.test.ts— the predicate, the empty-candidate case, first-enabled/first-enabled-thinking selection, and an invariant that the pushed default is never a modelAvailableModelsreports as off. Three of the four fail on the old predicate (verified by reverting just the filter).pnpm --dir "Cursor++" run check-typespnpm --dir "Cursor++" run lintpnpm --dir "Cursor++" run test:server— 39 files / 371 tests passed (baseline onmainis 38 / 367)