diff --git a/docs/providers/cerebras.md b/docs/providers/cerebras.md index c53f9e17eec9..1475a39ce986 100644 --- a/docs/providers/cerebras.md +++ b/docs/providers/cerebras.md @@ -17,7 +17,7 @@ read_when: | Direct CLI flag | `--cerebras-api-key ` | | API | OpenAI-compatible (`openai-completions`) | | Base URL | `https://api.cerebras.ai/v1` | -| Default model | `cerebras/zai-glm-4.7` | +| Default model | `cerebras/gpt-oss-120b` | ## Install plugin @@ -75,11 +75,11 @@ openclaw onboard --non-interactive \ All three models have a 131,072-token context window and a 40,960-token max output. -| Model ref | Name | Reasoning | Notes | -| ----------------------- | ------------ | --------- | ---------------------------------------- | -| `cerebras/zai-glm-4.7` | Z.ai GLM 4.7 | yes | Default model; scheduled for deprecation | -| `cerebras/gpt-oss-120b` | GPT OSS 120B | yes | Production reasoning model | -| `cerebras/gemma-4-31b` | Gemma 4 31B | yes | Text-and-image input; text output | +| Model ref | Name | Reasoning | Notes | +| ----------------------- | ------------ | --------- | ----------------------------------------- | +| `cerebras/zai-glm-4.7` | Z.ai GLM 4.7 | yes | Scheduled for deprecation August 17, 2026 | +| `cerebras/gpt-oss-120b` | GPT OSS 120B | yes | Default production reasoning model | +| `cerebras/gemma-4-31b` | Gemma 4 31B | yes | Preview; text-and-image input | ## Manual config @@ -90,7 +90,7 @@ Most setups only need the API key. Use explicit `models.providers.cerebras` conf env: { CEREBRAS_API_KEY: "csk-..." }, agents: { defaults: { - model: { primary: "cerebras/zai-glm-4.7" }, + model: { primary: "cerebras/gpt-oss-120b" }, }, }, models: { diff --git a/docs/providers/fireworks.md b/docs/providers/fireworks.md index 3e3320422370..fef3088e8fb8 100644 --- a/docs/providers/fireworks.md +++ b/docs/providers/fireworks.md @@ -7,19 +7,19 @@ read_when: - You are debugging Kimi thinking-off behavior on Fireworks --- -[Fireworks](https://fireworks.ai) exposes open-weight and routed models through an OpenAI-compatible API. Install the official Fireworks provider plugin to use two pre-cataloged Kimi models and any Fireworks model or router id at runtime. +[Fireworks](https://fireworks.ai) exposes open-weight and routed models through an OpenAI-compatible API. Install the official Fireworks provider plugin to use the current Fire Pass GLM router, two pre-cataloged Kimi models, and any Fireworks model or router id at runtime. -| Property | Value | -| --------------- | ------------------------------------------------------ | -| Provider id | `fireworks` (alias: `fireworks-ai`) | -| Package | `@openclaw/fireworks-provider` | -| Auth env var | `FIREWORKS_API_KEY` | -| Onboarding flag | `--auth-choice fireworks-api-key` | -| Direct CLI flag | `--fireworks-api-key ` | -| API | OpenAI-compatible (`openai-completions`) | -| Base URL | `https://api.fireworks.ai/inference/v1` | -| Default model | `fireworks/accounts/fireworks/routers/kimi-k2p6-turbo` | -| Default alias | `Kimi K2.6 Turbo` | +| Property | Value | +| --------------- | --------------------------------------------------- | +| Provider id | `fireworks` (alias: `fireworks-ai`) | +| Package | `@openclaw/fireworks-provider` | +| Auth env var | `FIREWORKS_API_KEY` | +| Onboarding flag | `--auth-choice fireworks-api-key` | +| Direct CLI flag | `--fireworks-api-key ` | +| API | OpenAI-compatible (`openai-completions`) | +| Base URL | `https://api.fireworks.ai/inference/v1` | +| Default model | `fireworks/accounts/fireworks/routers/glm-5p2-fast` | +| Default alias | `GLM 5.2 Fast` | ## Getting started @@ -48,7 +48,7 @@ export FIREWORKS_API_KEY=fw-... - Onboarding stores the key against the `fireworks` provider in your auth profiles and sets the **Fire Pass** Kimi K2.6 Turbo router as the default model. + Onboarding stores the key against the `fireworks` provider in your auth profiles and sets Fireworks' current [Fire Pass](https://docs.fireworks.ai/firepass) GLM 5.2 Fast router as the default model. @@ -56,7 +56,7 @@ export FIREWORKS_API_KEY=fw-... openclaw models list --provider fireworks ``` - The list should include `Kimi K2.6` and `Kimi K2.6 Turbo (Fire Pass)`. If `FIREWORKS_API_KEY` is unresolved, `openclaw models status --json` reports the missing credential under `auth.unusableProfiles`. + The list should include `GLM 5.2 Fast`, `Kimi K2.6`, and `Kimi K2.6 Fast`. If `FIREWORKS_API_KEY` is unresolved, `openclaw models status --json` reports the missing credential under `auth.unusableProfiles`. @@ -76,10 +76,11 @@ openclaw onboard --non-interactive \ ## Built-in catalog -| Model ref | Name | Input | Context | Max output | Thinking | -| ------------------------------------------------------ | -------------- | ------------ | ------- | ---------- | -------------------- | -| `fireworks/accounts/fireworks/models/kimi-k2p6` | Kimi K2.6 | text + image | 262,144 | 262,144 | Forced off | -| `fireworks/accounts/fireworks/routers/kimi-k2p6-turbo` | Kimi K2.6 Fast | text + image | 262,144 | 256,000 | Forced off (default) | +| Model ref | Name | Input | Context | Max output | Thinking | +| ------------------------------------------------------ | -------------- | ------------ | ------- | ---------- | ------------ | +| `fireworks/accounts/fireworks/routers/glm-5p2-fast` | GLM 5.2 Fast | text + image | 256,000 | 256,000 | On (default) | +| `fireworks/accounts/fireworks/models/kimi-k2p6` | Kimi K2.6 | text + image | 262,144 | 262,144 | Forced off | +| `fireworks/accounts/fireworks/routers/kimi-k2p6-turbo` | Kimi K2.6 Fast | text + image | 262,144 | 256,000 | Forced off | OpenClaw pins all Fireworks Kimi models to `thinking: off` because Kimi on Fireworks can leak chain-of-thought into the visible reply unless the request explicitly disables thinking. Routing the same model through [Moonshot](/providers/moonshot) directly preserves Kimi reasoning output. See [thinking modes](/tools/thinking) for switching between providers. @@ -87,7 +88,7 @@ openclaw onboard --non-interactive \ ## Custom Fireworks model ids -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. +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 and the OpenAI-compatible API) 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. ```json5 { diff --git a/docs/providers/moonshot.md b/docs/providers/moonshot.md index 0911c16232b7..24c0068c63a2 100644 --- a/docs/providers/moonshot.md +++ b/docs/providers/moonshot.md @@ -7,9 +7,9 @@ read_when: title: "Moonshot AI" --- -Moonshot provides the Kimi API with OpenAI-compatible endpoints. Select -`moonshot/kimi-k3` for Kimi K3, keep the onboarding default -`moonshot/kimi-k2.6`, or use `kimi/kimi-for-coding` for Kimi Coding. +Moonshot provides the Kimi API with OpenAI-compatible endpoints. Fresh Moonshot +onboarding selects `moonshot/kimi-k3`; use `kimi/kimi-for-coding` for the +separate Kimi Coding provider. Moonshot and Kimi Coding are **separate providers**, each shipped as a separate external plugin. Keys are not interchangeable, endpoints differ, and model refs differ (`moonshot/...` vs `kimi/...`). @@ -39,7 +39,7 @@ overrides (`temperature`, `top_p`, `n`, `presence_penalty`, and `frequency_penalty`) that K3 fixes to provider defaults. Kimi K2.7 Code also always uses native thinking but requires both `thinking` and `reasoning_effort` to be omitted; the HighSpeed variant uses the same contract. -Kimi K2.6 remains the onboarding default. +Kimi K3 is the onboarding default. See Moonshot's [Kimi K3 quickstart](https://platform.kimi.ai/docs/guide/kimi-k3-quickstart). ## Getting started @@ -75,9 +75,8 @@ onboarding. openclaw onboard --auth-choice moonshot-api-key-cn ``` - - Onboarding keeps Kimi K2.6 as the initial default. Switch explicitly - when you want Kimi K3: + + Fresh onboarding selects Kimi K3. Existing installations can switch explicitly: ```bash openclaw models set moonshot/kimi-k3 @@ -398,7 +397,7 @@ Config lives under `plugins.entries.moonshot.config.webSearch`: provider id pointed at the same native Moonshot host inherits the same streaming-usage behavior. - With the catalog K2.6 pricing, streamed usage that includes input, output, + With the catalog K3 pricing, streamed usage that includes input, output, and cache-read tokens is also converted into local estimated USD cost for `/status`, `/usage full`, `/usage cost`, and transcript-backed session accounting. diff --git a/docs/providers/venice.md b/docs/providers/venice.md index aff614d64b7a..edcf3ac67a0a 100644 --- a/docs/providers/venice.md +++ b/docs/providers/venice.md @@ -95,7 +95,7 @@ You can also run `openclaw configure` and pick **Model/auth provider > Venice AI | Model ID | Name | Context | Notes | | -------------------------------------- | --------------------------- | ------- | --------------------------- | | `zai-org-glm-5-2` | GLM 5.2 | 1M | Recommended, coding | - | `zai-org-glm-4.7` | GLM 4.7 | 198k | Venice default | + | `zai-org-glm-4.7` | GLM 4.7 | 198k | Private reasoning | | `venice-uncensored-1-2` | Venice Uncensored 1.2 | 128k | Most uncensored, vision | | `google-gemma-4-31b-it` | Google Gemma 4 31B Instruct | 256k | Recommended, vision | | `kimi-k2-6` | Kimi K2.6 | 256k | Recommended, coding, vision | diff --git a/docs/providers/zai.md b/docs/providers/zai.md index b186ab996e85..4e6f3d346c75 100644 --- a/docs/providers/zai.md +++ b/docs/providers/zai.md @@ -82,8 +82,8 @@ openclaw plugins install @openclaw/zai-provider | Onboarding choice | Base URL | Default model | | ------------------- | --------------------------------------------- | ------------- | -| `zai-global` | `https://api.z.ai/api/paas/v4` | `glm-5.1` | -| `zai-cn` | `https://open.bigmodel.cn/api/paas/v4` | `glm-5.1` | +| `zai-global` | `https://api.z.ai/api/paas/v4` | `glm-5.2` | +| `zai-cn` | `https://open.bigmodel.cn/api/paas/v4` | `glm-5.2` | | `zai-coding-global` | `https://api.z.ai/api/coding/paas/v4` | `glm-5.2` | | `zai-coding-cn` | `https://open.bigmodel.cn/api/coding/paas/v4` | `glm-5.2` | @@ -167,7 +167,7 @@ The manifest-backed catalog currently includes: | Model ref | Notes | | ------------------ | ------------------------------------------------- | -| `zai/glm-5.2` | Coding Plan default; 1M context | +| `zai/glm-5.2` | Default; 1M context | | `zai/glm-5-turbo` | OpenClaw-optimized text model; 200K context | | `zai/glm-5v-turbo` | Multimodal coding model; 200K context | | `zai/glm-5.1` | Deprecated; hidden unless configured; use GLM-5.2 | @@ -182,8 +182,8 @@ GLM models are available as `zai/` (example: `zai/glm-5.2`). -Coding Plan setup defaults to `zai/glm-5.2`; general API setup keeps -`zai/glm-5.1`. On the Coding Plan endpoints, auto-detection falls back to +All fresh Z.AI setup paths default to `zai/glm-5.2`. On the Coding Plan endpoints, +auto-detection falls back to `glm-5.1` and then `glm-4.7` when the key/plan does not expose GLM-5.2. GLM versions and availability can change; run `openclaw models list --all --provider zai` to see the catalog known to your installed version. diff --git a/extensions/cerebras/onboard.test.ts b/extensions/cerebras/onboard.test.ts index fd9a4143ae43..43f7536af04b 100644 --- a/extensions/cerebras/onboard.test.ts +++ b/extensions/cerebras/onboard.test.ts @@ -14,7 +14,7 @@ describe("Cerebras onboarding", () => { CEREBRAS_DEFAULT_MODEL_REF, ); expect(config.agents?.defaults?.models).toEqual({ - [CEREBRAS_DEFAULT_MODEL_REF]: { alias: "Cerebras GLM 4.7" }, + [CEREBRAS_DEFAULT_MODEL_REF]: { alias: "Cerebras GPT OSS 120B" }, }); }); }); diff --git a/extensions/cerebras/onboard.ts b/extensions/cerebras/onboard.ts index ee0009584f35..978528ecd675 100644 --- a/extensions/cerebras/onboard.ts +++ b/extensions/cerebras/onboard.ts @@ -22,7 +22,7 @@ const cerebrasPresetAppliers = createModelCatalogPresetAppliers({ api: "openai-completions", baseUrl: CEREBRAS_BASE_URL, catalogModels: CEREBRAS_MODEL_CATALOG.map(buildCerebrasModelDefinition), - aliases: [{ modelRef: CEREBRAS_DEFAULT_MODEL_REF, alias: "Cerebras GLM 4.7" }], + aliases: [{ modelRef: CEREBRAS_DEFAULT_MODEL_REF, alias: "Cerebras GPT OSS 120B" }], }), }); diff --git a/extensions/cerebras/openclaw.plugin.json b/extensions/cerebras/openclaw.plugin.json index 7c9766f73949..b5e1fcc8fdc6 100644 --- a/extensions/cerebras/openclaw.plugin.json +++ b/extensions/cerebras/openclaw.plugin.json @@ -23,7 +23,7 @@ "cerebras": { "baseUrl": "https://api.cerebras.ai/v1", "api": "openai-completions", - "defaultModel": "zai-glm-4.7", + "defaultModel": "gpt-oss-120b", "models": [ { "id": "zai-glm-4.7", diff --git a/extensions/fireworks/index.test.ts b/extensions/fireworks/index.test.ts index 2941824cfcc0..b98f38af100f 100644 --- a/extensions/fireworks/index.test.ts +++ b/extensions/fireworks/index.test.ts @@ -19,6 +19,7 @@ import { import { resolveThinkingProfile } from "./provider-policy-api.js"; const FIREWORKS_KIMI_K2_6_MODEL_ID = "accounts/fireworks/models/kimi-k2p6"; +const FIREWORKS_KIMI_K2_6_TURBO_MODEL_ID = "accounts/fireworks/routers/kimi-k2p6-turbo"; function createFireworksDefaultRuntimeModel(params: { reasoning: boolean }): ProviderRuntimeModel { return { @@ -66,29 +67,44 @@ describe("fireworks provider plugin", () => { throw new Error("expected Fireworks catalog models"); } expect(models.map((model) => model.id)).toEqual([ - FIREWORKS_KIMI_K2_6_MODEL_ID, FIREWORKS_DEFAULT_MODEL_ID, + FIREWORKS_KIMI_K2_6_MODEL_ID, + FIREWORKS_KIMI_K2_6_TURBO_MODEL_ID, ]); - expect(models[0]?.reasoning).toBe(false); + expect(models[0]?.name).toBe("GLM 5.2 Fast"); + expect(models[0]?.reasoning).toBe(true); expect(models[0]?.input).toEqual(["text", "image"]); - expect(models[0]?.contextWindow).toBe(262144); - expect(models[0]?.maxTokens).toBe(262144); + expect(models[0]?.contextWindow).toBe(FIREWORKS_DEFAULT_CONTEXT_WINDOW); + expect(models[0]?.maxTokens).toBe(FIREWORKS_DEFAULT_MAX_TOKENS); expect(models[0]?.cost).toEqual({ + input: 2.1, + output: 6.6, + cacheRead: 0.21, + cacheWrite: 0, + }); + expect(models[1]?.name).toBe("Kimi K2.6"); + expect(models[1]?.reasoning).toBe(false); + expect(models[1]?.input).toEqual(["text", "image"]); + expect(models[1]?.contextWindow).toBe(262144); + expect(models[1]?.maxTokens).toBe(262144); + expect(models[1]?.cost).toEqual({ input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0, }); - expect(models[1]?.name).toBe("Kimi K2.6 Fast"); - expect(models[1]?.reasoning).toBe(false); - expect(models[1]?.input).toEqual(["text", "image"]); - expect(models[1]?.contextWindow).toBe(262144); - expect(models[1]?.maxTokens).toBe(FIREWORKS_DEFAULT_MAX_TOKENS); - expect(models[1]?.cost).toEqual({ - input: 2, - output: 8, - cacheRead: 0.3, - cacheWrite: 0, + expect(models[2]).toMatchObject({ + name: "Kimi K2.6 Fast", + reasoning: false, + input: ["text", "image"], + contextWindow: 262144, + maxTokens: 256000, + cost: { + input: 2, + output: 8, + cacheRead: 0.3, + cacheWrite: 0, + }, }); }); @@ -158,7 +174,11 @@ describe("fireworks provider plugin", () => { it("defers manifest catalog models to core static-catalog resolution", async () => { const provider = await registerSingleProviderPlugin(fireworksPlugin); - for (const modelId of [FIREWORKS_KIMI_K2_6_MODEL_ID, FIREWORKS_DEFAULT_MODEL_ID]) { + for (const modelId of [ + FIREWORKS_DEFAULT_MODEL_ID, + FIREWORKS_KIMI_K2_6_MODEL_ID, + FIREWORKS_KIMI_K2_6_TURBO_MODEL_ID, + ]) { const resolved = provider.resolveDynamicModel?.( createProviderDynamicModelContext({ provider: "fireworks", @@ -177,7 +197,7 @@ describe("fireworks provider plugin", () => { expect( provider.resolveThinkingProfile?.({ provider: "fireworks", - modelId: FIREWORKS_DEFAULT_MODEL_ID, + modelId: FIREWORKS_KIMI_K2_6_TURBO_MODEL_ID, }), ).toEqual({ levels: [{ id: "off" }], @@ -195,7 +215,7 @@ describe("fireworks provider plugin", () => { expect( provider.resolveThinkingProfile?.({ provider: "fireworks", - modelId: "accounts/fireworks/models/qwen3.6-plus", + modelId: FIREWORKS_DEFAULT_MODEL_ID, }), ).toBeUndefined(); expect(resolveThinkingProfile({ modelId: FIREWORKS_KIMI_K2_6_MODEL_ID })).toEqual({ diff --git a/extensions/fireworks/onboard.test.ts b/extensions/fireworks/onboard.test.ts index 9b8eb9b06957..b95e07ae2b8f 100644 --- a/extensions/fireworks/onboard.test.ts +++ b/extensions/fireworks/onboard.test.ts @@ -12,7 +12,7 @@ describe("Fireworks onboarding", () => { FIREWORKS_DEFAULT_MODEL_REF, ); expect(config.agents?.defaults?.models).toEqual({ - [FIREWORKS_DEFAULT_MODEL_REF]: { alias: "Kimi K2.6 Turbo" }, + [FIREWORKS_DEFAULT_MODEL_REF]: { alias: "GLM 5.2 Fast" }, }); }); }); diff --git a/extensions/fireworks/onboard.ts b/extensions/fireworks/onboard.ts index 4da9e96bd665..cd1892db6d26 100644 --- a/extensions/fireworks/onboard.ts +++ b/extensions/fireworks/onboard.ts @@ -19,7 +19,7 @@ const fireworksPresetAppliers = createDefaultModelsPresetAppliers({ baseUrl: defaultProvider.baseUrl, defaultModels: buildFireworksCatalogModels(), defaultModelId: FIREWORKS_DEFAULT_MODEL_ID, - aliases: [{ modelRef: FIREWORKS_DEFAULT_MODEL_REF, alias: "Kimi K2.6 Turbo" }], + aliases: [{ modelRef: FIREWORKS_DEFAULT_MODEL_REF, alias: "GLM 5.2 Fast" }], }; }, }); diff --git a/extensions/fireworks/openclaw.plugin.json b/extensions/fireworks/openclaw.plugin.json index 7ff7f04620f8..2df6fe02bec3 100644 --- a/extensions/fireworks/openclaw.plugin.json +++ b/extensions/fireworks/openclaw.plugin.json @@ -34,8 +34,22 @@ "fireworks": { "baseUrl": "https://api.fireworks.ai/inference/v1", "api": "openai-completions", - "defaultModel": "accounts/fireworks/routers/kimi-k2p6-turbo", + "defaultModel": "accounts/fireworks/routers/glm-5p2-fast", "models": [ + { + "id": "accounts/fireworks/routers/glm-5p2-fast", + "name": "GLM 5.2 Fast", + "reasoning": true, + "input": ["text", "image"], + "contextWindow": 256000, + "maxTokens": 256000, + "cost": { + "input": 2.1, + "output": 6.6, + "cacheRead": 0.21, + "cacheWrite": 0 + } + }, { "id": "accounts/fireworks/models/kimi-k2p6", "name": "Kimi K2.6", diff --git a/extensions/moonshot/api.ts b/extensions/moonshot/api.ts index 21fde669a894..3a01fd5205f5 100644 --- a/extensions/moonshot/api.ts +++ b/extensions/moonshot/api.ts @@ -6,5 +6,5 @@ export { MOONSHOT_BASE_URL, MOONSHOT_CN_BASE_URL, MOONSHOT_DEFAULT_MODEL_ID, + MOONSHOT_DEFAULT_MODEL_REF, } from "./provider-catalog.js"; -export { MOONSHOT_DEFAULT_MODEL_REF } from "./onboard.js"; diff --git a/extensions/moonshot/index.ts b/extensions/moonshot/index.ts index 7771a0527f6b..1490a8693304 100644 --- a/extensions/moonshot/index.ts +++ b/extensions/moonshot/index.ts @@ -4,12 +4,8 @@ import { buildOpenAICompatibleReplayPolicy } from "openclaw/plugin-sdk/provider- import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family"; import { applyMoonshotNativeStreamingUsageCompat } from "./api.js"; import { moonshotMediaUnderstandingProvider } from "./media-understanding-provider.js"; -import { - applyMoonshotConfig, - applyMoonshotConfigCn, - MOONSHOT_DEFAULT_MODEL_REF, -} from "./onboard.js"; -import { buildMoonshotProvider } from "./provider-catalog.js"; +import { applyMoonshotConfig, applyMoonshotConfigCn } from "./onboard.js"; +import { buildMoonshotProvider, MOONSHOT_DEFAULT_MODEL_REF } from "./provider-catalog.js"; import { isMoonshotAlwaysThinkingModelId, resolveThinkingProfile } from "./provider-policy-api.js"; import { createKimiWebSearchProvider } from "./src/kimi-web-search-provider.js"; diff --git a/extensions/moonshot/media-understanding-provider.ts b/extensions/moonshot/media-understanding-provider.ts index de264f0fa318..2893c79f0875 100644 --- a/extensions/moonshot/media-understanding-provider.ts +++ b/extensions/moonshot/media-understanding-provider.ts @@ -16,10 +16,14 @@ import { readProviderJsonResponse, resolveProviderHttpRequestConfig, } from "openclaw/plugin-sdk/provider-http"; -import { MOONSHOT_DEFAULT_MODEL_ID } from "./provider-catalog.js"; +import manifest from "./openclaw.plugin.json" with { type: "json" }; const DEFAULT_MOONSHOT_VIDEO_BASE_URL = "https://api.moonshot.ai/v1"; -const DEFAULT_MOONSHOT_VIDEO_MODEL = MOONSHOT_DEFAULT_MODEL_ID; +// Media defaults are capability-specific and intentionally independent from chat onboarding. +const DEFAULT_MOONSHOT_IMAGE_MODEL = + manifest.mediaUnderstandingProviderMetadata.moonshot.defaultModels.image; +const DEFAULT_MOONSHOT_VIDEO_MODEL = + manifest.mediaUnderstandingProviderMetadata.moonshot.defaultModels.video; const DEFAULT_MOONSHOT_VIDEO_PROMPT = "Describe the video."; async function describeMoonshotVideo( @@ -83,7 +87,10 @@ async function describeMoonshotVideo( export const moonshotMediaUnderstandingProvider: MediaUnderstandingProvider = { id: "moonshot", capabilities: ["image", "video"], - defaultModels: { image: MOONSHOT_DEFAULT_MODEL_ID, video: DEFAULT_MOONSHOT_VIDEO_MODEL }, + defaultModels: { + image: DEFAULT_MOONSHOT_IMAGE_MODEL, + video: DEFAULT_MOONSHOT_VIDEO_MODEL, + }, autoPriority: { video: 20 }, describeImage: describeImageWithModel, describeImages: describeImagesWithModel, diff --git a/extensions/moonshot/onboard.test.ts b/extensions/moonshot/onboard.test.ts new file mode 100644 index 000000000000..5e9bbb957a65 --- /dev/null +++ b/extensions/moonshot/onboard.test.ts @@ -0,0 +1,30 @@ +import { resolveAgentModelPrimaryValue } from "openclaw/plugin-sdk/provider-onboard"; +import { describe, expect, it } from "vitest"; +import { applyMoonshotConfig, applyMoonshotConfigCn } from "./onboard.js"; +import manifest from "./openclaw.plugin.json" with { type: "json" }; +import { + MOONSHOT_BASE_URL, + MOONSHOT_CN_BASE_URL, + MOONSHOT_DEFAULT_MODEL_ID, + MOONSHOT_DEFAULT_MODEL_REF, +} from "./provider-catalog.js"; + +describe("Moonshot onboarding", () => { + it.each([ + ["international", applyMoonshotConfig, MOONSHOT_BASE_URL], + ["China", applyMoonshotConfigCn, MOONSHOT_CN_BASE_URL], + ])("applies the manifest default on the %s endpoint", (_name, applyConfig, baseUrl) => { + const config = applyConfig({}); + const provider = config.models?.providers?.moonshot; + + expect(MOONSHOT_DEFAULT_MODEL_ID).toBe(manifest.modelCatalog.providers.moonshot.defaultModel); + expect(provider?.baseUrl).toBe(baseUrl); + expect(provider?.models.map((model) => model.id)).toEqual([MOONSHOT_DEFAULT_MODEL_ID]); + expect(resolveAgentModelPrimaryValue(config.agents?.defaults?.model)).toBe( + MOONSHOT_DEFAULT_MODEL_REF, + ); + expect(config.agents?.defaults?.models).toEqual({ + [MOONSHOT_DEFAULT_MODEL_REF]: { alias: "Kimi" }, + }); + }); +}); diff --git a/extensions/moonshot/onboard.ts b/extensions/moonshot/onboard.ts index 4877e7ed98f3..d3e0a1e02dd4 100644 --- a/extensions/moonshot/onboard.ts +++ b/extensions/moonshot/onboard.ts @@ -8,13 +8,15 @@ import { MOONSHOT_BASE_URL, MOONSHOT_CN_BASE_URL, MOONSHOT_DEFAULT_MODEL_ID, + MOONSHOT_DEFAULT_MODEL_REF, } from "./provider-catalog.js"; -export const MOONSHOT_DEFAULT_MODEL_REF = `moonshot/${MOONSHOT_DEFAULT_MODEL_ID}`; const moonshotPresetAppliers = createDefaultModelPresetAppliers<[string]>({ primaryModelRef: MOONSHOT_DEFAULT_MODEL_REF, resolveParams: (_cfg: OpenClawConfig, baseUrl: string) => { - const defaultModel = buildMoonshotProvider().models[0]; + const defaultModel = buildMoonshotProvider().models.find( + (model) => model.id === MOONSHOT_DEFAULT_MODEL_ID, + ); if (!defaultModel) { return null; } diff --git a/extensions/moonshot/openclaw.plugin.json b/extensions/moonshot/openclaw.plugin.json index 8a0969d57f4a..a1437e50643f 100644 --- a/extensions/moonshot/openclaw.plugin.json +++ b/extensions/moonshot/openclaw.plugin.json @@ -54,6 +54,7 @@ "moonshot": { "baseUrl": "https://api.moonshot.ai/v1", "api": "openai-completions", + "defaultModel": "kimi-k3", "models": [ { "id": "kimi-k3", diff --git a/extensions/moonshot/provider-catalog.test.ts b/extensions/moonshot/provider-catalog.test.ts index c9126e3bc1a2..62364bd0c057 100644 --- a/extensions/moonshot/provider-catalog.test.ts +++ b/extensions/moonshot/provider-catalog.test.ts @@ -55,7 +55,7 @@ describe("moonshot provider catalog", () => { xhigh: "max", max: "max", }, - input: ["text", "image", "video"], + input: ["text", "image"], contextWindow: 1_048_576, maxTokens: 1_048_576, cost: { @@ -71,7 +71,7 @@ describe("moonshot provider catalog", () => { }); expect(requireMoonshotModel(provider, "kimi-k2.7-code")).toMatchObject({ reasoning: true, - input: ["text", "image", "video"], + input: ["text", "image"], contextWindow: 262144, maxTokens: 262144, cost: { @@ -83,7 +83,7 @@ describe("moonshot provider catalog", () => { }); expect(requireMoonshotModel(provider, "kimi-k2.7-code-highspeed")).toMatchObject({ reasoning: true, - input: ["text", "image", "video"], + input: ["text", "image"], contextWindow: 262144, maxTokens: 262144, cost: { diff --git a/extensions/moonshot/provider-catalog.ts b/extensions/moonshot/provider-catalog.ts index fbcca26f092b..2744634a6332 100644 --- a/extensions/moonshot/provider-catalog.ts +++ b/extensions/moonshot/provider-catalog.ts @@ -1,7 +1,8 @@ // Moonshot provider module implements model/runtime integration. import { - buildManifestModelProviderConfig, applyProviderNativeStreamingUsageCompat, + buildManifestModelProviderConfig, + readManifestProviderDefaultModelRef, supportsNativeStreamingUsageCompat, } from "openclaw/plugin-sdk/provider-catalog-shared"; import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared"; @@ -9,7 +10,11 @@ import manifest from "./openclaw.plugin.json" with { type: "json" }; export const MOONSHOT_BASE_URL = "https://api.moonshot.ai/v1"; export const MOONSHOT_CN_BASE_URL = "https://api.moonshot.cn/v1"; -export const MOONSHOT_DEFAULT_MODEL_ID = "kimi-k2.6"; +export const MOONSHOT_DEFAULT_MODEL_REF = readManifestProviderDefaultModelRef( + manifest, + "moonshot", +)!; +export const MOONSHOT_DEFAULT_MODEL_ID = MOONSHOT_DEFAULT_MODEL_REF.slice("moonshot/".length); export function isNativeMoonshotBaseUrl(baseUrl: string | undefined): boolean { return supportsNativeStreamingUsageCompat({ diff --git a/extensions/moonshot/src/kimi-web-search-provider.runtime.ts b/extensions/moonshot/src/kimi-web-search-provider.runtime.ts index 9273576bb70b..c549064ed4f8 100644 --- a/extensions/moonshot/src/kimi-web-search-provider.runtime.ts +++ b/extensions/moonshot/src/kimi-web-search-provider.runtime.ts @@ -35,11 +35,11 @@ import { isNativeMoonshotBaseUrl, MOONSHOT_BASE_URL, MOONSHOT_CN_BASE_URL, - MOONSHOT_DEFAULT_MODEL_ID, } from "../provider-catalog.js"; const DEFAULT_KIMI_BASE_URL = MOONSHOT_BASE_URL; -const DEFAULT_KIMI_SEARCH_MODEL = MOONSHOT_DEFAULT_MODEL_ID; +// Search owns a separate model default so chat onboarding changes do not silently reroute searches. +const DEFAULT_KIMI_SEARCH_MODEL = "kimi-k2.6"; /** Models that require explicit thinking disablement for web search. */ const KIMI_THINKING_MODELS = new Set(["kimi-k2.6", "kimi-k2.5"]); const KIMI_WEB_SEARCH_TOOL = { diff --git a/extensions/venice/onboard.test.ts b/extensions/venice/onboard.test.ts index 8d1df44c287c..363e04f7615f 100644 --- a/extensions/venice/onboard.test.ts +++ b/extensions/venice/onboard.test.ts @@ -15,7 +15,7 @@ describe("Venice onboarding", () => { VENICE_DEFAULT_MODEL_REF, ); expect(config.agents?.defaults?.models).toEqual({ - [VENICE_DEFAULT_MODEL_REF]: { alias: "Kimi K2.5" }, + [VENICE_DEFAULT_MODEL_REF]: { alias: "Kimi K2.6" }, }); }); }); diff --git a/extensions/venice/onboard.ts b/extensions/venice/onboard.ts index 4f43647cf625..290b058a85b4 100644 --- a/extensions/venice/onboard.ts +++ b/extensions/venice/onboard.ts @@ -17,7 +17,7 @@ const venicePresetAppliers = createModelCatalogPresetAppliers({ api: "openai-completions", baseUrl: VENICE_BASE_URL, catalogModels: VENICE_MODEL_CATALOG.map(buildVeniceModelDefinition), - aliases: [{ modelRef: VENICE_DEFAULT_MODEL_REF, alias: "Kimi K2.5" }], + aliases: [{ modelRef: VENICE_DEFAULT_MODEL_REF, alias: "Kimi K2.6" }], }), }); diff --git a/extensions/venice/openclaw.plugin.json b/extensions/venice/openclaw.plugin.json index 3c516bb0ff3f..51508feed69d 100644 --- a/extensions/venice/openclaw.plugin.json +++ b/extensions/venice/openclaw.plugin.json @@ -43,7 +43,7 @@ "venice": { "baseUrl": "https://api.venice.ai/api/v1", "api": "openai-completions", - "defaultModel": "kimi-k2-5", + "defaultModel": "kimi-k2-6", "models": [ { "id": "zai-org-glm-5-2", diff --git a/extensions/zai/detect.test.ts b/extensions/zai/detect.test.ts index b9a4a6f84172..e0084ba6835a 100644 --- a/extensions/zai/detect.test.ts +++ b/extensions/zai/detect.test.ts @@ -100,21 +100,21 @@ describe("detectZaiEndpoint", () => { }> = [ { responses: { - "https://api.z.ai/api/paas/v4/chat/completions::glm-5.1": { status: 200 }, + "https://api.z.ai/api/paas/v4/chat/completions::glm-5.2": { status: 200 }, }, - expected: { endpoint: "global", modelId: "glm-5.1" }, + expected: { endpoint: "global", modelId: "glm-5.2" }, }, { responses: { - "https://api.z.ai/api/paas/v4/chat/completions::glm-5.1": { status: 404 }, - "https://open.bigmodel.cn/api/paas/v4/chat/completions::glm-5.1": { status: 200 }, + "https://api.z.ai/api/paas/v4/chat/completions::glm-5.2": { status: 404 }, + "https://open.bigmodel.cn/api/paas/v4/chat/completions::glm-5.2": { status: 200 }, }, - expected: { endpoint: "cn", modelId: "glm-5.1" }, + expected: { endpoint: "cn", modelId: "glm-5.2" }, }, { responses: { - "https://api.z.ai/api/paas/v4/chat/completions::glm-5.1": { status: 404 }, - "https://open.bigmodel.cn/api/paas/v4/chat/completions::glm-5.1": { status: 404 }, + "https://api.z.ai/api/paas/v4/chat/completions::glm-5.2": { status: 404 }, + "https://open.bigmodel.cn/api/paas/v4/chat/completions::glm-5.2": { status: 404 }, "https://api.z.ai/api/coding/paas/v4/chat/completions::glm-5.2": { status: 200 }, }, expected: { endpoint: "coding-global", modelId: "glm-5.2" }, @@ -199,8 +199,8 @@ describe("detectZaiEndpoint", () => { }, { responses: { - "https://api.z.ai/api/paas/v4/chat/completions::glm-5.1": { status: 401 }, - "https://open.bigmodel.cn/api/paas/v4/chat/completions::glm-5.1": { status: 401 }, + "https://api.z.ai/api/paas/v4/chat/completions::glm-5.2": { status: 401 }, + "https://open.bigmodel.cn/api/paas/v4/chat/completions::glm-5.2": { status: 401 }, "https://api.z.ai/api/coding/paas/v4/chat/completions::glm-5.2": { status: 401 }, "https://api.z.ai/api/coding/paas/v4/chat/completions::glm-5.1": { status: 401 }, "https://api.z.ai/api/coding/paas/v4/chat/completions::glm-4.7": { status: 401 }, @@ -240,7 +240,7 @@ describe("detectZaiEndpoint", () => { .mockReturnValue(1 as unknown as ReturnType); vi.spyOn(globalThis, "clearTimeout").mockImplementation(() => undefined); const fetchFn = makeFetch({ - "https://api.z.ai/api/paas/v4/chat/completions::glm-5.1": { status: 200 }, + "https://api.z.ai/api/paas/v4/chat/completions::glm-5.2": { status: 200 }, }); await detectZaiEndpoint({ diff --git a/extensions/zai/detect.ts b/extensions/zai/detect.ts index a0acffd02193..e17aa7734c94 100644 --- a/extensions/zai/detect.ts +++ b/extensions/zai/detect.ts @@ -165,13 +165,13 @@ export async function detectZaiEndpoint(params: { endpoint: "global" as const, baseUrl: ZAI_GLOBAL_BASE_URL, modelId: ZAI_DEFAULT_MODEL_ID, - note: "Verified GLM-5.1 on global endpoint.", + note: "Verified GLM-5.2 on global endpoint.", }, { endpoint: "cn" as const, baseUrl: ZAI_CN_BASE_URL, modelId: ZAI_DEFAULT_MODEL_ID, - note: "Verified GLM-5.1 on cn endpoint.", + note: "Verified GLM-5.2 on cn endpoint.", }, ]; const codingModels: ProbeCandidate[] = [ diff --git a/extensions/zai/index.test.ts b/extensions/zai/index.test.ts index f7f86828c207..56da5f4a4618 100644 --- a/extensions/zai/index.test.ts +++ b/extensions/zai/index.test.ts @@ -194,13 +194,13 @@ describe("zai provider plugin", () => { const resolved = provider.resolveDynamicModel?.({ provider: "zai", - modelId: "glm-5-turbo", + modelId: "glm-5.3", modelRegistry: { find: () => null, }, } as never) as Record | undefined; expectModelFields(resolved, { - id: "glm-5-turbo", + id: "glm-5.3", provider: "zai", api: "openai-completions", baseUrl: "https://api.z.ai/api/paas/v4", @@ -215,14 +215,13 @@ describe("zai provider plugin", () => { const resolved = provider.resolveDynamicModel?.({ provider: "zai", - modelId: "glm-5-turbo", + modelId: "glm-5.3", modelRegistry: { find: (_provider: string, modelId: string) => (modelId === "glm-4.7" ? template : null), }, } as never) as Record | undefined; expectModelFields(resolved, { - id: "glm-5-turbo", - name: "GLM-5 Turbo", + id: "glm-5.3", provider: "zai", api: "openai-completions", baseUrl: "https://api.z.ai/api/paas/v4", diff --git a/extensions/zai/onboard.test.ts b/extensions/zai/onboard.test.ts index 541a55bc9781..4fd1c54c11d6 100644 --- a/extensions/zai/onboard.test.ts +++ b/extensions/zai/onboard.test.ts @@ -12,6 +12,7 @@ import { ZAI_GLOBAL_BASE_URL, } from "./model-definitions.js"; import { applyZaiConfig, applyZaiProviderConfig } from "./onboard.js"; +import manifest from "./openclaw.plugin.json" with { type: "json" }; describe("zai onboard", () => { let defaultCfg: ReturnType; @@ -28,7 +29,7 @@ describe("zai onboard", () => { expect(defaultCfg.models?.providers?.zai?.baseUrl).toBe(ZAI_GLOBAL_BASE_URL); expect(defaultCfg.models?.providers?.zai?.api).toBe("openai-completions"); const ids = defaultCfg.models?.providers?.zai?.models?.map((m) => m.id); - expect(ids).toEqual(["glm-5.2", "glm-5.1"]); + expect(ids).toEqual(manifest.modelCatalog.providers.zai.models.map((model) => model.id)); expect( defaultCfg.models?.providers?.zai?.models?.find((model) => model.id === "glm-5.2"), ).toMatchObject({ @@ -41,9 +42,9 @@ describe("zai onboard", () => { }); it("uses the manifest default and alias for a fresh general endpoint setup", () => { - expect(resolveAgentModelPrimaryValue(defaultCfg.agents?.defaults?.model)).toBe("zai/glm-5.1"); + expect(resolveAgentModelPrimaryValue(defaultCfg.agents?.defaults?.model)).toBe("zai/glm-5.2"); expect(defaultCfg.agents?.defaults?.models).toEqual({ - "zai/glm-5.1": { alias: "GLM" }, + "zai/glm-5.2": { alias: "GLM" }, }); }); @@ -98,7 +99,7 @@ describe("zai onboard", () => { } }); - it("defaults Coding Plan endpoints to GLM-5.2 without changing the general API default", () => { + it("defaults general and Coding Plan endpoints to GLM-5.2", () => { const codingCfg = applyZaiConfig({}, { endpoint: "coding-global" }); const existingCodingCfg = applyZaiConfig({ models: { @@ -112,7 +113,7 @@ describe("zai onboard", () => { }, }); - expect(resolveAgentModelPrimaryValue(defaultCfg.agents?.defaults?.model)).toBe("zai/glm-5.1"); + expect(resolveAgentModelPrimaryValue(defaultCfg.agents?.defaults?.model)).toBe("zai/glm-5.2"); expect(codingCfg.models?.providers?.zai?.baseUrl).toBe(ZAI_CODING_GLOBAL_BASE_URL); expect(resolveAgentModelPrimaryValue(codingCfg.agents?.defaults?.model)).toBe("zai/glm-5.2"); expect(resolveAgentModelPrimaryValue(existingCodingCfg.agents?.defaults?.model)).toBe( diff --git a/extensions/zai/openclaw.plugin.json b/extensions/zai/openclaw.plugin.json index 7b76a3bb5602..07ecf386dc25 100644 --- a/extensions/zai/openclaw.plugin.json +++ b/extensions/zai/openclaw.plugin.json @@ -32,7 +32,7 @@ "zai": { "baseUrl": "https://api.z.ai/api/paas/v4", "api": "openai-completions", - "defaultModel": "glm-5.1", + "defaultModel": "glm-5.2", "models": [ { "id": "glm-5.2",