diff --git a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApi.java b/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApi.java
index 5b728b641..57492a926 100644
--- a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApi.java
+++ b/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApi.java
@@ -19,10 +19,10 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
-
import org.springframework.ai.model.ModelDescription;
import org.springframework.ai.model.ModelOptionsUtils;
import org.springframework.ai.retry.RetryUtils;
+import org.springframework.ai.util.api.ApiUtils;
import org.springframework.boot.context.properties.bind.ConstructorBinding;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.ResponseEntity;
@@ -41,8 +41,8 @@ import java.util.function.Predicate;
// @formatter:off
/**
- * Single class implementation of the MiniMax Chat Completion API: https://www.minimaxi.com/document/guides/chat-model/V2 and
- * MiniMax Embedding API: https://www.minimaxi.com/document/guides/Embeddings.
+ * Single class implementation of the MiniMax Chat Completion API and
+ * MiniMax Embedding API.
*
* @author Geng Rong
* @since 1.0.0 M1
@@ -63,7 +63,7 @@ public class MiniMaxApi {
* @param miniMaxToken MiniMax apiKey.
*/
public MiniMaxApi(String miniMaxToken) {
- this(ApiUtils.DEFAULT_BASE_URL, miniMaxToken);
+ this(MiniMaxApiConstants.DEFAULT_BASE_URL, miniMaxToken);
}
/**
diff --git a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApiConstants.java b/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApiConstants.java
new file mode 100644
index 000000000..bc1b8d139
--- /dev/null
+++ b/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/MiniMaxApiConstants.java
@@ -0,0 +1,13 @@
+package org.springframework.ai.minimax.api;
+
+/**
+ * Common value constants for MiniMax api.
+ *
+ * @author Piotr Olaszewski
+ * @since 1.0.0 M2
+ */
+public final class MiniMaxApiConstants {
+
+ public static final String DEFAULT_BASE_URL = "https://api.minimax.chat";
+
+}
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/ApiUtils.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/ApiUtils.java
deleted file mode 100644
index 36ad4b8f7..000000000
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/ApiUtils.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2023 - 2024 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.ai.openai.api;
-
-import java.util.function.Consumer;
-
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-
-/**
- * @author Christian Tzolov
- */
-public class ApiUtils {
-
- public static final String DEFAULT_BASE_URL = "https://api.openai.com";
-
- public static Consumer getJsonContentHeaders(String apiKey) {
- return (headers) -> {
- headers.setBearerAuth(apiKey);
- headers.setContentType(MediaType.APPLICATION_JSON);
- };
- };
-
-}
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 796874d35..64df4e92d 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
@@ -28,7 +28,9 @@ import reactor.core.publisher.Mono;
import org.springframework.ai.model.ModelDescription;
import org.springframework.ai.model.ModelOptionsUtils;
+import org.springframework.ai.openai.api.common.OpenAiApiConstants;
import org.springframework.ai.retry.RetryUtils;
+import org.springframework.ai.util.api.ApiUtils;
import org.springframework.boot.context.properties.bind.ConstructorBinding;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.ResponseEntity;
@@ -62,7 +64,7 @@ public class OpenAiApi {
* @param openAiToken OpenAI apiKey.
*/
public OpenAiApi(String openAiToken) {
- this(ApiUtils.DEFAULT_BASE_URL, openAiToken);
+ this(OpenAiApiConstants.DEFAULT_BASE_URL, openAiToken);
}
/**
@@ -280,7 +282,7 @@ public class OpenAiApi {
}
}
- /**
+ /**
* Creates a model response for the given chat conversation.
*
* @param messages A list of messages comprising the conversation so far.
@@ -393,7 +395,7 @@ public class OpenAiApi {
tools, toolChoice, null);
}
- /**
+ /**
* Shortcut constructor for a chat completion request with the given messages for streaming.
*
* @param messages A list of messages comprising the conversation so far.
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 3daa981ec..77f4eb70e 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
@@ -21,7 +21,9 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonProperty;
+import org.springframework.ai.openai.api.common.OpenAiApiConstants;
import org.springframework.ai.retry.RetryUtils;
+import org.springframework.ai.util.api.ApiUtils;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
@@ -49,11 +51,11 @@ public class OpenAiAudioApi {
private final WebClient webClient;
/**
- * Create an new audio api.
+ * Create a new audio api.
* @param openAiToken OpenAI apiKey.
*/
public OpenAiAudioApi(String openAiToken) {
- this(ApiUtils.DEFAULT_BASE_URL, openAiToken, RestClient.builder(), WebClient.builder(),
+ this(OpenAiApiConstants.DEFAULT_BASE_URL, openAiToken, RestClient.builder(), WebClient.builder(),
RetryUtils.DEFAULT_RESPONSE_ERROR_HANDLER);
}
@@ -710,4 +712,4 @@ public class OpenAiAudioApi {
.toEntity(responseType);
}
-}
\ No newline at end of file
+}
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 18b3d0bff..f508939b2 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
@@ -20,7 +20,9 @@ import java.util.List;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import org.springframework.ai.openai.api.common.OpenAiApiConstants;
import org.springframework.ai.retry.RetryUtils;
+import org.springframework.ai.util.api.ApiUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.client.ResponseErrorHandler;
@@ -38,11 +40,11 @@ public class OpenAiImageApi {
private final RestClient restClient;
/**
- * Create a new OpenAI Image api with base URL set to https://api.openai.com
+ * Create a new OpenAI Image api with base URL set to {@code https://api.openai.com}.
* @param openAiToken OpenAI apiKey.
*/
public OpenAiImageApi(String openAiToken) {
- this(ApiUtils.DEFAULT_BASE_URL, openAiToken, RestClient.builder());
+ this(OpenAiApiConstants.DEFAULT_BASE_URL, openAiToken, RestClient.builder());
}
/**
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/OpenAiApiConstants.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/OpenAiApiConstants.java
new file mode 100644
index 000000000..a6069bc2e
--- /dev/null
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/common/OpenAiApiConstants.java
@@ -0,0 +1,13 @@
+package org.springframework.ai.openai.api.common;
+
+/**
+ * Common value constants for OpenAI api.
+ *
+ * @author Piotr Olaszewski
+ * @since 1.0.0 M2
+ */
+public final class OpenAiApiConstants {
+
+ public static final String DEFAULT_BASE_URL = "https://api.openai.com";
+
+}
diff --git a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ApiUtils.java b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ApiUtils.java
deleted file mode 100644
index ca5a96a80..000000000
--- a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ApiUtils.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright 2024 - 2024 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.ai.zhipuai.api;
-
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.MediaType;
-
-import java.util.function.Consumer;
-
-/**
- * @author Geng Rong
- */
-public class ApiUtils {
-
- public static final String DEFAULT_BASE_URL = "https://open.bigmodel.cn/api/paas";
-
- public static Consumer getJsonContentHeaders(String apiKey) {
- return (headers) -> {
- headers.setBearerAuth(apiKey);
- headers.setContentType(MediaType.APPLICATION_JSON);
- };
- };
-
-}
diff --git a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java
index 45e21a500..56c45214d 100644
--- a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java
+++ b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiApi.java
@@ -22,6 +22,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.ai.model.ModelDescription;
import org.springframework.ai.model.ModelOptionsUtils;
import org.springframework.ai.retry.RetryUtils;
+import org.springframework.ai.util.api.ApiUtils;
import org.springframework.boot.context.properties.bind.ConstructorBinding;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.ResponseEntity;
@@ -40,8 +41,8 @@ import java.util.function.Predicate;
// @formatter:off
/**
- * Single class implementation of the ZhiPuAI Chat Completion API: https://open.bigmodel.cn/dev/api#http and
- * ZhiPuAI Embedding API: https://open.bigmodel.cn/dev/api#text_embedding.
+ * Single class implementation of the ZhiPuAI Chat Completion API and
+ * ZhiPuAI Embedding API.
*
* @author Geng Rong
* @since 1.0.0 M1
@@ -62,7 +63,7 @@ public class ZhiPuAiApi {
* @param zhiPuAiToken ZhiPuAI apiKey.
*/
public ZhiPuAiApi(String zhiPuAiToken) {
- this(ApiUtils.DEFAULT_BASE_URL, zhiPuAiToken);
+ this(ZhiPuApiConstants.DEFAULT_BASE_URL, zhiPuAiToken);
}
/**
diff --git a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiImageApi.java b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiImageApi.java
index 85ce72f6c..b64e4964b 100644
--- a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiImageApi.java
+++ b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuAiImageApi.java
@@ -18,6 +18,7 @@ package org.springframework.ai.zhipuai.api;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.ai.retry.RetryUtils;
+import org.springframework.ai.util.api.ApiUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.util.Assert;
import org.springframework.web.client.ResponseErrorHandler;
@@ -39,11 +40,12 @@ public class ZhiPuAiImageApi {
private final RestClient restClient;
/**
- * Create a new ZhiPuAI Image api with base URL set to https://api.ZhiPuAI.com
+ * Create a new ZhiPuAI Image api with base URL set to
+ * {@code https://api.ZhiPuAI.com}.
* @param zhiPuAiToken ZhiPuAI apiKey.
*/
public ZhiPuAiImageApi(String zhiPuAiToken) {
- this(ApiUtils.DEFAULT_BASE_URL, zhiPuAiToken, RestClient.builder());
+ this(ZhiPuApiConstants.DEFAULT_BASE_URL, zhiPuAiToken, RestClient.builder());
}
/**
diff --git a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuApiConstants.java b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuApiConstants.java
new file mode 100644
index 000000000..28dcd229d
--- /dev/null
+++ b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/api/ZhiPuApiConstants.java
@@ -0,0 +1,13 @@
+package org.springframework.ai.zhipuai.api;
+
+/**
+ * Common value constants for ZhiPu api.
+ *
+ * @author Piotr Olaszewski
+ * @since 1.0.0 M2
+ */
+public final class ZhiPuApiConstants {
+
+ public static final String DEFAULT_BASE_URL = "https://open.bigmodel.cn/api/paas";
+
+}
diff --git a/spring-ai-core/pom.xml b/spring-ai-core/pom.xml
index 6cefebac1..703f4f852 100644
--- a/spring-ai-core/pom.xml
+++ b/spring-ai-core/pom.xml
@@ -74,6 +74,11 @@
spring-messaging
+
+ org.springframework
+ spring-web
+
+
com.knuddels
jtokkit
diff --git a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/ApiUtils.java b/spring-ai-core/src/main/java/org/springframework/ai/util/api/ApiUtils.java
similarity index 89%
rename from models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/ApiUtils.java
rename to spring-ai-core/src/main/java/org/springframework/ai/util/api/ApiUtils.java
index 101b26e03..3f1f98750 100644
--- a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/api/ApiUtils.java
+++ b/spring-ai-core/src/main/java/org/springframework/ai/util/api/ApiUtils.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.ai.minimax.api;
+package org.springframework.ai.util.api;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
@@ -25,17 +25,17 @@ import java.util.function.Consumer;
* responses.
*
* @author Geng Rong
+ * @author Christian Tzolov
+ * @author Piotr Olaszewski
* @since 1.0.0 M1
*/
public class ApiUtils {
- public static final String DEFAULT_BASE_URL = "https://api.minimax.chat";
-
public static Consumer getJsonContentHeaders(String apiKey) {
return (headers) -> {
headers.setBearerAuth(apiKey);
headers.setContentType(MediaType.APPLICATION_JSON);
};
- };
+ }
}