mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-20 22:22:57 +03:00
fix(providers): cap grok-cli tools at 200 for cli-chat-proxy (#6986)
* fix(providers): cap grok-cli tools at 200 for cli-chat-proxy xAI's cli-chat-proxy enforces a hard limit of 200 tools per request and returns a 400 above that ceiling. A client fanning a large MCP toolset through Grok Build/Composer (e.g. Claude Code with many registered tools) can exceed it. transformRequest() now caps the tools array defensively before forwarding, and the grok-cli registry entries are annotated supportsReasoning:false to document the existing (already unconditional) reasoning_effort/reasoning strip for these two models. Co-authored-by: Joseph Yaksich <294273268+gitcommit90@users.noreply.github.com> Inspired-by: https://github.com/decolua/9router/pull/2534 * chore(changelog): fragment for #6986 --------- Co-authored-by: Joseph Yaksich <294273268+gitcommit90@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
32dd3a8249
commit
d06151bd86
1
changelog.d/fixes/6986-grok-cli-tools-cap.md
Normal file
1
changelog.d/fixes/6986-grok-cli-tools-cap.md
Normal file
@@ -0,0 +1 @@
|
||||
- **fix(providers):** cap grok-cli tools at 200 per request, matching xAI's cli-chat-proxy limit, and document the non-reasoning capability of grok-build/grok-composer-2.5-fast in the registry (#6986, thanks @gitcommit90)
|
||||
@@ -15,6 +15,9 @@ export const grok_cliProvider: RegistryEntry = {
|
||||
id: "grok-build",
|
||||
name: "Grok Build",
|
||||
contextLength: 256000,
|
||||
// cli-chat-proxy rejects reasoning_effort/reasoning outright (see grok-cli.ts
|
||||
// executor's transformRequest, which strips them unconditionally for this model).
|
||||
supportsReasoning: false,
|
||||
unsupportedParams: [
|
||||
"presencePenalty",
|
||||
"frequencyPenalty",
|
||||
@@ -27,6 +30,9 @@ export const grok_cliProvider: RegistryEntry = {
|
||||
id: "grok-composer-2.5-fast",
|
||||
name: "Grok Composer 2.5 Fast",
|
||||
contextLength: 200000,
|
||||
// cli-chat-proxy rejects reasoning_effort/reasoning outright (see grok-cli.ts
|
||||
// executor's transformRequest, which strips them unconditionally for this model).
|
||||
supportsReasoning: false,
|
||||
unsupportedParams: [
|
||||
"presencePenalty",
|
||||
"frequencyPenalty",
|
||||
|
||||
@@ -21,6 +21,8 @@ import { HttpsProxyAgent } from "https-proxy-agent";
|
||||
|
||||
const GROK_TOKEN_URL = "https://auth.x.ai/oauth2/token";
|
||||
const REQUEST_TIMEOUT_MS = 60_000;
|
||||
// xAI cli-chat-proxy hard limit on tools per request.
|
||||
const MAX_TOOLS = 200;
|
||||
|
||||
type ProxyResolution = { source: string; proxyUrl: string | null };
|
||||
type GrokRequestDispatch = { agent?: https.Agent; family?: 4 };
|
||||
@@ -310,6 +312,14 @@ export class GrokCliExecutor extends BaseExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
// xAI's cli-chat-proxy enforces a maximum of 200 tools per request and
|
||||
// 400s above that ceiling. Clients that fan a large MCP toolset through
|
||||
// Grok Build/Composer (e.g. Claude Code with many registered tools) can
|
||||
// exceed it — cap defensively rather than let the request fail upstream.
|
||||
if (Array.isArray(transformed.tools) && transformed.tools.length > MAX_TOOLS) {
|
||||
transformed.tools = transformed.tools.slice(0, MAX_TOOLS);
|
||||
}
|
||||
|
||||
return transformed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,3 +51,40 @@ test("#5273 grok-cli transformRequest leaves a clean body unchanged (no false st
|
||||
assert.equal(out.model, "grok-composer-2.5-fast");
|
||||
assert.equal(out.stream, true);
|
||||
});
|
||||
|
||||
// Ported from decolua/9router#2534 (@gitcommit90): xAI's cli-chat-proxy enforces a
|
||||
// hard cap of 200 tools per request and 400s above it. Clients that fan a large MCP
|
||||
// toolset through Grok Build/Composer can exceed that ceiling — transformRequest()
|
||||
// must cap defensively instead of forwarding an oversized array upstream.
|
||||
test("2534 grok-cli transformRequest caps tools at 200", () => {
|
||||
const executor = new GrokCliExecutor();
|
||||
const tools = Array.from({ length: 250 }, (_, i) => ({
|
||||
type: "function",
|
||||
function: { name: `tool_${i}` },
|
||||
}));
|
||||
const out = executor.transformRequest(
|
||||
"grok-build",
|
||||
{ messages: [{ role: "user", content: "hi" }], tools },
|
||||
false,
|
||||
{} as never
|
||||
) as Record<string, unknown>;
|
||||
|
||||
assert.equal((out.tools as unknown[]).length, 200);
|
||||
assert.deepEqual(out.tools, tools.slice(0, 200));
|
||||
});
|
||||
|
||||
test("2534 grok-cli transformRequest leaves a tools array under the cap untouched", () => {
|
||||
const executor = new GrokCliExecutor();
|
||||
const tools = Array.from({ length: 10 }, (_, i) => ({
|
||||
type: "function",
|
||||
function: { name: `tool_${i}` },
|
||||
}));
|
||||
const out = executor.transformRequest(
|
||||
"grok-composer-2.5-fast",
|
||||
{ messages: [{ role: "user", content: "hi" }], tools },
|
||||
false,
|
||||
{} as never
|
||||
) as Record<string, unknown>;
|
||||
|
||||
assert.deepEqual(out.tools, tools);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user