mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
fix(ai): exclude Cerebras from supportsStrictMode (#9804)
Make strict mode as unsupported in cerebras, as mixed strict/unstrict tool usage doesn't work (400 from API), and extensions may define both strict and unstrict tools
This commit is contained in:
parent
0e283203c7
commit
af7359b904
3 changed files with 71 additions and 6 deletions
|
|
@ -670,13 +670,13 @@ function detectOpenAICompletionsCompat(model: Model<"openai-completions">): Open
|
|||
const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || baseUrl.includes("gateway.ai.cloudflare.com");
|
||||
const isNvidia = provider === "nvidia" || baseUrl.includes("integrate.api.nvidia.com");
|
||||
const isAntLing = provider === "ant-ling" || baseUrl.includes("api.ant-ling.com");
|
||||
const isCerebras = provider === "cerebras" || baseUrl.includes("cerebras.ai");
|
||||
const isTogetherReasoningOnly = isTogether && TOGETHER_REASONING_ONLY_MODELS.has(model.id);
|
||||
const isDeepSeek = provider === "deepseek" || baseUrl.toLowerCase().includes("deepseek.com");
|
||||
|
||||
const isNonStandard =
|
||||
isNvidia ||
|
||||
provider === "cerebras" ||
|
||||
baseUrl.includes("cerebras.ai") ||
|
||||
isCerebras ||
|
||||
provider === "xai" ||
|
||||
baseUrl.includes("api.x.ai") ||
|
||||
isTogether ||
|
||||
|
|
@ -734,7 +734,7 @@ function detectOpenAICompletionsCompat(model: Model<"openai-completions">): Open
|
|||
chatTemplateKwargs: {},
|
||||
chatTemplateArgs: {},
|
||||
zaiToolStream: false,
|
||||
supportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia,
|
||||
supportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia && !isCerebras,
|
||||
supportsOpenAIGrammarTools: false,
|
||||
supportsMidConvoSystemMessages: false,
|
||||
supportsMidConvoToolAdditions: false,
|
||||
|
|
|
|||
|
|
@ -1597,12 +1597,12 @@ function detectCompat(model: Model<"openai-completions">): ResolvedOpenAIComplet
|
|||
const isCloudflareAiGateway = provider === "cloudflare-ai-gateway" || baseUrl.includes("gateway.ai.cloudflare.com");
|
||||
const isNvidia = provider === "nvidia" || baseUrl.includes("integrate.api.nvidia.com");
|
||||
const isAntLing = provider === "ant-ling" || baseUrl.includes("api.ant-ling.com");
|
||||
const isCerebras = provider === "cerebras" || baseUrl.includes("cerebras.ai");
|
||||
const isDeepSeek = provider === "deepseek" || baseUrl.toLowerCase().includes("deepseek.com");
|
||||
|
||||
const isNonStandard =
|
||||
isNvidia ||
|
||||
provider === "cerebras" ||
|
||||
baseUrl.includes("cerebras.ai") ||
|
||||
isCerebras ||
|
||||
provider === "xai" ||
|
||||
baseUrl.includes("api.x.ai") ||
|
||||
isTogether ||
|
||||
|
|
@ -1661,7 +1661,7 @@ function detectCompat(model: Model<"openai-completions">): ResolvedOpenAIComplet
|
|||
zaiToolStream: false,
|
||||
supportsThinkingTokenBudget: false,
|
||||
thinkingTokenBudgetField: undefined,
|
||||
supportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia,
|
||||
supportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia && !isCerebras,
|
||||
supportsOpenAIGrammarTools: false,
|
||||
supportsMidConvoSystemMessages: false,
|
||||
supportsMidConvoToolAdditions: false,
|
||||
|
|
|
|||
|
|
@ -535,5 +535,70 @@ describe("Cache Retention (PI_CACHE_RETENTION)", () => {
|
|||
expect(capturedPayload?.prompt_cache_key).toBeUndefined();
|
||||
expect(capturedPayload?.prompt_cache_retention).toBeUndefined();
|
||||
});
|
||||
|
||||
it.each([MODELS.cerebras["gpt-oss-120b"], MODELS.cerebras["qwen-3.8-27b"]] as const)(
|
||||
"should omit strict field on tools for cerebras/$id",
|
||||
async (metadata) => {
|
||||
const model = metadata as Model<"openai-completions">;
|
||||
|
||||
const contextWithTools = {
|
||||
messages: [
|
||||
{
|
||||
role: "system" as const,
|
||||
content: "test",
|
||||
toolsAdded: [
|
||||
{
|
||||
name: "t1",
|
||||
description: "strict tool",
|
||||
parameters: {
|
||||
type: "object" as const,
|
||||
properties: { x: { type: "string" } },
|
||||
required: ["x"],
|
||||
},
|
||||
constrainedSampling: { type: "json_schema" as const },
|
||||
},
|
||||
{
|
||||
name: "t2",
|
||||
description: "non-strict tool",
|
||||
parameters: {
|
||||
type: "object" as const,
|
||||
properties: { y: { type: "string" } },
|
||||
required: ["y"],
|
||||
},
|
||||
},
|
||||
],
|
||||
timestamp: 0,
|
||||
},
|
||||
{ role: "user" as const, content: "hello", timestamp: 1 },
|
||||
],
|
||||
};
|
||||
|
||||
let capturedPayload: any;
|
||||
|
||||
try {
|
||||
const s = streamOpenAICompletions(model, contextWithTools as any, {
|
||||
apiKey: "fake-key",
|
||||
sessionId: "test",
|
||||
onPayload: stopAfterPayload((payload: any) => {
|
||||
capturedPayload = payload;
|
||||
}),
|
||||
});
|
||||
|
||||
for await (const event of s) {
|
||||
if (event.type === "error") break;
|
||||
}
|
||||
} catch {
|
||||
// Expected to fail
|
||||
}
|
||||
|
||||
expect(model.compat?.supportsStrictMode).toBe(false);
|
||||
expect(capturedPayload).toBeDefined();
|
||||
const tools = capturedPayload?.tools as any[] | undefined;
|
||||
expect(tools).toBeDefined();
|
||||
for (const tool of tools!) {
|
||||
expect(tool.function).not.toHaveProperty("strict");
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue