¶Ô±ÈÐÂÎļþ |
| | |
| | | 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(); |
| | | } |
| | | } |