Given following code:
package be.vdab.localtimetest;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;
import java.time.LocalTime;
@SpringBootApplication
public class LocalTimeTestApplication {
public static void main(String[] args) {
SpringApplication.run(LocalTimeTestApplication.class, args);
}
}
@Component
class MyRunner implements CommandLineRunner {
private final ChatClient chatClient;
public MyRunner(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
@Override
public void run(String... args) throws Exception {
IO.println(chatClient.prompt("Is the shop open at 08:00 ?").tools(this).call().content());
}
@Tool(description = "Returns true if the shop is open at a certain time.")
boolean open(
@ToolParam(description = "The time for which you want to know if the shop is open.") LocalTime time) {
var hour = time.getHour();
return hour >= 10 && hour <= 18;
}
}
This works on version 2.0.0-M2,
but does not work anymore on versions 2.0.0-M3 and 2.0.0-M4, giving an exception:
java.lang.IllegalStateException: Conversion from JSON to java.time.LocalTime failed
at org.springframework.ai.util.json.JsonParser.fromJson(JsonParser.java:70) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.util.json.JsonParser.toTypedObject(JsonParser.java:177) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.tool.method.MethodToolCallback.buildTypedArgument(MethodToolCallback.java:157) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.tool.method.MethodToolCallback.lambda$buildMethodArguments$0(MethodToolCallback.java:147) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:214) ~[na:na]
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:1024) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:570) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:635) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:291) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:652) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:658) ~[na:na]
at org.springframework.ai.tool.method.MethodToolCallback.buildMethodArguments(MethodToolCallback.java:148) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.tool.method.MethodToolCallback.call(MethodToolCallback.java:107) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.model.tool.DefaultToolCallingManager.lambda$executeToolCall$3(DefaultToolCallingManager.java:228) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at io.micrometer.observation.Observation.observe(Observation.java:634) ~[micrometer-observation-1.16.4.jar:1.16.4]
at org.springframework.ai.model.tool.DefaultToolCallingManager.executeToolCall(DefaultToolCallingManager.java:225) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.model.tool.DefaultToolCallingManager.executeToolCalls(DefaultToolCallingManager.java:144) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.ollama.OllamaChatModel.internalCall(OllamaChatModel.java:295) ~[spring-ai-ollama-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.ollama.OllamaChatModel.call(OllamaChatModel.java:237) ~[spring-ai-ollama-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.chat.client.advisor.ChatModelCallAdvisor.adviseCall(ChatModelCallAdvisor.java:58) ~[spring-ai-client-chat-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.lambda$nextCall$1(DefaultAroundAdvisorChain.java:115) ~[spring-ai-client-chat-2.0.0-M4.jar:2.0.0-M4]
at io.micrometer.observation.Observation.observe(Observation.java:634) ~[micrometer-observation-1.16.4.jar:1.16.4]
at org.springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.nextCall(DefaultAroundAdvisorChain.java:114) ~[spring-ai-client-chat-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.lambda$doGetObservableChatClientResponse$1(DefaultChatClient.java:529) ~[spring-ai-client-chat-2.0.0-M4.jar:2.0.0-M4]
at io.micrometer.observation.Observation.observe(Observation.java:634) ~[micrometer-observation-1.16.4.jar:1.16.4]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetObservableChatClientResponse(DefaultChatClient.java:527) ~[spring-ai-client-chat-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.content(DefaultChatClient.java:507) ~[spring-ai-client-chat-2.0.0-M4.jar:2.0.0-M4]
at be.vdab.localtimetest.MyRunner.run(LocalTimeTestApplication.java:32) ~[main/:na]
at org.springframework.boot.SpringApplication.lambda$callRunner$1(SpringApplication.java:792) ~[spring-boot-4.0.5.jar:4.0.5]
at org.springframework.util.function.ThrowingConsumer$1.acceptWithException(ThrowingConsumer.java:82) ~[spring-core-7.0.6.jar:7.0.6]
at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:60) ~[spring-core-7.0.6.jar:7.0.6]
at org.springframework.util.function.ThrowingConsumer$1.accept(ThrowingConsumer.java:86) ~[spring-core-7.0.6.jar:7.0.6]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800) ~[spring-boot-4.0.5.jar:4.0.5]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:791) ~[spring-boot-4.0.5.jar:4.0.5]
at org.springframework.boot.SpringApplication.lambda$callRunners$0(SpringApplication.java:776) ~[spring-boot-4.0.5.jar:4.0.5]
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:186) ~[na:na]
at java.base/java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:357) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:571) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560) ~[na:na]
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:153) ~[na:na]
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:176) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:632) ~[na:na]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:776) ~[spring-boot-4.0.5.jar:4.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:328) ~[spring-boot-4.0.5.jar:4.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1365) ~[spring-boot-4.0.5.jar:4.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) ~[spring-boot-4.0.5.jar:4.0.5]
at be.vdab.localtimetest.LocalTimeTestApplication.main(LocalTimeTestApplication.java:17) ~[main/:na]
Caused by: tools.jackson.core.exc.StreamReadException: Invalid numeric value: Leading zeroes not allowed
You find the code on
https://github.com/hansdesmet/LocalTimeTest
Given following code:
This works on version 2.0.0-M2,
but does not work anymore on versions 2.0.0-M3 and 2.0.0-M4, giving an exception:
java.lang.IllegalStateException: Conversion from JSON to java.time.LocalTime failed
at org.springframework.ai.util.json.JsonParser.fromJson(JsonParser.java:70) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.util.json.JsonParser.toTypedObject(JsonParser.java:177) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.tool.method.MethodToolCallback.buildTypedArgument(MethodToolCallback.java:157) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.tool.method.MethodToolCallback.lambda$buildMethodArguments$0(MethodToolCallback.java:147) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:214) ~[na:na]
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:1024) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:570) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:635) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:291) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:652) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:658) ~[na:na]
at org.springframework.ai.tool.method.MethodToolCallback.buildMethodArguments(MethodToolCallback.java:148) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.tool.method.MethodToolCallback.call(MethodToolCallback.java:107) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.model.tool.DefaultToolCallingManager.lambda$executeToolCall$3(DefaultToolCallingManager.java:228) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at io.micrometer.observation.Observation.observe(Observation.java:634) ~[micrometer-observation-1.16.4.jar:1.16.4]
at org.springframework.ai.model.tool.DefaultToolCallingManager.executeToolCall(DefaultToolCallingManager.java:225) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.model.tool.DefaultToolCallingManager.executeToolCalls(DefaultToolCallingManager.java:144) ~[spring-ai-model-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.ollama.OllamaChatModel.internalCall(OllamaChatModel.java:295) ~[spring-ai-ollama-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.ollama.OllamaChatModel.call(OllamaChatModel.java:237) ~[spring-ai-ollama-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.chat.client.advisor.ChatModelCallAdvisor.adviseCall(ChatModelCallAdvisor.java:58) ~[spring-ai-client-chat-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.lambda$nextCall$1(DefaultAroundAdvisorChain.java:115) ~[spring-ai-client-chat-2.0.0-M4.jar:2.0.0-M4]
at io.micrometer.observation.Observation.observe(Observation.java:634) ~[micrometer-observation-1.16.4.jar:1.16.4]
at org.springframework.ai.chat.client.advisor.DefaultAroundAdvisorChain.nextCall(DefaultAroundAdvisorChain.java:114) ~[spring-ai-client-chat-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.lambda$doGetObservableChatClientResponse$1(DefaultChatClient.java:529) ~[spring-ai-client-chat-2.0.0-M4.jar:2.0.0-M4]
at io.micrometer.observation.Observation.observe(Observation.java:634) ~[micrometer-observation-1.16.4.jar:1.16.4]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.doGetObservableChatClientResponse(DefaultChatClient.java:527) ~[spring-ai-client-chat-2.0.0-M4.jar:2.0.0-M4]
at org.springframework.ai.chat.client.DefaultChatClient$DefaultCallResponseSpec.content(DefaultChatClient.java:507) ~[spring-ai-client-chat-2.0.0-M4.jar:2.0.0-M4]
at be.vdab.localtimetest.MyRunner.run(LocalTimeTestApplication.java:32) ~[main/:na]
at org.springframework.boot.SpringApplication.lambda$callRunner$1(SpringApplication.java:792) ~[spring-boot-4.0.5.jar:4.0.5]
at org.springframework.util.function.ThrowingConsumer$1.acceptWithException(ThrowingConsumer.java:82) ~[spring-core-7.0.6.jar:7.0.6]
at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:60) ~[spring-core-7.0.6.jar:7.0.6]
at org.springframework.util.function.ThrowingConsumer$1.accept(ThrowingConsumer.java:86) ~[spring-core-7.0.6.jar:7.0.6]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800) ~[spring-boot-4.0.5.jar:4.0.5]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:791) ~[spring-boot-4.0.5.jar:4.0.5]
at org.springframework.boot.SpringApplication.lambda$callRunners$0(SpringApplication.java:776) ~[spring-boot-4.0.5.jar:4.0.5]
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:186) ~[na:na]
at java.base/java.util.stream.SortedOps$SizedRefSortingSink.end(SortedOps.java:357) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:571) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:560) ~[na:na]
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:153) ~[na:na]
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:176) ~[na:na]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:265) ~[na:na]
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:632) ~[na:na]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:776) ~[spring-boot-4.0.5.jar:4.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:328) ~[spring-boot-4.0.5.jar:4.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1365) ~[spring-boot-4.0.5.jar:4.0.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1354) ~[spring-boot-4.0.5.jar:4.0.5]
at be.vdab.localtimetest.LocalTimeTestApplication.main(LocalTimeTestApplication.java:17) ~[main/:na]
Caused by: tools.jackson.core.exc.StreamReadException: Invalid numeric value: Leading zeroes not allowed
You find the code on
https://github.com/hansdesmet/LocalTimeTest