修改为OpenAI规范
去除了单次对话 配置文件格式修改 待测试
This commit is contained in:
@@ -20,6 +20,7 @@ dependencies{
|
||||
implementation ("org.apache.logging.log4j:log4j-api:2.23.1")
|
||||
implementation("top.mrxiaom.mirai:overflow-core-api:1.0.0.519-0d68f08-SNAPSHOT")
|
||||
implementation ("com.alibaba:fastjson:1.2.73")
|
||||
implementation ("org.projectlombok:lombok:1.18.36")
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -6,16 +6,15 @@ import net.mamoe.mirai.event.GlobalEventChannel;
|
||||
import net.mamoe.mirai.event.events.FriendMessageEvent;
|
||||
import net.mamoe.mirai.event.events.GroupMessageEvent;
|
||||
import net.mamoe.mirai.event.events.MessageEvent;
|
||||
import plugin.constant.ChatConstant;
|
||||
import plugin.constant.Constant;
|
||||
import plugin.chat.constant.Constant;
|
||||
import plugin.config.Config;
|
||||
import plugin.config.CustomCommandTemplate;
|
||||
import plugin.listener.FriendMessageListener;
|
||||
import plugin.listener.GroupMessageListener;
|
||||
import plugin.listener.OwnerMessageListener;
|
||||
import plugin.pojo.Config;
|
||||
import plugin.utils.ConfigUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -36,28 +35,30 @@ public final class App extends JavaPlugin {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
String owner, bot;
|
||||
HashMap<String, String> customCommands;
|
||||
ArrayList<CustomCommandTemplate> customCommands;
|
||||
List<Long> blacklist;
|
||||
//加载配置
|
||||
try {
|
||||
ConfigUtil.load();
|
||||
Thread.sleep(1500);
|
||||
Config config = ConfigUtil.getConfig();
|
||||
Config config = Config.ConfigLoader.load();
|
||||
App.class.getClassLoader().loadClass("plugin.utils.OCRUtil");
|
||||
App.class.getClassLoader().loadClass("plugin.utils.ChatUtil");
|
||||
|
||||
owner = config.getOwner().substring(1);
|
||||
bot = config.getBot().substring(1);
|
||||
customCommands = config.getCustomCommands();
|
||||
customCommands = config.getCustomCommandTemplates();
|
||||
blacklist = config.getBlacklist();
|
||||
} catch (IOException | ClassNotFoundException | InterruptedException e) {
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
getLogger().info("ChatAI-InGroup loaded!");
|
||||
getLogger().info("ChatAI loaded!");
|
||||
|
||||
//群聊监听器
|
||||
GlobalEventChannel.INSTANCE.filterIsInstance(GroupMessageEvent.class)
|
||||
.filter(event -> {
|
||||
String msg = event.getMessage().contentToString();
|
||||
long groupId = event.getGroup().getId();
|
||||
return ((msg.startsWith(Constant.Order.PREFIX_ONECE) && msg.length() != 1) || msg.startsWith(Constant.Order.PREFIX_DEFAULT + bot) || customCommands.containsKey(msg.split(Constant.Order.SPLIT_BLANK)[0] + Constant.Order.SPLIT_BLANK)) && !blacklist.contains(groupId);
|
||||
String prefix = msg.split(Constant.Order.SPLIT_BLANK)[0];
|
||||
return (msg.startsWith(Constant.Order.PREFIX_DEFAULT + bot) || checkCommandExist(prefix,customCommands)) && !blacklist.contains(groupId);
|
||||
}).registerListenerHost(new GroupMessageListener());
|
||||
|
||||
//私聊监听器
|
||||
@@ -65,7 +66,10 @@ public final class App extends JavaPlugin {
|
||||
.filter(event -> {
|
||||
String msg = event.getMessage().contentToString();
|
||||
String sender = String.valueOf(event.getFriend().getId());
|
||||
return !(msg.startsWith(Constant.Order.PREFIX_SET) && sender.equals(owner)) && !msg.equals(Constant.Order.MSG_HELP);
|
||||
String prefix = msg.split(Constant.Order.SPLIT_BLANK)[0];
|
||||
// return !(msg.startsWith(Constant.Order.PREFIX_SET) && sender.equals(owner)) && !msg.equals(Constant.Order.MSG_HELP);
|
||||
return checkCommandExist(prefix,customCommands) //包含指令前缀
|
||||
|| !((msg.startsWith(Constant.Order.PREFIX_SET) && sender.equals(owner)) || msg.startsWith(Constant.Order.PREFIX_CUSTOM)); //如果不包含指令前缀,则不能以设置指令、"/"开头
|
||||
}).registerListenerHost(new FriendMessageListener());
|
||||
|
||||
//所有者监听
|
||||
@@ -97,23 +101,39 @@ public final class App extends JavaPlugin {
|
||||
$ clearAll (仅限群聊)
|
||||
$ shutUp (仅限群聊)
|
||||
$ speak (仅限群聊)
|
||||
$ 添加预设|<预设指令>|<模型名称/null>|<预设内容>
|
||||
$ 切换模型|<预设指令>|<模型名称>
|
||||
$ 添加预设|<预设指令>|<模型模板ID>|<模型名称>|<预设内容>
|
||||
$ 切换模型|<预设指令>|<模型模板ID>|<模型名称>
|
||||
$ 更改预设|<预设指令>|<预设内容>
|
||||
$ 删除预设|<预设指令>
|
||||
|
||||
例:
|
||||
$ 添加预设|/c|glm-4-flash|你是一只猫娘...
|
||||
$ 添加预设|/c|<模型模板ID>|glm-4-flash|你是一只猫娘...
|
||||
|
||||
"""};
|
||||
helpMsg[0] += "————<预设列表>————";
|
||||
customCommands.forEach((s, s2) -> helpMsg[0] += "\r\n\r\n" + s + "-> \r\n" + s2);
|
||||
for (CustomCommandTemplate customCommand : customCommands) {
|
||||
helpMsg[0] += "\r\n\r\n"+customCommand.toString();
|
||||
}
|
||||
helpMsg[0] += "\r\n";
|
||||
helpMsg[0] += "————<模型列表>————";
|
||||
for (int i = 0; i < Config.ConfigLoader.getConfig().getModelConfigTemplates().size(); i++) {
|
||||
helpMsg[0] += "\r\n\r\n"+"TemplateIndex: "+i+"\r\n"+Config.ConfigLoader.getConfig().getModelConfigTemplates().get(i).toString();
|
||||
}
|
||||
event.getSubject().sendMessage(helpMsg[0]);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private boolean checkCommandExist(String prefix, ArrayList<CustomCommandTemplate> customCommands) {
|
||||
for (CustomCommandTemplate customCommand : customCommands) {
|
||||
if (customCommand.getCommand().equals(prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
getLogger().info("ChatAI-InGroup disabled!");
|
||||
|
||||
108
src/main/java/plugin/chat/ChatClient.java
Normal file
108
src/main/java/plugin/chat/ChatClient.java
Normal file
@@ -0,0 +1,108 @@
|
||||
package plugin.chat;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import plugin.chat.constant.Constant;
|
||||
import plugin.chat.pojo.ChatBody;
|
||||
import plugin.chat.pojo.ChatResponse;
|
||||
import plugin.chat.pojo.Message;
|
||||
import plugin.chat.pojo.PrimaryChatResponse;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ChatClient {
|
||||
private String clientId;
|
||||
|
||||
private String url;
|
||||
private String apikey;
|
||||
private String model;
|
||||
|
||||
private int top_p;
|
||||
private int temperature;
|
||||
private int max_tokens;
|
||||
|
||||
private List<Message> messages = new ArrayList<>();
|
||||
|
||||
public ChatClient(String clientId,String url,String apikey,String model){
|
||||
this(url, apikey,model);
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public ChatClient(String clientId,String url, String apikey,String model, int top_p, int temperature, int max_tokens) {
|
||||
this(url, apikey,model, top_p, temperature, max_tokens);
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public ChatClient(String url, String apikey,String model, int top_p, int temperature, int max_tokens) {
|
||||
this(url, apikey,model);
|
||||
this.top_p = top_p;
|
||||
this.temperature = temperature;
|
||||
this.max_tokens = max_tokens;
|
||||
}
|
||||
|
||||
public ChatClient(String url,String apikey,String model){
|
||||
this.url = url;
|
||||
this.apikey = apikey;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
public void setPromotion(String promotion){
|
||||
Message message = Message.builder()
|
||||
.role(Constant.Character.SYSTEM)
|
||||
.content(promotion)
|
||||
.build();
|
||||
messages.add(0,message);
|
||||
}
|
||||
|
||||
public ChatResponse runChat(String content){
|
||||
HttpRequest request = HttpRequest.post(url+"/chat/completions");
|
||||
request.header("Content-Type", "application/json");
|
||||
request.header("Authorization", "Bearer " + apikey);
|
||||
|
||||
Message message = new Message(Constant.Character.USER,content);
|
||||
messages.add(message);
|
||||
ChatBody body;
|
||||
if (top_p > 0) {
|
||||
body = ChatBody.builder()
|
||||
.model(model)
|
||||
.messages(messages)
|
||||
.top_p(top_p)
|
||||
.temperature(temperature)
|
||||
.max_tokens(max_tokens)
|
||||
.build();
|
||||
}else {
|
||||
body = ChatBody.builder()
|
||||
.model(model)
|
||||
.messages(messages)
|
||||
.build();
|
||||
}
|
||||
|
||||
HttpResponse response = request.body(JSONUtil.toJsonStr(body)).execute();
|
||||
ChatResponse finalResponse;
|
||||
try {
|
||||
PrimaryChatResponse primaryChatResponse = JSONUtil.toBean(response.body(), PrimaryChatResponse.class);
|
||||
finalResponse = ChatResponse.builder()
|
||||
.type(Constant.Response.SUCCESS)
|
||||
.message(primaryChatResponse.getChoices().get(0).getMessage().getContent())
|
||||
.usageBean(primaryChatResponse.getUsage())
|
||||
.build();
|
||||
messages.add(new Message(Constant.Character.SYSTEM, finalResponse.getMessage()));
|
||||
}catch (Exception e){
|
||||
finalResponse = ChatResponse.builder()
|
||||
.type(Constant.Response.ERROR)
|
||||
.message(response.getStatus()+": "+response.body())
|
||||
.build();
|
||||
}
|
||||
response.close();
|
||||
return finalResponse;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package plugin.constant;
|
||||
package plugin.chat.constant;
|
||||
|
||||
public class Constant {
|
||||
public static class Character{
|
||||
@@ -42,9 +42,21 @@ public class Constant {
|
||||
|
||||
public static final String DEFAULT = "default";
|
||||
public static final String NULL = "null";
|
||||
public static final String MSG_STATUS = "/status";
|
||||
public static final String PREFIX_CUSTOM = "/";
|
||||
public static final String MODEL_CHANGE = ".*\\|.*";
|
||||
}
|
||||
|
||||
public static class StatusCode {
|
||||
public static final int OK = "200";
|
||||
public static final int OK = 200;
|
||||
}
|
||||
|
||||
public static class Response {
|
||||
public static final String SUCCESS = "success";
|
||||
public static final String ERROR = "error";
|
||||
}
|
||||
|
||||
public static class Path {
|
||||
public static final String CONFIG_PATH = "./config/ChatAI/config.yaml";
|
||||
}
|
||||
}
|
||||
25
src/main/java/plugin/chat/pojo/ChatBody.java
Normal file
25
src/main/java/plugin/chat/pojo/ChatBody.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package plugin.chat.pojo;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Builder
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ChatBody {
|
||||
@NonNull
|
||||
private String model;
|
||||
@NonNull
|
||||
private List<Message> messages;
|
||||
@Builder.Default
|
||||
private int temperature = 1;
|
||||
@Builder.Default
|
||||
private int top_p = 1;
|
||||
private boolean stream;
|
||||
@Builder.Default
|
||||
private int max_tokens = 1024;
|
||||
private int presence_penalty;
|
||||
private int frequency_penalty;
|
||||
}
|
||||
16
src/main/java/plugin/chat/pojo/ChatResponse.java
Normal file
16
src/main/java/plugin/chat/pojo/ChatResponse.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package plugin.chat.pojo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ChatResponse {
|
||||
private String type;
|
||||
private String message;
|
||||
private PrimaryChatResponse.UsageBean usageBean;
|
||||
}
|
||||
14
src/main/java/plugin/chat/pojo/Message.java
Normal file
14
src/main/java/plugin/chat/pojo/Message.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package plugin.chat.pojo;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Builder
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Message {
|
||||
@NonNull
|
||||
private String role;
|
||||
@NonNull
|
||||
private String content;
|
||||
}
|
||||
111
src/main/java/plugin/chat/pojo/PrimaryChatResponse.java
Normal file
111
src/main/java/plugin/chat/pojo/PrimaryChatResponse.java
Normal file
@@ -0,0 +1,111 @@
|
||||
package plugin.chat.pojo;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class PrimaryChatResponse {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private String id;
|
||||
/**
|
||||
* object
|
||||
*/
|
||||
private String object;
|
||||
/**
|
||||
* created
|
||||
*/
|
||||
private int created;
|
||||
/**
|
||||
* model
|
||||
*/
|
||||
private String model;
|
||||
/**
|
||||
* choices
|
||||
*/
|
||||
private List<ChoicesBean> choices;
|
||||
/**
|
||||
* usage
|
||||
*/
|
||||
private UsageBean usage;
|
||||
/**
|
||||
* system_fingerprint
|
||||
*/
|
||||
private String system_fingerprint;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public static class UsageBean {
|
||||
/**
|
||||
* prompt_tokens
|
||||
*/
|
||||
private int prompt_tokens;
|
||||
/**
|
||||
* completion_tokens
|
||||
*/
|
||||
private int completion_tokens;
|
||||
/**
|
||||
* total_tokens
|
||||
*/
|
||||
private int total_tokens;
|
||||
/**
|
||||
* prompt_cache_hit_tokens
|
||||
*/
|
||||
private int prompt_cache_hit_tokens;
|
||||
/**
|
||||
* prompt_cache_miss_tokens
|
||||
*/
|
||||
private int prompt_cache_miss_tokens;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UsageBean{" +
|
||||
"prompt_tokens=" + prompt_tokens +
|
||||
", completion_tokens=" + completion_tokens +
|
||||
", total_tokens=" + total_tokens +
|
||||
", prompt_cache_hit_tokens=" + prompt_cache_hit_tokens +
|
||||
", prompt_cache_miss_tokens=" + prompt_cache_miss_tokens +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public static class ChoicesBean {
|
||||
/**
|
||||
* index
|
||||
*/
|
||||
private int index;
|
||||
/**
|
||||
* message
|
||||
*/
|
||||
private MessageBean message;
|
||||
/**
|
||||
* logprobs
|
||||
*/
|
||||
private Object logprobs;
|
||||
/**
|
||||
* finish_reason
|
||||
*/
|
||||
private String finish_reason;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public static class MessageBean {
|
||||
/**
|
||||
* role
|
||||
*/
|
||||
private String role;
|
||||
/**
|
||||
* content
|
||||
*/
|
||||
private String content;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
23
src/main/java/plugin/config/AliOCRConfig.java
Normal file
23
src/main/java/plugin/config/AliOCRConfig.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package plugin.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class AliOCRConfig {
|
||||
private String accessKeyId;
|
||||
private String accessKeySecret;
|
||||
|
||||
public AliOCRConfig() {
|
||||
}
|
||||
|
||||
public AliOCRConfig(String accessKeyId, String accessKeySecret) {
|
||||
this.accessKeyId = accessKeyId;
|
||||
this.accessKeySecret = accessKeySecret;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "AliOCRConfig{accessKeyId = " + accessKeyId + ", accessKeySecret = " + accessKeySecret + "}";
|
||||
}
|
||||
}
|
||||
202
src/main/java/plugin/config/Config.java
Normal file
202
src/main/java/plugin/config/Config.java
Normal file
@@ -0,0 +1,202 @@
|
||||
package plugin.config;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import plugin.chat.constant.Constant;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@Slf4j
|
||||
public class Config {
|
||||
|
||||
/**
|
||||
* owner QQ
|
||||
*/
|
||||
private String owner;
|
||||
|
||||
/**
|
||||
* bot QQ
|
||||
*/
|
||||
private String bot;
|
||||
|
||||
/**
|
||||
* 对话记录过期时间
|
||||
*/
|
||||
private String timeout;
|
||||
|
||||
/**
|
||||
* 检测对话记录间隔
|
||||
*/
|
||||
private String timeCheck;
|
||||
|
||||
/**
|
||||
* 群聊黑名单
|
||||
*/
|
||||
private List<Long> blacklist;
|
||||
|
||||
/**
|
||||
* 阿里OCR配置
|
||||
*/
|
||||
private AliOCRConfig ocrConfig;
|
||||
|
||||
/**
|
||||
* 模板配置
|
||||
*/
|
||||
private List<ModelConfigTemplate> modelConfigTemplates;
|
||||
|
||||
/**
|
||||
* 预设配置
|
||||
*/
|
||||
private ArrayList<CustomCommandTemplate> customCommandTemplates;
|
||||
|
||||
private Config() {
|
||||
}
|
||||
|
||||
public static class ConfigLoader {
|
||||
private static final Yaml yaml;
|
||||
@Getter
|
||||
private static Config config;
|
||||
|
||||
static {
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
yaml = new Yaml(options);
|
||||
}
|
||||
|
||||
public static Config load() throws IOException {
|
||||
Config config;
|
||||
DumperOptions dumperOptions = new DumperOptions();
|
||||
dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
Yaml yaml = new Yaml(dumperOptions);
|
||||
File file = new File(Constant.Path.CONFIG_PATH);
|
||||
if (file.exists()) {
|
||||
FileInputStream fileInputStream = new FileInputStream(Constant.Path.CONFIG_PATH);
|
||||
config = BeanUtil.toBean(yaml.load(fileInputStream), Config.class);
|
||||
fileInputStream.close();
|
||||
log.info("load config success");
|
||||
} else {
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
config = new Config();
|
||||
//基础配置
|
||||
config.setOwner("your_bot_owner_qq_number(e.g. Q1145141919810)");
|
||||
config.setBot("your_bot_qq_number(e.g. Q1145141919810)");
|
||||
config.setTimeout("M3600000");
|
||||
config.setTimeCheck("M60000");
|
||||
ArrayList<Long> blacklist = new ArrayList<>();
|
||||
blacklist.add(123456789L);
|
||||
blacklist.add(987654321L);
|
||||
config.setBlacklist(blacklist);
|
||||
|
||||
//OCR配置
|
||||
config.setOcrConfig(new AliOCRConfig("ocr_accessKeyId", "ocr_accessKeySecret"));
|
||||
|
||||
//模型模板
|
||||
List<ModelConfigTemplate> templateList = new ArrayList<>();
|
||||
templateList.add(new ModelConfigTemplate("zhipu", "https://open.bigmodel.cn/api/paas/v4", "zhipu_apikey"));
|
||||
templateList.add(new ModelConfigTemplate("deepseek", "https://api.deepseek.com/v1", "deepseek_apikey"));
|
||||
config.setModelConfigTemplates(templateList);
|
||||
|
||||
//自定义预设
|
||||
ArrayList<CustomCommandTemplate> customCommands = new ArrayList<>();
|
||||
customCommands.add(new CustomCommandTemplate("default", 0, "glm-4-flash", "null"));
|
||||
customCommands.add(new CustomCommandTemplate("/c", 0, "glm-4-flash", "你是一位智能编程助手,你会为用户回答关于编程、代码、计算机方面的任何问题,并提供格式规范、可以执行、准确安全的代码,并在必要时提供详细的解释。 请用中文回答。"));
|
||||
config.setCustomCommandTemplates(customCommands);
|
||||
dump();
|
||||
log.warn("配置文件创建成功,请关闭后进行配置");
|
||||
System.exit(0);
|
||||
}
|
||||
ConfigLoader.config = config;
|
||||
return config;
|
||||
}
|
||||
|
||||
private static void dump() throws IOException {
|
||||
FileWriter fileWriter = new FileWriter(Constant.Path.CONFIG_PATH);
|
||||
yaml.dump(BeanUtil.beanToMap(config), fileWriter);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭当前群聊发言
|
||||
*
|
||||
* @param id 群聊id
|
||||
*/
|
||||
public static String shutUp(long id) {
|
||||
config.getBlacklist().add(id);
|
||||
return "ChatAI-InGroup 已关闭";
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启当前群聊发言
|
||||
*
|
||||
* @param id 群聊id
|
||||
*/
|
||||
public static String speak(long id) {
|
||||
config.getBlacklist().remove(id);
|
||||
return "ChatAI-InGroup 已开启";
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加预设
|
||||
*
|
||||
* @param command
|
||||
* @param modelTemplateIndex
|
||||
* @param customModel
|
||||
* @param customPromotion
|
||||
* @return
|
||||
* @throws IOException
|
||||
*/
|
||||
public static String addCustom(String command, int modelTemplateIndex, String customModel, String customPromotion) throws IOException {
|
||||
ArrayList<CustomCommandTemplate> customCommands = config.getCustomCommandTemplates();
|
||||
synchronized (customCommands) {
|
||||
for (CustomCommandTemplate customCommand : customCommands) {
|
||||
if (customCommand.getCommand().equals(command)) {
|
||||
return "当前指令已存在!\r\n" + customCommand;
|
||||
}
|
||||
}
|
||||
CustomCommandTemplate customCommand = new CustomCommandTemplate(command, modelTemplateIndex, customModel, customPromotion);
|
||||
customCommands.add(customCommand);
|
||||
dump();
|
||||
return "预设添加完毕!\r\n" + customCommand;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除预设
|
||||
*
|
||||
* @param command
|
||||
* @return
|
||||
*/
|
||||
public static String removeCustom(String command) {
|
||||
if (command.equals(Constant.Order.DEFAULT)) {
|
||||
return "该预设不可删除!";
|
||||
}
|
||||
ArrayList<CustomCommandTemplate> customCommands = config.getCustomCommandTemplates();
|
||||
int index = -1;
|
||||
for (int i = 0; i < customCommands.size(); i++) {
|
||||
if (customCommands.get(i).getCommand().equals(command)) {
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
if (index == -1) {
|
||||
return "该预设不存在!";
|
||||
}
|
||||
return "预设删除完毕" + customCommands.remove(index);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
25
src/main/java/plugin/config/CustomCommandTemplate.java
Normal file
25
src/main/java/plugin/config/CustomCommandTemplate.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package plugin.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class CustomCommandTemplate {
|
||||
private String command;
|
||||
private int modelTemplateIndex;
|
||||
private String customModel;
|
||||
private String customPromotion;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "command: " + command + "\r\n" +
|
||||
"modelTemplateIndex: " + modelTemplateIndex + "\r\n" +
|
||||
"customModel: " + customModel + "\r\n" +
|
||||
"customPromotion: " + customPromotion + "\r\n";
|
||||
}
|
||||
}
|
||||
14
src/main/java/plugin/config/ModelConfigTemplate.java
Normal file
14
src/main/java/plugin/config/ModelConfigTemplate.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package plugin.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ModelConfigTemplate {
|
||||
private String template_name;
|
||||
private String base_url;
|
||||
private String apikey;
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package plugin.constant;
|
||||
|
||||
/**
|
||||
* @author SLHAF
|
||||
*/
|
||||
public class AIConstant {
|
||||
/**
|
||||
* 当前模型
|
||||
*/
|
||||
public static final String CURRENT_MODEL = "当前模型";
|
||||
|
||||
|
||||
/**
|
||||
* 错误结果
|
||||
*/
|
||||
public static final String ERROR = "ERROR";
|
||||
public static final int NORMAL_CODE = 200;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
package plugin.constant;
|
||||
|
||||
/**
|
||||
* @author SLHAF
|
||||
*/
|
||||
public class ChatConstant {
|
||||
|
||||
/**
|
||||
* 匹配含有图片信息的消息
|
||||
*/
|
||||
public static final String MATCH_MESSAGE = ".*[mirai:image:(https?://[\\w./?&=]+)].*";
|
||||
|
||||
/**
|
||||
* 匹配图片信息
|
||||
*/
|
||||
public static final String MATCH_IMAGE = "\\[mirai:image:(.*?)]";
|
||||
|
||||
/**
|
||||
* 单次对话标志
|
||||
*/
|
||||
public static final String ONCE_MESSAGE_START = ".";
|
||||
|
||||
/**
|
||||
* 普通对话标志
|
||||
*/
|
||||
public static final String DEFAULT_MESSAGE_START = "@";
|
||||
|
||||
/**
|
||||
* 分隔符(空格)
|
||||
*/
|
||||
public static final String BLANK = " ";
|
||||
|
||||
public static final String SET = "$ ";
|
||||
|
||||
/**
|
||||
* 清理消息
|
||||
*/
|
||||
public static final String CLEAR = "clear";
|
||||
|
||||
/**
|
||||
* 当前模型
|
||||
*/
|
||||
public static final String CURRENT_MODEL = "当前模型";
|
||||
public static final String SPLIT = "|";
|
||||
public static final String HELP = "/chatHelp";
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package plugin.constant;
|
||||
|
||||
/**
|
||||
* @author SLHAF
|
||||
*/
|
||||
public class ConfigConstant {
|
||||
|
||||
public static final String DEFAULT = "default";
|
||||
|
||||
public static final String NULL = "null";
|
||||
|
||||
public static final String CUSTOM_SPLIT = "\\|";
|
||||
public static final String ADD_CUSTOM = "/[a-zA-Z]+\\|.*\\|.*";
|
||||
public static final String MODEL_CHANGE = ".*\\|.*";
|
||||
}
|
||||
@@ -6,16 +6,10 @@ public enum MethodsConstant {
|
||||
* 正常对话
|
||||
*/
|
||||
NORMAL,
|
||||
|
||||
/**
|
||||
* 单次对话
|
||||
*/
|
||||
ONCE,
|
||||
/**
|
||||
* 预设对话
|
||||
*/
|
||||
CUSTOM,
|
||||
|
||||
/**
|
||||
* 未匹配
|
||||
*/
|
||||
|
||||
@@ -3,10 +3,9 @@ package plugin.listener;
|
||||
import net.mamoe.mirai.event.EventHandler;
|
||||
import net.mamoe.mirai.event.SimpleListenerHost;
|
||||
import net.mamoe.mirai.event.events.FriendMessageEvent;
|
||||
import plugin.constant.ChatConstant;
|
||||
import plugin.constant.MethodsConstant;
|
||||
import plugin.utils.AIUtil;
|
||||
import plugin.utils.ConfigUtil;
|
||||
import plugin.chat.constant.Constant;
|
||||
import plugin.utils.ChatUtil;
|
||||
import plugin.utils.OCRUtil;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -22,9 +21,9 @@ public class FriendMessageListener extends SimpleListenerHost {
|
||||
String content = event.getMessage().contentToString();
|
||||
String miraiCode = event.getMessage().serializeToMiraiCode();
|
||||
String url = null;
|
||||
String chatCommand = null;
|
||||
if (miraiCode.matches(ChatConstant.MATCH_MESSAGE)) {
|
||||
String regex = ChatConstant.MATCH_IMAGE;
|
||||
String chatCommand;
|
||||
if (miraiCode.matches(Constant.Regex.MATCH_MESSAGE)) {
|
||||
String regex = Constant.Regex.MATCH_IMAGE;
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
|
||||
// 创建Matcher对象
|
||||
@@ -36,25 +35,26 @@ public class FriendMessageListener extends SimpleListenerHost {
|
||||
url = matcher.group(1);
|
||||
}
|
||||
}
|
||||
MethodsConstant method = MethodsConstant.NORMAL;
|
||||
if (OCRUtil.isSupported && url != null) {
|
||||
content = content + "```content\r\n" + OCRUtil.getContentOfImage(url) + "\r\n```";
|
||||
}
|
||||
|
||||
//处理消息头
|
||||
if (ConfigUtil.getConfig().getCustomCommands().containsKey(content.split(ChatConstant.BLANK)[0]+ChatConstant.BLANK)) {
|
||||
String[] split = content.split(ChatConstant.BLANK);
|
||||
chatCommand = split[0] + ChatConstant.BLANK;
|
||||
method = MethodsConstant.CUSTOM;
|
||||
content = content.substring((content.split(ChatConstant.BLANK)[0]+ChatConstant.BLANK).length());
|
||||
} else if (content.startsWith(ChatConstant.ONCE_MESSAGE_START)) {
|
||||
content = content.substring(1);
|
||||
method = MethodsConstant.ONCE;
|
||||
if (content.startsWith(Constant.Order.PREFIX_CUSTOM)) {
|
||||
chatCommand = content.split(Constant.Order.SPLIT_BLANK)[0];
|
||||
content = content.substring(chatCommand.length() + 1);
|
||||
} else {
|
||||
chatCommand = Constant.Order.DEFAULT;
|
||||
}
|
||||
//发送请求并获取回应
|
||||
String response = switch (method) {
|
||||
case CUSTOM -> AIUtil.customChat(Long.valueOf(id), content, url, chatCommand);
|
||||
case ONCE -> AIUtil.chatOnce(content, url);
|
||||
case NORMAL -> AIUtil.defaultChat(Long.valueOf(id), content, url);
|
||||
default -> "ERROR!";
|
||||
};
|
||||
String response;
|
||||
if (content.equals(Constant.Order.MSG_CLEAR)){
|
||||
//检测是否为清除指令
|
||||
response = ChatUtil.removeClient(id, chatCommand);
|
||||
}else {
|
||||
//发送请求并获取回应
|
||||
response = ChatUtil.chat(id, content, chatCommand);
|
||||
}
|
||||
event.getFriend().sendMessage(response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,47 +1,36 @@
|
||||
package plugin.listener;
|
||||
|
||||
import kotlin.coroutines.CoroutineContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.mamoe.mirai.event.EventHandler;
|
||||
import net.mamoe.mirai.event.SimpleListenerHost;
|
||||
import net.mamoe.mirai.event.events.GroupMessageEvent;
|
||||
import net.mamoe.mirai.message.data.At;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import plugin.constant.ChatConstant;
|
||||
import plugin.constant.Constant;
|
||||
import plugin.constant.MethodsConstant;
|
||||
import plugin.pojo.Config;
|
||||
import plugin.utils.AIUtil;
|
||||
import plugin.utils.ConfigUtil;
|
||||
import plugin.chat.constant.Constant;
|
||||
import plugin.utils.ChatUtil;
|
||||
import plugin.utils.OCRUtil;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static plugin.utils.ConfigUtil.logger;
|
||||
|
||||
|
||||
/**
|
||||
* @author SLHAF
|
||||
*/
|
||||
@Slf4j
|
||||
public class GroupMessageListener extends SimpleListenerHost {
|
||||
|
||||
@Override
|
||||
public void handleException(@NotNull CoroutineContext context, @NotNull Throwable exception) {
|
||||
logger.warning(exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* 负责提取链接、获取消息内容(去除指令头),提取指令、提取发送者id
|
||||
* @param event 接收群聊消息
|
||||
*/
|
||||
@EventHandler
|
||||
public void groupMessageHandler(GroupMessageEvent event) {
|
||||
Config config = ConfigUtil.getConfig();
|
||||
//处理消息
|
||||
String id = String.valueOf(event.getSender().getId());
|
||||
String content = event.getMessage().contentToString();
|
||||
String miraiCode = event.getMessage().serializeToMiraiCode();
|
||||
String url = null;
|
||||
String chatCommand = null;
|
||||
String chatCommand;
|
||||
if (miraiCode.matches(Constant.Regex.MATCH_MESSAGE)) {
|
||||
Pattern pattern = Pattern.compile(Constant.Regex.MATCH_IMAGE);
|
||||
|
||||
@@ -54,36 +43,33 @@ public class GroupMessageListener extends SimpleListenerHost {
|
||||
url = matcher.group(1);
|
||||
}
|
||||
}
|
||||
|
||||
MethodsConstant method = MethodsConstant.NONE;
|
||||
if (OCRUtil.isSupported && url != null) {
|
||||
content = content + "```content\r\n" + OCRUtil.getContentOfImage(url) + "\r\n```";
|
||||
}
|
||||
|
||||
//消息头处理
|
||||
if (content.startsWith(Constant.Order.PREFIX_ONECE)) {
|
||||
//单次对话
|
||||
content = content.substring(1);
|
||||
method = MethodsConstant.ONCE;
|
||||
} else if (content.startsWith(Constant.Order.PREFIX_DEFAULT + event.getBot().getId())) {
|
||||
if (content.startsWith(Constant.Order.PREFIX_DEFAULT + event.getBot().getId())) {
|
||||
//默认对话
|
||||
content = content.substring((Constant.Order.PREFIX_DEFAULT + event.getBot().getId()).length());
|
||||
method = MethodsConstant.NORMAL;
|
||||
} else if (config.getCustomCommands().containsKey(content.split(Constant.Order.SPLIT_BLANK)[0]+Constant.Order.SPLIT_BLANK)) {
|
||||
chatCommand = Constant.Order.DEFAULT;
|
||||
} else {
|
||||
//预设对话
|
||||
String[] split = content.split(Constant.Order.SPLIT_BLANK);
|
||||
chatCommand = split[0] + Constant.Order.SPLIT_BLANK;
|
||||
method = MethodsConstant.CUSTOM;
|
||||
content = content.substring(chatCommand.length());
|
||||
chatCommand = split[0];
|
||||
content = content.substring(chatCommand.length()+1);
|
||||
}
|
||||
//消息内容处理
|
||||
if (content.isBlank()) {
|
||||
content = "在吗";
|
||||
}
|
||||
String response;
|
||||
if (content.equals(Constant.Order.MSG_CLEAR)){
|
||||
//检测是否为清除指令
|
||||
response = ChatUtil.removeClient(id, chatCommand);
|
||||
}else {
|
||||
//发送请求并获取回应
|
||||
String response = switch (method) {
|
||||
case CUSTOM -> AIUtil.customChat(Long.valueOf(id), content, url,chatCommand);
|
||||
case NORMAL -> AIUtil.defaultChat(Long.valueOf(id), content, url);
|
||||
case ONCE -> AIUtil.chatOnce(content, url);
|
||||
default -> Constant.Status.ERROR;
|
||||
};
|
||||
response = ChatUtil.chat(id, content, chatCommand);
|
||||
}
|
||||
event.getGroup().sendMessage(new At(Long.parseLong(id)).plus("\r\n").plus(response));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package plugin.listener;
|
||||
|
||||
import kotlin.coroutines.CoroutineContext;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.mamoe.mirai.contact.Group;
|
||||
import net.mamoe.mirai.event.EventHandler;
|
||||
import net.mamoe.mirai.event.SimpleListenerHost;
|
||||
@@ -8,28 +8,19 @@ import net.mamoe.mirai.event.events.FriendMessageEvent;
|
||||
import net.mamoe.mirai.event.events.GroupMessageEvent;
|
||||
import net.mamoe.mirai.event.events.MessageEvent;
|
||||
import net.mamoe.mirai.message.data.At;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import plugin.constant.ChatConstant;
|
||||
import plugin.constant.Constant;
|
||||
import plugin.constant.ConfigConstant;
|
||||
import plugin.utils.AIUtil;
|
||||
import plugin.utils.ConfigUtil;
|
||||
import plugin.chat.constant.Constant;
|
||||
import plugin.config.Config;
|
||||
import plugin.config.CustomCommandTemplate;
|
||||
import plugin.utils.ChatUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static plugin.utils.ConfigUtil.logger;
|
||||
|
||||
/**
|
||||
* @author SLHAF
|
||||
*/
|
||||
@Slf4j
|
||||
public class OwnerMessageListener extends SimpleListenerHost {
|
||||
|
||||
@Override
|
||||
public void handleException(@NotNull CoroutineContext context, @NotNull Throwable exception) {
|
||||
super.handleException(context, exception);
|
||||
logger.error(exception);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void messageClassifier(MessageEvent event) throws IOException {
|
||||
if (event.getSubject() instanceof Group) {
|
||||
@@ -45,23 +36,23 @@ public class OwnerMessageListener extends SimpleListenerHost {
|
||||
if (!primaryContent.contains(Constant.Order.SPLIT_GUN)) {
|
||||
String response;
|
||||
response = switch (primaryContent) {
|
||||
case "clearAll" -> AIUtil.clearAll();
|
||||
case "shutUp" -> ConfigUtil.shutUp(event.getGroup().getId());
|
||||
case "speak" -> ConfigUtil.speak(event.getGroup().getId());
|
||||
case "clearAll" -> ChatUtil.removeAllClients();
|
||||
case "shutUp" -> Config.ConfigLoader.shutUp(event.getGroup().getId());
|
||||
case "speak" -> Config.ConfigLoader.speak(event.getGroup().getId());
|
||||
default -> "无对应操作";
|
||||
};
|
||||
event.getGroup().sendMessage(response);
|
||||
return;
|
||||
}
|
||||
|
||||
String command = primaryContent.split(Constant.Order.SPLIT_CUSTOM)[0];
|
||||
String instruction = primaryContent.split(Constant.Order.SPLIT_CUSTOM)[0];
|
||||
String arguments = primaryContent.substring(primaryContent.indexOf(Constant.Order.SPLIT_GUN) + 1);
|
||||
long id = event.getSender().getId();
|
||||
String response;
|
||||
try {
|
||||
response = handleCommand(command, arguments);
|
||||
response = handleCommand(instruction, arguments);
|
||||
} catch (Exception e) {
|
||||
logger.error(e.toString());
|
||||
log.error(e.toString());
|
||||
response = "操作失败!\r\n" + e.getMessage();
|
||||
}
|
||||
event.getGroup().sendMessage(new At(id).plus(response));
|
||||
@@ -69,57 +60,84 @@ public class OwnerMessageListener extends SimpleListenerHost {
|
||||
|
||||
private void onFriendMessageEvent(FriendMessageEvent event) throws IOException {
|
||||
String primaryContent = event.getMessage().contentToString().split(Constant.Order.SPLIT_BLANK)[1];
|
||||
String command;
|
||||
String instruction;
|
||||
String arguments;
|
||||
try {
|
||||
command = primaryContent.split(ConfigConstant.CUSTOM_SPLIT)[0];
|
||||
instruction = primaryContent.split(Constant.Order.SPLIT_CUSTOM)[0];
|
||||
arguments = primaryContent.substring(primaryContent.indexOf(Constant.Order.SPLIT_CUSTOM) + 1);
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
event.getFriend().sendMessage("操作失败,缺少参数");
|
||||
return;
|
||||
}
|
||||
String response = handleCommand(command, arguments);
|
||||
String response = handleCommand(instruction, arguments);
|
||||
event.getFriend().sendMessage(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对命令及其参数进行处理
|
||||
*
|
||||
* @param command 命令
|
||||
* @param instruction 命令
|
||||
* @param arguments 参数
|
||||
* @return 处理结果
|
||||
*/
|
||||
private String handleCommand(String command, String arguments) throws IOException {
|
||||
return switch (command) {
|
||||
private String handleCommand(String instruction, String arguments) throws IOException {
|
||||
return switch (instruction) {
|
||||
case "添加预设" -> {
|
||||
if (arguments.matches(ConfigConstant.ADD_CUSTOM)) {
|
||||
String instruction = arguments.split(ConfigConstant.CUSTOM_SPLIT)[0] + ChatConstant.BLANK;
|
||||
String customModel = arguments.split(ConfigConstant.CUSTOM_SPLIT)[1];
|
||||
String customContent = arguments.split(ConfigConstant.CUSTOM_SPLIT)[2];
|
||||
yield ConfigUtil.addCustom(instruction, customModel, customContent);
|
||||
if (arguments.matches(Constant.Regex.ADD_CUSTOM)) {
|
||||
String[] argumentsArray = arguments.split(Constant.Order.SPLIT_CUSTOM);
|
||||
String command = argumentsArray[0];
|
||||
int modelTemplateIndex = Integer.parseInt(argumentsArray[1]);
|
||||
String customModel = argumentsArray[2];
|
||||
String customPromotion = argumentsArray[3];
|
||||
if (modelTemplateIndex >= Config.ConfigLoader.getConfig().getModelConfigTemplates().size()){
|
||||
yield "不存在模型模板["+modelTemplateIndex+"]";
|
||||
}
|
||||
yield Config.ConfigLoader.addCustom(command,modelTemplateIndex,customModel,customPromotion);
|
||||
} else {
|
||||
yield "格式不正确! 格式如下: \r\n" + ChatConstant.SET + "命令|预设指令|模型名称|预设\r\n例: \r\n" + ChatConstant.SPLIT + "/example|glm-4-flash|你是...\r\n注:如果不需要预设,可以将预设写为null";
|
||||
yield "格式不正确!";
|
||||
}
|
||||
}
|
||||
case "切换模型" -> {
|
||||
if (arguments.matches(ConfigConstant.MODEL_CHANGE)) {
|
||||
String instruction = arguments.split(ConfigConstant.CUSTOM_SPLIT)[0] + ChatConstant.BLANK;
|
||||
String modelName = arguments.split(ConfigConstant.CUSTOM_SPLIT)[1];
|
||||
yield ConfigUtil.customModelChange(instruction, modelName);
|
||||
if (arguments.matches(Constant.Order.MODEL_CHANGE)) {
|
||||
//获取需更改的信息
|
||||
String[] argumentsArray = arguments.split(Constant.Order.SPLIT_CUSTOM);
|
||||
String command = argumentsArray[0];
|
||||
int modelTemplateIndex = Integer.parseInt(argumentsArray[1]);
|
||||
if (modelTemplateIndex >= Config.ConfigLoader.getConfig().getModelConfigTemplates().size()){
|
||||
yield "不存在模型模板["+modelTemplateIndex+"]";
|
||||
}
|
||||
String customModel = argumentsArray[2];
|
||||
//迭代现有预设,更改对应信息
|
||||
for (CustomCommandTemplate customCommandTemplate : Config.ConfigLoader.getConfig().getCustomCommandTemplates()) {
|
||||
if (customCommandTemplate.getCommand().equals(command)){
|
||||
customCommandTemplate.setModelTemplateIndex(modelTemplateIndex);
|
||||
customCommandTemplate.setCustomModel(customModel);
|
||||
yield "指令: "+command+"模型切换成功!\r\n"+customCommandTemplate;
|
||||
}
|
||||
}
|
||||
yield "未找到指令: "+command;
|
||||
} else {
|
||||
yield "格式不正确! 格式如下: \r\n" + ChatConstant.SET + "命令|预设指令|指令对应模型";
|
||||
yield "格式不正确!";
|
||||
}
|
||||
}
|
||||
case "更改预设" -> {
|
||||
if (arguments.matches(ConfigConstant.MODEL_CHANGE)) {
|
||||
String instruction = arguments.split(ConfigConstant.CUSTOM_SPLIT)[0] + ChatConstant.BLANK;
|
||||
String customContent = arguments.split(ConfigConstant.CUSTOM_SPLIT)[1];
|
||||
yield ConfigUtil.customContentChange(instruction, customContent);
|
||||
if (arguments.matches(Constant.Order.MODEL_CHANGE)) {
|
||||
String[] argumentsArray = arguments.split(Constant.Order.SPLIT_CUSTOM);
|
||||
String command = argumentsArray[0];
|
||||
String customPromotion = argumentsArray[1];
|
||||
//迭代现有预设,更改对应信息
|
||||
for (CustomCommandTemplate customCommandTemplate : Config.ConfigLoader.getConfig().getCustomCommandTemplates()) {
|
||||
if (customCommandTemplate.getCommand().equals(command)){
|
||||
customCommandTemplate.setCustomPromotion(customPromotion);
|
||||
yield "指令: "+command+"更改预设成功!\r\n"+customCommandTemplate;
|
||||
}
|
||||
}
|
||||
yield "未找到指令: "+command;
|
||||
} else {
|
||||
yield "格式不正确! 格式如下: \r\n" + ChatConstant.SET + "命令|预设指令|指令对应预设";
|
||||
yield "格式不正确!";
|
||||
}
|
||||
}
|
||||
case "删除预设" -> ConfigUtil.removeCustom(arguments);
|
||||
case "删除预设" -> Config.ConfigLoader.removeCustom(arguments);
|
||||
default -> "该指令不存在!";
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,226 +0,0 @@
|
||||
package plugin.pojo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class Config {
|
||||
/**
|
||||
* 智谱apikey
|
||||
*/
|
||||
private String apikey;
|
||||
|
||||
/**
|
||||
* 阿里accessKey
|
||||
*/
|
||||
private String accessKeyId;
|
||||
private String accessKeySecret;
|
||||
|
||||
/**
|
||||
* 基础配置
|
||||
*/
|
||||
private String owner;
|
||||
private String defaultModel;
|
||||
private String bot;
|
||||
private String timeout;
|
||||
private String timeCheck;
|
||||
private List<Long> blacklist;
|
||||
|
||||
/**
|
||||
* 自定义预设
|
||||
*/
|
||||
private LinkedHashMap<String,String> customCommands;
|
||||
|
||||
public Config() {
|
||||
}
|
||||
|
||||
public Config(String apikey, String accessKeyId, String accessKeySecret, String owner, String defaultModel, String bot, String timeout, String timeCheck, LinkedHashMap<String, String> customCommands) {
|
||||
this.apikey = apikey;
|
||||
this.accessKeyId = accessKeyId;
|
||||
this.accessKeySecret = accessKeySecret;
|
||||
this.owner = owner;
|
||||
this.defaultModel = defaultModel;
|
||||
this.bot = bot;
|
||||
this.timeout = timeout;
|
||||
this.timeCheck = timeCheck;
|
||||
this.customCommands = customCommands;
|
||||
}
|
||||
|
||||
public Config(String apikey, String accessKeyId, String accessKeySecret, String owner, String defaultModel, String bot, String timeout, String timeCheck, List<Long> blacklist, LinkedHashMap<String, String> customCommands) {
|
||||
this.apikey = apikey;
|
||||
this.accessKeyId = accessKeyId;
|
||||
this.accessKeySecret = accessKeySecret;
|
||||
this.owner = owner;
|
||||
this.defaultModel = defaultModel;
|
||||
this.bot = bot;
|
||||
this.timeout = timeout;
|
||||
this.timeCheck = timeCheck;
|
||||
this.blacklist = blacklist;
|
||||
this.customCommands = customCommands;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return apikey
|
||||
*/
|
||||
public String getApikey() {
|
||||
return apikey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param apikey
|
||||
*/
|
||||
public void setApikey(String apikey) {
|
||||
this.apikey = apikey;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return accessKeyId
|
||||
*/
|
||||
public String getAccessKeyId() {
|
||||
return accessKeyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param accessKeyId
|
||||
*/
|
||||
public void setAccessKeyId(String accessKeyId) {
|
||||
this.accessKeyId = accessKeyId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return accessKeySecret
|
||||
*/
|
||||
public String getAccessKeySecret() {
|
||||
return accessKeySecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param accessKeySecret
|
||||
*/
|
||||
public void setAccessKeySecret(String accessKeySecret) {
|
||||
this.accessKeySecret = accessKeySecret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return owner
|
||||
*/
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param owner
|
||||
*/
|
||||
public void setOwner(String owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return modelNormal
|
||||
*/
|
||||
public String getDefaultModel() {
|
||||
return defaultModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param defaultModel
|
||||
*/
|
||||
public void setDefaultModel(String defaultModel) {
|
||||
this.defaultModel = defaultModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return bot
|
||||
*/
|
||||
public String getBot() {
|
||||
return bot;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param bot
|
||||
*/
|
||||
public void setBot(String bot) {
|
||||
this.bot = bot;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return timeout
|
||||
*/
|
||||
public String getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param timeout
|
||||
*/
|
||||
public void setTimeout(String timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return timeCheck
|
||||
*/
|
||||
public String getTimeCheck() {
|
||||
return timeCheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param timeCheck
|
||||
*/
|
||||
public void setTimeCheck(String timeCheck) {
|
||||
this.timeCheck = timeCheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return customCommands
|
||||
*/
|
||||
public HashMap<String, String> getCustomCommands() {
|
||||
return customCommands;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param customCommands
|
||||
*/
|
||||
public void setCustomCommands(LinkedHashMap<String, String> customCommands) {
|
||||
this.customCommands = customCommands;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Config{apikey = " + apikey + ", accessKeyId = " + accessKeyId + ", accessKeySecret = " + accessKeySecret + ", owner = " + owner + ", modelNormal = " + defaultModel + ", modelCode = " + ", bot = " + bot + ", timeout = " + timeout + ", timeCheck = " + timeCheck + ", customCommands = " + customCommands + "}";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return blacklist
|
||||
*/
|
||||
public List<Long> getBlacklist() {
|
||||
return blacklist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param blacklist
|
||||
*/
|
||||
public void setBlacklist(List<Long> blacklist) {
|
||||
this.blacklist = blacklist;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,12 @@
|
||||
package plugin.pojo;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class OCRDataInfo {
|
||||
|
||||
/**
|
||||
@@ -41,78 +46,6 @@ public class OCRDataInfo {
|
||||
*/
|
||||
private int width;
|
||||
|
||||
public String getAlgo_version() {
|
||||
return algo_version;
|
||||
}
|
||||
|
||||
public void setAlgo_version(String algo_version) {
|
||||
this.algo_version = algo_version;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getOrgHeight() {
|
||||
return orgHeight;
|
||||
}
|
||||
|
||||
public void setOrgHeight(int orgHeight) {
|
||||
this.orgHeight = orgHeight;
|
||||
}
|
||||
|
||||
public int getOrgWidth() {
|
||||
return orgWidth;
|
||||
}
|
||||
|
||||
public void setOrgWidth(int orgWidth) {
|
||||
this.orgWidth = orgWidth;
|
||||
}
|
||||
|
||||
public String getPrism_version() {
|
||||
return prism_version;
|
||||
}
|
||||
|
||||
public void setPrism_version(String prism_version) {
|
||||
this.prism_version = prism_version;
|
||||
}
|
||||
|
||||
public int getPrism_wnum() {
|
||||
return prism_wnum;
|
||||
}
|
||||
|
||||
public void setPrism_wnum(int prism_wnum) {
|
||||
this.prism_wnum = prism_wnum;
|
||||
}
|
||||
|
||||
public List<PrismWordsInfoBean> getPrism_wordsInfo() {
|
||||
return prism_wordsInfo;
|
||||
}
|
||||
|
||||
public void setPrism_wordsInfo(List<PrismWordsInfoBean> prism_wordsInfo) {
|
||||
this.prism_wordsInfo = prism_wordsInfo;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public static class PrismWordsInfoBean {
|
||||
/**
|
||||
* angle
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
package plugin.pojo;
|
||||
|
||||
/**
|
||||
* @author SLHAF
|
||||
*/
|
||||
public class UserCustomLatestTime {
|
||||
private String chatCommand;
|
||||
private Long latestTime;
|
||||
|
||||
public UserCustomLatestTime() {
|
||||
}
|
||||
|
||||
public UserCustomLatestTime(String chatCommand, Long latestTime) {
|
||||
this.chatCommand = chatCommand;
|
||||
this.latestTime = latestTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return chatCommand
|
||||
*/
|
||||
public String getChatCommand() {
|
||||
return chatCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param chatCommand
|
||||
*/
|
||||
public void setChatCommand(String chatCommand) {
|
||||
this.chatCommand = chatCommand;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return latestTime
|
||||
*/
|
||||
public Long getLatestTime() {
|
||||
return latestTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param latestTime
|
||||
*/
|
||||
public void setLatestTime(Long latestTime) {
|
||||
this.latestTime = latestTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserCustomLatestTime{chatCommand = " + chatCommand + ", latestTime = " + latestTime + "}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof UserCustomLatestTime other) {
|
||||
return other.getChatCommand().equals(this.chatCommand);
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
package plugin.pojo;
|
||||
|
||||
import com.zhipu.oapi.service.v4.model.ChatMessage;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UserCustomMessage {
|
||||
private String command;
|
||||
private List<ChatMessage> messages;
|
||||
|
||||
|
||||
public UserCustomMessage() {
|
||||
}
|
||||
|
||||
public UserCustomMessage(String command, List<ChatMessage> messages) {
|
||||
this.command = command;
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return command
|
||||
*/
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param command
|
||||
*/
|
||||
public void setCommand(String command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取
|
||||
* @return messages
|
||||
*/
|
||||
public List<ChatMessage> getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
* @param messages
|
||||
*/
|
||||
public void setMessages(List<ChatMessage> messages) {
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserCustomMessage{command = " + command + ", messages = " + messages + "}";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,370 +0,0 @@
|
||||
package plugin.utils;
|
||||
|
||||
import com.zhipu.oapi.ClientV4;
|
||||
import com.zhipu.oapi.Constants;
|
||||
import com.zhipu.oapi.service.v4.model.ChatCompletionRequest;
|
||||
import com.zhipu.oapi.service.v4.model.ChatMessage;
|
||||
import com.zhipu.oapi.service.v4.model.ChatMessageRole;
|
||||
import com.zhipu.oapi.service.v4.model.ModelApiResponse;
|
||||
import plugin.constant.AIConstant;
|
||||
import plugin.constant.ChatConstant;
|
||||
import plugin.constant.ConfigConstant;
|
||||
import plugin.pojo.Config;
|
||||
import plugin.pojo.UserCustomLatestTime;
|
||||
import plugin.pojo.UserCustomMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static plugin.utils.ConfigUtil.logger;
|
||||
|
||||
|
||||
/**
|
||||
* @author SLHAF
|
||||
*/
|
||||
public class AIUtil {
|
||||
private static final String APIKEY;
|
||||
private static final ClientV4 CLIENT;
|
||||
private static final String REQUEST_ID_TEMPLATE = "ChatAI_InGroup_v2";
|
||||
private static final HashMap<Long, List<ChatMessage>> userDefaultMessages = new HashMap<>();
|
||||
private static final HashMap<Long, Long> userLatestTimeOfDefault = new HashMap<>();
|
||||
private static String defaultModel;
|
||||
|
||||
private static final HashMap<Long, List<UserCustomMessage>> userCustomMessages = new HashMap<>();
|
||||
private static final HashMap<Long, List<UserCustomLatestTime>> userLatestTimeOfCustom = new HashMap<>();
|
||||
/*private static String modelCode;*/
|
||||
/**
|
||||
* 结构:
|
||||
* /c : glm-4-flush|预设内容
|
||||
*/
|
||||
private static HashMap<String, String> customCommands;
|
||||
|
||||
private static final Long CHECK_TIME, TIMEOUT;
|
||||
|
||||
static {
|
||||
Config config = ConfigUtil.getConfig();
|
||||
APIKEY = config.getApikey();
|
||||
CLIENT = new ClientV4.Builder(APIKEY).build();
|
||||
defaultModel = config.getDefaultModel();
|
||||
customCommands = config.getCustomCommands();
|
||||
CHECK_TIME = Long.valueOf(config.getTimeCheck().substring(1));
|
||||
TIMEOUT = Long.valueOf(config.getTimeout().substring(1));
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
try {
|
||||
Thread.sleep(CHECK_TIME);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
if (!userLatestTimeOfDefault.isEmpty()) {
|
||||
//查看user最近时间,如果超过TIMEOUT,则清理对应记录
|
||||
userLatestTimeOfDefault.forEach((id, latestTime) -> {
|
||||
synchronized (userDefaultMessages.get(id)) {
|
||||
Long currentTime = System.currentTimeMillis();
|
||||
if (currentTime - latestTime > TIMEOUT && userDefaultMessages.containsKey(id)) {
|
||||
userDefaultMessages.remove(id);
|
||||
logger.info("default记录清理:" + id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (!userLatestTimeOfCustom.isEmpty()) {
|
||||
//查看user最近时间,如果超过TIMEOUT,则清理对应记录
|
||||
userLatestTimeOfCustom.forEach((id, userCustomLatestTimeList) -> {
|
||||
synchronized (userCustomMessages.get(id)) {
|
||||
ArrayList<Integer> indexToRemove = new ArrayList<>();
|
||||
Long currentTime = System.currentTimeMillis();
|
||||
for (int i = 0; i < userCustomLatestTimeList.size(); i++) {
|
||||
if (currentTime - userCustomLatestTimeList.get(i).getLatestTime() > TIMEOUT){
|
||||
logger.info("custom记录清理: "+id+" "+userCustomLatestTimeList.get(i).getChatCommand());
|
||||
userCustomMessages.get(id).remove(i);
|
||||
indexToRemove.add(i);
|
||||
}
|
||||
}
|
||||
//移除最近操作时间
|
||||
for (int i : indexToRemove) {
|
||||
userCustomLatestTimeList.remove(i);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}).start();
|
||||
logger.info("清理线程启动");
|
||||
logger.info("当前默认聊天模型: " + defaultModel);
|
||||
}
|
||||
|
||||
private AIUtil() {
|
||||
}
|
||||
|
||||
public static String customChat(Long id, String content, String url, String chatCommand) {
|
||||
if (ChatConstant.CLEAR.equals(content.replace(ChatConstant.BLANK, ""))) {
|
||||
if (!userCustomMessages.containsKey(id)) {
|
||||
return "不存在消息记录";
|
||||
}
|
||||
ArrayList<Integer> indexToRemove = new ArrayList<>();
|
||||
List<UserCustomMessage> userCustomMessageList = userCustomMessages.get(id);
|
||||
for (int i = 0; i < userCustomMessageList.size(); i++) {
|
||||
if (userCustomMessageList.get(i).getCommand().equals(chatCommand)) {
|
||||
indexToRemove.add(i);
|
||||
}
|
||||
}
|
||||
indexToRemove.forEach(i -> userCustomMessageList.remove(i.intValue()));
|
||||
return "消息记录已清空";
|
||||
} else if (AIConstant.CURRENT_MODEL.equals(content.replace(ChatConstant.BLANK, ""))) {
|
||||
String modelName = customCommands.get(chatCommand).split(ConfigConstant.CUSTOM_SPLIT)[0];
|
||||
return "当前模型为: " + modelName;
|
||||
}
|
||||
//查看本次id是否有记录存在
|
||||
if (!userCustomMessages.containsKey(id)) {
|
||||
//不存在消息记录
|
||||
//创建消息list
|
||||
List<ChatMessage> chatMessages = new ArrayList<>();
|
||||
if (!customCommands.get(chatCommand).split(ConfigConstant.CUSTOM_SPLIT)[1].equals(ConfigConstant.NULL)) {
|
||||
ChatMessage customMessage = new ChatMessage(ChatMessageRole.SYSTEM.value(), customCommands.get(chatCommand).split(ConfigConstant.CUSTOM_SPLIT)[1]);
|
||||
chatMessages.add(customMessage);
|
||||
}
|
||||
List<UserCustomMessage> userCustomMessageList = new ArrayList<>();
|
||||
userCustomMessageList.add(new UserCustomMessage(chatCommand, chatMessages));
|
||||
userCustomMessages.put(id, userCustomMessageList);
|
||||
}else {
|
||||
//存在消息记录,但需要判断是否存在该指令对应的消息记录
|
||||
List<UserCustomMessage> userCustomMessageList = userCustomMessages.get(id);
|
||||
boolean found = false;
|
||||
for (UserCustomMessage userCustomMessage : userCustomMessageList) {
|
||||
if (userCustomMessage.getCommand().equals(chatCommand)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
//如果不存在该指令对应的消息记录
|
||||
UserCustomMessage userCustomMessage = new UserCustomMessage();
|
||||
userCustomMessage.setCommand(chatCommand);
|
||||
List<ChatMessage> chatMessages = new ArrayList<>();
|
||||
//判断是否存在预设
|
||||
if (!customCommands.get(chatCommand).split(ConfigConstant.CUSTOM_SPLIT)[1].equals(ConfigConstant.NULL)){
|
||||
ChatMessage customMessage = new ChatMessage(ChatMessageRole.SYSTEM.value(), customCommands.get(chatCommand).split(ConfigConstant.CUSTOM_SPLIT)[1]);
|
||||
chatMessages.add(customMessage);
|
||||
}
|
||||
userCustomMessage.setMessages(chatMessages);
|
||||
userCustomMessageList.add(userCustomMessage);
|
||||
}
|
||||
}
|
||||
String modelName = customCommands.get(chatCommand).split(ConfigConstant.CUSTOM_SPLIT)[0];
|
||||
synchronized (userCustomMessages.get(id)) {
|
||||
return getChatResponse(id, content, url, modelName, chatCommand);
|
||||
}
|
||||
}
|
||||
|
||||
public static String defaultChat(Long id, String content, String url) {
|
||||
if (ChatConstant.CLEAR.equals(content.replace(ChatConstant.BLANK, ""))) {
|
||||
if (!userDefaultMessages.containsKey(id)) {
|
||||
return "不存在消息记录";
|
||||
}
|
||||
userDefaultMessages.remove(id);
|
||||
return "消息记录已清空";
|
||||
} else if (ChatConstant.CURRENT_MODEL.equals(content.replace(ChatConstant.BLANK, ""))) {
|
||||
return "当前模型为: " + defaultModel;
|
||||
}
|
||||
//查看本次id是否有记录存在
|
||||
if (!userDefaultMessages.containsKey(id)) {
|
||||
//创建消息list
|
||||
List<ChatMessage> chatMessages = new ArrayList<>();
|
||||
if (customCommands.containsKey(ConfigConstant.DEFAULT+ChatConstant.BLANK) && !ConfigConstant.NULL.equals(customCommands.get(ConfigConstant.DEFAULT+ChatConstant.BLANK))) {
|
||||
ChatMessage customMessage = new ChatMessage(ChatMessageRole.SYSTEM.value(), customCommands.get(ConfigConstant.DEFAULT+ChatConstant.BLANK));
|
||||
chatMessages.add(customMessage);
|
||||
}
|
||||
userDefaultMessages.put(id, chatMessages);
|
||||
}
|
||||
synchronized (userDefaultMessages.get(id)) {
|
||||
return getChatResponse(id, content, url, defaultModel, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static String chatOnce(String content, String url) {
|
||||
|
||||
if (AIConstant.CURRENT_MODEL.equals(content.replace(ChatConstant.BLANK, ""))) {
|
||||
return "当前模型为: " + defaultModel;
|
||||
}
|
||||
String result = "";
|
||||
if (url != null) {
|
||||
if (!OCRUtil.isSupported) {
|
||||
return "当前不支持文字识别,请检查阿里云OCR相关配置。";
|
||||
} else {
|
||||
String contentOfImage = OCRUtil.getContentOfImage(url);
|
||||
if (contentOfImage == null) {
|
||||
result = "未识别出图片内容。";
|
||||
} else if (AIConstant.ERROR.equals(contentOfImage)) {
|
||||
result = "识别图片内容出错,请查看控制台。";
|
||||
} else {
|
||||
content = content.replace("[图片]", "\r\n[" + contentOfImage + "]\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
String requestId = REQUEST_ID_TEMPLATE + "_once_" + System.currentTimeMillis();
|
||||
List<ChatMessage> messages = new ArrayList<>();
|
||||
messages.add(new ChatMessage(ChatMessageRole.USER.value(), content));
|
||||
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
|
||||
.model(defaultModel)
|
||||
.stream(Boolean.FALSE)
|
||||
.invokeMethod(Constants.invokeMethod)
|
||||
.messages(messages)
|
||||
.requestId(requestId)
|
||||
.build();
|
||||
ModelApiResponse invokeModelApiResp = CLIENT.invokeModelApi(chatCompletionRequest);
|
||||
int code = invokeModelApiResp.getCode();
|
||||
if (code == AIConstant.NORMAL_CODE) {
|
||||
printTokenInfo(invokeModelApiResp);
|
||||
return invokeModelApiResp.getData().getChoices().get(0).getMessage().getContent().toString();
|
||||
} else {
|
||||
logger.warning("code: " + code);
|
||||
logger.warning("ErrorCode:" + invokeModelApiResp.getData().getError().getCode());
|
||||
logger.warning("msg:" + invokeModelApiResp.getData().getError().getMessage());
|
||||
return invokeModelApiResp.getMsg() + "\r\n<" + result + ">";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 取得回复内容
|
||||
* <br>chatMessages内容只有两个static变量,只需根据传入的chatCommand是否为null进行判断
|
||||
*
|
||||
* @param id 聊天用户ID
|
||||
* @param content 聊天用户发送的内容,content已在Listener处进行处理
|
||||
* @param url 获取到的图片url,如果没有图片,则为null
|
||||
* @param model 本次对话所需的模型名称
|
||||
* <br>当为userDefaultMessages时:
|
||||
* <br><code>
|
||||
* <br> qq1 : [msg1,msg2,msg3]
|
||||
* <br> qq2 : [msg1,msg2,msg3]
|
||||
* <br></code>
|
||||
* <br>当为userCustomMessages时:
|
||||
* <br><code>
|
||||
* <br> qq1 : [{command1,[msg1.msg2,msg3]},{command2,[msg1,msg2,msg3]},{command3,[msg1,msg2,msg3]}]
|
||||
* <br> qq2 : [{command1,[msg1.msg2,msg3]},{command2,[msg1,msg2,msg3]},{command3,[msg1,msg2,msg3]}]
|
||||
* <br></code>
|
||||
* @param chatCommand 聊天指令
|
||||
* @return 得到的模型响应内容
|
||||
*/
|
||||
private static String getChatResponse(Long id, String content, String url, String model, String chatCommand) {
|
||||
String requestId = REQUEST_ID_TEMPLATE + "_" + model + "_" + System.currentTimeMillis();
|
||||
//处理url内容
|
||||
String result = "";
|
||||
if (url != null) {
|
||||
if (!OCRUtil.isSupported) {
|
||||
logger.warning("unSupportedOCR");
|
||||
return "当前不支持文字识别,请检查阿里云OCR相关配置。";
|
||||
} else {
|
||||
String contentOfImage = OCRUtil.getContentOfImage(url);
|
||||
if (contentOfImage == null) {
|
||||
result = "未识别出图片内容。";
|
||||
} else if (AIConstant.ERROR.equals(contentOfImage)) {
|
||||
result = "识别图片内容出错,请查看控制台。";
|
||||
} else {
|
||||
content = content.replace("[图片]", "\r\n[" + contentOfImage + "]\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
logger.info("final content:" + content);
|
||||
|
||||
//根据primaryUserMessages中的内容来定义userMessages并更新latestTime
|
||||
List<ChatMessage> chatMessages = null;
|
||||
if (chatCommand == null) {
|
||||
chatMessages = userDefaultMessages.get(id);
|
||||
userLatestTimeOfDefault.put(id, System.currentTimeMillis());
|
||||
} else {
|
||||
List<UserCustomMessage> userCustomMessageList = userCustomMessages.get(id);
|
||||
for (UserCustomMessage userCustomMessage : userCustomMessageList) {
|
||||
//在调用时已确保存在指令对应的消息记录
|
||||
if (userCustomMessage.getCommand().equals(chatCommand)) {
|
||||
chatMessages = userCustomMessage.getMessages();
|
||||
break;
|
||||
}
|
||||
}
|
||||
//更新最新操作时间
|
||||
boolean foundTime = false;
|
||||
List<UserCustomLatestTime> userCustomLatestTimeList;
|
||||
if (userLatestTimeOfCustom.containsKey(id)) {
|
||||
//如果存在该id对应的任一聊天记录
|
||||
userCustomLatestTimeList = userLatestTimeOfCustom.get(id);
|
||||
for (UserCustomLatestTime userCustomLatestTime : userCustomLatestTimeList) {
|
||||
if (userCustomLatestTime.getChatCommand().equals(chatCommand)) {
|
||||
userCustomLatestTime.setLatestTime(System.currentTimeMillis());
|
||||
foundTime = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}else {
|
||||
//如果没有记录存在
|
||||
userCustomLatestTimeList = new ArrayList<>();
|
||||
userCustomLatestTimeList.add(new UserCustomLatestTime(chatCommand,System.currentTimeMillis()));
|
||||
userLatestTimeOfCustom.put(id,userCustomLatestTimeList);
|
||||
foundTime = true;
|
||||
}
|
||||
if (!foundTime) {
|
||||
userCustomLatestTimeList.add(new UserCustomLatestTime(chatCommand, System.currentTimeMillis()));
|
||||
}
|
||||
}
|
||||
|
||||
if (chatMessages == null) {
|
||||
return "消息记录读取失败";
|
||||
}
|
||||
|
||||
//添加消息
|
||||
chatMessages.add(new ChatMessage(ChatMessageRole.USER.value(), content));
|
||||
|
||||
//创建并发送请求
|
||||
ChatCompletionRequest chatCompletionRequest = ChatCompletionRequest.builder()
|
||||
.model(model)
|
||||
.stream(Boolean.FALSE)
|
||||
.invokeMethod(Constants.invokeMethod)
|
||||
.messages(chatMessages)
|
||||
.requestId(requestId).build();
|
||||
|
||||
ModelApiResponse invokeModelApiResp = CLIENT.invokeModelApi(chatCompletionRequest);
|
||||
int code = invokeModelApiResp.getCode();
|
||||
if (code == AIConstant.NORMAL_CODE) {
|
||||
printTokenInfo(invokeModelApiResp);
|
||||
String response = invokeModelApiResp.getData().getChoices().get(0).getMessage().getContent().toString();
|
||||
chatMessages.add(new ChatMessage(ChatMessageRole.ASSISTANT.value(), response));
|
||||
return response;
|
||||
} else {
|
||||
logger.warning("code: " + code);
|
||||
logger.warning("ErrorCode:" + invokeModelApiResp.getData().getError().getCode());
|
||||
logger.warning("msg:" + invokeModelApiResp.getData().getError().getMessage());
|
||||
return invokeModelApiResp.getMsg() + "\r\n<" + result + ">";
|
||||
}
|
||||
}
|
||||
|
||||
private static void printTokenInfo(ModelApiResponse invokeModelApiResp) {
|
||||
int promptTokens = invokeModelApiResp.getData().getUsage().getPromptTokens();
|
||||
int completionTokens = invokeModelApiResp.getData().getUsage().getCompletionTokens();
|
||||
int totalTokens = invokeModelApiResp.getData().getUsage().getTotalTokens();
|
||||
logger.info("prompt_tokens: " + promptTokens);
|
||||
logger.info("completion_tokens: " + completionTokens);
|
||||
logger.info("total_tokens: " + totalTokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空所有聊天记录
|
||||
*/
|
||||
public static String clearAll() {
|
||||
int size = 0;
|
||||
size += userDefaultMessages.size();
|
||||
userDefaultMessages.clear();
|
||||
userLatestTimeOfDefault.clear();
|
||||
|
||||
for (Long id : userCustomMessages.keySet()) {
|
||||
size += userCustomMessages.get(id).size();
|
||||
}
|
||||
userCustomMessages.clear();
|
||||
userLatestTimeOfCustom.clear();
|
||||
return "本次清空" + size + "条会话";
|
||||
}
|
||||
}
|
||||
110
src/main/java/plugin/utils/ChatUtil.java
Normal file
110
src/main/java/plugin/utils/ChatUtil.java
Normal file
@@ -0,0 +1,110 @@
|
||||
package plugin.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import plugin.chat.ChatClient;
|
||||
import plugin.chat.constant.Constant;
|
||||
import plugin.chat.pojo.ChatResponse;
|
||||
import plugin.config.Config;
|
||||
import plugin.config.CustomCommandTemplate;
|
||||
import plugin.config.ModelConfigTemplate;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
@Slf4j
|
||||
public class ChatUtil {
|
||||
|
||||
private static final HashMap<String, ChatClient> chatClients = new HashMap<>();
|
||||
private static final HashMap<String,Long> latestTime = new HashMap<>();
|
||||
|
||||
private ChatUtil() {
|
||||
|
||||
}
|
||||
|
||||
static {
|
||||
launchCleanerThread();
|
||||
}
|
||||
|
||||
private static void launchCleanerThread() {
|
||||
Config config = Config.ConfigLoader.getConfig();
|
||||
long timeout = Long.parseLong(config.getTimeout());
|
||||
long timeCheck = Long.parseLong(config.getTimeCheck());
|
||||
Thread thread = new Thread(() -> {
|
||||
long currentTime = System.currentTimeMillis();
|
||||
while (true) {
|
||||
synchronized (chatClients) {
|
||||
latestTime.forEach((chatId, latestTime) -> {
|
||||
if (currentTime - latestTime > timeout) {
|
||||
chatClients.remove(chatId);
|
||||
log.info("记录清理: {}", chatId);
|
||||
}
|
||||
});
|
||||
}
|
||||
try {
|
||||
Thread.sleep(timeCheck);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
thread.setName("ChatClientsCleaner");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public static String chat(String id, String content, String command) {
|
||||
String chatId = id + "-" + command;
|
||||
ChatResponse chatResponse = null;
|
||||
synchronized (chatClients) {
|
||||
if (chatClients.containsKey(chatId)) {
|
||||
ChatClient chatClient = chatClients.get(chatId);
|
||||
chatResponse = chatClient.runChat(content);
|
||||
} else {
|
||||
int modelTemplateIndex;
|
||||
String customModel;
|
||||
String customPromotion;
|
||||
|
||||
Config config = Config.ConfigLoader.getConfig();
|
||||
for (CustomCommandTemplate customCommandTemplate : config.getCustomCommandTemplates()) {
|
||||
if (customCommandTemplate.getCommand().equals(command)) {
|
||||
modelTemplateIndex = customCommandTemplate.getModelTemplateIndex();
|
||||
customModel = customCommandTemplate.getCustomModel();
|
||||
customPromotion = customCommandTemplate.getCustomPromotion();
|
||||
ModelConfigTemplate modelConfigTemplate = config.getModelConfigTemplates().get(modelTemplateIndex);
|
||||
String url = modelConfigTemplate.getBase_url();
|
||||
String apikey = modelConfigTemplate.getApikey();
|
||||
|
||||
ChatClient chatClient = new ChatClient(chatId, url, apikey, customModel);
|
||||
chatClient.setPromotion(customPromotion);
|
||||
chatClients.put(chatId, chatClient);
|
||||
chatResponse = chatClient.runChat(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Objects.requireNonNull(chatResponse).getType().equals(Constant.Response.ERROR)) {
|
||||
log.warn("出现错误: {}", chatResponse.getMessage());
|
||||
return "ERROR!\r\n" + chatResponse.getMessage();
|
||||
}
|
||||
log.info("本次消耗Token: {}", Objects.requireNonNull(chatResponse).getUsageBean().toString());
|
||||
latestTime.put(chatId, System.currentTimeMillis());
|
||||
}
|
||||
return chatResponse.getMessage();
|
||||
}
|
||||
|
||||
public static String removeClient(String id,String command) {
|
||||
String chatId = id + "-" + command;
|
||||
synchronized (chatClients) {
|
||||
chatClients.remove(chatId);
|
||||
latestTime.remove(chatId);
|
||||
}
|
||||
return "消息记录: "+chatId +"已清空";
|
||||
}
|
||||
|
||||
public static String removeAllClients(){
|
||||
synchronized (chatClients) {
|
||||
chatClients.clear();
|
||||
latestTime.clear();
|
||||
}
|
||||
return "所有消息记录已清空";
|
||||
}
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
package plugin.utils;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import net.mamoe.mirai.utils.LoggerAdapters;
|
||||
import net.mamoe.mirai.utils.MiraiLogger;
|
||||
import org.slf4j.Logger;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import plugin.constant.ChatConstant;
|
||||
import plugin.constant.ConfigConstant;
|
||||
import plugin.pojo.Config;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
|
||||
/**
|
||||
* @author SLHAF
|
||||
*/
|
||||
public class ConfigUtil {
|
||||
private static final String CONFIG_PATH = "./config/ChatAIinGroup/config.yaml";
|
||||
private static final Yaml yaml;
|
||||
private static Config config;
|
||||
private static final Logger log = org. slf4j. LoggerFactory. getLogger("ChatAIinGroup");
|
||||
public static MiraiLogger logger = LoggerAdapters.asMiraiLogger(log);;
|
||||
|
||||
private ConfigUtil() {
|
||||
}
|
||||
|
||||
static {
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
yaml = new Yaml(options);
|
||||
config = new Config();
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查配置
|
||||
*
|
||||
* @throws IOException 配置文件写入出错
|
||||
*/
|
||||
public static void load() throws IOException, ClassNotFoundException {
|
||||
//检查配置文件
|
||||
File file = new File(CONFIG_PATH);
|
||||
if (!file.exists()) {
|
||||
//创建配置文件
|
||||
file.getParentFile().mkdirs();
|
||||
file.createNewFile();
|
||||
config.setApikey("your_zhipu_apikey");
|
||||
config.setAccessKeyId("your_ali_access_key_id");
|
||||
config.setAccessKeySecret("your_ali_access_key_secret");
|
||||
config.setOwner("your_bot_owner_qq_number(e.g. Q1145141919810)");
|
||||
config.setDefaultModel("glm-4-flash");
|
||||
config.setBot("your_bot_qq_number(e.g. Q1145141919810)");
|
||||
config.setTimeout("M3600000");
|
||||
config.setTimeCheck("M60000");
|
||||
ArrayList<Long> blacklist = new ArrayList<>();
|
||||
blacklist.add(123456789L);
|
||||
blacklist.add(987654321L);
|
||||
config.setBlacklist(blacklist);
|
||||
LinkedHashMap<String, String> commands = new LinkedHashMap<>();
|
||||
commands.put("default ", "null");
|
||||
commands.put("/c ", "glm-4-flash|你是一位智能编程助手,你会为用户回答关于编程、代码、计算机方面的任何问题,并提供格式规范、可以执行、准确安全的代码,并在必要时提供详细的解释。 请用中文回答。");
|
||||
config.setCustomCommands(commands);
|
||||
dump();
|
||||
logger.warning("配置文件创建成功,请关闭后进行配置");
|
||||
System.exit(0);
|
||||
} else {
|
||||
//读取配置文件
|
||||
InputStream inputStream = new FileInputStream(CONFIG_PATH);
|
||||
config = BeanUtil.toBean(yaml.load(new FileInputStream(CONFIG_PATH)), Config.class);
|
||||
inputStream.close();
|
||||
logger.info(config.toString());
|
||||
logger.info("读取配置文件完毕");
|
||||
HashMap<String, String> customCommands = config.getCustomCommands();
|
||||
if (!customCommands.containsKey(ConfigConstant.DEFAULT+ChatConstant.BLANK)){
|
||||
logger.warning("未找到default预设!");
|
||||
customCommands.put("default ","null");
|
||||
dump();
|
||||
logger.warning("已自动添加default预设!");
|
||||
}
|
||||
Class.forName("plugin.utils.AIUtil");
|
||||
Class.forName("plugin.utils.OCRUtil");
|
||||
}
|
||||
}
|
||||
|
||||
public static Config getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
|
||||
public static String customModelChange(String instruction, String customModel) throws IOException {
|
||||
HashMap<String, String> customCommands = config.getCustomCommands();
|
||||
synchronized (customCommands) {
|
||||
if (!customCommands.containsKey(instruction)) {
|
||||
return "该预设不存在!";
|
||||
}
|
||||
if ((ConfigConstant.DEFAULT+ChatConstant.BLANK).equals(instruction)){
|
||||
config.setDefaultModel(customModel);
|
||||
dump();
|
||||
return "模型切换成功: [defaultModel -> "+config.getDefaultModel()+"]";
|
||||
}else {
|
||||
String customContent = customCommands.get(instruction).split(ConfigConstant.CUSTOM_SPLIT)[1];
|
||||
customCommands.put(instruction, customModel + "|" + customContent);
|
||||
dump();
|
||||
return "模型切换成功: [" + instruction + "->" + customCommands.get(instruction) + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void dump() throws IOException {
|
||||
FileWriter writer = new FileWriter(CONFIG_PATH);
|
||||
yaml.dump(BeanUtil.beanToMap(config), writer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭当前群聊发言
|
||||
*
|
||||
* @param id 群聊id
|
||||
*/
|
||||
public static String shutUp(long id) {
|
||||
config.getBlacklist().add(id);
|
||||
return "ChatAI-InGroup 已关闭";
|
||||
}
|
||||
|
||||
/**
|
||||
* 开启当前群聊发言
|
||||
*
|
||||
* @param id 群聊id
|
||||
*/
|
||||
public static String speak(long id) {
|
||||
config.getBlacklist().remove(id);
|
||||
return "ChatAI-InGroup 已开启";
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加预设
|
||||
*
|
||||
* @param instruction 指令
|
||||
* @param customModel 预设模型
|
||||
* @param customContent 预设内容
|
||||
* @return 运行结果
|
||||
* @throws IOException 配置保存出错
|
||||
*/
|
||||
public static String addCustom(String instruction, String customModel, String customContent) throws IOException {
|
||||
HashMap<String, String> customCommands = config.getCustomCommands();
|
||||
synchronized (customCommands) {
|
||||
if (customCommands.containsKey(instruction)) {
|
||||
return "已存在当前指令! \r\n[" + instruction + "->" + customCommands.get(instruction) + "]";
|
||||
}
|
||||
String content = customModel + "|" + customContent;
|
||||
customCommands.put(instruction, content);
|
||||
dump();
|
||||
return "预设添加完毕! \r\n[" + instruction + "->" + content + "]";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 改变指令对应预设
|
||||
*
|
||||
* @param instruction 指令
|
||||
* @param customContent 预设内容
|
||||
* @return 运行结果
|
||||
*/
|
||||
public static String customContentChange(String instruction, String customContent) throws IOException {
|
||||
HashMap<String, String> customCommands = config.getCustomCommands();
|
||||
synchronized (customCommands) {
|
||||
if (!customCommands.containsKey(instruction)) {
|
||||
return "该指令不存在!";
|
||||
}
|
||||
if ((ConfigConstant.DEFAULT+ChatConstant.BLANK).equals(instruction)) {
|
||||
customCommands.put(instruction, customContent);
|
||||
}else {
|
||||
String modelName = customCommands.get(instruction).split(ConfigConstant.CUSTOM_SPLIT)[0];
|
||||
customCommands.put(instruction, modelName + "|" + customContent);
|
||||
}
|
||||
dump();
|
||||
return "预设更改成功! \r\n[" + instruction + "->" + customCommands.get(instruction) + "]";
|
||||
}
|
||||
}
|
||||
|
||||
public static String removeCustom(String arguments) throws IOException {
|
||||
HashMap<String, String> customCommands = getConfig().getCustomCommands();
|
||||
synchronized (customCommands) {
|
||||
if (!customCommands.containsKey(arguments + ChatConstant.BLANK)) {
|
||||
return "该预设不存在";
|
||||
}
|
||||
if (ConfigConstant.DEFAULT.equals(arguments)){
|
||||
return "默认配置不可删除!";
|
||||
}
|
||||
String content = customCommands.get(arguments + ChatConstant.BLANK);
|
||||
customCommands.remove(arguments + ChatConstant.BLANK);
|
||||
dump();
|
||||
return "删除预设[" + arguments + "->" + content + "]成功";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,24 +6,23 @@ import com.aliyun.ocr_api20210707.models.RecognizeAdvancedRequest;
|
||||
import com.aliyun.ocr_api20210707.models.RecognizeAdvancedResponse;
|
||||
import com.aliyun.tea.TeaException;
|
||||
import com.aliyun.teautil.models.RuntimeOptions;
|
||||
import plugin.pojo.Config;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import plugin.config.Config;
|
||||
import plugin.pojo.OCRDataInfo;
|
||||
|
||||
import static plugin.utils.ConfigUtil.logger;
|
||||
|
||||
|
||||
@Slf4j
|
||||
public class OCRUtil {
|
||||
private static Client client;
|
||||
public static boolean isSupported;
|
||||
|
||||
static {
|
||||
//读取密钥
|
||||
Config pluginConfig = ConfigUtil.getConfig();
|
||||
String accessKeyId = pluginConfig.getAccessKeyId();
|
||||
String accessKeySecret = pluginConfig.getAccessKeySecret();
|
||||
Config pluginConfig = Config.ConfigLoader.getConfig();
|
||||
String accessKeyId = pluginConfig.getOcrConfig().getAccessKeyId();
|
||||
String accessKeySecret = pluginConfig.getOcrConfig().getAccessKeySecret();
|
||||
if (accessKeySecret == null || accessKeyId == null) {
|
||||
isSupported = false;
|
||||
logger.warning("未检测到阿里云OCR配置信息,图片文字识别将不可用。");
|
||||
log.warn("未检测到阿里云OCR配置信息,图片文字识别将不可用。");
|
||||
} else {
|
||||
isSupported = true;
|
||||
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
|
||||
@@ -33,10 +32,10 @@ public class OCRUtil {
|
||||
try {
|
||||
client = new Client(config);
|
||||
} catch (Exception e) {
|
||||
logger.error("创建client出错");
|
||||
logger.error(e.getMessage());
|
||||
log.error("创建client出错");
|
||||
log.error(e.getMessage());
|
||||
}
|
||||
logger.info("阿里云OCR已配置。");
|
||||
log.info("阿里云OCR已配置。");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,18 +64,18 @@ public class OCRUtil {
|
||||
} catch (TeaException error) {
|
||||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// 错误 message
|
||||
logger.error(error.getMessage());
|
||||
log.error(error.getMessage());
|
||||
// 诊断地址
|
||||
logger.error(error.getData().get("Recommend").toString());
|
||||
log.error(error.getData().get("Recommend").toString());
|
||||
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||
return "ERROR";
|
||||
} catch (Exception _error) {
|
||||
TeaException error = new TeaException(_error.getMessage(), _error);
|
||||
// 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
|
||||
// 错误 message
|
||||
logger.error(error.getMessage());
|
||||
log.error(error.getMessage());
|
||||
// 诊断地址
|
||||
logger.error(error.getData().get("Recommend").toString());
|
||||
log.error(error.getData().get("Recommend").toString());
|
||||
com.aliyun.teautil.Common.assertAsString(error.message);
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
@@ -14,19 +14,10 @@ import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.junit.Test;
|
||||
import plugin.App;
|
||||
import plugin.constant.ChatConstant;
|
||||
import plugin.constant.ConfigConstant;
|
||||
import plugin.listener.OwnerMessageListener;
|
||||
import plugin.utils.AIUtil;
|
||||
import plugin.utils.ConfigUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Scanner;
|
||||
|
||||
import static kotlin.io.ConsoleKt.readln;
|
||||
|
||||
public class MyTest {
|
||||
|
||||
@Test
|
||||
@@ -128,57 +119,6 @@ public class MyTest {
|
||||
client.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ownerTest() throws ClassNotFoundException, IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
|
||||
ConfigUtil.load();
|
||||
|
||||
Class clazz = OwnerMessageListener.class;
|
||||
Method handleCommand = clazz.getDeclaredMethod("handleCommand", String.class, String.class);
|
||||
handleCommand.setAccessible(true);
|
||||
while (true){
|
||||
String input = readln();
|
||||
String command = input.split(ChatConstant.BLANK)[0];
|
||||
String arguments = input.split(ChatConstant.BLANK)[1];
|
||||
|
||||
Object invoke = handleCommand.invoke(clazz.getDeclaredConstructor().newInstance(), command, arguments);
|
||||
System.out.println(invoke);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chatTest() throws IOException, ClassNotFoundException {
|
||||
ConfigUtil.load();
|
||||
|
||||
Long id = 1L;
|
||||
String content = "你好";
|
||||
String chatCommand = "/c ";
|
||||
|
||||
String customChat = AIUtil.customChat(id, content, null, chatCommand);
|
||||
System.out.println(customChat);
|
||||
|
||||
String defaultChat = AIUtil.defaultChat(id, content, null);
|
||||
System.out.println(defaultChat);
|
||||
|
||||
String chatOnce = AIUtil.chatOnce(content, null);
|
||||
System.out.println(chatOnce);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void regexTest(){
|
||||
String str = "/c glm";
|
||||
System.out.println(str.matches(ConfigConstant.MODEL_CHANGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void textBlockTest(){
|
||||
String str = """
|
||||
aliyun:
|
||||
123:
|
||||
111
|
||||
""";
|
||||
System.out.println(str);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void terminalTest() throws InterruptedException {
|
||||
|
||||
Reference in New Issue
Block a user