From 987e47336484c0004f5147ec184e05a5991e3260 Mon Sep 17 00:00:00 2001 From: Sid Date: Thu, 5 Mar 2026 13:29:25 +0800 Subject: [PATCH] fix(agents): detect Venice provider proxying xAI/Grok models for schema cleaning (#35355) Merged via squash. Prepared head SHA: 8bfdec257bb6a6025cb69a0a213a433da32b15db Co-authored-by: Sid-Qin <201593046+Sid-Qin@users.noreply.github.com> Co-authored-by: shakkernerd <165377636+shakkernerd@users.noreply.github.com> Reviewed-by: @shakkernerd --- CHANGELOG.md | 1 + src/agents/schema/clean-for-xai.test.ts | 12 ++++++++++++ src/agents/schema/clean-for-xai.ts | 7 ++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2250b2135ff..c2b7ff16c54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Agents/schema cleaning: detect Venice + Grok model IDs as xAI-proxied targets so unsupported JSON Schema keywords are stripped before requests, preventing Venice/Grok `Invalid arguments` failures. (openclaw#35355) thanks @Sid-Qin. - Skills/native command deduplication: centralize skill command dedupe by canonical `skillName` in `listSkillCommandsForAgents` so duplicate suffixed variants (for example `_2`) are no longer surfaced across interfaces outside Discord. (#27521) thanks @shivama205. - Feishu/streaming card delivery synthesis: unify snapshot and delta streaming merge semantics, apply overlap-aware final merge, suppress duplicate final text delivery (including text+media final packets), prefer topic-thread `message.reply` routing when a reply target exists, and tune card print cadence to avoid duplicate incremental rendering. (from #33245, #32896, #33840) Thanks @rexl2018, @kcinzgg, and @aerelune. - Security/dependency audit: patch transitive Hono vulnerabilities by pinning `hono` to `4.12.5` and `@hono/node-server` to `1.19.10` in production resolution paths. Thanks @shakkernerd. diff --git a/src/agents/schema/clean-for-xai.test.ts b/src/agents/schema/clean-for-xai.test.ts index a48cc99fbc2..6f9c316c784 100644 --- a/src/agents/schema/clean-for-xai.test.ts +++ b/src/agents/schema/clean-for-xai.test.ts @@ -29,6 +29,18 @@ describe("isXaiProvider", () => { it("handles undefined provider", () => { expect(isXaiProvider(undefined)).toBe(false); }); + + it("matches venice provider with grok model id", () => { + expect(isXaiProvider("venice", "grok-4.1-fast")).toBe(true); + }); + + it("matches venice provider with venice/ prefixed grok model id", () => { + expect(isXaiProvider("venice", "venice/grok-4.1-fast")).toBe(true); + }); + + it("does not match venice provider with non-grok model id", () => { + expect(isXaiProvider("venice", "llama-3.3-70b")).toBe(false); + }); }); describe("stripXaiUnsupportedKeywords", () => { diff --git a/src/agents/schema/clean-for-xai.ts b/src/agents/schema/clean-for-xai.ts index b18b5746371..f11f82629da 100644 --- a/src/agents/schema/clean-for-xai.ts +++ b/src/agents/schema/clean-for-xai.ts @@ -48,8 +48,13 @@ export function isXaiProvider(modelProvider?: string, modelId?: string): boolean if (provider.includes("xai") || provider.includes("x-ai")) { return true; } + const lowerModelId = modelId?.toLowerCase() ?? ""; // OpenRouter proxies to xAI when the model id starts with "x-ai/" - if (provider === "openrouter" && modelId?.toLowerCase().startsWith("x-ai/")) { + if (provider === "openrouter" && lowerModelId.startsWith("x-ai/")) { + return true; + } + // Venice proxies to xAI/Grok models + if (provider === "venice" && lowerModelId.includes("grok")) { return true; } return false;