Moonshot: reuse native base URL for Kimi web search

This commit is contained in:
Gaston Rodriguez
2026-03-29 00:38:34 -03:00
committed by Peter Steinberger
parent e5d03f734a
commit b6b1d5dd6c
4 changed files with 70 additions and 5 deletions

View File

@@ -1,3 +1,4 @@
import type { OpenClawConfig } from "openclaw/plugin-sdk/provider-onboard";
import { withEnv } from "openclaw/plugin-sdk/testing";
import { describe, expect, it } from "vitest";
import { __testing } from "./kimi-web-search-provider.js";
@@ -14,6 +15,40 @@ describe("kimi web search provider", () => {
);
});
it("inherits native Moonshot chat baseUrl when kimi baseUrl is unset", () => {
const cnConfig = {
models: { providers: { moonshot: { baseUrl: "https://api.moonshot.cn/v1" } } },
} as unknown as OpenClawConfig;
const cnConfigWithTrailingSlash = {
models: { providers: { moonshot: { baseUrl: "https://api.moonshot.cn/v1/" } } },
} as unknown as OpenClawConfig;
expect(__testing.resolveKimiBaseUrl(undefined, cnConfig)).toBe("https://api.moonshot.cn/v1");
expect(__testing.resolveKimiBaseUrl(undefined, cnConfigWithTrailingSlash)).toBe(
"https://api.moonshot.cn/v1",
);
});
it("does not inherit non-native Moonshot baseUrl for web search", () => {
const proxyConfig = {
models: { providers: { moonshot: { baseUrl: "https://proxy.example/v1" } } },
} as unknown as OpenClawConfig;
expect(__testing.resolveKimiBaseUrl(undefined, proxyConfig)).toBe(
"https://api.moonshot.ai/v1",
);
});
it("keeps explicit kimi baseUrl over models.providers.moonshot.baseUrl", () => {
const moonshotConfig = {
models: { providers: { moonshot: { baseUrl: "https://api.moonshot.cn/v1" } } },
} as unknown as OpenClawConfig;
expect(
__testing.resolveKimiBaseUrl({ baseUrl: "https://api.moonshot.ai/v1" }, moonshotConfig),
).toBe("https://api.moonshot.ai/v1");
});
it("extracts unique citations from search results and tool call arguments", () => {
expect(
__testing.extractKimiCitations({

View File

@@ -1,4 +1,5 @@
import { Type } from "@sinclair/typebox";
import type { OpenClawConfig } from "openclaw/plugin-sdk/provider-onboard";
import {
buildSearchCacheKey,
buildUnsupportedSearchFilterResponse,
@@ -95,9 +96,28 @@ function resolveKimiModel(kimi?: KimiConfig): string {
return model || DEFAULT_KIMI_SEARCH_MODEL;
}
function resolveKimiBaseUrl(kimi?: KimiConfig): string {
const baseUrl = typeof kimi?.baseUrl === "string" ? kimi.baseUrl.trim() : "";
return baseUrl || DEFAULT_KIMI_BASE_URL;
function trimTrailingSlashes(url: string): string {
return url.replace(/\/+$/, "");
}
function resolveKimiBaseUrl(kimi?: KimiConfig, openClawConfig?: OpenClawConfig): string {
const explicitBaseUrl = typeof kimi?.baseUrl === "string" ? kimi.baseUrl.trim() : "";
if (explicitBaseUrl) {
return trimTrailingSlashes(explicitBaseUrl) || DEFAULT_KIMI_BASE_URL;
}
const moonshotBaseUrl = openClawConfig?.models?.providers?.moonshot?.baseUrl;
if (typeof moonshotBaseUrl === "string") {
const normalizedMoonshotBaseUrl = trimTrailingSlashes(moonshotBaseUrl.trim());
if (
normalizedMoonshotBaseUrl &&
isNativeMoonshotBaseUrl(normalizedMoonshotBaseUrl)
) {
return normalizedMoonshotBaseUrl;
}
}
return DEFAULT_KIMI_BASE_URL;
}
function extractKimiMessageText(message: KimiMessage | undefined): string | undefined {
@@ -259,7 +279,8 @@ function createKimiSchema() {
}
function createKimiToolDefinition(
searchConfig?: SearchConfigRecord,
searchConfig: SearchConfigRecord | undefined,
openClawConfig: OpenClawConfig | undefined,
): WebSearchProviderToolDefinition {
return {
description:
@@ -289,7 +310,7 @@ function createKimiToolDefinition(
searchConfig?.maxResults ??
undefined;
const model = resolveKimiModel(kimiConfig);
const baseUrl = resolveKimiBaseUrl(kimiConfig);
const baseUrl = resolveKimiBaseUrl(kimiConfig, openClawConfig);
const cacheKey = buildSearchCacheKey([
"kimi",
query,
@@ -445,6 +466,7 @@ export function createKimiWebSearchProvider(): WebSearchProviderPlugin {
"kimi",
resolveProviderWebSearchPluginConfig(ctx.config, "moonshot"),
) as SearchConfigRecord | undefined,
ctx.config,
),
};
}