fix(xai): enforce positive integer for xaiModelContextWindow and handle undefined cacheWritesPrice

This commit is contained in:
Hannes Rudolph 2025-10-30 13:38:38 -06:00
parent a981925065
commit d6e594eeda
5 changed files with 9 additions and 8 deletions

View file

@ -353,7 +353,7 @@ const fakeAiSchema = baseProviderSettingsSchema.extend({
const xaiSchema = apiModelIdProviderModelSchema.extend({
xaiApiKey: z.string().optional(),
xaiModelContextWindow: z.number().optional(),
xaiModelContextWindow: z.number().int().min(1).optional(),
})
const groqSchema = apiModelIdProviderModelSchema.extend({

View file

@ -77,7 +77,7 @@ export async function getXaiModels(apiKey?: string, baseUrl?: string): Promise<R
inputPrice: centsToDollars(m.prompt_text_token_price),
outputPrice: centsToDollars(m.completion_text_token_price),
cacheReadsPrice,
cacheWritesPrice: cacheReadsPrice, // xAI uses same price for reads and writes
cacheWritesPrice: undefined, // Leave undefined unless API exposes a distinct write price
description: staticInfo?.description,
supportsReasoningEffort:
staticInfo && "supportsReasoningEffort" in staticInfo

View file

@ -89,7 +89,7 @@ export class XAIHandler extends BaseProvider implements SingleCompletionHandler
try {
stream = await this.client.chat.completions.create({
model: modelId,
max_tokens: modelInfo.maxTokens,
...(typeof modelInfo.maxTokens === "number" ? { max_tokens: modelInfo.maxTokens } : {}),
temperature: this.options.modelTemperature ?? XAI_DEFAULT_TEMPERATURE,
messages: [{ role: "system", content: systemPrompt }, ...convertToOpenAiMessages(messages)],
stream: true,

View file

@ -166,9 +166,9 @@ export const XAI = ({
<VSCodeTextField
value={apiConfiguration?.xaiModelContextWindow?.toString() || ""}
onInput={handleInputChange("xaiModelContextWindow", (e) => {
const target = e.target as HTMLInputElement
const value = target.value
return value ? parseInt(value, 10) : undefined
const v = (e.target as HTMLInputElement).value.trim()
const n = Number(v)
return Number.isFinite(n) && n > 0 ? Math.floor(n) : undefined
})}
placeholder="e.g., 256000"
className="w-full mt-4">

View file

@ -184,10 +184,11 @@ function getSelectedModel({
const id = apiConfiguration.apiModelId ?? xaiDefaultModelId
const dynamicInfo = routerModels.xai?.[id]
if (dynamicInfo) {
// If router-provided model lacks contextWindow, apply manual override when provided
// If router-provided contextWindow is missing or invalid (<= 0), apply manual override when provided
const overrideCw = apiConfiguration.xaiModelContextWindow
const info =
dynamicInfo.contextWindow === undefined && typeof overrideCw === "number"
!(typeof dynamicInfo.contextWindow === "number" && dynamicInfo.contextWindow > 0) &&
typeof overrideCw === "number"
? { ...dynamicInfo, contextWindow: overrideCw }
: dynamicInfo
return { id, info }