providers: default Moonshot to Kimi 2.6 (#69477)

Merged via squash.

Prepared head SHA: 4d778d09d1
Co-authored-by: scoootscooob <167050519+scoootscooob@users.noreply.github.com>
Co-authored-by: scoootscooob <167050519+scoootscooob@users.noreply.github.com>
Reviewed-by: @scoootscooob
This commit is contained in:
scoootscooob
2026-04-20 16:15:29 -07:00
committed by GitHub
parent 74178b37be
commit f700ad32a8
19 changed files with 51 additions and 39 deletions

View File

@@ -9,6 +9,7 @@ Docs: https://docs.openclaw.ai
- Plugins/tests: reuse plugin loader alias and Jiti config resolution across repeated same-context loads, reducing import-heavy test overhead. (#69316) Thanks @amknight.
- Cron: split runtime execution state into `jobs-state.json` so `jobs.json` stays stable for git-tracked job definitions. (#63105) Thanks @Feelw00.
- Agents/compaction: send opt-in start and completion notices during context compaction. (#67830) Thanks @feniix.
- Moonshot/Kimi: default bundled Moonshot setup, web search, and media-understanding surfaces to `kimi-k2.6` while keeping `kimi-k2.5` available for compatibility. (#69477) Thanks @scoootscooob.
### Fixes

View File

@@ -40,7 +40,7 @@ export default definePluginEntry({
providerId: PROVIDER_ID,
methodId: "api-key",
label: "Kimi Code API key (subscription)",
hint: "Kimi K2.5 + Kimi",
hint: "Kimi K2.6 + Kimi",
optionKey: "kimiCodeApiKey",
flagName: "--kimi-code-api-key",
envVar: "KIMI_API_KEY",
@@ -57,8 +57,8 @@ export default definePluginEntry({
choiceId: "kimi-code-api-key",
choiceLabel: "Kimi Code API key (subscription)",
groupId: "moonshot",
groupLabel: "Moonshot AI (Kimi K2.5)",
groupHint: "Kimi K2.5",
groupLabel: "Moonshot AI (Kimi K2.6)",
groupHint: "Kimi K2.6",
},
}),
],

View File

@@ -13,8 +13,8 @@
"choiceId": "kimi-code-api-key",
"choiceLabel": "Kimi Code API key (subscription)",
"groupId": "moonshot",
"groupLabel": "Moonshot AI (Kimi K2.5)",
"groupHint": "Kimi K2.5",
"groupLabel": "Moonshot AI (Kimi K2.6)",
"groupHint": "Kimi K2.6",
"optionKey": "kimiCodeApiKey",
"cliFlag": "--kimi-code-api-key",
"cliOption": "--kimi-code-api-key <key>",

View File

@@ -12,7 +12,7 @@ describe("moonshot provider plugin", () => {
provider.buildReplayPolicy?.({
provider: "moonshot",
modelApi: "openai-completions",
modelId: "kimi-k2.5",
modelId: "kimi-k2.6",
} as never),
).toMatchObject({
sanitizeToolCallIds: true,
@@ -29,7 +29,7 @@ describe("moonshot provider plugin", () => {
const wrapped = provider.wrapStreamFn?.({
provider: "moonshot",
modelId: "kimi-k2.5",
modelId: "kimi-k2.6",
thinkingLevel: "off",
streamFn: capturedStream.streamFn,
} as never);
@@ -38,7 +38,7 @@ describe("moonshot provider plugin", () => {
{
api: "openai-completions",
provider: "moonshot",
id: "kimi-k2.5",
id: "kimi-k2.6",
} as Model<"openai-completions">,
{ messages: [] } as Context,
{},

View File

@@ -24,7 +24,7 @@ export default defineSingleProviderPluginEntry({
{
methodId: "api-key",
label: "Kimi API key (.ai)",
hint: "Kimi K2.5 + Kimi",
hint: "Kimi K2.6 + Kimi",
optionKey: "moonshotApiKey",
flagName: "--moonshot-api-key",
envVar: "MOONSHOT_API_KEY",
@@ -32,13 +32,13 @@ export default defineSingleProviderPluginEntry({
defaultModel: MOONSHOT_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyMoonshotConfig(cfg),
wizard: {
groupLabel: "Moonshot AI (Kimi K2.5)",
groupLabel: "Moonshot AI (Kimi K2.6)",
},
},
{
methodId: "api-key-cn",
label: "Kimi API key (.cn)",
hint: "Kimi K2.5 + Kimi",
hint: "Kimi K2.6 + Kimi",
optionKey: "moonshotApiKey",
flagName: "--moonshot-api-key",
envVar: "MOONSHOT_API_KEY",
@@ -46,7 +46,7 @@ export default defineSingleProviderPluginEntry({
defaultModel: MOONSHOT_DEFAULT_MODEL_REF,
applyConfig: (cfg) => applyMoonshotConfigCn(cfg),
wizard: {
groupLabel: "Moonshot AI (Kimi K2.5)",
groupLabel: "Moonshot AI (Kimi K2.6)",
},
},
],

View File

@@ -19,14 +19,14 @@ describe("describeMoonshotVideo", () => {
apiKey: "moonshot-test",
timeoutMs: 1500,
baseUrl: "https://api.moonshot.ai/v1/",
model: "kimi-k2.5",
model: "kimi-k2.6",
headers: { "X-Trace": "1" },
fetchFn,
});
const { url, init } = getRequest();
expect(result.text).toBe("video ok");
expect(result.model).toBe("kimi-k2.5");
expect(result.model).toBe("kimi-k2.6");
expect(url).toBe("https://api.moonshot.ai/v1/chat/completions");
expect(init?.method).toBe("POST");
expect(init?.signal).toBeInstanceOf(AbortSignal);
@@ -42,7 +42,7 @@ describe("describeMoonshotVideo", () => {
content?: Array<{ type?: string; text?: string; video_url?: { url?: string } }>;
}>;
};
expect(body.model).toBe("kimi-k2.5");
expect(body.model).toBe("kimi-k2.6");
expect(body.messages?.[0]?.content?.[0]).toMatchObject({
type: "text",
text: "Describe the video.",
@@ -67,6 +67,6 @@ describe("describeMoonshotVideo", () => {
});
expect(result.text).toBe("reasoned answer");
expect(result.model).toBe("kimi-k2.5");
expect(result.model).toBe("kimi-k2.6");
});
});

View File

@@ -14,9 +14,10 @@ import {
postJsonRequest,
resolveProviderHttpRequestConfig,
} from "openclaw/plugin-sdk/provider-http";
import { MOONSHOT_DEFAULT_MODEL_ID } from "./provider-catalog.js";
export const DEFAULT_MOONSHOT_VIDEO_BASE_URL = "https://api.moonshot.ai/v1";
const DEFAULT_MOONSHOT_VIDEO_MODEL = "kimi-k2.5";
const DEFAULT_MOONSHOT_VIDEO_MODEL = MOONSHOT_DEFAULT_MODEL_ID;
const DEFAULT_MOONSHOT_VIDEO_PROMPT = "Describe the video.";
export async function describeMoonshotVideo(
@@ -76,7 +77,7 @@ export async function describeMoonshotVideo(
export const moonshotMediaUnderstandingProvider: MediaUnderstandingProvider = {
id: "moonshot",
capabilities: ["image", "video"],
defaultModels: { image: "kimi-k2.5", video: DEFAULT_MOONSHOT_VIDEO_MODEL },
defaultModels: { image: MOONSHOT_DEFAULT_MODEL_ID, video: DEFAULT_MOONSHOT_VIDEO_MODEL },
autoPriority: { video: 20 },
describeImage: describeImageWithModel,
describeImages: describeImagesWithModel,

View File

@@ -12,8 +12,8 @@
"choiceId": "moonshot-api-key",
"choiceLabel": "Moonshot API key (.ai)",
"groupId": "moonshot",
"groupLabel": "Moonshot AI (Kimi K2.5)",
"groupHint": "Kimi K2.5",
"groupLabel": "Moonshot AI (Kimi K2.6)",
"groupHint": "Kimi K2.6",
"optionKey": "moonshotApiKey",
"cliFlag": "--moonshot-api-key",
"cliOption": "--moonshot-api-key <key>",
@@ -25,8 +25,8 @@
"choiceId": "moonshot-api-key-cn",
"choiceLabel": "Moonshot API key (.cn)",
"groupId": "moonshot",
"groupLabel": "Moonshot AI (Kimi K2.5)",
"groupHint": "Kimi K2.5",
"groupLabel": "Moonshot AI (Kimi K2.6)",
"groupHint": "Kimi K2.6",
"optionKey": "moonshotApiKey",
"cliFlag": "--moonshot-api-key",
"cliOption": "--moonshot-api-key <key>",

View File

@@ -13,6 +13,7 @@ describe("moonshot provider catalog", () => {
expect(provider.baseUrl).toBe(MOONSHOT_BASE_URL);
expect(provider.api).toBe("openai-completions");
expect(provider.models.map((model) => model.id)).toEqual([
"kimi-k2.6",
"kimi-k2.5",
"kimi-k2-thinking",
"kimi-k2-thinking-turbo",

View File

@@ -6,7 +6,7 @@ import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-sha
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.5";
export const MOONSHOT_DEFAULT_MODEL_ID = "kimi-k2.6";
const MOONSHOT_DEFAULT_CONTEXT_WINDOW = 262144;
const MOONSHOT_DEFAULT_MAX_TOKENS = 262144;
const MOONSHOT_DEFAULT_COST = {
@@ -17,6 +17,15 @@ const MOONSHOT_DEFAULT_COST = {
};
const MOONSHOT_MODEL_CATALOG = [
{
id: "kimi-k2.6",
name: "Kimi K2.6",
reasoning: false,
input: ["text", "image"],
cost: MOONSHOT_DEFAULT_COST,
contextWindow: MOONSHOT_DEFAULT_CONTEXT_WINDOW,
maxTokens: MOONSHOT_DEFAULT_MAX_TOKENS,
},
{
id: "kimi-k2.5",
name: "Kimi K2.5",

View File

@@ -12,20 +12,20 @@ export function createMoonshotProvider(): ProviderPlugin {
id: "api-key",
kind: "api_key",
label: "Kimi API key (.ai)",
hint: "Kimi K2.5 + Kimi",
hint: "Kimi K2.6 + Kimi",
run: noopAuth,
wizard: {
groupLabel: "Moonshot AI (Kimi K2.5)",
groupLabel: "Moonshot AI (Kimi K2.6)",
},
},
{
id: "api-key-cn",
kind: "api_key",
label: "Kimi API key (.cn)",
hint: "Kimi K2.5 + Kimi",
hint: "Kimi K2.6 + Kimi",
run: noopAuth,
wizard: {
groupLabel: "Moonshot AI (Kimi K2.5)",
groupLabel: "Moonshot AI (Kimi K2.6)",
},
},
],

View File

@@ -34,7 +34,7 @@ const DEFAULT_KIMI_SEARCH_MODEL = MOONSHOT_DEFAULT_MODEL_ID;
* Reasoning variants (kimi-k2-thinking, kimi-k2-thinking-turbo) are excluded
* because they default to thinking-enabled and disabling it would defeat their
* purpose; they are also unlikely to be used for web search. */
const KIMI_THINKING_MODELS = new Set(["kimi-k2.5"]);
const KIMI_THINKING_MODELS = new Set(["kimi-k2.6", "kimi-k2.5"]);
const KIMI_WEB_SEARCH_TOOL = {
type: "builtin_function",
function: { name: "$web_search" },
@@ -262,7 +262,7 @@ export async function executeKimiWebSearchProviderTool(
ctx.searchConfig,
"kimi",
resolveProviderWebSearchPluginConfig(ctx.config, "moonshot"),
) as SearchConfigRecord | undefined;
);
const unsupportedResponse = buildUnsupportedSearchFilterResponse(args, "kimi");
if (unsupportedResponse) {
return unsupportedResponse;

View File

@@ -7,7 +7,7 @@ const kimiApiKeyEnv = ["KIMI_API", "KEY"].join("_");
describe("kimi web search provider", () => {
it("uses configured model and base url overrides with sane defaults", () => {
expect(__testing.resolveKimiModel()).toBe("kimi-k2.5");
expect(__testing.resolveKimiModel()).toBe("kimi-k2.6");
expect(__testing.resolveKimiModel({ model: "kimi-k2" })).toBe("kimi-k2");
expect(__testing.resolveKimiBaseUrl()).toBe("https://api.moonshot.ai/v1");
expect(__testing.resolveKimiBaseUrl({ baseUrl: "https://kimi.example/v1" })).toBe(

View File

@@ -12,8 +12,8 @@ function buildMoonshotProvider(): ModelProviderConfig {
api: "openai-completions",
models: [
{
id: "kimi-k2.5",
name: "Kimi K2.5",
id: "kimi-k2.6",
name: "Kimi K2.6",
reasoning: false,
input: ["text", "image"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },

View File

@@ -143,7 +143,7 @@ describe("buildAuthChoiceOptions", () => {
choiceId: "moonshot-api-key",
choiceLabel: "Kimi API key (.ai)",
groupId: "moonshot",
groupLabel: "Moonshot AI (Kimi K2.5)",
groupLabel: "Moonshot AI (Kimi K2.6)",
},
{
pluginId: "minimax",

View File

@@ -101,7 +101,7 @@ function createSearchProviderEntry(id: string): PluginWebSearchProviderEntry {
});
const webSearch = ensureWebSearchConfig(config, metadata.pluginId);
webSearch.baseUrl = baseUrl;
webSearch.model = modelChoice === "__keep__" ? "kimi-k2.5" : modelChoice;
webSearch.model = modelChoice === "__keep__" ? "kimi-k2.6" : modelChoice;
return config;
};
}
@@ -345,7 +345,7 @@ describe("setupSearch", () => {
expect(pluginWebSearchApiKey(kimiResult, "moonshot")).toBe("sk-moonshot");
expect(kimiResult.plugins?.entries?.moonshot?.enabled).toBe(true);
expect(kimiWebSearchConfig?.baseUrl).toBe("https://api.moonshot.ai/v1");
expect(kimiWebSearchConfig?.model).toBe("kimi-k2.5");
expect(kimiWebSearchConfig?.model).toBe("kimi-k2.6");
const disabledCfg = createDisabledFirecrawlConfig();
const { prompter: disabledPrompter } = createPrompter({

View File

@@ -58,7 +58,7 @@ const BUNDLED_MEDIA_PROVIDER_DEFAULTS: Record<string, BundledMediaProviderDefaul
autoPriority: { video: 15 },
},
moonshot: {
defaultModels: { image: "kimi-k2.5", video: "kimi-k2.5" },
defaultModels: { image: "kimi-k2.6", video: "kimi-k2.6" },
autoPriority: { video: 20 },
},
openrouter: {

View File

@@ -20,7 +20,7 @@ describe("resolveDefaultMediaModel", () => {
"gpt-5.4",
);
expect(resolveDefaultMediaModel({ providerId: "moonshot", capability: "image" })).toBe(
"kimi-k2.5",
"kimi-k2.6",
);
expect(resolveDefaultMediaModel({ providerId: "openrouter", capability: "image" })).toBe(
"auto",

View File

@@ -93,8 +93,8 @@ export const pluginRegistrationContractCases = {
choiceId: "kimi-code-api-key",
choiceLabel: "Kimi Code API key (subscription)",
groupId: "moonshot",
groupLabel: "Moonshot AI (Kimi K2.5)",
groupHint: "Kimi K2.5",
groupLabel: "Moonshot AI (Kimi K2.6)",
groupHint: "Kimi K2.6",
},
},
openai: {