spring-projects / spring-ai

An Application Framework for AI Engineering
https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/index.html
Apache License 2.0
2.83k stars 705 forks source link

AzureOpenAiChatModel stream skip(1) cause functionName is null #1033

Closed jacklvyx closed 1 month ago

jacklvyx commented 1 month ago

Bug description

AzureOpenAiChatModel.class method: stream(Prompt prompt) // Note: the first chat completions can be ignored when using Azure OpenAI // service which is a known service bug. .skip(1) commit https://github.com/spring-projects/spring-ai/commit/0ccf32780696af284794ee0f8420857dc1cce6a3#diff-008124b444ef3c62065ae60104221890d1bb876c01ea71501d34eeb040e7f210R197

bug: The first data returned specifies the name of FunctionCalling and other information, which will be lost after being skipped, eventually resulting in a null pointer.

model:gpt4o-0513

image

- exception

2024-07-12 15:57:00 [task-2] ERROR org.springframework.ai.chat.model.MessageAggregator - Aggregation Error java.lang.NullPointerException: Cannot invoke "Object.hashCode()" because "key" is null at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936) ~[?:?] at java.base/java.util.concurrent.ConcurrentHashMap.containsKey(ConcurrentHashMap.java:964) ~[?:?] at org.springframework.ai.azure.openai.AzureOpenAiChatModel.doCreateToolResponseRequest(AzureOpenAiChatModel.java:551) ~[spring-ai-azure-openai-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT] at org.springframework.ai.azure.openai.AzureOpenAiChatModel.doCreateToolResponseRequest(AzureOpenAiChatModel.java:85) ~[spring-ai-azure-openai-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT] at org.springframework.ai.model.function.AbstractFunctionCallSupport.lambda$handleFunctionCallOrReturnStream$1(AbstractFunctionCallSupport.java:176) ~[spring-ai-core-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT] at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:153) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxSwitchMapNoPrefetch.subscribeOrReturn(FluxSwitchMapNoPrefetch.java:61) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.Flux.subscribe(Flux.java:8825) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxSwitchMapNoPrefetch$SwitchMapMain.subscribeInner(FluxSwitchMapNoPrefetch.java:219) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxSwitchMapNoPrefetch$SwitchMapMain.onNext(FluxSwitchMapNoPrefetch.java:164) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxFlatMap$FlatMapMain.tryEmit(FluxFlatMap.java:547) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxFlatMap$FlatMapInner.onNext(FluxFlatMap.java:988) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.Operators$BaseFluxToMonoOperator.completePossiblyEmpty(Operators.java:2097) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.MonoReduceSeed$ReduceSeedSubscriber.onComplete(MonoReduceSeed.java:163) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxWindowPredicate$WindowFlux.checkTerminated(FluxWindowPredicate.java:768) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxWindowPredicate$WindowFlux.drainRegular(FluxWindowPredicate.java:662) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxWindowPredicate$WindowFlux.drain(FluxWindowPredicate.java:748) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxWindowPredicate$WindowFlux.onComplete(FluxWindowPredicate.java:814) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxWindowPredicate$WindowPredicateMain.onNext(FluxWindowPredicate.java:243) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxMap$MapSubscriber.onNext(FluxMap.java:122) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxSkip$SkipSubscriber.onNext(FluxSkip.java:87) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:335) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:294) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxSkip$SkipSubscriber.request(FluxSkip.java:121) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxMap$MapSubscriber.request(FluxMap.java:164) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxWindowPredicate$WindowPredicateMain.onSubscribe(FluxWindowPredicate.java:188) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxMap$MapSubscriber.onSubscribe(FluxMap.java:92) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxSkip$SkipSubscriber.onSubscribe(FluxSkip.java:78) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:201) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:83) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.Flux.subscribe(Flux.java:8840) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.Flux.subscribeWith(Flux.java:8961) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.Flux.subscribe(Flux.java:8805) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.Flux.subscribe(Flux.java:8729) ~[reactor-core-3.6.4.jar:3.6.4] at reactor.core.publisher.Flux.subscribe(Flux.java:8647) ~[reactor-core-3.6.4.jar:3.6.4] at org.intellitech.engine.themeagent.agent.AbsAgent.stream(AbsAgent.java:205) ~[main/:?] at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?] at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:351) ~[spring-aop-6.1.5.jar:6.1.5] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.5.jar:6.1.5] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.5.jar:6.1.5] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:765) ~[spring-aop-6.1.5.jar:6.1.5] at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:113) ~[spring-aop-6.1.5.jar:6.1.5] at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317) ~[?:?] at java.base/java.lang.VirtualThread.run(VirtualThread.java:309) ~[?:?]

jacklvyx commented 1 month ago

@tzolov found This issue is addressed by the https://github.com/spring-projects/spring-ai/commit/feb036d2f6534505ad0bdac12925f93a52737e73

tzolov commented 1 month ago

@jacklvyx is it working as expected now?

tzolov commented 1 month ago

Closing as resolved by https://github.com/spring-projects/spring-ai/commit/feb036d2f6534505ad0bdac12925f93a52737e73 @jacklvyx if the problem is still present please re-open the issue.