Skip to content

feat(kimi): support fixed temperature by thinking#1507

Merged
zerob13 merged 2 commits into
devfrom
feat/kimi-fixed-temperature-compat
Apr 22, 2026
Merged

feat(kimi): support fixed temperature by thinking#1507
zerob13 merged 2 commits into
devfrom
feat/kimi-fixed-temperature-compat

Conversation

@yyhhyyyyyy
Copy link
Copy Markdown
Collaborator

@yyhhyyyyyy yyhhyyyyyy commented Apr 22, 2026

https://platform.kimi.com/docs/guide/kimi-k2-6-quickstart#%E5%8F%82%E6%95%B0%E5%8F%98%E5%8A%A8%E8%AF%B4%E6%98%8E
image

Summary by CodeRabbit

  • New Features

    • Moonshot Kimi K2.5/K2.6 models now automatically lock temperature based on thinking mode (1.0 when enabled, 0.6 when disabled). Temperature controls become disabled in chat and settings interfaces when this policy is active.
  • Localization

    • Added temperature-locking explanations across 12 supported languages.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 22, 2026

📝 Walkthrough

Walkthrough

This PR implements Moonshot Kimi K2.5/K2.6 temperature policy enforcement, introducing a new shared module that resolves fixed temperature values (1.0 when reasoning enabled, 0.6 disabled) and integrating this policy across presenter layers, provider option mapping, runtime request generation, and frontend UI components while adding multilingual support.

Changes

Cohort / File(s) Summary
Core Policy Module
src/shared/moonshotKimiPolicy.ts
New module defining temperature policy for Moonshot Kimi models (kimi-k2.5, kimi-k2.6), with constants for enabled/disabled temperatures (1.0/0.6), policy resolution functions based on provider/model ID and reasoning state, and helpers to apply policies to config objects.
Presenter Layer
src/main/presenter/agentRuntimePresenter/index.ts, src/main/presenter/configPresenter/modelConfig.ts
Integrated policy resolution into generation settings and model config flows; agentRuntimePresenter resolves fixed temperature during default/sanitized settings, while configPresenter applies policies when constructing, retrieving, and persisting model configs for provider-backed models.
Provider Options & Runtime
src/main/presenter/llmProviderPresenter/aiSdk/providerOptionsMapper.ts, src/main/presenter/llmProviderPresenter/aiSdk/runtime.ts
providerOptionsMapper consults policy to conditionally set thinking configuration; runtime.ts normalizes incoming model config via policy, introduces resolveRuntimeTemperature() to force temperature inclusion when policy is active, and applies policy-driven temperature overrides in both non-streaming and streaming paths.
Frontend UI Components
src/renderer/src/components/chat/ChatStatusBar.vue, src/renderer/src/components/settings/ModelConfigDialog.vue
Added policy-aware computed values (isMoonshotKimiTemperatureLocked, moonshotKimiTemperatureHint); temperature controls (buttons, input) now disable when locked, updateLocalGenerationSettings strips temperature when locked, and both components enforce policy-derived reasoning and temperature values via watchers/handlers.
Localization
src/renderer/src/i18n/*/chat.json, src/renderer/src/i18n/*/settings.json
Added translation keys advancedSettings.temperatureFixedMoonshotKimi (chat) and model.modelConfig.temperature.fixedMoonshotKimi (settings) across 10 language variants (en-US, da-DK, fa-IR, fr-FR, he-IL, ja-JP, ko-KR, pt-BR, ru-RU, zh-CN, zh-HK, zh-TW) with {enabled} / {disabled} placeholders.
Test Coverage
test/main/presenter/agentRuntimePresenter/agentRuntimePresenter.test.ts, test/main/presenter/llmProviderPresenter/aiSdkProviderOptionsMapper.test.ts, test/main/presenter/llmProviderPresenter/aiSdkRuntime.test.ts, test/main/presenter/providerDbModelConfig.test.ts, test/renderer/components/ChatStatusBar.test.ts, test/renderer/components/ModelConfigDialog.test.ts
Added comprehensive test cases verifying policy application across presenter layers, provider options mapping, runtime temperature overrides, model config resolution, and UI lock behavior for Moonshot Kimi models.

