deepseek-reasoner : APICallError with no tools params in request
DEPDENCIES
"dependencies": {
"@ai-sdk/deepseek": "^0.2.8",
"@ai-sdk/openai": "^1.3.9",
"@ai-sdk/react": "^1.2.8",
"ai": "4.2.10"
MODEL CONFIGURE
export enum LLM_TYPE {
QWEN_PLUS = 'qwen-plus',
DEEPSEEK_R1 = 'deepseek-reasoner',
}
export const customMiddleware: Record<LLM_TYPE, LanguageModelV1Middleware> = {
[LLM_TYPE.DEEPSEEK_R1]: extractReasoningMiddleware({ tagName: 'think' }),
[LLM_TYPE.QWEN_PLUS] : {}
};
export const customModel: Record<LLM_TYPE, LanguageModelV1> = {
[LLM_TYPE.DEEPSEEK_R1]: createDeepSeek({apiKey: DEFINE_ENV.DEEPSEEK_API_KEY,baseURL:DEFINE_ENV.DEEPSEEK_BASE_URL })(LLM_TYPE.DEEPSEEK_R1),
[LLM_TYPE.QWEN_PLUS]: createOpenAI({ apiKey: DEFINE_ENV.QIANWEN_DASHSCOPE_API_KEY, baseURL: DEFINE_ENV.QIANWEN_DASHSCOPE_API_URL})(LLM_TYPE.QWEN_PLUS)
};
export const getLLM = (modelId = LLM_TYPE.QWEN_PLUS) => wrapLanguageModel({
model: customModel[modelId],
middleware: customMiddleware[modelId],
})
LOGIC in streamText function
maxSteps: modelId!==LLM_TYPE.DEEPSEEK_R1 ? 2 : 1,
tools: modelId!==LLM_TYPE.DEEPSEEK_R1 ? {
getInformation: tool({
description: `get information from your knowledge base to answer questions.`,
parameters: z.object({
question: z.string().describe('the users question'),
}),
execute: getInformationFromKnowledgeBase,
})}
: undefined,
onFinish: async ({ response }) => {
if (session.user && session.user.id) {
try {
const assistantId = getTrailingMessageId({
messages: response.messages.filter(
(message) => message.role === 'assistant',
),
});
if (!assistantId) {
throw new Error('No assistant message found!');
}
const [, assistantMessage] = appendResponseMessages({
messages: [userMessage],
responseMessages: response.messages,
});
await saveMessages({
messages: [
{
id: assistantId,
chatId: id,
role: assistantMessage.role,
// content's datastruct same with parts
content: assistantMessage.parts,
createdAt: new Date(),
},
]
})
} catch (error) {
console.log(error);
console.error("Failed to save chat");
}
}
},
experimental_telemetry: {
isEnabled: true,
functionId: "stream-text",
},
});
result.consumeStream();
result.mergeIntoDataStream(dataStream, {
sendReasoning: true,
})
STEPS
- pnpm dev, run project in localhost:3000
- select chat model (qwen-plus in my project),which will use tools call in the progress,and the result is ok
- select reasoning model (deepseek-reasoner in my project, which will cause error,the detail as shown blow。
ERROR LOG
ERROR: createDataStreamResponse APICallError [AI_APICallError]: deepseek-reasoner does not support Function Calling.
at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/@[email protected][email protected]/node_modules/@ai-sdk/provider-utils/dist/index.mjs:708:14)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async postToApi (webpack-internal:///(rsc)/./node_modules/.pnpm/@[email protected][email protected]/node_modules/@ai-sdk/provider-utils/dist/index.mjs:608:28)
at async OpenAICompatibleChatLanguageModel.doStream (webpack-internal:///(rsc)/./node_modules/.pnpm/@[email protected][email protected]/node_modules/@ai-sdk/openai-compatible/dist/index.mjs:491:50)
at async wrapStream (webpack-internal:///(rsc)/./node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/ai/dist/index.mjs:6337:35)
at async fn (webpack-internal:///(rsc)/./node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/ai/dist/index.mjs:5523:25)
at async eval (webpack-internal:///(rsc)/./node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/ai/dist/index.mjs:544:22)
at async _retryWithExponentialBackoff (webpack-internal:///(rsc)/./node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/ai/dist/index.mjs:345:12)
at async streamStep (webpack-internal:///(rsc)/./node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/ai/dist/index.mjs:5478:15)
at async fn (webpack-internal:///(rsc)/./node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/ai/dist/index.mjs:5848:9)
at async eval (webpack-internal:///(rsc)/./node_modules/.pnpm/[email protected][email protected][email protected]/node_modules/ai/dist/index.mjs:544:22) {
cause: undefined,
url: 'https://api.deepseek.com/chat/completions',
requestBodyValues: {
model: 'deepseek-reasoner',
user: undefined,
max_tokens: undefined,
temperature: 0,
top_p: undefined,
frequency_penalty: undefined,
presence_penalty: undefined,
response_format: undefined,
stop: undefined,
seed: undefined,
messages: [
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object], [Object],
[Object]
],
tools: undefined,
tool_choice: undefined,
stream: true
},
statusCode: 400,
responseHeaders: {
'access-control-allow-credentials': 'true',
'cf-cache-status': 'DYNAMIC',
'cf-ray': '92e8167699c5f080-DFW',
connection: 'keep-alive',
'content-length': '151',
'content-type': 'application/json',
date: 'Fri, 11 Apr 2025 05:29:42 GMT',
server: 'cloudflare',
'set-cookie': 'COOKIE VALUE; path=/; expires=Fri, 11-Apr-25 05:59:42 GMT; domain=.deepseek.com; HttpOnly; Secure; SameSite=None',
'strict-transport-security': 'max-age=31536000; includeSubDomains; preload',
vary: 'origin, access-control-request-method, access-control-request-headers',
'x-content-type-options': 'nosniff',
'x-ds-trace-id': 'dfcbe5aadf4e8be6c55c590e50b20c60'
},
responseBody: '{"error":{"message":"deepseek-reasoner does not support Function Calling.","type":"invalid_request_error","param":null,"code":"invalid_request_error"}}',
isRetryable: false,
data: {
error: {
message: 'deepseek-reasoner does not support Function Calling.',
type: 'invalid_request_error',
param: null,
code: 'invalid_request_error'
}
},
[Symbol(vercel.ai.error)]: true,
[Symbol(vercel.ai.error.AI_APICallError)]: true
}
message params in ERROR LOG
Since the tools params would be undefined when the model is deepseek-reasoner(LLM_TYPE.DEEPSEEK_R1), I doubt that the messages causes this error, I mark the suspicious message in picture. because I compared the same operation in https://chat.vercel.ai/ . There has no message contains type: "step-start"
@uwularpy
Hi! @cht527 Here are several approaches you can try: 1. Disable Function Calling for Deepseek Completely: Since deepseek-reasoner does not support function calling, ensure that no function calling-related parameters are being sent when it is selected. This may involve: • Bypassing Middleware: Either conditionally disable the extractReasoningMiddleware when using DEEPSEEK_R1 or adapt it so that it does not insert any extra instructions (such as a "step-start" marker) that imply function calls. • Modifying Data Stream Merge: Avoid merging the data stream with sendReasoning: true for deepseek. For example, you could conditionally pass the parameter like:
result.mergeIntoDataStream(dataStream, {
sendReasoning: modelId !== LLM_TYPE.DEEPSEEK_R1,
});
This way, no reasoning-related function call data is appended when using deepseek.
Hi! @cht527 Here are several approaches you can try: 1. Disable Function Calling for Deepseek Completely: Since deepseek-reasoner does not support function calling, ensure that no function calling-related parameters are being sent when it is selected. This may involve: • Bypassing Middleware: Either conditionally disable the extractReasoningMiddleware when using DEEPSEEK_R1 or adapt it so that it does not insert any extra instructions (such as a "step-start" marker) that imply function calls. • Modifying Data Stream Merge: Avoid merging the data stream with sendReasoning: true for deepseek. For example, you could conditionally pass the parameter like:
result.mergeIntoDataStream(dataStream, { sendReasoning: modelId !== LLM_TYPE.DEEPSEEK_R1, });This way, no reasoning-related function call data is appended when using deepseek.
@ailunc Hi,This is not the valid way to solve the problem, it simply stops receiving reasoning content. The 'step-start' already happens before I switch the model to DEEPSEEK_R1