Skip to content

Commit 0eacc91

Browse files
tzolovilayaperumalg
authored andcommitted
feat(tools): Add tool call history to ToolContext
- Add TOOL_CALL_HISTORY constant to store tool call history - Extend ToolContext with getToolConversationHistory method - Include tool call history in tool context during function execution - Add test coverage for tool call history verification Resolves #1202
1 parent edc7003 commit 0eacc91

File tree

3 files changed

+41
-2
lines changed

3 files changed

+41
-2
lines changed

models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/client/AnthropicChatClientMethodInvokingFunctionCallbackIT.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.ai.anthropic.client;
1818

19+
import java.util.List;
1920
import java.util.Map;
2021
import java.util.concurrent.ConcurrentHashMap;
2122

@@ -27,6 +28,7 @@
2728

2829
import org.springframework.ai.anthropic.AnthropicTestConfiguration;
2930
import org.springframework.ai.chat.client.ChatClient;
31+
import org.springframework.ai.chat.messages.Message;
3032
import org.springframework.ai.chat.model.ChatModel;
3133
import org.springframework.ai.chat.model.ToolContext;
3234
import org.springframework.ai.model.function.FunctionCallback;
@@ -158,6 +160,9 @@ void methodGetWeatherToolContext() {
158160

159161
assertThat(response).contains("30", "10", "15");
160162
assertThat(arguments).containsEntry("tool", "value");
163+
assertThat(arguments).containsKey(ToolContext.TOOL_CALL_HISTORY);
164+
List<Message> tootConversationMessages = (List<Message>) arguments.get(ToolContext.TOOL_CALL_HISTORY);
165+
assertThat(tootConversationMessages).hasSize(6);
161166
}
162167

163168
@Test
@@ -252,6 +257,7 @@ public String getWeatherNonStatic(String city, Unit unit) {
252257

253258
public String getWeatherWithContext(String city, Unit unit, ToolContext context) {
254259
arguments.put("tool", context.getContext().get("tool"));
260+
arguments.put(ToolContext.TOOL_CALL_HISTORY, context.getToolCallHistory());
255261
return getWeatherStatic(city, unit);
256262
}
257263

spring-ai-core/src/main/java/org/springframework/ai/chat/model/AbstractToolCallSupport.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.springframework.ai.chat.model;
1818

1919
import java.util.ArrayList;
20+
import java.util.HashMap;
2021
import java.util.HashSet;
2122
import java.util.List;
2223
import java.util.Map;
@@ -142,12 +143,23 @@ protected List<Message> handleToolCalls(Prompt prompt, ChatResponse response) {
142143
Map<String, Object> toolContextMap = Map.of();
143144
if (prompt.getOptions() instanceof FunctionCallingOptions functionCallOptions
144145
&& !CollectionUtils.isEmpty(functionCallOptions.getToolContext())) {
145-
toolContextMap = functionCallOptions.getToolContext();
146+
147+
toolContextMap = new HashMap<>(functionCallOptions.getToolContext());
148+
149+
List<Message> toolCallHistory = new ArrayList<>(prompt.copy().getInstructions());
150+
toolCallHistory.add(new AssistantMessage(assistantMessage.getContent(), assistantMessage.getMetadata(),
151+
assistantMessage.getToolCalls()));
152+
153+
toolContextMap.put(ToolContext.TOOL_CALL_HISTORY, toolCallHistory);
146154
}
155+
147156
ToolResponseMessage toolMessageResponse = this.executeFunctions(assistantMessage,
148157
new ToolContext(toolContextMap));
149158

150-
return this.buildToolCallConversation(prompt.getInstructions(), assistantMessage, toolMessageResponse);
159+
List<Message> toolConversationHistory = this.buildToolCallConversation(prompt.getInstructions(),
160+
assistantMessage, toolMessageResponse);
161+
162+
return toolConversationHistory;
151163
}
152164

153165
protected List<Message> buildToolCallConversation(List<Message> previousMessages, AssistantMessage assistantMessage,

spring-ai-core/src/main/java/org/springframework/ai/chat/model/ToolContext.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@
1717
package org.springframework.ai.chat.model;
1818

1919
import java.util.Collections;
20+
import java.util.List;
2021
import java.util.Map;
2122

23+
import org.springframework.ai.chat.messages.Message;
24+
2225
/**
2326
* Represents the context for tool execution in a function calling scenario.
2427
*
@@ -33,11 +36,20 @@
3336
* {@code FunctionCallingOptions} and is used in the function execution process.
3437
* </p>
3538
*
39+
* <p>
40+
* The context map can contain any information that is relevant to the tool execution.
41+
* </p>
42+
*
3643
* @author Christian Tzolov
3744
* @since 1.0.0
3845
*/
3946
public class ToolContext {
4047

48+
/**
49+
* The key for the running, tool call history stored in the context map.
50+
*/
51+
public static final String TOOL_CALL_HISTORY = "TOOL_CALL_HISTORY";
52+
4153
private final Map<String, Object> context;
4254

4355
/**
@@ -57,4 +69,13 @@ public Map<String, Object> getContext() {
5769
return this.context;
5870
}
5971

72+
/**
73+
* Returns the tool call history from the context map.
74+
* @return The tool call history.
75+
*/
76+
@SuppressWarnings("unchecked")
77+
public List<Message> getToolCallHistory() {
78+
return (List<Message>) this.context.get(TOOL_CALL_HISTORY);
79+
}
80+
6081
}

0 commit comments

Comments
 (0)