Sequence Diagram(s)

sequenceDiagram
    participant Agent as Agent Runtime
    participant Config as Config Presenter
    participant Policy as Policy Module
    participant Provider as Provider Options
    participant Runtime as AI SDK Runtime
    
    Agent->>Config: getModelConfig(providerId, modelId)
    Config->>Policy: getMoonshotKimiTemperaturePolicy(providerId, modelId)
    Policy-->>Config: policy (if applicable)
    Config->>Config: applyMoonshotKimiReasoningTemperaturePolicy()
    Config-->>Agent: normalized config
    Agent->>Policy: resolveMoonshotKimiTemperaturePolicy(providerId, modelId, reasoning)
    Policy-->>Agent: fixedTemperature (1.0 or 0.6)
    Agent->>Agent: buildDefaultGenerationSettings(fixedTemperature)
    Agent-->>Agent: temperature overridden
    
    Agent->>Provider: buildProviderOptions(providerId, modelId, reasoning)
    Provider->>Policy: resolveMoonshotKimiTemperaturePolicy()
    Policy-->>Provider: policy with thinking type
    Provider->>Provider: set config.thinking type
    Provider-->>Agent: optionsWithThinking
    
    Agent->>Runtime: runAiSdkGenerateText(modelConfig, settings)
    Runtime->>Policy: resolveMoonshotKimiTemperaturePolicy()
    Policy-->>Runtime: temperature override
    Runtime->>Runtime: resolveRuntimeTemperature(shouldForce=true)
    Runtime->>Runtime: generateText/streamText with forced temperature
    Runtime-->>Agent: result
Loading
sequenceDiagram
    participant User as User
    participant UI as ChatStatusBar
    participant Policy as Policy Module
    participant Settings as Generation Settings
    
    User->>UI: Open chat with Moonshot Kimi model
    UI->>Policy: resolveMoonshotKimiTemperaturePolicy(providerId, modelId)
    Policy-->>UI: policy + isMoonshotKimiTemperatureLocked=true
    UI->>UI: Disable temperature input & increment buttons
    UI->>UI: Display moonshotKimiTemperatureHint
    
    User->>UI: Attempt to change temperature
    UI->>UI: Early return (locked)
    UI->>UI: Temperature unchanged
    
    User->>UI: Update generation settings
    UI->>Settings: updateLocalGenerationSettings(patch)
    Settings->>Settings: Strip temperature from patch if locked
    Settings-->>UI: normalized patch
    UI-->>User: Settings applied (temperature excluded)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • zerob13

Poem

🐰 A Kimi's thought now locked in place,
Temperature fixed with grace,
When reason flows at 1.0 bright,
Or 0.6 when thinking takes flight,
Your UI buttons bow with care! 🎯

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(kimi): support fixed temperature by thinking' clearly and specifically describes the main feature added: enabling fixed temperature control for Kimi models based on reasoning/thinking state.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/kimi-fixed-temperature-compat

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 and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/presenter/llmProviderPresenter/aiSdk/runtime.ts (1)

315-338: ⚠️ Potential issue | 🟡 Minor

Minor: image-generation trace still emits the pre-normalized modelConfig.

The image-generation branch at Line 315 now uses normalizedModelConfig for the runtime check, but the trace emission at Line 331 still passes the original modelConfig. The other two trace calls in this file (Lines 279 and 381) were updated to use normalizedModelConfig. In practice Kimi won't hit the image path, so no behavior divergence today, but for consistency (and to keep trace payloads uniformly reflecting the policy-applied config) consider switching this one too.

🔧 Suggested tweak
-    await context.emitRequestTrace?.(modelConfig, {
+    await context.emitRequestTrace?.(normalizedModelConfig, {
       endpoint: providerContext.imageEndpoint ?? providerContext.endpoint,
       headers: context.buildTraceHeaders?.() ?? context.defaultHeaders,
       body: {
         model: providerContext.resolvedModelId ?? modelId,
         prompt
       }
     })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/presenter/llmProviderPresenter/aiSdk/runtime.ts` around lines 315 -
338, The image-generation branch uses normalizedModelConfig for runtime checks
but still passes the original modelConfig into the trace; update the
context.emitRequestTrace call in the image path (the block guarded by
shouldUseImageGenerationRuntime and using
extractImagePrompt/createAiSdkProviderContext) to pass normalizedModelConfig
instead of modelConfig so the emitted trace payloads consistently reflect the
policy-normalized configuration.
🧹 Nitpick comments (3)
test/main/presenter/llmProviderPresenter/aiSdkRuntime.test.ts (1)

257-325: Consider parameterizing these Moonshot cases over K2.5 as well.

The new runtime assertions only exercise moonshotai/kimi-k2.6, while the UI copy and Kimi docs describe the same temperature policy for the K2.6/K2.5 series. A K2.5 matcher regression would currently pass. Reference: https://platform.kimi.com/docs/guide/kimi-k2-6-quickstart#%E5%8F%82%E6%95%B0%E5%8F%98%E5%8A%A8%E8%AF%B4%E6%98%8E

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/main/presenter/llmProviderPresenter/aiSdkRuntime.test.ts` around lines
257 - 325, The two Moonshot tests only assert behavior for
'moonshotai/kimi-k2.6' so K2.5 regressions would be missed; parameterize the
tests to run the same assertions for both 'moonshotai/kimi-k2.6' and
'moonshotai/kimi-k2.5' (use test.each or a small loop) and replace the
hard-coded model id in the runAiSdkGenerateText and runAiSdkCoreStream calls
with the parameterized modelId; keep the same expectations against
mockGenerateText, mockStreamText, tracePayloads and events so both model ids are
covered.
src/renderer/src/components/settings/ModelConfigDialog.vue (1)

933-952: Minor redundancy with the policy-enforcement watcher.

The watcher at lines 1403-1420 already forces config.value.reasoning to resolvedMoonshotKimiTemperaturePolicy.reasoningEnabled whenever the policy applies. So at save time, config.value.reasoning should already equal fixedTemperatureKimi?.reasoningEnabled, making the second resolve in buildCustomModelPayload redundant.

You could simplify to just reasoning: config.value.reasoning ?? false and rely on the watcher as the single source of truth. Not blocking — the current form is defensive and safe.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/src/components/settings/ModelConfigDialog.vue` around lines 933
- 952, buildCustomModelPayload currently computes fixedTemperatureKimi via
resolveMoonshotKimiTemperaturePolicy then uses it to set reasoning, which is
redundant because the watcher already enforces config.value.reasoning; remove
the fixedTemperatureKimi variable and simplify the payload to use reasoning:
config.value.reasoning ?? false (keep other fields unchanged) so the watcher
remains the single source of truth; leave resolveMoonshotKimiTemperaturePolicy
usage elsewhere if needed but do not re-resolve here.
src/shared/moonshotKimiPolicy.ts (1)

33-59: _providerId is intentionally ignored — worth documenting.

Matching purely on model ID means the policy fires for any provider that serves a model literally named kimi-k2.5/kimi-k2.6 (or moonshotai/...), including new-api, OpenRouter-style proxies, etc. This is almost certainly intentional (proxies inherit Moonshot's temperature semantics), but a short JSDoc on getMoonshotKimiTemperaturePolicy noting "matched by model ID across all providers, since Moonshot proxies share the same temperature contract" would prevent future confusion and justify the _providerId underscore.

If a third-party provider ever re-uses these IDs under different temperature semantics, the policy would over-apply — but that seems sufficiently unlikely to not warrant a provider allowlist today.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/moonshotKimiPolicy.ts` around lines 33 - 59, Add a short JSDoc
above getMoonshotKimiTemperaturePolicy explaining that the _providerId parameter
is intentionally ignored and the policy matches purely on model ID across all
providers (e.g., proxies like new-api/OpenRouter) because Moonshot model IDs
carry temperature semantics; mention that this is why the parameter is
underscored and warn that if third parties reuse these model IDs with different
semantics the policy may over-apply.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/presenter/configPresenter/modelConfig.ts`:
- Around line 126-136: The current flow in applyProviderSpecificPolicies returns
applyMoonshotKimiReasoningTemperaturePolicy(providerId, modelId, config) which
treats reasoning: undefined as disabled; update the logic so Kimi configs
preserve the default "thinking enabled" behavior: if the providerId indicates
Kimi (or in applyMoonshotKimiReasoningTemperaturePolicy itself) and
config.reasoning === undefined, set reasoning to true on the ModelConfig before
applying temperature defaults (or modify
applyMoonshotKimiReasoningTemperaturePolicy to implicitly treat undefined as
true), ensuring callers like applyProviderSpecificPolicies and any other
consumers get the correct default; alternatively consolidate the defaulting in
src/shared/moonshotKimiPolicy.ts so all callers inherit the same behavior.

In `@src/main/presenter/llmProviderPresenter/aiSdk/providerOptionsMapper.ts`:
- Around line 131-141: The current call to resolveMoonshotKimiTemperaturePolicy
with params.modelConfig.reasoning causes Kimi base models to default to
thinkingType: 'disabled' when reasoning is undefined; update the logic so that
resolveMoonshotKimiTemperaturePolicy (or moonshotKimiPolicy.ts) does not emit a
thinkingType: 'disabled' when params.modelConfig.reasoning is omitted — instead
leave thinking/thinkingType undefined (or centralize the default behavior in
src/shared/moonshotKimiPolicy.ts) so that
getReasoningEffectiveEnabledForProvider can apply the intended default; adjust
resolveMoonshotKimiTemperaturePolicy and/or the policy module to only set
disabled when reasoning was explicitly provided.

---

Outside diff comments:
In `@src/main/presenter/llmProviderPresenter/aiSdk/runtime.ts`:
- Around line 315-338: The image-generation branch uses normalizedModelConfig
for runtime checks but still passes the original modelConfig into the trace;
update the context.emitRequestTrace call in the image path (the block guarded by
shouldUseImageGenerationRuntime and using
extractImagePrompt/createAiSdkProviderContext) to pass normalizedModelConfig
instead of modelConfig so the emitted trace payloads consistently reflect the
policy-normalized configuration.

---

Nitpick comments:
In `@src/renderer/src/components/settings/ModelConfigDialog.vue`:
- Around line 933-952: buildCustomModelPayload currently computes
fixedTemperatureKimi via resolveMoonshotKimiTemperaturePolicy then uses it to
set reasoning, which is redundant because the watcher already enforces
config.value.reasoning; remove the fixedTemperatureKimi variable and simplify
the payload to use reasoning: config.value.reasoning ?? false (keep other fields
unchanged) so the watcher remains the single source of truth; leave
resolveMoonshotKimiTemperaturePolicy usage elsewhere if needed but do not
re-resolve here.

In `@src/shared/moonshotKimiPolicy.ts`:
- Around line 33-59: Add a short JSDoc above getMoonshotKimiTemperaturePolicy
explaining that the _providerId parameter is intentionally ignored and the
policy matches purely on model ID across all providers (e.g., proxies like
new-api/OpenRouter) because Moonshot model IDs carry temperature semantics;
mention that this is why the parameter is underscored and warn that if third
parties reuse these model IDs with different semantics the policy may
over-apply.

In `@test/main/presenter/llmProviderPresenter/aiSdkRuntime.test.ts`:
- Around line 257-325: The two Moonshot tests only assert behavior for
'moonshotai/kimi-k2.6' so K2.5 regressions would be missed; parameterize the
tests to run the same assertions for both 'moonshotai/kimi-k2.6' and
'moonshotai/kimi-k2.5' (use test.each or a small loop) and replace the
hard-coded model id in the runAiSdkGenerateText and runAiSdkCoreStream calls
with the parameterized modelId; keep the same expectations against
mockGenerateText, mockStreamText, tracePayloads and events so both model ids are
covered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 623cc1fd-f2b5-4116-a8e3-a33684cd40c6

📥 Commits

Reviewing files that changed from the base of the PR and between 752286f and 5a3735f.

📒 Files selected for processing (37)
  • src/main/presenter/agentRuntimePresenter/index.ts
  • src/main/presenter/configPresenter/modelConfig.ts
  • src/main/presenter/llmProviderPresenter/aiSdk/providerOptionsMapper.ts
  • src/main/presenter/llmProviderPresenter/aiSdk/runtime.ts
  • src/renderer/src/components/chat/ChatStatusBar.vue
  • src/renderer/src/components/settings/ModelConfigDialog.vue
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/da-DK/settings.json
  • src/renderer/src/i18n/en-US/chat.json
  • src/renderer/src/i18n/en-US/settings.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/fa-IR/settings.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/fr-FR/settings.json
  • src/renderer/src/i18n/he-IL/chat.json
  • src/renderer/src/i18n/he-IL/settings.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/ja-JP/settings.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/ko-KR/settings.json
  • src/renderer/src/i18n/pt-BR/chat.json
  • src/renderer/src/i18n/pt-BR/settings.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/ru-RU/settings.json
  • src/renderer/src/i18n/zh-CN/chat.json
  • src/renderer/src/i18n/zh-CN/settings.json
  • src/renderer/src/i18n/zh-HK/chat.json
  • src/renderer/src/i18n/zh-HK/settings.json
  • src/renderer/src/i18n/zh-TW/chat.json
  • src/renderer/src/i18n/zh-TW/settings.json
  • src/shared/moonshotKimiPolicy.ts
  • test/main/presenter/agentRuntimePresenter/agentRuntimePresenter.test.ts
  • test/main/presenter/llmProviderPresenter/aiSdkProviderOptionsMapper.test.ts
  • test/main/presenter/llmProviderPresenter/aiSdkRuntime.test.ts
  • test/main/presenter/providerDbModelConfig.test.ts
  • test/renderer/components/ChatStatusBar.test.ts
  • test/renderer/components/ModelConfigDialog.test.ts

Comment on lines +126 to +136
private applyProviderSpecificPolicies(
providerId: string | undefined,
modelId: string,
config: ModelConfig
): ModelConfig {
if (!providerId) {
return config
}

return applyMoonshotKimiReasoningTemperaturePolicy(providerId, modelId, config)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, find and read the modelConfig.ts file around the specified lines
fd -t f "modelConfig.ts" | head -5

Repository: ThinkInAIXYZ/deepchat

Length of output: 114


🏁 Script executed:

# Check the structure of the codebase
find . -type f -name "*.ts" | grep -E "(modelConfig|moonshotKimi)" | head -10

Repository: ThinkInAIXYZ/deepchat

Length of output: 322


🏁 Script executed:

# Let's get the actual file location
git ls-files | grep -E "modelConfig|moonshotKimi"

Repository: ThinkInAIXYZ/deepchat

Length of output: 310


🏁 Script executed:

# Read the modelConfig.ts file, specifically around lines 126-136
head -150 src/main/presenter/configPresenter/modelConfig.ts | tail -40

Repository: ThinkInAIXYZ/deepchat

Length of output: 1486


🏁 Script executed:

# Also read the moonshotKimiPolicy.ts to understand the policy function
cat -n src/shared/moonshotKimiPolicy.ts

Repository: ThinkInAIXYZ/deepchat

Length of output: 3678


🏁 Script executed:

# Check guideline compliance: verify single quotes, semicolons, and line width in modelConfig.ts
head -150 src/main/presenter/configPresenter/modelConfig.ts | tail -50 | cat -n

Repository: ThinkInAIXYZ/deepchat

Length of output: 2175


🏁 Script executed:

# Let's also check if there are any imports or other context around the method
sed -n '1,30p' src/main/presenter/configPresenter/modelConfig.ts

Repository: ThinkInAIXYZ/deepchat

Length of output: 1042


🏁 Script executed:

# Check the full method signature and surrounding code
sed -n '120,145p' src/main/presenter/configPresenter/modelConfig.ts

Repository: ThinkInAIXYZ/deepchat

Length of output: 1013


🏁 Script executed:

# Check for tests related to this behavior
cat -n test/main/shared/modelConfigDefaults.test.ts | grep -A 10 -B 5 -i moonshot

Repository: ThinkInAIXYZ/deepchat

Length of output: 47


🏁 Script executed:

# Check if there are any other references to this behavior
rg -n "applyMoonshotKimiReasoningTemperaturePolicy" --type ts

Repository: ThinkInAIXYZ/deepchat

Length of output: 705


🏁 Script executed:

# Check line width compliance for the method in question
sed -n '126,136p' src/main/presenter/configPresenter/modelConfig.ts | awk '{print length($0) ": " $0}'

Repository: ThinkInAIXYZ/deepchat

Length of output: 384


🏁 Script executed:

# Check the specific line that calls the function to verify line width
sed -n '135p' src/main/presenter/configPresenter/modelConfig.ts | wc -c

Repository: ThinkInAIXYZ/deepchat

Length of output: 67


🏁 Script executed:

# Let's also verify the behavior described in the review by looking at how configs flow
# Check if ModelConfig has reasoning field and defaults
rg -n "reasoning" src/shared/presenter.ts | head -20

Repository: ThinkInAIXYZ/deepchat

Length of output: 128


🏁 Script executed:

# Check test files for any tests of this policy behavior
cat test/main/presenter/modelConfig.test.ts 2>/dev/null || echo "File not found"

Repository: ThinkInAIXYZ/deepchat

Length of output: 23379


🏁 Script executed:

# Look for any Kimi-related tests
find test -name "*.test.ts" -type f -exec grep -l "kimi\|Kimi\|moonshot\|Moonshot" {} \;

Repository: ThinkInAIXYZ/deepchat

Length of output: 889


🏁 Script executed:

# Check for any documentation or comments about Kimi defaults in the code
rg -n "thinking.*default\|default.*thinking" --type ts -i src/

Repository: ThinkInAIXYZ/deepchat

Length of output: 47


🏁 Script executed:

# Check the actual behavior when reasoning is undefined in applyMoonshotKimiReasoningTemperaturePolicy
sed -n '61,81p' src/shared/moonshotKimiPolicy.ts

Repository: ThinkInAIXYZ/deepchat

Length of output: 714


🏁 Script executed:

# Look at the parameter type to confirm reasoning can be undefined
sed -n '83,102p' src/shared/moonshotKimiPolicy.ts

Repository: ThinkInAIXYZ/deepchat

Length of output: 539


🏁 Script executed:

# Check if there are any existing Kimi model configs in defaults
rg -n "kimi\|k2\." --type ts src/shared/modelConfigDefaults.ts -i

Repository: ThinkInAIXYZ/deepchat

Length of output: 47


🏁 Script executed:

# Final verification: check if there are any existing tests that cover this Kimi behavior
grep -n "reasoning.*undefined\|kimi.*undefined" test/main/shared/modelConfigDefaults.test.ts 2>/dev/null || echo "No specific tests found"

Repository: ThinkInAIXYZ/deepchat

Length of output: 88


🏁 Script executed:

# Check if there are any other callers of this function that might be affected
rg "applyMoonshotKimiReasoningTemperaturePolicy\|resolveMoonshotKimiTemperaturePolicy" --type ts -B 3 -A 3 | head -40

Repository: ThinkInAIXYZ/deepchat

Length of output: 47


Preserve Kimi's default thinking mode when reasoning is omitted.

applyMoonshotKimiReasoningTemperaturePolicy treats reasoning: undefined as disabled, so legacy or partial Kimi configs get rewritten to reasoning: false and temperature: 0.6. Kimi's K2.6 docs say thinking defaults to enabled, so omitted reasoning should resolve to enabled, not disabled. Source: Kimi K2.6 parameter notes.

🐛 Proposed local fix
-import { applyMoonshotKimiReasoningTemperaturePolicy } from '@shared/moonshotKimiPolicy'
+import { resolveMoonshotKimiTemperaturePolicy } from '@shared/moonshotKimiPolicy'
@@
   private applyProviderSpecificPolicies(
     providerId: string | undefined,
     modelId: string,
     config: ModelConfig
   ): ModelConfig {
     if (!providerId) {
       return config
     }
 
-    return applyMoonshotKimiReasoningTemperaturePolicy(providerId, modelId, config)
+    const resolved = resolveMoonshotKimiTemperaturePolicy(
+      providerId,
+      modelId,
+      config.reasoning ?? true
+    )
+    if (!resolved) {
+      return config
+    }
+
+    return {
+      ...config,
+      reasoning: resolved.reasoningEnabled,
+      temperature: resolved.temperature
+    }
   }

Alternatively, centralize this in src/shared/moonshotKimiPolicy.ts so all callers inherit the same defaulting behavior.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/presenter/configPresenter/modelConfig.ts` around lines 126 - 136,
The current flow in applyProviderSpecificPolicies returns
applyMoonshotKimiReasoningTemperaturePolicy(providerId, modelId, config) which
treats reasoning: undefined as disabled; update the logic so Kimi configs
preserve the default "thinking enabled" behavior: if the providerId indicates
Kimi (or in applyMoonshotKimiReasoningTemperaturePolicy itself) and
config.reasoning === undefined, set reasoning to true on the ModelConfig before
applying temperature defaults (or modify
applyMoonshotKimiReasoningTemperaturePolicy to implicitly treat undefined as
true), ensuring callers like applyProviderSpecificPolicies and any other
consumers get the correct default; alternatively consolidate the defaulting in
src/shared/moonshotKimiPolicy.ts so all callers inherit the same behavior.

Comment on lines +131 to +141
const fixedTemperatureKimi = resolveMoonshotKimiTemperaturePolicy(
params.providerId,
params.modelId,
params.modelConfig.reasoning
)
const reasoningEnabled =
fixedTemperatureKimi?.reasoningEnabled ??
getReasoningEffectiveEnabledForProvider(params.capabilityProviderId, reasoningPortrait, {
reasoning: params.modelConfig.reasoning,
reasoningEffort: params.modelConfig.reasoningEffort
}
)
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find the resolveMoonshotKimiTemperaturePolicy function
rg "resolveMoonshotKimiTemperaturePolicy" -A 20 -B 2

Repository: ThinkInAIXYZ/deepchat

Length of output: 28806


🏁 Script executed:

# Look at the specific file and lines mentioned
cat -n src/main/presenter/llmProviderPresenter/aiSdk/providerOptionsMapper.ts | sed -n '125,150p'

Repository: ThinkInAIXYZ/deepchat

Length of output: 1262


🏁 Script executed:

# Find where thinking type is mapped
rg "thinking.*type" -B 5 -A 5 src/main/presenter/llmProviderPresenter/aiSdk/

Repository: ThinkInAIXYZ/deepchat

Length of output: 47


🏁 Script executed:

# Check for Kimi-related code in shared directory
fd "kimi\|moonshot" src/shared/ --type f

Repository: ThinkInAIXYZ/deepchat

Length of output: 47


🏁 Script executed:

# Search for the moonshotKimiPolicy file
find . -name "*moonshotKimiPolicy*" -o -name "*kimi*" | grep -v node_modules

Repository: ThinkInAIXYZ/deepchat

Length of output: 285


🏁 Script executed:

# Find the getMoonshotKimiTemperaturePolicy function
rg "getMoonshotKimiTemperaturePolicy" -A 30 src/shared/moonshotKimiPolicy.ts

Repository: ThinkInAIXYZ/deepchat

Length of output: 1812


🏁 Script executed:

# Look for the full moonshotKimiPolicy file to understand the policy structure
cat -n src/shared/moonshotKimiPolicy.ts | head -100

Repository: ThinkInAIXYZ/deepchat

Length of output: 3613


🏁 Script executed:

# Verify if params.modelConfig.reasoning can actually be undefined
# by checking ModelConfig type definition
rg "type ModelConfig" -A 20 src/shared/presenter.ts

Repository: ThinkInAIXYZ/deepchat

Length of output: 128


🏁 Script executed:

# Check how thinking type is actually sent to the API in provider options
rg "thinking.*type.*disabled\|thinking.*type.*enabled" -B 5 -A 5 src/main/presenter/llmProviderPresenter/aiSdk/providerOptionsMapper.ts

Repository: ThinkInAIXYZ/deepchat

Length of output: 47


🏁 Script executed:

# Search for where thinking type is used in the mapped options
rg "thinkingType" -B 3 -A 3 src/main/presenter/llmProviderPresenter/aiSdk/

Repository: ThinkInAIXYZ/deepchat

Length of output: 790


🏁 Script executed:

# Check the actual lines where thinking config is set in providerOptionsMapper.ts
cat -n src/main/presenter/llmProviderPresenter/aiSdk/providerOptionsMapper.ts | sed -n '170,190p'

Repository: ThinkInAIXYZ/deepchat

Length of output: 891


🏁 Script executed:

# Find ModelConfig type definition
fd "ModelConfig" --type f | xargs rg "type ModelConfig\|interface ModelConfig" -A 15 | head -100

Repository: ThinkInAIXYZ/deepchat

Length of output: 47


🏁 Script executed:

# Verify how reasoningEnabled is used in the mapping context
cat -n src/main/presenter/llmProviderPresenter/aiSdk/providerOptionsMapper.ts | sed -n '131,200p'

Repository: ThinkInAIXYZ/deepchat

Length of output: 3074


🏁 Script executed:

# Check ModelConfig type definition more thoroughly
rg "reasoning" src/shared/types/ -B 2 -A 2 | head -60

Repository: ThinkInAIXYZ/deepchat

Length of output: 3501


🏁 Script executed:

# Look for tests or usage of resolveMoonshotKimiTemperaturePolicy with undefined reasoning
rg "resolveMoonshotKimiTemperaturePolicy" -B 3 -A 3 | grep -A 3 -B 3 "undefined\|reasoning"

Repository: ThinkInAIXYZ/deepchat

Length of output: 4935


Base Kimi models silently default thinking to disabled when reasoning config is omitted.

For K2.5/K2.6 base models (without :thinking suffix), when params.modelConfig.reasoning is undefined, resolveMoonshotKimiTemperaturePolicy sets thinkingType: 'disabled', which sends thinking: { type: 'disabled' } to the API. Since modelConfig.reasoning is an optional field, legacy configurations or direct mapper callers without explicit reasoning will change to thinking-disabled behavior, contradicting Kimi's documented default.

Suggested fix
   const fixedTemperatureKimi = resolveMoonshotKimiTemperaturePolicy(
     params.providerId,
     params.modelId,
-    params.modelConfig.reasoning
+    params.modelConfig.reasoning ?? true
   )

Alternatively, move the default into src/shared/moonshotKimiPolicy.ts to centralize the policy logic.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const fixedTemperatureKimi = resolveMoonshotKimiTemperaturePolicy(
params.providerId,
params.modelId,
params.modelConfig.reasoning
)
const reasoningEnabled =
fixedTemperatureKimi?.reasoningEnabled ??
getReasoningEffectiveEnabledForProvider(params.capabilityProviderId, reasoningPortrait, {
reasoning: params.modelConfig.reasoning,
reasoningEffort: params.modelConfig.reasoningEffort
}
)
})
const fixedTemperatureKimi = resolveMoonshotKimiTemperaturePolicy(
params.providerId,
params.modelId,
params.modelConfig.reasoning ?? true
)
const reasoningEnabled =
fixedTemperatureKimi?.reasoningEnabled ??
getReasoningEffectiveEnabledForProvider(params.capabilityProviderId, reasoningPortrait, {
reasoning: params.modelConfig.reasoning,
reasoningEffort: params.modelConfig.reasoningEffort
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/presenter/llmProviderPresenter/aiSdk/providerOptionsMapper.ts`
around lines 131 - 141, The current call to resolveMoonshotKimiTemperaturePolicy
with params.modelConfig.reasoning causes Kimi base models to default to
thinkingType: 'disabled' when reasoning is undefined; update the logic so that
resolveMoonshotKimiTemperaturePolicy (or moonshotKimiPolicy.ts) does not emit a
thinkingType: 'disabled' when params.modelConfig.reasoning is omitted — instead
leave thinking/thinkingType undefined (or centralize the default behavior in
src/shared/moonshotKimiPolicy.ts) so that
getReasoningEffectiveEnabledForProvider can apply the intended default; adjust
resolveMoonshotKimiTemperaturePolicy and/or the policy module to only set
disabled when reasoning was explicitly provided.

@zerob13 zerob13 merged commit 6eefbfa into dev Apr 22, 2026
3 checks passed
@zhangmo8 zhangmo8 deleted the feat/kimi-fixed-temperature-compat branch April 24, 2026 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants