From 24681c81c09022f584a57006f2534b5f74723414 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 30 六月 2026 09:27:31 +0800
Subject: [PATCH] 初始化项目
---
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java | 69 ++++++++++++++++++++++++----------
1 files changed, 48 insertions(+), 21 deletions(-)
diff --git a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java
index 1518523..d687c54 100644
--- a/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java
+++ b/yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java
@@ -8,22 +8,23 @@
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.ai.enums.model.AiPlatformEnum;
import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatOptions;
-import org.springaicommunity.moonshot.MoonshotChatOptions;
-import org.springaicommunity.qianfan.QianFanChatOptions;
+import cn.hutool.extra.spring.SpringUtil;
import org.springframework.ai.anthropic.AnthropicChatOptions;
-import org.springframework.ai.azure.openai.AzureOpenAiChatOptions;
import org.springframework.ai.chat.messages.*;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.deepseek.DeepSeekAssistantMessage;
import org.springframework.ai.deepseek.DeepSeekChatOptions;
-import org.springframework.ai.minimax.MiniMaxChatOptions;
+import org.springframework.ai.google.genai.GoogleGenAiChatOptions;
import org.springframework.ai.ollama.api.OllamaChatOptions;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.tool.ToolCallback;
-import org.springframework.ai.zhipuai.ZhiPuAiChatOptions;
+import org.springframework.core.env.Environment;
import java.util.*;
+
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.ai.enums.ErrorCodeConstants.API_CONFIG_PLACEHOLDER_NOT_RESOLVED;
/**
* Spring AI 宸ュ叿绫�
@@ -36,13 +37,42 @@
public static final String TOOL_CONTEXT_TENANT_ID = "TENANT_ID";
/**
+ * 瑙f瀽 DB 绛夊姩鎬侀厤缃噷鐨� Spring 鍗犱綅绗︼紝渚嬪 ${OPENAI_API_KEY}
+ *
+ * @param value 寰呰В鏋愮殑閰嶇疆鍊�
+ * @return 瑙f瀽鍚庣殑閰嶇疆鍊�
+ */
+ public static String resolveSpringPlaceholders(String value) {
+ if (StrUtil.isBlank(value) || !StrUtil.contains(value, "${")) {
+ return value;
+ }
+ try {
+ return SpringUtil.getBean(Environment.class).resolveRequiredPlaceholders(value);
+ } catch (IllegalArgumentException ex) {
+ throw exception(API_CONFIG_PLACEHOLDER_NOT_RESOLVED, value);
+ }
+ }
+
+ /**
+ * 鏍¢獙 API Key锛岄伩鍏嶉泦鎴愭祴璇曚娇鐢ㄩ粯璁ゅ崰浣嶅�煎彂璧疯皟鐢ㄣ��
+ *
+ * @param apiKey API Key
+ */
+ public static void validateApiKey(String apiKey) {
+ if (StrUtil.isBlank(apiKey) || "sk-xxxx".equals(apiKey)) {
+ throw new IllegalStateException("apiKey 涓嶈兘涓虹┖");
+ }
+ }
+
+ /**
* 閫氫箟鍗冮棶鏀寔澶氭ā鎬佺殑妯″瀷
*
* @see <a href="https://bailian.console.aliyun.com/cn-beijing/?tab=model#/model-market/all?providers=qwen&capabilities=VU">妯″瀷骞垮満</a>
* @see <a href="https://help.aliyun.com/zh/model-studio/error-code#error-url">蹇呴』寮�鍚� withMultiModel 鍙傛暟</a>
*/
public static final Set<String> TONG_YI_MULTI_MODELS = SetUtils.asSet(
- // qwen3.5 / 3.6 绯诲垪锛堢粺涓�澶氭ā鎬佷富骞诧級
+ // qwen3.5 / 3.6 / 3.7 绯诲垪锛堢粺涓�澶氭ā鎬佷富骞诧級
+ "qwen3.7-max", "qwen3.7-plus", "qwen3.7-flash",
"qwen3.6-plus", "qwen3.6-flash",
"qwen3.5-plus", "qwen3.5-flash",
// qwen-vl 瑙嗚鐞嗚В
@@ -72,32 +102,29 @@
.enableThinking(true) // TODO 鑺嬭壙锛氶粯璁ら兘寮�鍚� thinking 妯″紡锛屽悗缁彲浠ヨ鐢ㄦ埛閰嶇疆
.multiModel(TONG_YI_MULTI_MODELS.contains(model)) // 鏄惁澶氭ā鎬佹ā鍨�
.toolCallbacks(toolCallbacks).toolContext(toolContext).build();
- case YI_YAN:
- return QianFanChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens).build();
case DEEP_SEEK:
case DOU_BAO: // 澶嶇敤 DeepSeek 瀹㈡埛绔�
case HUN_YUAN: // 澶嶇敤 DeepSeek 瀹㈡埛绔�
case SILICON_FLOW: // 澶嶇敤 DeepSeek 瀹㈡埛绔�
+ case YI_YAN: // 澶嶇敤 DeepSeek 瀹㈡埛绔�
+ case ZHI_PU: // 澶嶇敤 DeepSeek 瀹㈡埛绔�
case XING_HUO: // 澶嶇敤 DeepSeek 瀹㈡埛绔�
+ case MINI_MAX: // 澶嶇敤 DeepSeek 瀹㈡埛绔�
+ case MOONSHOT: // 澶嶇敤 DeepSeek 瀹㈡埛绔�
+ case BAI_CHUAN: // 澶嶇敤 DeepSeek 瀹㈡埛绔�
+ case STEP_FUN: // 澶嶇敤 DeepSeek 瀹㈡埛绔�
return DeepSeekChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
.toolCallbacks(toolCallbacks).toolContext(toolContext).build();
- case ZHI_PU:
- return ZhiPuAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
- .toolCallbacks(toolCallbacks).toolContext(toolContext).build();
- case MINI_MAX:
- return MiniMaxChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
- .toolCallbacks(toolCallbacks).toolContext(toolContext).build();
- case MOONSHOT:
- return MoonshotChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
- .toolCallbacks(toolCallbacks).toolContext(toolContext).build();
case OPENAI:
- case GEMINI: // 澶嶇敤 OpenAI 瀹㈡埛绔�
- case BAI_CHUAN: // 澶嶇敤 OpenAI 瀹㈡埛绔�
case GROK: // 澶嶇敤 OpenAI 瀹㈡埛绔�
return OpenAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
.toolCallbacks(toolCallbacks).toolContext(toolContext).build();
+ case GEMINI:
+ return GoogleGenAiChatOptions.builder().model(model).temperature(temperature).maxOutputTokens(maxTokens)
+ .toolCallbacks(toolCallbacks).toolContext(toolContext).build();
case AZURE_OPENAI:
- return AzureOpenAiChatOptions.builder().deploymentName(model).temperature(temperature).maxTokens(maxTokens)
+ return OpenAiChatOptions.builder().model(model).deploymentName(model).azure(true)
+ .temperature(temperature).maxTokens(maxTokens)
.toolCallbacks(toolCallbacks).toolContext(toolContext).build();
case ANTHROPIC:
return AnthropicChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens)
@@ -159,4 +186,4 @@
return MapUtil.getStr(output.getMetadata(), "reasoningContent");
}
-}
\ No newline at end of file
+}
--
Gitblit v1.9.3