-
Notifications
You must be signed in to change notification settings - Fork 2k
Open
Labels
Description
Please do a quick search on GitHub issues first, there might be already a duplicate issue for the one you are about to create.
If the bug is trivial, just go ahead and create the issue. Otherwise, please take a few moments and fill in the following sections:
Bug description
When I use DeepSeekChatModel to force a ToolCall call using tool_choice, if the tool definition has returnDirect=false, the completion of the push back will trigger ToolCall again, causing an infinite loop.
Environment
Java Version: 17
Spring AI Version: 1.0.3
Steps to reproduce
- Define a tool function and specify returnDirect=false.
- Use the DeepSeekChatModel ChatClient to specify ToolChoice as this tool and perform completion.
Expected behavior
Call the function only once and output the text normally
My Suggestion
- Before
Lines 209 to 225 in 3fc1ed6
if (this.toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), response)) { | |
var toolExecutionResult = this.toolCallingManager.executeToolCalls(prompt, response); | |
if (toolExecutionResult.returnDirect()) { | |
// Return tool execution result directly to the client. | |
return ChatResponse.builder() | |
.from(response) | |
.generations(ToolExecutionResult.buildGenerations(toolExecutionResult)) | |
.build(); | |
} | |
else { | |
// Send the tool execution result back to the model. | |
return this.internalCall(new Prompt(toolExecutionResult.conversationHistory(), prompt.getOptions()), | |
response); | |
} | |
} | |
return response; |
- After
Reset tool_choice to "auto" when push back to model
if (this.toolExecutionEligibilityPredicate.isToolExecutionRequired(prompt.getOptions(), response)) {
var toolExecutionResult = this.toolCallingManager.executeToolCalls(prompt, response);
if (toolExecutionResult.returnDirect()) {
// Return tool execution result directly to the client.
return ChatResponse.builder()
.from(response)
.generations(ToolExecutionResult.buildGenerations(toolExecutionResult))
.build();
}
else {
if (prompt.getOptions() instanceof DeepSeekChatOptions) {
DeepSeekChatOptions options = (DeepSeekChatOptions)prompt.getOptions();
options.setToolChoice(ChatCompletionRequest.ToolChoiceBuilder.AUTO);
}
// Send the tool execution result back to the model.
return this.internalCall(new Prompt(toolExecutionResult.conversationHistory(), prompt.getOptions()),
response);
}
}
return response;