Skip to content

feat(virtualmodels): disable_reasoning flag for redirects (Kimi Code K2.6 via virtual models) - #31

Draft
weselben wants to merge 1 commit into
mainfrom
proto/kimicode-vm-aliases
Draft

feat(virtualmodels): disable_reasoning flag for redirects (Kimi Code K2.6 via virtual models)#31
weselben wants to merge 1 commit into
mainfrom
proto/kimicode-vm-aliases

Conversation

@weselben

Copy link
Copy Markdown
Owner

Prototype C of 4 for #27 — a virtual-models based approach. Compare: prototype A (provider-level static map + KIMICODE_MODEL_MAP=off toggle, PR #30), prototype B (provider-level map, always-on, PR #29), prototype D (alternative architecture).

Approach

A new disable_reasoning flag on virtual model redirects lets an operator make any redirect serve the non-thinking variant of its target:

virtual_models:
  - source: kimi-k2.6
    target: kimicode/kimi-for-coding
    disable_reasoning: true
  - source: kimi-k2.7-code
    target: kimicode/kimi-for-coding
  - source: kimi-k2.7-code-highspeed
    target: kimicode/kimi-for-coding-highspeed
  - source: kimi-k3
    target: kimicode/k3
  - source: kimi-k3-256k
    target: kimicode/k3-256k

When a request hits a flagged redirect, rewriteChatRequest strips the typed Reasoning field and the flat reasoning_effort extra, then sets thinking.type=disabled on the forwarded copy — so Kimi Code routes the request to the K2.6 behavior of the same kimi-for-coding endpoint. Providers without a thinking toggle ignore the unknown extra (Postel's law).

What's wired

  • config.VirtualModelConfig.DisableReasoning bool (yaml + json)
  • virtualmodels.VirtualModel.DisableReasoning bool + View.DisableReasoning bool
  • virtualmodels.Service.DisableReasoningForSource(source string) bool (lookup by source)
  • virtualmodels.Service.ResolveRedirectForUserPath (returns full Resolution so request rewrites can consult the matched redirect's flags)
  • rewriteChatRequest applies the flag; signature of the two internal resolve helpers now returns the matched source too (batch preparer updated for the new signature)
  • SQL store: new disable_reasoning boolean column with a backfill migration (mirrors the slowdown pattern)
  • Mongo store: bson field, round-tripped in upsert/decode
  • Admin View carries the flag

Trade-offs vs A/B

Aspect A/B (provider-level map) C (this)
Default-on yes operator-only — must declare the aliases
Metadata for canonicals yes (auto-resolved from registry bare entries) no — pricing/modes must come from a registered upstream model; if the target isn't in the registry, metadata is missing
Thinking-pin per alias yes yes (this flag)
K2.6 routing yes (canonical kimi-k2.6 → thinking off) yes (disable_reasoning: true redirect to kimicode/kimi-for-coding)
Operator-editable without code no yes
Reuses existing primitives new provider code existing virtual models
Token/cost tracking records client-requested canonical name records the post-redirect resolved target — see caveat below

Caveat: usage recording

Today internal/gateway/usage.go records the resolved target model (kimicode/kimi-for-coding), not the requested virtual-model source. For the K2.6 case this means usage rows will show kimi-for-coding rather than kimi-k2.6, which is misleading. A small follow-up — adding a precedence slot for the original request model when a virtual-model alias rewrote it — would close this gap. The PR documents the divergence; fixing it is out of scope here so this stays a minimal, reviewable diff.

Tests

  • go build ./... — pass
  • go test ./internal/virtualmodels/... ./config/... — pass (4 new unit tests + carried-over suite):
    • TestRewriteChatRequest_DisableReasoningStripsControls — flag strips Reasoning + reasoning_effort, sets thinking.type=disabled, preserves other extras, does not mutate the caller's request
    • TestRewriteChatRequest_DisableReasoningUnsetKeepsControls — unflagged redirect leaves reasoning alone
    • TestService_DisableReasoningForSource — flag lookup by source, missing/empty handled
    • TestConfigModel_MapsDisableReasoning — config → service mapping round-trips the flag and marks Managed

Refs #27

Lets a redirect strip reasoning controls from the forwarded request and
force the provider's thinking toggle off (thinking.type=disabled), so
the request is served by the non-thinking variant of the target model —
e.g. Kimi Code's K2.6 behind kimi-for-coding. Generic across providers;
unknown extra fields are forwarded (Postel's law) so providers without
a thinking toggle are unaffected.

Round-trips through config.VirtualModelConfig, SQL store (new
disable_reasoning column + migration), Mongo store, View, and admin API.
resolveRedirectRequestSelector / resolveRedirectRoutableSelector now
return the matched redirect source so rewriteChatRequest can consult
the flag; batch_preparer updated for the new signature.

Refs #27
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant