Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .changeset/kimi-thinking-off-temperature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
"@moonshot-ai/kosong": patch
"@moonshot-ai/kimi-code": patch
---

fix: set Kimi temperature to 0.6 when thinking is disabled

The Kimi API requires temperature=0.6 when thinking is disabled; without
it, toggling thinking off causes a 400 error with "invalid temperature: only
0.6 is allowed". This fix applies the default only when no explicit
temperature has been configured, preserving user overrides (e.g., via
ProviderConfig or env var).

Fixes #686.
19 changes: 19 additions & 0 deletions packages/kosong/src/providers/kimi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,24 @@ export interface ExtraBody {
thinking?: ThinkingConfig;
[key: string]: unknown;
}

function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === 'object' && value !== null && !Array.isArray(value);
}

/**
* Apply the default temperature=0.6 when thinking is disabled and no explicit
* temperature has been configured. This prevents 400 errors from the Kimi API
* while preserving user overrides (e.g., via ProviderConfig or env var).
*/
function applyDisabledThinkingTemperatureDefault(params: Record<string, unknown>): void {
if (params['temperature'] !== undefined) return;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Override env temperature when disabling thinking

For users who set KIMI_MODEL_TEMPERATURE, this guard preserves that value even after ConfigState.provider applies withThinking(this.thinkingLevel) and then applyKimiEnvSamplingParams reads the env var into temperature. When they toggle Kimi thinking off, the request still sends thinking: { type: 'disabled' } with the non-0.6 env temperature, so it continues to hit the same Moonshot 400 (only 0.6 is allowed) instead of applying the disabled-thinking fix.

Useful? React with 👍 / 👎.

const thinking = params['thinking'];
if (isRecord(thinking) && thinking['type'] === 'disabled') {
params['temperature'] = 0.6;
}
}

const KIMI_TOOL_CALL_ID_POLICY: ToolCallIdPolicy = {
normalize: (id) => sanitizeToolCallId(id, 64),
maxLength: 64,
Expand Down Expand Up @@ -475,6 +493,7 @@ export class KimiChatProvider implements ChatProvider {
...requestKwargs,
...(extraBody as Record<string, unknown> | undefined),
};
applyDisabledThinkingTemperatureDefault(createParams);

if (tools.length > 0) {
createParams['tools'] = tools.map((t) => convertTool(t));
Expand Down
15 changes: 15 additions & 0 deletions packages/kosong/test/kimi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -722,9 +722,24 @@ describe('KimiChatProvider', () => {

expect(body['reasoning_effort']).toBeUndefined();
expect(body['thinking']).toEqual({ type: 'disabled' });
expect(body['temperature']).toBe(0.6);
expect(body['extra_body']).toBeUndefined();
});

it('does not overwrite an explicit temperature when thinking is off', async () => {
const provider = createProvider()
.withGenerationKwargs({ temperature: 0.7 })
.withThinking('off');
const history: Message[] = [
{ role: 'user', content: [{ type: 'text', text: 'Think' }], toolCalls: [] },
];
const body = await captureRequestBody(provider, '', [], history);

expect(body['reasoning_effort']).toBeUndefined();
expect(body['thinking']).toEqual({ type: 'disabled' });
expect(body['temperature']).toBe(0.7);
});

it('thinkingEffort property reflects current state', () => {
const provider = createProvider();
expect(provider.thinkingEffort).toBeNull();
Expand Down
Loading