Skip to content

Commit 622bc4a

Browse files
committed
fix(xai): enhance error logging and support dynamic model context window overrides
1 parent 1f52407 commit 622bc4a

File tree

3 files changed

+23
-17
lines changed

3 files changed

+23
-17
lines changed

src/api/providers/fetchers/xai.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,14 @@ export async function getXaiModels(apiKey?: string, baseUrl?: string): Promise<R
9090
// Users should use the primary model ID; xAI API will handle alias resolution
9191
}
9292
} catch (error) {
93-
try {
94-
const err = JSON.stringify(error, Object.getOwnPropertyNames(error), 2)
95-
console.error(`[xAI] models fetch failed: ${err}`)
96-
} catch {
97-
console.error("[xAI] models fetch failed.")
93+
// Avoid logging sensitive data like Authorization headers
94+
if (axios.isAxiosError(error)) {
95+
const status = error.response?.status
96+
const statusText = error.response?.statusText
97+
const url = (error as any)?.config?.url
98+
console.error(`[xAI] models fetch failed: ${status ?? "unknown"} ${statusText ?? ""} ${url ?? ""}`.trim())
99+
} else {
100+
console.error("[xAI] models fetch failed.", error instanceof Error ? error.message : String(error))
98101
}
99102
throw error
100103
}

src/api/providers/xai.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,19 @@ export class XAIHandler extends BaseProvider implements SingleCompletionHandler
3535
}
3636

3737
override getModel() {
38-
const id =
39-
this.options.apiModelId && this.options.apiModelId in xaiModels
40-
? (this.options.apiModelId as XAIModelId)
41-
: xaiDefaultModelId
38+
// Allow any model ID (dynamic discovery) and augment with static info when available
39+
const id = this.options.apiModelId ?? xaiDefaultModelId
4240

43-
const staticInfo = xaiModels[id]
41+
const staticInfo = (xaiModels as Record<string, any>)[id as any]
4442

45-
// Build complete ModelInfo with all required fields
46-
// Dynamic data (pricing, cache support) will come from router models, this is just for type safety
43+
// Build complete ModelInfo with required fields; dynamic data comes from router models
4744
const info: ModelInfo = {
48-
contextWindow: this.options.xaiModelContextWindow ?? staticInfo.contextWindow,
49-
maxTokens: staticInfo.maxTokens ?? undefined,
45+
contextWindow: this.options.xaiModelContextWindow ?? staticInfo?.contextWindow,
46+
maxTokens: staticInfo?.maxTokens ?? undefined,
5047
supportsPromptCache: false, // Placeholder - actual value comes from dynamic API call
51-
description: staticInfo.description,
48+
description: staticInfo?.description,
5249
supportsReasoningEffort:
53-
"supportsReasoningEffort" in staticInfo ? staticInfo.supportsReasoningEffort : undefined,
50+
staticInfo && "supportsReasoningEffort" in staticInfo ? staticInfo.supportsReasoningEffort : undefined,
5451
}
5552

5653
const params = getModelParams({ format: "openai", modelId: id, model: info, settings: this.options })

webview-ui/src/components/ui/hooks/useSelectedModel.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,13 @@ function getSelectedModel({
166166
const id = apiConfiguration.apiModelId ?? xaiDefaultModelId
167167
const dynamicInfo = routerModels.xai?.[id]
168168
if (dynamicInfo) {
169-
return { id, info: dynamicInfo }
169+
// If router-provided model lacks contextWindow, apply manual override when provided
170+
const overrideCw = apiConfiguration.xaiModelContextWindow
171+
const info =
172+
dynamicInfo.contextWindow === undefined && typeof overrideCw === "number"
173+
? { ...dynamicInfo, contextWindow: overrideCw }
174+
: dynamicInfo
175+
return { id, info }
170176
}
171177
const staticInfo = xaiModels[id as keyof typeof xaiModels]
172178
// Build a complete ModelInfo fallback to satisfy UI expectations until dynamic models load

0 commit comments

Comments
 (0)