Skip to content

Commit aa3187e

Browse files
committed
feat(fireworks): catalog DeepSeek V4 Pro, MiniMax M3, GLM-5.1, GPT-OSS 120B reasoning models
Add four Fireworks serverless reasoning models to the bundled catalog, each with reasoning_effort compat (supported efforts + level map) verified against the live Fireworks API. Thinking menus are derived from each row's supportedReasoningEfforts, so /think only offers levels the deployment accepts. DeepSeek V4 Pro carries thinkingFormat:"openai" to opt out of core's deepseek-native fallback: Fireworks 400s when a request sends `thinking` alongside `reasoning_effort`. GPT-OSS 120B is the first bundled profile with no off level (the API rejects reasoning_effort:"none"). The core thinking-clamp fix it relies on ships separately on fix/thinking-clamp-below-range so this stays plugin-only. Model ids, context windows, reasoning_effort ranges, and pricing verified against the live Fireworks API (/v1/models, /v1/chat/completions) and docs.fireworks.ai/serverless/pricing.
1 parent da92615 commit aa3187e

5 files changed

Lines changed: 268 additions & 23 deletions

File tree

docs/providers/fireworks.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ read_when:
77
- You are debugging Kimi thinking-off behavior on Fireworks
88
---
99

10-
[Fireworks](https://fireworks.ai) exposes open-weight and routed models through an OpenAI-compatible API. OpenClaw includes a bundled Fireworks provider plugin that ships with two pre-cataloged Kimi models and accepts any Fireworks model or router id at runtime.
10+
[Fireworks](https://fireworks.ai) exposes open-weight and routed models through an OpenAI-compatible API. OpenClaw includes a bundled Fireworks provider plugin that ships with pre-cataloged Kimi, DeepSeek, MiniMax, GLM, and GPT-OSS models and accepts any Fireworks model or router id at runtime.
1111

1212
| Property | Value |
1313
| --------------- | ------------------------------------------------------ |
@@ -51,7 +51,7 @@ export FIREWORKS_API_KEY=fw-...
5151
openclaw models list --provider fireworks
5252
```
5353

54-
The list should include `Kimi K2.6` and `Kimi K2.5 Turbo (Fire Pass)`. If `FIREWORKS_API_KEY` is unresolved, `openclaw models status --json` reports the missing credential under `auth.unusableProfiles`.
54+
The list should include `Kimi K2.6`, `Kimi K2.5 Turbo (Fire Pass)`, `DeepSeek V4 Pro`, `MiniMax M3`, `GLM-5.1`, and `GPT-OSS 120B`. If `FIREWORKS_API_KEY` is unresolved, `openclaw models status --json` reports the missing credential under `auth.unusableProfiles`.
5555

5656
</Step>
5757
</Steps>
@@ -71,18 +71,22 @@ openclaw onboard --non-interactive \
7171

7272
## Built-in catalog
7373

74-
| Model ref | Name | Input | Context | Max output | Thinking |
75-
| ------------------------------------------------------ | --------------------------- | ------------ | ------- | ---------- | -------------------- |
76-
| `fireworks/accounts/fireworks/models/kimi-k2p6` | Kimi K2.6 | text + image | 262,144 | 262,144 | Forced off |
77-
| `fireworks/accounts/fireworks/routers/kimi-k2p5-turbo` | Kimi K2.5 Turbo (Fire Pass) | text + image | 256,000 | 256,000 | Forced off (default) |
74+
| Model ref | Name | Input | Context | Max output | Thinking |
75+
| ------------------------------------------------------ | --------------------------- | ------------ | --------- | ---------- | ----------------------------- |
76+
| `fireworks/accounts/fireworks/models/kimi-k2p6` | Kimi K2.6 | text + image | 262,144 | 262,144 | Forced off |
77+
| `fireworks/accounts/fireworks/routers/kimi-k2p5-turbo` | Kimi K2.5 Turbo (Fire Pass) | text + image | 256,000 | 256,000 | Forced off (default) |
78+
| `fireworks/accounts/fireworks/models/deepseek-v4-pro` | DeepSeek V4 Pro | text | 1,048,576 | 1,048,576 | off/low/medium/high/xhigh/max |
79+
| `fireworks/accounts/fireworks/models/minimax-m3` | MiniMax M3 | text + image | 524,288 | 64,000 | off/low/medium/high |
80+
| `fireworks/accounts/fireworks/models/glm-5p1` | GLM-5.1 | text | 202,752 | 202,752 | off/low/medium/high |
81+
| `fireworks/accounts/fireworks/models/gpt-oss-120b` | GPT-OSS 120B | text | 131,072 | 131,072 | low/medium/high |
7882

7983
<Note>
8084
OpenClaw pins all Fireworks Kimi models to `thinking: off` because Fireworks rejects Kimi thinking parameters in production. Routing the same model through [Moonshot](/providers/moonshot) directly preserves Kimi reasoning output. See [thinking modes](/tools/thinking) for switching between providers.
8185
</Note>
8286

8387
## Custom Fireworks model ids
8488

85-
OpenClaw accepts any Fireworks model or router id at runtime. Use the exact id shown by Fireworks and prefix it with `fireworks/`. Dynamic resolution clones the Fire Pass template (text + image input, OpenAI-compatible API, default cost zero) and disables thinking automatically when the id matches the Kimi pattern. GLM dynamic ids are marked text-only unless you configure a custom model entry with image input.
89+
OpenClaw accepts any Fireworks model or router id at runtime. Use the exact id shown by Fireworks and prefix it with `fireworks/`. Dynamic resolution clones the Fire Pass template (text + image input, OpenAI-compatible API, default cost zero) and disables thinking automatically when the id matches the Kimi pattern. GLM dynamic ids are marked text-only unless you configure a custom model entry with image input. The cataloged reasoning models above (DeepSeek V4 Pro, MiniMax M3, GLM-5.1, GPT-OSS 120B) carry their per-model `reasoning_effort` contract in the manifest, and their `/think` menus are derived from each model's `supportedReasoningEfforts`; configure those exact ids to get those menus.
8690

8791
```json5
8892
{
@@ -108,7 +112,7 @@ OpenClaw accepts any Fireworks model or router id at runtime. Use the exact id s
108112
</Accordion>
109113

110114
<Accordion title="Why thinking is forced off for Kimi">
111-
Fireworks K2.6 returns a 400 if the request carries `reasoning_*` parameters even though Kimi supports thinking through Moonshot's own API. The bundled policy (`extensions/fireworks/thinking-policy.ts`) advertises only the `off` thinking level for Kimi model ids, so manual `/think` switches and provider-policy surfaces stay aligned with the runtime contract.
115+
Fireworks K2.6 returns a 400 if the request carries `reasoning_*` parameters even though Kimi supports thinking through Moonshot's own API. The Kimi catalog rows are marked `reasoning: false` in the manifest, so OpenClaw advertises only the `off` thinking level for them, and the bundled stream wrapper (`extensions/fireworks/stream.ts`) strips any thinking parameters from the request — manual `/think` switches and provider-policy surfaces stay aligned with the runtime contract.
112116

113117
To use Kimi reasoning end-to-end, configure the [Moonshot provider](/providers/moonshot) and route the same model through it.
114118

extensions/fireworks/index.test.ts

Lines changed: 110 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,16 @@ import {
1212
import fireworksPlugin from "./index.js";
1313
import {
1414
FIREWORKS_BASE_URL,
15+
FIREWORKS_DEEPSEEK_V4_MODEL_ID,
1516
FIREWORKS_DEFAULT_CONTEXT_WINDOW,
1617
FIREWORKS_DEFAULT_MAX_TOKENS,
1718
FIREWORKS_DEFAULT_MODEL_ID,
19+
FIREWORKS_GLM_5_1_MODEL_ID,
20+
FIREWORKS_GPT_OSS_120B_MODEL_ID,
1821
FIREWORKS_K2_6_CONTEXT_WINDOW,
1922
FIREWORKS_K2_6_MAX_TOKENS,
2023
FIREWORKS_K2_6_MODEL_ID,
24+
FIREWORKS_MINIMAX_M3_MODEL_ID,
2125
} from "./provider-catalog.js";
2226
import { resolveThinkingProfile } from "./provider-policy-api.js";
2327

@@ -69,6 +73,10 @@ describe("fireworks provider plugin", () => {
6973
expect(models.map((model) => model.id)).toEqual([
7074
FIREWORKS_K2_6_MODEL_ID,
7175
FIREWORKS_DEFAULT_MODEL_ID,
76+
FIREWORKS_DEEPSEEK_V4_MODEL_ID,
77+
FIREWORKS_MINIMAX_M3_MODEL_ID,
78+
FIREWORKS_GLM_5_1_MODEL_ID,
79+
FIREWORKS_GPT_OSS_120B_MODEL_ID,
7280
]);
7381
expect(models[0]?.reasoning).toBe(false);
7482
expect(models[0]?.input).toEqual(["text", "image"]);
@@ -80,6 +88,51 @@ describe("fireworks provider plugin", () => {
8088
expect(models[1]?.maxTokens).toBe(FIREWORKS_DEFAULT_MAX_TOKENS);
8189
});
8290

91+
it("catalogs reasoning families with reasoning_effort compat from the manifest", async () => {
92+
const provider = await registerSingleProviderPlugin(fireworksPlugin);
93+
const catalogProvider = await runSingleProviderCatalog(provider);
94+
const byId = new Map(catalogProvider.models?.map((model) => [model.id, model]) ?? []);
95+
96+
const deepseek = byId.get(FIREWORKS_DEEPSEEK_V4_MODEL_ID);
97+
expect(deepseek?.reasoning).toBe(true);
98+
// thinkingFormat "openai" opts out of core's deepseek-native fallback for
99+
// deepseek-v4-* ids; Fireworks 400s on payloads carrying `thinking` next to
100+
// `reasoning_effort`.
101+
expect(deepseek?.compat).toMatchObject({
102+
thinkingFormat: "openai",
103+
supportsReasoningEffort: true,
104+
supportedReasoningEfforts: ["none", "low", "medium", "high", "xhigh", "max"],
105+
reasoningEffortMap: { off: "none", max: "max" },
106+
});
107+
108+
const minimax = byId.get(FIREWORKS_MINIMAX_M3_MODEL_ID);
109+
expect(minimax?.reasoning).toBe(true);
110+
expect(minimax?.input).toEqual(["text", "image"]);
111+
expect(minimax?.compat).toMatchObject({
112+
supportsReasoningEffort: true,
113+
supportedReasoningEfforts: ["none", "low", "medium", "high"],
114+
reasoningEffortMap: { off: "none", max: "high" },
115+
});
116+
117+
const glm = byId.get(FIREWORKS_GLM_5_1_MODEL_ID);
118+
expect(glm?.reasoning).toBe(true);
119+
expect(glm?.compat).toMatchObject({
120+
supportsReasoningEffort: true,
121+
supportedReasoningEfforts: ["none", "low", "medium", "high"],
122+
reasoningEffortMap: { off: "none", max: "high" },
123+
});
124+
125+
const gptOss = byId.get(FIREWORKS_GPT_OSS_120B_MODEL_ID);
126+
expect(gptOss?.reasoning).toBe(true);
127+
expect(gptOss?.compat).toMatchObject({
128+
supportsReasoningEffort: true,
129+
supportedReasoningEfforts: ["low", "medium", "high"],
130+
reasoningEffortMap: { max: "high" },
131+
});
132+
expect(gptOss?.compat?.supportedReasoningEfforts).not.toContain("minimal");
133+
expect(gptOss?.compat?.reasoningEffortMap).not.toHaveProperty("off");
134+
});
135+
83136
it("resolves forward-compat Fireworks model ids from the default template", async () => {
84137
const provider = await registerSingleProviderPlugin(fireworksPlugin);
85138
const resolved = provider.resolveDynamicModel?.(
@@ -119,13 +172,13 @@ describe("fireworks provider plugin", () => {
119172
const resolved = provider.resolveDynamicModel?.(
120173
createProviderDynamicModelContext({
121174
provider: "fireworks",
122-
modelId: "accounts/fireworks/models/glm-5p1",
175+
modelId: "accounts/fireworks/models/glm-4p6",
123176
models: [createFireworksDefaultRuntimeModel({ reasoning: false })],
124177
}),
125178
);
126179

127180
expect(resolved?.provider).toBe("fireworks");
128-
expect(resolved?.id).toBe("accounts/fireworks/models/glm-5p1");
181+
expect(resolved?.id).toBe("accounts/fireworks/models/glm-4p6");
129182
expect(resolved?.input).toEqual(["text"]);
130183
});
131184

@@ -159,6 +212,61 @@ describe("fireworks provider plugin", () => {
159212
}
160213
});
161214

215+
it("derives thinking menus from each cataloged model's supportedReasoningEfforts", async () => {
216+
const provider = await registerSingleProviderPlugin(fireworksPlugin);
217+
expect(
218+
provider.resolveThinkingProfile?.({
219+
provider: "fireworks",
220+
modelId: FIREWORKS_DEEPSEEK_V4_MODEL_ID,
221+
}),
222+
).toEqual({
223+
levels: [
224+
{ id: "off" },
225+
{ id: "low" },
226+
{ id: "medium" },
227+
{ id: "high" },
228+
{ id: "xhigh" },
229+
{ id: "max" },
230+
],
231+
});
232+
expect(
233+
provider.resolveThinkingProfile?.({
234+
provider: "fireworks",
235+
modelId: FIREWORKS_MINIMAX_M3_MODEL_ID,
236+
}),
237+
).toEqual({
238+
levels: [{ id: "off" }, { id: "low" }, { id: "medium" }, { id: "high" }],
239+
});
240+
expect(
241+
provider.resolveThinkingProfile?.({
242+
provider: "fireworks",
243+
modelId: FIREWORKS_GLM_5_1_MODEL_ID,
244+
}),
245+
).toEqual({
246+
levels: [{ id: "off" }, { id: "low" }, { id: "medium" }, { id: "high" }],
247+
});
248+
expect(
249+
provider.resolveThinkingProfile?.({
250+
provider: "fireworks",
251+
modelId: FIREWORKS_GPT_OSS_120B_MODEL_ID,
252+
}),
253+
).toEqual({
254+
levels: [{ id: "low" }, { id: "medium" }, { id: "high" }],
255+
});
256+
expect(
257+
provider.resolveThinkingProfile?.({
258+
provider: "fireworks",
259+
modelId: "accounts/fireworks/models/deepseek-v4-flash",
260+
}),
261+
).toBeUndefined();
262+
expect(
263+
provider.resolveThinkingProfile?.({
264+
provider: "fireworks",
265+
modelId: "accounts/fireworks/models/glm-5p2",
266+
}),
267+
).toBeUndefined();
268+
});
269+
162270
it("exposes off-only thinking policy for Fireworks Kimi models", async () => {
163271
const provider = await registerSingleProviderPlugin(fireworksPlugin);
164272

@@ -169,7 +277,6 @@ describe("fireworks provider plugin", () => {
169277
}),
170278
).toEqual({
171279
levels: [{ id: "off" }],
172-
defaultLevel: "off",
173280
});
174281
expect(
175282
provider.resolveThinkingProfile?.({
@@ -178,7 +285,6 @@ describe("fireworks provider plugin", () => {
178285
}),
179286
).toEqual({
180287
levels: [{ id: "off" }],
181-
defaultLevel: "off",
182288
});
183289
expect(
184290
provider.resolveThinkingProfile?.({
@@ -188,7 +294,6 @@ describe("fireworks provider plugin", () => {
188294
).toBeUndefined();
189295
expect(resolveThinkingProfile({ modelId: FIREWORKS_K2_6_MODEL_ID })).toEqual({
190296
levels: [{ id: "off" }],
191-
defaultLevel: "off",
192297
});
193298
expect(
194299
resolveThinkingProfile({

extensions/fireworks/openclaw.plugin.json

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,117 @@
6464
"cacheRead": 0,
6565
"cacheWrite": 0
6666
}
67+
},
68+
{
69+
"id": "accounts/fireworks/models/deepseek-v4-pro",
70+
"name": "DeepSeek V4 Pro",
71+
"reasoning": true,
72+
"input": ["text"],
73+
"contextWindow": 1048576,
74+
"maxTokens": 1048576,
75+
"compat": {
76+
"thinkingFormat": "openai",
77+
"supportsReasoningEffort": true,
78+
"supportedReasoningEfforts": ["none", "low", "medium", "high", "xhigh", "max"],
79+
"reasoningEffortMap": {
80+
"off": "none",
81+
"none": "none",
82+
"low": "low",
83+
"medium": "medium",
84+
"high": "high",
85+
"xhigh": "xhigh",
86+
"adaptive": "high",
87+
"max": "max"
88+
}
89+
},
90+
"cost": {
91+
"input": 1.74,
92+
"output": 3.48,
93+
"cacheRead": 0.145,
94+
"cacheWrite": 0
95+
}
96+
},
97+
{
98+
"id": "accounts/fireworks/models/minimax-m3",
99+
"name": "MiniMax M3",
100+
"reasoning": true,
101+
"input": ["text", "image"],
102+
"contextWindow": 524288,
103+
"maxTokens": 64000,
104+
"compat": {
105+
"supportsReasoningEffort": true,
106+
"supportedReasoningEfforts": ["none", "low", "medium", "high"],
107+
"reasoningEffortMap": {
108+
"off": "none",
109+
"none": "none",
110+
"low": "low",
111+
"medium": "medium",
112+
"high": "high",
113+
"xhigh": "high",
114+
"adaptive": "medium",
115+
"max": "high"
116+
}
117+
},
118+
"cost": {
119+
"input": 0.3,
120+
"output": 1.2,
121+
"cacheRead": 0.06,
122+
"cacheWrite": 0
123+
}
124+
},
125+
{
126+
"id": "accounts/fireworks/models/glm-5p1",
127+
"name": "GLM-5.1",
128+
"reasoning": true,
129+
"input": ["text"],
130+
"contextWindow": 202752,
131+
"maxTokens": 202752,
132+
"compat": {
133+
"supportsReasoningEffort": true,
134+
"supportedReasoningEfforts": ["none", "low", "medium", "high"],
135+
"reasoningEffortMap": {
136+
"off": "none",
137+
"none": "none",
138+
"low": "low",
139+
"medium": "medium",
140+
"high": "high",
141+
"xhigh": "high",
142+
"adaptive": "high",
143+
"max": "high"
144+
}
145+
},
146+
"cost": {
147+
"input": 1.4,
148+
"output": 4.4,
149+
"cacheRead": 0.26,
150+
"cacheWrite": 0
151+
}
152+
},
153+
{
154+
"id": "accounts/fireworks/models/gpt-oss-120b",
155+
"name": "GPT-OSS 120B",
156+
"reasoning": true,
157+
"input": ["text"],
158+
"contextWindow": 131072,
159+
"maxTokens": 131072,
160+
"compat": {
161+
"supportsReasoningEffort": true,
162+
"supportedReasoningEfforts": ["low", "medium", "high"],
163+
"reasoningEffortMap": {
164+
"low": "low",
165+
"medium": "medium",
166+
"high": "high",
167+
"xhigh": "high",
168+
"adaptive": "medium",
169+
"max": "high"
170+
}
171+
},
172+
"cost": {
173+
"input": 0.15,
174+
"output": 0.6,
175+
"cacheRead": 0.015,
176+
"cacheWrite": 0
177+
}
67178
}
68179
]
69180
}

extensions/fireworks/provider-catalog.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ const FIREWORKS_MANIFEST_PROVIDER = buildManifestModelProviderConfig({
1414
export const FIREWORKS_BASE_URL = FIREWORKS_MANIFEST_PROVIDER.baseUrl;
1515
export const FIREWORKS_DEFAULT_MODEL_ID = "accounts/fireworks/routers/kimi-k2p5-turbo";
1616
export const FIREWORKS_K2_6_MODEL_ID = "accounts/fireworks/models/kimi-k2p6";
17+
export const FIREWORKS_DEEPSEEK_V4_MODEL_ID = "accounts/fireworks/models/deepseek-v4-pro";
18+
export const FIREWORKS_MINIMAX_M3_MODEL_ID = "accounts/fireworks/models/minimax-m3";
19+
export const FIREWORKS_GLM_5_1_MODEL_ID = "accounts/fireworks/models/glm-5p1";
20+
export const FIREWORKS_GPT_OSS_120B_MODEL_ID = "accounts/fireworks/models/gpt-oss-120b";
1721

1822
function requireFireworksManifestModel(id: string): ModelDefinitionConfig {
1923
const model = FIREWORKS_MANIFEST_PROVIDER.models.find((entry) => entry.id === id);

0 commit comments

Comments
 (0)