mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-18 15:14:45 +00:00
fix(mcp): keep numeric bundle tool names provider-safe
This commit is contained in:
@@ -67,6 +67,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Models/OpenRouter: hide missing-auth direct provider rows in `/model status` when they are only duplicated by a nested OpenRouter model id such as `openrouter/google/...`, while preserving explicitly configured direct providers. Fixes #62317.
|
||||
- Models: preserve an explicitly selected provider/model such as `opencode-go/deepseek-v4-pro` when another provider owns the same bare model alias. Fixes #79325.
|
||||
- Models/config: explain missing `models.providers.<provider>.models[]` registration when a model exists only in `agents.defaults.models`, instead of returning a bare unknown-model error. Fixes #80089.
|
||||
- MCP/tools: prefix bundle MCP server/tool fragments that would start with digits, keeping generated tool names valid for Moonshot/Kimi and other strict providers. Fixes #79179.
|
||||
- Kimi Code: use Kimi's stable `kimi-for-coding` API model id in bundled catalog, onboarding, and docs while normalizing legacy `kimi-code` and `k2p5` refs. Fixes #79965.
|
||||
- Volcengine/Kimi: strip provider-unsupported tool schema length and item constraint keywords for direct and coding-plan models so hosted Kimi runs do not reject message tools with `minLength`. Fixes #38817.
|
||||
- DeepSeek: backfill V4 `reasoning_content` replay fields for unowned OpenAI-compatible proxy providers, preventing follow-up request failures outside the bundled DeepSeek and OpenRouter routes. Fixes #79608.
|
||||
|
||||
@@ -165,6 +165,8 @@ OpenClaw registers bundle MCP tools with provider-safe names in the form
|
||||
`memory_search` tool registers as `vigil-harbor__memory_search`.
|
||||
|
||||
- characters outside `A-Za-z0-9_-` are replaced with `-`
|
||||
- fragments that would start with a non-letter get a letter prefix, so numeric
|
||||
server keys such as `12306` become provider-safe tool prefixes
|
||||
- server prefixes are capped at 30 characters
|
||||
- full tool names are capped at 64 characters
|
||||
- empty server names fall back to `mcp`
|
||||
|
||||
@@ -14,6 +14,20 @@ describe("pi bundle MCP names", () => {
|
||||
expect(sanitizeServerName("vigil:harbor", usedNames)).toBe("vigil-harbor-2");
|
||||
});
|
||||
|
||||
it("keeps server and tool fragments provider-safe when they start with digits", () => {
|
||||
const usedNames = new Set<string>();
|
||||
const serverName = sanitizeServerName("12306", usedNames);
|
||||
|
||||
expect(serverName).toBe("mcp-12306");
|
||||
expect(
|
||||
buildSafeToolName({
|
||||
serverName,
|
||||
toolName: "2024-query",
|
||||
reservedNames: new Set(),
|
||||
}),
|
||||
).toBe(`mcp-12306${TOOL_NAME_SEPARATOR}tool-2024-query`);
|
||||
});
|
||||
|
||||
it("builds provider-safe tool names and avoids collisions", () => {
|
||||
const reservedNames = normalizeReservedToolNames(["memory__status"]);
|
||||
|
||||
|
||||
@@ -11,10 +11,11 @@ const TOOL_NAME_MAX_TOTAL = 64;
|
||||
function sanitizeToolFragment(raw: string, fallback: string, maxChars?: number): string {
|
||||
const cleaned = raw.trim().replace(TOOL_NAME_SAFE_RE, "-");
|
||||
const normalized = cleaned || fallback;
|
||||
const providerSafe = /^[A-Za-z]/.test(normalized) ? normalized : `${fallback}-${normalized}`;
|
||||
if (!maxChars) {
|
||||
return normalized;
|
||||
return providerSafe;
|
||||
}
|
||||
return normalized.length > maxChars ? normalized.slice(0, maxChars) : normalized;
|
||||
return providerSafe.length > maxChars ? providerSafe.slice(0, maxChars) : providerSafe;
|
||||
}
|
||||
|
||||
export function sanitizeServerName(raw: string, usedNames: Set<string>): string {
|
||||
|
||||
Reference in New Issue
Block a user