diff --git a/foundation-models/openai/pom.xml b/foundation-models/openai/pom.xml
index 8846896f3..998b89dc1 100644
--- a/foundation-models/openai/pom.xml
+++ b/foundation-models/openai/pom.xml
@@ -38,11 +38,11 @@
${project.basedir}/../../
- 71%
+ 70%
80%
76%
70%
- 76%
+ 75%
84%
diff --git a/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiAssistantMessage.java b/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiAssistantMessage.java
index c77f1044d..26fe6d8b9 100644
--- a/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiAssistantMessage.java
+++ b/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiAssistantMessage.java
@@ -1,6 +1,6 @@
package com.sap.ai.sdk.foundationmodels.openai;
-import static lombok.AccessLevel.PUBLIC;
+import static lombok.AccessLevel.PACKAGE;
import com.google.common.annotations.Beta;
import com.sap.ai.sdk.foundationmodels.openai.generated.model.ChatCompletionMessageToolCall;
@@ -8,6 +8,7 @@
import com.sap.ai.sdk.foundationmodels.openai.generated.model.ChatCompletionRequestAssistantMessage;
import com.sap.ai.sdk.foundationmodels.openai.generated.model.ChatCompletionRequestAssistantMessageContent;
import com.sap.ai.sdk.foundationmodels.openai.generated.model.ToolCallType;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.annotation.Nonnull;
@@ -28,7 +29,7 @@
@Beta
@Value
@Accessors(fluent = true)
-@AllArgsConstructor(access = PUBLIC)
+@AllArgsConstructor(access = PACKAGE)
public class OpenAiAssistantMessage implements OpenAiMessage {
/** The role associated with this message. */
@@ -52,12 +53,27 @@ public class OpenAiAssistantMessage implements OpenAiMessage {
@Nonnull
List toolCalls;
+ /**
+ * Creates a new assistant message with the given content and additional tool calls.
+ *
+ * @param toolCalls the additional tool calls to associate with the message.
+ * @return a new assistant message with the given content and additional tool calls.
+ * @since 1.10.0
+ */
+ @Nonnull
+ public OpenAiAssistantMessage withToolCalls(
+ @Nonnull final List extends OpenAiToolCall> toolCalls) {
+ final List newToolCalls = new ArrayList<>(this.toolCalls);
+ newToolCalls.addAll(toolCalls);
+ return new OpenAiAssistantMessage(content, newToolCalls);
+ }
+
/**
* Creates a new assistant message with the given single message as text content.
*
* @param singleMessage the message.
*/
- public OpenAiAssistantMessage(@Nonnull final String singleMessage) {
+ OpenAiAssistantMessage(@Nonnull final String singleMessage) {
this(
new OpenAiMessageContent(List.of(new OpenAiTextItem(singleMessage))),
Collections.emptyList());
diff --git a/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiFunctionCall.java b/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiFunctionCall.java
index 8075cb01b..c3668d26b 100644
--- a/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiFunctionCall.java
+++ b/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiFunctionCall.java
@@ -2,7 +2,6 @@
import com.google.common.annotations.Beta;
import javax.annotation.Nonnull;
-import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Value;
@@ -13,7 +12,7 @@
*/
@Beta
@Value
-@AllArgsConstructor(access = AccessLevel.PUBLIC)
+@AllArgsConstructor(access = lombok.AccessLevel.PACKAGE)
public class OpenAiFunctionCall implements OpenAiToolCall {
/** The unique identifier for the function call. */
@Nonnull String id;
diff --git a/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiToolCall.java b/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiToolCall.java
index 9c400c4f4..9a4d3ff27 100644
--- a/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiToolCall.java
+++ b/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiToolCall.java
@@ -1,6 +1,7 @@
package com.sap.ai.sdk.foundationmodels.openai;
import com.google.common.annotations.Beta;
+import javax.annotation.Nonnull;
/**
* Represents a tool called by an OpenAI model.
@@ -8,4 +9,19 @@
* @since 1.6.0
*/
@Beta
-public sealed interface OpenAiToolCall permits OpenAiFunctionCall {}
+public sealed interface OpenAiToolCall permits OpenAiFunctionCall {
+ /**
+ * Creates a new instance of {@link OpenAiToolCall}.
+ *
+ * @param id The unique identifier for the tool call.
+ * @param name The name of the tool to be called.
+ * @param arguments The arguments for the tool call, encoded as a JSON string.
+ * @return A new instance of {@link OpenAiToolCall}.
+ * @since 1.10.0
+ */
+ @Nonnull
+ static OpenAiToolCall function(
+ @Nonnull final String id, @Nonnull final String name, @Nonnull final String arguments) {
+ return new OpenAiFunctionCall(id, name, arguments);
+ }
+}
diff --git a/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/spring/OpenAiChatModel.java b/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/spring/OpenAiChatModel.java
index efef63d5c..2d7dee093 100644
--- a/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/spring/OpenAiChatModel.java
+++ b/foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/spring/OpenAiChatModel.java
@@ -2,14 +2,10 @@
import static org.springframework.ai.model.tool.ToolCallingChatOptions.isInternalToolExecutionEnabled;
-import com.sap.ai.sdk.foundationmodels.openai.OpenAiAssistantMessage;
import com.sap.ai.sdk.foundationmodels.openai.OpenAiChatCompletionRequest;
import com.sap.ai.sdk.foundationmodels.openai.OpenAiChatCompletionResponse;
import com.sap.ai.sdk.foundationmodels.openai.OpenAiClient;
-import com.sap.ai.sdk.foundationmodels.openai.OpenAiFunctionCall;
import com.sap.ai.sdk.foundationmodels.openai.OpenAiMessage;
-import com.sap.ai.sdk.foundationmodels.openai.OpenAiMessageContent;
-import com.sap.ai.sdk.foundationmodels.openai.OpenAiTextItem;
import com.sap.ai.sdk.foundationmodels.openai.OpenAiToolCall;
import com.sap.ai.sdk.foundationmodels.openai.generated.model.ChatCompletionMessageToolCall;
import com.sap.ai.sdk.foundationmodels.openai.generated.model.ChatCompletionResponseMessage;
@@ -86,10 +82,9 @@ private static void addAssistantMessage(
return;
}
final Function callTranslate =
- toolCall -> new OpenAiFunctionCall(toolCall.id(), toolCall.name(), toolCall.arguments());
- val content = new OpenAiMessageContent(List.of(new OpenAiTextItem(message.getText())));
+ toolCall -> OpenAiToolCall.function(toolCall.id(), toolCall.name(), toolCall.arguments());
val calls = message.getToolCalls().stream().map(callTranslate).toList();
- result.add(new OpenAiAssistantMessage(content, calls));
+ result.add(OpenAiMessage.assistant(message.getText()).withToolCalls(calls));
}
private static void addToolMessages(