Skip to content

Commit 1d8ddb8

Browse files
fix: [Orchestration] tool calling works on all models (#578)
* fix: [Orchestration] tool calling works on all models * release notes * fix test * PMD * withToolCalls --------- Co-authored-by: Alexander Dümont <[email protected]>
1 parent b79da3b commit 1d8ddb8

File tree

4 files changed

+43
-15
lines changed

4 files changed

+43
-15
lines changed

docs/release_notes.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@
2020

2121
### 🐛 Fixed Issues
2222

23-
-
23+
- [Orchestration] Tool calling works on all models

orchestration/src/main/java/com/sap/ai/sdk/orchestration/AssistantMessage.java

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.sap.ai.sdk.orchestration.model.ChatMessageContent;
99
import com.sap.ai.sdk.orchestration.model.MessageToolCall;
1010
import com.sap.ai.sdk.orchestration.model.TextContent;
11+
import java.util.ArrayList;
1112
import java.util.List;
1213
import javax.annotation.Nonnull;
1314
import javax.annotation.Nullable;
@@ -57,30 +58,55 @@ public AssistantMessage(@Nonnull final String singleMessage) {
5758
* Creates a new assistant message with the given tool calls.
5859
*
5960
* @param toolCalls list of tool call objects
61+
* @deprecated Please use {@link #withToolCalls(List)} instead.
6062
*/
63+
@Deprecated
6164
public AssistantMessage(@Nonnull final List<MessageToolCall> toolCalls) {
6265
content = new MessageContent(List.of());
6366
this.toolCalls = toolCalls;
6467
}
6568

69+
private AssistantMessage(
70+
@Nonnull final MessageContent content, @Nullable final List<MessageToolCall> toolCalls) {
71+
this.content = content;
72+
this.toolCalls = toolCalls;
73+
}
74+
75+
/**
76+
* Returns a new AssistantMessage instance with the provided tool calls added to the existing
77+
* ones.
78+
*
79+
* @param toolCalls the list of tool calls to add.
80+
* @return a new AssistantMessage instance with the combined tool calls.
81+
*/
82+
@Nonnull
83+
public AssistantMessage withToolCalls(@Nonnull final List<MessageToolCall> toolCalls) {
84+
val newToolcalls = new ArrayList<>(this.toolCalls != null ? this.toolCalls : List.of());
85+
newToolcalls.addAll(toolCalls);
86+
return new AssistantMessage(this.content, newToolcalls);
87+
}
88+
6689
@Nonnull
6790
@Override
6891
public ChatMessage createChatMessage() {
92+
val assistantChatMessage = AssistantChatMessage.create().role(ASSISTANT);
93+
6994
if (toolCalls != null) {
70-
return AssistantChatMessage.create().role(ASSISTANT).toolCalls(toolCalls);
95+
assistantChatMessage.setToolCalls(toolCalls);
7196
}
97+
98+
ChatMessageContent text;
7299
if (content.items().size() == 1 && content.items().get(0) instanceof TextItem textItem) {
73-
return AssistantChatMessage.create()
74-
.role(ASSISTANT)
75-
.content(ChatMessageContent.create(textItem.text()));
100+
text = ChatMessageContent.create(textItem.text());
101+
} else {
102+
val texts =
103+
content.items().stream()
104+
.filter(item -> item instanceof TextItem)
105+
.map(item -> (TextItem) item)
106+
.map(item -> TextContent.create().type(TextContent.TypeEnum.TEXT).text(item.text()))
107+
.toList();
108+
text = ChatMessageContent.create(texts);
76109
}
77-
val texts =
78-
content.items().stream()
79-
.filter(item -> item instanceof TextItem)
80-
.map(item -> (TextItem) item)
81-
.map(item -> TextContent.create().type(TextContent.TypeEnum.TEXT).text(item.text()))
82-
.toList();
83-
84-
return AssistantChatMessage.create().role(ASSISTANT).content(ChatMessageContent.create(texts));
110+
return assistantChatMessage.content(text);
85111
}
86112
}

orchestration/src/main/java/com/sap/ai/sdk/orchestration/spring/OrchestrationChatModel.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,17 @@ private static com.sap.ai.sdk.orchestration.Message[] toOrchestrationMessages(
126126
case USER:
127127
yield List.of(new UserMessage(msg.getText()));
128128
case ASSISTANT:
129+
val assistantMessage = new AssistantMessage(msg.getText());
129130
val springToolCalls =
130131
((org.springframework.ai.chat.messages.AssistantMessage) msg).getToolCalls();
131132
if (springToolCalls != null && !springToolCalls.isEmpty()) {
132133
final List<MessageToolCall> sdkToolCalls =
133134
springToolCalls.stream()
134135
.map(OrchestrationChatModel::toOrchestrationToolCall)
135136
.toList();
136-
yield List.of(new AssistantMessage(sdkToolCalls));
137+
yield List.of(assistantMessage.withToolCalls(sdkToolCalls));
137138
}
138-
yield List.of(new AssistantMessage(msg.getText()));
139+
yield List.of(assistantMessage);
139140
case TOOL:
140141
val toolResponses = ((ToolResponseMessage) msg).getResponses();
141142
yield toolResponses.stream()

orchestration/src/test/resources/toolCallsRequest2.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
},
1818
{
1919
"role": "assistant",
20+
"content" : "",
2021
"tool_calls": [
2122
{
2223
"id": "call_LOyP7EVdeqFlGEmVzmPdCVey",

0 commit comments

Comments
 (0)