33import static com .sap .ai .sdk .foundationmodels .openai .generated .model .ChatCompletionTool .TypeEnum .FUNCTION ;
44
55import com .fasterxml .jackson .core .type .TypeReference ;
6- import com .fasterxml .jackson .databind .JsonMappingException ;
7- import com .fasterxml .jackson .databind .ObjectMapper ;
8- import com .fasterxml .jackson .module .jsonSchema .JsonSchema ;
9- import com .fasterxml .jackson .module .jsonSchema .JsonSchemaGenerator ;
6+ import com .github .victools .jsonschema .generator .Option ;
7+ import com .github .victools .jsonschema .generator .OptionPreset ;
8+ import com .github .victools .jsonschema .generator .SchemaGenerator ;
9+ import com .github .victools .jsonschema .generator .SchemaGeneratorConfigBuilder ;
10+ import com .github .victools .jsonschema .generator .SchemaVersion ;
11+ import com .github .victools .jsonschema .module .jackson .JacksonModule ;
12+ import com .github .victools .jsonschema .module .jackson .JacksonOption ;
1013import com .google .common .annotations .Beta ;
1114import com .sap .ai .sdk .foundationmodels .openai .generated .model .ChatCompletionTool ;
1215import com .sap .ai .sdk .foundationmodels .openai .generated .model .FunctionObject ;
2124import lombok .experimental .Accessors ;
2225
2326/**
24- * Represents an OpenAI function tool that can be used to define a function call in an OpenAI Chat
25- * Completion request. This tool generates a JSON schema based on the provided class representing
26- * the function's request structure.
27+ * Represents an OpenAI tool that can be used to define a function call in an OpenAI Chat Completion
28+ * request. This tool generates a JSON schema based on the provided class representing the
29+ * function's request structure.
2730 *
2831 * @param <I> the type of the input argument for the function
2932 * @see <a href="https://platform.openai.com/docs/guides/gpt/function-calling"/>OpenAI Function
3639@ AllArgsConstructor (access = AccessLevel .PRIVATE )
3740public class OpenAiTool <I > {
3841
42+ /** The schema generator used to create JSON schemas. */
43+ @ Nonnull private static final SchemaGenerator GENERATOR = createSchemaGenerator ();
44+
3945 /** The name of the function. */
40- private @ Nonnull String name ;
46+ @ Nonnull private String name ;
4147
4248 /** The model class for function request. */
43- private @ Nonnull Class <I > requestClass ;
49+ @ Nonnull private Class <I > requestClass ;
4450
4551 /** An optional description of the function. */
46- private @ Nullable String description ;
52+ @ Nullable private String description ;
4753
4854 /** An optional flag indicating whether the function parameters should be treated strictly. */
49- private @ Nullable Boolean strict ;
55+ @ Nullable private Boolean strict ;
5056
5157 /** The function to be called. */
52- private @ Nullable Function <I , ?> function ;
58+ @ Nullable private Function <I , ?> function ;
5359
5460 /**
5561 * Constructs an {@code OpenAiFunctionTool} with the specified name and a model class that
@@ -65,22 +71,16 @@ public OpenAiTool(@Nonnull final String name, @Nonnull final Class<I> requestCla
6571 @ Nonnull
6672 Object execute (@ Nonnull final I argument ) {
6773 if (getFunction () == null ) {
68- throw new IllegalStateException ("Function must not be set to execute the tool ." );
74+ throw new IllegalStateException ("No function configured to execute." );
6975 }
7076 return getFunction ().apply (argument );
7177 }
7278
7379 ChatCompletionTool createChatCompletionTool () {
74- final var objectMapper = new ObjectMapper ();
75- JsonSchema schema = null ;
76- try {
77- schema = new JsonSchemaGenerator (objectMapper ).generateSchema (getRequestClass ());
78- } catch (JsonMappingException e ) {
79- throw new IllegalArgumentException ("Could not generate schema for " + getRequestClass (), e );
80- }
81-
80+ final var schema = GENERATOR .generateSchema (getRequestClass ());
8281 final var schemaMap =
83- objectMapper .convertValue (schema , new TypeReference <Map <String , Object >>() {});
82+ OpenAiUtils .getOpenAiObjectMapper ()
83+ .convertValue (schema , new TypeReference <Map <String , Object >>() {});
8484
8585 final var function =
8686 new FunctionObject ()
@@ -90,4 +90,15 @@ ChatCompletionTool createChatCompletionTool() {
9090 .strict (getStrict ());
9191 return new ChatCompletionTool ().type (FUNCTION ).function (function );
9292 }
93+
94+ private static SchemaGenerator createSchemaGenerator () {
95+ final var module =
96+ new JacksonModule (
97+ JacksonOption .RESPECT_JSONPROPERTY_REQUIRED , JacksonOption .RESPECT_JSONPROPERTY_ORDER );
98+ return new SchemaGenerator (
99+ new SchemaGeneratorConfigBuilder (SchemaVersion .DRAFT_2020_12 , OptionPreset .PLAIN_JSON )
100+ .without (Option .SCHEMA_VERSION_INDICATOR )
101+ .with (module )
102+ .build ());
103+ }
93104}
0 commit comments