Roo-Code/src/api/providers/moonshot.ts
roomote[bot] 0e5407aa76
fix: make defaultTemperature required in getModelParams to prevent silent temperature overrides (#11218)
* fix: DeepSeek temperature defaulting to 0 instead of 0.3

Pass defaultTemperature: DEEP_SEEK_DEFAULT_TEMPERATURE to getModelParams() in
DeepSeekHandler.getModel() to ensure the correct default temperature (0.3)
is used when no user configuration is provided.

Closes #11194

* refactor: make defaultTemperature required in getModelParams

Make the defaultTemperature parameter required in getModelParams() instead
of defaulting to 0. This prevents providers with their own non-zero default
temperature (like DeepSeek's 0.3) from being silently overridden by the
implicit 0 default.

Every provider now explicitly declares its temperature default, making the
temperature resolution chain clear:
  user setting → model default → provider default

---------

Co-authored-by: Roo Code <roomote@roocode.com>
Co-authored-by: daniel-lxs <ricciodaniel98@gmail.com>
2026-02-06 18:38:31 -05:00

76 lines
2.5 KiB
TypeScript

import { moonshotModels, moonshotDefaultModelId, type ModelInfo } from "@roo-code/types"
import type { ApiHandlerOptions } from "../../shared/api"
import type { ApiStreamUsageChunk } from "../transform/stream"
import { getModelParams } from "../transform/model-params"
import { OpenAICompatibleHandler, OpenAICompatibleConfig } from "./openai-compatible"
export class MoonshotHandler extends OpenAICompatibleHandler {
constructor(options: ApiHandlerOptions) {
const modelId = options.apiModelId ?? moonshotDefaultModelId
const modelInfo =
moonshotModels[modelId as keyof typeof moonshotModels] || moonshotModels[moonshotDefaultModelId]
const config: OpenAICompatibleConfig = {
providerName: "moonshot",
baseURL: options.moonshotBaseUrl || "https://api.moonshot.ai/v1",
apiKey: options.moonshotApiKey ?? "not-provided",
modelId,
modelInfo,
modelMaxTokens: options.modelMaxTokens ?? undefined,
temperature: options.modelTemperature ?? undefined,
}
super(options, config)
}
override getModel() {
const id = this.options.apiModelId ?? moonshotDefaultModelId
const info = moonshotModels[id as keyof typeof moonshotModels] || moonshotModels[moonshotDefaultModelId]
const params = getModelParams({
format: "openai",
modelId: id,
model: info,
settings: this.options,
defaultTemperature: 0,
})
return { id, info, ...params }
}
/**
* Override to handle Moonshot's usage metrics, including caching.
* Moonshot returns cached_tokens in a different location than standard OpenAI.
*/
protected override processUsageMetrics(usage: {
inputTokens?: number
outputTokens?: number
details?: {
cachedInputTokens?: number
reasoningTokens?: number
}
raw?: Record<string, unknown>
}): ApiStreamUsageChunk {
// Moonshot uses cached_tokens at the top level of raw usage data
const rawUsage = usage.raw as { cached_tokens?: number } | undefined
return {
type: "usage",
inputTokens: usage.inputTokens || 0,
outputTokens: usage.outputTokens || 0,
cacheWriteTokens: 0,
cacheReadTokens: rawUsage?.cached_tokens ?? usage.details?.cachedInputTokens,
}
}
/**
* Override to always include max_tokens for Moonshot (not max_completion_tokens).
* Moonshot requires max_tokens parameter to be sent.
*/
protected override getMaxOutputTokens(): number | undefined {
const modelInfo = this.config.modelInfo
// Moonshot always requires max_tokens
return this.options.modelMaxTokens || modelInfo.maxTokens || undefined
}
}