We are using AnthropicChatModel with function calling. Model: Sonnet 3.5 v2 We send browser screenshot to the LLM with several tools available. Everything was working smoothly until today. Functions are set according to the documentation. Example of one of our functions: @Bean @Description("Mouse click at coordinates.") public Function<OnlyCoordinates, String> click() { return coordinates -> { browserInteractor.moveMouseAndClick(coordinates.getCoordinates().getX(), coordinates.getCoordinates().getY()); return "success"; }; }

Bug description With fresh Snapshot artifact Spirng AI fails during model call. Stacktrace: `2024-11-06T20:25:10.924+08:00 ERROR 14230 --- [discovery] [ main] o.s.boot.SpringApplication : Application run failed

java.lang.IllegalArgumentException: Type must be a Function, BiFunction, Function1 or Function2. Found: ? at org.springframework.ai.model.function.TypeResolverHelper.getFunctionArgumentType(TypeResolverHelper.java:119) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT] at org.springframework.ai.model.function.FunctionCallbackContext.getFunctionCallback(FunctionCallbackContext.java:84) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT] at org.springframework.ai.chat.model.AbstractToolCallSupport.resolveFunctionCallbacks(AbstractToolCallSupport.java:174) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT] at org.springframework.ai.anthropic.AnthropicChatModel.getFunctionTools(AnthropicChatModel.java:450) ~[spring-ai-anthropic-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT] at org.springframework.ai.anthropic.AnthropicChatModel.createRequest(AnthropicChatModel.java:441) ~[spring-ai-anthropic-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT] at org.springframework.ai.anthropic.AnthropicChatModel.call(AnthropicChatModel.java:212) ~[spring-ai-anthropic-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT] at com.legalmonkeys.discovery.service.PortalStatusUpdateService.foo1(PortalStatusUpdateService.java:119) ~[main/:na] at com.legalmonkeys.discovery.DiscoveryApplication.run(DiscoveryApplication.java:56) ~[main/:na] at org.springframework.boot.SpringApplication.lambda$callRunner$5(SpringApplication.java:790) ~[spring-boot-3.3.4.jar:3.3.4] at org.springframework.util.function.ThrowingConsumer$1.acceptWithException(ThrowingConsumer.java:83) ~[spring-core-6.1.13.jar:6.1.13] at org.springframework.util.function.ThrowingConsumer.accept(ThrowingConsumer.java:60) ~[spring-core-6.1.13.jar:6.1.13] at org.springframework.util.function.ThrowingConsumer$1.accept(ThrowingConsumer.java:88) ~[spring-core-6.1.13.jar:6.1.13] at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) ~[spring-boot-3.3.4.jar:3.3.4] at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:789) ~[spring-boot-3.3.4.jar:3.3.4] at org.springframework.boot.SpringApplication.lambda$callRunners$3(SpringApplication.java:774) ~[spring-boot-3.3.4.jar:3.3.4] at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) ~[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:510) ~[na:na] at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na] at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) ~[na:na] at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) ~[na:na] at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na] at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[na:na] at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:774) ~[spring-boot-3.3.4.jar:3.3.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:342) ~[spring-boot-3.3.4.jar:3.3.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.4.jar:3.3.4] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.4.jar:3.3.4] at com.legalmonkeys.discovery.DiscoveryApplication.main(DiscoveryApplication.java:32) ~[main/:na]`

Environment implementation platform("org.springframework.ai:spring-ai-bom:1.0.0-SNAPSHOT") implementation 'org.springframework.ai:spring-ai-anthropic-spring-boot-starter' Java 21

Steps to reproduce Create a function, register it into options and call model with that options.

Expected behavior sucessful LLM call with tool usage.

We tried to switch to M3, but app became slower and LLM responses with tool usage are less precise

Comment From: ThomasVitale

Looks like to be a consequence of https://github.com/spring-projects/spring-ai/commit/9cf66333b5f0e36753f1a74931a59b8ace68bdec

It's also failing for me. Demo with error: https://github.com/ThomasVitale/llm-apps-java-spring-ai/tree/main/05-function-calling/function-calling-openai

Error:

java.lang.IllegalArgumentException: Type must be a Function, BiFunction, Function1 or Function2. Found: ?
    at org.springframework.ai.model.function.TypeResolverHelper.getFunctionArgumentType(TypeResolverHelper.java:119) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at org.springframework.ai.model.function.FunctionCallbackContext.getFunctionCallback(FunctionCallbackContext.java:84) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at org.springframework.ai.chat.model.AbstractToolCallSupport.resolveFunctionCallbacks(AbstractToolCallSupport.java:174) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at org.springframework.ai.openai.OpenAiChatModel.getFunctionTools(OpenAiChatModel.java:528) ~[spring-ai-openai-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at org.springframework.ai.openai.OpenAiChatModel.createRequest(OpenAiChatModel.java:498) ~[spring-ai-openai-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at org.springframework.ai.openai.OpenAiChatModel.call(OpenAiChatModel.java:214) ~[spring-ai-openai-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    at org.springframework.ai.chat.client.DefaultChatClient$DefaultChatClientRequestSpec$1.aroundCall(DefaultChatClient.java:675) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]
    ...

Comment From: markpollack

ok, wow, can't believe our IT tests didn't catch this. We are investigating to see if there is a quick fix and if not will revert the commit with kotlin funciton support.

Comment From: sdeleuze

@ThomasVitale Sorry for the regression, we are likely going to revert my commit, add more IT tests and I will provide a refined version of my contribution. Thanks for catching it.

Comment From: markpollack

CI is running, when green this commit will have been reverted. Thanks for the quick report @piratovi

Comment From: piratovi

Thank you guys for the very quick fix!