fix(provider): preserve Alibaba DeepSeek effort
This commit is contained in:
parent
743f6410f2
commit
5ae20dfe93
4 changed files with 88 additions and 8 deletions
|
|
@ -1686,7 +1686,13 @@ const layer = Layer.effect(
|
|||
delete options.fetch
|
||||
}
|
||||
|
||||
if (model.api.npm.includes("@ai-sdk/openai-compatible") && options["includeUsage"] !== false) {
|
||||
// Alibaba's SDK does not expose DeepSeek V4's native reasoning_effort field.
|
||||
const npm =
|
||||
model.api.npm === "@ai-sdk/alibaba" && ["deepseek-v4-pro", "deepseek-v4-flash"].includes(model.api.id)
|
||||
? "@ai-sdk/openai-compatible"
|
||||
: model.api.npm
|
||||
|
||||
if (npm.includes("@ai-sdk/openai-compatible") && options["includeUsage"] !== false) {
|
||||
options["includeUsage"] = true
|
||||
}
|
||||
|
||||
|
|
@ -1722,7 +1728,7 @@ const layer = Layer.effect(
|
|||
const key = Hash.fast(
|
||||
JSON.stringify({
|
||||
providerID: model.providerID,
|
||||
npm: model.api.npm,
|
||||
npm,
|
||||
options,
|
||||
}),
|
||||
)
|
||||
|
|
@ -1762,7 +1768,7 @@ const layer = Layer.effect(
|
|||
return wrapSSE(res, chunkTimeout, chunkAbortCtl)
|
||||
}
|
||||
|
||||
const bundledLoader = BUNDLED_PROVIDERS[model.api.npm]
|
||||
const bundledLoader = BUNDLED_PROVIDERS[npm]
|
||||
if (bundledLoader) {
|
||||
const factory = await bundledLoader()
|
||||
const loaded = factory({
|
||||
|
|
@ -1774,11 +1780,11 @@ const layer = Layer.effect(
|
|||
}
|
||||
|
||||
const installedPath = await (async () => {
|
||||
if (model.api.npm.startsWith("file://")) {
|
||||
return model.api.npm
|
||||
if (npm.startsWith("file://")) {
|
||||
return npm
|
||||
}
|
||||
const item = await Npm.add(model.api.npm)
|
||||
if (!item.entrypoint) throw new Error(`Package ${model.api.npm} has no import entrypoint`)
|
||||
const item = await Npm.add(npm)
|
||||
if (!item.entrypoint) throw new Error(`Package ${npm} has no import entrypoint`)
|
||||
return item.entrypoint
|
||||
})()
|
||||
|
||||
|
|
|
|||
|
|
@ -1744,9 +1744,11 @@ function reasoningEffort(model: Provider.Model, effort: string) {
|
|||
case "@ai-sdk/cohere":
|
||||
case "@ai-sdk/perplexity":
|
||||
case "@ai-sdk/vercel":
|
||||
case "@ai-sdk/alibaba":
|
||||
case "gitlab-ai-provider":
|
||||
return
|
||||
case "@ai-sdk/alibaba":
|
||||
if (["deepseek-v4-pro", "deepseek-v4-flash"].includes(model.api.id)) return { reasoningEffort: effort }
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3289,6 +3289,18 @@ describe("ProviderTransform.reasoningVariants", () => {
|
|||
).toEqual({ max: { effort: "max" } })
|
||||
})
|
||||
|
||||
test.each(["deepseek-v4-pro", "deepseek-v4-flash"])("preserves Alibaba %s reasoning effort", (id) => {
|
||||
expect(
|
||||
ProviderTransform.reasoningVariants(
|
||||
model([{ type: "effort", values: ["high", "max"] }]),
|
||||
target("@ai-sdk/alibaba", id),
|
||||
),
|
||||
).toEqual({
|
||||
high: { reasoningEffort: "high" },
|
||||
max: { reasoningEffort: "max" },
|
||||
})
|
||||
})
|
||||
|
||||
test("maps Kimi effort metadata to adaptive thinking", () => {
|
||||
expect(
|
||||
ProviderTransform.reasoningVariants(
|
||||
|
|
|
|||
|
|
@ -832,6 +832,66 @@ describe("session.llm.stream", () => {
|
|||
},
|
||||
)
|
||||
|
||||
it.instance(
|
||||
"preserves DeepSeek V4 effort and caching with the Alibaba SDK",
|
||||
() =>
|
||||
Effect.gen(function* () {
|
||||
const request = waitRequest(
|
||||
"/chat/completions",
|
||||
new Response(createChatStream("Hello"), {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "text/event-stream" },
|
||||
}),
|
||||
)
|
||||
const source = yield* Provider.use.getModel(ProviderV2.ID.make("alibaba"), ModelV2.ID.make("qwen-plus"))
|
||||
const resolved = {
|
||||
...source,
|
||||
id: ModelV2.ID.make("deepseek-v4-pro"),
|
||||
api: { ...source.api, id: "deepseek-v4-pro", npm: "@ai-sdk/alibaba" },
|
||||
variants: { high: { reasoningEffort: "high" } },
|
||||
}
|
||||
const sessionID = SessionID.make("session-test-alibaba-deepseek-effort")
|
||||
const agent = {
|
||||
name: "test",
|
||||
mode: "primary",
|
||||
options: {},
|
||||
permission: [{ permission: "*", pattern: "*", action: "allow" }],
|
||||
} satisfies Agent.Info
|
||||
const user = {
|
||||
id: MessageID.make("msg_user-alibaba-deepseek-effort"),
|
||||
sessionID,
|
||||
role: "user",
|
||||
time: { created: Date.now() },
|
||||
agent: agent.name,
|
||||
model: { providerID: resolved.providerID, modelID: resolved.id, variant: "high" },
|
||||
} satisfies SessionV1.User
|
||||
|
||||
yield* drain({
|
||||
user,
|
||||
sessionID,
|
||||
model: resolved,
|
||||
agent,
|
||||
system: ["You are a helpful assistant."],
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
tools: {},
|
||||
})
|
||||
|
||||
const capture = yield* Effect.promise(() => request)
|
||||
expect(capture.body.reasoning_effort).toBe("high")
|
||||
expect(JSON.stringify(capture.body.messages)).toContain('"cache_control":{"type":"ephemeral"}')
|
||||
}),
|
||||
{
|
||||
config: () => ({
|
||||
enabled_providers: ["alibaba"],
|
||||
provider: {
|
||||
alibaba: {
|
||||
options: { apiKey: "test-key", baseURL: `${state.server!.url.origin}/v1` },
|
||||
},
|
||||
},
|
||||
}),
|
||||
},
|
||||
)
|
||||
|
||||
const cerebrasFixture = { providerID: "cerebras", modelID: "gpt-oss-120b" }
|
||||
it.instance(
|
||||
"replays Cerebras assistant reasoning using the provider-supported field",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue