Skip to content

Commit 7ce6aef

Browse files
committed
part done
1 parent 33f2ca8 commit 7ce6aef

File tree

4 files changed

+35
-20
lines changed

4 files changed

+35
-20
lines changed

foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiChatCompletionResponse.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import com.sap.ai.sdk.foundationmodels.openai.generated.model.CompletionUsage;
99
import com.sap.ai.sdk.foundationmodels.openai.generated.model.CreateChatCompletionResponse;
1010
import com.sap.ai.sdk.foundationmodels.openai.generated.model.CreateChatCompletionResponseChoicesInner;
11+
12+
import java.util.ArrayList;
1113
import java.util.List;
1214
import java.util.Objects;
1315
import javax.annotation.Nonnull;
@@ -96,4 +98,21 @@ public OpenAiAssistantMessage getMessage() {
9698

9799
return new OpenAiAssistantMessage(new OpenAiMessageContent(contentItems), openAiToolCalls);
98100
}
101+
102+
public List<OpenAiToolMessage> executeTools() {
103+
var toolMessages = new ArrayList<OpenAiToolMessage>();
104+
for (var toolcall : getMessage().toolCalls()) {
105+
if (toolcall instanceof OpenAiFunctionCall functionCall) {
106+
if (functionCall.getName() == "weather") {
107+
final WeatherMethod.Request arguments =
108+
functionCall.getArgumentsAsObject(weatherFunction);
109+
final WeatherMethod.Response currentWeather = WeatherMethod.getCurrentWeather(arguments);
110+
toolMessages.add(currentWeather.toString(), functionCall.getId());
111+
}
112+
} else {
113+
throw new IllegalArgumentException(
114+
"Expected a function call, but got: %s".formatted(assistantMessage));
115+
}
116+
}
117+
}
99118
}

foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiFunctionCall.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public <T> T getArgumentsAsObject(@Nonnull final OpenAiFunctionTool tool)
5858
new TypeReference<T>() {
5959
@Override
6060
public Type getType() {
61-
return tool.getRequestModel();
61+
return tool.getFunction();
6262
}
6363
};
6464
return parseArguments(typeRef);

foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiFunctionTool.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.sap.ai.sdk.foundationmodels.openai.generated.model.ChatCompletionTool;
1212
import com.sap.ai.sdk.foundationmodels.openai.generated.model.FunctionObject;
1313
import java.util.Map;
14+
import java.util.function.Function;
1415
import javax.annotation.Nonnull;
1516
import javax.annotation.Nullable;
1617
import lombok.AccessLevel;
@@ -32,13 +33,15 @@
3233
@With
3334
@Getter(AccessLevel.PACKAGE)
3435
@AllArgsConstructor(access = AccessLevel.PRIVATE)
35-
public class OpenAiFunctionTool implements OpenAiTool {
36+
public class OpenAiFunctionTool<T, R> implements OpenAiTool {
3637

3738
/** The name of the function. */
3839
@Nonnull String name;
3940

4041
/** The model class for function request. */
41-
@Nonnull Class<?> requestModel;
42+
@Nonnull Function<T, R> function;
43+
44+
/** The model class for function response. */
4245

4346
/** An optional description of the function. */
4447
@Nullable String description;
@@ -51,20 +54,20 @@ public class OpenAiFunctionTool implements OpenAiTool {
5154
* captures the request to the function.
5255
*
5356
* @param name the name of the function
54-
* @param requestModel the model class for the function request
57+
* @param function the model class for function request
5558
*/
56-
public <T> OpenAiFunctionTool(@Nonnull final String name, @Nonnull final Class<T> requestModel) {
57-
this(name, requestModel, null, null);
59+
public OpenAiFunctionTool(@Nonnull final String name, @Nonnull final Function<T, R> function) {
60+
this(name, function, null, null);
5861
}
5962

6063
ChatCompletionTool createChatCompletionTool() {
6164
final var objectMapper = new ObjectMapper();
6265
JsonSchema schema = null;
6366
try {
64-
schema = new JsonSchemaGenerator(objectMapper).generateSchema(requestModel);
67+
schema = new JsonSchemaGenerator(objectMapper).generateSchema(Class<T>.class);
6568
} catch (JsonMappingException e) {
6669
throw new IllegalArgumentException(
67-
"Could not generate schema for " + requestModel.getTypeName(), e);
70+
"Could not generate schema for " + function.getTypeName(), e);
6871
}
6972

7073
schema.setId(null);

sample-code/spring-app/src/main/java/com/sap/ai/sdk/app/services/OpenAiServiceV2.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,9 @@
1212
import com.sap.ai.sdk.foundationmodels.openai.OpenAiClient;
1313
import com.sap.ai.sdk.foundationmodels.openai.OpenAiEmbeddingRequest;
1414
import com.sap.ai.sdk.foundationmodels.openai.OpenAiEmbeddingResponse;
15-
import com.sap.ai.sdk.foundationmodels.openai.OpenAiFunctionCall;
1615
import com.sap.ai.sdk.foundationmodels.openai.OpenAiFunctionTool;
1716
import com.sap.ai.sdk.foundationmodels.openai.OpenAiImageItem;
1817
import com.sap.ai.sdk.foundationmodels.openai.OpenAiMessage;
19-
import com.sap.ai.sdk.foundationmodels.openai.OpenAiToolCall;
2018
import java.util.ArrayList;
2119
import java.util.List;
2220
import java.util.stream.Stream;
@@ -97,7 +95,8 @@ public OpenAiChatCompletionResponse chatCompletionToolExecution(
9795

9896
// 1. Define the function
9997
final var weatherFunction =
100-
new OpenAiFunctionTool("weather", WeatherMethod.Request.class)
98+
new OpenAiFunctionTool(
99+
"weather", WeatherMethod.Request.class, WeatherMethod.Response.class)
101100
.withDescription("Get the weather for the given location");
102101

103102
// 2. Assistant calls the function
@@ -106,16 +105,10 @@ public OpenAiChatCompletionResponse chatCompletionToolExecution(
106105
final OpenAiChatCompletionResponse response =
107106
OpenAiClient.forModel(GPT_4O_MINI).chatCompletion(request);
108107
final OpenAiAssistantMessage assistantMessage = response.getMessage();
109-
108+
110109
// 3. Execute the function
111-
final OpenAiToolCall toolCall = assistantMessage.toolCalls().get(0);
112-
if (!(toolCall instanceof OpenAiFunctionCall functionCall)) {
113-
throw new IllegalArgumentException(
114-
"Expected a function call, but got: %s".formatted(assistantMessage));
115-
}
116-
final WeatherMethod.Request arguments = functionCall.getArgumentsAsObject(weatherFunction);
117-
final WeatherMethod.Response currentWeather = WeatherMethod.getCurrentWeather(arguments);
118-
110+
111+
119112
// 4. Send back the results, and the model will incorporate them into its final response.
120113
messages.add(assistantMessage);
121114
messages.add(OpenAiMessage.tool(currentWeather.toString(), functionCall.getId()));

0 commit comments

Comments
 (0)