tools;
-
- /**
- * 取值:String或者ToolChoiceObj
- *
- * @since 1.1.2
- */
- @JsonProperty("tool_choice")
- private Object toolChoice;
-
- /**
- * 使用什么取样温度,0到2之间。较高的值(如0.8)将使输出更加随机,而较低的值(如0.2)将使输出更加集中和确定。
- *
- * We generally recommend altering this or but not both.top_p
- */
- @Builder.Default
- private double temperature = 0.2;
-
- /**
- * 使用温度采样的替代方法称为核心采样,其中模型考虑具有top_p概率质量的令牌的结果。因此,0.1 意味着只考虑包含前 10% 概率质量的代币。
- *
- * 我们通常建议更改此设置,但不要同时更改两者。temperature
- */
- @JsonProperty("top_p")
- @Builder.Default
- private Double topP = 1d;
-
-
- /**
- * 为每个提示生成的完成次数。
- */
- @Builder.Default
- private Integer n = 1;
-
-
- /**
- * 是否流式输出.
- * default:false
- */
- @Builder.Default
- private boolean stream = false;
- /**
- * 停止输出标识
- */
- private List stop;
- /**
- * 最大支持4096
- */
- @JsonProperty("max_tokens")
- @Builder.Default
- private Integer maxTokens = 2048;
-
-
- @JsonProperty("presence_penalty")
- @Builder.Default
- private double presencePenalty = 0;
-
- /**
- * -2.0 ~~ 2.0
- */
- @JsonProperty("frequency_penalty")
- @Builder.Default
- private double frequencyPenalty = 0;
-
- @JsonProperty("logit_bias")
- private Map logitBias;
- /**
- * 用户唯一值,确保接口不被重复调用
- */
- private String user;
-
- /**
- * @since 1.1.2
- */
- private Integer seed;
-
-
- /**
- * 最新模型参考官方文档:
- * 官方稳定模型列表
- */
- @Getter
- @AllArgsConstructor
- public enum Model {
- /**
- * gpt-3.5-turbo
- */
- GPT_3_5_TURBO("gpt-3.5-turbo"),
- /**
- * 临时模型,不建议使用,2023年9 月 13 日将被弃用
- */
- @Deprecated
- GPT_3_5_TURBO_0301("gpt-3.5-turbo-0301"),
- /**
- * gpt-3.5-turbo-0613 支持函数
- */
- GPT_3_5_TURBO_1106("gpt-3.5-turbo-1106"),
-
- GPT_3_5_TURBO_0613("gpt-3.5-turbo-0613"),
- /**
- * gpt-3.5-turbo-16k 超长上下文
- */
- GPT_3_5_TURBO_16K("gpt-3.5-turbo-16k"),
- /**
- * gpt-3.5-turbo-16k-0613 超长上下文 支持函数
- */
- GPT_3_5_TURBO_16K_0613("gpt-3.5-turbo-16k-0613"),
- /**
- * gpt-3.5-turbo-0125 超长上下文 支持函数
- */
- GPT_3_5_TURBO_0125("gpt-3.5-turbo-0125"),
- /**
- * GPT4.0
- */
- GPT_4("gpt-4"),
- /**
- * 临时模型,不建议使用,2023年9 月 13 日将被弃用
- */
- @Deprecated
- GPT_4_0314("gpt-4-0314"),
- /**
- * GPT4.0 超长上下文
- */
- GPT_4_32K("gpt-4-32k"),
- /**
- * 临时模型,不建议使用,2023年9 月 13 日将被弃用
- */
- @Deprecated
- GPT_4_32K_0314("gpt-4-32k-0314"),
-
- /**
- * gpt-4-0613,支持函数
- */
- GPT_4_0613("gpt-4-0613"),
- /**
- * gpt-4-0613,支持函数
- */
- GPT_4_32K_0613("gpt-4-32k-0613"),
- /**
- * 支持数组模式,支持function call,支持可重复输出
- */
- GPT_4_1106_PREVIEW("gpt-4-1106-preview"),
- /**
- * 支持图片
- */
- GPT_4_VISION_PREVIEW("gpt-4-vision-preview"),
- /**
- * gpt-4-0613,支持函数
- */
- GPT_4_0125_PREVIEW("gpt-4-0125-preview"),
-
- /**
- * GPT_4_ALL
- */
- GPT_4_ALL("gpt-4-all"),
-
- GPT_4_GIZMO("gpt-4-gizmo"),
-
- NET("net"),
-
- CLAUDE_3_SONNET("claude-3-sonnet-20240229"),
-
- GEMINI_PRO("gemini-pro"),
-
- STABLE_DIFFUSION("stable-diffusion"),
-
- SUNO_V3("suno-v3"),
- ;
- private final String name;
- }
-
- @Getter
- @AllArgsConstructor
- public enum ChatType {
- /**
- * 对话类型 - 输入
- */
- CHAT_IN("in"),
- /**
- * 对话类型 - 输出
- */
- CHAT_OUT("out"),
-
- ;
- private final String name;
- }
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/BaseMessage.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/BaseMessage.java
deleted file mode 100644
index 983602f0..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/BaseMessage.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.Getter;
-import org.ruoyi.common.chat.entity.chat.tool.ToolCalls;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * @author https:www.unfbx.com
- * @since 1.1.2
- * 2023-03-02
- */
-@Data
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@JsonIgnoreProperties(ignoreUnknown = true)
-@AllArgsConstructor
-public class BaseMessage implements Serializable {
-
- /**
- * 目前支持四个中角色参考官网,进行情景输入:
- * https://platform.openai.com/docs/guides/chat/introduction
- */
- private String role;
-
-
- private String name;
-
- /**
- * The tool calls generated by the model, such as function calls.
- *
- * @since 1.1.2
- */
- @JsonProperty("tool_calls")
- private List toolCalls;
-
- /**
- * @since 1.1.2
- */
- @JsonProperty("tool_call_id")
- private String toolCallId;
-
- @Deprecated
- @JsonProperty("function_call")
- private FunctionCall functionCall;
-
-
- /**
- * 构造函数
- *
- * @param role 角色
- * @param name name
- * @param functionCall functionCall
- */
- public BaseMessage(String role, String name, FunctionCall functionCall) {
- this.role = role;
- this.name = name;
- this.functionCall = functionCall;
- }
-
- public BaseMessage() {
- }
-
-
- @Getter
- @AllArgsConstructor
- public enum Role {
-
- SYSTEM("system"),
- USER("user"),
- ASSISTANT("assistant"),
- FUNCTION("function"),
- TOOL("tool"),
- ;
- private final String name;
- }
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatChoice.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatChoice.java
deleted file mode 100644
index 8340482c..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatChoice.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * @since 2023-03-02
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class ChatChoice implements Serializable {
- private long index;
- /**
- * 请求参数stream为true返回是delta
- */
- @JsonProperty("delta")
- private Message delta;
- /**
- * 请求参数stream为false返回是message
- */
- @JsonProperty("message")
- private Message message;
- @JsonProperty("finish_reason")
- private String finishReason;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatCompletion.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatCompletion.java
deleted file mode 100644
index 217e3e59..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatCompletion.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.NonNull;
-import lombok.experimental.SuperBuilder;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * chat模型参数
- *
- * @author https:www.unfbx.com
- * 2023-03-02
- */
-@Data
-@SuperBuilder
-@Slf4j
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@NoArgsConstructor
-@AllArgsConstructor
-public class ChatCompletion extends BaseChatCompletion implements Serializable {
-
- /**
- * 问题描述
- */
- @NonNull
- private List messages;
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatCompletionResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatCompletionResponse.java
deleted file mode 100644
index 477e7cf9..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatCompletionResponse.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-import org.ruoyi.common.chat.entity.common.Usage;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * chat答案类
- *
- * @author https:www.unfbx.com
- * 2023-03-02
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class ChatCompletionResponse implements Serializable {
- private String id;
- private String object;
- private long created;
- private String model;
- private List choices;
- private Usage usage;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatCompletionWithPicture.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatCompletionWithPicture.java
deleted file mode 100644
index 64e84406..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatCompletionWithPicture.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.SuperBuilder;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * : chat模型附带图片的参数
- *
- * @author https:www.unfbx.com
- * @since 1.1.2
- * 2023-11-10
- */
-@Data
-@SuperBuilder
-@Slf4j
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@NoArgsConstructor
-@AllArgsConstructor
-public class ChatCompletionWithPicture extends BaseChatCompletion implements Serializable {
- /**
- * 问题描述
- */
- private List messages;
-
-}
diff --git a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatMessage.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatMessage.java
similarity index 71%
rename from ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatMessage.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatMessage.java
index 6a4fac2c..89325dc2 100644
--- a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatMessage.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatMessage.java
@@ -1,24 +1,23 @@
-package org.ruoyi.domain;
+package org.ruoyi.common.chat.entity.chat;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
-import org.ruoyi.core.domain.BaseEntity;
+import org.ruoyi.common.tenant.core.TenantEntity;
import java.io.Serial;
-import java.math.BigDecimal;
/**
* 聊天消息对象 chat_message
*
* @author ageerle
- * @date 2025-04-08
+ * @date 2025-12-14
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("chat_message")
-public class ChatMessage extends BaseEntity {
+public class ChatMessage extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
@@ -29,16 +28,16 @@ public class ChatMessage extends BaseEntity {
@TableId(value = "id")
private Long id;
- /**
- * 用户id
- */
- private Long userId;
-
/**
* 会话id
*/
private Long sessionId;
+ /**
+ * 用户id
+ */
+ private Long userId;
+
/**
* 消息内容
*/
@@ -49,10 +48,6 @@ public class ChatMessage extends BaseEntity {
*/
private String role;
- /**
- * 扣除金额
- */
- private BigDecimal deductCost;
/**
* 累计 Tokens
@@ -69,10 +64,5 @@ public class ChatMessage extends BaseEntity {
*/
private String remark;
- /**
- * 计费类型(1-token计费,2-次数计费,null-普通消息)
- */
- private String billingType;
-
}
diff --git a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatModel.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatModel.java
similarity index 67%
rename from ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatModel.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatModel.java
index 8eaeb4d2..b4621de9 100644
--- a/ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatModel.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ChatModel.java
@@ -1,25 +1,23 @@
-package org.ruoyi.domain;
-
+package org.ruoyi.common.chat.entity.chat;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
-import org.ruoyi.core.domain.BaseEntity;
+import org.ruoyi.common.tenant.core.TenantEntity;
import java.io.Serial;
-
/**
- * 聊天模型对象 chat_model
+ * 模型管理对象 chat_model
*
* @author ageerle
- * @date 2025-04-08
+ * @date 2025-12-14
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("chat_model")
-public class ChatModel extends BaseEntity {
+public class ChatModel extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
@@ -40,20 +38,16 @@ public class ChatModel extends BaseEntity {
*/
private String modelName;
+ /**
+ * 模型供应商
+ */
+ private String providerCode;
+
/**
* 模型描述
*/
private String modelDescribe;
- /**
- * 模型价格
- */
- private Double modelPrice;
-
- /**
- * 计费类型
- */
- private String modelType;
/**
* 是否显示
@@ -61,31 +55,20 @@ public class ChatModel extends BaseEntity {
private String modelShow;
/**
- * 系统提示词
+ * 向量维度
*/
- private String systemPrompt;
+ private Integer modelDimension;
/**
* 请求地址
*/
private String apiHost;
-
/**
* 密钥
*/
private String apiKey;
- /**
- * 优先级
- */
- private Integer priority;
-
- /**
- * 模型供应商
- */
- private String providerName;
-
/**
* 备注
*/
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Content.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Content.java
deleted file mode 100644
index ecffd20d..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Content.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.*;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * @author https://www.unfbx.com
- * @since 1.1.2
- * 2023-11-10
- */
-@Data
-@Builder
-@Slf4j
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@NoArgsConstructor
-@AllArgsConstructor
-public class Content {
- /**
- * 输入类型:text、image_url
- *
- * @see Type
- */
- private String type;
- private String text;
- @JsonProperty("image_url")
- private ImageUrl imageUrl;
-
- /**
- * 生成图片风格
- */
- @Getter
- @AllArgsConstructor
- public enum Type {
- TEXT("text"),
- IMAGE_URL("image_url"),
- ;
- private final String name;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/FastGPTAnswerResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/FastGPTAnswerResponse.java
deleted file mode 100644
index 1673ca52..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/FastGPTAnswerResponse.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-import java.util.List;
-
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class FastGPTAnswerResponse {
- private String id;
- private String object;
- private long created;
- private String model;
- private List choices;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/FastGPTChatChoice.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/FastGPTChatChoice.java
deleted file mode 100644
index 11e9280b..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/FastGPTChatChoice.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class FastGPTChatChoice implements Serializable {
- private long index;
- /**
- * 请求参数stream为true返回是delta
- */
- @JsonProperty("delta")
- private Message delta;
- /**
- * 请求参数stream为false返回是message
- */
- @JsonProperty("message")
- private Message message;
- @JsonProperty("finish_reason")
- private String finishReason;
-}
\ No newline at end of file
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/FastGPTChatCompletion.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/FastGPTChatCompletion.java
deleted file mode 100644
index 8e8dc933..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/FastGPTChatCompletion.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.SuperBuilder;
-
-import java.io.Serializable;
-
-@Data
-@SuperBuilder
-@AllArgsConstructor
-@NoArgsConstructor
-public class FastGPTChatCompletion extends ChatCompletion implements Serializable {
-
- /**
- * 是否使用FastGPT提供的上下文
- */
- private String chatId;
-
-
- /**
- * 是否返回详细信息;stream模式下会通过event进行区分,非stream模式结果保存在responseData中.
- */
- private boolean detail;
-
-
- /**
- * 运行时变量
- * 模块变量,一个对象,会替换模块中,输入fastgpt框内容里的{{key}}
- */
- private Variables variables;
-
- /**
- * responseChatItemId: string | undefined 。
- * 如果传入,则会将该值作为本次对话的响应消息的 ID,
- * FastGPT 会自动将该 ID 存入数据库。请确保,
- * 在当前chatId下,responseChatItemId是唯一的。
- */
- private String responseChatItemId;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/FunctionCall.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/FunctionCall.java
deleted file mode 100644
index fcd8eccc..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/FunctionCall.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * 函数调用返回值
- *
- * @author https://www.unfbx.com
- * @since 2023-06-14
- */
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class FunctionCall {
- /**
- * 方法名
- */
- private String name;
- /**
- * 方法参数
- */
- private String arguments;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Functions.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Functions.java
deleted file mode 100644
index 8b726a6f..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Functions.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import lombok.Builder;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * 方法参数实体类,实例数据如下
- *
- * {
- * "name": "get_current_weather",
- * "description": "Get the current weather in a given location",
- * "parameters": {
- * "type": "object",
- * "properties": {
- * "location": {
- * "type": "string",
- * "description": "The city and state, e.g. San Francisco, CA"
- * },
- * "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
- * },
- * "required": ["location"]
- * },
- * }
- *
- *
- * @author https:www.unfbx.com
- * @since 2023-06-14
- */
-@Data
-@Builder
-public class Functions implements Serializable {
- /**
- * 方法名称
- */
- private String name;
- /**
- * 方法描述
- */
- private String description;
- /**
- * 方法参数
- * 扩展参数可以继承Parameters自己实现,json格式的数据
- */
- private Parameters parameters;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ImageUrl.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ImageUrl.java
deleted file mode 100644
index a15f7e24..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ImageUrl.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * @author https://www.unfbx.com
- * 2023-11-10
- */
-@Data
-@Builder
-@Slf4j
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@NoArgsConstructor
-@AllArgsConstructor
-public class ImageUrl {
- /**
- * 图片地址,支持base64. eg: data:image/jpeg;base64,{base64_image}
- * https://platform.openai.com/docs/guides/vision
- */
- private String url;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Message.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Message.java
deleted file mode 100644
index d49279f8..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Message.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-import org.ruoyi.common.chat.entity.chat.tool.ToolCalls;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * @author https:www.unfbx.com
- * @since 2023-03-02
- */
-@Data
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Message extends BaseMessage implements Serializable {
-
- private Object content;
- @JsonProperty("reasoning_content")
- private String reasoningContent;
-
- /**
- * 构造函数
- *
- * @param role 角色
- * @param name name
- * @param content content
- * @param functionCall functionCall
- */
- public Message(String role, String name, String content, List toolCalls, String toolCallId, FunctionCall functionCall) {
- this.content = content;
- super.setRole(role);
- super.setName(name);
- super.setToolCalls(toolCalls);
- super.setToolCallId(toolCallId);
- super.setFunctionCall(functionCall);
- }
-
- public Message() {
- }
-
- private Message(Builder builder) {
- setContent(builder.content);
- super.setRole(builder.role);
- super.setName(builder.name);
- super.setFunctionCall(builder.functionCall);
- super.setToolCalls(builder.toolCalls);
- super.setToolCallId(builder.toolCallId);
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static final class Builder {
- private String role;
- private String content;
- private String name;
- private String toolCallId;
- private List toolCalls;
- private FunctionCall functionCall;
-
- public Builder() {
- }
-
- public Builder role(Role role) {
- this.role = role.getName();
- return this;
- }
-
- public Builder role(String role) {
- this.role = role;
- return this;
- }
-
- public Builder content(String content) {
- this.content = content;
- return this;
- }
-
- public Builder name(String name) {
- this.name = name;
- return this;
- }
-
- public Builder functionCall(FunctionCall functionCall) {
- this.functionCall = functionCall;
- return this;
- }
-
- public Builder toolCalls(List toolCalls) {
- this.toolCalls = toolCalls;
- return this;
- }
-
- public Builder toolCallId(String toolCallId) {
- this.toolCallId = toolCallId;
- return this;
- }
-
- public Message build() {
- return new Message(this);
- }
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/MessagePicture.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/MessagePicture.java
deleted file mode 100644
index 69fb9be1..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/MessagePicture.java
+++ /dev/null
@@ -1,112 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonInclude;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import org.ruoyi.common.chat.entity.chat.tool.ToolCalls;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * @author https:www.unfbx.com
- * @since 2023-03-02
- */
-@Data
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@JsonIgnoreProperties(ignoreUnknown = true)
-@AllArgsConstructor
-public class MessagePicture extends BaseMessage implements Serializable {
- /**
- * Content数组支持多图片输入
- * https://platform.openai.com/docs/guides/vision
- */
- private List content;
-
-
- /**
- * 构造函数
- *
- * @param role 角色
- * @param name name
- * @param content content
- * @param functionCall functionCall
- */
- public MessagePicture(String role, String name, List content, List toolCalls, String toolCallId, FunctionCall functionCall) {
- this.content = content;
- super.setRole(role);
- super.setName(name);
- super.setToolCalls(toolCalls);
- super.setToolCallId(toolCallId);
- super.setFunctionCall(functionCall);
- }
-
- public MessagePicture() {
- }
-
- private MessagePicture(Builder builder) {
- setContent(builder.content);
- super.setRole(builder.role);
- super.setName(builder.name);
- super.setFunctionCall(builder.functionCall);
- super.setToolCalls(builder.toolCalls);
- super.setToolCallId(builder.toolCallId);
- }
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static final class Builder {
- private String role;
- private List content;
- private String name;
- private String toolCallId;
- private List toolCalls;
- private FunctionCall functionCall;
-
- public Builder() {
- }
-
- public Builder role(Role role) {
- this.role = role.getName();
- return this;
- }
-
- public Builder role(String role) {
- this.role = role;
- return this;
- }
-
- public Builder content(List content) {
- this.content = content;
- return this;
- }
-
- public Builder name(String name) {
- this.name = name;
- return this;
- }
-
- public Builder functionCall(FunctionCall functionCall) {
- this.functionCall = functionCall;
- return this;
- }
-
- public Builder toolCalls(List toolCalls) {
- this.toolCalls = toolCalls;
- return this;
- }
-
- public Builder toolCallId(String toolCallId) {
- this.toolCallId = toolCallId;
- return this;
- }
-
- public MessagePicture build() {
- return new MessagePicture(this);
- }
- }
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Parameters.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Parameters.java
deleted file mode 100644
index abd16ac5..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Parameters.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import lombok.Builder;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * 方法参数类,扩展参数可以继承Parameters自己实现
- * 参考:
- *
- * {
- * "type": "object",
- * "properties": {
- * "location": {
- * "type": "string",
- * "description": "The city and state, e.g. San Francisco, CA"
- * },
- * "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
- * },
- * "required": ["location"]
- * }
- *
- *
- * @author https:www.unfbx.com
- * @since 2023-06-14
- */
-@Data
-@Builder
-public class Parameters implements Serializable {
- /**
- * 参数类型
- */
- private String type;
- /**
- * 参数属性、描述
- */
- private Object properties;
- /**
- * 方法必输字段
- */
- private List required;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ResponseFormat.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ResponseFormat.java
deleted file mode 100644
index d1c691b6..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/ResponseFormat.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-import lombok.*;
-
-/**
- * 指定模型必须输出的格式的对象。
- */
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class ResponseFormat {
- /**
- * 默认:text
- *
- * @see Type
- */
- private String type;
-
- @Getter
- @AllArgsConstructor
- public enum Type {
- JSON_OBJECT("json_object"),
- TEXT("text"),
- ;
- private final String name;
-
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Variables.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Variables.java
deleted file mode 100644
index 3af364ac..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/Variables.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.ruoyi.common.chat.entity.chat;
-
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serializable;
-
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class Variables implements Serializable {
-
- private String uid;
-
- private String name;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolCallFunction.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolCallFunction.java
deleted file mode 100644
index da4a7934..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolCallFunction.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.ruoyi.common.chat.entity.chat.tool;
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serializable;
-
-/**
- * ToolCall 的 Function参数
- * The function that the model called.
- *
- * @author https:www.unfbx.com
- * @since 1.1.2
- * 2023-11-09
- */
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class ToolCallFunction implements Serializable {
- /**
- * 方法名
- */
- private String name;
- /**
- * 方法参数
- */
- private String arguments;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolCalls.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolCalls.java
deleted file mode 100644
index 6feb70ae..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolCalls.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.ruoyi.common.chat.entity.chat.tool;
-
-import lombok.*;
-
-import java.io.Serializable;
-
-/**
- * The tool calls generated by the model, such as function calls.
- *
- * @author unfbx
- * @since 1.1.2
- * 2023-11-09
- */
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class ToolCalls implements Serializable {
- /**
- * The ID of the tool call.
- */
- private String id;
- /**
- * The type of the tool. Currently, only function is supported.
- */
- private String type;
-
- private ToolCallFunction function;
-
- @Getter
- @AllArgsConstructor
- public enum Type {
- FUNCTION("function"),
- ;
- private final String name;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolChoice.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolChoice.java
deleted file mode 100644
index 8eda621f..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolChoice.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.ruoyi.common.chat.entity.chat.tool;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.Getter;
-
-import java.io.Serializable;
-
-/**
- * choice和object同时存在是以object为准
- *
- * @author unfbx
- * @since 1.1.2
- * 2023-11-09
- */
-@Data
-public class ToolChoice implements Serializable {
-
- @Getter
- @AllArgsConstructor
- public enum Choice {
- NONE("none"),
- AUTO("auto"),
- ;
- private final String name;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolChoiceObj.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolChoiceObj.java
deleted file mode 100644
index ca9708c6..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolChoiceObj.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package org.ruoyi.common.chat.entity.chat.tool;
-
-import lombok.*;
-
-/**
- * @author unfbx
- * @since 1.1.2
- * 2023-11-09
- */
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class ToolChoiceObj {
- /**
- * 需要调用的方法名称
- */
- private ToolChoiceObjFunction function;
- /**
- * 工具的类型。目前仅支持函数。
- *
- * @see Type
- */
- private String type;
-
- @Getter
- @AllArgsConstructor
- public enum Type {
- FUNCTION("function"),
- ;
- private final String name;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolChoiceObjFunction.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolChoiceObjFunction.java
deleted file mode 100644
index ac01c744..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolChoiceObjFunction.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.ruoyi.common.chat.entity.chat.tool;
-
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * @author unfbx
- * @since 1.1.2
- * 2023-11-09
- */
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class ToolChoiceObjFunction {
-
- private String name;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/Tools.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/Tools.java
deleted file mode 100644
index 443b4b28..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/Tools.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package org.ruoyi.common.chat.entity.chat.tool;
-
-
-import lombok.*;
-
-import java.io.Serializable;
-
-/**
- * @author unfbx
- * @since 1.1.2
- * 2023-11-09
- */
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class Tools implements Serializable {
-
- /**
- * 目前只支持:function
- *
- * @see Type
- */
- private String type;
-
- private ToolsFunction function;
-
- @Getter
- @AllArgsConstructor
- public enum Type {
- FUNCTION("function"),
- ;
- private final String name;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolsFunction.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolsFunction.java
deleted file mode 100644
index 173d2641..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/chat/tool/ToolsFunction.java
+++ /dev/null
@@ -1,36 +0,0 @@
-package org.ruoyi.common.chat.entity.chat.tool;
-
-
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.ruoyi.common.chat.entity.chat.Parameters;
-
-import java.io.Serializable;
-
-/**
- * @author unfbx
- * @since 1.1.2
- * 2023-11-09
- */
-@Data
-@Builder
-@AllArgsConstructor
-@NoArgsConstructor
-public class ToolsFunction implements Serializable {
-
- /**
- * 要调用的函数的名称。必须是 a-z、A-Z、0-9,或包含下划线和破折号,最大长度为 64
- */
- private String name;
- /**
- * 对函数功能的描述,模型使用它来选择何时以及如何调用该函数。
- */
- private String description;
- /**
- * 函数接受的参数,描述为 JSON Schema 对象
- * 扩展参数可以继承Parameters自己实现,json格式的数据
- */
- private Parameters parameters;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Choice.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Choice.java
deleted file mode 100644
index 4e4f6482..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Choice.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.ruoyi.common.chat.entity.common;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Choice implements Serializable {
- private String text;
- private long index;
- private Object logprobs;
- @JsonProperty("finish_reason")
- private String finishReason;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/DeleteResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/DeleteResponse.java
deleted file mode 100644
index 1f11fea3..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/DeleteResponse.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.ruoyi.common.chat.entity.common;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class DeleteResponse implements Serializable {
- private String id;
- private String object;
- private boolean deleted;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/OpenAiResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/OpenAiResponse.java
deleted file mode 100644
index 20e5f21c..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/OpenAiResponse.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.ruoyi.common.chat.entity.common;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class OpenAiResponse implements Serializable {
- private String object;
- private List data;
- private Error error;
-
-
- @Data
- @JsonIgnoreProperties(ignoreUnknown = true)
- public class Error {
- private String message;
- private String type;
- private String param;
- private String code;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Usage.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Usage.java
deleted file mode 100644
index 9a3e9ecb..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/common/Usage.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.ruoyi.common.chat.entity.common;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Usage implements Serializable {
- @JsonProperty("prompt_tokens")
- private long promptTokens;
- @JsonProperty("completion_tokens")
- private long completionTokens;
- @JsonProperty("total_tokens")
- private long totalTokens;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/Completion.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/Completion.java
deleted file mode 100644
index 267a8510..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/Completion.java
+++ /dev/null
@@ -1,126 +0,0 @@
-package org.ruoyi.common.chat.entity.completions;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.*;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 问题类
- *
- * @author https:www.unfbx.com
- * 2023-02-11
- */
-@Data
-@Builder
-@Slf4j
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@NoArgsConstructor
-@AllArgsConstructor
-public class Completion implements Serializable {
-
- @NonNull
- @Builder.Default
- private String model = Model.DAVINCI_003.getName();
- /**
- * 问题描述
- */
- @NonNull
- private String prompt;
- /**
- * 完成输出后的后缀,用于格式化输出结果
- */
- private String suffix;
-
- /**
- * 最大支持4096
- */
- @JsonProperty("max_tokens")
- @Builder.Default
- private Integer maxTokens = 2048;
- /**
- * 使用什么取样温度,0到2之间。较高的值(如0.8)将使输出更加随机,而较低的值(如0.2)将使输出更加集中和确定。
- *
- * We generally recommend altering this or but not both.top_p
- */
- @Builder.Default
- private double temperature = 0;
-
- /**
- * 使用温度采样的替代方法称为核心采样,其中模型考虑具有top_p概率质量的令牌的结果。因此,0.1 意味着只考虑包含前 10% 概率质量的代币。
- *
- * 我们通常建议更改此设置,但不要同时更改两者。temperature
- */
- @JsonProperty("top_p")
- @Builder.Default
- private Double topP = 1d;
-
- /**
- * 为每个提示生成的完成次数。
- */
- @Builder.Default
- private Integer n = 1;
-
- @Builder.Default
- private boolean stream = false;
- /**
- * 最大值:5
- */
- private Integer logprobs;
-
- @Builder.Default
- private boolean echo = false;
-
- private List stop;
-
- @JsonProperty("presence_penalty")
- @Builder.Default
- private double presencePenalty = 0;
-
- /**
- * -2.0 ~~ 2.0
- */
- @JsonProperty("frequency_penalty")
- @Builder.Default
- private double frequencyPenalty = 0;
-
- @JsonProperty("best_of")
- @Builder.Default
- private Integer bestOf = 1;
-
- @JsonProperty("logit_bias")
- private Map logitBias;
- /**
- * 用户唯一值,确保接口不被重复调用
- */
- private String user;
-
- /**
- * 获取当前参数的tokens数
- *
- * @return token数量
- */
-// public long tokens() {
-// if (StrUtil.isBlank(this.prompt) || StrUtil.isBlank(this.model)) {
-// log.warn("参数异常model:{},prompt:{}", this.model, this.prompt);
-// return 0;
-// }
-// return TikTokensUtil.tokens(this.model, this.prompt);
-// }
-
- @Getter
- @AllArgsConstructor
- public enum Model {
- DAVINCI_003("text-davinci-003"),
- DAVINCI_002("text-davinci-002"),
- DAVINCI("davinci"),
- ;
- private String name;
- }
-}
-
-
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/CompletionResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/CompletionResponse.java
deleted file mode 100644
index 53651fc1..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/completions/CompletionResponse.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package org.ruoyi.common.chat.entity.completions;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-import org.ruoyi.common.chat.entity.common.Choice;
-import org.ruoyi.common.chat.entity.common.OpenAiResponse;
-import org.ruoyi.common.chat.entity.common.Usage;
-
-import java.io.Serializable;
-
-/**
- * 答案类
- *
- * @author https:www.unfbx.com
- * 2023-02-11
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class CompletionResponse extends OpenAiResponse implements Serializable {
- private String id;
- private String object;
- private long created;
- private String model;
- private Choice[] choices;
- private Usage usage;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/Edit.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/Edit.java
deleted file mode 100644
index d7669c39..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/Edit.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package org.ruoyi.common.chat.entity.edits;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.*;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Getter
-@Builder
-@Slf4j
-@NoArgsConstructor
-@AllArgsConstructor
-public class Edit implements Serializable {
- /**
- * 编辑模型,目前支持两种
- */
- @NonNull
- private String model;
-
- @NonNull
- private String input;
- /**
- * 提示说明。告知模型如何修改。
- */
- @NonNull
- private String instruction;
-
-
- /**
- * 使用什么取样温度,0到2之间。较高的值(如0.8)将使输出更加随机,而较低的值(如0.2)将使输出更加集中和确定。
- *
- * We generally recommend altering this or but not both.top_p
- */
- @Builder.Default
- private double temperature = 0;
-
- /**
- * 使用温度采样的替代方法称为核心采样,其中模型考虑具有top_p概率质量的令牌的结果。因此,0.1 意味着只考虑包含前 10% 概率质量的代币。
- *
- * 我们通常建议更改此设置,但不要同时更改两者。temperature
- */
- @JsonProperty("top_p")
- @Builder.Default
- private Double topP = 1d;
-
- /**
- * 为每个提示生成的完成次数。
- */
- @Builder.Default
- private Integer n = 1;
-
- public void setModel(Model model) {
- this.model = model.getName();
- }
-
- public void setTemperature(double temperature) {
- if (temperature > 2 || temperature < 0) {
- log.error("temperature参数异常,temperature属于[0,2]");
- this.temperature = 2;
- return;
- }
- if (temperature < 0) {
- log.error("temperature参数异常,temperature属于[0,2]");
- this.temperature = 0;
- return;
- }
- this.temperature = temperature;
- }
-
-
- public void setTopP(Double topP) {
- this.topP = topP;
- }
-
- public void setN(Integer n) {
- this.n = n;
- }
-
- public void setInput(String input) {
- this.input = input;
- }
-
- public void setInstruction(String instruction) {
- this.instruction = instruction;
- }
-
- @Getter
- @AllArgsConstructor
- public enum Model {
- TEXT_DAVINCI_EDIT_001("text-davinci-edit-001"),
- CODE_DAVINCI_EDIT_001("code-davinci-edit-001"),
- ;
- private String name;
- }
-}
-
-
-
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/EditResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/EditResponse.java
deleted file mode 100644
index 9c0adf70..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/edits/EditResponse.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.ruoyi.common.chat.entity.edits;
-
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-import org.ruoyi.common.chat.entity.common.Choice;
-import org.ruoyi.common.chat.entity.common.Usage;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class EditResponse implements Serializable {
- private String id;
- private String object;
- private long created;
- private String model;
- private Choice[] choices;
- private Usage usage;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/Embedding.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/Embedding.java
deleted file mode 100644
index c07bbf1d..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/Embedding.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.ruoyi.common.chat.entity.embeddings;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import lombok.*;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Getter
-@Slf4j
-@Builder
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@NoArgsConstructor
-@AllArgsConstructor
-public class Embedding implements Serializable {
- @NonNull
- @Builder.Default
- private String model = Model.TEXT_EMBEDDING_ADA_002.getName();
- /**
- * 必选项:长度不能超过:8192
- */
- @NonNull
- private List input;
-
- private String user;
-
- public void setModel(Model model) {
- if (Objects.isNull(model)) {
- model = Model.TEXT_EMBEDDING_ADA_002;
- }
- this.model = model.getName();
- }
-
-
- public void setUser(String user) {
- this.user = user;
- }
-
- @Getter
- @AllArgsConstructor
- public enum Model {
- TEXT_EMBEDDING_ADA_002("text-embedding-ada-002"),
- ;
- private String name;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/EmbeddingResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/EmbeddingResponse.java
deleted file mode 100644
index 9b157bd2..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/EmbeddingResponse.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package org.ruoyi.common.chat.entity.embeddings;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-import org.ruoyi.common.chat.entity.common.Usage;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class EmbeddingResponse implements Serializable {
-
- private String object;
- private List- data;
- private String model;
- private Usage usage;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/Item.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/Item.java
deleted file mode 100644
index ba9deba9..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/embeddings/Item.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.ruoyi.common.chat.entity.embeddings;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.util.List;
-
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Item implements Serializable {
- private String object;
- private List embedding;
- private Integer index;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/engines/Engine.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/engines/Engine.java
deleted file mode 100644
index 9a2113bb..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/engines/Engine.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.ruoyi.common.chat.entity.engines;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Engine implements Serializable {
-
- private String id;
- private String object;
- private String owner;
- private boolean ready;
- private Object permissions;
- private long created;
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/File.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/File.java
deleted file mode 100644
index 6e932d01..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/File.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.ruoyi.common.chat.entity.files;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class File implements Serializable {
-
-// private String id;
-// private String object;
-// private long bytes;
-// private long created_at;
-// private String filename;
-// private String purpose;
-// private String status;
-// @JsonProperty("status_details")
-// private String statusDetails;
-
- private long bytes;
- private long created_at;
- private String filename;
- private String id;
- private String object;
- private String url;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/UploadFileResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/UploadFileResponse.java
deleted file mode 100644
index 385b951c..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/files/UploadFileResponse.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.ruoyi.common.chat.entity.files;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class UploadFileResponse extends File implements Serializable {
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/Event.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/Event.java
deleted file mode 100644
index f8b68492..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/Event.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.ruoyi.common.chat.entity.fineTune;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Event implements Serializable {
- private String object;
- @JsonProperty("created_at")
- private long createdAt;
- private String level;
- private String message;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTune.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTune.java
deleted file mode 100644
index 096caa42..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTune.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package org.ruoyi.common.chat.entity.fineTune;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.*;
-import lombok.extern.slf4j.Slf4j;
-import org.ruoyi.common.chat.openai.exception.CommonError;
-import org.ruoyi.common.core.exception.base.BaseException;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.Objects;
-
-@Getter
-@Slf4j
-@Builder
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@NoArgsConstructor
-@AllArgsConstructor
-public class FineTune implements Serializable {
-
- /**
- * 上传的文件ID
- */
- @NonNull
- @JsonProperty("training_file")
- private String trainingFile;
-
- @JsonProperty("validation_file")
- private String validationFile;
- /**
- * 参考
- *
- * @see Model
- */
- private String model;
-
- @JsonProperty("n_epochs")
- @Builder.Default
- private Integer n_epochs = 4;
-
- @JsonProperty("batch_size")
- private Integer batchSize;
-
- @JsonProperty("learning_rate_multiplier")
- private Double learningRateMultiplier;
-
- @JsonProperty("prompt_loss_weight")
- @Builder.Default
- private Double promptLossWeight = 0.01;
-
- @JsonProperty("compute_classification_metrics")
- @Builder.Default
- private boolean computeClassificationMetrics = false;
-
- @JsonProperty("classification_n_classes")
- private Integer classificationNClasses;
-
- @JsonProperty("classification_betas")
- private List classificationBetas;
-
- private String suffix;
-
- public void setTrainingFile(String trainingFile) {
- this.trainingFile = trainingFile;
- }
-
- public void setValidationFile(String validationFile) {
- this.validationFile = validationFile;
- }
-
- public void setModel(String model) {
- this.model = model;
- }
-
- public void setN_epochs(Integer n_epochs) {
- this.n_epochs = n_epochs;
- }
-
- public void setBatchSize(Integer batchSize) {
- this.batchSize = batchSize;
- }
-
- public void setLearningRateMultiplier(Double learningRateMultiplier) {
- this.learningRateMultiplier = learningRateMultiplier;
- }
-
- public void setPromptLossWeight(Double promptLossWeight) {
- this.promptLossWeight = promptLossWeight;
- }
-
- public void setComputeClassificationMetrics(boolean computeClassificationMetrics) {
- this.computeClassificationMetrics = computeClassificationMetrics;
- }
-
- public void setClassificationNClasses(Integer classificationNClasses) {
- this.classificationNClasses = classificationNClasses;
- }
-
- public void setClassificationBetas(List classificationBetas) {
- this.classificationBetas = classificationBetas;
- }
-
- public void setSuffix(String suffix) {
- if (Objects.nonNull(suffix) && !"".equals(suffix) && suffix.length() > 40) {
- log.error("后缀长度不能大于40");
- throw new BaseException(CommonError.PARAM_ERROR.msg());
- }
- this.suffix = suffix;
- }
-
- @Getter
- @AllArgsConstructor
- public enum Model {
- // or a fine-tuned model created after 2022-04-21.
- ADA("ada"),
- BABBAGE("babbage"),
- CURIE("curie"),
- DAVINCI("davinci"),
- ;
- private String name;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTuneDeleteResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTuneDeleteResponse.java
deleted file mode 100644
index 90a145b4..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTuneDeleteResponse.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.ruoyi.common.chat.entity.fineTune;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-import java.io.Serializable;
-
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class FineTuneDeleteResponse implements Serializable {
-
- private String id;
-
- private String object;
-
- private boolean deleted;
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTuneResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTuneResponse.java
deleted file mode 100644
index 5b8a3d3b..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/FineTuneResponse.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.ruoyi.common.chat.entity.fineTune;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.List;
-
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class FineTuneResponse implements Serializable {
-
- private String id;
-
- private String object;
-
- private String model;
-
- @JsonProperty("created_at")
- private long createdAt;
-
- private List events;
-
- @JsonProperty("fine_tuned_model")
- private String fineTunedModel;
-
- @JsonProperty("hyperparams")
- private HyperParam hyperParams;
-
- @JsonProperty("organization_id")
- private String organizationId;
-
- @JsonProperty("result_files")
- private List resultFiles;
-
- private String status;
-
- @JsonProperty("validation_files")
- private List validationFiles;
-
- @JsonProperty("training_files")
- private List trainingFiles;
-
- @JsonProperty("updated_at")
- private long updatedAt;
-
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/HyperParam.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/HyperParam.java
deleted file mode 100644
index c685f660..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/HyperParam.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.ruoyi.common.chat.entity.fineTune;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class HyperParam implements Serializable {
-
- @JsonProperty("batch_size")
- private Integer batchSize;
- @JsonProperty("learning_rate_multiplier")
- private Double learningRateMultiplier;
- @JsonProperty("n_epochs")
- private Integer nEpochs;
- @JsonProperty("prompt_loss_weight")
- private Double promptLossWeight;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/TrainingFile.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/TrainingFile.java
deleted file mode 100644
index afd371ae..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/fineTune/TrainingFile.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.ruoyi.common.chat.entity.fineTune;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class TrainingFile implements Serializable {
-
- private String id;
- private String object;
- private long bytes;
- @JsonProperty("created_at")
- private long createdAt;
- private String filename;
- private String purpose;
- private String status;
- @JsonProperty("status_details")
- private String statusDetails;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/image/ImageContext.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/image/ImageContext.java
new file mode 100644
index 00000000..60be2739
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/image/ImageContext.java
@@ -0,0 +1,45 @@
+package org.ruoyi.common.chat.entity.image;
+
+import jakarta.validation.constraints.Max;
+import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.NotNull;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
+
+/**
+ * 文生图对话上下文对象
+ *
+ * @author zengxb
+ * @date 2026-02-14
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Builder
+public class ImageContext {
+
+ /**
+ * 模型管理视图对象
+ */
+ @NotNull(message = "模型管理视图对象不能为空")
+ private ChatModelVo chatModelVo;
+
+ /**
+ * 提示词
+ */
+ @NotNull(message = "提示词不能为空")
+ private String prompt;
+
+ /**
+ * 图片尺寸大小
+ */
+ private String size;
+
+ /**
+ * 随机数种子
+ */
+ @Min(value = 0, message = "随机数种子不能小于0")
+ @Max(value = 2147483647, message = "随机数种子不能大于2147483647")
+ private Integer seed;
+}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Image.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Image.java
deleted file mode 100644
index ba830bbe..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Image.java
+++ /dev/null
@@ -1,109 +0,0 @@
-package org.ruoyi.common.chat.entity.images;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Getter
-@Slf4j
-@Builder
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@NoArgsConstructor
-@AllArgsConstructor
-public class Image implements Serializable {
-
- /**
- * 提示词:dall-e-2支持1000字符、dall-e-3支持4000字符
- */
- private String prompt;
- /**
- * 支持dall-e-2、dall-e-3
- *
- * @see Model
- */
- @Builder.Default
- private String model = Model.DALL_E_3.getName();
-
- /**
- * 此参数仅仅dall-e-3,默认值:standard
- *
- * @see Quality
- */
- private String quality;
-
- /**
- * 为每个提示生成的个数,dall-e-3只能为1。
- */
- private Integer n;
- /**
- * 图片尺寸,默认值:1024x1024
- * dall-e-2支持:256x256, 512x512, or 1024x1024
- * dall-e-3支持:1024x1024, 1792x1024, or 1024x1792
- *
- * @see SizeEnum
- */
- private String size;
- /**
- * 此参数仅仅dall-e-3,取值范围:vivid、natural
- * 默认值:vivid
- *
- * @see Style
- */
- private String style;
-
- /**
- * 生成图片格式:url、b64_json
- *
- * @see ResponseFormat
- */
- @JsonProperty("response_format")
- private String responseFormat;
-
- private String user;
-
- /**
- * 图片生成模型
- */
- @Getter
- @AllArgsConstructor
- public enum Model {
- DALL_E_2("dall-e-2"),
- DALL_E_3("dall-e-3"),
- ;
- private final String name;
- }
-
- /**
- * 生成图片质量
- */
- @Getter
- @AllArgsConstructor
- public enum Quality {
- STANDARD("standard"),
- HD("hd"),
- ;
- private final String name;
- }
-
- /**
- * 生成图片风格
- */
- @Getter
- @AllArgsConstructor
- public enum Style {
- VIVID("vivid"),
- NATURAL("natural"),
- ;
- private final String name;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageEdit.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageEdit.java
deleted file mode 100644
index 5a781bf3..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageEdit.java
+++ /dev/null
@@ -1,96 +0,0 @@
-package org.ruoyi.common.chat.entity.images;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.*;
-import lombok.extern.slf4j.Slf4j;
-import org.ruoyi.common.chat.openai.exception.CommonError;
-import org.ruoyi.common.core.exception.base.BaseException;
-
-import java.io.Serializable;
-import java.util.Objects;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Getter
-@Slf4j
-@Builder
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@NoArgsConstructor
-@AllArgsConstructor
-public class ImageEdit implements Serializable {
- /**
- * 必选项:描述文字,最多1000字符
- */
- @NonNull
- private String prompt;
- /**
- * 为每个提示生成的完成次数。
- */
- @Builder.Default
- private Integer n = 1;
- /**
- * 256x256
- * 512x512
- * 1024x1024
- */
- @Builder.Default
- private String size = SizeEnum.size_512.getName();
-
- @JsonProperty("response_format")
- @Builder.Default
- private String responseFormat = ResponseFormat.URL.getName();
-
- private String user;
-
- public ImageEdit setN(Integer n) {
- if (n < 1) {
- log.warn("n最小值1");
- n = 1;
- }
- if (n > 10) {
- log.warn("n最大值10");
- n = 10;
- }
- this.n = n;
- return this;
- }
-
- public ImageEdit setPrompt(String prompt) {
- if (Objects.isNull(prompt) || "".equals(prompt)) {
- log.error("参数异常");
- throw new BaseException(CommonError.PARAM_ERROR.msg());
- }
- if (prompt.length() > 1000) {
- log.error("长度超过1000");
- throw new BaseException(CommonError.PARAM_ERROR.msg());
- }
- this.prompt = prompt;
- return this;
- }
-
- public ImageEdit setSize(SizeEnum size) {
- if (Objects.isNull(size)) {
- size = SizeEnum.size_512;
- }
- this.size = size.getName();
- return this;
- }
-
- public ImageEdit setResponseFormat(ResponseFormat responseFormat) {
- if (Objects.isNull(responseFormat)) {
- responseFormat = ResponseFormat.URL;
- }
- this.responseFormat = responseFormat.getName();
- return this;
- }
-
- public ImageEdit setUser(String user) {
- this.user = user;
- return this;
- }
-
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageResponse.java
deleted file mode 100644
index 000767af..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageResponse.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.ruoyi.common.chat.entity.images;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class ImageResponse implements Serializable {
- private long created;
- private List
- data;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageVariations.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageVariations.java
deleted file mode 100644
index a36b8b88..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ImageVariations.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package org.ruoyi.common.chat.entity.images;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
-
-import java.io.Serializable;
-import java.util.Objects;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Getter
-@Slf4j
-@Builder
-@JsonInclude(JsonInclude.Include.NON_NULL)
-@NoArgsConstructor
-@AllArgsConstructor
-public class ImageVariations implements Serializable {
- /**
- * 为每个提示生成的完成次数。
- */
- @Builder.Default
- private Integer n = 1;
- /**
- * 256x256
- * 512x512
- * 1024x1024
- */
- @Builder.Default
- private String size = SizeEnum.size_512.getName();
-
- @JsonProperty("response_format")
- @Builder.Default
- private String responseFormat = ResponseFormat.URL.getName();
-
- private String user;
-
-
- public void setN(Integer n) {
- if (n < 1) {
- log.warn("n最小值1");
- this.n = 1;
- return;
- }
- if (n > 10) {
- log.warn("n最大值10");
- this.n = 10;
- return;
- }
- this.n = n;
- }
-
-
- public void setSize(SizeEnum size) {
- if (Objects.isNull(size)) {
- size = SizeEnum.size_512;
- }
- this.size = size.getName();
- }
-
- public void setResponseFormat(ResponseFormat responseFormat) {
- if (Objects.isNull(responseFormat)) {
- responseFormat = ResponseFormat.URL;
- }
- this.responseFormat = responseFormat.getName();
- }
-
- public void setUser(String user) {
- this.user = user;
- }
-
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Item.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Item.java
deleted file mode 100644
index 625290fa..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/Item.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.ruoyi.common.chat.entity.images;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Item implements Serializable {
- private String url;
- @JsonProperty("b64_json")
- private String b64Json;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ResponseFormat.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ResponseFormat.java
deleted file mode 100644
index 9f2dcce9..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/ResponseFormat.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.ruoyi.common.chat.entity.images;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@AllArgsConstructor
-@Getter
-public enum ResponseFormat implements Serializable {
- URL("url"),
- B64_JSON("b64_json"),
- ;
-
- private String name;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/SizeEnum.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/SizeEnum.java
deleted file mode 100644
index 3c8f34c3..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/images/SizeEnum.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.ruoyi.common.chat.entity.images;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Getter
-@AllArgsConstructor
-public enum SizeEnum implements Serializable {
- size_1024_1792("1024x1792"),
- size_1792_1024("1792x1024"),
- size_1024("1024x1024"),
- size_512("512x512"),
- size_256("256x256"),
-
- ;
- private String name;
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/LocalModelsSearchRequest.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/LocalModelsSearchRequest.java
deleted file mode 100644
index 4ca71bab..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/LocalModelsSearchRequest.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.ruoyi.common.chat.entity.models;
-
-import lombok.Data;
-
-import java.util.List;
-
-/**
- * @program: RUOYIAI
- * @ClassName LocalModelsSearchRequest
- * @description:
- * @author: hejh
- * @create: 2025-03-15 17:22
- * @Version 1.0
- **/
-@Data
-public class LocalModelsSearchRequest {
-
- private List text;
- private String model_name;
- private String delimiter;
- private int k;
- private int block_size;
- private int overlap_chars;
-
- // 构造函数、Getter 和 Setter
- public LocalModelsSearchRequest(List text, String model_name, String delimiter, int k, int block_size, int overlap_chars) {
- this.text = text;
- this.model_name = model_name;
- this.delimiter = delimiter;
- this.k = k;
- this.block_size = block_size;
- this.overlap_chars = overlap_chars;
- }
-
-
-}
-
-
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/LocalModelsSearchResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/LocalModelsSearchResponse.java
deleted file mode 100644
index e0d68cac..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/LocalModelsSearchResponse.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.ruoyi.common.chat.entity.models;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.util.List;
-
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class LocalModelsSearchResponse {
- @JsonProperty("topKEmbeddings")
-
- private List
>> topKEmbeddings; // 处理三层嵌套数组
-
- // 默认构造函数
- public LocalModelsSearchResponse() {
- }
-
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Model.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Model.java
deleted file mode 100644
index 80a22dc0..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Model.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.ruoyi.common.chat.entity.models;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Model implements Serializable {
-
- private String id;
- private String object;
- private long created;
- @JsonProperty("owned_by")
- private String ownedBy;
- @JsonProperty("permission")
- private List permission;
- private String root;
- private Object parent;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/ModelResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/ModelResponse.java
deleted file mode 100644
index 2c14bb70..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/ModelResponse.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.ruoyi.common.chat.entity.models;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class ModelResponse implements Serializable {
- private String object;
- private List data;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Permission.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Permission.java
deleted file mode 100644
index f54a8ef7..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/models/Permission.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package org.ruoyi.common.chat.entity.models;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Permission implements Serializable {
-
- private String id;
- @JsonProperty("object")
- private String object;
- @JsonProperty("created")
- private long created;
- @JsonProperty("allow_create_engine")
- private boolean allowCreateEngine;
- @JsonProperty("allow_sampling")
- private boolean allowSampling;
- @JsonProperty("allow_logprobs")
- private boolean allowLogprobs;
- @JsonProperty("allow_search_indices")
- private boolean allowSearchIndices;
- @JsonProperty("allow_view")
- private boolean allowView;
- @JsonProperty("allow_fine_tuning")
- private boolean allowFineTuning;
- @JsonProperty("organization")
- private String organization;
- /**
- * 不知道是什么类型的数据
- */
- @JsonProperty("group")
- private Object group;
- @JsonProperty("is_blocking")
- private boolean isBlocking;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Categories.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Categories.java
deleted file mode 100644
index 65d566fb..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Categories.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package org.ruoyi.common.chat.entity.moderations;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Categories implements Serializable {
- /**
- * 表达、煽动或宣扬基于种族、性别、民族、宗教、国籍、性取向、残疾状况或种姓的仇恨的内容。
- */
- private boolean hate;
- /**
- * 仇恨内容,还包括对目标群体的暴力或严重伤害。
- */
- @JsonProperty("hate/threatening")
- private boolean hateThreatening;
- /**
- * 宣扬、鼓励或描绘自残行为(例如自杀、割伤和饮食失调)的内容。
- */
- @JsonProperty("self-harm")
- private boolean selfHarm;
- /**
- * 旨在引起性兴奋的内容,例如对性活动的描述,或宣传性服务(不包括性教育和健康)的内容。
- */
- private boolean sexual;
- /**
- * 包含未满 18 周岁的个人的色情内容。
- */
- @JsonProperty("sexual/minors")
- private boolean sexualMinors;
- /**
- * 宣扬或美化暴力或歌颂他人遭受苦难或羞辱的内容。
- */
- private boolean violence;
- /**
- * 以极端血腥细节描绘死亡、暴力或严重身体伤害的暴力内容。
- */
- @JsonProperty("violence/graphic")
- private boolean violenceGraphic;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/CategoryScores.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/CategoryScores.java
deleted file mode 100644
index f78066b9..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/CategoryScores.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.ruoyi.common.chat.entity.moderations;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class CategoryScores implements Serializable {
- private BigDecimal hate;
- @JsonProperty("hate/threatening")
- private BigDecimal hateThreatening;
- @JsonProperty("self-harm")
- private BigDecimal selfHarm;
- private BigDecimal sexual;
- @JsonProperty("sexual/minors")
- private BigDecimal sexualMinors;
- private BigDecimal violence;
- @JsonProperty("violence/graphic")
- private BigDecimal violenceGraphic;
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Moderation.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Moderation.java
deleted file mode 100644
index bd42e75f..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Moderation.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.ruoyi.common.chat.entity.moderations;
-
-import lombok.*;
-import lombok.extern.slf4j.Slf4j;
-import org.ruoyi.common.chat.openai.exception.CommonError;
-import org.ruoyi.common.core.exception.base.BaseException;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.Objects;
-
-/**
- * 文本审核,敏感词鉴别
- *
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Getter
-@Builder
-@Slf4j
-@NoArgsConstructor
-@AllArgsConstructor
-public class Moderation implements Serializable {
-
- @NonNull
- private List input;
- @Builder.Default
- private String model = Model.TEXT_MODERATION_LATEST.getName();
-
- public void setInput(List input) {
- if (Objects.isNull(input) || input.size() == 0) {
- log.error("input不能为空");
- throw new BaseException(CommonError.PARAM_ERROR.msg());
- }
- this.input = input;
- }
-
- public void setModel(Model model) {
- if (Objects.isNull(model)) {
- model = Model.TEXT_MODERATION_LATEST;
- }
- this.model = model.getName();
- }
-
- @Getter
- @AllArgsConstructor
- public enum Model {
- TEXT_MODERATION_STABLE("text-moderation-stable"),
- TEXT_MODERATION_LATEST("text-moderation-latest"),
- ;
-
- private String name;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/ModerationResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/ModerationResponse.java
deleted file mode 100644
index a2c2e667..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/ModerationResponse.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.ruoyi.common.chat.entity.moderations;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class ModerationResponse implements Serializable {
- private String id;
- private String model;
- private List results;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Result.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Result.java
deleted file mode 100644
index b73f12fa..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/moderations/Result.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package org.ruoyi.common.chat.entity.moderations;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class Result implements Serializable {
- private Categories categories;
- @JsonProperty("category_scores")
- private CategoryScores categoryScores;
- private boolean flagged;
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Transcriptions.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Transcriptions.java
deleted file mode 100644
index cf8fbdb5..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Transcriptions.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.ruoyi.common.chat.entity.whisper;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.FieldNameConstants;
-
-/**
- * @author Admin
- */
-@Data
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-@FieldNameConstants
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class Transcriptions extends Whisper {
- /**
- * 模型目前只支持这一种:WHISPER_1
- */
- @Builder.Default
- private String model = Model.WHISPER_1.getName();
- /**
- * 提示语,需要与语音语言匹配
- */
- private String prompt;
- /**
- * 输出的格式,采用以下选项之一:json、text、srt、verbose_json 或 vtt。
- * 默认值:json
- */
- @JsonProperty("response_format")
- @Builder.Default
- private String responseFormat = ResponseFormat.JSON.getName();
- /**
- * 温度控制随机效果:0-1,值越大输出更加随机
- * 默认值:0
- */
- @Builder.Default
- private Double temperature = 0d;
- /**
- * 输入音频的语言,以 ISO-639-1 格式提供输入语言将提高准确性和延迟。
- * 参考:ISO-639-1
- */
- private String language;
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Translations.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Translations.java
deleted file mode 100644
index 4ad14129..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Translations.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.ruoyi.common.chat.entity.whisper;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import lombok.experimental.FieldNameConstants;
-
-@Data
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-@FieldNameConstants
-@JsonInclude(JsonInclude.Include.NON_NULL)
-public class Translations {
- /**
- * 模型目前只支持这一种:WHISPER_1
- */
- @Builder.Default
- private String model = Whisper.Model.WHISPER_1.getName();
- /**
- * 提示语,需要与语音语言匹配
- */
- private String prompt;
- /**
- * 输出的格式,采用以下选项之一:json、text、srt、verbose_json 或 vtt。
- * 默认值:json
- */
- @JsonProperty("response_format")
- @Builder.Default
- private String responseFormat = Whisper.ResponseFormat.JSON.getName();
- /**
- * 温度控制随机效果:0-1,值越大输出更加随机
- * 默认值:0
- */
- @Builder.Default
- private double temperature = 0;
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Whisper.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Whisper.java
deleted file mode 100644
index ea5f3e92..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/Whisper.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package org.ruoyi.common.chat.entity.whisper;
-
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.Getter;
-
-import java.io.Serializable;
-
-/**
- * 语音转文字
- *
- * @author https:www.unfbx.com
- * @since 2023-03-02
- */
-@Data
-public class Whisper implements Serializable {
-
-
- @Getter
- @AllArgsConstructor
- public enum Model {
- WHISPER_1("whisper-1"),
- ;
- private String name;
- }
-
- @Getter
- @AllArgsConstructor
- public enum ResponseFormat {
- JSON("json"),
- TEXT("text"),
- SRT("srt"),
- VERBOSE_JSON("verbose_json"),
- VTT("vtt"),
- ;
- private String name;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/WhisperResponse.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/WhisperResponse.java
deleted file mode 100644
index 03afa121..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/entity/whisper/WhisperResponse.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.ruoyi.common.chat.entity.whisper;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author https:www.unfbx.com
- * @since 2023-03-02
- */
-@Data
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class WhisperResponse implements Serializable {
-
- private String text;
-}
diff --git a/ruoyi-modules-api/ruoyi-workflow-api/src/main/java/org/ruoyi/workflow/enums/BaseEnum.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/BaseEnum.java
similarity index 84%
rename from ruoyi-modules-api/ruoyi-workflow-api/src/main/java/org/ruoyi/workflow/enums/BaseEnum.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/BaseEnum.java
index 66a2fb63..902adf45 100644
--- a/ruoyi-modules-api/ruoyi-workflow-api/src/main/java/org/ruoyi/workflow/enums/BaseEnum.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/BaseEnum.java
@@ -1,4 +1,4 @@
-package org.ruoyi.workflow.enums;
+package org.ruoyi.common.chat.enums;
import com.baomidou.mybatisplus.annotation.IEnum;
diff --git a/ruoyi-modules-api/ruoyi-workflow-api/src/main/java/org/ruoyi/workflow/enums/ErrorEnum.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/ErrorEnum.java
similarity index 99%
rename from ruoyi-modules-api/ruoyi-workflow-api/src/main/java/org/ruoyi/workflow/enums/ErrorEnum.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/ErrorEnum.java
index f9de801e..06095cec 100644
--- a/ruoyi-modules-api/ruoyi-workflow-api/src/main/java/org/ruoyi/workflow/enums/ErrorEnum.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/ErrorEnum.java
@@ -1,4 +1,4 @@
-package org.ruoyi.workflow.enums;
+package org.ruoyi.common.chat.enums;
import lombok.Getter;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/RoleType.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/RoleType.java
new file mode 100644
index 00000000..daaaaaa2
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/RoleType.java
@@ -0,0 +1,26 @@
+package org.ruoyi.common.chat.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * 角色枚举
+ *
+ * @author ageerle@163.com
+ * @date 2025-12-17
+ */
+@Getter
+@AllArgsConstructor
+public enum RoleType {
+
+ SYSTEM("system"),
+ USER("user"),
+ ASSISTANT("assistant"),
+ FUNCTION("function"),
+ TOOL("tool"),
+ WORKFLOW("workFlow")
+ ;
+
+ private final String name;
+
+}
diff --git a/ruoyi-modules-api/ruoyi-workflow-api/src/main/java/org/ruoyi/workflow/enums/UserStatusEnum.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/UserStatusEnum.java
similarity index 93%
rename from ruoyi-modules-api/ruoyi-workflow-api/src/main/java/org/ruoyi/workflow/enums/UserStatusEnum.java
rename to ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/UserStatusEnum.java
index 2be9a950..2b2cca43 100644
--- a/ruoyi-modules-api/ruoyi-workflow-api/src/main/java/org/ruoyi/workflow/enums/UserStatusEnum.java
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/enums/UserStatusEnum.java
@@ -1,4 +1,4 @@
-package org.ruoyi.workflow.enums;
+package org.ruoyi.common.chat.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/factory/ImageServiceFactory.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/factory/ImageServiceFactory.java
new file mode 100644
index 00000000..52d3731b
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/factory/ImageServiceFactory.java
@@ -0,0 +1,45 @@
+package org.ruoyi.common.chat.factory;
+
+import org.ruoyi.common.chat.service.image.IImageGenerationService;
+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 zengxb
+ * @date 2026-02-14
+ */
+@Component
+public class ImageServiceFactory implements ApplicationContextAware {
+
+ private final Map imageSerivceMap = new ConcurrentHashMap<>();
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ // 初始化时收集所有IImageGenerationService的实现
+ Map serviceMap = applicationContext.getBeansOfType(IImageGenerationService.class);
+ for (IImageGenerationService service : serviceMap.values()) {
+ if (service != null ) {
+ imageSerivceMap.put(service.getProviderName(), service);
+ }
+ }
+ }
+
+
+ /**
+ * 获取原始服务(不包装代理)
+ */
+ public IImageGenerationService getOriginalService(String category) {
+ IImageGenerationService service = imageSerivceMap.get(category);
+ if (service == null) {
+ throw new IllegalArgumentException("不支持的模型类别: " + category);
+ }
+ return service;
+ }
+}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/handler/PlusWebSocketHandler.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/handler/PlusWebSocketHandler.java
deleted file mode 100644
index 90d6f11e..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/handler/PlusWebSocketHandler.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package org.ruoyi.common.chat.handler;
-
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSONUtil;
-import lombok.extern.slf4j.Slf4j;
-import org.ruoyi.common.chat.config.LocalCache;
-import org.ruoyi.common.chat.entity.chat.ChatCompletion;
-import org.ruoyi.common.chat.entity.chat.Message;
-import org.ruoyi.common.chat.holder.WebSocketSessionHolder;
-import org.ruoyi.common.chat.listener.WebSocketEventListener;
-import org.ruoyi.common.chat.openai.OpenAiStreamClient;
-import org.ruoyi.common.chat.utils.WebSocketUtils;
-import org.ruoyi.common.core.utils.SpringUtils;
-import org.springframework.web.socket.*;
-import org.springframework.web.socket.handler.AbstractWebSocketHandler;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * WebSocketHandler 实现类
- *
- * @author zendwang
- */
-@Slf4j
-public class PlusWebSocketHandler extends AbstractWebSocketHandler {
-
- /**
- * 连接成功后
- */
- @Override
- public void afterConnectionEstablished(WebSocketSession session) {
- WebSocketSessionHolder.addSession(session.getId(), session);
- }
-
- /**
- * 处理发送来的文本消息
- *
- * @param session
- * @param message
- */
- @Override
- protected void handleTextMessage(WebSocketSession session, TextMessage message) {
- WebSocketEventListener eventSourceListener = new WebSocketEventListener(session);
- String messageContext = (String) LocalCache.CACHE.get(session.getId());
- List messages = new ArrayList<>();
- if (StrUtil.isNotBlank(messageContext)) {
- messages = JSONUtil.toList(messageContext, Message.class);
- // 上下文长度
- int contextSize = 10;
- if (messages.size() >= contextSize) {
- messages = messages.subList(1, contextSize);
- }
- Message currentMessage = Message.builder().content(message.getPayload()).role(Message.Role.USER).build();
- messages.add(currentMessage);
- } else {
- Message currentMessage = Message.builder().content(message.getPayload()).role(Message.Role.USER).build();
- messages.add(currentMessage);
- }
- ChatCompletion chatCompletion = ChatCompletion
- .builder()
- .model("gpt-4o-mini")
- .messages(messages)
- .temperature(0.2)
- .stream(true)
- .build();
- OpenAiStreamClient openAiStreamClient = (OpenAiStreamClient) SpringUtils.context().getBean("openAiStreamClient");
- openAiStreamClient.streamChatCompletion(chatCompletion, eventSourceListener);
- LocalCache.CACHE.put(session.getId(), JSONUtil.toJsonStr(messages), LocalCache.TIMEOUT);
- }
-
-
- @Override
- protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) throws Exception {
- super.handleBinaryMessage(session, message);
- }
-
- /**
- * 心跳监测的回复
- *
- * @param session
- * @param message
- * @throws Exception
- */
- @Override
- protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {
- WebSocketUtils.sendPongMessage(session);
- }
-
- /**
- * 连接出错时
- *
- * @param session
- * @param exception
- * @throws Exception
- */
- @Override
- public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
- log.error("[transport error] sessionId: {} , exception:{}", session.getId(), exception.getMessage());
- }
-
- /**
- * 连接关闭后
- *
- * @param session
- * @param status
- */
- @Override
- public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
- WebSocketSessionHolder.removeSession(session.getId());
- }
-
- /**
- * 指示处理程序是否支持接收部分消息
- *
- * @return 如果支持接收部分消息,则返回true;否则返回false
- */
- @Override
- public boolean supportsPartialMessages() {
- return false;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/holder/WebSocketSessionHolder.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/holder/WebSocketSessionHolder.java
deleted file mode 100644
index 793a8d8a..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/holder/WebSocketSessionHolder.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.ruoyi.common.chat.holder;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.springframework.web.socket.WebSocketSession;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * WebSocketSession 用于保存当前所有在线的会话信息
- *
- * @author zendwang
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public class WebSocketSessionHolder {
-
- private static final Map USER_SESSION_MAP = new ConcurrentHashMap<>();
-
- public static void addSession(String sessionKey, WebSocketSession session) {
- USER_SESSION_MAP.put(sessionKey, session);
- }
-
- public static void removeSession(String sessionKey) {
- if (USER_SESSION_MAP.containsKey(sessionKey)) {
- USER_SESSION_MAP.remove(sessionKey);
- }
- }
-
- public static WebSocketSession getSessions(Long sessionKey) {
- return USER_SESSION_MAP.get(sessionKey);
- }
-
- public static Boolean existSession(Long sessionKey) {
- return USER_SESSION_MAP.containsKey(sessionKey);
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/interceptor/PlusWebSocketInterceptor.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/interceptor/PlusWebSocketInterceptor.java
deleted file mode 100644
index e5548dd3..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/interceptor/PlusWebSocketInterceptor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.ruoyi.common.chat.interceptor;
-
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.http.server.ServerHttpRequest;
-import org.springframework.http.server.ServerHttpResponse;
-import org.springframework.web.socket.WebSocketHandler;
-import org.springframework.web.socket.server.HandshakeInterceptor;
-
-import java.util.Map;
-
-/**
- * WebSocket握手请求的拦截器
- *
- * @author zendwang
- */
-@Slf4j
-public class PlusWebSocketInterceptor implements HandshakeInterceptor {
-
- /**
- * 握手前
- *
- * @param request request
- * @param response response
- * @param wsHandler wsHandler
- * @param attributes attributes
- * @return 是否握手成功
- */
- @Override
- public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map attributes) {
- return true;
- }
-
-
- /**
- * 握手后
- *
- * @param request request
- * @param response response
- * @param wsHandler wsHandler
- * @param exception 异常
- */
- @Override
- public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
-
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/listener/WebSocketEventListener.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/listener/WebSocketEventListener.java
deleted file mode 100644
index 7421e0d5..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/listener/WebSocketEventListener.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package org.ruoyi.common.chat.listener;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-import okhttp3.Response;
-import okhttp3.ResponseBody;
-import okhttp3.sse.EventSource;
-import okhttp3.sse.EventSourceListener;
-import org.ruoyi.common.chat.entity.chat.ChatCompletionResponse;
-import org.springframework.web.socket.TextMessage;
-import org.springframework.web.socket.WebSocketSession;
-
-import java.util.Objects;
-
-/**
- * OpenAI流式输出Socket接收
- *
- * @author https:www.unfbx.com
- * @date 2023-03-23
- */
-@Slf4j
-public class WebSocketEventListener extends EventSourceListener {
-
- /**
- * 消息结束标识
- */
- private final String msgEnd = "[DONE]";
- private WebSocketSession session;
-
- public WebSocketEventListener(WebSocketSession session) {
- this.session = session;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void onOpen(EventSource eventSource, Response response) {
- log.info("OpenAI建立Socket连接...");
- }
-
- /**
- * {@inheritDoc}
- */
- @SneakyThrows
- @Override
- public void onEvent(EventSource eventSource, String id, String type, String data) {
- log.info("OpenAI返回数据:{}", data);
- if (data.equals(msgEnd)) {
- log.info("OpenAI返回数据结束了");
- session.sendMessage(new TextMessage(msgEnd));
- return;
- }
- ObjectMapper mapper = new ObjectMapper();
- // 读取Json
- ChatCompletionResponse completionResponse = mapper.readValue(data, ChatCompletionResponse.class);
- String delta = "";
- try {
- delta = mapper.writeValueAsString(completionResponse.getChoices().get(0).getDelta());
- } catch (Exception e) {
- log.error("转换失败{}", e.getMessage());
- }
- session.sendMessage(new TextMessage(delta));
- }
-
-
- @Override
- public void onClosed(EventSource eventSource) {
- log.info("OpenAI关闭Socket连接...");
- }
-
-
- @SneakyThrows
- @Override
- public void onFailure(EventSource eventSource, Throwable t, Response response) {
- if (Objects.isNull(response)) {
- return;
- }
- ResponseBody body = response.body();
- if (Objects.nonNull(body)) {
- // 返回非流式回复内容
- log.error("Socket连接异常data:{},异常:{}", body.string(), t);
- } else {
- log.error("Socket连接异常data:{},异常:{}", response, t);
- }
- eventSource.cancel();
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiApi.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiApi.java
deleted file mode 100644
index 1d494b09..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiApi.java
+++ /dev/null
@@ -1,355 +0,0 @@
-package org.ruoyi.common.chat.openai;
-
-import io.reactivex.Single;
-import okhttp3.MultipartBody;
-import okhttp3.RequestBody;
-import okhttp3.ResponseBody;
-import org.ruoyi.common.chat.entity.Tts.TextToSpeech;
-import org.ruoyi.common.chat.entity.billing.BillingUsage;
-import org.ruoyi.common.chat.entity.billing.CreditGrantsResponse;
-import org.ruoyi.common.chat.entity.billing.Subscription;
-import org.ruoyi.common.chat.entity.chat.ChatCompletion;
-import org.ruoyi.common.chat.entity.chat.ChatCompletionResponse;
-import org.ruoyi.common.chat.entity.chat.ChatCompletionWithPicture;
-import org.ruoyi.common.chat.entity.common.DeleteResponse;
-import org.ruoyi.common.chat.entity.common.OpenAiResponse;
-import org.ruoyi.common.chat.entity.completions.Completion;
-import org.ruoyi.common.chat.entity.completions.CompletionResponse;
-import org.ruoyi.common.chat.entity.edits.Edit;
-import org.ruoyi.common.chat.entity.edits.EditResponse;
-import org.ruoyi.common.chat.entity.embeddings.Embedding;
-import org.ruoyi.common.chat.entity.embeddings.EmbeddingResponse;
-import org.ruoyi.common.chat.entity.engines.Engine;
-import org.ruoyi.common.chat.entity.files.File;
-import org.ruoyi.common.chat.entity.files.UploadFileResponse;
-import org.ruoyi.common.chat.entity.fineTune.Event;
-import org.ruoyi.common.chat.entity.fineTune.FineTune;
-import org.ruoyi.common.chat.entity.fineTune.FineTuneDeleteResponse;
-import org.ruoyi.common.chat.entity.fineTune.FineTuneResponse;
-import org.ruoyi.common.chat.entity.images.Image;
-import org.ruoyi.common.chat.entity.images.ImageResponse;
-import org.ruoyi.common.chat.entity.models.Model;
-import org.ruoyi.common.chat.entity.models.ModelResponse;
-import org.ruoyi.common.chat.entity.moderations.Moderation;
-import org.ruoyi.common.chat.entity.moderations.ModerationResponse;
-import org.ruoyi.common.chat.entity.whisper.WhisperResponse;
-import retrofit2.Call;
-import retrofit2.http.*;
-
-import java.time.LocalDate;
-import java.util.Map;
-
-/**
- * open ai官方api接口
- *
- * @author https:www.unfbx.com
- * 2023-02-15
- */
-public interface OpenAiApi {
-
- /**
- * 模型列表
- *
- * @return Single ModelResponse
- */
- @GET("v1/models")
- Single models();
-
- /**
- * models 返回的数据id
- *
- * @param id 模型主键
- * @return Single Model
- */
- @GET("v1/models/{id}")
- Single model(@Path("id") String id);
-
- /**
- * 文本问答
- * Given a prompt, the model will return one or more predicted completions, and can also return the probabilities of alternative tokens at each position.
- *
- * @param completion 问答参数
- * @return Single CompletionResponse
- */
- @POST("v1/completions")
- Single completions(@Body Completion completion);
-
- /**
- * Creates a new edit for the provided input, instruction, and parameters.
- * 文本修复
- *
- * @param edit 编辑参数
- * @return Single EditResponse
- */
- @POST("v1/edits")
- Single edits(@Body Edit edit);
-
- /**
- * Creates an image given a prompt.
- * 根据描述生成图片
- *
- * @param image 图片对象
- * @return Single ImageResponse
- */
- @POST("v1/images/generations")
- Single genImages(@Body Image image);
-
- /**
- * Creates an edited or extended image given an original image and a prompt.
- * 根据描述修改图片
- *
- * @param image 图片对象
- * @param mask 图片对象
- * @param requestBodyMap 请求参数
- * @return Single ImageResponse
- */
- @Multipart
- @POST("v1/images/edits")
- Single editImages(@Part() MultipartBody.Part image,
- @Part() MultipartBody.Part mask,
- @PartMap() Map requestBodyMap
- );
-
- /**
- * Creates a variation of a given image.
- *
- * @param image 图片对象
- * @param requestBodyMap 请求参数
- * @return Single ImageResponse
- */
- @Multipart
- @POST("v1/images/variations")
- Single variationsImages(@Part() MultipartBody.Part image,
- @PartMap() Map requestBodyMap
- );
-
- /**
- * 文本向量计算
- *
- * @param embedding 向量参数
- * @return Single EmbeddingResponse
- */
- @POST("v1/embeddings")
- Single embeddings(@Body Embedding embedding);
-
-
- /**
- * Returns a list of files that belong to the user's organization.
- *
- * @return Single OpenAiResponse File
- */
- @GET("/v1/files")
- Single> files();
-
- /**
- * 删除文件
- *
- * @param fileId 文件id
- * @return Single DeleteResponse
- */
- @DELETE("v1/files/{file_id}")
- Single deleteFile(@Path("file_id") String fileId);
-
- /**
- * 上传文件
- *
- * @param purpose purpose
- * @param file 文件对象
- * @return Single UploadFileResponse
- */
- @Multipart
- @POST("v1/files")
- Single uploadFile(@Part MultipartBody.Part file,
- @Part("purpose") RequestBody purpose);
-
-
- /**
- * 检索文件
- *
- * @param fileId 文件id
- * @return Single File
- */
- @GET("v1/files/{file_id}")
- Single retrieveFile(@Path("file_id") String fileId);
-
- /**
- * 检索文件内容
- * ###不对免费用户开放###
- * ###不对免费用户开放###
- * ###不对免费用户开放###
- *
- * @param fileId 文件id
- * @return Single ResponseBody
- */
- @Streaming
- @GET("v1/files/{file_id}/content")
- Single retrieveFileContent(@Path("file_id") String fileId);
-
-
- /**
- * 文本审核
- *
- * @param moderation 文本审核参数
- * @return Single ModerationResponse
- */
- @POST("v1/moderations")
- Single moderations(@Body Moderation moderation);
-
-
- /**
- * 创建微调作业
- *
- * @param fineTune 微调
- * @return Single FineTuneResponse
- */
- @POST("v1/fine-tunes")
- Single fineTune(@Body FineTune fineTune);
-
- /**
- * 微调作业集合
- *
- * @return Single OpenAiResponse FineTuneResponse
- */
- @GET("v1/fine-tunes")
- Single> fineTunes();
-
-
- /**
- * 检索微调作业
- *
- * @return Single FineTuneResponse
- */
- @GET("v1/fine-tunes/{fine_tune_id}")
- Single retrieveFineTune(@Path("fine_tune_id") String fineTuneId);
-
- /**
- * 取消微调作业
- *
- * @return Single FineTuneResponse
- */
- @POST("v1/fine-tunes/{fine_tune_id}/cancel")
- Single cancelFineTune(@Path("fine_tune_id") String fineTuneId);
-
- /**
- * 微调作业事件列表
- *
- * @return Single OpenAiResponse Event
- */
- @GET("v1/fine-tunes/{fine_tune_id}/events")
- Single> fineTuneEvents(@Path("fine_tune_id") String fineTuneId);
-
- /**
- * 删除微调作业模型
- * Delete a fine-tuned model. You must have the Owner role in your organization.
- *
- * @return Single DeleteResponse
- */
- @DELETE("v1/models/{model}")
- Single deleteFineTuneModel(@Path("model") String model);
-
-
- /**
- * 引擎列表
- * 官方已废弃此接口
- *
- * @return Single OpenAiResponse Engine
- */
- @Deprecated
- @GET("v1/engines")
- Single> engines();
-
- /**
- * 检索引擎
- * 官方已废弃此接口
- *
- * @param engineId 引擎id
- * @return Engine
- */
- @Deprecated
- @GET("v1/engines/{engine_id}")
- Single engine(@Path("engine_id") String engineId);
-
-
- /**
- * 最新版的GPT-3.5 chat completion 更加贴近官方网站的问答模型
- *
- * @param chatCompletion chat completion
- * @return 返回答案
- */
- @POST("v1/chat/completions")
- Single chatCompletion(@Body ChatCompletion chatCompletion);
-
-
- /**
- * 语音转文字
- *
- * @param file 语音文件
- * @param requestBodyMap 参数
- * @return 文本
- */
- @Multipart
- @POST("v1/audio/transcriptions")
- Single speechToTextTranscriptions(@Part MultipartBody.Part file,
- @PartMap() Map requestBodyMap);
-
- /**
- * 语音翻译:目前仅支持翻译为英文
- *
- * @param file 语音文件
- * @param requestBodyMap 参数
- * @return 文本
- */
- @Multipart
- @POST("v1/audio/translations")
- Single speechToTextTranslations(@Part MultipartBody.Part file,
- @PartMap() Map requestBodyMap);
-
- /**
- * 余额查询
- * 官方禁止访问此接口
- *
- * @return 余额结果
- */
- @GET("dashboard/billing/credit_grants")
- @Deprecated
- Single creditGrants();
-
- /**
- * 账户信息查询:里面包含总金额(美元)等信息
- *
- * @return 账户信息
- */
- @GET("v1/dashboard/billing/subscription")
- Single subscription();
-
- /**
- * 账户调用接口消耗金额信息查询
- * totalUsage = 账户总使用金额(美分)
- *
- * @param starDate 开始时间
- * @param endDate 结束时间
- * @return 消耗金额信息
- */
- @GET("v1/dashboard/billing/usage")
- Single billingUsage(@Query("start_date") LocalDate starDate, @Query("end_date") LocalDate endDate);
-
- /**
- * 最新版的GPT-4 chat completion 支持图片输入
- *
- * @param chatCompletion chat completion
- * @return 返回答案
- */
- @POST("v1/chat/completions")
- Single chatCompletionWithPicture(@Body ChatCompletionWithPicture chatCompletion);
-
- /**
- * 文本转语音
- *
- * @param textToSpeech 参数
- * @return ResponseBody body
- * @since 1.1.2
- */
- @POST("v1/audio/speech")
- @Streaming
- Call textToSpeech(@Body TextToSpeech textToSpeech);
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiClient.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiClient.java
deleted file mode 100644
index 21b1061c..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiClient.java
+++ /dev/null
@@ -1,889 +0,0 @@
-package org.ruoyi.common.chat.openai;
-
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSONUtil;
-import io.reactivex.Single;
-import lombok.Getter;
-import lombok.extern.slf4j.Slf4j;
-import okhttp3.MediaType;
-import okhttp3.MultipartBody;
-import okhttp3.OkHttpClient;
-import okhttp3.RequestBody;
-import org.jetbrains.annotations.NotNull;
-import org.ruoyi.common.chat.constant.OpenAIConst;
-import org.ruoyi.common.chat.entity.billing.BillingUsage;
-import org.ruoyi.common.chat.entity.billing.Subscription;
-import org.ruoyi.common.chat.entity.chat.*;
-import org.ruoyi.common.chat.entity.common.DeleteResponse;
-import org.ruoyi.common.chat.entity.common.OpenAiResponse;
-import org.ruoyi.common.chat.entity.completions.Completion;
-import org.ruoyi.common.chat.entity.completions.CompletionResponse;
-import org.ruoyi.common.chat.entity.edits.Edit;
-import org.ruoyi.common.chat.entity.edits.EditResponse;
-import org.ruoyi.common.chat.entity.embeddings.Embedding;
-import org.ruoyi.common.chat.entity.embeddings.EmbeddingResponse;
-import org.ruoyi.common.chat.entity.engines.Engine;
-import org.ruoyi.common.chat.entity.files.File;
-import org.ruoyi.common.chat.entity.files.UploadFileResponse;
-import org.ruoyi.common.chat.entity.fineTune.Event;
-import org.ruoyi.common.chat.entity.fineTune.FineTune;
-import org.ruoyi.common.chat.entity.fineTune.FineTuneDeleteResponse;
-import org.ruoyi.common.chat.entity.fineTune.FineTuneResponse;
-import org.ruoyi.common.chat.entity.images.*;
-import org.ruoyi.common.chat.entity.models.Model;
-import org.ruoyi.common.chat.entity.models.ModelResponse;
-import org.ruoyi.common.chat.entity.moderations.Moderation;
-import org.ruoyi.common.chat.entity.moderations.ModerationResponse;
-import org.ruoyi.common.chat.entity.whisper.Translations;
-import org.ruoyi.common.chat.entity.whisper.WhisperResponse;
-import org.ruoyi.common.chat.openai.exception.CommonError;
-import org.ruoyi.common.chat.openai.function.KeyRandomStrategy;
-import org.ruoyi.common.chat.openai.function.KeyStrategyFunction;
-import org.ruoyi.common.chat.openai.interceptor.DefaultOpenAiAuthInterceptor;
-import org.ruoyi.common.chat.openai.interceptor.DynamicKeyOpenAiAuthInterceptor;
-import org.ruoyi.common.chat.openai.interceptor.OpenAiAuthInterceptor;
-import org.ruoyi.common.chat.openai.plugin.PluginAbstract;
-import org.ruoyi.common.chat.openai.plugin.PluginParam;
-import org.ruoyi.common.core.exception.base.BaseException;
-import retrofit2.Retrofit;
-import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
-import retrofit2.converter.jackson.JacksonConverterFactory;
-
-import java.time.LocalDate;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-
-
-/**
- * open ai 客户端
- *
- * @author https:www.unfbx.com
- * @since 2023-02-11
- */
-
-@Slf4j
-public class OpenAiClient {
- /**
- * keys
- */
- @Getter
- @NotNull
- private List apiKey;
- /**
- * 自定义api host使用builder的方式构造client
- */
- @Getter
- private String apiHost;
- @Getter
- private OpenAiApi openAiApi;
- /**
- * 自定义的okHttpClient
- * 如果不自定义 ,就是用sdk默认的OkHttpClient实例
- */
- @Getter
- private OkHttpClient okHttpClient;
- /**
- * api key的获取策略
- */
- @Getter
- private KeyStrategyFunction, String> keyStrategy;
-
- /**
- * 自定义鉴权处理拦截器
- * 可以不设置,默认实现:DefaultOpenAiAuthInterceptor
- * 如需自定义实现参考:DealKeyWithOpenAiAuthInterceptor
- *
- * @see DynamicKeyOpenAiAuthInterceptor
- * @see DefaultOpenAiAuthInterceptor
- */
- @Getter
- private OpenAiAuthInterceptor authInterceptor;
-
- /**
- * 构造
- *
- * @param builder
- */
- private OpenAiClient(Builder builder) {
- if (CollectionUtil.isEmpty(builder.apiKey)) {
- throw new BaseException(CommonError.API_KEYS_NOT_NUL.msg()
- );
- }
- apiKey = builder.apiKey;
-
- if (StrUtil.isBlank(builder.apiHost)) {
- builder.apiHost = OpenAIConst.OPENAI_HOST;
- }
- apiHost = builder.apiHost;
-
- if (Objects.isNull(builder.keyStrategy)) {
- builder.keyStrategy = new KeyRandomStrategy();
- }
- keyStrategy = builder.keyStrategy;
-
- if (Objects.isNull(builder.authInterceptor)) {
- builder.authInterceptor = new DefaultOpenAiAuthInterceptor();
- }
- authInterceptor = builder.authInterceptor;
- authInterceptor.setApiKey(this.apiKey);
- authInterceptor.setKeyStrategy(this.keyStrategy);
-
- if (Objects.isNull(builder.okHttpClient)) {
- builder.okHttpClient = this.okHttpClient();
- } else {
- //自定义的okhttpClient 需要增加api keys
- builder.okHttpClient = builder.okHttpClient
- .newBuilder()
- .addInterceptor(authInterceptor)
- .build();
- }
- okHttpClient = builder.okHttpClient;
- this.openAiApi = new Retrofit.Builder()
- .baseUrl(apiHost)
- .client(okHttpClient)
- .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
- .addConverterFactory(JacksonConverterFactory.create())
- .build().create(OpenAiApi.class);
- }
-
- /**
- * 构造器
- *
- * @return OpenAiClient.Builder
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * 创建默认OkHttpClient
- *
- * @return
- */
- private OkHttpClient okHttpClient() {
- if (Objects.isNull(this.authInterceptor)) {
- this.authInterceptor = new DefaultOpenAiAuthInterceptor();
- }
- this.authInterceptor.setApiKey(this.apiKey);
- this.authInterceptor.setKeyStrategy(this.keyStrategy);
- return new OkHttpClient
- .Builder()
- .addInterceptor(this.authInterceptor)
- .connectTimeout(30, TimeUnit.SECONDS)
- .writeTimeout(30, TimeUnit.SECONDS)
- .readTimeout(30, TimeUnit.SECONDS).build();
- }
-
- /**
- * openAi模型列表
- *
- * @return Model list
- */
- public List models() {
- Single models = this.openAiApi.models();
- return models.blockingGet().getData();
- }
-
- /**
- * openAi模型详细信息
- *
- * @param id 模型主键
- * @return Model 模型类
- */
- public Model model(String id) {
- if (Objects.isNull(id) || "".equals(id)) {
- throw new BaseException(CommonError.PARAM_ERROR.msg());
- }
- Single model = this.openAiApi.model(id);
- return model.blockingGet();
- }
-
-
- /**
- * 问答接口
- *
- * @param completion 问答参数
- * @return CompletionResponse
- */
- public CompletionResponse completions(Completion completion) {
- Single completions = this.openAiApi.completions(completion);
- return completions.blockingGet();
- }
-
- /**
- * 问答接口-简易版
- *
- * @param question 问题描述
- * @return CompletionResponse
- */
- public CompletionResponse completions(String question) {
- Completion q = Completion.builder()
- .prompt(question)
- .build();
- Single completions = this.openAiApi.completions(q);
- return completions.blockingGet();
- }
-
- /**
- * 文本修改
- *
- * @param edit 图片对象
- * @return EditResponse
- */
- public EditResponse edit(Edit edit) {
- Single edits = this.openAiApi.edits(edit);
- return edits.blockingGet();
- }
-
- /**
- * 根据描述生成图片
- *
- * @param prompt 描述信息
- * @return ImageResponse
- */
- public ImageResponse genImages(String prompt) {
- Image image = Image.builder().prompt(prompt).build();
- return this.genImages(image);
- }
-
- /**
- * 根据描述生成图片
- *
- * @param image 图片参数
- * @return ImageResponse
- */
- public ImageResponse genImages(Image image) {
- Single edits = this.openAiApi.genImages(image);
- return edits.blockingGet();
- }
-
- /**
- * Creates an edited or extended image given an original image and a prompt.
- * 根据描述修改图片
- *
- * @param image 图片对象
- * @param prompt 描述信息
- * @return Item list
- */
- public List- editImages(java.io.File image, String prompt) {
- ImageEdit imageEdit = ImageEdit.builder().prompt(prompt).build();
- return this.editImages(image, null, imageEdit);
- }
-
- /**
- * Creates an edited or extended image given an original image and a prompt.
- * 根据描述修改图片
- *
- * @param image 图片对象
- * @param imageEdit 图片参数
- * @return Item list
- */
- public List
- editImages(java.io.File image, ImageEdit imageEdit) {
- return this.editImages(image, null, imageEdit);
- }
-
- /**
- * Creates an edited or extended image given an original image and a prompt.
- * 根据描述修改图片
- *
- * @param image png格式的图片,最大4MB
- * @param mask png格式的图片,最大4MB
- * @param imageEdit 图片参数
- * @return Item list
- */
- public List
- editImages(java.io.File image, java.io.File mask, ImageEdit imageEdit) {
- checkImage(image);
- checkImageFormat(image);
- checkImageSize(image);
- if (Objects.nonNull(mask)) {
- checkImageFormat(image);
- checkImageSize(image);
- }
- // 创建 RequestBody,用于封装构建RequestBody
- RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), image);
- MultipartBody.Part imageMultipartBody = MultipartBody.Part.createFormData("image", image.getName(), imageBody);
- MultipartBody.Part maskMultipartBody = null;
- if (Objects.nonNull(mask)) {
- RequestBody maskBody = RequestBody.create(MediaType.parse("multipart/form-data"), mask);
- maskMultipartBody = MultipartBody.Part.createFormData("mask", image.getName(), maskBody);
- }
- Map requestBodyMap = new HashMap<>();
- requestBodyMap.put("prompt", RequestBody.create(MediaType.parse("multipart/form-data"), imageEdit.getPrompt()));
- requestBodyMap.put("n", RequestBody.create(MediaType.parse("multipart/form-data"), imageEdit.getN().toString()));
- requestBodyMap.put("size", RequestBody.create(MediaType.parse("multipart/form-data"), imageEdit.getSize()));
- requestBodyMap.put("response_format", RequestBody.create(MediaType.parse("multipart/form-data"), imageEdit.getResponseFormat()));
- if (!(Objects.isNull(imageEdit.getUser()) || "".equals(imageEdit.getUser()))) {
- requestBodyMap.put("user", RequestBody.create(MediaType.parse("multipart/form-data"), imageEdit.getUser()));
- }
- Single imageResponse = this.openAiApi.editImages(
- imageMultipartBody,
- maskMultipartBody,
- requestBodyMap
- );
- return imageResponse.blockingGet().getData();
- }
-
- /**
- * Creates a variation of a given image.
- *
- * 变化图片,类似ai重做图片
- *
- * @param image 图片对象
- * @param imageVariations 图片参数
- * @return ImageResponse
- */
- public ImageResponse variationsImages(java.io.File image, ImageVariations imageVariations) {
- checkImage(image);
- checkImageFormat(image);
- checkImageSize(image);
- RequestBody imageBody = RequestBody.create(MediaType.parse("multipart/form-data"), image);
- MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("image", image.getName(), imageBody);
- Map requestBodyMap = new HashMap<>();
- requestBodyMap.put("n", RequestBody.create(MediaType.parse("multipart/form-data"), imageVariations.getN().toString()));
- requestBodyMap.put("size", RequestBody.create(MediaType.parse("multipart/form-data"), imageVariations.getSize()));
- requestBodyMap.put("response_format", RequestBody.create(MediaType.parse("multipart/form-data"), imageVariations.getResponseFormat()));
- if (!(Objects.isNull(imageVariations.getUser()) || "".equals(imageVariations.getUser()))) {
- requestBodyMap.put("user", RequestBody.create(MediaType.parse("multipart/form-data"), imageVariations.getUser()));
- }
- Single variationsImages = this.openAiApi.variationsImages(
- multipartBody,
- requestBodyMap
- );
- return variationsImages.blockingGet();
- }
-
- /**
- * Creates a variation of a given image.
- *
- * @param image 图片对象
- * @return ImageResponse
- */
- public ImageResponse variationsImages(java.io.File image) {
- checkImage(image);
- checkImageFormat(image);
- checkImageSize(image);
- ImageVariations imageVariations = ImageVariations.builder().build();
- return this.variationsImages(image, imageVariations);
- }
-
- /**
- * 校验图片不能为空
- *
- * @param image
- */
- private void checkImage(java.io.File image) {
- if (Objects.isNull(image)) {
- log.error("image不能为空");
- throw new BaseException(CommonError.PARAM_ERROR.msg());
- }
- }
-
- /**
- * 校验图片格式
- *
- * @param image
- */
- private void checkImageFormat(java.io.File image) {
- if (!(image.getName().endsWith("png") || image.getName().endsWith("PNG"))) {
- log.error("image格式错误");
- throw new BaseException(CommonError.PARAM_ERROR.msg());
- }
- }
-
- /**
- * 校验图片大小
- *
- * @param image
- */
- private void checkImageSize(java.io.File image) {
- if (image.length() > 4 * 1024 * 1024) {
- log.error("image最大支持4MB");
- throw new BaseException(CommonError.PARAM_ERROR.msg());
- }
- }
-
- /**
- * 向量计算:单文本
- *
- * @param input 单文本
- * @return EmbeddingResponse
- */
- public EmbeddingResponse embeddings(String input) {
- List inputs = new ArrayList<>(1);
- inputs.add(input);
- Embedding embedding = Embedding.builder().input(inputs).build();
- return this.embeddings(embedding);
- }
-
- /**
- * 向量计算:集合文本
- *
- * @param input 文本集合
- * @return EmbeddingResponse
- */
- public EmbeddingResponse embeddings(List input) {
- Embedding embedding = Embedding.builder().input(input).build();
- return this.embeddings(embedding);
- }
-
- /**
- * 文本转换向量
- *
- * @param embedding 入参
- * @return EmbeddingResponse
- */
- public EmbeddingResponse embeddings(Embedding embedding) {
- Single embeddings = this.openAiApi.embeddings(embedding);
- return embeddings.blockingGet();
- }
-
- /**
- * 获取文件列表
- *
- * @return File list
- */
- public List files() {
- Single> files = this.openAiApi.files();
- return files.blockingGet().getData();
- }
-
- /**
- * 删除文件
- *
- * @param fileId 文件id
- * @return DeleteResponse
- */
- public DeleteResponse deleteFile(String fileId) {
- Single deleteFile = this.openAiApi.deleteFile(fileId);
- return deleteFile.blockingGet();
- }
-
- /**
- * 上传文件
- *
- * @param purpose purpose
- * @param file 文件对象
- * @return UploadFileResponse
- */
- public UploadFileResponse uploadFile(String purpose, java.io.File file) {
- // 创建 RequestBody,用于封装构建RequestBody
- RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
- MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", file.getName(), fileBody);
-
- RequestBody purposeBody = RequestBody.create(MediaType.parse("multipart/form-data"), purpose);
- Single uploadFileResponse = this.openAiApi.uploadFile(multipartBody, purposeBody);
- return uploadFileResponse.blockingGet();
- }
-
- /**
- * 上传文件
- *
- * @param file 文件
- * @return UploadFileResponse
- */
- public UploadFileResponse uploadFile(java.io.File file) {
- //purpose 官网示例默认是:fine-tune
- return this.uploadFile("fine-tune", file);
- }
-
- /**
- * 检索文件
- *
- * @param fileId 文件id
- * @return File
- */
- public File retrieveFile(String fileId) {
- Single fileContent = this.openAiApi.retrieveFile(fileId);
- return fileContent.blockingGet();
- }
-
- /**
- * 检索文件内容
- * 免费用户无法使用此接口 #未经过测试
- *
- * @param fileId
- * @return ResponseBody
- */
-// public ResponseBody retrieveFileContent(String fileId) {
-// Single fileContent = this.openAiApi.retrieveFileContent(fileId);
-// return fileContent.blockingGet();
-// }
-
- /**
- * 文本审核
- *
- * @param input 待检测数据
- * @return ModerationResponse
- */
- public ModerationResponse moderations(String input) {
- List content = new ArrayList<>(1);
- content.add(input);
- Moderation moderation = Moderation.builder().input(content).build();
- return this.moderations(moderation);
- }
-
- /**
- * 文本审核
- *
- * @param input 待检测数据集合
- * @return ModerationResponse
- */
- public ModerationResponse moderations(List input) {
- Moderation moderation = Moderation.builder().input(input).build();
- return this.moderations(moderation);
- }
-
- /**
- * 文本审核
- *
- * @param moderation 审核参数
- * @return ModerationResponse
- */
- public ModerationResponse moderations(Moderation moderation) {
- Single moderations = this.openAiApi.moderations(moderation);
- return moderations.blockingGet();
- }
-
- /**
- * 创建微调模型
- *
- * @param fineTune 微调作业id
- * @return FineTuneResponse
- */
- public FineTuneResponse fineTune(FineTune fineTune) {
- Single fineTuneResponse = this.openAiApi.fineTune(fineTune);
- return fineTuneResponse.blockingGet();
- }
-
- /**
- * 创建微调模型
- *
- * @param trainingFileId 文件id,文件上传返回的id
- * @return FineTuneResponse
- */
- public FineTuneResponse fineTune(String trainingFileId) {
- FineTune fineTune = FineTune.builder().trainingFile(trainingFileId).build();
- return this.fineTune(fineTune);
- }
-
- /**
- * 微调模型列表
- *
- * @return FineTuneResponse list
- */
- public List fineTunes() {
- Single> fineTunes = this.openAiApi.fineTunes();
- return fineTunes.blockingGet().getData();
- }
-
- /**
- * 检索微调作业
- *
- * @param fineTuneId 微调作业id
- * @return FineTuneResponse
- */
- public FineTuneResponse retrieveFineTune(String fineTuneId) {
- Single fineTune = this.openAiApi.retrieveFineTune(fineTuneId);
- return fineTune.blockingGet();
- }
-
- /**
- * 取消微调作业
- *
- * @param fineTuneId 主键
- * @return FineTuneResponse
- */
- public FineTuneResponse cancelFineTune(String fineTuneId) {
- Single fineTune = this.openAiApi.cancelFineTune(fineTuneId);
- return fineTune.blockingGet();
- }
-
- /**
- * 微调作业事件列表
- *
- * @param fineTuneId 微调作业id
- * @return Event List
- */
- public List fineTuneEvents(String fineTuneId) {
- Single> events = this.openAiApi.fineTuneEvents(fineTuneId);
- return events.blockingGet().getData();
- }
-
- /**
- * 删除微调作业模型
- * Delete a fine-tuned model. You must have the Owner role in your organization.
- *
- * @param model 模型名称
- * @return FineTuneDeleteResponse
- */
- public FineTuneDeleteResponse deleteFineTuneModel(String model) {
- Single delete = this.openAiApi.deleteFineTuneModel(model);
- return delete.blockingGet();
- }
-
-
- /**
- * 引擎列表
- *
- * @return Engine List
- */
- @Deprecated
- public List engines() {
- Single> engines = this.openAiApi.engines();
- return engines.blockingGet().getData();
- }
-
- /**
- * 引擎详细信息
- *
- * @param engineId 引擎id
- * @return Engine
- */
- @Deprecated
- public Engine engine(String engineId) {
- Single engine = this.openAiApi.engine(engineId);
- return engine.blockingGet();
- }
-
- /**
- * 最新版的GPT-3.5 chat completion 更加贴近官方网站的问答模型
- *
- * @param chatCompletion 问答参数
- * @return 答案
- */
- public ChatCompletionResponse chatCompletion(ChatCompletion chatCompletion) {
- Single chatCompletionResponse = this.openAiApi.chatCompletion(chatCompletion);
- return chatCompletionResponse.blockingGet();
- }
-
- /**
- * 简易版
- *
- * @param messages 问答参数
- * @return 答案
- */
- public ChatCompletionResponse chatCompletion(List messages) {
- ChatCompletion chatCompletion = ChatCompletion.builder().messages(messages).build();
- return this.chatCompletion(chatCompletion);
- }
-
- /**
- * 语音翻译:目前仅支持翻译为英文
- *
- * @param translations 参数
- * @param file 语音文件 最大支持25MB mp3, mp4, mpeg, mpga, m4a, wav, webm
- * @return 翻译后文本
- */
- public WhisperResponse speechToTextTranslations(java.io.File file, Translations translations) {
- //文件
- RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
- MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", file.getName(), fileBody);
- //自定义参数
- Map requestBodyMap = new HashMap<>(5, 1L);
-
- if (StrUtil.isNotBlank(translations.getModel())) {
- requestBodyMap.put(Translations.Fields.model, RequestBody.create(MediaType.parse("multipart/form-data"), translations.getModel()));
- }
- if (StrUtil.isNotBlank(translations.getPrompt())) {
- requestBodyMap.put(Translations.Fields.prompt, RequestBody.create(MediaType.parse("multipart/form-data"), translations.getPrompt()));
- }
- if (StrUtil.isNotBlank(translations.getResponseFormat())) {
- requestBodyMap.put(Translations.Fields.responseFormat, RequestBody.create(MediaType.parse("multipart/form-data"), translations.getResponseFormat()));
- }
- requestBodyMap.put(Translations.Fields.temperature, RequestBody.create(MediaType.parse("multipart/form-data"), String.valueOf(translations.getTemperature())));
- Single whisperResponse = this.openAiApi.speechToTextTranslations(multipartBody, requestBodyMap);
- return whisperResponse.blockingGet();
- }
-
- /**
- * 插件问答简易版
- * 默认取messages最后一个元素构建插件对话
- * 默认模型:ChatCompletion.Model.GPT_3_5_TURBO_16K_0613
- *
- * @param chatCompletion 参数
- * @param plugin 插件
- * @param 插件自定义函数的请求值
- * @param 插件自定义函数的返回值
- * @return ChatCompletionResponse
- */
- public ChatCompletionResponse chatCompletionWithPlugin(ChatCompletion chatCompletion, PluginAbstract plugin) {
- if (Objects.isNull(plugin)) {
- return this.chatCompletion(chatCompletion);
- }
- if (CollectionUtil.isEmpty(chatCompletion.getMessages())) {
- throw new BaseException(CommonError.MESSAGE_NOT_NUL.msg());
- }
- List messages = chatCompletion.getMessages();
- Functions functions = Functions.builder()
- .name(plugin.getFunction())
- .description(plugin.getDescription())
- .parameters(plugin.getParameters())
- .build();
- //没有值,设置默认值
- if (Objects.isNull(chatCompletion.getFunctionCall())) {
- chatCompletion.setFunctionCall("auto");
- }
- //tip: 覆盖自己设置的functions参数,使用plugin构造的functions
- chatCompletion.setFunctions(Collections.singletonList(functions));
- //调用OpenAi
- ChatCompletionResponse functionCallChatCompletionResponse = this.chatCompletion(chatCompletion);
- ChatChoice chatChoice = functionCallChatCompletionResponse.getChoices().get(0);
- log.debug("构造的方法值:{}", chatChoice.getMessage().getFunctionCall());
-
- R realFunctionParam = (R) JSONUtil.toBean(chatChoice.getMessage().getFunctionCall().getArguments(), plugin.getR());
- T tq = plugin.func(realFunctionParam);
-
- FunctionCall functionCall = FunctionCall.builder()
- .arguments(chatChoice.getMessage().getFunctionCall().getArguments())
- .name(plugin.getFunction())
- .build();
- messages.add(Message.builder().role(Message.Role.ASSISTANT).content("function_call").functionCall(functionCall).build());
- messages.add(Message.builder().role(Message.Role.FUNCTION).name(plugin.getFunction()).content(plugin.content(tq)).build());
- //设置第二次,请求的参数
- chatCompletion.setFunctionCall(null);
- chatCompletion.setFunctions(null);
-
- ChatCompletionResponse chatCompletionResponse = this.chatCompletion(chatCompletion);
- log.debug("自定义的方法返回值:{}", chatCompletionResponse.getChoices());
- return chatCompletionResponse;
- }
-
- /**
- * 插件问答简易版
- * 默认取messages最后一个元素构建插件对话
- * 默认模型:ChatCompletion.Model.GPT_3_5_TURBO_16K_0613
- *
- * @param messages 问答参数
- * @param plugin 插件
- * @param 插件自定义函数的请求值
- * @param 插件自定义函数的返回值
- * @return ChatCompletionResponse
- */
- public ChatCompletionResponse chatCompletionWithPlugin(List messages, PluginAbstract plugin) {
- return chatCompletionWithPlugin(messages, ChatCompletion.Model.GPT_3_5_TURBO_16K_0613.getName(), plugin);
- }
-
- /**
- * 插件问答简易版
- * 默认取messages最后一个元素构建插件对话
- *
- * @param messages 问答参数
- * @param model 模型
- * @param plugin 插件
- * @param 插件自定义函数的请求值
- * @param 插件自定义函数的返回值
- * @return ChatCompletionResponse
- */
- public ChatCompletionResponse chatCompletionWithPlugin(List messages, String model, PluginAbstract plugin) {
- ChatCompletion chatCompletion = ChatCompletion.builder().messages(messages).model(model).build();
- return this.chatCompletionWithPlugin(chatCompletion, plugin);
- }
-
- /**
- * 简易版 语音翻译:目前仅支持翻译为英文
- *
- * @param file 语音文件 最大支持25MB mp3, mp4, mpeg, mpga, m4a, wav, webm
- * @return 翻译后文本
- */
- public WhisperResponse speechToTextTranslations(java.io.File file) {
- Translations translations = Translations.builder().build();
- return this.speechToTextTranslations(file, translations);
- }
-
- /**
- * 校验语音文件大小给出提示,目前官方限制25MB,后续可能会改动所以不报错只做提示
- *
- * @param file
- */
- private void checkSpeechFileSize(java.io.File file) {
- if (file.length() > 25 * 1204 * 1024) {
- log.warn("2023-03-02官方文档提示:文件不能超出25MB");
- }
- }
-
- /**
- * 账户信息查询:里面包含总金额等信息
- *
- * @return 账户信息
- */
- public Subscription subscription() {
- Single subscription = this.openAiApi.subscription();
- return subscription.blockingGet();
- }
-
- /**
- * 账户调用接口消耗金额信息查询
- * 最多查询100天
- *
- * @param starDate 开始时间
- * @param endDate 结束时间
- * @return 消耗金额信息
- */
- public BillingUsage billingUsage(@NotNull LocalDate starDate, @NotNull LocalDate endDate) {
- Single billingUsage = this.openAiApi.billingUsage(starDate, endDate);
- return billingUsage.blockingGet();
- }
-
-
- public static final class Builder {
- /**
- * api keys
- */
- private @NotNull List apiKey;
- /**
- * api请求地址,结尾处有斜杠
- */
- private String apiHost;
- /**
- * 自定义OkhttpClient
- */
- private OkHttpClient okHttpClient;
-
- /**
- * api key的获取策略
- */
- private KeyStrategyFunction keyStrategy;
-
- /**
- * 自定义鉴权拦截器
- */
- private OpenAiAuthInterceptor authInterceptor;
-
- public Builder() {
- }
-
- /**
- * @param val api请求地址,结尾处有斜杠
- * @return Builder对象
- */
- public Builder apiHost(String val) {
- apiHost = val;
- return this;
- }
-
- public Builder apiKey(@NotNull List val) {
- apiKey = val;
- return this;
- }
-
- public Builder keyStrategy(KeyStrategyFunction val) {
- keyStrategy = val;
- return this;
- }
-
- public Builder okHttpClient(OkHttpClient val) {
- okHttpClient = val;
- return this;
- }
-
- public Builder authInterceptor(OpenAiAuthInterceptor val) {
- authInterceptor = val;
- return this;
- }
-
- public OpenAiClient build() {
- return new OpenAiClient(this);
- }
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiStreamClient.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiStreamClient.java
deleted file mode 100644
index 04613ac8..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/OpenAiStreamClient.java
+++ /dev/null
@@ -1,679 +0,0 @@
-package org.ruoyi.common.chat.openai;
-
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.http.ContentType;
-import cn.hutool.json.JSONUtil;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import io.reactivex.Single;
-import lombok.Getter;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-import okhttp3.*;
-import okhttp3.sse.EventSource;
-import okhttp3.sse.EventSourceListener;
-import okhttp3.sse.EventSources;
-import org.jetbrains.annotations.NotNull;
-import org.ruoyi.common.chat.constant.OpenAIConst;
-import org.ruoyi.common.chat.entity.Tts.TextToSpeech;
-import org.ruoyi.common.chat.entity.billing.BillingUsage;
-import org.ruoyi.common.chat.entity.billing.KeyInfo;
-import org.ruoyi.common.chat.entity.billing.Subscription;
-import org.ruoyi.common.chat.entity.chat.*;
-import org.ruoyi.common.chat.entity.embeddings.Embedding;
-import org.ruoyi.common.chat.entity.embeddings.EmbeddingResponse;
-import org.ruoyi.common.chat.entity.files.UploadFileResponse;
-import org.ruoyi.common.chat.entity.images.Image;
-import org.ruoyi.common.chat.entity.images.ImageResponse;
-import org.ruoyi.common.chat.entity.models.Model;
-import org.ruoyi.common.chat.entity.models.ModelResponse;
-import org.ruoyi.common.chat.entity.whisper.Transcriptions;
-import org.ruoyi.common.chat.entity.whisper.WhisperResponse;
-import org.ruoyi.common.chat.openai.exception.CommonError;
-import org.ruoyi.common.chat.openai.function.KeyRandomStrategy;
-import org.ruoyi.common.chat.openai.function.KeyStrategyFunction;
-import org.ruoyi.common.chat.openai.interceptor.DefaultOpenAiAuthInterceptor;
-import org.ruoyi.common.chat.openai.interceptor.DynamicKeyOpenAiAuthInterceptor;
-import org.ruoyi.common.chat.openai.interceptor.OpenAiAuthInterceptor;
-import org.ruoyi.common.chat.openai.plugin.PluginAbstract;
-import org.ruoyi.common.chat.openai.plugin.PluginParam;
-import org.ruoyi.common.chat.sse.DefaultPluginListener;
-import org.ruoyi.common.chat.sse.PluginListener;
-import org.ruoyi.common.core.exception.base.BaseException;
-import retrofit2.Call;
-import retrofit2.Retrofit;
-import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
-import retrofit2.converter.jackson.JacksonConverterFactory;
-
-import java.io.IOException;
-import java.time.LocalDate;
-import java.time.ZoneId;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-
-/**
- * open ai 客户端
- *
- * @author https:www.unfbx.com
- * 2023-02-28
- */
-
-@Getter
-@Slf4j
-@Setter
-public class OpenAiStreamClient {
-
- private static final String DONE_SIGNAL = "[DONE]";
- @NotNull
- private List apiKey;
- /**
- * 自定义api host使用builder的方式构造client
- */
- private String apiHost;
- /**
- * 自定义url 兼容多个平台
- */
- private String apiUrl;
- /**
- * 自定义的okHttpClient
- * 如果不自定义 ,就是用sdk默认的OkHttpClient实例
- */
- private OkHttpClient okHttpClient;
- /**
- * api key的获取策略
- */
- private KeyStrategyFunction, String> keyStrategy;
- private OpenAiApi openAiApi;
- /**
- * 自定义鉴权处理拦截器
- * 可以不设置,默认实现:DefaultOpenAiAuthInterceptor
- * 如需自定义实现参考:DealKeyWithOpenAiAuthInterceptor
- *
- * @see DynamicKeyOpenAiAuthInterceptor
- * @see DefaultOpenAiAuthInterceptor
- */
- private OpenAiAuthInterceptor authInterceptor;
-
- /**
- * 构造实例对象
- *
- * @param builder
- */
- private OpenAiStreamClient(Builder builder) {
- if (CollectionUtil.isEmpty(builder.apiKey)) {
- throw new BaseException(CommonError.API_KEYS_NOT_NUL.msg());
- }
- apiKey = builder.apiKey;
-
- if (StrUtil.isBlank(builder.apiHost)) {
- builder.apiHost = OpenAIConst.OPENAI_HOST;
- }
- apiHost = builder.apiHost;
-
- if (StrUtil.isBlank(builder.apiUrl)) {
- builder.apiUrl = OpenAIConst.apiUrl;
- }
- apiUrl = builder.apiUrl;
-
- if (Objects.isNull(builder.keyStrategy)) {
- builder.keyStrategy = new KeyRandomStrategy();
- }
- keyStrategy = builder.keyStrategy;
-
- if (Objects.isNull(builder.authInterceptor)) {
- builder.authInterceptor = new DefaultOpenAiAuthInterceptor();
- }
- authInterceptor = builder.authInterceptor;
- //设置apiKeys和key的获取策略
- authInterceptor.setApiKey(this.apiKey);
- authInterceptor.setKeyStrategy(this.keyStrategy);
-
- if (Objects.isNull(builder.okHttpClient)) {
- builder.okHttpClient = this.okHttpClient();
- } else {
- //自定义的okhttpClient 需要增加api keys
- builder.okHttpClient = builder.okHttpClient
- .newBuilder()
- .addInterceptor(authInterceptor)
- .build();
- }
- okHttpClient = builder.okHttpClient;
- if (apiHost.endsWith("/")) {
- this.openAiApi = new Retrofit.Builder()
- .baseUrl(apiHost)
- .client(okHttpClient)
- .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
- .addConverterFactory(JacksonConverterFactory.create())
- .build().create(OpenAiApi.class);
- }
-
- }
-
- /**
- * 构造
- *
- * @return Builder
- */
- public static Builder builder() {
- return new Builder();
- }
-
- /**
- * 创建默认的OkHttpClient
- */
- private OkHttpClient okHttpClient() {
- if (Objects.isNull(this.authInterceptor)) {
- this.authInterceptor = new DefaultOpenAiAuthInterceptor();
- }
- this.authInterceptor.setApiKey(this.apiKey);
- this.authInterceptor.setKeyStrategy(this.keyStrategy);
- OkHttpClient okHttpClient = new OkHttpClient
- .Builder()
- .addInterceptor(this.authInterceptor)
- .connectTimeout(10, TimeUnit.SECONDS)
- .writeTimeout(50, TimeUnit.SECONDS)
- .readTimeout(50, TimeUnit.SECONDS)
- .build();
- return okHttpClient;
- }
-
- /**
- * 流式输出,最新版的GPT-3.5 chat completion 更加贴近官方网站的问答模型
- *
- * @param chatCompletion 问答参数
- * @param eventSourceListener 监听器
- */
- public void streamChatCompletion(T chatCompletion, EventSourceListener eventSourceListener) {
- if (Objects.isNull(eventSourceListener)) {
- log.error("参数异常:EventSourceListener不能为空!");
- throw new BaseException(CommonError.PARAM_ERROR.msg());
- }
- try {
- EventSource.Factory factory = EventSources.createFactory(this.okHttpClient);
- ObjectMapper mapper = new ObjectMapper();
- String requestBody = mapper.writeValueAsString(chatCompletion);
- Request request = new Request.Builder()
- .url(this.apiHost)
- .post(RequestBody.create(MediaType.parse(ContentType.JSON.getValue()), requestBody))
- .build();
- factory.newEventSource(request, eventSourceListener);
- } catch (Exception e) {
- log.error("请求参数解析异常:{}", e.getMessage());
- }
- }
-
- /**
- * 插件问答简易版
- * 默认取messages最后一个元素构建插件对话
- * 默认模型:ChatCompletion.Model.GPT_3_5_TURBO_16K_0613
- *
- * @param chatCompletion 参数
- * @param eventSourceListener sse监听器
- * @param pluginEventSourceListener 插件sse监听器,收集function call返回信息
- * @param plugin 插件
- * @param 插件自定义函数的请求值
- * @param 插件自定义函数的返回值
- */
- public void streamChatCompletionWithPlugin(ChatCompletion chatCompletion, EventSourceListener eventSourceListener, PluginListener pluginEventSourceListener, PluginAbstract plugin) {
- if (Objects.isNull(plugin)) {
- this.streamChatCompletion(chatCompletion, eventSourceListener);
- return;
- }
- if (CollectionUtil.isEmpty(chatCompletion.getMessages())) {
- throw new BaseException(CommonError.MESSAGE_NOT_NUL.msg());
- }
- Functions functions = Functions.builder()
- .name(plugin.getFunction())
- .description(plugin.getDescription())
- .parameters(plugin.getParameters())
- .build();
- //没有值,设置默认值
- if (Objects.isNull(chatCompletion.getFunctionCall())) {
- chatCompletion.setFunctionCall("auto");
- }
- //tip: 覆盖自己设置的functions参数,使用plugin构造的functions
- chatCompletion.setFunctions(Collections.singletonList(functions));
- //调用OpenAi
- if (Objects.isNull(pluginEventSourceListener)) {
- pluginEventSourceListener = new DefaultPluginListener(this, eventSourceListener, plugin, chatCompletion);
- }
- this.streamChatCompletion(chatCompletion, pluginEventSourceListener);
- }
-
- /**
- * 插件问答简易版
- * 默认取messages最后一个元素构建插件对话
- * 默认模型:ChatCompletion.Model.GPT_3_5_TURBO_16K_0613
- *
- * @param chatCompletion 参数
- * @param eventSourceListener sse监听器
- * @param plugin 插件
- * @param 插件自定义函数的请求值
- * @param 插件自定义函数的返回值
- */
- public void streamChatCompletionWithPlugin(ChatCompletion chatCompletion, EventSourceListener eventSourceListener, PluginAbstract plugin) {
- PluginListener pluginEventSourceListener = new DefaultPluginListener(this, eventSourceListener, plugin, chatCompletion);
- this.streamChatCompletionWithPlugin(chatCompletion, eventSourceListener, pluginEventSourceListener, plugin);
- }
-
- /**
- * 插件问答简易版
- * 默认取messages最后一个元素构建插件对话
- * 默认模型:ChatCompletion.Model.GPT_3_5_TURBO_16K_0613
- *
- * @param messages 问答参数
- * @param eventSourceListener sse监听器
- * @param plugin 插件
- * @param 插件自定义函数的请求值
- * @param 插件自定义函数的返回值
- */
- public void streamChatCompletionWithPlugin(List messages, EventSourceListener eventSourceListener, PluginAbstract plugin) {
- this.streamChatCompletionWithPlugin(messages, ChatCompletion.Model.GPT_3_5_TURBO_16K_0613.getName(), eventSourceListener, plugin);
- }
-
- /**
- * 插件问答简易版
- * 默认取messages最后一个元素构建插件对话
- *
- * @param messages 问答参数
- * @param model 模型
- * @param eventSourceListener eventSourceListener
- * @param plugin 插件
- * @param 插件自定义函数的请求值
- * @param 插件自定义函数的返回值
- */
- public void streamChatCompletionWithPlugin(List messages, String model, EventSourceListener eventSourceListener, PluginAbstract plugin) {
- ChatCompletion chatCompletion = ChatCompletion.builder().messages(messages).model(model).build();
- this.streamChatCompletionWithPlugin(chatCompletion, eventSourceListener, plugin);
- }
-
- /**
- * 根据描述生成图片
- *
- * @param image 图片参数
- * @return ImageResponse
- */
- public ImageResponse genImages(Image image) {
- Single edits = this.openAiApi.genImages(image);
- return edits.blockingGet();
- }
-
- /**
- * 最新版的GPT-3.5 chat completion 更加贴近官方网站的问答模型
- *
- * @param chatCompletion 问答参数
- * @return 答案
- */
- public ChatCompletionResponse chatCompletion(T chatCompletion) {
- if (chatCompletion instanceof ChatCompletion) {
- Single chatCompletionResponse = this.openAiApi.chatCompletion((ChatCompletion) chatCompletion);
- return chatCompletionResponse.blockingGet();
- }
- Single chatCompletionResponse = this.openAiApi.chatCompletionWithPicture((ChatCompletionWithPicture) chatCompletion);
- return chatCompletionResponse.blockingGet();
- }
-
- /**
- * 上传文件
- *
- * @param purpose purpose
- * @param file 文件对象
- * @return UploadFileResponse
- */
- public UploadFileResponse uploadFile(String purpose, java.io.File file) {
- // 创建 RequestBody,用于封装构建RequestBody
- RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
- MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", file.getName(), fileBody);
-
- RequestBody purposeBody = RequestBody.create(MediaType.parse("multipart/form-data"), purpose);
- Single uploadFileResponse = this.openAiApi.uploadFile(multipartBody, purposeBody);
- return uploadFileResponse.blockingGet();
- }
-
- /**
- * 获取openKey账户信息(近90天)
- *
- * @param key
- * @return KeyInfo
- * @Date 2023/7/6
- **/
- public KeyInfo getKeyInfo(String key) {
- Date now = new Date();
- Date start = new Date(now.getTime() - (long) 90 * 24 * 60 * 60 * 1000);
- Date end = new Date(now.getTime() + (long) 24 * 60 * 60 * 1000);
-
- BillingUsage billingUsage = billingUsage(start.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(), end.toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
- double totalUsage = billingUsage.getTotalUsage().doubleValue() / 100;
- Subscription subscription = subscription();
- KeyInfo keyInfo = new KeyInfo();
- String start_key = key.substring(0, 6);
- String end_key = key.substring(key.length() - 6);
- String mid_key = key.substring(6, key.length() - 6);
- mid_key = mid_key.replaceAll(".", "*");
-
- keyInfo.setKeyValue(start_key + mid_key + end_key);
- keyInfo.setTotalAmount(subscription.getHardLimitUsd());
- keyInfo.setRemaining(subscription.getHardLimitUsd() - totalUsage);
- keyInfo.setTotalUsage(totalUsage);
- keyInfo.setLimitDate(new Date(subscription.getAccessUntil() * 1000).toInstant().atZone(ZoneId.systemDefault()).toLocalDate());
- keyInfo.setPlanTitle(subscription.getPlan() != null ? subscription.getPlan().getTitle() : "null");
- keyInfo.setIsHasPaymentMethod(subscription.isHasPaymentMethod());
- keyInfo.setModel(getModelName());
- return keyInfo;
- }
-
- /**
- * 获取可用模型
- *
- * @param
- * @return String
- * @Date 2023/7/6
- **/
- public String getModelName() {
- Single models = this.openAiApi.models();
- List modelList = models.blockingGet().getData();
- for (Model model : modelList) {
- if (Objects.equals(model.getId(), "gpt-4")) {
- return "GPT-4.0";
- }
- }
- return "GPT-3.5";
- }
-
- /**
- * 账户调用接口消耗金额信息查询
- * 最多查询100天
- *
- * @param starDate 开始时间
- * @param endDate 结束时间
- * @return 消耗金额信息
- */
- public BillingUsage billingUsage(@NotNull LocalDate starDate, @NotNull LocalDate endDate) {
- Single billingUsage = this.openAiApi.billingUsage(starDate, endDate);
- return billingUsage.blockingGet();
- }
-
- /**
- * 文本转换向量
- *
- * @param embedding 入参
- * @return EmbeddingResponse
- */
- public EmbeddingResponse embeddings(Embedding embedding) {
- Single embeddings = this.openAiApi.embeddings(embedding);
- return embeddings.blockingGet();
- }
-
- /**
- * 账户信息查询:里面包含总金额等信息
- *
- * @return 账户信息
- */
- public Subscription subscription() {
- Single subscription = this.openAiApi.subscription();
- return subscription.blockingGet();
- }
-
- /**
- * 语音转文字
- *
- * @param transcriptions 参数
- * @param file 语音文件 最大支持25MB mp3, mp4, mpeg, mpga, m4a, wav, webm
- * @return 语音文本
- */
- public WhisperResponse speechToTextTranscriptions(java.io.File file, Transcriptions transcriptions) {
- //文件
- RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
- MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", file.getName(), fileBody);
- //自定义参数
- Map requestBodyMap = new HashMap<>(10);
- if (StrUtil.isNotBlank(transcriptions.getLanguage())) {
- requestBodyMap.put(Transcriptions.Fields.language, RequestBody.create(MediaType.parse("multipart/form-data"), transcriptions.getLanguage()));
- }
- if (StrUtil.isNotBlank(transcriptions.getModel())) {
- requestBodyMap.put(Transcriptions.Fields.model, RequestBody.create(MediaType.parse("multipart/form-data"), transcriptions.getModel()));
- }
- if (StrUtil.isNotBlank(transcriptions.getPrompt())) {
- requestBodyMap.put(Transcriptions.Fields.prompt, RequestBody.create(MediaType.parse("multipart/form-data"), transcriptions.getPrompt()));
- }
- if (StrUtil.isNotBlank(transcriptions.getResponseFormat())) {
- requestBodyMap.put(Transcriptions.Fields.responseFormat, RequestBody.create(MediaType.parse("multipart/form-data"), transcriptions.getResponseFormat()));
- }
- if (Objects.nonNull(transcriptions.getTemperature())) {
- requestBodyMap.put(Transcriptions.Fields.temperature, RequestBody.create(MediaType.parse("multipart/form-data"), String.valueOf(transcriptions.getTemperature())));
- }
- Single whisperResponse = this.openAiApi.speechToTextTranscriptions(multipartBody, requestBodyMap);
- return whisperResponse.blockingGet();
- }
-
- /**
- * 简易版 语音转文字
- *
- * @param file 语音文件 最大支持25MB mp3, mp4, mpeg, mpga, m4a, wav, webm
- * @return 语音文本
- */
- public WhisperResponse speechToTextTranscriptions(java.io.File file) {
- Transcriptions transcriptions = Transcriptions.builder().build();
- return this.speechToTextTranscriptions(file, transcriptions);
- }
-
- /**
- * 文本转语音(异步)
- *
- * @param textToSpeech 参数
- * @param callback 返回值接收
- * @since 1.1.2
- */
- public void textToSpeech(TextToSpeech textToSpeech, retrofit2.Callback callback) {
- Call responseBody = this.openAiApi.textToSpeech(textToSpeech);
- responseBody.enqueue(callback);
- }
-
- /**
- * 文本转语音(同步)
- *
- * @param textToSpeech 参数
- * @since 1.1.3
- */
- public ResponseBody textToSpeech(TextToSpeech textToSpeech) {
- try {
- Call responseBody = this.openAiApi.textToSpeech(textToSpeech);
- return responseBody.execute().body();
- } catch (IOException e) {
- throw new BaseException("文本转语音(同步)失败: " + e.getMessage());
- }
- }
-
- /**
- * 文本转语音(克隆)
- *
- * @param textToSpeech
- * @return
- */
- public ResponseBody textToSpeechClone(TextToSpeech textToSpeech) {
- String baseUrl = "http://localhost:8081";
- String spk = "三月七";
- String text = textToSpeech.getInput();
- String lang = "zh";
-
- // 创建OkHttpClient实例
- OkHttpClient client = new OkHttpClient();
-
- // 构建请求URL
- HttpUrl.Builder urlBuilder = HttpUrl.parse(baseUrl).newBuilder();
- urlBuilder.addQueryParameter("spk", spk);
- urlBuilder.addQueryParameter("text", text);
- urlBuilder.addQueryParameter("lang", lang);
- String url = urlBuilder.build().toString();
-
- // 创建请求对象
- Request request = new Request.Builder()
- .url(url)
- .build();
- // 发送请求并处理响应
- try {
- return client.newCall(request).execute().body();
- } catch (IOException e) {
- throw new BaseException("语音克隆失败!{}", e.getMessage());
- }
- }
-
- /**
- * 插件问答简易版
- * 默认取messages最后一个元素构建插件对话
- * 默认模型:ChatCompletion.Model.GPT_3_5_TURBO_16K_0613
- *
- * @param chatCompletion 参数
- * @param plugin 插件
- * @param 插件自定义函数的请求值
- * @param 插件自定义函数的返回值
- * @return ChatCompletionResponse
- */
- public ChatCompletionResponse chatCompletionWithPlugin(ChatCompletion chatCompletion, PluginAbstract plugin) {
- if (Objects.isNull(plugin)) {
- return this.chatCompletion(chatCompletion);
- }
- if (CollectionUtil.isEmpty(chatCompletion.getMessages())) {
- throw new BaseException(CommonError.MESSAGE_NOT_NUL.msg());
- }
- List messages = chatCompletion.getMessages();
- Functions functions = Functions.builder()
- .name(plugin.getFunction())
- .description(plugin.getDescription())
- .parameters(plugin.getParameters())
- .build();
- //没有值,设置默认值
- if (Objects.isNull(chatCompletion.getFunctionCall())) {
- chatCompletion.setFunctionCall("auto");
- }
- //tip: 覆盖自己设置的functions参数,使用plugin构造的functions
- chatCompletion.setFunctions(Collections.singletonList(functions));
- //调用OpenAi
- ChatCompletionResponse functionCallChatCompletionResponse = this.chatCompletion(chatCompletion);
- ChatChoice chatChoice = functionCallChatCompletionResponse.getChoices().get(0);
- log.debug("构造的方法值:{}", chatChoice.getMessage().getFunctionCall());
-
- R realFunctionParam = (R) JSONUtil.toBean(chatChoice.getMessage().getFunctionCall().getArguments(), plugin.getR());
- T tq = plugin.func(realFunctionParam);
-
- FunctionCall functionCall = FunctionCall.builder()
- .arguments(chatChoice.getMessage().getFunctionCall().getArguments())
- .name(plugin.getFunction())
- .build();
- messages.add(Message.builder().role(Message.Role.ASSISTANT).content("function_call").functionCall(functionCall).build());
- messages.add(Message.builder().role(Message.Role.FUNCTION).name(plugin.getFunction()).content(plugin.content(tq)).build());
- //设置第二次,请求的参数
- chatCompletion.setFunctionCall(null);
- chatCompletion.setFunctions(null);
-
- ChatCompletionResponse chatCompletionResponse = this.chatCompletion(chatCompletion);
- log.debug("自定义的方法返回值:{}", chatCompletionResponse.getChoices());
- return chatCompletionResponse;
- }
-
- /**
- * 插件问答简易版
- * 默认取messages最后一个元素构建插件对话
- * 默认模型:ChatCompletion.Model.GPT_3_5_TURBO_16K_0613
- *
- * @param messages 问答参数
- * @param plugin 插件
- * @param 插件自定义函数的请求值
- * @param 插件自定义函数的返回值
- * @return ChatCompletionResponse
- */
- public ChatCompletionResponse chatCompletionWithPlugin(List messages, PluginAbstract plugin) {
- return chatCompletionWithPlugin(messages, ChatCompletion.Model.GPT_3_5_TURBO_16K_0613.getName(), plugin);
- }
-
- /**
- * 插件问答简易版
- * 默认取messages最后一个元素构建插件对话
- *
- * @param messages 问答参数
- * @param model 模型
- * @param plugin 插件
- * @param 插件自定义函数的请求值
- * @param 插件自定义函数的返回值
- * @return ChatCompletionResponse
- */
- public ChatCompletionResponse chatCompletionWithPlugin(List messages, String model, PluginAbstract plugin) {
- ChatCompletion chatCompletion = ChatCompletion.builder().messages(messages).model(model).build();
- return this.chatCompletionWithPlugin(chatCompletion, plugin);
- }
-
- public static final class Builder {
- private @NotNull List apiKey;
- /**
- * api请求地址,结尾处有斜杠
- *
- * @see OpenAIConst
- */
- private String apiHost;
-
- private String apiUrl;
-
- /**
- * 自定义OkhttpClient
- */
- private OkHttpClient okHttpClient;
-
-
- /**
- * api key的获取策略
- */
- private KeyStrategyFunction keyStrategy;
-
- /**
- * 自定义鉴权拦截器
- */
- private OpenAiAuthInterceptor authInterceptor;
-
- public Builder() {
- }
-
- public Builder apiKey(@NotNull List val) {
- apiKey = val;
- return this;
- }
-
- /**
- * @param val api请求地址,结尾处有斜杠
- * @return Builder
- * @see OpenAIConst
- */
- public Builder apiHost(String val) {
- apiHost = val;
- return this;
- }
-
- /**
- * @param val 自定义请求后缀
- * @return Builder
- * @see OpenAIConst
- */
- public Builder apiUrl(String val) {
- apiUrl = val;
- return this;
- }
-
- public Builder keyStrategy(KeyStrategyFunction val) {
- keyStrategy = val;
- return this;
- }
-
- public Builder okHttpClient(OkHttpClient val) {
- okHttpClient = val;
- return this;
- }
-
- public Builder authInterceptor(OpenAiAuthInterceptor val) {
- authInterceptor = val;
- return this;
- }
-
- public OpenAiStreamClient build() {
- return new OpenAiStreamClient(this);
- }
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/TestOpenAIAPI.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/TestOpenAIAPI.java
deleted file mode 100644
index cbf3486a..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/TestOpenAIAPI.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.ruoyi.common.chat.openai;
-
-import okhttp3.*;
-
-import java.io.IOException;
-
-public class TestOpenAIAPI {
-
- private static final String API_KEY = "sk-Waea254YSRYVg4FZVCz2CDz73B22xRpmKpJ41kbczVgpPxvg";
- private static final String URL = "https://api.gptgod.online/v1/chat/completions";
- private final OkHttpClient client = new OkHttpClient();
-
- public static void main(String[] args) throws IOException {
- TestOpenAIAPI api = new TestOpenAIAPI();
- api.getChatGptResponse("Hello, how are you?");
- }
-
- public void getChatGptResponse(String prompt) throws IOException {
- RequestBody body = RequestBody.create(MediaType.get("application/json; charset=utf-8"),
- "{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You are a helpful assistant.\"}, {\"role\": \"user\", \"content\": \"" + prompt + "\"}]}");
-
- Request request = new Request.Builder()
- .url(URL)
- .post(body)
- .addHeader("Authorization", "Bearer " + API_KEY)
- .build();
-
- try (Response response = client.newCall(request).execute()) {
-
- }
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/CommonError.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/CommonError.java
deleted file mode 100644
index 1d409e78..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/CommonError.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.ruoyi.common.chat.openai.exception;
-
-/**
- * 错误
- *
- * @author https:www.unfbx.com
- * 2023-02-11
- */
-public enum CommonError implements IError {
- MESSAGE_NOT_NUL(500, "Message 不能为空"),
- API_KEYS_NOT_NUL(500, "API KEYS 不能为空"),
- NO_ACTIVE_API_KEYS(500, "没有可用的API KEYS"),
- SYS_ERROR(500, "系统繁忙"),
- PARAM_ERROR(501, "参数异常"),
- RETRY_ERROR(502, "请求异常,请重试~"),
- //官方的错误码列表:https://platform.openai.com/docs/guides/error-codes/api-errors
- OPENAI_AUTHENTICATION_ERROR(401, "身份验证无效/提供的 API 密钥不正确/您必须是组织的成员才能使用 API"),
- OPENAI_LIMIT_ERROR(429, "达到请求的速率限制/您超出了当前配额,请检查您的计划和帐单详细信息/发动机当前过载,请稍后重试"),
- OPENAI_SERVER_ERROR(500, "服务器在处理您的请求时出错"),
- ;
-
-
- private final int code;
- private final String msg;
-
- CommonError(int code, String msg) {
- this.code = code;
- this.msg = msg;
- }
-
- @Override
- public String msg() {
- return this.msg;
- }
-
- @Override
- public int code() {
- return this.code;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/IError.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/IError.java
deleted file mode 100644
index ee4f44a4..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/exception/IError.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package org.ruoyi.common.chat.openai.exception;
-
-/**
- * @author https:www.unfbx.com
- * 2023-02-11
- */
-public interface IError {
- String msg();
-
- int code();
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyRandomStrategy.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyRandomStrategy.java
deleted file mode 100644
index e3c507f1..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyRandomStrategy.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package org.ruoyi.common.chat.openai.function;
-
-import cn.hutool.core.util.RandomUtil;
-
-import java.util.List;
-
-/**
- * 随机策略
- *
- * @author https:www.unfbx.com
- * @since 2023-04-03
- */
-public class KeyRandomStrategy implements KeyStrategyFunction, String> {
-
- @Override
- public String apply(List apiKeys) {
- return RandomUtil.randomEle(apiKeys);
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyStrategyFunction.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyStrategyFunction.java
deleted file mode 100644
index 5de0eee3..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/function/KeyStrategyFunction.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package org.ruoyi.common.chat.openai.function;
-
-import java.util.function.Function;
-
-/**
- * key 的获取策略
- * jdk默认实现
- *
- * @author https:www.unfbx.com
- * @see Function
- * @since 2023-04-03
- */
-@FunctionalInterface
-public interface KeyStrategyFunction {
-
- /**
- * Applies this function to the given argument.
- *
- * @param t the function argument
- * @return the function result
- */
- R apply(T t);
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DefaultOpenAiAuthInterceptor.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DefaultOpenAiAuthInterceptor.java
deleted file mode 100644
index 24771215..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DefaultOpenAiAuthInterceptor.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package org.ruoyi.common.chat.openai.interceptor;
-
-import lombok.extern.slf4j.Slf4j;
-import okhttp3.Request;
-import okhttp3.Response;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 请求增加header apikey
- *
- * @author https:www.unfbx.com
- * @since 2023-03-23
- */
-@Slf4j
-public class DefaultOpenAiAuthInterceptor extends OpenAiAuthInterceptor {
- /**
- * 请求头处理
- */
- public DefaultOpenAiAuthInterceptor() {
- super.setWarringConfig(null);
- }
-
- /**
- * 构造方法
- *
- * @param warringConfig 所有的key都失效后的告警参数配置
- */
- public DefaultOpenAiAuthInterceptor(Map warringConfig) {
- super.setWarringConfig(warringConfig);
- }
-
- /**
- * 拦截器鉴权
- *
- * @param chain Chain
- * @return Response对象
- * @throws IOException io异常
- */
- @Override
- public Response intercept(Chain chain) throws IOException {
- Request original = chain.request();
- return chain.proceed(auth(super.getKey(), original));
- }
-
- /**
- * key失效或者禁用后的处理逻辑
- * 默认不处理
- *
- * @param apiKey 返回新的api keys集合
- * @return 新的apiKey集合
- */
- @Override
- protected List onErrorDealApiKeys(String apiKey) {
- return super.getApiKey();
- }
-
- @Override
- protected void noHaveActiveKeyWarring() {
- log.error("--------> [告警] 没有可用的key!!!");
- return;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DynamicKeyOpenAiAuthInterceptor.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DynamicKeyOpenAiAuthInterceptor.java
deleted file mode 100644
index 94edda51..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/DynamicKeyOpenAiAuthInterceptor.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package org.ruoyi.common.chat.openai.interceptor;
-
-import cn.hutool.json.JSONUtil;
-import lombok.Getter;
-import lombok.extern.slf4j.Slf4j;
-import okhttp3.Request;
-import okhttp3.Response;
-import org.ruoyi.common.chat.entity.common.OpenAiResponse;
-import org.ruoyi.common.chat.openai.exception.CommonError;
-import org.ruoyi.common.core.exception.base.BaseException;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-/**
- * 动态处理key的鉴权拦截器
- *
- * @author https:www.unfbx.com
- * @since 2023-04-25
- */
-@Getter
-@Slf4j
-public class DynamicKeyOpenAiAuthInterceptor extends OpenAiAuthInterceptor {
- /**
- * 账号被封了
- */
- private static final String ACCOUNT_DEACTIVATED = "account_deactivated";
- /**
- * key不正确
- */
- private static final String INVALID_API_KEY = "invalid_api_key";
-
- /**
- * 请求头处理
- */
- public DynamicKeyOpenAiAuthInterceptor() {
- this.setWarringConfig(null);
- }
-
- /**
- * 构造方法
- *
- * @param warringConfig 所有的key都失效后的告警参数配置
- */
- public DynamicKeyOpenAiAuthInterceptor(Map warringConfig) {
- this.setWarringConfig(warringConfig);
- }
-
- @Override
- public Response intercept(Chain chain) throws IOException {
- String key = getKey();
- Request original = chain.request();
- Request request = this.auth(key, original);
- Response response = chain.proceed(request);
- if (!response.isSuccessful()) {
- String errorMsg = response.body().string();
- if (response.code() == CommonError.OPENAI_AUTHENTICATION_ERROR.code()
- || response.code() == CommonError.OPENAI_LIMIT_ERROR.code()
- || response.code() == CommonError.OPENAI_SERVER_ERROR.code()) {
- OpenAiResponse openAiResponse = JSONUtil.toBean(errorMsg, OpenAiResponse.class);
- String errorCode = openAiResponse.getError().getCode();
- log.error("--------> 请求openai异常,错误code:{}", errorCode);
- log.error("--------> 请求异常:{}", errorMsg);
- //账号被封或者key不正确就移除掉
- if (ACCOUNT_DEACTIVATED.equals(errorCode) || INVALID_API_KEY.equals(errorCode)) {
- super.setApiKey(this.onErrorDealApiKeys(key));
- }
- throw new BaseException(openAiResponse.getError().getMessage());
- }
- //非官方定义的错误code
- log.error("--------> 请求异常:{}", errorMsg);
- OpenAiResponse openAiResponse = JSONUtil.toBean(errorMsg, OpenAiResponse.class);
- if (Objects.nonNull(openAiResponse.getError())) {
- log.error(openAiResponse.getError().getMessage());
- throw new BaseException(openAiResponse.getError().getMessage());
- }
- throw new BaseException(CommonError.RETRY_ERROR.msg());
- }
- return response;
- }
-
-
- @Override
- protected List onErrorDealApiKeys(String errorKey) {
- List apiKey = super.getApiKey().stream().filter(e -> !errorKey.equals(e)).collect(Collectors.toList());
- log.error("--------> 当前ApiKey:[{}] 失效了,移除!", errorKey);
- return apiKey;
- }
-
- /**
- * 所有的key都失效后,自定义预警配置
- * 不配置直接return
- */
- @Override
- protected void noHaveActiveKeyWarring() {
- log.error("--------> [告警] 没有可用的key!!!");
- return;
- }
-
- @Override
- public Request auth(String key, Request original) {
- return super.auth(key, original);
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAILogger.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAILogger.java
deleted file mode 100644
index 7eafa6cc..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAILogger.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.ruoyi.common.chat.openai.interceptor;
-
-import lombok.extern.slf4j.Slf4j;
-import okhttp3.logging.HttpLoggingInterceptor;
-
-/**
- * 日志
- *
- * @author https:www.unfbx.com
- * 2023-02-28
- */
-@Slf4j
-public class OpenAILogger implements HttpLoggingInterceptor.Logger {
- @Override
- public void log(String message) {
- log.info("OkHttp-------->:{}", message);
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAiAuthInterceptor.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAiAuthInterceptor.java
deleted file mode 100644
index 68365d62..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAiAuthInterceptor.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.ruoyi.common.chat.openai.interceptor;
-
-
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.http.ContentType;
-import cn.hutool.http.Header;
-import lombok.Getter;
-import lombok.Setter;
-import okhttp3.Interceptor;
-import okhttp3.Request;
-import org.ruoyi.common.chat.openai.exception.CommonError;
-import org.ruoyi.common.chat.openai.function.KeyStrategyFunction;
-import org.ruoyi.common.core.exception.base.BaseException;
-
-import java.util.List;
-import java.util.Map;
-
-public abstract class OpenAiAuthInterceptor implements Interceptor {
-
-
- /**
- * key 集合
- */
- @Getter
- @Setter
- private List apiKey;
- /**
- * 自定义的key的使用策略
- */
- @Getter
- @Setter
- private KeyStrategyFunction, String> keyStrategy;
-
- /**
- * 预警触发参数配置,配置参数实现飞书、钉钉、企业微信、邮箱预警等功能
- */
- @Getter
- @Setter
- private Map warringConfig;
-
- /**
- * 自定义apiKeys的处理逻辑
- *
- * @param errorKey 错误的key
- * @return 返回值是新的apiKeys
- */
- protected abstract List onErrorDealApiKeys(String errorKey);
-
- /**
- * 所有的key都失效后,自定义预警配置
- * 可以通过warringConfig配置参数实现飞书、钉钉、企业微信、邮箱预警等
- */
- protected abstract void noHaveActiveKeyWarring();
-
-
- /**
- * 获取请求key
- *
- * @return key
- */
- public final String getKey() {
- if (CollectionUtil.isEmpty(apiKey)) {
- this.noHaveActiveKeyWarring();
- throw new BaseException(CommonError.NO_ACTIVE_API_KEYS.msg());
- }
- return keyStrategy.apply(apiKey);
- }
-
- /**
- * 默认的鉴权处理方法
- *
- * @param key api key
- * @param original 源请求体
- * @return 请求体
- */
- public Request auth(String key, Request original) {
- Request request = original.newBuilder()
- .header(Header.AUTHORIZATION.getValue(), "Bearer " + key)
- .header(Header.CONTENT_TYPE.getValue(), ContentType.JSON.getValue())
- .method(original.method(), original.body())
- .build();
- return request;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAiResponseInterceptor.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAiResponseInterceptor.java
deleted file mode 100644
index 8aee3507..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/interceptor/OpenAiResponseInterceptor.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.ruoyi.common.chat.openai.interceptor;
-
-import cn.hutool.json.JSONUtil;
-import lombok.extern.slf4j.Slf4j;
-import okhttp3.Interceptor;
-import okhttp3.Request;
-import okhttp3.Response;
-import org.ruoyi.common.chat.entity.common.OpenAiResponse;
-import org.ruoyi.common.chat.openai.exception.CommonError;
-import org.ruoyi.common.core.exception.base.BaseException;
-
-import java.io.IOException;
-import java.util.Objects;
-
-/**
- * openai 返回值处理Interceptor
- *
- * @author https:www.unfbx.com
- * @since 2023-03-23
- */
-@Slf4j
-public class OpenAiResponseInterceptor implements Interceptor {
- @Override
- public Response intercept(Chain chain) throws IOException {
-
- Request original = chain.request();
- Response response = chain.proceed(original);
- if (!response.isSuccessful()) {
- if (response.code() == CommonError.OPENAI_AUTHENTICATION_ERROR.code()
- || response.code() == CommonError.OPENAI_LIMIT_ERROR.code()
- || response.code() == CommonError.OPENAI_SERVER_ERROR.code()) {
- OpenAiResponse openAiResponse = JSONUtil.toBean(response.body().string(), OpenAiResponse.class);
- log.error(openAiResponse.getError().getMessage());
- throw new BaseException(openAiResponse.getError().getMessage());
- }
- String errorMsg = response.body().string();
- log.error("--------> 请求异常:{}", errorMsg);
- OpenAiResponse openAiResponse = JSONUtil.toBean(errorMsg, OpenAiResponse.class);
- if (Objects.nonNull(openAiResponse.getError())) {
- log.error(openAiResponse.getError().getMessage());
- throw new BaseException(openAiResponse.getError().getMessage());
- }
- throw new BaseException(CommonError.RETRY_ERROR.msg());
- }
- return response;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/plugin/PluginAbstract.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/plugin/PluginAbstract.java
deleted file mode 100644
index da122db8..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/plugin/PluginAbstract.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package org.ruoyi.common.chat.openai.plugin;
-
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.json.JSONObject;
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import org.ruoyi.common.chat.entity.chat.Parameters;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-@Data
-@AllArgsConstructor
-public abstract class PluginAbstract {
-
- private Class> R;
-
- private String name;
-
- private String function;
-
- private String description;
-
- private List args;
-
- private List required;
-
- private Parameters parameters;
-
- public PluginAbstract(Class> r) {
- R = r;
- }
-
- public void setRequired(List required) {
- if (CollectionUtil.isEmpty(required)) {
- this.required = this.getArgs().stream().filter(e -> e.isRequired()).map(Arg::getName).collect(Collectors.toList());
- return;
- }
- this.required = required;
- }
-
- private void setRequired() {
- if (CollectionUtil.isEmpty(required)) {
- this.required = this.getArgs().stream().filter(e -> e.isRequired()).map(Arg::getName).collect(Collectors.toList());
- }
- }
-
- private void setParameters() {
- JSONObject properties = new JSONObject();
- args.forEach(e -> {
- JSONObject param = new JSONObject();
- param.putOpt("type", e.getType());
- param.putOpt("enum", e.getEnumDictValue());
- param.putOpt("description", e.getDescription());
- properties.putOpt(e.getName(), param);
- });
- this.parameters = Parameters.builder()
- .type("object")
- .properties(properties)
- .required(this.getRequired())
- .build();
- }
-
- public void setArgs(List args) {
- this.args = args;
- setRequired();
- setParameters();
- }
-
- public abstract T func(R args);
-
- public abstract String content(T t);
-
- @Data
- public static class Arg {
- private String name;
- private String type;
- private String description;
- @JsonIgnore
- private boolean enumDict;
- @JsonProperty("enum")
- private List enumDictValue;
- @JsonIgnore
- private boolean required;
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/plugin/PluginParam.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/plugin/PluginParam.java
deleted file mode 100644
index c5a5909d..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/openai/plugin/PluginParam.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.ruoyi.common.chat.openai.plugin;
-
-import lombok.Data;
-
-@Data
-public class PluginParam {
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/ChatRequest.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/ChatRequest.java
deleted file mode 100644
index e0b9bf44..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/ChatRequest.java
+++ /dev/null
@@ -1,97 +0,0 @@
-package org.ruoyi.common.chat.request;
-
-import jakarta.validation.constraints.NotEmpty;
-import lombok.Data;
-import org.ruoyi.common.chat.entity.chat.Message;
-
-import java.util.List;
-
-/**
- * 对话请求对象
- *
- * @author ageerle
- * @sine 2023-04-08
- */
-@Data
-public class ChatRequest {
-
- @NotEmpty(message = "对话消息不能为空")
- List messages;
-
- @NotEmpty(message = "传入的模型不能为空")
- private String model;
-
- /**
- * 提示词
- */
- private String prompt;
-
-
- /**
- * 系统提示词
- */
- private String sysPrompt;
-
-
- /**
- * 消息id
- */
- private Long messageId;
-
- /**
- * 是否开启流式对话
- */
- private Boolean stream = Boolean.TRUE;
-
- /**
- * 知识库id
- */
- private String kid;
-
- /**
- * 用户id
- */
- private Long userId;
-
- /**
- * 会话id
- */
- private Long sessionId;
-
- /**
- * 应用ID
- */
- private String appId;
-
- /**
- * 对话角色
- */
- private String role;
-
-
- /**
- * 对话id(每个聊天窗口都不一样)
- */
- private Long uuid;
-
- /**
- * 是否有附件
- */
- private Boolean hasAttachment;
-
- /**
- * 是否启用深度思考
- */
- private Boolean enableThinking;
-
- /**
- * 是否自动切换模型
- */
- private Boolean autoSelectModel;
-
- /**
- * 会话令牌(为避免在非Web线程中获取Request,入口处注入)
- */
- private String token;
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/Dall3Request.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/Dall3Request.java
deleted file mode 100644
index afc72ab7..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/request/Dall3Request.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package org.ruoyi.common.chat.request;
-
-import jakarta.validation.constraints.NotEmpty;
-import lombok.Data;
-
-/**
- * @author https:www.unfbx.com
- * @sine 2023-04-08
- */
-@Data
-public class Dall3Request {
-
- @NotEmpty(message = "传入的模型不能为空")
- private String model;
-
- @NotEmpty(message = "提示词不能为空")
- private String prompt;
-
- /**
- * 图片大小
- */
- @NotEmpty(message = "图片大小不能为空")
- private String size;
-
- /**
- * 图片质量
- */
- @NotEmpty(message = "图片质量不能为空")
- private String quality;
-
- /**
- * 图片风格
- */
- @NotEmpty(message = "图片风格不能为空")
- private String style;
-
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chat/IChatModelService.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chat/IChatModelService.java
new file mode 100644
index 00000000..3c362a52
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chat/IChatModelService.java
@@ -0,0 +1,76 @@
+package org.ruoyi.common.chat.service.chat;
+
+import org.ruoyi.common.chat.domain.bo.chat.ChatModelBo;
+import org.ruoyi.common.chat.domain.vo.chat.ChatModelVo;
+import org.ruoyi.common.mybatis.core.page.PageQuery;
+import org.ruoyi.common.mybatis.core.page.TableDataInfo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 模型管理Service接口
+ *
+ * @author ageerle
+ * @date 2025-12-14
+ */
+public interface IChatModelService {
+
+ /**
+ * 查询模型管理
+ *
+ * @param id 主键
+ * @return 模型管理
+ */
+ ChatModelVo queryById(Long id);
+
+ /**
+ * 根据模型名称查询模型
+ *
+ * @param modelName 模型名称
+ * @return 模型管理
+ */
+ ChatModelVo selectModelByName(String modelName);
+
+ /**
+ * 分页查询模型管理列表
+ *
+ * @param bo 查询条件
+ * @param pageQuery 分页参数
+ * @return 模型管理分页列表
+ */
+ TableDataInfo queryPageList(ChatModelBo bo, PageQuery pageQuery);
+
+ /**
+ * 查询符合条件的模型管理列表
+ *
+ * @param bo 查询条件
+ * @return 模型管理列表
+ */
+ List queryList(ChatModelBo bo);
+
+ /**
+ * 新增模型管理
+ *
+ * @param bo 模型管理
+ * @return 是否新增成功
+ */
+ Boolean insertByBo(ChatModelBo bo);
+
+ /**
+ * 修改模型管理
+ *
+ * @param bo 模型管理
+ * @return 是否修改成功
+ */
+ Boolean updateByBo(ChatModelBo bo);
+
+ /**
+ * 校验并批量删除模型管理信息
+ *
+ * @param ids 待删除的主键集合
+ * @param isValid 是否进行有效性校验
+ * @return 是否删除成功
+ */
+ Boolean deleteWithValidByIds(Collection ids, Boolean isValid);
+}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chat/IChatService.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chat/IChatService.java
new file mode 100644
index 00000000..155a582e
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/chat/IChatService.java
@@ -0,0 +1,27 @@
+package org.ruoyi.common.chat.service.chat;
+
+import dev.langchain4j.model.chat.response.StreamingChatResponseHandler;
+import jakarta.validation.Valid;
+import org.ruoyi.common.chat.domain.dto.request.ChatRequest;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+/**
+ * 公共大模型对话接口
+ */
+public interface IChatService {
+
+ /**
+ * 客户端发送对话消息到服务端
+ */
+ SseEmitter chat(@Valid ChatRequest chatRequest);
+
+ /**
+ * 支持外部 handler 的对话接口(跨模块调用)
+ * 同时发送到 SSE 和外部 handler
+ *
+ * @param chatRequest 聊天请求
+ * @param externalHandler 外部响应处理器(可为 null)
+ */
+ void chat(@Valid ChatRequest chatRequest, StreamingChatResponseHandler externalHandler);
+
+}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/image/IImageGenerationService.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/image/IImageGenerationService.java
new file mode 100644
index 00000000..3be0a84f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/image/IImageGenerationService.java
@@ -0,0 +1,20 @@
+package org.ruoyi.common.chat.service.image;
+
+import jakarta.validation.Valid;
+import org.ruoyi.common.chat.entity.image.ImageContext;
+
+/**
+ * 公共文生图接口
+ */
+public interface IImageGenerationService {
+
+ /**
+ * 根据文字生成图片
+ */
+ String generateImage(@Valid ImageContext imageContext);
+
+ /**
+ * 获取服务提供商名称
+ */
+ String getProviderName();
+}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/workFlow/IWorkFlowStarterService.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/workFlow/IWorkFlowStarterService.java
new file mode 100644
index 00000000..4001b67f
--- /dev/null
+++ b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/service/workFlow/IWorkFlowStarterService.java
@@ -0,0 +1,33 @@
+package org.ruoyi.common.chat.service.workFlow;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.ruoyi.common.chat.entity.User;
+import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
+
+import java.util.List;
+
+/**
+ * 工作流启动Service接口
+ *
+ * @author Zengxb
+ * @date 2026-02-24
+ */
+public interface IWorkFlowStarterService {
+
+ /**
+ * 启动工作流
+ * @param user 用户
+ * @param workflowUuid 工作流UUID
+ * @param userInputs 用户输入信息
+ * @return 流式输出结果
+ */
+ SseEmitter streaming(User user, String workflowUuid, List userInputs, Long sessionId);
+
+ /**
+ * 恢复工作流
+ * @param runtimeUuid 运行时UUID
+ * @param userInput 用户输入
+ * @param sseEmitter SSE连接对象
+ */
+ void resumeFlow(String runtimeUuid, String userInput, SseEmitter sseEmitter);
+}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/ConsoleEventSourceListener.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/ConsoleEventSourceListener.java
deleted file mode 100644
index 445f82eb..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/ConsoleEventSourceListener.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package org.ruoyi.common.chat.sse;
-
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-import okhttp3.Response;
-import okhttp3.ResponseBody;
-import okhttp3.sse.EventSource;
-import okhttp3.sse.EventSourceListener;
-
-import java.util.Objects;
-
-/**
- * sse
- *
- * @author https:www.unfbx.com
- * 2023-02-28
- */
-@Slf4j
-public class ConsoleEventSourceListener extends EventSourceListener {
-
- @Override
- public void onOpen(EventSource eventSource, Response response) {
- log.info("OpenAI建立sse连接...");
- }
-
- @Override
- public void onEvent(EventSource eventSource, String id, String type, String data) {
- log.info("OpenAI返回数据:{}", data);
- if ("[DONE]".equals(data)) {
- log.info("OpenAI返回数据结束了");
- }
- }
-
- @Override
- public void onClosed(EventSource eventSource) {
- log.info("OpenAI关闭sse连接...");
- }
-
- @SneakyThrows
- @Override
- public void onFailure(EventSource eventSource, Throwable t, Response response) {
- if (Objects.isNull(response)) {
- log.error("OpenAI sse连接异常:{}", t);
- eventSource.cancel();
- return;
- }
- ResponseBody body = response.body();
- if (Objects.nonNull(body)) {
- log.error("OpenAI sse连接异常data:{},异常:{}", body.string(), t);
- } else {
- log.error("OpenAI sse连接异常data:{},异常:{}", response, t);
- }
- eventSource.cancel();
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/DefaultPluginListener.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/DefaultPluginListener.java
deleted file mode 100644
index b03a170f..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/DefaultPluginListener.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.ruoyi.common.chat.sse;
-
-import lombok.extern.slf4j.Slf4j;
-import okhttp3.sse.EventSourceListener;
-import org.ruoyi.common.chat.entity.chat.ChatCompletion;
-import org.ruoyi.common.chat.openai.OpenAiStreamClient;
-import org.ruoyi.common.chat.openai.plugin.PluginAbstract;
-
-/**
- * 插件开发返回信息收集sse监听器
- *
- * @author https:www.unfbx.com
- * 2023-08-18
- */
-@Slf4j
-public class DefaultPluginListener extends PluginListener {
-
- public DefaultPluginListener(OpenAiStreamClient client, EventSourceListener eventSourceListener, PluginAbstract plugin, ChatCompletion chatCompletion) {
- super(client, eventSourceListener, plugin, chatCompletion);
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/PluginListener.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/PluginListener.java
deleted file mode 100644
index a23522ad..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/sse/PluginListener.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package org.ruoyi.common.chat.sse;
-
-import cn.hutool.json.JSONUtil;
-import lombok.SneakyThrows;
-import lombok.extern.slf4j.Slf4j;
-import okhttp3.Response;
-import okhttp3.ResponseBody;
-import okhttp3.sse.EventSource;
-import okhttp3.sse.EventSourceListener;
-import org.jetbrains.annotations.NotNull;
-import org.ruoyi.common.chat.entity.chat.ChatCompletion;
-import org.ruoyi.common.chat.entity.chat.ChatCompletionResponse;
-import org.ruoyi.common.chat.entity.chat.FunctionCall;
-import org.ruoyi.common.chat.entity.chat.Message;
-import org.ruoyi.common.chat.openai.OpenAiStreamClient;
-import org.ruoyi.common.chat.openai.plugin.PluginAbstract;
-import org.ruoyi.common.chat.openai.plugin.PluginParam;
-
-import java.util.Objects;
-
-/**
- * 插件开发返回信息收集sse监听器
- *
- * @author https:www.unfbx.com
- * 2023-08-18
- */
-@Slf4j
-public abstract class PluginListener extends EventSourceListener {
- /**
- * openAi插件构建的参数
- */
- private String arguments = "";
- private OpenAiStreamClient client;
- private EventSourceListener eventSourceListener;
- private PluginAbstract plugin;
- private ChatCompletion chatCompletion;
- /**
- * 构造方法必备四个元素
- *
- * @param client OpenAiStreamClient
- * @param eventSourceListener 处理真实第二次sse请求的自定义监听
- * @param plugin 插件信息
- * @param chatCompletion 请求参数
- */
- public PluginListener(OpenAiStreamClient client, EventSourceListener eventSourceListener, PluginAbstract plugin, ChatCompletion chatCompletion) {
- this.client = client;
- this.eventSourceListener = eventSourceListener;
- this.plugin = plugin;
- this.chatCompletion = chatCompletion;
- }
-
- /**
- * 获取openAi插件构建的参数
- *
- * @return arguments
- */
- private String getArguments() {
- return this.arguments;
- }
-
- /**
- * sse关闭后处理,第二次请求方法
- */
- public void onClosedAfter() {
- log.debug("构造的方法值:{}", getArguments());
-
- R realFunctionParam = (R) JSONUtil.toBean(getArguments(), plugin.getR());
- T tq = plugin.func(realFunctionParam);
-
- FunctionCall functionCall = FunctionCall.builder()
- .arguments(getArguments())
- .name(plugin.getFunction())
- .build();
- chatCompletion.getMessages().add(Message.builder().role(Message.Role.ASSISTANT).content("function_call").functionCall(functionCall).build());
- chatCompletion.getMessages().add(Message.builder().role(Message.Role.FUNCTION).name(plugin.getFunction()).content(plugin.content(tq)).build());
- //设置第二次,请求的参数
- chatCompletion.setFunctionCall(null);
- chatCompletion.setFunctions(null);
- client.streamChatCompletion(chatCompletion, eventSourceListener);
- }
-
- @SneakyThrows
- @Override
- public final void onEvent(@NotNull EventSource eventSource, String id, String type, String data) {
- log.debug("插件开发返回信息收集sse监听器返回数据:{}", data);
- if ("[DONE]".equals(data)) {
- log.debug("插件开发返回信息收集sse监听器返回数据结束了");
- return;
- }
- ChatCompletionResponse chatCompletionResponse = JSONUtil.toBean(data, ChatCompletionResponse.class);
- if (Objects.nonNull(chatCompletionResponse.getChoices().get(0).getDelta().getFunctionCall())) {
- this.arguments += chatCompletionResponse.getChoices().get(0).getDelta().getFunctionCall().getArguments();
- }
- }
-
- @Override
- public final void onClosed(EventSource eventSource) {
- log.debug("插件开发返回信息收集sse监听器关闭连接...");
- this.onClosedAfter();
- }
-
- @Override
- public void onOpen(EventSource eventSource, Response response) {
- log.debug("插件开发返回信息收集sse监听器建立连接...");
- }
-
- @SneakyThrows
- @Override
- public void onFailure(EventSource eventSource, Throwable t, Response response) {
- if (Objects.isNull(response)) {
- log.error("插件开发返回信息收集sse监听器,连接异常:{}", t);
- eventSource.cancel();
- return;
- }
- ResponseBody body = response.body();
- if (Objects.nonNull(body)) {
- log.error("插件开发返回信息收集sse监听器,连接异常data:{},异常:{}", body.string(), t);
- } else {
- log.error("插件开发返回信息收集sse监听器,连接异常data:{},异常:{}", response, t);
- }
- eventSource.cancel();
- }
-}
diff --git a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/utils/TikTokensUtil.java b/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/utils/TikTokensUtil.java
deleted file mode 100644
index e71e4e63..00000000
--- a/ruoyi-common/ruoyi-common-chat/src/main/java/org/ruoyi/common/chat/utils/TikTokensUtil.java
+++ /dev/null
@@ -1,237 +0,0 @@
-package org.ruoyi.common.chat.utils;
-
-import cn.hutool.core.util.StrUtil;
-import com.knuddels.jtokkit.Encodings;
-import com.knuddels.jtokkit.api.Encoding;
-import com.knuddels.jtokkit.api.EncodingRegistry;
-import com.knuddels.jtokkit.api.EncodingType;
-import com.knuddels.jtokkit.api.ModelType;
-import lombok.extern.slf4j.Slf4j;
-import org.jetbrains.annotations.NotNull;
-import org.ruoyi.common.chat.entity.chat.ChatCompletion;
-import org.ruoyi.common.chat.entity.chat.FunctionCall;
-import org.ruoyi.common.chat.entity.chat.Message;
-
-import java.util.*;
-
-/**
- * token计算工具类
- *
- * @author https:www.unfbx.com
- * @since 2023-04-04
- */
-@Slf4j
-public class TikTokensUtil {
- /**
- * 模型名称对应Encoding
- */
- private static final Map modelMap = new HashMap<>();
- /**
- * registry实例
- */
- private static final EncodingRegistry registry = Encodings.newDefaultEncodingRegistry();
-
- static {
- for (ModelType modelType : ModelType.values()) {
- modelMap.put(modelType.getName(), registry.getEncodingForModel(modelType));
- }
- modelMap.put(ChatCompletion.Model.GPT_3_5_TURBO_0613.getName(), registry.getEncodingForModel(ModelType.GPT_3_5_TURBO));
- modelMap.put(ChatCompletion.Model.GPT_3_5_TURBO_16K.getName(), registry.getEncodingForModel(ModelType.GPT_3_5_TURBO));
- modelMap.put(ChatCompletion.Model.GPT_3_5_TURBO_16K_0613.getName(), registry.getEncodingForModel(ModelType.GPT_3_5_TURBO));
- modelMap.put(ChatCompletion.Model.GPT_3_5_TURBO_0125.getName(), registry.getEncodingForModel(ModelType.GPT_3_5_TURBO));
- modelMap.put(ChatCompletion.Model.GPT_4_32K.getName(), registry.getEncodingForModel(ModelType.GPT_4));
- modelMap.put(ChatCompletion.Model.GPT_4_0613.getName(), registry.getEncodingForModel(ModelType.GPT_4));
- modelMap.put(ChatCompletion.Model.GPT_4_32K_0613.getName(), registry.getEncodingForModel(ModelType.GPT_4));
- modelMap.put(ChatCompletion.Model.GPT_4_1106_PREVIEW.getName(), registry.getEncodingForModel(ModelType.GPT_4));
- modelMap.put(ChatCompletion.Model.GPT_4_VISION_PREVIEW.getName(), registry.getEncodingForModel(ModelType.GPT_4));
- modelMap.put(ChatCompletion.Model.GPT_4_0125_PREVIEW.getName(), registry.getEncodingForModel(ModelType.GPT_4));
- }
-
- /**
- * 通过Encoding和text获取编码数组
- *
- * @param enc Encoding类型
- * @param text 文本信息
- * @return 编码数组
- */
- public static List encode(@NotNull Encoding enc, String text) {
- return StrUtil.isBlank(text) ? new ArrayList<>() : enc.encode(text);
- }
-
- /**
- * 通过Encoding计算text信息的tokens
- *
- * @param enc Encoding类型
- * @param text 文本信息
- * @return tokens数量
- */
- public static int tokens(@NotNull Encoding enc, String text) {
- return encode(enc, text).size();
- }
-
-
- /**
- * 通过Encoding和encoded数组反推text信息
- *
- * @param enc Encoding
- * @param encoded 编码数组
- * @return 编码数组对应的文本信息
- */
- public static String decode(@NotNull Encoding enc, @NotNull List encoded) {
- return enc.decode(encoded);
- }
-
- /**
- * 获取一个Encoding对象,通过Encoding类型
- *
- * @param encodingType encodingType
- * @return Encoding
- */
- public static Encoding getEncoding(@NotNull EncodingType encodingType) {
- return registry.getEncoding(encodingType);
- }
-
- /**
- * 获取encode的编码数组
- *
- * @param text 文本信息
- * @return 编码数组
- */
- public static List