Skip to content

Commit c0a0dcf

Browse files
committed
feat(xai): add dynamic model discovery with correct pricing
- Implemented dynamic model discovery for xAI provider using /v1/language-models endpoint - Models are now fetched at runtime with real-time pricing and capabilities - Fixed pricing conversion: XAI API returns fractional cents (basis points), divide by 10,000 not 100 - This fixes pricing display showing $20.00 instead of $0.20 per 1M tokens - Removed static xAI models from MODELS_BY_PROVIDER to rely on dynamic discovery - Enhanced error logging with detailed status and URL information - Support dynamic model context window overrides from API - Fixed parseApiPrice to handle zero values correctly (for free models) - Provided complete ModelInfo fallback in useSelectedModel for UI type safety - Added comprehensive test coverage for cost utilities and XAI fetcher - Updated all tests to reflect correct pricing scale and dynamic model behavior
1 parent ed45d1c commit c0a0dcf

File tree

83 files changed

+790
-2941
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+790
-2941
lines changed

.changeset/v3.29.4.md

Lines changed: 0 additions & 10 deletions
This file was deleted.

CHANGELOG.md

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,5 @@
11
# Roo Code Changelog
22

3-
## [3.29.3] - 2025-10-28
4-
5-
- Update Gemini models with latest 09-2025 versions including Gemini 2.5 Pro and Flash (#8485 by @cleacos, PR by @roomote)
6-
- Add reasoning support for Z.ai GLM binary thinking mode (#8465 by @BeWater799, PR by @daniel-lxs)
7-
- Enable reasoning in Roo provider (thanks @mrubens!)
8-
- Add settings to configure time and cost display in system prompt (#8450 by @jaxnb, PR by @roomote)
9-
- Fix: Use max_output_tokens when available in LiteLLM fetcher (#8454 by @fabb, PR by @roomote)
10-
- Fix: Process queued messages after context condensing completes (#8477 by @JosXa, PR by @roomote)
11-
- Fix: Use monotonic clock for rate limiting to prevent timing issues (#7770 by @intermarkec, PR by @chrarnoldus)
12-
- Fix: Resolve checkpoint menu popover overflow (thanks @daniel-lxs!)
13-
- Fix: LiteLLM test failures after merge (thanks @daniel-lxs!)
14-
- Improve UX: Focus textbox and add newlines after adding to context (thanks @mrubens!)
15-
163
## [3.29.2] - 2025-10-27
174

185
- Add support for LongCat-Flash-Thinking-FP8 models in Chutes AI provider (#8425 by @leakless21, PR by @roomote)

apps/web-roo-code/src/app/reviewer/ReviewerContent.tsx

Lines changed: 2 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
11
"use client"
22

3-
import {
4-
ArrowRight,
5-
Blocks,
6-
BookMarked,
7-
ListChecks,
8-
LucideIcon,
9-
GitPullRequest,
10-
Key,
11-
MessageSquareCode,
12-
} from "lucide-react"
3+
import { ArrowRight, Blocks, BookMarked, ListChecks, LucideIcon } from "lucide-react"
134
import Image from "next/image"
145

156
import { Button } from "@/components/ui"
@@ -25,26 +16,6 @@ interface Feature {
2516
logos?: string[]
2617
}
2718

28-
const workflowSteps: Feature[] = [
29-
{
30-
icon: GitPullRequest,
31-
title: "1. Connect Your Repository",
32-
description: "Link your GitHub repository and configure which branches and pull requests should be reviewed.",
33-
},
34-
{
35-
icon: Key,
36-
title: "2. Add Your API Key",
37-
description:
38-
"Provide your AI provider API key and set your review preferences, custom rules, and quality standards.",
39-
},
40-
{
41-
icon: MessageSquareCode,
42-
title: "3. Get Review Comments",
43-
description:
44-
"Every pull request gets detailed GitHub comments in minutes from a Roo Code agent highlighting issues and suggesting improvements.",
45-
},
46-
]
47-
4819
const howItWorks: Feature[] = [
4920
{
5021
icon: Blocks,
@@ -97,7 +68,7 @@ export function ReviewerContent() {
9768
<p>
9869
Roo Code&apos;s PR Reviewer flips the script: you bring your own key and
9970
leverage it to the max – to find real issues, increase code quality and keep
100-
your pull request queue moving.
71+
your PR queue moving.
10172
</p>
10273
</div>
10374
</div>
@@ -138,38 +109,6 @@ export function ReviewerContent() {
138109
</div>
139110
</section>
140111

141-
{/* How It Works Section */}
142-
<section className="relative overflow-hidden border-t border-border py-32">
143-
<div className="container relative z-10 mx-auto px-4 sm:px-6 lg:px-8">
144-
<div className="mx-auto mb-12 md:mb-24 max-w-5xl text-center">
145-
<div>
146-
<h2 className="text-4xl font-bold tracking-tight sm:text-5xl">How It Works</h2>
147-
</div>
148-
</div>
149-
150-
<div className="relative mx-auto md:max-w-[1200px]">
151-
<ul className="grid grid-cols-1 place-items-center gap-6 md:grid-cols-3 lg:gap-8">
152-
{workflowSteps.map((step, index) => {
153-
const Icon = step.icon
154-
return (
155-
<li
156-
key={index}
157-
className="relative h-full border border-border rounded-2xl bg-background p-8 transition-all duration-300 hover:shadow-lg">
158-
<Icon className="size-6 text-foreground/80" />
159-
<h3 className="mb-3 mt-3 text-xl font-semibold text-foreground">
160-
{step.title}
161-
</h3>
162-
<div className="leading-relaxed font-light text-muted-foreground">
163-
{step.description}
164-
</div>
165-
</li>
166-
)
167-
})}
168-
</ul>
169-
</div>
170-
</div>
171-
</section>
172-
173112
<section className="relative overflow-hidden border-t border-border py-32">
174113
<div className="container relative z-10 mx-auto px-4 sm:px-6 lg:px-8">
175114
<div className="mx-auto mb-12 md:mb-24 max-w-5xl text-center">

packages/types/src/global-settings.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -93,17 +93,6 @@ export const globalSettingsSchema = z.object({
9393
autoCondenseContextPercent: z.number().optional(),
9494
maxConcurrentFileReads: z.number().optional(),
9595

96-
/**
97-
* Whether to include current time in the environment details
98-
* @default true
99-
*/
100-
includeCurrentTime: z.boolean().optional(),
101-
/**
102-
* Whether to include current cost in the environment details
103-
* @default true
104-
*/
105-
includeCurrentCost: z.boolean().optional(),
106-
10796
/**
10897
* Whether to include diagnostic messages (errors, warnings) in tool outputs
10998
* @default true
@@ -218,7 +207,6 @@ export const SECRET_STATE_KEYS = [
218207
"doubaoApiKey",
219208
"moonshotApiKey",
220209
"mistralApiKey",
221-
"minimaxApiKey",
222210
"unboundApiKey",
223211
"requestyApiKey",
224212
"xaiApiKey",

packages/types/src/model.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,10 @@ export const modelInfoSchema = z.object({
6161
// Capability flag to indicate whether the model supports an output verbosity parameter
6262
supportsVerbosity: z.boolean().optional(),
6363
supportsReasoningBudget: z.boolean().optional(),
64-
// Capability flag to indicate whether the model supports simple on/off binary reasoning
65-
supportsReasoningBinary: z.boolean().optional(),
6664
// Capability flag to indicate whether the model supports temperature parameter
6765
supportsTemperature: z.boolean().optional(),
6866
requiredReasoningBudget: z.boolean().optional(),
6967
supportsReasoningEffort: z.boolean().optional(),
70-
requiredReasoningEffort: z.boolean().optional(),
7168
supportedParameters: z.array(modelParametersSchema).optional(),
7269
inputPrice: z.number().optional(),
7370
outputPrice: z.number().optional(),

packages/types/src/provider-settings.ts

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ import {
2222
sambaNovaModels,
2323
vertexModels,
2424
vscodeLlmModels,
25-
xaiModels,
2625
internationalZAiModels,
27-
minimaxModels,
2826
} from "./providers/index.js"
2927

3028
/**
@@ -50,6 +48,7 @@ export const dynamicProviders = [
5048
"unbound",
5149
"glama",
5250
"roo",
51+
"xai",
5352
] as const
5453

5554
export type DynamicProvider = (typeof dynamicProviders)[number]
@@ -132,13 +131,11 @@ export const providerNames = [
132131
"groq",
133132
"mistral",
134133
"moonshot",
135-
"minimax",
136134
"openai-native",
137135
"qwen-code",
138136
"roo",
139137
"sambanova",
140138
"vertex",
141-
"xai",
142139
"zai",
143140
] as const
144141

@@ -329,13 +326,6 @@ const moonshotSchema = apiModelIdProviderModelSchema.extend({
329326
moonshotApiKey: z.string().optional(),
330327
})
331328

332-
const minimaxSchema = apiModelIdProviderModelSchema.extend({
333-
minimaxBaseUrl: z
334-
.union([z.literal("https://api.minimax.io/v1"), z.literal("https://api.minimaxi.com/v1")])
335-
.optional(),
336-
minimaxApiKey: z.string().optional(),
337-
})
338-
339329
const unboundSchema = baseProviderSettingsSchema.extend({
340330
unboundApiKey: z.string().optional(),
341331
unboundModelId: z.string().optional(),
@@ -355,6 +345,7 @@ const fakeAiSchema = baseProviderSettingsSchema.extend({
355345

356346
const xaiSchema = apiModelIdProviderModelSchema.extend({
357347
xaiApiKey: z.string().optional(),
348+
xaiModelContextWindow: z.number().optional(),
358349
})
359350

360351
const groqSchema = apiModelIdProviderModelSchema.extend({
@@ -444,7 +435,6 @@ export const providerSettingsSchemaDiscriminated = z.discriminatedUnion("apiProv
444435
deepInfraSchema.merge(z.object({ apiProvider: z.literal("deepinfra") })),
445436
doubaoSchema.merge(z.object({ apiProvider: z.literal("doubao") })),
446437
moonshotSchema.merge(z.object({ apiProvider: z.literal("moonshot") })),
447-
minimaxSchema.merge(z.object({ apiProvider: z.literal("minimax") })),
448438
unboundSchema.merge(z.object({ apiProvider: z.literal("unbound") })),
449439
requestySchema.merge(z.object({ apiProvider: z.literal("requesty") })),
450440
humanRelaySchema.merge(z.object({ apiProvider: z.literal("human-relay") })),
@@ -486,7 +476,6 @@ export const providerSettingsSchema = z.object({
486476
...deepInfraSchema.shape,
487477
...doubaoSchema.shape,
488478
...moonshotSchema.shape,
489-
...minimaxSchema.shape,
490479
...unboundSchema.shape,
491480
...requestySchema.shape,
492481
...humanRelaySchema.shape,
@@ -571,7 +560,6 @@ export const modelIdKeysByProvider: Record<TypicalProvider, ModelIdKey> = {
571560
"gemini-cli": "apiModelId",
572561
mistral: "apiModelId",
573562
moonshot: "apiModelId",
574-
minimax: "apiModelId",
575563
deepseek: "apiModelId",
576564
deepinfra: "deepInfraModelId",
577565
doubao: "apiModelId",
@@ -688,11 +676,6 @@ export const MODELS_BY_PROVIDER: Record<
688676
label: "Moonshot",
689677
models: Object.keys(moonshotModels),
690678
},
691-
minimax: {
692-
id: "minimax",
693-
label: "MiniMax",
694-
models: Object.keys(minimaxModels),
695-
},
696679
"openai-native": {
697680
id: "openai-native",
698681
label: "OpenAI",
@@ -715,7 +698,7 @@ export const MODELS_BY_PROVIDER: Record<
715698
label: "VS Code LM API",
716699
models: Object.keys(vscodeLlmModels),
717700
},
718-
xai: { id: "xai", label: "xAI (Grok)", models: Object.keys(xaiModels) },
701+
xai: { id: "xai", label: "xAI (Grok)", models: [] },
719702
zai: { id: "zai", label: "Zai", models: Object.keys(internationalZAiModels) },
720703

721704
// Dynamic providers; models pulled from remote APIs.

packages/types/src/providers/cerebras.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,9 @@ import type { ModelInfo } from "../model.js"
33
// https://inference-docs.cerebras.ai/api-reference/chat-completions
44
export type CerebrasModelId = keyof typeof cerebrasModels
55

6-
export const cerebrasDefaultModelId: CerebrasModelId = "gpt-oss-120b"
6+
export const cerebrasDefaultModelId: CerebrasModelId = "qwen-3-coder-480b-free"
77

88
export const cerebrasModels = {
9-
"zai-glm-4.6": {
10-
maxTokens: 16_384,
11-
contextWindow: 128000,
12-
supportsImages: false,
13-
supportsPromptCache: false,
14-
inputPrice: 0,
15-
outputPrice: 0,
16-
description: "Highly intelligent general-purpose model with ~2000 tokens/s",
17-
},
189
"qwen-3-coder-480b-free": {
1910
maxTokens: 40000,
2011
contextWindow: 64000,
@@ -23,7 +14,7 @@ export const cerebrasModels = {
2314
inputPrice: 0,
2415
outputPrice: 0,
2516
description:
26-
"[SOON TO BE DEPRECATED] SOTA coding model with ~2000 tokens/s ($0 free tier)\n\n• Use this if you don't have a Cerebras subscription\n• 64K context window\n• Rate limits: 150K TPM, 1M TPH/TPD, 10 RPM, 100 RPH/RPD\n\nUpgrade for higher limits: [https://cloud.cerebras.ai/?utm=roocode](https://cloud.cerebras.ai/?utm=roocode)",
17+
"SOTA coding model with ~2000 tokens/s ($0 free tier)\n\n• Use this if you don't have a Cerebras subscription\n• 64K context window\n• Rate limits: 150K TPM, 1M TPH/TPD, 10 RPM, 100 RPH/RPD\n\nUpgrade for higher limits: [https://cloud.cerebras.ai/?utm=roocode](https://cloud.cerebras.ai/?utm=roocode)",
2718
},
2819
"qwen-3-coder-480b": {
2920
maxTokens: 40000,
@@ -33,7 +24,7 @@ export const cerebrasModels = {
3324
inputPrice: 0,
3425
outputPrice: 0,
3526
description:
36-
"[SOON TO BE DEPRECATED] SOTA coding model with ~2000 tokens/s ($50/$250 paid tiers)\n\n• Use this if you have a Cerebras subscription\n• 131K context window with higher rate limits",
27+
"SOTA coding model with ~2000 tokens/s ($50/$250 paid tiers)\n\n• Use this if you have a Cerebras subscription\n• 131K context window with higher rate limits",
3728
},
3829
"qwen-3-235b-a22b-instruct-2507": {
3930
maxTokens: 64000,

0 commit comments

Comments
 (0)