Commit 6d10f136a037ddc5afaaa131cf54f002eeacd3aa
Committed by
GitHub
Merge pull request #981 from gezipppp-ux/master-jdk17
支持 GROK
Showing
6 changed files
with
94 additions
and
0 deletions
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/enums/model/AiPlatformEnum.java
| ... | ... | @@ -40,6 +40,7 @@ public enum AiPlatformEnum implements ArrayValuable<String> { |
| 40 | 40 | STABLE_DIFFUSION("StableDiffusion", "StableDiffusion"), // Stability AI |
| 41 | 41 | MIDJOURNEY("Midjourney", "Midjourney"), // Midjourney |
| 42 | 42 | SUNO("Suno", "Suno"), // Suno AI |
| 43 | + GROK("Grok","Grok"), // Grok | |
| 43 | 44 | |
| 44 | 45 | ; |
| 45 | 46 | ... | ... |
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/AiAutoConfiguration.java
| ... | ... | @@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.ai.framework.ai.core.model.AiModelFactoryImpl; |
| 7 | 7 | import cn.iocoder.yudao.module.ai.framework.ai.core.model.baichuan.BaiChuanChatModel; |
| 8 | 8 | import cn.iocoder.yudao.module.ai.framework.ai.core.model.doubao.DouBaoChatModel; |
| 9 | 9 | import cn.iocoder.yudao.module.ai.framework.ai.core.model.gemini.GeminiChatModel; |
| 10 | +import cn.iocoder.yudao.module.ai.framework.ai.core.model.grok.GrokChatModel; | |
| 10 | 11 | import cn.iocoder.yudao.module.ai.framework.ai.core.model.hunyuan.HunYuanChatModel; |
| 11 | 12 | import cn.iocoder.yudao.module.ai.framework.ai.core.model.midjourney.api.MidjourneyApi; |
| 12 | 13 | import cn.iocoder.yudao.module.ai.framework.ai.core.model.siliconflow.SiliconFlowApiConstants; |
| ... | ... | @@ -17,6 +18,7 @@ import cn.iocoder.yudao.module.ai.framework.ai.core.webserch.AiWebSearchClient; |
| 17 | 18 | import cn.iocoder.yudao.module.ai.framework.ai.core.webserch.bocha.AiBoChaWebSearchClient; |
| 18 | 19 | import cn.iocoder.yudao.module.ai.tool.method.PersonService; |
| 19 | 20 | import lombok.extern.slf4j.Slf4j; |
| 21 | +import org.springframework.ai.chat.model.ChatModel; | |
| 20 | 22 | import org.springframework.ai.deepseek.DeepSeekChatModel; |
| 21 | 23 | import org.springframework.ai.deepseek.DeepSeekChatOptions; |
| 22 | 24 | import org.springframework.ai.deepseek.api.DeepSeekApi; |
| ... | ... | @@ -40,6 +42,7 @@ import org.springframework.context.annotation.Bean; |
| 40 | 42 | import org.springframework.context.annotation.Configuration; |
| 41 | 43 | |
| 42 | 44 | import java.util.List; |
| 45 | +import java.util.Optional; | |
| 43 | 46 | |
| 44 | 47 | /** |
| 45 | 48 | * 芋道 AI 自动配置 |
| ... | ... | @@ -286,4 +289,25 @@ public class AiAutoConfiguration { |
| 286 | 289 | return List.of(ToolCallbacks.from(personService)); |
| 287 | 290 | } |
| 288 | 291 | |
| 292 | + public ChatModel buildGrokChatClient(YudaoAiProperties.Grok properties) { | |
| 293 | + if (StrUtil.isEmpty(properties.getModel())) { | |
| 294 | + properties.setModel(GrokChatModel.MODEL_DEFAULT); | |
| 295 | + } | |
| 296 | + OpenAiChatModel openAiChatModel = OpenAiChatModel.builder() | |
| 297 | + .openAiApi(OpenAiApi.builder() | |
| 298 | + .baseUrl(Optional.ofNullable(properties.getBaseUrl()) | |
| 299 | + .orElse(GrokChatModel.BASE_URL)) | |
| 300 | + .completionsPath(GrokChatModel.COMPLETE_PATH) | |
| 301 | + .apiKey(properties.getApiKey()) | |
| 302 | + .build()) | |
| 303 | + .defaultOptions(OpenAiChatOptions.builder() | |
| 304 | + .model(properties.getModel()) | |
| 305 | + .temperature(properties.getTemperature()) | |
| 306 | + .maxTokens(properties.getMaxTokens()) | |
| 307 | + .topP(properties.getTopP()) | |
| 308 | + .build()) | |
| 309 | + .toolCallingManager(getToolCallingManager()) | |
| 310 | + .build(); | |
| 311 | + return new DouBaoChatModel(openAiChatModel); | |
| 312 | + } | |
| 289 | 313 | } |
| 290 | 314 | \ No newline at end of file | ... | ... |
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/config/YudaoAiProperties.java
| ... | ... | @@ -161,6 +161,20 @@ public class YudaoAiProperties { |
| 161 | 161 | } |
| 162 | 162 | |
| 163 | 163 | @Data |
| 164 | + public static class Grok { | |
| 165 | + | |
| 166 | + private String enable; | |
| 167 | + private String apiKey; | |
| 168 | + private String baseUrl; | |
| 169 | + | |
| 170 | + private String model; | |
| 171 | + private Double temperature; | |
| 172 | + private Integer maxTokens; | |
| 173 | + private Double topP; | |
| 174 | + | |
| 175 | + } | |
| 176 | + | |
| 177 | + @Data | |
| 164 | 178 | public static class WebSearch { |
| 165 | 179 | |
| 166 | 180 | private boolean enable; | ... | ... |
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/AiModelFactoryImpl.java
| ... | ... | @@ -178,6 +178,8 @@ public class AiModelFactoryImpl implements AiModelFactory { |
| 178 | 178 | return buildGeminiChatModel(apiKey); |
| 179 | 179 | case OLLAMA: |
| 180 | 180 | return buildOllamaChatModel(url); |
| 181 | + case GROK: | |
| 182 | + return buildGrokChatModel(apiKey,url); | |
| 181 | 183 | default: |
| 182 | 184 | throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform)); |
| 183 | 185 | } |
| ... | ... | @@ -405,6 +407,12 @@ public class AiModelFactoryImpl implements AiModelFactory { |
| 405 | 407 | .build(); |
| 406 | 408 | } |
| 407 | 409 | |
| 410 | + private ChatModel buildGrokChatModel(String apiKey,String url) { | |
| 411 | + YudaoAiProperties.Grok properties = new YudaoAiProperties.Grok() | |
| 412 | + .setBaseUrl(url) | |
| 413 | + .setApiKey(apiKey); | |
| 414 | + return new AiAutoConfiguration().buildGrokChatClient(properties); | |
| 415 | + } | |
| 408 | 416 | /** |
| 409 | 417 | * 可参考 {@link AiAutoConfiguration#douBaoChatClient(YudaoAiProperties)} |
| 410 | 418 | */ | ... | ... |
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/framework/ai/core/model/grok/GrokChatModel.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.ai.framework.ai.core.model.grok; | |
| 2 | + | |
| 3 | +import lombok.RequiredArgsConstructor; | |
| 4 | +import lombok.extern.slf4j.Slf4j; | |
| 5 | +import org.springframework.ai.chat.model.ChatModel; | |
| 6 | +import org.springframework.ai.chat.model.ChatResponse; | |
| 7 | +import org.springframework.ai.chat.prompt.ChatOptions; | |
| 8 | +import org.springframework.ai.chat.prompt.Prompt; | |
| 9 | +import reactor.core.publisher.Flux; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * Grok {@link ChatModel} 实现类 | |
| 13 | + * | |
| 14 | + * | |
| 15 | + */ | |
| 16 | +@Slf4j | |
| 17 | +@RequiredArgsConstructor | |
| 18 | +public class GrokChatModel implements ChatModel { | |
| 19 | + | |
| 20 | + public static final String BASE_URL = "https://api.x.ai"; | |
| 21 | + public static final String COMPLETE_PATH = "/v1/chat/completions"; | |
| 22 | + public static final String MODEL_DEFAULT = "grok-4-fast-reasoning"; | |
| 23 | + | |
| 24 | + /** | |
| 25 | + * 兼容 OpenAI 接口,进行复用 | |
| 26 | + */ | |
| 27 | + private final ChatModel openAiChatModel; | |
| 28 | + | |
| 29 | + @Override | |
| 30 | + public ChatResponse call(Prompt prompt) { | |
| 31 | + return openAiChatModel.call(prompt); | |
| 32 | + } | |
| 33 | + | |
| 34 | + @Override | |
| 35 | + public Flux<ChatResponse> stream(Prompt prompt) { | |
| 36 | + return openAiChatModel.stream(prompt); | |
| 37 | + } | |
| 38 | + | |
| 39 | + @Override | |
| 40 | + public ChatOptions getDefaultOptions() { | |
| 41 | + return openAiChatModel.getDefaultOptions(); | |
| 42 | + } | |
| 43 | + | |
| 44 | +} | ... | ... |
yudao-module-ai/src/main/java/cn/iocoder/yudao/module/ai/util/AiUtils.java
| ... | ... | @@ -79,6 +79,9 @@ public class AiUtils { |
| 79 | 79 | case OLLAMA: |
| 80 | 80 | return OllamaOptions.builder().model(model).temperature(temperature).numPredict(maxTokens) |
| 81 | 81 | .toolCallbacks(toolCallbacks).toolContext(toolContext).build(); |
| 82 | + case GROK: | |
| 83 | + return OpenAiChatOptions.builder().model(model).temperature(temperature).maxTokens(maxTokens) | |
| 84 | + .toolCallbacks(toolCallbacks).toolContext(toolContext).build(); | |
| 82 | 85 | default: |
| 83 | 86 | throw new IllegalArgumentException(StrUtil.format("未知平台({})", platform)); |
| 84 | 87 | } | ... | ... |