mirror of
https://github.com/badlogic/pi-mono.git
synced 2026-11-05 23:37:25 +00:00
fix(ai): send max_tokens to DeepSeek APIs
Auto-detect DeepSeek in generated and runtime compatibility metadata so built-in and custom models use the supported token limit field.
This commit is contained in:
parent
368e013dec
commit
c185d41238
4 changed files with 53 additions and 3 deletions
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
- Fixed upstream request buffer limit failures to trigger automatic assistant retries.
|
||||
- Fixed OpenAI Responses function and custom tool calls to preserve namespaces during streaming, proxying, and replay ([#7709](https://github.com/earendil-works/pi/issues/7709)).
|
||||
- Fixed built-in and custom DeepSeek API models to send output limits through the supported `max_tokens` field.
|
||||
|
||||
## [0.84.1] - 2026-08-07
|
||||
|
||||
|
|
|
|||
|
|
@ -643,11 +643,18 @@ function detectOpenAICompletionsCompat(model: Model<"openai-completions">): Open
|
|||
isCloudflareAiGateway ||
|
||||
isAntLing;
|
||||
|
||||
const isDeepSeek = provider === "deepseek" || baseUrl.includes("deepseek.com");
|
||||
const useMaxTokens =
|
||||
baseUrl.includes("chutes.ai") || isMoonshot || isCloudflareAiGateway || isTogether || isNvidia || isAntLing || isZai;
|
||||
baseUrl.includes("chutes.ai") ||
|
||||
isDeepSeek ||
|
||||
isMoonshot ||
|
||||
isCloudflareAiGateway ||
|
||||
isTogether ||
|
||||
isNvidia ||
|
||||
isAntLing ||
|
||||
isZai;
|
||||
|
||||
const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
|
||||
const isDeepSeek = provider === "deepseek" || baseUrl.includes("deepseek.com");
|
||||
const isOpenRouterDeveloperRoleModel =
|
||||
isOpenRouter && (model.id.startsWith("anthropic/") || model.id.startsWith("openai/"));
|
||||
const cacheControlFormat =
|
||||
|
|
|
|||
|
|
@ -1475,8 +1475,10 @@ function detectCompat(model: Model<"openai-completions">): ResolvedOpenAIComplet
|
|||
isCloudflareAiGateway ||
|
||||
isAntLing;
|
||||
|
||||
const isDeepSeek = provider === "deepseek" || baseUrl.includes("deepseek.com");
|
||||
const useMaxTokens =
|
||||
baseUrl.includes("chutes.ai") ||
|
||||
isDeepSeek ||
|
||||
isMoonshot ||
|
||||
isCloudflareAiGateway ||
|
||||
isTogether ||
|
||||
|
|
@ -1485,7 +1487,6 @@ function detectCompat(model: Model<"openai-completions">): ResolvedOpenAIComplet
|
|||
isZai;
|
||||
|
||||
const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
|
||||
const isDeepSeek = provider === "deepseek" || baseUrl.includes("deepseek.com");
|
||||
const isOpenRouterDeveloperRoleModel =
|
||||
isOpenRouter && (model.id.startsWith("anthropic/") || model.id.startsWith("openai/"));
|
||||
const cacheControlFormat = provider === "openrouter" && model.id.startsWith("anthropic/") ? "anthropic" : undefined;
|
||||
|
|
|
|||
|
|
@ -1429,6 +1429,47 @@ describe("openai-completions tool_choice", () => {
|
|||
}
|
||||
});
|
||||
|
||||
it("sends max_tokens for built-in and custom DeepSeek API models", async () => {
|
||||
const customModel = {
|
||||
...localOpenAICompletionsModel,
|
||||
id: "custom-deepseek-model",
|
||||
name: "Custom DeepSeek Model",
|
||||
provider: "custom-deepseek",
|
||||
baseUrl: "https://api.deepseek.com",
|
||||
} satisfies Model<"openai-completions">;
|
||||
const nativeModels = [
|
||||
getModel("deepseek", "deepseek-v4-flash")!,
|
||||
getModel("deepseek", "deepseek-v4-pro")!,
|
||||
] as const;
|
||||
const cases = [...nativeModels, customModel] as const;
|
||||
|
||||
for (const model of nativeModels) {
|
||||
expect(model.compat?.maxTokensField).toBe("max_tokens");
|
||||
}
|
||||
|
||||
for (const model of cases) {
|
||||
let payload: unknown;
|
||||
|
||||
await streamSimple(
|
||||
model,
|
||||
{
|
||||
messages: [{ role: "user", content: "Hi", timestamp: Date.now() }],
|
||||
},
|
||||
{
|
||||
apiKey: "test",
|
||||
maxTokens: 123,
|
||||
onPayload: (params: unknown) => {
|
||||
payload = params;
|
||||
},
|
||||
},
|
||||
).result();
|
||||
|
||||
const params = (payload ?? mockState.lastParams) as { max_tokens?: number; max_completion_tokens?: number };
|
||||
expect(params.max_tokens).toBe(123);
|
||||
expect(params.max_completion_tokens).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
it("sends max_tokens for Z.AI completions models", async () => {
|
||||
const cases = [getModel("zai", "glm-5-turbo")!, getModel("zai", "glm-5.2")!] as const;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue