| | |
| | | # æ é¢ |
| | | title: 'æ é¢ï¼RuoYi-Vue-Pluså¤ç§æ·ç®¡çç³»ç»_æ¥å£ææ¡£' |
| | | # æè¿° |
| | | description: 'æè¿°ï¼ç¨äºç®¡çé墿ä¸å
¬å¸ç人åä¿¡æ¯,å
·ä½å
æ¬XXX,XXX模å...' |
| | | description: ' ç¨äºç®¡çé墿ä¸å
¬å¸ç人åä¿¡æ¯,å
·ä½å
æ¬XXX,XXX模å...' |
| | | # çæ¬ |
| | | version: 'çæ¬å·: ${ruoyi.version}' |
| | | # ä½è
ä¿¡æ¯ |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @date 2023-03-10 |
| | |
| | | package org.ruoyi.common.chat.constant; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-06 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼é颿¶èä¿¡æ¯ |
| | | * é颿¶èä¿¡æ¯ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-04-08 |
| | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * æè¿°ï¼ä½é¢æ¥è¯¢æ¥å£è¿åå¼ |
| | | * ä½é¢æ¥è¯¢æ¥å£è¿åå¼ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-18 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼é颿¶èå表 |
| | | * é颿¶èå表 |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-04-08 |
| | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-18 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-18 |
| | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * æè¿°ï¼é颿¶èå表 |
| | | * é颿¶èå表 |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-04-08 |
| | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-04-08 |
| | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * æè¿°ï¼è´¦æ·ä¿¡æ¯ |
| | | * è´¦æ·ä¿¡æ¯ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-04-08 |
| | |
| | | import static org.ruoyi.common.chat.entity.chat.BaseChatCompletion.Model.GPT_3_5_TURBO; |
| | | |
| | | /** |
| | | * æè¿°ï¼ chat模ååºç¡ç±» |
| | | * chat模ååºç¡ç±» |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 1.1.2 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 1.1.2 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-02 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ chat模ååæ° |
| | | * chat模ååæ° |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-03-02 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ chatçæ¡ç±» |
| | | * chatçæ¡ç±» |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-03-02 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ chat模åé带å¾ççåæ° |
| | | * ï¼ chat模åé带å¾ççåæ° |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 1.1.2 |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * @author https://www.unfbx.com |
| | | * @since 1.1.2 |
| | |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | /** |
| | | * æè¿°ï¼å½æ°è°ç¨è¿åå¼ |
| | | * 彿°è°ç¨è¿åå¼ |
| | | * |
| | | * @author https://www.unfbx.com |
| | | * @since 2023-06-14 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼æ¹æ³åæ°å®ä½ç±»ï¼å®ä¾æ°æ®å¦ä¸ |
| | | * æ¹æ³åæ°å®ä½ç±»ï¼å®ä¾æ°æ®å¦ä¸ |
| | | * <pre> |
| | | * { |
| | | * "name": "get_current_weather", |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * @author https://www.unfbx.com |
| | | * 2023-11-10 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-02 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-02 |
| | | */ |
| | |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | /** |
| | | * æè¿°ï¼æ¹æ³åæ°ç±»ï¼æ©å±åæ°å¯ä»¥ç»§æ¿Parametersèªå·±å®ç° |
| | | * æ¹æ³åæ°ç±»ï¼æ©å±åæ°å¯ä»¥ç»§æ¿Parametersèªå·±å®ç° |
| | | * åèï¼ |
| | | * <pre> |
| | | * { |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | import java.util.List; |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æè¿°ï¼ é®é¢ç±» |
| | | * é®é¢ç±» |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-11 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ çæ¡ç±» |
| | | * çæ¡ç±» |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-11 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.math.BigDecimal; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * æè¿°ï¼ææ¬å®¡æ ¸ï¼ææè¯é´å« |
| | | * ææ¬å®¡æ ¸ï¼ææè¯é´å« |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼è¯é³è½¬æå |
| | | * è¯é³è½¬æå |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-02 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-02 |
| | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * æè¿°ï¼OpenAIæµå¼è¾åºSocketæ¥æ¶ |
| | | * OpenAIæµå¼è¾åºSocketæ¥æ¶ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @date 2023-03-23 |
| | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æè¿°ï¼ open ai宿¹apiæ¥å£ |
| | | * open ai宿¹apiæ¥å£ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | |
| | | |
| | | /** |
| | | * æè¿°ï¼ open ai 客æ·ç«¯ |
| | | * open ai 客æ·ç«¯ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-02-11 |
| | |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * æè¿°ï¼ open ai 客æ·ç«¯ |
| | | * open ai 客æ·ç«¯ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-28 |
| | |
| | | ObjectMapper mapper = new ObjectMapper(); |
| | | String requestBody = mapper.writeValueAsString(chatCompletion); |
| | | Request request = new Request.Builder() |
| | | .url(this.apiHost + apiUrl) |
| | | .url(this.apiHost) |
| | | .post(RequestBody.create(MediaType.parse(ContentType.JSON.getValue()), requestBody)) |
| | | .build(); |
| | | factory.newEventSource(request, eventSourceListener); |
| | |
| | | package org.ruoyi.common.chat.openai.exception; |
| | | |
| | | /** |
| | | * æè¿°ï¼ é误 |
| | | * é误 |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-11 |
| | |
| | | package org.ruoyi.common.chat.openai.exception; |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-11 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼éæºçç¥ |
| | | * éæºçç¥ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-04-03 |
| | |
| | | import java.util.function.Function; |
| | | |
| | | /** |
| | | * æè¿°ï¼key çè·åçç¥ |
| | | * key çè·åçç¥ |
| | | * jdké»è®¤å®ç° |
| | | * @see Function |
| | | * |
| | |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * æè¿°ï¼è¯·æ±å¢å header apikey |
| | | * 请æ±å¢å header apikey |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-23 |
| | |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * æè¿°ï¼å¨æå¤çkeyçé´ææ¦æªå¨ |
| | | * 卿å¤çkeyçé´ææ¦æªå¨ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-04-25 |
| | |
| | | import okhttp3.logging.HttpLoggingInterceptor; |
| | | |
| | | /** |
| | | * æè¿°ï¼ æ¥å¿ |
| | | * æ¥å¿ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-28 |
| | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * æè¿°ï¼openai è¿åå¼å¤çInterceptor |
| | | * openai è¿åå¼å¤çInterceptor |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-23 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼å¯¹è¯è¯·æ±å¯¹è±¡ |
| | | * 对è¯è¯·æ±å¯¹è±¡ |
| | | * |
| | | * @author ageerle |
| | | * @sine 2023-04-08 |
| | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @sine 2023-04-08 |
| | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * æè¿°ï¼ sse |
| | | * sse |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-28 |
| | |
| | | import org.ruoyi.common.chat.openai.plugin.PluginAbstract; |
| | | |
| | | /** |
| | | * æè¿°ï¼ æä»¶å¼åè¿åä¿¡æ¯æ¶ésseçå¬å¨ |
| | | * æä»¶å¼åè¿åä¿¡æ¯æ¶ésseçå¬å¨ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-08-18 |
| | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * æè¿°ï¼ æä»¶å¼åè¿åä¿¡æ¯æ¶ésseçå¬å¨ |
| | | * æä»¶å¼åè¿åä¿¡æ¯æ¶ésseçå¬å¨ |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-08-18 |
| | |
| | | import java.util.*; |
| | | |
| | | /** |
| | | * æè¿°ï¼token计ç®å·¥å
·ç±» |
| | | * token计ç®å·¥å
·ç±» |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-04-04 |
| | |
| | | import org.springframework.context.ApplicationEvent; |
| | | |
| | | /** |
| | | * æè¿°ï¼å®ä¹ä¸ä¸ªäºä»¶ç±»ï¼ç¨äºéç¥é
ç½®åå |
| | | * å®ä¹ä¸ä¸ªäºä»¶ç±»ï¼ç¨äºéç¥é
ç½®åå |
| | | * |
| | | * @author ageerle@163.com |
| | | * date 2024/5/19 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-02 |
| | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ chatçæ¡ç±» |
| | | * chatçæ¡ç±» |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-03-02 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @since 2023-03-02 |
| | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * æè¿°ï¼ |
| | | * |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * 2023-02-15 |
| | |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * æè¿°ï¼å建ä¸ä¸ªçå¬å¨ï¼ç¨äºå¤çé
ç½®ååäºä»¶ |
| | | * å建ä¸ä¸ªçå¬å¨ï¼ç¨äºå¤çé
ç½®ååäºä»¶ |
| | | * |
| | | * @author ageerle@163.com |
| | | * date 2024/5/19 |
| | |
| | | <artifactId>spring-ai-starter-model-openai</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>io.github.imfangs</groupId> |
| | | <artifactId>dify-java-client</artifactId> |
| | | <version>1.0.7</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.coze</groupId> |
| | | <artifactId>coze-api</artifactId> |
| | | <version>0.3.1</version> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| | |
| | | /** |
| | | * 模åä»·æ ¼ |
| | | */ |
| | | private Long modelPrice; |
| | | private Double modelPrice; |
| | | |
| | | /** |
| | | * 计费类å |
| | |
| | | */ |
| | | private String apiHost; |
| | | |
| | | /** |
| | | * 请æ±å°ååç¼ - å
¼å®¹å¤å¹³å° |
| | | */ |
| | | @ExcelProperty(value = "请æ±å°ååç¼") |
| | | private String apiUrl; |
| | | |
| | | /** |
| | | * å¯é¥ |
| | |
| | | * 模åä»·æ ¼ |
| | | */ |
| | | @NotNull(message = "模åä»·æ ¼ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private Long modelPrice; |
| | | private Double modelPrice; |
| | | |
| | | /** |
| | | * 计费类å |
| | |
| | | @NotBlank(message = "å¯é¥ä¸è½ä¸ºç©º", groups = { AddGroup.class, EditGroup.class }) |
| | | private String apiKey; |
| | | |
| | | /** |
| | | * 请æ±å°ååç¼ - å
¼å®¹å¤å¹³å° |
| | | */ |
| | | @ExcelProperty(value = "请æ±å°ååç¼") |
| | | private String apiUrl; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * æè¿°ï¼ç¿»è¯è¯·æ±å¯¹è±¡ |
| | | * ç¿»è¯è¯·æ±å¯¹è±¡ |
| | | * |
| | | * @author ageerle@163.com |
| | | * date 2025/1/13 |
| | |
| | | * 模åä»·æ ¼ |
| | | */ |
| | | @ExcelProperty(value = "模åä»·æ ¼") |
| | | private Long modelPrice; |
| | | private Double modelPrice; |
| | | |
| | | /** |
| | | * 计费类å |
| | |
| | | */ |
| | | @ExcelProperty(value = "å¯é¥") |
| | | private String apiKey; |
| | | |
| | | /** |
| | | * 请æ±å°ååç¼ - å
¼å®¹å¤å¹³å° |
| | | */ |
| | | @ExcelProperty(value = "请æ±å°ååç¼") |
| | | private String apiUrl; |
| | | |
| | | /** |
| | | * 夿³¨ |
| | |
| | | |
| | | |
| | | /** |
| | | * æè¿°ï¼ç¨æ·å¯ç ä¿®æ¹bo |
| | | * ç¨æ·å¯ç ä¿®æ¹bo |
| | | * |
| | | * @author ageerle@163.com |
| | | * date 2025/3/9 |
| | |
| | | public OpenAiStreamClient openAiStreamClient() { |
| | | String apiHost = configService.getConfigValue("chat", "apiHost"); |
| | | String apiKey = configService.getConfigValue("chat", "apiKey"); |
| | | String url = configService.getConfigValue("chat", "apiUrl"); |
| | | openAiStreamClient = createOpenAiStreamClient(apiHost,apiKey,url); |
| | | openAiStreamClient = createOpenAiStreamClient(apiHost,apiKey); |
| | | return openAiStreamClient; |
| | | } |
| | | |
| | | public static OpenAiStreamClient createOpenAiStreamClient(String apiHost, String apiKey,String url) { |
| | | public static OpenAiStreamClient createOpenAiStreamClient(String apiHost, String apiKey) { |
| | | HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger()); |
| | | httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS); |
| | | OkHttpClient okHttpClient = new OkHttpClient.Builder() |
| | |
| | | .build(); |
| | | return OpenAiStreamClient.builder() |
| | | .apiHost(apiHost) |
| | | .apiUrl(url) |
| | | .apiKey(Collections.singletonList(apiKey)) |
| | | .keyStrategy(new KeyRandomStrategy()) |
| | | .okHttpClient(okHttpClient) |
| | |
| | | |
| | | |
| | | /** |
| | | * æè¿°ï¼è天管ç |
| | | * è天管ç |
| | | * |
| | | * @author ageerle@163.com |
| | | * @date 2023-03-01 |
| | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * æè¿°ï¼æçè§é¢è¯·æ±å¯¹è±¡ |
| | | * æçè§é¢è¯·æ±å¯¹è±¡ |
| | | * |
| | | * @author ageerle@163.com |
| | | * date 2024/6/27 |
| | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * æè¿°ï¼çææè¯ |
| | | * çææè¯ |
| | | * |
| | | * @author ageerle@163.com |
| | | * date 2024/6/27 |
| | |
| | | public enum ChatModeType { |
| | | OLLAMA("ollama", "æ¬å°é¨ç½²æ¨¡å"), |
| | | CHAT("chat", "ä¸è½¬æ¨¡å"), |
| | | DIFY("dify", "DIFY"), |
| | | COZE("coze", "æ£å"), |
| | | VECTOR("vector", "ç¥è¯åºå鿍¡å"); |
| | | |
| | | private final String code; |
| | |
| | | import lombok.Getter; |
| | | |
| | | /** |
| | | * æè¿°ï¼æ¯å¦æ¾ç¤º |
| | | * æ¯å¦æ¾ç¤º |
| | | * |
| | | * @author ageerle@163.com |
| | | * date 2025/4/10 |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.chat.factory; |
| | | |
| | | import org.ruoyi.chat.service.chat.IChatService; |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.context.ApplicationContextAware; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | import java.util.Map; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | |
| | | /** |
| | | * è天æå¡å·¥åç±» |
| | | * |
| | | * @author ageerle@163.com |
| | | * date 2025/5/10 |
| | | */ |
| | | @Component |
| | | public class ChatServiceFactory implements ApplicationContextAware { |
| | | private final Map<String, IChatService> chatServiceMap = new ConcurrentHashMap<>(); |
| | | |
| | | @Override |
| | | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { |
| | | // åå§åæ¶æ¶éææIChatServiceçå®ç° |
| | | Map<String, IChatService> serviceMap = applicationContext.getBeansOfType(IChatService.class); |
| | | for (IChatService service : serviceMap.values()) { |
| | | if (service != null) { |
| | | chatServiceMap.put(service.getCategory(), service); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®æ¨¡åç±»å«è·å对åºçè天æå¡å®ç° |
| | | */ |
| | | public IChatService getChatService(String category) { |
| | | IChatService service = chatServiceMap.get(category); |
| | | if (service == null) { |
| | | throw new IllegalArgumentException("䏿¯æç模åç±»å«: " + category); |
| | | } |
| | | return service; |
| | | } |
| | | } |
| | |
| | | import java.util.Objects; |
| | | |
| | | /** |
| | | * æè¿°ï¼OpenAIEventSourceListener |
| | | * OpenAIEventSourceListener |
| | | * |
| | | * @author https:www.unfbx.com |
| | | * @date 2023-02-22 |
| | |
| | | * @param chatRequest 请æ±å¯¹è±¡ |
| | | */ |
| | | SseEmitter chat(ChatRequest chatRequest,SseEmitter emitter); |
| | | |
| | | |
| | | /** |
| | | * è·åæ¤æå¡æ¯æç模åç±»å« |
| | | */ |
| | | String getCategory(); |
| | | } |
| | |
| | | package org.ruoyi.chat.service.chat; |
| | | |
| | | import cn.dev33.satoken.stp.StpUtil; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.ruoyi.chat.enums.DisplayType; |
| | | import org.ruoyi.chat.enums.UserGradeType; |
| | | import org.ruoyi.common.satoken.utils.LoginHelper; |
| | | import org.ruoyi.domain.bo.ChatModelBo; |
| | | import org.ruoyi.domain.bo.ChatPackagePlanBo; |
| | | import org.ruoyi.domain.vo.ChatModelVo; |
| | | import org.ruoyi.domain.vo.ChatPackagePlanVo; |
| | | import org.ruoyi.service.IChatModelService; |
| | | import org.ruoyi.service.IChatPackagePlanService; |
| | | import org.ruoyi.system.domain.vo.SysUserVo; |
| | | import org.ruoyi.system.service.ISysUserService; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * æè¿°ï¼ç¨æ·æ¨¡åä¿¡æ¯ |
| | | * ç¨æ·æ¨¡åä¿¡æ¯ |
| | | * |
| | | * @author ageerle@163.com |
| | | * date 2025/4/10 |
| | |
| | | |
| | | private final IChatModelService chatModelService; |
| | | |
| | | private final ISysUserService userService; |
| | | |
| | | private final IChatPackagePlanService packagePlanService; |
| | | |
| | | public List<ChatModelVo> modelList(ChatModelBo bo) { |
| | | bo.setModelShow(DisplayType.VISIBLE.getCode()); |
| | | List<ChatModelVo> chatModelList = chatModelService.queryList(bo); |
| | | ChatPackagePlanBo sysPackagePlanBo = new ChatPackagePlanBo(); |
| | | if (StpUtil.isLogin()) { |
| | | Long userId = LoginHelper.getLoginUser().getUserId(); |
| | | SysUserVo sysUserVo = userService.selectUserById(userId); |
| | | if (UserGradeType.UNPAID.getCode().equals(sysUserVo.getUserGrade())){ |
| | | sysPackagePlanBo.setName("Free"); |
| | | ChatPackagePlanVo chatPackagePlanVo = packagePlanService.queryList(sysPackagePlanBo).get(0); |
| | | List<String> array = new ArrayList<>(Arrays.asList(chatPackagePlanVo.getPlanDetail().split(","))); |
| | | chatModelList.removeIf(model -> !array.contains(model.getModelName())); |
| | | } |
| | | }else { |
| | | sysPackagePlanBo.setName("Visitor"); |
| | | ChatPackagePlanVo sysPackagePlanVo = packagePlanService.queryList(sysPackagePlanBo).get(0); |
| | | List<String> array = new ArrayList<>(Arrays.asList(sysPackagePlanVo.getPlanDetail().split(","))); |
| | | chatModelList.removeIf(model -> !array.contains(model.getModelName())); |
| | | } |
| | | return new ArrayList<>(chatModelList); |
| | | return chatModelService.queryList(bo); |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.chat.service.chat.impl; |
| | | |
| | | import com.coze.openapi.client.chat.CreateChatReq; |
| | | import com.coze.openapi.client.chat.model.ChatEvent; |
| | | import com.coze.openapi.client.chat.model.ChatEventType; |
| | | import com.coze.openapi.client.connversations.message.model.Message; |
| | | import com.coze.openapi.service.auth.TokenAuth; |
| | | import com.coze.openapi.service.config.Consts; |
| | | import com.coze.openapi.service.service.CozeAPI; |
| | | import io.reactivex.Flowable; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.chat.enums.ChatModeType; |
| | | import org.ruoyi.chat.service.chat.IChatService; |
| | | 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.Collections; |
| | | import java.util.concurrent.ExecutorService; |
| | | import java.util.concurrent.Executors; |
| | | |
| | | /** |
| | | * æ£åè天管ç |
| | | * |
| | | * @author ageer |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | public class CozeServiceImpl implements IChatService { |
| | | |
| | | @Autowired |
| | | private IChatModelService chatModelService; |
| | | |
| | | @Override |
| | | public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) { |
| | | ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); |
| | | |
| | | TokenAuth authCli = new TokenAuth(chatModelVo.getApiKey()); |
| | | CozeAPI coze = |
| | | new CozeAPI.Builder() |
| | | .baseURL(chatModelVo.getApiHost()) |
| | | .auth(authCli) |
| | | .readTimeout(10000) |
| | | .build(); |
| | | CreateChatReq req = |
| | | CreateChatReq.builder() |
| | | .botID(chatModelVo.getModelName()) |
| | | .userID(chatRequest.getUserId().toString()) |
| | | .messages(Collections.singletonList(Message.buildUserQuestionText("What can you do?"))) |
| | | .build(); |
| | | |
| | | Flowable<ChatEvent> resp = coze.chat().stream(req); |
| | | ExecutorService executor = Executors.newFixedThreadPool(10); |
| | | executor.submit(() -> { |
| | | resp.blockingForEach( |
| | | event -> { |
| | | if (ChatEventType.CONVERSATION_MESSAGE_DELTA.equals(event.getEvent())) { |
| | | emitter.send(event.getMessage().getContent()); |
| | | log.info("coze: {}", event.getMessage().getContent()); |
| | | } |
| | | if (ChatEventType.CONVERSATION_CHAT_COMPLETED.equals(event.getEvent())) { |
| | | emitter.complete(); |
| | | log.info("Token usage: {}", event.getChat().getUsage().getTokenCount()); |
| | | } |
| | | } |
| | | ); |
| | | coze.shutdownExecutor(); |
| | | }); |
| | | |
| | | |
| | | return emitter; |
| | | } |
| | | |
| | | @Override |
| | | public String getCategory() { |
| | | return ChatModeType.COZE.getCode(); |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | package org.ruoyi.chat.service.chat.impl; |
| | | |
| | | import io.github.imfangs.dify.client.DifyClient; |
| | | import io.github.imfangs.dify.client.DifyClientFactory; |
| | | import io.github.imfangs.dify.client.callback.ChatStreamCallback; |
| | | import io.github.imfangs.dify.client.enums.ResponseMode; |
| | | import io.github.imfangs.dify.client.event.ErrorEvent; |
| | | import io.github.imfangs.dify.client.event.MessageEndEvent; |
| | | import io.github.imfangs.dify.client.event.MessageEvent; |
| | | import io.github.imfangs.dify.client.model.DifyConfig; |
| | | import io.github.imfangs.dify.client.model.chat.ChatMessage; |
| | | |
| | | import lombok.SneakyThrows; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import org.ruoyi.chat.enums.ChatModeType; |
| | | import org.ruoyi.chat.service.chat.IChatService; |
| | | 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; |
| | | |
| | | /** |
| | | * dify è天管ç |
| | | * |
| | | * @author ageer |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | public class DifyServiceImpl implements IChatService { |
| | | |
| | | @Autowired |
| | | private IChatModelService chatModelService; |
| | | |
| | | @Override |
| | | public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) { |
| | | ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); |
| | | |
| | | // 使ç¨èªå®ä¹é
ç½®å建客æ·ç«¯ |
| | | DifyConfig config = DifyConfig.builder() |
| | | .baseUrl(chatModelVo.getApiHost()) |
| | | .apiKey(chatModelVo.getApiKey()) |
| | | .connectTimeout(5000) |
| | | .readTimeout(60000) |
| | | .writeTimeout(30000) |
| | | .build(); |
| | | DifyClient chatClient = DifyClientFactory.createClient(config); |
| | | |
| | | // å建èå¤©æ¶æ¯ |
| | | ChatMessage message = ChatMessage.builder() |
| | | .query(chatRequest.getPrompt()) |
| | | .user(chatRequest.getUserId().toString()) |
| | | .responseMode(ResponseMode.STREAMING) |
| | | .build(); |
| | | |
| | | // å鿵弿¶æ¯ |
| | | try { |
| | | chatClient.sendChatMessageStream(message, new ChatStreamCallback() { |
| | | @SneakyThrows |
| | | @Override |
| | | public void onMessage(MessageEvent event) { |
| | | emitter.send(event.getAnswer()); |
| | | log.info("æ¶å°æ¶æ¯ç段: {}", event.getAnswer()); |
| | | } |
| | | |
| | | @Override |
| | | public void onMessageEnd(MessageEndEvent event) { |
| | | emitter.complete(); |
| | | log.info("æ¶æ¯ç»æï¼å®æ´æ¶æ¯ID: {}", event.getMessageId()); |
| | | } |
| | | |
| | | @Override |
| | | public void onError(ErrorEvent event) { |
| | | System.err.println("é误: " + event.getMessage()); |
| | | } |
| | | |
| | | @Override |
| | | public void onException(Throwable throwable) { |
| | | System.err.println("å¼å¸¸: " + throwable.getMessage()); |
| | | } |
| | | }); |
| | | } catch (Exception e) { |
| | | log.error("dify请æ±å¤±è´¥ï¼{}", e.getMessage()); |
| | | } |
| | | |
| | | return emitter; |
| | | } |
| | | |
| | | @Override |
| | | public String getCategory() { |
| | | return ChatModeType.DIFY.getCode(); |
| | | } |
| | | |
| | | } |
| | |
| | | import io.github.ollama4j.models.chat.OllamaChatRequestModel; |
| | | import io.github.ollama4j.models.generate.OllamaStreamHandler; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.ruoyi.chat.enums.ChatModeType; |
| | | import org.ruoyi.chat.service.chat.IChatService; |
| | | import org.ruoyi.chat.util.SSEUtil; |
| | | import org.ruoyi.common.chat.entity.chat.Message; |
| | | import org.ruoyi.common.chat.request.ChatRequest; |
| | |
| | | import java.util.concurrent.CompletableFuture; |
| | | |
| | | |
| | | /** |
| | | * @author ageer |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | public class OllamaServiceImpl { |
| | | public class OllamaServiceImpl implements IChatService { |
| | | |
| | | @Autowired |
| | | private IChatModelService chatModelService; |
| | | @Autowired |
| | | private IChatModelService chatModelService; |
| | | |
| | | public SseEmitter chat(ChatRequest chatRequest,SseEmitter emitter) { |
| | | @Override |
| | | public SseEmitter chat(ChatRequest chatRequest, SseEmitter emitter) { |
| | | ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); |
| | | String host = chatModelVo.getApiHost(); |
| | | List<Message> msgList = chatRequest.getMessages(); |
| | |
| | | return emitter; |
| | | } |
| | | |
| | | @Override |
| | | public String getCategory() { |
| | | return ChatModeType.OLLAMA.getCode(); |
| | | } |
| | | } |
| | |
| | | import io.modelcontextprotocol.client.McpSyncClient; |
| | | 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 java.util.List; |
| | | |
| | | |
| | | /** |
| | | * @author ageer |
| | | */ |
| | | @Service |
| | | @Slf4j |
| | | public class OpenAIServiceImpl implements IChatService { |
| | | |
| | | @Autowired |
| | | private IChatModelService chatModelService; |
| | | |
| | | private OpenAiStreamClient openAiStreamClient; |
| | | |
| | | |
| | | @Value("${spring.ai.mcp.client.enabled}") |
| | | private Boolean enabled; |
| | |
| | | @Override |
| | | public SseEmitter chat(ChatRequest chatRequest,SseEmitter emitter) { |
| | | ChatModelVo chatModelVo = chatModelService.selectModelByName(chatRequest.getModel()); |
| | | openAiStreamClient = ChatConfig.createOpenAiStreamClient(chatModelVo.getApiHost(), chatModelVo.getApiKey(),chatModelVo.getApiUrl()); |
| | | OpenAiStreamClient openAiStreamClient = ChatConfig.createOpenAiStreamClient(chatModelVo.getApiHost(), chatModelVo.getApiKey()); |
| | | List<Message> messages = chatRequest.getMessages(); |
| | | if (enabled) { |
| | | String toolString = mcpChat(chatRequest.getPrompt()); |
| | |
| | | return this.chatClient.prompt(prompt).call().content(); |
| | | } |
| | | |
| | | @Override |
| | | public String getCategory() { |
| | | return ChatModeType.CHAT.getCode(); |
| | | } |
| | | |
| | | } |
| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import okhttp3.ResponseBody; |
| | | import org.ruoyi.chat.enums.ChatModeType; |
| | | import org.ruoyi.chat.factory.ChatServiceFactory; |
| | | import org.ruoyi.chat.service.chat.IChatCostService; |
| | | import org.ruoyi.chat.service.chat.IChatService; |
| | | import org.ruoyi.chat.service.chat.ISseService; |
| | | import org.ruoyi.chat.util.IpUtil; |
| | | import org.ruoyi.chat.util.SSEUtil; |
| | |
| | | |
| | | private final IChatModelService chatModelService; |
| | | |
| | | private final OpenAIServiceImpl openAIService; |
| | | |
| | | private final OllamaServiceImpl ollamaService; |
| | | private final ChatServiceFactory chatServiceFactory; |
| | | |
| | | private final IChatSessionService chatSessionService; |
| | | |
| | |
| | | chatCostService.deductToken(chatRequest); |
| | | } |
| | | // æ ¹æ®æ¨¡ååç±»è°ç¨ä¸åçå¤çé»è¾ |
| | | switchModelAndHandle(chatRequest,sseEmitter); |
| | | IChatService chatService = chatServiceFactory.getChatService(chatModelVo.getCategory()); |
| | | chatService.chat(chatRequest, sseEmitter); |
| | | } catch (Exception e) { |
| | | log.error(e.getMessage(),e); |
| | | SSEUtil.sendErrorEvent(sseEmitter,e.getMessage()); |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æ ¹æ®æ¨¡ååç§°åç¼è°ç¨ä¸åçå¤çé»è¾ |
| | | */ |
| | | private void switchModelAndHandle(ChatRequest chatRequest,SseEmitter emitter) { |
| | | // è°ç¨ollamaä¸é¨ç½²çæ¬å°æ¨¡å |
| | | if (ChatModeType.OLLAMA.getCode().equals(chatModelVo.getCategory())) { |
| | | ollamaService.chat(chatRequest,emitter); |
| | | } else { |
| | | openAIService.chat(chatRequest,emitter); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * æå»ºæ¶æ¯å表 |
| | |
| | | import java.util.UUID; |
| | | |
| | | /** |
| | | * æè¿°ï¼å¾®ä¿¡å
¬ä¼å·ç»å½ |
| | | * 微信å
¬ä¼å·ç»å½ |
| | | * |
| | | * @author ageerle@163.com |
| | | * date 2025/4/30 |