spring-ai icon indicating copy to clipboard operation
spring-ai copied to clipboard

OpenAI Auto Configuration failing to apply Webclient configuration instead of RestClient.

Open Adakole2020 opened this issue 1 year ago • 4 comments

Bug description The OpenAI autoconfiguration relies on an import of the restclient autoconfiguration or a webclient autoconfiguration. Commit 377b5ff attempts to fix it but fails to handle the situation when either is null. An @nullable annotation on both followed by a later check might be ideal.

Screenshot 2024-07-17 at 2 19 50 PM

Environment Spring-AI: 1.0.0-M1 Java: 21

Steps to reproduce Initiate chatClient in a reactive setup with no non-reactive dependency inclusions. Screenshot 2024-07-17 at 2 19 01 PM

Adakole2020 avatar Jul 17 '24 21:07 Adakole2020

Can you please share the complete error stack trace?

tzolov avatar Jul 18 '24 13:07 tzolov

Does this suffice?

Unsatisfied dependency expressed through constructor parameter 0: 
Error creating bean with name 'chatClientBuilder' defined in class path resource [org/springframework/ai/autoconfigure/chat/client/ChatClientAutoConfiguration.class]: Unsatisfied dependency expressed through method 'chatClientBuilder' parameter 1: 
Error creating bean with name 'openAiChatModel' defined in class path resource [org/springframework/ai/autoconfigure/openai/OpenAiAutoConfiguration.class]: Unsatisfied dependency expressed through method 'openAiChatModel' parameter 2: 
No qualifying bean of type 'org.springframework.web.client.RestClient$Builder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

Adakole2020 avatar Jul 18 '24 16:07 Adakole2020

I think this is a bug rather than an enhancement.

The failure occurs when trying to use spring-boot-starter-webflux. For example, the following two dependencies will trigger the problem:

<dependency>
	<groupId>org.springframework.ai</groupId>
	<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

Here's a start.spring.io link that will generate a project that reproduces the problem: https://start.spring.io/#!type=maven-project&language=java&platformVersion=3.3.4&packaging=jar&jvmVersion=17&groupId=com.example&artifactId=spring-ai-with-webflux&name=spring-ai-with-webflux&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.spring-ai-with-webflux&dependencies=spring-ai-openai,webflux.

Generate the project, unzip, and run ./mvnw spring-boot:run:

[INFO] --- spring-boot:3.3.4:run (default-cli) @ spring-ai-with-webflux ---
[INFO] Attaching agents: []

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.4)

2024-09-23T09:09:50.860+01:00  INFO 48009 --- [spring-ai-with-webflux] [           main] c.e.s.SpringAiWithWebfluxApplication     : Starting SpringAiWithWebfluxApplication using Java 17.0.12 with PID 48009 (/Users/awilkinson/Downloads/spring-ai-with-webflux/target/classes started by awilkinson in /Users/awilkinson/Downloads/spring-ai-with-webflux)
2024-09-23T09:09:50.863+01:00  INFO 48009 --- [spring-ai-with-webflux] [           main] c.e.s.SpringAiWithWebfluxApplication     : No active profile set, falling back to 1 default profile: "default"
2024-09-23T09:09:52.072+01:00  WARN 48009 --- [spring-ai-with-webflux] [           main] onfigReactiveWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'openAiChatModel' defined in class path resource [org/springframework/ai/autoconfigure/openai/OpenAiAutoConfiguration.class]: Unsatisfied dependency expressed through method 'openAiChatModel' parameter 2: No qualifying bean of type 'org.springframework.web.client.RestClient$Builder' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2024-09-23T09:09:52.081+01:00  INFO 48009 --- [spring-ai-with-webflux] [           main] .s.b.a.l.ConditionEvaluationReportLogger : 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-09-23T09:09:52.104+01:00 ERROR 48009 --- [spring-ai-with-webflux] [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 2 of method openAiChatModel in org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration required a bean of type 'org.springframework.web.client.RestClient$Builder' that could not be found.


Action:

Consider defining a bean of type 'org.springframework.web.client.RestClient$Builder' in your configuration.

wilkinsona avatar Sep 23 '24 08:09 wilkinsona

@tzolov Just faced this myself. Is this something only the core team can fix or can anyone submit a patch for it?

axymthr avatar Sep 30 '24 17:09 axymthr

related to https://github.com/spring-projects/spring-ai/issues/524

markpollack avatar Oct 06 '24 15:10 markpollack

I've experimented a bit with this and am not quite sure how to handle it. If one adds

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

or the actuator dependency to the sample app, then we get a RestClientBuilder autoconfigured.

However, in the spring-ai-openai module I didn't want to pull in spring-boot-starter-web as someone may want to create a console application. A console app wouldn't need to have dependencies such as embedded tomcat pulled in and would then need to set the spring.main.web-application-type=none or exclude the tomcat-ebmed deps?

[INFO] |     +- org.springframework.boot:spring-boot-starter-web:jar:3.3.4:compile
[INFO] |     |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:3.3.4:compile
[INFO] |     |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.30:compile
[INFO] |     |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:10.1.30:compile
[INFO] |     |  |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:10.1.30:compile
[INFO] |     |  \- org.springframework:spring-webmvc:jar:6.1.13:compile

I'm ok to live with that compromise if there isn't another way to just pick up the autoconfig for RestClient.

Thoughts @wilkinsona ?

markpollack avatar Oct 07 '24 16:10 markpollack

I think I'd use a dependency on spring-web rather than spring-boot-starter-web as I agree that the latter's much too broad in this situation. I'd also update the injection points for RestClient.Builder and WebClient.Builder to use ObjectProvider and only require one or the other (you could guard this with a custom AnyNestedCondition that nests classes that are @ConditionalOnBean(RestClient.Builder.class) and @ConditionalOnBean(WebClient.Builder.class)). That should give you something that works when someone is building a console app or build a web app using either spring-boot-starter-web or spring-boot-starter-webflux.

wilkinsona avatar Oct 07 '24 16:10 wilkinsona

#1550 should help resolving this issue.

tzolov avatar Oct 16 '24 10:10 tzolov

I can't use spring-ai latest release 1.0.0-M3 with spring.main.web-application-type=reactive. Application failed to start:

Parameter 2 of method openAiEmbeddingModel in org.springframework.ai.autoconfigure.openai.OpenAiAutoConfiguration required a bean of type 'org.springframework.web.client.RestClient$Builder' that could not be found.

In this case it should use WebClient with spring webflux.

fedecompa avatar Oct 24 '24 13:10 fedecompa

@fedecompa could you please test with 1.0.0-SNAPSHOT well (you will have to add the snapshot repository to your pom)? Also can you share, which spring boot starers have enabled in your POM?

tzolov avatar Oct 24 '24 14:10 tzolov

@tzolov this is my pom:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.4</version>
</parent>

<properties>
	<java.version>17</java.version>
	<spring.ai.bom.version>1.0.0-M3</spring.ai.bom.version>
</properties>


<dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>org.springframework.ai</groupId>
			<artifactId>spring-ai-bom</artifactId>
			<version>${spring.ai.bom.version}</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

<dependencies>

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-webflux</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.ai</groupId>
		<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
	</dependency>

	<dependency>
		<groupId>org.springframework.ai</groupId>
		<artifactId>spring-ai-pgvector-store-spring-boot-starter</artifactId>
	</dependency>
</dependencies>

	
	

fedecompa avatar Oct 28 '24 08:10 fedecompa

@tzolov with the 1.0.0-SNAPSHOT version it works! When will the fix be released? Thanks

fedecompa avatar Oct 28 '24 10:10 fedecompa