@openclaw/moonshot-provider 2026.9.8 → 2026.10.1-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
1
- import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
1
+ import { createLazyRuntimeMethod, createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
2
2
  import { createWebSearchProviderContractFields } from "openclaw/plugin-sdk/provider-web-search-config-contract";
3
3
  //#region extensions/moonshot/src/kimi-web-search-provider.ts
4
4
  const KIMI_CREDENTIAL_PATH = "plugins.entries.moonshot.config.webSearch.apiKey";
5
- const loadKimiWebSearchProviderRuntime = createLazyRuntimeModule(() => import("./kimi-web-search-provider.runtime-DRzTngzG.mjs"));
5
+ const loadKimiWebSearchProviderRuntime = createLazyRuntimeModule(() => import("./kimi-web-search-provider.runtime-f2NJlw96.mjs"));
6
6
  const KimiSearchSchema = {
7
7
  type: "object",
8
8
  properties: {
@@ -38,9 +38,6 @@ const KimiSearchSchema = {
38
38
  }
39
39
  }
40
40
  };
41
- async function runKimiSearchProviderSetup(ctx) {
42
- return await (await loadKimiWebSearchProviderRuntime()).runKimiSearchProviderSetup(ctx);
43
- }
44
41
  function createKimiWebSearchProvider() {
45
42
  return {
46
43
  id: "kimi",
@@ -62,7 +59,7 @@ function createKimiWebSearchProvider() {
62
59
  },
63
60
  configuredCredential: { pluginId: "moonshot" }
64
61
  }),
65
- runSetup: runKimiSearchProviderSetup,
62
+ runSetup: createLazyRuntimeMethod(loadKimiWebSearchProviderRuntime, (runtime) => runtime.runKimiSearchProviderSetup),
66
63
  createTool: (ctx) => ({
67
64
  description: "Search the web using Kimi by Moonshot. Returns AI-synthesized answers with citations from native $web_search.",
68
65
  parameters: KimiSearchSchema,
@@ -1,7 +1,7 @@
1
1
  import { MOONSHOT_BASE_URL, MOONSHOT_CN_BASE_URL, isNativeMoonshotBaseUrl } from "../provider-policy-api.js";
2
2
  import "../provider-catalog.js";
3
- import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
- import { createProviderHttpError, readProviderJsonObjectResponse } from "openclaw/plugin-sdk/provider-http";
3
+ import { asNonArrayRecord, isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
+ import { createProviderHttpError, normalizeBaseUrl, readProviderJsonObjectResponse } from "openclaw/plugin-sdk/provider-http";
5
5
  import { MAX_SEARCH_COUNT, buildSearchCacheKey, buildUnsupportedSearchFilterResponse, mergeScopedSearchConfig, readCachedSearchPayload, readConfiguredSecretString, readPositiveIntegerParam, readProviderEnvValue, readStringParam, resolveProviderWebSearchPluginConfig, resolveSearchCacheTtlMs, resolveSearchTimeoutSeconds, setProviderWebSearchPluginConfigValue, withTrustedWebSearchEndpoint, wrapWebContent, writeCachedSearchPayload } from "openclaw/plugin-sdk/provider-web-search";
6
6
  //#region extensions/moonshot/src/kimi-web-search-provider.runtime.ts
7
7
  const DEFAULT_KIMI_BASE_URL = MOONSHOT_BASE_URL;
@@ -15,25 +15,15 @@ const KIMI_WEB_SEARCH_TOOL = {
15
15
  function throwMalformedKimiResponse() {
16
16
  throw new Error("Kimi API error: malformed JSON response");
17
17
  }
18
- function resolveKimiConfig(searchConfig) {
19
- const kimi = searchConfig?.kimi;
20
- return kimi && typeof kimi === "object" && !Array.isArray(kimi) ? kimi : {};
21
- }
22
18
  function resolveKimiApiKey(kimi) {
23
19
  return readConfiguredSecretString(kimi?.apiKey, "plugins.entries.moonshot.config.webSearch.apiKey") ?? readProviderEnvValue(["KIMI_API_KEY", "MOONSHOT_API_KEY"]);
24
20
  }
25
- function resolveKimiModel(kimi) {
26
- return (normalizeOptionalString(kimi?.model) ?? "") || DEFAULT_KIMI_SEARCH_MODEL;
27
- }
28
- function trimTrailingSlashes(url) {
29
- return url.replace(/\/+$/, "");
30
- }
31
21
  function resolveKimiBaseUrl(kimi, openClawConfig) {
32
- const explicitBaseUrl = normalizeOptionalString(kimi?.baseUrl) ?? "";
33
- if (explicitBaseUrl) return trimTrailingSlashes(explicitBaseUrl) || DEFAULT_KIMI_BASE_URL;
22
+ const explicitBaseUrl = normalizeOptionalString(kimi?.baseUrl);
23
+ if (explicitBaseUrl) return normalizeBaseUrl(explicitBaseUrl) || DEFAULT_KIMI_BASE_URL;
34
24
  const moonshotBaseUrl = openClawConfig?.models?.providers?.moonshot?.baseUrl;
35
25
  if (typeof moonshotBaseUrl === "string") {
36
- const normalizedMoonshotBaseUrl = trimTrailingSlashes(moonshotBaseUrl.trim());
26
+ const normalizedMoonshotBaseUrl = normalizeBaseUrl(moonshotBaseUrl);
37
27
  if (normalizedMoonshotBaseUrl && isNativeMoonshotBaseUrl(normalizedMoonshotBaseUrl)) return normalizedMoonshotBaseUrl;
38
28
  }
39
29
  return DEFAULT_KIMI_BASE_URL;
@@ -43,18 +33,11 @@ function extractKimiMessageText(message) {
43
33
  if (content) return content;
44
34
  return message?.reasoning_content?.trim() || void 0;
45
35
  }
46
- function collectKimiCitations(data, citations) {
47
- const searchResults = data.search_results ?? [];
48
- if (!Array.isArray(searchResults)) throwMalformedKimiResponse();
36
+ function collectKimiCitations(searchResults, toolCalls, citations) {
49
37
  for (const entry of searchResults) {
50
38
  const url = isRecord(entry) && typeof entry.url === "string" ? entry.url.trim() : "";
51
39
  if (url) citations.add(url);
52
40
  }
53
- const choices = data.choices ?? [];
54
- if (!Array.isArray(choices)) throwMalformedKimiResponse();
55
- const firstChoice = choices[0];
56
- const toolCalls = (firstChoice && isRecord(firstChoice.message) ? firstChoice.message : void 0)?.tool_calls ?? [];
57
- if (!Array.isArray(toolCalls)) throwMalformedKimiResponse();
58
41
  for (const toolCall of toolCalls) {
59
42
  if (!isRecord(toolCall) || !isRecord(toolCall.function)) continue;
60
43
  const rawArguments = toolCall.function.arguments;
@@ -70,9 +53,7 @@ function collectKimiCitations(data, citations) {
70
53
  } catch {}
71
54
  }
72
55
  }
73
- function hasKimiSearchResults(data) {
74
- const searchResults = data.search_results ?? [];
75
- if (!Array.isArray(searchResults)) throwMalformedKimiResponse();
56
+ function hasKimiSearchResults(searchResults) {
76
57
  return searchResults.some((entry) => isRecord(entry) && (Boolean(normalizeOptionalString(entry.url)) || Boolean(normalizeOptionalString(entry.title)) || Boolean(normalizeOptionalString(entry.content))));
77
58
  }
78
59
  function extractKimiToolResultContent(toolCall) {
@@ -110,53 +91,46 @@ async function runKimiSearch(params) {
110
91
  if (!res.ok) throw await createProviderHttpError(res, "Kimi API error");
111
92
  const data = await readProviderJsonObjectResponse(res, "Kimi API error");
112
93
  if (!Array.isArray(data.choices)) throwMalformedKimiResponse();
113
- if (hasKimiSearchResults(data)) hasGroundingEvidence = true;
114
- collectKimiCitations(data, collectedCitations);
115
- if (collectedCitations.size > 0) hasGroundingEvidence = true;
116
- const choice = data.choices?.[0];
94
+ const searchResults = data.search_results ?? [];
95
+ if (!Array.isArray(searchResults)) throwMalformedKimiResponse();
96
+ const choice = data.choices[0];
117
97
  if (!isRecord(choice) || !isRecord(choice.message)) throwMalformedKimiResponse();
118
- const message = choice?.message;
119
- const text = extractKimiMessageText(message);
120
- const toolCalls = message?.tool_calls ?? [];
98
+ const message = choice.message;
99
+ const toolCalls = message.tool_calls ?? [];
121
100
  if (!Array.isArray(toolCalls)) throwMalformedKimiResponse();
122
- if (choice?.finish_reason !== "tool_calls" || toolCalls.length === 0) {
123
- if (!text) throwMalformedKimiResponse();
124
- return {
125
- done: true,
126
- content: text,
127
- citations: [...collectedCitations]
128
- };
129
- }
130
- messages.push({
131
- role: "assistant",
132
- content: message?.content ?? "",
133
- ...message?.reasoning_content ? { reasoning_content: message.reasoning_content } : {},
134
- tool_calls: toolCalls
135
- });
136
- let pushed = false;
137
- for (const toolCall of toolCalls) {
138
- const toolCallId = toolCall.id?.trim();
139
- const toolCallName = toolCall.function?.name?.trim();
140
- const toolContent = extractKimiToolResultContent(toolCall);
141
- if (!toolCallId || !toolCallName || !toolContent) continue;
142
- if (toolCallName === KIMI_WEB_SEARCH_TOOL.function.name) hasGroundingEvidence = true;
143
- pushed = true;
101
+ collectKimiCitations(searchResults, toolCalls, collectedCitations);
102
+ hasGroundingEvidence ||= hasKimiSearchResults(searchResults) || collectedCitations.size > 0;
103
+ const text = extractKimiMessageText(message);
104
+ if (choice.finish_reason === "tool_calls" && toolCalls.length > 0) {
144
105
  messages.push({
145
- role: "tool",
146
- tool_call_id: toolCallId,
147
- name: toolCallName,
148
- content: toolContent
106
+ role: "assistant",
107
+ content: message.content ?? "",
108
+ ...message.reasoning_content ? { reasoning_content: message.reasoning_content } : {},
109
+ tool_calls: toolCalls
149
110
  });
111
+ let pushed = false;
112
+ for (const toolCall of toolCalls) {
113
+ const toolCallId = toolCall.id?.trim();
114
+ const toolCallName = toolCall.function?.name?.trim();
115
+ const toolContent = extractKimiToolResultContent(toolCall);
116
+ if (!toolCallId || !toolCallName || !toolContent) continue;
117
+ if (toolCallName === KIMI_WEB_SEARCH_TOOL.function.name) hasGroundingEvidence = true;
118
+ pushed = true;
119
+ messages.push({
120
+ role: "tool",
121
+ tool_call_id: toolCallId,
122
+ name: toolCallName,
123
+ content: toolContent
124
+ });
125
+ }
126
+ if (pushed) return { done: false };
150
127
  }
151
- if (!pushed) {
152
- if (!text) throwMalformedKimiResponse();
153
- return {
154
- done: true,
155
- content: text,
156
- citations: [...collectedCitations]
157
- };
158
- }
159
- return { done: false };
128
+ if (!text) throwMalformedKimiResponse();
129
+ return {
130
+ done: true,
131
+ content: text,
132
+ citations: [...collectedCitations]
133
+ };
160
134
  });
161
135
  if (next.done) return {
162
136
  content: next.content,
@@ -171,7 +145,7 @@ async function executeKimiWebSearchProviderTool(ctx, args, opts) {
171
145
  const searchConfig = mergeScopedSearchConfig(ctx.searchConfig, "kimi", resolveProviderWebSearchPluginConfig(ctx.config, "moonshot"));
172
146
  const unsupportedResponse = buildUnsupportedSearchFilterResponse(args, "kimi");
173
147
  if (unsupportedResponse) return unsupportedResponse;
174
- const kimiConfig = resolveKimiConfig(searchConfig);
148
+ const kimiConfig = asNonArrayRecord(searchConfig?.kimi);
175
149
  const apiKey = resolveKimiApiKey(kimiConfig);
176
150
  if (!apiKey) return {
177
151
  error: "missing_kimi_api_key",
@@ -183,7 +157,7 @@ async function executeKimiWebSearchProviderTool(ctx, args, opts) {
183
157
  max: MAX_SEARCH_COUNT,
184
158
  message: `count must be an integer from 1 to ${MAX_SEARCH_COUNT}.`
185
159
  });
186
- const model = resolveKimiModel(kimiConfig);
160
+ const model = normalizeOptionalString(kimiConfig.model) ?? DEFAULT_KIMI_SEARCH_MODEL;
187
161
  const baseUrl = resolveKimiBaseUrl(kimiConfig, ctx.config);
188
162
  const cacheKey = buildSearchCacheKey([
189
163
  "kimi",
@@ -232,7 +206,7 @@ async function executeKimiWebSearchProviderTool(ctx, args, opts) {
232
206
  }
233
207
  async function runKimiSearchProviderSetup(ctx) {
234
208
  const existingPluginConfig = resolveProviderWebSearchPluginConfig(ctx.config, "moonshot");
235
- const normalizedBaseUrl = (normalizeOptionalString(existingPluginConfig?.baseUrl) ?? "").replace(/\/+$/, "");
209
+ const normalizedBaseUrl = normalizeBaseUrl(normalizeOptionalString(existingPluginConfig?.baseUrl));
236
210
  const existingModel = normalizeOptionalString(existingPluginConfig?.model) ?? "";
237
211
  const isCustomBaseUrl = normalizedBaseUrl && !isNativeMoonshotBaseUrl(normalizedBaseUrl);
238
212
  const regionOptions = [];
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { MOONSHOT_DEFAULT_MODEL_REF, buildMoonshotProvider } from "./provider-ca
4
4
  import { moonshotMediaUnderstandingProvider } from "./media-understanding-provider.js";
5
5
  import { wrapMoonshotStream } from "./native-video.js";
6
6
  import { applyMoonshotConfig, applyMoonshotConfigCn } from "./onboard.js";
7
- import { t as createKimiWebSearchProvider } from "./.setup/kimi-web-search-provider-c6i-_MVz.mjs";
7
+ import { t as createKimiWebSearchProvider } from "./.setup/kimi-web-search-provider-u4LLc55G.mjs";
8
8
  import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
9
9
  import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
10
10
  import { buildOpenAICompatibleReplayPolicy } from "openclaw/plugin-sdk/provider-model-shared";
@@ -54,7 +54,7 @@ var moonshot_default = defineSingleProviderPluginEntry({
54
54
  duplicateToolCallIdStyle: "openai",
55
55
  dropReasoningFromHistory: false
56
56
  }),
57
- wrapStreamFn: (ctx) => wrapMoonshotStream(ctx),
57
+ wrapStreamFn: wrapMoonshotStream,
58
58
  wrapSimpleCompletionStreamFn: (ctx) => wrapMoonshotStream(ctx, true),
59
59
  resolveThinkingProfile,
60
60
  isModernModelRef: ({ modelId }) => isMoonshotAlwaysThinkingModelId(modelId)
@@ -6,16 +6,6 @@ import { describeOpenAiCompatibleVideo } from "openclaw/plugin-sdk/media-underst
6
6
  const DEFAULT_MOONSHOT_IMAGE_MODEL = openclaw_plugin_default.mediaUnderstandingProviderMetadata.moonshot.defaultModels.image;
7
7
  const DEFAULT_MOONSHOT_VIDEO_MODEL = openclaw_plugin_default.mediaUnderstandingProviderMetadata.moonshot.defaultModels.video;
8
8
  const DEFAULT_MOONSHOT_VIDEO_PROMPT = "Describe the video.";
9
- async function describeMoonshotVideo(params) {
10
- return describeOpenAiCompatibleVideo({
11
- ...params,
12
- defaultBaseUrl: MOONSHOT_BASE_URL,
13
- defaultModel: DEFAULT_MOONSHOT_VIDEO_MODEL,
14
- defaultPrompt: DEFAULT_MOONSHOT_VIDEO_PROMPT,
15
- provider: "moonshot",
16
- providerLabel: "Moonshot"
17
- });
18
- }
19
9
  const moonshotMediaUnderstandingProvider = {
20
10
  id: "moonshot",
21
11
  capabilities: ["image", "video"],
@@ -26,7 +16,14 @@ const moonshotMediaUnderstandingProvider = {
26
16
  autoPriority: { video: 20 },
27
17
  describeImage: void 0,
28
18
  describeImages: void 0,
29
- describeVideo: describeMoonshotVideo
19
+ describeVideo: async (params) => describeOpenAiCompatibleVideo({
20
+ ...params,
21
+ defaultBaseUrl: MOONSHOT_BASE_URL,
22
+ defaultModel: DEFAULT_MOONSHOT_VIDEO_MODEL,
23
+ defaultPrompt: DEFAULT_MOONSHOT_VIDEO_PROMPT,
24
+ provider: "moonshot",
25
+ providerLabel: "Moonshot"
26
+ })
30
27
  };
31
28
  //#endregion
32
29
  export { moonshotMediaUnderstandingProvider };
@@ -1,3 +1,3 @@
1
- import { t as createKimiWebSearchProvider } from "./.setup/kimi-web-search-provider-c6i-_MVz.mjs";
1
+ import { t as createKimiWebSearchProvider } from "./.setup/kimi-web-search-provider-u4LLc55G.mjs";
2
2
  import "./web-search-provider.js";
3
3
  export { createKimiWebSearchProvider };
@@ -1,2 +1,2 @@
1
- import { t as createKimiWebSearchProvider } from "./.setup/kimi-web-search-provider-c6i-_MVz.mjs";
1
+ import { t as createKimiWebSearchProvider } from "./.setup/kimi-web-search-provider-u4LLc55G.mjs";
2
2
  export { createKimiWebSearchProvider };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/moonshot-provider",
3
- "version": "2026.9.8",
3
+ "version": "2026.10.1-beta.1",
4
4
  "description": "OpenClaw Moonshot provider plugin",
5
5
  "type": "module",
6
6
  "openclaw": {
@@ -14,10 +14,10 @@
14
14
  "minHostVersion": ">=2026.6.9"
15
15
  },
16
16
  "compat": {
17
- "pluginApi": ">=2026.9.8"
17
+ "pluginApi": ">=2026.10.1-beta.1"
18
18
  },
19
19
  "build": {
20
- "openclawVersion": "2026.9.8",
20
+ "openclawVersion": "2026.10.1-beta.1",
21
21
  "bundledDist": false
22
22
  },
23
23
  "release": {
@@ -40,7 +40,7 @@
40
40
  "assets/activity.svg"
41
41
  ],
42
42
  "peerDependencies": {
43
- "openclaw": ">=2026.9.8"
43
+ "openclaw": ">=2026.10.1-beta.1"
44
44
  },
45
45
  "peerDependenciesMeta": {
46
46
  "openclaw": {