Skip to content

Commit 4b7aa19

Browse files
Revert tool call iteration limit, match Spring AI's recursive pattern
Remove MAX_TOOL_CALL_ITERATIONS and the iterative loop. Use recursive internalCall() matching Spring AI's OpenAiChatModel pattern. Temporal's activity timeouts and workflow execution timeout already bound runaway tool loops. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 8ba4eb0 commit 4b7aa19

2 files changed

Lines changed: 19 additions & 27 deletions

File tree

TASK_QUEUE.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@
7979
"depends_on": [
8080
"T1"
8181
],
82-
"status": "completed",
83-
"notes": "Do after type conversion tests exist to verify we don't break the call flow."
82+
"status": "reverted",
83+
"notes": "Reverted: Spring AI does not limit tool call iterations either. Temporal activity timeouts and workflow execution timeout provide the safety net."
8484
},
8585
{
8686
"id": "T8",

temporal-spring-ai/src/main/java/io/temporal/springai/model/ActivityChatModel.java

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,6 @@ public class ActivityChatModel implements ChatModel {
8383
/** Default maximum retry attempts for chat model activity calls. */
8484
public static final int DEFAULT_MAX_ATTEMPTS = 3;
8585

86-
/** Maximum number of tool call iterations before aborting to prevent infinite loops. */
87-
public static final int MAX_TOOL_CALL_ITERATIONS = 10;
88-
8986
private final ChatModelActivity chatModelActivity;
9087
private final String modelName;
9188
private final ToolCallingManager toolCallingManager;
@@ -190,24 +187,22 @@ public ChatOptions getDefaultOptions() {
190187

191188
@Override
192189
public ChatResponse call(Prompt prompt) {
193-
Prompt currentPrompt = prompt;
194-
195-
for (int iteration = 0; iteration < MAX_TOOL_CALL_ITERATIONS; iteration++) {
196-
// Convert prompt to activity input and call the activity
197-
ChatModelTypes.ChatModelActivityInput input = createActivityInput(currentPrompt);
198-
ChatModelTypes.ChatModelActivityOutput output = chatModelActivity.callChatModel(input);
190+
return internalCall(prompt);
191+
}
199192

200-
// Convert activity output to ChatResponse
201-
ChatResponse response = toResponse(output);
193+
private ChatResponse internalCall(Prompt prompt) {
194+
// Convert prompt to activity input and call the activity
195+
ChatModelTypes.ChatModelActivityInput input = createActivityInput(prompt);
196+
ChatModelTypes.ChatModelActivityOutput output = chatModelActivity.callChatModel(input);
202197

203-
// If no tool calls requested, return the response
204-
if (currentPrompt.getOptions() == null
205-
|| !toolExecutionEligibilityPredicate.isToolExecutionRequired(
206-
currentPrompt.getOptions(), response)) {
207-
return response;
208-
}
198+
// Convert activity output to ChatResponse
199+
ChatResponse response = toResponse(output);
209200

210-
var toolExecutionResult = toolCallingManager.executeToolCalls(currentPrompt, response);
201+
// Handle tool calls if the model requested them
202+
if (prompt.getOptions() != null
203+
&& toolExecutionEligibilityPredicate.isToolExecutionRequired(
204+
prompt.getOptions(), response)) {
205+
var toolExecutionResult = toolCallingManager.executeToolCalls(prompt, response);
211206

212207
if (toolExecutionResult.returnDirect()) {
213208
return ChatResponse.builder()
@@ -216,15 +211,12 @@ public ChatResponse call(Prompt prompt) {
216211
.build();
217212
}
218213

219-
// Continue loop with tool results sent back to the model
220-
currentPrompt =
221-
new Prompt(toolExecutionResult.conversationHistory(), currentPrompt.getOptions());
214+
// Send tool results back to the model
215+
return internalCall(
216+
new Prompt(toolExecutionResult.conversationHistory(), prompt.getOptions()));
222217
}
223218

224-
throw new IllegalStateException(
225-
"Chat model exceeded maximum tool call iterations ("
226-
+ MAX_TOOL_CALL_ITERATIONS
227-
+ "). This may indicate the model is stuck in a tool-calling loop.");
219+
return response;
228220
}
229221

230222
private ChatModelTypes.ChatModelActivityInput createActivityInput(Prompt prompt) {

0 commit comments

Comments
 (0)