-
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;