Skip to content

Commit 06028a5

Browse files
sobychackoleijendary
authored andcommitted
Convert API records to POJOs and fix failing autconfig tests
Following removal of Spring Boot's ConstructorBinding, convert record types to regular POJOs to maintain JSON serialization. Update API classes: - Convert FunctionTool and Function records to standard Java classes with getters/setters - Update test assertions to use getter methods instead of record accessors - Fix failing tests in MiniMax, OpenAi and ZhiPu API implementations This keeps core API models independent of Spring Boot while ensuring proper serialization through standard Java beans. - MistralAIApi FunctionTool ConstructorBinding removal changes Signed-off-by: leijendary <[email protected]>
1 parent 7cd05f4 commit 06028a5

File tree

21 files changed

+704
-169
lines changed

21 files changed

+704
-169
lines changed

models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/MiniMaxChatModel.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
import org.springframework.ai.minimax.api.MiniMaxApi.ChatCompletionMessage.Role;
6161
import org.springframework.ai.minimax.api.MiniMaxApi.ChatCompletionMessage.ToolCall;
6262
import org.springframework.ai.minimax.api.MiniMaxApi.ChatCompletionRequest;
63-
import org.springframework.ai.minimax.api.MiniMaxApi.FunctionTool;
6463
import org.springframework.ai.minimax.api.MiniMaxApiConstants;
6564
import org.springframework.ai.minimax.metadata.MiniMaxUsage;
6665
import org.springframework.ai.model.ModelOptionsUtils;
@@ -508,11 +507,11 @@ else if (message.getMessageType() == MessageType.TOOL) {
508507
return request;
509508
}
510509

