diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java index 7827f034d55..f0d424e29be 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java @@ -16,25 +16,9 @@ package org.springframework.ai.openai.api; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; -import java.util.function.Predicate; - -import com.fasterxml.jackson.annotation.JsonFormat; -import com.fasterxml.jackson.annotation.JsonIgnore; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.annotation.JsonInclude.Include; -import com.fasterxml.jackson.annotation.JsonProperty; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import org.springframework.ai.model.ApiKey; -import org.springframework.ai.model.ChatModelDescription; -import org.springframework.ai.model.ModelOptionsUtils; -import org.springframework.ai.model.SimpleApiKey; +import org.springframework.ai.model.*; import org.springframework.ai.openai.api.common.OpenAiApiConstants; import org.springframework.ai.retry.RetryUtils; import org.springframework.core.ParameterizedTypeReference; @@ -48,6 +32,14 @@ import org.springframework.web.client.ResponseErrorHandler; import org.springframework.web.client.RestClient; import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import java.util.function.Predicate; /** * Single class implementation of the @@ -200,7 +192,10 @@ public OpenAiApi(String baseUrl, ApiKey apiKey, MultiValueMap he this.embeddingsPath = embeddingsPath; // @formatter:off Consumer finalHeaders = h -> { - h.setBearerAuth(apiKey.getValue()); + if(!(apiKey instanceof NoopApiKey)) { + h.setBearerAuth(apiKey.getValue()); + } + h.setContentType(MediaType.APPLICATION_JSON); h.addAll(headers); }; diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java index 1f4ca2a590d..b68f1f63762 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java @@ -72,7 +72,14 @@ public OpenAiAudioApi(String openAiToken) { public OpenAiAudioApi(String baseUrl, String openAiToken, RestClient.Builder restClientBuilder, ResponseErrorHandler responseErrorHandler) { - Consumer authHeaders = h -> h.setBearerAuth(openAiToken); + Consumer authHeaders; + if (openAiToken != null && !openAiToken.isEmpty()) { + authHeaders = h -> h.setBearerAuth(openAiToken); + } + else { + authHeaders = h -> { + }; + } this.restClient = restClientBuilder.baseUrl(baseUrl) .defaultHeaders(authHeaders) @@ -111,7 +118,9 @@ public OpenAiAudioApi(String baseUrl, String apiKey, MultiValueMap authHeaders = h -> { - h.setBearerAuth(apiKey); + if (apiKey != null && !apiKey.isEmpty()) { + h.setBearerAuth(apiKey); + } h.addAll(headers); // h.setContentType(MediaType.APPLICATION_JSON); }; @@ -135,7 +144,7 @@ public ResponseEntity createSpeech(SpeechRequest requestBody) { /** * Streams audio generated from the input text. - * + *

* This method sends a POST request to the OpenAI API to generate audio from the * provided text. The audio is streamed back as a Flux of ResponseEntity objects, each * containing a byte array of the audio data. diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java index bfb846c0510..06f071a1b52 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java @@ -87,7 +87,9 @@ public OpenAiImageApi(String baseUrl, String apiKey, MultiValueMap { - h.setBearerAuth(apiKey); + if(apiKey != null && !apiKey.isEmpty()) { + h.setBearerAuth(apiKey); + } h.setContentType(MediaType.APPLICATION_JSON); h.addAll(headers); }) diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java index f4522dc0eab..9496df68763 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; - import org.springframework.ai.retry.RetryUtils; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -59,7 +58,9 @@ public OpenAiModerationApi(String baseUrl, String openAiToken, RestClient.Builde this.objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); this.restClient = restClientBuilder.baseUrl(baseUrl).defaultHeaders(h -> { - h.setBearerAuth(openAiToken); + if (openAiToken != null && !openAiToken.isEmpty()) { + h.setBearerAuth(openAiToken); + } h.setContentType(MediaType.APPLICATION_JSON); }).defaultStatusHandler(responseErrorHandler).build(); } diff --git a/spring-ai-core/src/main/java/org/springframework/ai/model/NoopApiKey.java b/spring-ai-core/src/main/java/org/springframework/ai/model/NoopApiKey.java new file mode 100644 index 00000000000..2b891813ba2 --- /dev/null +++ b/spring-ai-core/src/main/java/org/springframework/ai/model/NoopApiKey.java @@ -0,0 +1,14 @@ +package org.springframework.ai.model; + +/** + * This implementation of ApiKey indicates that no API key should be used, e.g. no HTTP + * headers should be set. + */ +public class NoopApiKey implements ApiKey { + + @Override + public String getValue() { + return ""; + } + +}