| | |
| | | * éè¿æ¨¡ååç§°è·å模åä¿¡æ¯ |
| | | */ |
| | | ChatModelVo selectModelByName(String modelName); |
| | | |
| | | /** |
| | | * éè¿æ¨¡ååç±»è·å模åä¿¡æ¯ |
| | | */ |
| | | ChatModelVo selectModelByCategory(String image); |
| | | /** |
| | | * è·åppt模åä¿¡æ¯ |
| | | */ |
| | | ChatModel getPPT(); |
| | | |
| | | } |
| | |
| | | public ChatModelVo selectModelByName(String modelName) { |
| | | return baseMapper.selectVoOne(Wrappers.<ChatModel>lambdaQuery().eq(ChatModel::getModelName, modelName)); |
| | | } |
| | | /** |
| | | * éè¿æ¨¡ååç±»è·å模åä¿¡æ¯ |
| | | */ |
| | | @Override |
| | | public ChatModelVo selectModelByCategory(String category) { |
| | | return baseMapper.selectVoOne(Wrappers.<ChatModel>lambdaQuery().eq(ChatModel::getCategory, category)); |
| | | } |
| | | |
| | | @Override |
| | | public ChatModel getPPT() { |
| | |
| | | |
| | | QIANWEN("qianwen", "éä¹åé®"), |
| | | |
| | | VECTOR("vector", "ç¥è¯åºå鿍¡å"); |
| | | VECTOR("vector", "ç¥è¯åºå鿍¡å"), |
| | | |
| | | IMAGE("image", "å¾çè¯å«æ¨¡å"); |
| | | |
| | | private final String code; |
| | | private final String description; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.chat.service.chat.impl; |
| | | |
| | | import lombok.SneakyThrows; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.chat.config.ChatConfig; |
| | | import org.ruoyi.chat.enums.ChatModeType; |
| | | import org.ruoyi.chat.listener.SSEEventSourceListener; |
| | | import org.ruoyi.chat.service.chat.IChatService; |
| | | import org.ruoyi.common.chat.entity.chat.ChatCompletion; |
| | | import org.ruoyi.common.chat.entity.chat.Message; |
| | | import org.ruoyi.common.chat.openai.OpenAiStreamClient; |
| | | import org.ruoyi.common.chat.request.ChatRequest; |
| | | import org.ruoyi.domain.vo.ChatModelVo; |
| | | import org.ruoyi.service.IChatModelService; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.web.servlet.mvc.method.annotation.SseEmitter; |
| | | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * å¾çè¯å«æ¨¡å |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | public class ImageServiceImpl implements IChatService { |
| | | |
| | | @Autowired |
| | | private IChatModelService chatModelService; |
| | | |
| | | @SneakyThrows |
| | | // @Override |
| | | // public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) { |
| | | // ChatModelVo chatModelVo = chatModelService.selectModelByCategory("image"); |
| | | // |
| | | // // å鿵弿¶æ¯ |
| | | // |
| | | // MultiModalConversation conv = new MultiModalConversation(); |
| | | // MultiModalMessage systemMessage = MultiModalMessage.builder().role(Role.SYSTEM.getValue()) |
| | | // .content(Arrays.asList( |
| | | // Collections.singletonMap("text",chatRequest.getSysPrompt()))).build(); |
| | | // // è·åç¨æ·æ¶æ¯å
容 |
| | | // List<Message> messages = chatRequest.getMessages(); |
| | | // MultiModalMessage userMessage = null; |
| | | // //漫é¿çæ ¼å¼è½¬æ¢ |
| | | // // éåæ¶æ¯åè¡¨ï¼æåææ¬å
容 |
| | | // if (messages != null && !messages.isEmpty()) { |
| | | // Object content = messages.get(messages.size() - 1).getContent(); |
| | | // List<Map<String, Object>> contentList = new ArrayList<>(); |
| | | // StringBuilder textContent = new StringBuilder(); |
| | | // if (content instanceof List<?>) { |
| | | // for (Object item : (List<?>) content) { |
| | | // if (item instanceof Map<?, ?> mapItem) { |
| | | // String type = (String) mapItem.get("type"); |
| | | // if ("text".equals(type)) { |
| | | // String text = (String) mapItem.get("text"); |
| | | // if (text != null) { |
| | | // textContent.append(text).append(" "); |
| | | // } |
| | | // } else if ("image_url".equals(type)) { |
| | | // Map<String, String> imageUrl = (Map<String, String>) mapItem.get("image_url"); |
| | | // contentList.add(Collections.singletonMap("image", imageUrl.get("url"))); |
| | | // } |
| | | // } |
| | | // } |
| | | // } |
| | | // // å°æ¼æ¥åçææ¬å
容添å å° contentList |
| | | // if (textContent.length() > 0) { |
| | | // contentList.add(Collections.singletonMap("text", textContent.toString().trim())); |
| | | // } |
| | | // userMessage = MultiModalMessage.builder() |
| | | // .role(Role.USER.getValue()) |
| | | // .content(contentList) |
| | | // .build(); |
| | | // } |
| | | // MultiModalConversationParam param = MultiModalConversationParam.builder() |
| | | // .apiKey(chatModelVo.getApiKey()) |
| | | // .model(chatModelVo.getModelName()) |
| | | // .messages(Arrays.asList(systemMessage, userMessage)) |
| | | // .incrementalOutput(true) |
| | | // .build(); |
| | | // |
| | | // |
| | | // try { |
| | | // final QwenStreamingResponseBuilder responseBuilder = new QwenStreamingResponseBuilder(param.getModel(),param.getIncrementalOutput() ); |
| | | // conv.streamCall(param, new ResultCallback<>() { |
| | | // @SneakyThrows |
| | | // public void onEvent(MultiModalConversationResult result) { |
| | | // |
| | | // String delta = responseBuilder.append(result); |
| | | // if (Utils.isNotNullOrEmpty(delta)) { |
| | | // |
| | | // emitter.send(delta); |
| | | // log.info("æ¶å°æ¶æ¯ç段: {}", delta); |
| | | // } |
| | | // } |
| | | // public void onComplete() { |
| | | // emitter.complete(); |
| | | // log.info("æ¶æ¯ç»æ", responseBuilder.build()); |
| | | // } |
| | | // public void onError(Exception e) { |
| | | // log.info("请æ±å¤±è´¥", e.getMessage()); |
| | | // } |
| | | // }); |
| | | // } catch (NoApiKeyException e) { |
| | | // emitter.send("请å
é
ç½®APIå¯é¥"); |
| | | // throw new RuntimeException(e); |
| | | // } catch (UploadFileException e) { |
| | | // throw new RuntimeException(e); |
| | | // } |
| | | // |
| | | // |
| | | // return emitter; |
| | | // } |
| | | |
| | | @Override |
| | | public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) { |
| | | // 仿°æ®åºè·å image ç±»åçæ¨¡åé
ç½® |
| | | ChatModelVo chatModelVo = chatModelService.selectModelByCategory(ChatModeType.IMAGE.getCode()); |
| | | if (chatModelVo == null) { |
| | | log.error("æªæ¾å° image ç±»åçæ¨¡åé
ç½®"); |
| | | emitter.completeWithError(new IllegalStateException("æªæ¾å° image ç±»åçæ¨¡åé
ç½®")); |
| | | return emitter; |
| | | } |
| | | |
| | | // å建 OpenAI æµå®¢æ·ç«¯ |
| | | OpenAiStreamClient openAiStreamClient = ChatConfig.createOpenAiStreamClient(chatModelVo.getApiHost(), chatModelVo.getApiKey()); |
| | | List<Message> messages = chatRequest.getMessages(); |
| | | |
| | | // å建 SSE äºä»¶æºçå¬å¨ |
| | | SSEEventSourceListener listener = new SSEEventSourceListener(emitter, chatRequest.getUserId(), chatRequest.getSessionId()); |
| | | |
| | | // æå»ºèå¤©å®æè¯·æ± |
| | | ChatCompletion completion = ChatCompletion |
| | | .builder() |
| | | .messages(messages) |
| | | .model(chatModelVo.getModelName()) // ä½¿ç¨æ°æ®åºä¸é
ç½®çæ¨¡ååç§° |
| | | .stream(true) |
| | | .build(); |
| | | |
| | | // åèµ·æµå¼èå¤©å®æè¯·æ± |
| | | openAiStreamClient.streamChatCompletion(completion, listener); |
| | | |
| | | return emitter; |
| | | } |
| | | |
| | | @Override |
| | | public String getCategory() { |
| | | return ChatModeType.IMAGE.getCode(); |
| | | } |
| | | } |
| | |
| | | .modelName(chatModelVo.getModelName()) |
| | | .build(); |
| | | |
| | | |
| | | |
| | | // å鿵弿¶æ¯ |
| | | try { |
| | | model.chat(chatRequest.getPrompt(), new StreamingChatResponseHandler() { |
| | |
| | | */ |
| | | private void buildChatMessageList(ChatRequest chatRequest){ |
| | | String sysPrompt; |
| | | chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); |
| | | // ç«æ£æ¨¡ååç§° 妿æ¯gpt-image åæ¥è¯¢imageç±»åæ¨¡å è·å模ååç§° |
| | | if(chatRequest.getModel().equals("gpt-image")) { |
| | | chatModelVo = chatModelService.selectModelByCategory("image"); |
| | | if (chatModelVo == null) { |
| | | log.error("æªæ¾å°imageç±»åçæ¨¡åé
ç½®"); |
| | | throw new IllegalStateException("æªæ¾å°imageç±»åçæ¨¡åé
ç½®"); |
| | | } |
| | | }else{ |
| | | chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); |
| | | } |
| | | // è·åå¯¹è¯æ¶æ¯å表 |
| | | List<Message> messages = chatRequest.getMessages(); |
| | | // æ¥è¯¢åéåºç¸å
³ä¿¡æ¯å å
¥å°ä¸ä¸æ |
| | |
| | | INSERT INTO `chat_model` VALUES (1828324413241466881, '000000', 'vector', 'baai/bge-m3', 'baai/bge-m3', 0.01, '2', '1', NULL, 'https://api.ppinfra.com/v3/openai', 'sk-xx', NULL, 103, 1, '2024-08-27 14:51:23', 1, '2025-05-24 17:33:11', 'BGE-M3 æ¯ä¸æ¬¾å
·å¤å¤ç»´åº¦è½åçææ¬åµå
¥æ¨¡åï¼å¯åæ¶å®ç°å¯éæ£ç´¢ãå¤åéæ£ç´¢åç¨çæ£ç´¢ä¸å¤§æ ¸å¿åè½ã该模å设计ä¸å
¼å®¹è¶
è¿100ç§è¯è¨ï¼å¹¶æ¯æä»çå¥å°é¿è¾¾8192è¯å
çé¿ææ¬çå¤ç§è¾å
¥å½¢å¼ãå¨è·¨è¯è¨æ£ç´¢ä»»å¡ä¸ï¼BGE-M3å±ç°åºæ¾èä¼å¿ï¼å
¶æ§è½å¨MIRACLãMKQAçå½é
åºåæµè¯ä¸ä½å±
ååãæ¤å¤ï¼éå¯¹é¿ææ¡£æ£ç´¢åºæ¯ï¼è¯¥æ¨¡åå¨MLDRãNarritiveQAçæ°æ®éä¸ç表ç°åæ ·è¾¾å°è¡ä¸é¢å
æ°´å¹³ã'); |
| | | INSERT INTO `chat_model` VALUES (1859570229117022211, '000000', 'chat', 'deepseek/deepseek-v3-0324', 'deepseek/deepseek-v3-0324', 0.1, '1', '0', '', 'https://api.ppinfra.com/v3/openai/chat/completions', 'sk-xx', NULL, 103, 1, '2024-11-21 20:11:06', 1, '2025-05-24 17:56:22', 'DeepSeek V3 0324 æ¯æ·±åº¦æ±ç´¢ï¼DeepSeekï¼å¢éæè°çº§å¯¹è¯æ¨¡åç³»åçææ°çæ¬ï¼éç¨æ··åä¸å®¶ï¼Mixture-of-Experts, MoEï¼æ¶æï¼åæ°éè¾¾685Båæ°ã'); |
| | | INSERT INTO `chat_model` VALUES (1859570229117022212, '000000', 'chat', 'deepseek/deepseek-r1', 'deepseek/deepseek-r1', 0.1, '1', '0', '', 'https://api.ppinfra.com/v3/openai/chat/completions', 'sk-xx', NULL, 103, 1, '2024-11-21 20:11:06', 1, '2025-05-24 17:56:14', 'DeepSeek R1æ¯DeepSeekå¢éåå¸çææ°å¼æºæ¨¡åï¼å
·å¤é常强æçæ¨çæ§è½ï¼å°¤å
¶å¨æ°å¦ãç¼ç¨åæ¨çä»»å¡ä¸è¾¾å°äºä¸OpenAIço1模åç¸å½çæ°´å¹³ã'); |
| | | INSERT INTO `chat_model` VALUES (1926215622017482754, '000000', 'chat', 'gpt-4o-mini', 'gpt-4o-mini', 0.1, '1', '0', NULL, 'https://api.pandarobot.chat/v1/chat/completions/', 'sk-xx', NULL, 103, 1, '2025-05-24 17:56:06', 1, '2025-05-24 17:56:06', 'gpt 夿¨¡ææ¨¡å'); |
| | | INSERT INTO `chat_model` VALUES (1926215622017482755, '000000', 'chat', 'gpt-4-all', 'gpt-4-all', 0.5, '2', '0', NULL, 'https://api.pandarobot.chat/v1/chat/completions/', 'sk-xx', NULL, 103, 1, '2025-05-24 17:56:06', 1, '2025-05-24 17:59:21', 'gpt éå夿¨¡ææ¨¡å'); |
| | | INSERT INTO `chat_model` VALUES (1930184891812147202, '000000', 'image', 'qwen/qwen2.5-vl-72b-instruct', 'qwen/qwen2.5-vl-72b-instruct', 0.003, '2', '0', NULL, 'https://api.ppinfra.com/v3/openai/chat/completions', 'xx', NULL, 103, 1, '2025-06-04 16:48:34', 1, '2025-06-04 16:48:34', 'è§è§æ¨¡å'); |
| | | |
| | | |
| | | -- ---------------------------- |
| | | -- Table structure for chat_pay_order |