511-
private List<FunctionTool> getFunctionTools(Set<String> functionNames) {
510+
private List<MiniMaxApi.FunctionTool> getFunctionTools(Set<String> functionNames) {
512511
return this.resolveFunctionCallbacks(functionNames).stream().map(functionCallback -> {
513-
var function = new FunctionTool.Function(functionCallback.getDescription(), functionCallback.getName(),
514-
functionCallback.getInputTypeSchema());
515-
return new FunctionTool(function);
512+
var function = new MiniMaxApi.FunctionTool.Function(functionCallback.getDescription(),
513+
functionCallback.getName(), functionCallback.getInputTypeSchema());
514+
return new MiniMaxApi.FunctionTool(function);
516515
}).toList();
517516
}
518517

models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApi.java

Lines changed: 128 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -331,14 +331,35 @@ public String getValue() {
331331

332332
/**
333333
* Represents a tool the model may call. Currently, only functions are supported as a tool.
334-
*
335-
* @param type The type of the tool. Currently, only 'function' is supported.
336-
* @param function The function definition.
337334
*/
338-
@JsonInclude(Include.NON_NULL)
339-
public record FunctionTool(
340-
@JsonProperty("type") Type type,
341-
@JsonProperty("function") Function function) {
335+
@JsonInclude(JsonInclude.Include.NON_NULL)
336+
public static class FunctionTool {
337+
338+
/**
339+
* The type of the tool. Currently, only 'function' is supported.
340+
*/
341+
private Type type = Type.FUNCTION;
342+
343+
/**
344+
* The function definition.
345+
*/
346+
private Function function;
347+
348+
public FunctionTool() {
349+
350+
}
351+
352+
/**
353+
* Create a tool of type 'function' and the given function definition.
354+
* @param type the tool type
355+
* @param function function definition
356+
*/
357+
public FunctionTool(
358+
@JsonProperty("type") Type type,
359+
@JsonProperty("function") Function function) {
360+
this.type = type;
361+
this.function = function;
362+
}
342363

343364
/**
344365
* Create a tool of type 'function' and the given function definition.
@@ -348,8 +369,22 @@ public FunctionTool(Function function) {
348369
this(Type.FUNCTION, function);
349370
}
350371

351-
public static FunctionTool webSearchFunctionTool() {
352-
return new FunctionTool(Type.WEB_SEARCH, null);
372+
@JsonProperty("type")
373+
public Type getType() {
374+
return this.type;
375+
}
376+
377+
@JsonProperty("function")
378+
public Function getFunction() {
379+
return this.function;
380+
}
381+
382+
public void setType(Type type) {
383+
this.type = type;
384+
}
385+
386+
public void setFunction(Function function) {
387+
this.function = function;
353388
}
354389

355390
/**
@@ -361,35 +396,104 @@ public enum Type {
361396
*/
362397
@JsonProperty("function")
363398
FUNCTION,
399+
364400
@JsonProperty("web_search")
365401
WEB_SEARCH
366402
}
367403

404+
public static FunctionTool webSearchFunctionTool() {
405+
return new FunctionTool(FunctionTool.Type.WEB_SEARCH, null);
406+
}
407+
408+
368409
/**
369410
* Function definition.
370-
*
371-
* @param description A description of what the function does, used by the model to choose when and how to call
372-
* the function.
373-
* @param name The name of the function to be called. Must be a-z, A-Z, 0-9, or contain underscores and dashes,
374-
* with a maximum length of 64.
375-
* @param parameters The parameters the functions accepts, described as a JSON Schema object. To describe a
376-
* function that accepts no parameters, provide the value {"type": "object", "properties": {}}.
377-
*/
378-
public record Function(
379-
@JsonProperty("description") String description,
380-
@JsonProperty("name") String name,
381-
@JsonProperty("parameters") String parameters) {
411+
*/
412+
public static class Function {
413+
414+
@JsonProperty("description")
415+
private String description;
416+
417+
@JsonProperty("name")
418+
private String name;
419+
420+
@JsonProperty("parameters")
421+
private Map<String, Object> parameters;
422+
423+
private String jsonSchema;
424+
425+
private Function() {
426+
427+
}
428+
429+
/**
430+
* Create tool function definition.
431+
*
432+
* @param description A description of what the function does, used by the model to choose when and how to call
433+
* the function.
434+
* @param name The name of the function to be called. Must be a-z, A-Z, 0-9, or contain underscores and dashes,
435+
* with a maximum length of 64.
436+
* @param parameters The parameters the functions accepts, described as a JSON Schema object. To describe a
437+
* function that accepts no parameters, provide the value {"type": "object", "properties": {}}.
438+
*/
439+
public Function(
440+
String description,
441+
String name,
442+
Map<String, Object> parameters) {
443+
this.description = description;
444+
this.name = name;
445+
this.parameters = parameters;
446+
}
382447

383448
/**
384449
* Create tool function definition.
385450
*
386451
* @param description tool function description.
387452
* @param name tool function name.
388-
* @param parameters tool function schema.
453+
* @param jsonSchema tool function schema as json.
389454
*/
390-
public Function(String description, String name, Map<String, Object> parameters) {
391-
this(description, name, ModelOptionsUtils.toJsonString(parameters));
455+
public Function(String description, String name, String jsonSchema) {
456+
this(description, name, ModelOptionsUtils.jsonToMap(jsonSchema));
457+
}
458+
459+
@JsonProperty("description")
460+
public String getDescription() {
461+
return this.description;
392462
}
463+
464+
@JsonProperty("name")
465+
public String getName() {
466+
return this.name;
467+
}
468+
469+
@JsonProperty("parameters")
470+
public Map<String, Object> getParameters() {
471+
return this.parameters;
472+
}
473+
474+
public void setDescription(String description) {
475+
this.description = description;
476+
}
477+
478+
public void setName(String name) {
479+
this.name = name;
480+
}
481+
482+
public void setParameters(Map<String, Object> parameters) {
483+
this.parameters = parameters;
484+
}
485+
486+
public String getJsonSchema() {
487+
return this.jsonSchema;
488+
}
489+
490+
public void setJsonSchema(String jsonSchema) {
491+
this.jsonSchema = jsonSchema;
492+
if (jsonSchema != null) {
493+
this.parameters = ModelOptionsUtils.jsonToMap(jsonSchema);
494+
}
495+
}
496+
393497
}
394498
}
395499

models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/ChatCompletionRequestTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public void promptOptionsTools() {
8383
assertThat(request.model()).isEqualTo("PROMPT_MODEL");
8484

8585
assertThat(request.tools()).hasSize(1);
86-
assertThat(request.tools().get(0).function().name()).isEqualTo(TOOL_FUNCTION_NAME);
86+
assertThat(request.tools().get(0).getFunction().getName()).isEqualTo(TOOL_FUNCTION_NAME);
8787
}
8888

8989
@Test
@@ -120,7 +120,7 @@ public void defaultOptionsTools() {
120120
MiniMaxChatOptions.builder().withFunction(TOOL_FUNCTION_NAME).build()), false);
121121

122122
assertThat(request.tools()).hasSize(1);
123-
assertThat(request.tools().get(0).function().name()).as("Explicitly enabled function")
123+
assertThat(request.tools().get(0).getFunction().getName()).as("Explicitly enabled function")
124124
.isEqualTo(TOOL_FUNCTION_NAME);
125125

126126
// Override the default options function with one from the prompt
@@ -134,7 +134,7 @@ public void defaultOptionsTools() {
134134
false);
135135

136136
assertThat(request.tools()).hasSize(1);
137-
assertThat(request.tools().get(0).function().name()).as("Explicitly enabled function")
137+
assertThat(request.tools().get(0).getFunction().getName()).as("Explicitly enabled function")
138138
.isEqualTo(TOOL_FUNCTION_NAME);
139139

140140
assertThat(client.getFunctionCallbackRegister()).hasSize(1);

models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/api/MiniMaxApiToolFunctionCallIT.java

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import org.springframework.ai.minimax.api.MiniMaxApi.ChatCompletionMessage.ToolCall;
3434
import org.springframework.ai.minimax.api.MiniMaxApi.ChatCompletionRequest;
3535
import org.springframework.ai.minimax.api.MiniMaxApi.ChatCompletionRequest.ToolChoiceBuilder;
36-
import org.springframework.ai.minimax.api.MiniMaxApi.FunctionTool.Type;
3736
import org.springframework.http.ResponseEntity;
3837

3938
import static org.assertj.core.api.Assertions.assertThat;
@@ -67,31 +66,33 @@ public void toolFunctionCall() {
6766
var message = new ChatCompletionMessage(
6867
"What's the weather like in San Francisco? Return the temperature in Celsius.", Role.USER);
6968

70-
var functionTool = new MiniMaxApi.FunctionTool(Type.FUNCTION, new MiniMaxApi.FunctionTool.Function(
71-
"Get the weather in location. Return temperature in 30°F or 30°C format.", "getCurrentWeather", """
72-
{
73-
"type": "object",
74-
"properties": {
75-
"location": {
76-
"type": "string",
77-
"description": "The city and state e.g. San Francisco, CA"
78-
},
79-
"lat": {
80-
"type": "number",
81-
"description": "The city latitude"
82-
},
83-
"lon": {
84-
"type": "number",
85-
"description": "The city longitude"
86-
},
87-
"unit": {
88-
"type": "string",
89-
"enum": ["C", "F"]
69+
var functionTool = new MiniMaxApi.FunctionTool(MiniMaxApi.FunctionTool.Type.FUNCTION,
70+
new MiniMaxApi.FunctionTool.Function(
71+
"Get the weather in location. Return temperature in 30°F or 30°C format.", "getCurrentWeather",
72+
"""
73+
{
74+
"type": "object",
75+
"properties": {
76+
"location": {
77+
"type": "string",
78+
"description": "The city and state e.g. San Francisco, CA"
79+
},
80+
"lat": {
81+
"type": "number",
82+
"description": "The city latitude"
83+
},
84+
"lon": {
85+
"type": "number",
86+
"description": "The city longitude"
87+
},
88+
"unit": {
89+
"type": "string",
90+
"enum": ["C", "F"]
91+
}
92+
},
93+
"required": ["location", "lat", "lon", "unit"]
9094
}
91-
},
92-
"required": ["location", "lat", "lon", "unit"]
93-
}
94-
"""));
95+
"""));
9596

9697
List<ChatCompletionMessage> messages = new ArrayList<>(List.of(message));
9798

0 commit comments

Comments
 (0)