|
@@ -16,6 +16,8 @@
|
|
|
|
|
|
package cn.tycoding.langchat.core.provider;
|
|
|
|
|
|
+import cn.hutool.core.lang.Pair;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import cn.tycoding.langchat.biz.component.ModelTypeEnum;
|
|
|
import cn.tycoding.langchat.biz.component.ProviderEnum;
|
|
@@ -23,12 +25,16 @@ import cn.tycoding.langchat.biz.entity.AigcModel;
|
|
|
import cn.tycoding.langchat.biz.service.AigcModelService;
|
|
|
import cn.tycoding.langchat.common.component.SpringContextHolder;
|
|
|
import cn.tycoding.langchat.core.consts.EmbedConst;
|
|
|
+import cn.tycoding.langchat.core.provider.model.config.strategy.ModelConfigHandler;
|
|
|
import dev.langchain4j.model.anthropic.AnthropicStreamingChatModel;
|
|
|
import dev.langchain4j.model.azure.AzureOpenAiEmbeddingModel;
|
|
|
import dev.langchain4j.model.azure.AzureOpenAiImageModel;
|
|
|
import dev.langchain4j.model.azure.AzureOpenAiStreamingChatModel;
|
|
|
+import dev.langchain4j.model.chat.StreamingChatLanguageModel;
|
|
|
import dev.langchain4j.model.dashscope.QwenEmbeddingModel;
|
|
|
import dev.langchain4j.model.dashscope.QwenStreamingChatModel;
|
|
|
+import dev.langchain4j.model.embedding.DimensionAwareEmbeddingModel;
|
|
|
+import dev.langchain4j.model.image.ImageModel;
|
|
|
import dev.langchain4j.model.ollama.OllamaEmbeddingModel;
|
|
|
import dev.langchain4j.model.ollama.OllamaStreamingChatModel;
|
|
|
import dev.langchain4j.model.openai.OpenAiEmbeddingModel;
|
|
@@ -41,6 +47,7 @@ import dev.langchain4j.model.zhipu.ZhipuAiEmbeddingModel;
|
|
|
import dev.langchain4j.model.zhipu.ZhipuAiImageModel;
|
|
|
import dev.langchain4j.model.zhipu.ZhipuAiStreamingChatModel;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.BeansException;
|
|
|
import org.springframework.context.ApplicationContext;
|
|
|
import org.springframework.context.ApplicationContextAware;
|
|
@@ -55,8 +62,9 @@ import java.util.Objects;
|
|
|
*/
|
|
|
@Configuration
|
|
|
@AllArgsConstructor
|
|
|
+@Slf4j
|
|
|
public class ProviderInitialize implements ApplicationContextAware {
|
|
|
-
|
|
|
+ private List<ModelConfigHandler> modelConfigHandlers;
|
|
|
private final AigcModelService aigcModelService;
|
|
|
private final SpringContextHolder contextHolder;
|
|
|
|
|
@@ -89,242 +97,57 @@ public class ProviderInitialize implements ApplicationContextAware {
|
|
|
}
|
|
|
|
|
|
private void chatHandler(AigcModel model) {
|
|
|
- String type = model.getType();
|
|
|
- String provider = model.getProvider();
|
|
|
-
|
|
|
- if (ModelTypeEnum.CHAT.name().equals(type)) {
|
|
|
- if (ProviderEnum.OPENAI.name().equals(provider)) {
|
|
|
- if (StrUtil.isBlank(model.getApiKey())) {
|
|
|
- return;
|
|
|
- }
|
|
|
- OpenAiStreamingChatModel build = OpenAiStreamingChatModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .baseUrl(model.getBaseUrl())
|
|
|
- .modelName(model.getModel())
|
|
|
- .maxTokens(model.getResponseLimit())
|
|
|
- .temperature(model.getTemperature())
|
|
|
- .logRequests(true)
|
|
|
- .logResponses(true)
|
|
|
- .topP(model.getTopP())
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(model.getId(), build);
|
|
|
- }
|
|
|
- if (ProviderEnum.AZURE_OPENAI.name().equals(provider)) {
|
|
|
- if (StrUtil.isBlank(model.getApiKey())) {
|
|
|
- return;
|
|
|
- }
|
|
|
- AzureOpenAiStreamingChatModel build = AzureOpenAiStreamingChatModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .endpoint(model.getEndpoint())
|
|
|
- .deploymentName(model.getAzureDeploymentName())
|
|
|
- .maxTokens(model.getResponseLimit())
|
|
|
- .temperature(model.getTemperature())
|
|
|
- .logRequestsAndResponses(true)
|
|
|
- .topP(model.getTopP())
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(model.getId(), build);
|
|
|
- }
|
|
|
- if (ProviderEnum.GEMINI.name().equals(provider)) {
|
|
|
- if (StrUtil.isBlank(model.getApiKey()) || StrUtil.isBlank(model.getSecretKey())) {
|
|
|
- return;
|
|
|
- }
|
|
|
- VertexAiGeminiStreamingChatModel build = VertexAiGeminiStreamingChatModel
|
|
|
- .builder()
|
|
|
- .project(model.getGeminiProject())
|
|
|
- .location(model.getGeminiLocation())
|
|
|
- .modelName(model.getModel())
|
|
|
- .temperature(Float.parseFloat(model.getTemperature().toString()))
|
|
|
- .maxOutputTokens(model.getResponseLimit())
|
|
|
- .logRequests(true)
|
|
|
- .logResponses(true)
|
|
|
- .topP(Float.parseFloat(model.getTopP().toString()))
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(model.getId(), build);
|
|
|
- }
|
|
|
- if (ProviderEnum.OLLAMA.name().equals(provider)) {
|
|
|
- OllamaStreamingChatModel build = OllamaStreamingChatModel
|
|
|
- .builder()
|
|
|
- .baseUrl(model.getBaseUrl())
|
|
|
- .modelName(model.getModel())
|
|
|
- .temperature(model.getTemperature())
|
|
|
- .topP(model.getTopP())
|
|
|
- .logRequests(true)
|
|
|
- .logResponses(true)
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(model.getId(), build);
|
|
|
- }
|
|
|
- if (ProviderEnum.CLAUDE.name().equals(provider)) {
|
|
|
- if (!model.getBaseUrl().endsWith("/")) {
|
|
|
- model.setBaseUrl(model.getBaseUrl() + "/");
|
|
|
+ try {
|
|
|
+ String type = model.getType();
|
|
|
+ if (!ModelTypeEnum.CHAT.name().equals(type)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ modelConfigHandlers.forEach(x -> {
|
|
|
+ StreamingChatLanguageModel streamingChatLanguageModel = x.chatConfig(model);
|
|
|
+ if (ObjectUtil.isNotEmpty(streamingChatLanguageModel)) {
|
|
|
+ contextHolder.registerBean(model.getId(), streamingChatLanguageModel);
|
|
|
}
|
|
|
- AnthropicStreamingChatModel build = AnthropicStreamingChatModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .baseUrl(model.getBaseUrl())
|
|
|
- .modelName(model.getModel())
|
|
|
- .temperature(model.getTemperature())
|
|
|
- .topP(model.getTopP())
|
|
|
- .logRequests(true)
|
|
|
- .logResponses(true)
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(model.getId(), build);
|
|
|
- }
|
|
|
- if (ProviderEnum.Q_FAN.name().equals(provider)) {
|
|
|
- QianfanStreamingChatModel build = QianfanStreamingChatModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .secretKey(model.getSecretKey())
|
|
|
- .modelName(model.getModel())
|
|
|
- .baseUrl(model.getBaseUrl())
|
|
|
- .temperature(model.getTemperature())
|
|
|
- .topP(model.getTopP())
|
|
|
- .logRequests(true)
|
|
|
- .logResponses(true)
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(model.getId(), build);
|
|
|
- }
|
|
|
- if (ProviderEnum.Q_WEN.name().equals(provider)) {
|
|
|
- QwenStreamingChatModel build = QwenStreamingChatModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .modelName(model.getModel())
|
|
|
- .baseUrl(model.getBaseUrl())
|
|
|
- .maxTokens(model.getResponseLimit())
|
|
|
- .temperature(Float.parseFloat(model.getTemperature().toString()))
|
|
|
- .topP(model.getTopP())
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(model.getId(), build);
|
|
|
- }
|
|
|
- if (ProviderEnum.ZHIPU.name().equals(provider)) {
|
|
|
- ZhipuAiStreamingChatModel build = ZhipuAiStreamingChatModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .baseUrl(model.getBaseUrl())
|
|
|
- .model(model.getModel())
|
|
|
- .maxToken(model.getResponseLimit())
|
|
|
- .temperature(model.getTemperature())
|
|
|
- .topP(model.getTopP())
|
|
|
- .logRequests(true)
|
|
|
- .logResponses(true)
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(model.getId(), build);
|
|
|
- }
|
|
|
+ });
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("model 【id{} name{}】 chat 配置报错", model.getId(), model.getName());
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
private void embeddingHandler(AigcModel model) {
|
|
|
- String type = model.getType();
|
|
|
- String provider = model.getProvider();
|
|
|
+ try {
|
|
|
+ String type = model.getType();
|
|
|
+ if (!ModelTypeEnum.EMBEDDING.name().equals(type)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ modelConfigHandlers.forEach(x -> {
|
|
|
+ Pair<String, DimensionAwareEmbeddingModel> embeddingModelPair = x.embeddingConfig(model);
|
|
|
+ if (ObjectUtil.isNotEmpty(embeddingModelPair)) {
|
|
|
+ contextHolder.registerBean(embeddingModelPair.getKey(), embeddingModelPair.getValue());
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
- if (ModelTypeEnum.EMBEDDING.name().equals(type)) {
|
|
|
- if (ProviderEnum.OPENAI.name().equals(provider)) {
|
|
|
- OpenAiEmbeddingModel build = OpenAiEmbeddingModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .baseUrl(model.getBaseUrl())
|
|
|
- .modelName(model.getModel())
|
|
|
- .dimensions(model.getDimensions())
|
|
|
- .logRequests(true)
|
|
|
- .logResponses(true)
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(EmbedConst.CLAZZ_NAME_OPENAI, build);
|
|
|
- }
|
|
|
- if (ProviderEnum.AZURE_OPENAI.name().equals(provider)) {
|
|
|
- AzureOpenAiEmbeddingModel build = AzureOpenAiEmbeddingModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .deploymentName(model.getBaseUrl())
|
|
|
- .logRequestsAndResponses(true)
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(EmbedConst.CLAZZ_NAME_AZURE_OPENAI, build);
|
|
|
- }
|
|
|
- if (ProviderEnum.Q_FAN.name().equals(provider)) {
|
|
|
- QianfanEmbeddingModel build = QianfanEmbeddingModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .modelName(model.getModel())
|
|
|
- .secretKey(model.getSecretKey())
|
|
|
- .logRequests(true)
|
|
|
- .logResponses(true)
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(EmbedConst.CLAZZ_NAME_QIANFAN, build);
|
|
|
- }
|
|
|
- if (ProviderEnum.Q_WEN.name().equals(provider)) {
|
|
|
- QwenEmbeddingModel build = QwenEmbeddingModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .modelName(model.getModel())
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(EmbedConst.CLAZZ_NAME_QIANWEN, build);
|
|
|
- }
|
|
|
- if (ProviderEnum.ZHIPU.name().equals(provider)) {
|
|
|
- ZhipuAiEmbeddingModel build = ZhipuAiEmbeddingModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .model(model.getModel())
|
|
|
- .baseUrl(model.getBaseUrl())
|
|
|
- .logRequests(true)
|
|
|
- .logResponses(true)
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(EmbedConst.CLAZZ_NAME_ZHIPU, build);
|
|
|
- }
|
|
|
- if (ProviderEnum.OLLAMA.name().equals(provider)) {
|
|
|
- OllamaEmbeddingModel build = OllamaEmbeddingModel
|
|
|
- .builder()
|
|
|
- .baseUrl(model.getBaseUrl())
|
|
|
- .modelName(model.getModel())
|
|
|
- .logRequests(true)
|
|
|
- .logResponses(true)
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(EmbedConst.CLAZZ_NAME_OLLAMA, build);
|
|
|
- }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("model 【id{} name{}】 embedding 配置报错", model.getId(), model.getName());
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
private void imageHandler(AigcModel model) {
|
|
|
- String type = model.getType();
|
|
|
- String provider = model.getProvider();
|
|
|
-
|
|
|
- if (ModelTypeEnum.TEXT_IMAGE.name().equals(type)) {
|
|
|
- if (ProviderEnum.OPENAI.name().equals(provider)) {
|
|
|
- OpenAiImageModel build = OpenAiImageModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .baseUrl(model.getBaseUrl())
|
|
|
- .modelName(model.getModel())
|
|
|
- .size(model.getImageSize())
|
|
|
- .quality(model.getImageQuality())
|
|
|
- .style(model.getImageStyle())
|
|
|
- .logRequests(true)
|
|
|
- .logResponses(true)
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(model.getId(), build);
|
|
|
- }
|
|
|
- if (ProviderEnum.AZURE_OPENAI.name().equals(provider)) {
|
|
|
- AzureOpenAiImageModel build = AzureOpenAiImageModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .deploymentName(model.getAzureDeploymentName())
|
|
|
- .size(model.getImageSize())
|
|
|
- .quality(model.getImageQuality())
|
|
|
- .style(model.getImageStyle())
|
|
|
- .logRequestsAndResponses(true)
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(model.getId(), build);
|
|
|
- }
|
|
|
- if (ProviderEnum.ZHIPU.name().equals(provider)) {
|
|
|
- ZhipuAiImageModel build = ZhipuAiImageModel
|
|
|
- .builder()
|
|
|
- .apiKey(model.getApiKey())
|
|
|
- .model(model.getModel())
|
|
|
- .baseUrl(model.getBaseUrl())
|
|
|
- .logRequests(true)
|
|
|
- .logResponses(true)
|
|
|
- .build();
|
|
|
- contextHolder.registerBean(model.getId(), build);
|
|
|
- }
|
|
|
+ try {
|
|
|
+ String type = model.getType();
|
|
|
+ if (!ModelTypeEnum.TEXT_IMAGE.name().equals(type)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ modelConfigHandlers.forEach(x -> {
|
|
|
+ ImageModel imageModel = x.imageConfig(model);
|
|
|
+ if (ObjectUtil.isNotEmpty(imageModel)) {
|
|
|
+ contextHolder.registerBean(model.getId(), imageModel);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("model 【id{} name{}】 image 配置报错", model.getId(), model.getName());
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
}
|