Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/0xpyex0_parrot-mirai.json
T

1 line
121 KiB
JSON

{"repo": "0xpyex0/parrot-mirai", "files": {"src/main/java/me/xpyex/plugin/parrot/mirai/module/aichat/DeepSeek.java": {"4cec5bcbc5aae0b98bbe23bd48eb43b3468d6088": {"t": 1785746120.88448, "n": 14507, "h": "ab217b9d6f9a693e", "c": "package me.xpyex.plugin.parrot.mirai.module.aichat;\n\nimport cn.hutool.core.io.IORuntimeException;\nimport cn.hutool.core.lang.Pair;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.text.SimpleDateFormat;\nimport java.util.Arrays;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.WeakHashMap;\nimport lombok.experimental.ExtensionMethod;\nimport me.xpyex.plugin.parrot.aichat.AIRequest;\nimport me.xpyex.plugin.parrot.aichat.AIResponse;\nimport me.xpyex.plugin.parrot.api.CommandMenu;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandArguments;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandExecutor;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandNode;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.ArgParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.GroupParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.StrParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.UserParser;\nimport me.xpyex.plugin.parrot.mirai.core.module.Module;\nimport me.xpyex.plugin.parrot.mirai.core.reachable.MiraiContact;\nimport me.xpyex.plugin.parrot.aichat.message.ChatMessages;\nimport me.xpyex.plugin.parrot.aichat.message.SingleChatMessage;\nimport me.xpyex.plugin.parrot.aichat.tool.FunctionCalling;\nimport me.xpyex.plugin.parrot.aichat.tool.ParamProperties;\nimport me.xpyex.plugin.parrot.aichat.tool.Parameters;\nimport me.xpyex.plugin.parrot.aichat.tool.RequestTool;\nimport me.xpyex.plugin.parrot.mirai.module.skripthub.SearchSkriptHub;\nimport net.mamoe.mirai.contact.Contact;\nimport net.mamoe.mirai.contact.Group;\nimport net.mamoe.mirai.contact.MemberPermission;\nimport net.mamoe.mirai.contact.User;\nimport net.mamoe.mirai.message.data.ForwardMessageBuilder;\nimport net.mamoe.mirai.message.data.PlainText;\n\n@ExtensionMethod(ArgParser.class)\npublic class DeepSeek extends Module {\n private static final String DEFAULT_MSG = \"\";\n private static final String API_KEY = \"\";\n private static final SimpleDateFormat SECOND_FORMAT = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\n private static final HashMap<Long, String> GROUP_RULES = new HashMap<>();\n private static final WeakHashMap<Long, ChatMessages> CHAT_CACHE = new WeakHashMap<>();\n private static final int MAX_TALK_COUNT = 60;\n\n @Override\n public void register() throws Throwable {\n registerCommand(Contact.class,\n CommandNode.of(arguments ->\n new CommandMenu(arguments)\n .add(\"chat <Content...>\", \"和DeepSeek-Chat-v3模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reasoner <Content...>\", \"和DeepSeek-Reasoner模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reset\", \"开启新话题\")\n .add(\"reChat\", \"按照先前的话题,指定DeepSeek-Chat-v3模型重新生成\")\n .add(\"reReasoner\", \"按照先前的话题,指定DeepSeek-Reasoner模型重新生成\")\n .add(\"groupRule\", \"设定在某个群的System语句\")\n )\n .child(CommandNode.of((source, sender, arguments) -> source.sendMessage(\"你想聊些什么?😊\"))\n .notMatchedArg(new CommandExecutor<>() {\n @Override\n public void execute(MiraiContact<Contact> source, MiraiContact<User> sender, CommandArguments arguments) throws Throwable {\n if (source.isGroup() && source.getContactAsGroup().getBotPermission().getLevel() > sender.getContactAsMember().getPermission().getLevel()) {\n getEvent(source).ifPresent(msgEvent -> {\n recall(msgEvent.getSource());\n });\n }\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(sender.getId(), ChatMessages.of(SingleChatMessage.Role.system, GROUP_RULES.getOrDefault(source.getId(), DEFAULT_MSG).replace(\"<USER_NAME>\", sender.getName())));\n String userMsg = String.join(\" \", arguments.getArguments());\n\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.plus(SingleChatMessage.Role.user, userMsg);\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage obj = chatMessages.getMessage().get(i);\n if (obj.getRole() == SingleChatMessage.Role.tool) continue;\n builder.add(\n SingleChatMessage.Role.user == obj.getRole() ? sender.getContact() : getBot(),\n new PlainText(obj.getContent().isEmpty() ? \" \" : obj.getContent())\n );\n }\n\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey().isEmpty() ? \" \" : response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }\n })\n .executableCheckWithArg((source, sender, args) -> {\n if (!sender.hasPerm(getName() + \".use.\" + args.getLabelReverse(0), args.getLabelReverse(0).equalsIgnoreCase(\"reasoner\") ? null : MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + args.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n return true;\n })\n , \"chat\", \"reasoner\")\n .child(CommandNode.of((source, sender, arguments) -> {\n CHAT_CACHE.remove(sender.getId());\n source.sendMessage(\"已清除连续对话记忆\");\n }), \"reset\")\n .child(CommandNode.of((source, sender, arguments) -> {\n arguments.getArgument(0, GroupParser.class, Group.class).ifPresentOrElse(group -> {\n File ruleFile = new File(getDataFolder(), group.getId() + \".txt\");\n StrParser.class.of().parse(() -> String.join(\" \", Arrays.copyOfRange(arguments.getArguments(), 1, arguments.getArguments().length))).ifPresentOrElse(rule -> {\n try {\n Files.writeString(ruleFile.toPath(), rule, StandardCharsets.UTF_8);\n GROUP_RULES.put(group.getId(), rule);\n source.sendMessage(\"已保存规则\");\n } catch (IOException e) {\n throw new RuntimeException(e);\n }\n }, () -> {\n source.sendMessage(\"未输入具体规则,默认执行清空\");\n GROUP_RULES.remove(group.getId());\n ruleFile.delete();\n });\n }, () -> source.sendMessage(\"未输入群号\"));\n }).permission(getName() + \".setGroupRule\", MemberPermission.ADMINISTRATOR, \"不理你不理你!\"), \"groupRule\")\n .child(CommandNode.of((source, sender, arguments) -> {\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除最终的缓存\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage message = chatMessages.getMessage().get(i);\n builder.add(SingleChatMessage.Role.user == message.getRole() ? sender.getContact() : getBot(), new PlainText(message.getContent()));\n }\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0).substring(2)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }).executableCheckWithArg((source, sender, arguments) -> {\n if (!sender.hasPerm(getName() + \".use.\" + arguments.getLabelReverse(0).substring(2), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + arguments.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n if (!CHAT_CACHE.containsKey(sender.getId())) {\n source.sendMessage(\"抱歉,我已经遗忘了与您的对话...\");\n return false;\n }\n return true;\n }), \"reChat\", \"reReasoner\")\n , \"deepSeek\", \"DS\", \"深度搜索\");\n\n for (File file : getDataFolder().listFiles()) {\n GROUP_RULES.put(Long.parseLong(file.getName().split(\"\\\\.\")[0]), Files.readString(file.toPath(), StandardCharsets.UTF_8));\n }\n }\n\n private Pair<String, String> talkToDS(long id, String model) { //答复, 思考链\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(id, ChatMessages.of(SingleChatMessage.Role.system,\n GROUP_RULES.getOrDefault(id, DEFAULT_MSG)\n .replace(\"<USER_NAME>\", UserParser.class.of().parse(id).map(User::getNick).orElse(\"null\"))\n ));\n try {\n ChatMessages chatMessages = CHAT_CACHE.get(id); //获取其缓存\n\n while (chatMessages.getMessage().size() >= MAX_TALK_COUNT + 1) { //只保留指定回合的对话,第一条为System\n chatMessages.getMessage().remove(1); //0是System语句,无需移除。从1开始是对话语句\n }\n\n while (chatMessages.getMessage().size() >= 2 && chatMessages.getMessage().get(chatMessages.getMessage().size() - 1).getRole() == chatMessages.getMessage().get(chatMessages.getMessage().size() - 2).getRole()) {\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除连续的同一角色对话\n }\n\n AIResponse response =\n AIRequest.of()\n .setMessages(chatMessages)\n .setTemperature(1.65f)\n .setModel(model)\n .setTop_p(0.95f)\n .addTool(\n RequestTool.of()\n .setFunction(\n FunctionCalling.of()\n .setName(\"searchSkriptHub\")\n .setDescription(\"在SkriptHub中搜索Skript语法。仅当用户让你编写Skript脚本时,你不清楚语法的情况下调用。该方法返回一个JSONArray\")\n .setParameters(\n Parameters.of()\n .addProperty(\"keyWords\", ParamProperties.of().setType(\"array\").setDescription(\"搜索的关键词,应当为String[]数组。不可为null,不可为长度为0的数组\"))\n .addProperty(\"type\", ParamProperties.of().setType(\"array\").setDescription(\"限制搜索结果的语句类型,应当为String[]数组,允许的类型有[expression, effect, type, condition, event, section, function, structure]。不允许为null,但可以是长度为0的数组\"))\n .addProperty(\"addon\", ParamProperties.of().setType(\"array\").setDescription(\"限制搜索结果的Skript附属插件,应当为String[]数组。不可为null,但可以为长度为0的数组\"))\n )\n ),\n json -> {\n try {\n List<String> keyWord = json.getJSONArray(\"keyWords\").toList(String.class);\n List<String> addon = json.getJSONArray(\"addon\").toList(String.class);\n List<String> type = json.getJSONArray(\"type\").toList(String.class);\n return SearchSkriptHub.searchDoc(keyWord, type, addon);\n } catch (NullPointerException e) {\n return \"参数填写错误,无法搜索\";\n }\n }\n )\n .addTool(\n RequestTool.of()\n .setFunction(\n FunctionCalling.of()\n .setName(\"getCurrentTime\")\n .setDescription(\"获取当前的时间,时区为中国(东八区,UTC+8)\")\n ), json -> SECOND_FORMAT.format(new Date())\n )\n .getResponse(\"https://api.deepseek.com/chat/completions\", \"Bearer \" + API_KEY);\n if (response.getError() != null) {\n return Pair.of(\"\"\"\n DeepSeek回答时出错: %s\n 错误码: %s\n 错误类型: %s\n \"\"\".formatted(\n response.getError().getMessage(),\n response.getError().getCode(),\n response.getError().getType()\n ), null);\n }\n SingleChatMessage firstChoice = response.getChoices().get(0).getMessage();\n String gptSaid = firstChoice.getContent();\n if (gptSaid.trim().endsWith(\"<STOP_HERE>\")) {\n CHAT_CACHE.remove(id);\n return Pair.of(gptSaid.replace(\"<STOP_HERE>\", \"\\n\\n我想我们需要换个新话题了\\n先前的对话记录已清除\"), null);\n }\n chatMessages.plus(SingleChatMessage.Role.assistant, gptSaid);\n return Pair.of(gptSaid, firstChoice.getReasoning_content());\n } catch (IORuntimeException e) {\n handleException(e, true, null);\n return Pair.of(\"网络异常,访问失败: \" + e, null);\n }\n }\n}\n"}, "bfc4f276a05d1538986172e2d1d48623e8e1795d": {"t": 1785759987.763121, "n": 13903, "h": "8ed43d5497fe1d56", "c": "package me.xpyex.plugin.parrot.mirai.module.aichat;\n\nimport cn.hutool.core.io.IORuntimeException;\nimport cn.hutool.core.lang.Pair;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.text.SimpleDateFormat;\nimport java.util.Arrays;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.WeakHashMap;\nimport lombok.experimental.ExtensionMethod;\nimport me.xpyex.plugin.parrot.aichat.AIRequest;\nimport me.xpyex.plugin.parrot.aichat.AIResponse;\nimport me.xpyex.plugin.parrot.api.CommandMenu;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandArguments;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandExecutor;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandNode;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.ArgParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.GroupParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.StrParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.UserParser;\nimport me.xpyex.plugin.parrot.mirai.core.module.Module;\nimport me.xpyex.plugin.parrot.mirai.core.reachable.MiraiContact;\nimport me.xpyex.plugin.parrot.aichat.message.ChatMessages;\nimport me.xpyex.plugin.parrot.aichat.message.SingleChatMessage;\nimport me.xpyex.plugin.parrot.aichat.tool.FunctionCalling;\nimport me.xpyex.plugin.parrot.aichat.tool.ParamProperties;\nimport me.xpyex.plugin.parrot.aichat.tool.Parameters;\nimport me.xpyex.plugin.parrot.aichat.tool.RequestTool;\nimport me.xpyex.plugin.parrot.mirai.module.skripthub.SearchSkriptHub;\nimport net.mamoe.mirai.contact.Contact;\nimport net.mamoe.mirai.contact.Group;\nimport net.mamoe.mirai.contact.MemberPermission;\nimport net.mamoe.mirai.contact.User;\nimport net.mamoe.mirai.message.data.ForwardMessageBuilder;\nimport net.mamoe.mirai.message.data.PlainText;\n\n@ExtensionMethod(ArgParser.class)\npublic class DeepSeek extends Module {\n private static final String DEFAULT_MSG = \"\";\n private static final String API_KEY = \"\";\n private static final SimpleDateFormat SECOND_FORMAT = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\n private static final HashMap<Long, String> GROUP_RULES = new HashMap<>();\n private static final WeakHashMap<Long, ChatMessages> CHAT_CACHE = new WeakHashMap<>();\n private static final int MAX_TALK_COUNT = 60;\n\n @Override\n public void register() throws Throwable {\n registerCommand(Contact.class,\n CommandNode.of(arguments ->\n new CommandMenu(arguments)\n .add(\"chat <Content...>\", \"和DeepSeek-Chat-v3模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reasoner <Content...>\", \"和DeepSeek-Reasoner模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reset\", \"开启新话题\")\n .add(\"reChat\", \"按照先前的话题,指定DeepSeek-Chat-v3模型重新生成\")\n .add(\"reReasoner\", \"按照先前的话题,指定DeepSeek-Reasoner模型重新生成\")\n .add(\"groupRule\", \"设定在某个群的System语句\")\n )\n .child(CommandNode.of((source, sender, arguments) -> source.sendMessage(\"你想聊些什么?😊\"))\n .notMatchedArg(new CommandExecutor<>() {\n @Override\n public void execute(MiraiContact<Contact> source, MiraiContact<User> sender, CommandArguments arguments) throws Throwable {\n if (source.isGroup() && source.getContactAsGroup().getBotPermission().getLevel() > sender.getContactAsMember().getPermission().getLevel()) {\n getEvent(source).ifPresent(msgEvent -> {\n recall(msgEvent.getSource());\n });\n }\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(sender.getId(), ChatMessages.of(SingleChatMessage.Role.system, GROUP_RULES.getOrDefault(source.getId(), DEFAULT_MSG).replace(\"<USER_NAME>\", sender.getName())));\n String userMsg = String.join(\" \", arguments.getArguments());\n\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.plus(SingleChatMessage.Role.user, userMsg);\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage obj = chatMessages.getMessage().get(i);\n if (obj.getRole() == SingleChatMessage.Role.tool) continue;\n builder.add(\n SingleChatMessage.Role.user == obj.getRole() ? sender.getContact() : getBot(),\n new PlainText(obj.getContent().isEmpty() ? \" \" : obj.getContent())\n );\n }\n\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey().isEmpty() ? \" \" : response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }\n })\n .executableCheckWithArg((source, sender, args) -> {\n if (!sender.hasPerm(getName() + \".use.\" + args.getLabelReverse(0), args.getLabelReverse(0).equalsIgnoreCase(\"reasoner\") ? null : MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + args.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n return true;\n })\n , \"chat\", \"reasoner\")\n .child(CommandNode.of((source, sender, arguments) -> {\n CHAT_CACHE.remove(sender.getId());\n source.sendMessage(\"已清除连续对话记忆\");\n }), \"reset\")\n .child(CommandNode.of((source, sender, arguments) -> {\n arguments.getArgument(0, GroupParser.class, Group.class).ifPresentOrElse(group -> {\n File ruleFile = new File(getDataFolder(), group.getId() + \".txt\");\n StrParser.class.of().parse(() -> String.join(\" \", Arrays.copyOfRange(arguments.getArguments(), 1, arguments.getArguments().length))).ifPresentOrElse(rule -> {\n try {\n Files.writeString(ruleFile.toPath(), rule, StandardCharsets.UTF_8);\n GROUP_RULES.put(group.getId(), rule);\n source.sendMessage(\"已保存规则\");\n } catch (IOException e) {\n throw new RuntimeException(e);\n }\n }, () -> {\n source.sendMessage(\"未输入具体规则,默认执行清空\");\n GROUP_RULES.remove(group.getId());\n ruleFile.delete();\n });\n }, () -> source.sendMessage(\"未输入群号\"));\n }).permission(getName() + \".setGroupRule\", MemberPermission.ADMINISTRATOR, \"不理你不理你!\"), \"groupRule\")\n .child(CommandNode.of((source, sender, arguments) -> {\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除最终的缓存\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage message = chatMessages.getMessage().get(i);\n builder.add(SingleChatMessage.Role.user == message.getRole() ? sender.getContact() : getBot(), new PlainText(message.getContent()));\n }\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0).substring(2)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }).executableCheckWithArg((source, sender, arguments) -> {\n if (!sender.hasPerm(getName() + \".use.\" + arguments.getLabelReverse(0).substring(2), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + arguments.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n if (!CHAT_CACHE.containsKey(sender.getId())) {\n source.sendMessage(\"抱歉,我已经遗忘了与您的对话...\");\n return false;\n }\n return true;\n }), \"reChat\", \"reReasoner\")\n , \"deepSeek\", \"DS\", \"深度搜索\");\n\n for (File file : getDataFolder().listFiles()) {\n GROUP_RULES.put(Long.parseLong(file.getName().split(\"\\\\.\")[0]), Files.readString(file.toPath(), StandardCharsets.UTF_8));\n }\n }\n\n private Pair<String, String> talkToDS(long id, String model) { //答复, 思考链\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(id, ChatMessages.of(SingleChatMessage.Role.system,\n GROUP_RULES.getOrDefault(id, DEFAULT_MSG)\n .replace(\"<USER_NAME>\", UserParser.class.of().parse(id).map(User::getNick).orElse(\"null\"))\n ));\n try {\n ChatMessages chatMessages = CHAT_CACHE.get(id); //获取其缓存\n\n while (chatMessages.getMessage().size() >= MAX_TALK_COUNT + 1) { //只保留指定回合的对话,第一条为System\n chatMessages.getMessage().remove(1); //0是System语句,无需移除。从1开始是对话语句\n }\n\n while (chatMessages.getMessage().size() >= 2 && chatMessages.getMessage().get(chatMessages.getMessage().size() - 1).getRole() == chatMessages.getMessage().get(chatMessages.getMessage().size() - 2).getRole()) {\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除连续的同一角色对话\n }\n\n AIResponse response =\n AIRequest.of()\n .setMessages(chatMessages)\n .setTemperature(1.65f)\n .setModel(model)\n .setTop_p(0.95f)\n .addTool(\n RequestTool.of()\n .setFunction(\n FunctionCalling.of()\n .setName(\"searchSkriptHub\")\n .setDescription(\"在SkriptHub中搜索Skript语法。仅当用户让你编写Skript脚本时,你不清楚语法的情况下调用。该方法返回一个JSONArray\")\n .setParameters(\n Parameters.of()\n .addProperty(\"keyWords\", ParamProperties.of().setType(\"array\").setDescription(\"搜索的关键词,应当为String[]数组。不可为null,不可为长度为0的数组\"))\n .addProperty(\"type\", ParamProperties.of().setType(\"array\").setDescription(\"限制搜索结果的语句类型,应当为String[]数组,允许的类型有[expression, effect, type, condition, event, section, function, structure]。不允许为null,但可以是长度为0的数组\"))\n .addProperty(\"addon\", ParamProperties.of().setType(\"array\").setDescription(\"限制搜索结果的Skript附属插件,应当为String[]数组。不可为null,但可以为长度为0的数组\"))\n )\n ),\n json -> {\n List<String> keyWord = json.getJSONArray(\"keyWords\").toList(String.class);\n List<String> addon = json.getJSONArray(\"addon\").toList(String.class);\n List<String> type = json.getJSONArray(\"type\").toList(String.class);\n return SearchSkriptHub.searchDoc(keyWord, type, addon);\n }\n )\n .addTool(\n RequestTool.of()\n .setFunction(\n FunctionCalling.of()\n .setName(\"getCurrentTime\")\n .setDescription(\"获取当前的时间,时区为中国(东八区,UTC+8)\")\n ), json -> SECOND_FORMAT.format(new Date())\n )\n .getResponse(\"https://api.deepseek.com/chat/completions\", \"Bearer \" + API_KEY);\n SingleChatMessage firstChoice = response.getChoices().get(0).getMessage();\n String gptSaid = firstChoice.getContent();\n if (gptSaid.trim().endsWith(\"<STOP_HERE>\")) {\n CHAT_CACHE.remove(id);\n return Pair.of(gptSaid.replace(\"<STOP_HERE>\", \"\\n\\n我想我们需要换个新话题了\\n先前的对话记录已清除\"), null);\n }\n chatMessages.plus(SingleChatMessage.Role.assistant, gptSaid);\n return Pair.of(gptSaid, firstChoice.getReasoning_content());\n } catch (IORuntimeException e) {\n handleException(e, true, null);\n return Pair.of(\"网络异常,访问失败: \" + e, null);\n }\n }\n}\n"}, "ca968706f517d5a54aeab4f5f68ea87d717e1fc5": {"t": 1785759989.4183016, "n": 13424, "h": "0113403dc7febc52", "c": "package me.xpyex.plugin.parrot.mirai.module.aichat;\n\nimport cn.hutool.core.io.IORuntimeException;\nimport cn.hutool.core.lang.Pair;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.text.SimpleDateFormat;\nimport java.util.Arrays;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.WeakHashMap;\nimport lombok.experimental.ExtensionMethod;\nimport me.xpyex.plugin.parrot.aichat.AIRequest;\nimport me.xpyex.plugin.parrot.aichat.AIResponse;\nimport me.xpyex.plugin.parrot.api.CommandMenu;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandArguments;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandExecutor;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandNode;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.ArgParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.GroupParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.StrParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.UserParser;\nimport me.xpyex.plugin.parrot.mirai.core.module.Module;\nimport me.xpyex.plugin.parrot.mirai.core.reachable.MiraiContact;\nimport me.xpyex.plugin.parrot.aichat.message.ChatMessages;\nimport me.xpyex.plugin.parrot.aichat.message.SingleChatMessage;\nimport me.xpyex.plugin.parrot.aichat.tool.FunctionCalling;\nimport me.xpyex.plugin.parrot.aichat.tool.ParamProperties;\nimport me.xpyex.plugin.parrot.aichat.tool.Parameters;\nimport me.xpyex.plugin.parrot.aichat.tool.RequestTool;\nimport net.mamoe.mirai.contact.Contact;\nimport net.mamoe.mirai.contact.Group;\nimport net.mamoe.mirai.contact.MemberPermission;\nimport net.mamoe.mirai.contact.User;\nimport net.mamoe.mirai.message.data.ForwardMessageBuilder;\nimport net.mamoe.mirai.message.data.PlainText;\n\n@ExtensionMethod(ArgParser.class)\npublic class DeepSeek extends Module {\n private static final String DEFAULT_MSG = \"\";\n private static final String API_KEY = \"\";\n private static final SimpleDateFormat SECOND_FORMAT = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\n private static final HashMap<Long, String> GROUP_RULES = new HashMap<>();\n private static final WeakHashMap<Long, ChatMessages> CHAT_CACHE = new WeakHashMap<>();\n private static final int MAX_TALK_COUNT = 60;\n\n @Override\n public void register() throws Throwable {\n AIRequest.getFunctions().put(\"getCurrentTime\", json -> SECOND_FORMAT.format(new Date()));\n registerCommand(Contact.class,\n CommandNode.of(arguments ->\n new CommandMenu(arguments)\n .add(\"chat <Content...>\", \"和DeepSeek-Chat-v3模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reasoner <Content...>\", \"和DeepSeek-Reasoner模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reset\", \"开启新话题\")\n .add(\"reChat\", \"按照先前的话题,指定DeepSeek-Chat-v3模型重新生成\")\n .add(\"reReasoner\", \"按照先前的话题,指定DeepSeek-Reasoner模型重新生成\")\n .add(\"groupRule\", \"设定在某个群的System语句\")\n )\n .child(CommandNode.of((source, sender, arguments) -> source.sendMessage(\"你想聊些什么?😊\"))\n .notMatchedArg(new CommandExecutor<>() {\n @Override\n public void execute(MiraiContact<Contact> source, MiraiContact<User> sender, CommandArguments arguments) throws Throwable {\n if (source.isGroup() && source.getContactAsGroup().getBotPermission().getLevel() > sender.getContactAsMember().getPermission().getLevel()) {\n getEvent(source).ifPresent(msgEvent -> {\n recall(msgEvent.getSource());\n });\n }\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(sender.getId(), ChatMessages.of(SingleChatMessage.Role.system, GROUP_RULES.getOrDefault(source.getId(), DEFAULT_MSG).replace(\"<USER_NAME>\", sender.getName())));\n String userMsg = String.join(\" \", arguments.getArguments());\n\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.plus(SingleChatMessage.Role.user, userMsg);\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage obj = chatMessages.getMessage().get(i);\n if (obj.getRole() == SingleChatMessage.Role.tool) continue;\n builder.add(\n SingleChatMessage.Role.user == obj.getRole() ? sender.getContact() : getBot(),\n new PlainText(obj.getContent().isEmpty() ? \" \" : obj.getContent())\n );\n }\n\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey().isEmpty() ? \" \" : response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }\n })\n .executableCheckWithArg((source, sender, args) -> {\n if (!sender.hasPerm(getName() + \".use.\" + args.getLabelReverse(0), args.getLabelReverse(0).equalsIgnoreCase(\"reasoner\") ? null : MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + args.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n return true;\n })\n , \"chat\", \"reasoner\")\n .child(CommandNode.of((source, sender, arguments) -> {\n CHAT_CACHE.remove(sender.getId());\n source.sendMessage(\"已清除连续对话记忆\");\n }), \"reset\")\n .child(CommandNode.of((source, sender, arguments) -> {\n arguments.getArgument(0, GroupParser.class, Group.class).ifPresentOrElse(group -> {\n File ruleFile = new File(getDataFolder(), group.getId() + \".txt\");\n StrParser.class.of().parse(() -> String.join(\" \", Arrays.copyOfRange(arguments.getArguments(), 1, arguments.getArguments().length))).ifPresentOrElse(rule -> {\n try {\n Files.writeString(ruleFile.toPath(), rule, StandardCharsets.UTF_8);\n GROUP_RULES.put(group.getId(), rule);\n source.sendMessage(\"已保存规则\");\n } catch (IOException e) {\n throw new RuntimeException(e);\n }\n }, () -> {\n source.sendMessage(\"未输入具体规则,默认执行清空\");\n GROUP_RULES.remove(group.getId());\n ruleFile.delete();\n });\n }, () -> source.sendMessage(\"未输入群号\"));\n }).permission(getName() + \".setGroupRule\", MemberPermission.ADMINISTRATOR, \"不理你不理你!\"), \"groupRule\")\n .child(CommandNode.of((source, sender, arguments) -> {\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除最终的缓存\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage message = chatMessages.getMessage().get(i);\n builder.add(SingleChatMessage.Role.user == message.getRole() ? sender.getContact() : getBot(), new PlainText(message.getContent()));\n }\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0).substring(2)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }).executableCheckWithArg((source, sender, arguments) -> {\n if (!sender.hasPerm(getName() + \".use.\" + arguments.getLabelReverse(0).substring(2), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + arguments.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n if (!CHAT_CACHE.containsKey(sender.getId())) {\n source.sendMessage(\"抱歉,我已经遗忘了与您的对话...\");\n return false;\n }\n return true;\n }), \"reChat\", \"reReasoner\")\n , \"deepSeek\", \"DS\", \"深度搜索\");\n\n for (File file : getDataFolder().listFiles()) {\n GROUP_RULES.put(Long.parseLong(file.getName().split(\"\\\\.\")[0]), Files.readString(file.toPath(), StandardCharsets.UTF_8));\n }\n }\n\n private Pair<String, String> talkToDS(long id, String model) { //答复, 思考链\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(id, ChatMessages.of(SingleChatMessage.Role.system,\n GROUP_RULES.getOrDefault(id, DEFAULT_MSG)\n .replace(\"<USER_NAME>\", UserParser.class.of().parse(id).map(User::getNick).orElse(\"null\"))\n ));\n try {\n ChatMessages chatMessages = CHAT_CACHE.get(id); //获取其缓存\n\n while (chatMessages.getMessage().size() >= MAX_TALK_COUNT + 1) { //只保留指定回合的对话,第一条为System\n chatMessages.getMessage().remove(1); //0是System语句,无需移除。从1开始是对话语句\n }\n\n while (chatMessages.getMessage().size() >= 2 && chatMessages.getMessage().get(chatMessages.getMessage().size() - 1).getRole() == chatMessages.getMessage().get(chatMessages.getMessage().size() - 2).getRole()) {\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除连续的同一角色对话\n }\n\n AIResponse response =\n AIRequest.of()\n .setMessages(chatMessages)\n .setTemperature(1.65f)\n .setModel(model)\n .setTop_p(0.95f)\n .addTool(\n RequestTool.of()\n .setFunction(\n FunctionCalling.of()\n .setName(\"searchSkriptHub\")\n .setDescription(\"在SkriptHub中搜索Skript语法。仅当用户让你编写Skript脚本时,你不清楚语法的情况下调用。该方法返回一个JSONArray\")\n .setParameters(\n Parameters.of()\n .addProperty(\"keyWords\", ParamProperties.of().setType(\"array\").setDescription(\"搜索的关键词,应当为String[]数组。不可为null,不可为长度为0的数组\"))\n .addProperty(\"type\", ParamProperties.of().setType(\"array\").setDescription(\"限制搜索结果的语句类型,应当为String[]数组,允许的类型有[expression, effect, type, condition, event, section, function, structure]。不允许为null,但可以是长度为0的数组\"))\n .addProperty(\"addon\", ParamProperties.of().setType(\"array\").setDescription(\"限制搜索结果的Skript附属插件,应当为String[]数组。不可为null,但可以为长度为0的数组\"))\n )\n )\n )\n .addTool(\n RequestTool.of()\n .setFunction(\n FunctionCalling.of()\n .setName(\"getCurrentTime\")\n .setDescription(\"获取当前的时间,时区为中国(东八区,UTC+8)\")\n )\n )\n .getResponse(\"https://api.deepseek.com/chat/completions\", \"Bearer \" + API_KEY);\n SingleChatMessage firstChoice = response.getChoices().get(0).getMessage();\n String gptSaid = firstChoice.getContent();\n if (gptSaid.trim().endsWith(\"<STOP_HERE>\")) {\n CHAT_CACHE.remove(id);\n return Pair.of(gptSaid.replace(\"<STOP_HERE>\", \"\\n\\n我想我们需要换个新话题了\\n先前的对话记录已清除\"), null);\n }\n chatMessages.plus(SingleChatMessage.Role.assistant, gptSaid);\n return Pair.of(gptSaid, firstChoice.getReasoning_content());\n } catch (IORuntimeException e) {\n handleException(e, true, null);\n return Pair.of(\"网络异常,访问失败: \" + e, null);\n }\n }\n}\n"}, "bb2c2a90616ad6cac3f307790877f33eaf5cc57d": {"t": 1785759991.0622897, "n": 13405, "h": "4b1688d32747b88b", "c": "package me.xpyex.plugin.parrot.mirai.module.aichat;\n\nimport cn.hutool.core.io.IORuntimeException;\nimport cn.hutool.core.lang.Pair;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.text.SimpleDateFormat;\nimport java.util.Arrays;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.WeakHashMap;\nimport lombok.experimental.ExtensionMethod;\nimport me.xpyex.plugin.parrot.api.CommandMenu;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandArguments;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandExecutor;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandNode;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.ArgParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.GroupParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.StrParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.UserParser;\nimport me.xpyex.plugin.parrot.mirai.core.module.Module;\nimport me.xpyex.plugin.parrot.mirai.core.reachable.MiraiContact;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.message.ChatMessages;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.message.SingleChatMessage;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.tool.FunctionCalling;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.tool.ParamProperties;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.tool.Parameters;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.tool.RequestTool;\nimport net.mamoe.mirai.contact.Contact;\nimport net.mamoe.mirai.contact.Group;\nimport net.mamoe.mirai.contact.MemberPermission;\nimport net.mamoe.mirai.contact.User;\nimport net.mamoe.mirai.message.data.ForwardMessageBuilder;\nimport net.mamoe.mirai.message.data.PlainText;\n\n@ExtensionMethod(ArgParser.class)\npublic class DeepSeek extends Module {\n private static final String DEFAULT_MSG = \"\";\n private static final String API_KEY = \"\";\n private static final SimpleDateFormat SECOND_FORMAT = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\n private static final HashMap<Long, String> GROUP_RULES = new HashMap<>();\n private static final WeakHashMap<Long, ChatMessages> CHAT_CACHE = new WeakHashMap<>();\n private static final int MAX_TALK_COUNT = 60;\n\n @Override\n public void register() throws Throwable {\n AIRequest.getFunctions().put(\"getCurrentTime\", json -> SECOND_FORMAT.format(new Date()));\n registerCommand(Contact.class,\n CommandNode.of(arguments ->\n new CommandMenu(arguments)\n .add(\"chat <Content...>\", \"和DeepSeek-Chat-v3模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reasoner <Content...>\", \"和DeepSeek-Reasoner模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reset\", \"开启新话题\")\n .add(\"reChat\", \"按照先前的话题,指定DeepSeek-Chat-v3模型重新生成\")\n .add(\"reReasoner\", \"按照先前的话题,指定DeepSeek-Reasoner模型重新生成\")\n .add(\"groupRule\", \"设定在某个群的System语句\")\n )\n .child(CommandNode.of((source, sender, arguments) -> source.sendMessage(\"你想聊些什么?😊\"))\n .notMatchedArg(new CommandExecutor<>() {\n @Override\n public void execute(MiraiContact<Contact> source, MiraiContact<User> sender, CommandArguments arguments) throws Throwable {\n if (source.isGroup() && source.getContactAsGroup().getBotPermission().getLevel() > sender.getContactAsMember().getPermission().getLevel()) {\n getEvent(source).ifPresent(msgEvent -> {\n recall(msgEvent.getSource());\n });\n }\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(sender.getId(), ChatMessages.of(SingleChatMessage.Role.system, GROUP_RULES.getOrDefault(source.getId(), DEFAULT_MSG).replace(\"<USER_NAME>\", sender.getName())));\n String userMsg = String.join(\" \", arguments.getArguments());\n\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.plus(SingleChatMessage.Role.user, userMsg);\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage obj = chatMessages.getMessage().get(i);\n if (obj.getRole() == SingleChatMessage.Role.tool) continue;\n builder.add(\n SingleChatMessage.Role.user == obj.getRole() ? sender.getContact() : getBot(),\n new PlainText(obj.getContent().isEmpty() ? \" \" : obj.getContent())\n );\n }\n\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey().isEmpty() ? \" \" : response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }\n })\n .executableCheckWithArg((source, sender, args) -> {\n if (!sender.hasPerm(getName() + \".use.\" + args.getLabelReverse(0), args.getLabelReverse(0).equalsIgnoreCase(\"reasoner\") ? null : MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + args.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n return true;\n })\n , \"chat\", \"reasoner\")\n .child(CommandNode.of((source, sender, arguments) -> {\n CHAT_CACHE.remove(sender.getId());\n source.sendMessage(\"已清除连续对话记忆\");\n }), \"reset\")\n .child(CommandNode.of((source, sender, arguments) -> {\n arguments.getArgument(0, GroupParser.class, Group.class).ifPresentOrElse(group -> {\n File ruleFile = new File(getDataFolder(), group.getId() + \".txt\");\n StrParser.class.of().parse(() -> String.join(\" \", Arrays.copyOfRange(arguments.getArguments(), 1, arguments.getArguments().length))).ifPresentOrElse(rule -> {\n try {\n Files.writeString(ruleFile.toPath(), rule, StandardCharsets.UTF_8);\n GROUP_RULES.put(group.getId(), rule);\n source.sendMessage(\"已保存规则\");\n } catch (IOException e) {\n throw new RuntimeException(e);\n }\n }, () -> {\n source.sendMessage(\"未输入具体规则,默认执行清空\");\n GROUP_RULES.remove(group.getId());\n ruleFile.delete();\n });\n }, () -> source.sendMessage(\"未输入群号\"));\n }).permission(getName() + \".setGroupRule\", MemberPermission.ADMINISTRATOR, \"不理你不理你!\"), \"groupRule\")\n .child(CommandNode.of((source, sender, arguments) -> {\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除最终的缓存\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage message = chatMessages.getMessage().get(i);\n builder.add(SingleChatMessage.Role.user == message.getRole() ? sender.getContact() : getBot(), new PlainText(message.getContent()));\n }\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0).substring(2)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }).executableCheckWithArg((source, sender, arguments) -> {\n if (!sender.hasPerm(getName() + \".use.\" + arguments.getLabelReverse(0).substring(2), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + arguments.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n if (!CHAT_CACHE.containsKey(sender.getId())) {\n source.sendMessage(\"抱歉,我已经遗忘了与您的对话...\");\n return false;\n }\n return true;\n }), \"reChat\", \"reReasoner\")\n , \"deepSeek\", \"DS\", \"深度搜索\");\n\n for (File file : getDataFolder().listFiles()) {\n GROUP_RULES.put(Long.parseLong(file.getName().split(\"\\\\.\")[0]), Files.readString(file.toPath(), StandardCharsets.UTF_8));\n }\n }\n\n private Pair<String, String> talkToDS(long id, String model) { //答复, 思考链\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(id, ChatMessages.of(SingleChatMessage.Role.system,\n GROUP_RULES.getOrDefault(id, DEFAULT_MSG)\n .replace(\"<USER_NAME>\", UserParser.class.of().parse(id).map(User::getNick).orElse(\"null\"))\n ));\n try {\n ChatMessages chatMessages = CHAT_CACHE.get(id); //获取其缓存\n\n while (chatMessages.getMessage().size() >= MAX_TALK_COUNT + 1) { //只保留指定回合的对话,第一条为System\n chatMessages.getMessage().remove(1); //0是System语句,无需移除。从1开始是对话语句\n }\n\n while (chatMessages.getMessage().size() >= 2 && chatMessages.getMessage().get(chatMessages.getMessage().size() - 1).getRole() == chatMessages.getMessage().get(chatMessages.getMessage().size() - 2).getRole()) {\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除连续的同一角色对话\n }\n\n AIResponse response =\n AIRequest.of()\n .setMessages(chatMessages)\n .setTemperature(1.65f)\n .setModel(model)\n .setTop_p(0.95f)\n .addTool(\n RequestTool.of()\n .setFunction(\n FunctionCalling.of()\n .setName(\"searchSkriptHub\")\n .setDescription(\"在SkriptHub中搜索Skript语法。仅当用户让你编写Skript脚本时,你不清楚语法的情况下调用。该方法返回一个JSONArray\")\n .setParameters(\n Parameters.of()\n .addProperty(\"keyWords\", ParamProperties.of().setType(\"array\").setDescription(\"搜索的关键词,应当为String[]数组。不可为null,不可为长度为0的数组\"))\n .addProperty(\"type\", ParamProperties.of().setType(\"array\").setDescription(\"限制搜索结果的语句类型,应当为String[]数组,允许的类型有[expression, effect, type, condition, event, section, function, structure]。不允许为null,但可以是长度为0的数组\"))\n .addProperty(\"addon\", ParamProperties.of().setType(\"array\").setDescription(\"限制搜索结果的Skript附属插件,应当为String[]数组。不可为null,但可以为长度为0的数组\"))\n )\n )\n )\n .addTool(\n RequestTool.of()\n .setFunction(\n FunctionCalling.of()\n .setName(\"getCurrentTime\")\n .setDescription(\"获取当前的时间,时区为中国(东八区,UTC+8)\")\n )\n )\n .getResponse(\"https://api.deepseek.com/chat/completions\", \"Bearer \" + API_KEY);\n SingleChatMessage firstChoice = response.getChoices().get(0).getMessage();\n String gptSaid = firstChoice.getContent();\n if (gptSaid.trim().endsWith(\"<STOP_HERE>\")) {\n CHAT_CACHE.remove(id);\n return Pair.of(gptSaid.replace(\"<STOP_HERE>\", \"\\n\\n我想我们需要换个新话题了\\n先前的对话记录已清除\"), null);\n }\n chatMessages.plus(SingleChatMessage.Role.assistant, gptSaid);\n return Pair.of(gptSaid, firstChoice.getReasoning_content());\n } catch (IORuntimeException e) {\n handleException(e, true, null);\n return Pair.of(\"网络异常,访问失败: \" + e, null);\n }\n }\n}\n"}, "3d848768b7e467d3f1bb5047dbd5addc781111bf": {"t": 1785759992.7338758, "n": 13199, "h": "4ed092d134d6a1f1", "c": "package me.xpyex.plugin.parrot.mirai.module.aichat;\n\nimport cn.hutool.core.io.IORuntimeException;\nimport cn.hutool.core.lang.Pair;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.text.SimpleDateFormat;\nimport java.util.Arrays;\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.WeakHashMap;\nimport lombok.experimental.ExtensionMethod;\nimport me.xpyex.plugin.parrot.api.CommandMenu;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandArguments;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandExecutor;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandNode;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.ArgParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.GroupParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.StrParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.UserParser;\nimport me.xpyex.plugin.parrot.mirai.core.module.Module;\nimport me.xpyex.plugin.parrot.mirai.core.reachable.MiraiContact;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.message.ChatMessages;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.message.SingleChatMessage;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.tool.FunctionCalling;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.tool.ParamProperties;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.tool.Parameters;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.tool.RequestTool;\nimport net.mamoe.mirai.contact.Contact;\nimport net.mamoe.mirai.contact.Group;\nimport net.mamoe.mirai.contact.MemberPermission;\nimport net.mamoe.mirai.contact.User;\nimport net.mamoe.mirai.message.data.ForwardMessageBuilder;\nimport net.mamoe.mirai.message.data.PlainText;\n\n@ExtensionMethod(ArgParser.class)\npublic class DeepSeek extends Module {\n private static final String DEFAULT_MSG = \"\";\n private static final String API_KEY = \"\";\n private static final SimpleDateFormat SECOND_FORMAT = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\n private static final HashMap<Long, String> GROUP_RULES = new HashMap<>();\n private static final WeakHashMap<Long, ChatMessages> CHAT_CACHE = new WeakHashMap<>();\n private static final int MAX_TALK_COUNT = 60;\n\n @Override\n public void register() throws Throwable {\n AIRequest.getFunctions().put(\"getCurrentTime\", json -> SECOND_FORMAT.format(new Date()));\n registerCommand(Contact.class,\n CommandNode.of(arguments ->\n new CommandMenu(arguments)\n .add(\"chat <Content...>\", \"和DeepSeek-Chat-v3模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reasoner <Content...>\", \"和DeepSeek-Reasoner模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reset\", \"开启新话题\")\n .add(\"reChat\", \"按照先前的话题,指定DeepSeek-Chat-v3模型重新生成\")\n .add(\"reReasoner\", \"按照先前的话题,指定DeepSeek-Reasoner模型重新生成\")\n .add(\"groupRule\", \"设定在某个群的System语句\")\n )\n .child(CommandNode.of((source, sender, arguments) -> source.sendMessage(\"你想聊些什么?😊\"))\n .notMatchedArg(new CommandExecutor<>() {\n @Override\n public void execute(MiraiContact<Contact> source, MiraiContact<User> sender, CommandArguments arguments) throws Throwable {\n if (source.isGroup() && source.getContactAsGroup().getBotPermission().getLevel() > sender.getContactAsMember().getPermission().getLevel()) {\n getEvent(source).ifPresent(msgEvent -> {\n recall(msgEvent.getSource());\n });\n }\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(sender.getId(), ChatMessages.of(SingleChatMessage.Role.system, GROUP_RULES.getOrDefault(source.getId(), DEFAULT_MSG).replace(\"<USER_NAME>\", sender.getName())));\n String userMsg = String.join(\" \", arguments.getArguments());\n\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.plus(SingleChatMessage.Role.user, userMsg);\n\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase());\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage obj = chatMessages.getMessage().get(i);\n if (obj.getRole() == SingleChatMessage.Role.tool) continue;\n if (obj.getContent().trim().isEmpty()) continue;\n builder.add(SingleChatMessage.Role.user == obj.getRole() ? sender.getContact() : getBot(), new PlainText(obj.getContent()));\n }\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }\n })\n .executableCheckWithArg((source, sender, args) -> {\n if (!sender.hasPerm(getName() + \".use.\" + args.getLabelReverse(0), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + args.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n return true;\n })\n , \"chat\", \"reasoner\")\n .child(CommandNode.of((source, sender, arguments) -> {\n CHAT_CACHE.remove(sender.getId());\n source.sendMessage(\"已清除连续对话记忆\");\n }), \"reset\")\n .child(CommandNode.of((source, sender, arguments) -> {\n arguments.getArgument(0, GroupParser.class, Group.class).ifPresentOrElse(group -> {\n File ruleFile = new File(getDataFolder(), group.getId() + \".txt\");\n StrParser.class.of().parse(() -> String.join(\" \", Arrays.copyOfRange(arguments.getArguments(), 1, arguments.getArguments().length))).ifPresentOrElse(rule -> {\n try {\n Files.writeString(ruleFile.toPath(), rule, StandardCharsets.UTF_8);\n GROUP_RULES.put(group.getId(), rule);\n source.sendMessage(\"已保存规则\");\n } catch (IOException e) {\n throw new RuntimeException(e);\n }\n }, () -> {\n source.sendMessage(\"未输入具体规则,默认执行清空\");\n GROUP_RULES.remove(group.getId());\n ruleFile.delete();\n });\n }, () -> source.sendMessage(\"未输入群号\"));\n }).permission(getName() + \".setGroupRule\", MemberPermission.ADMINISTRATOR, \"不理你不理你!\"), \"groupRule\")\n .child(CommandNode.of((source, sender, arguments) -> {\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除最终的缓存\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage message = chatMessages.getMessage().get(i);\n builder.add(SingleChatMessage.Role.user == message.getRole() ? sender.getContact() : getBot(), new PlainText(message.getContent()));\n }\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0).substring(2)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }).executableCheckWithArg((source, sender, arguments) -> {\n if (!sender.hasPerm(getName() + \".use.\" + arguments.getLabelReverse(0).substring(2), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + arguments.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n if (!CHAT_CACHE.containsKey(sender.getId())) {\n source.sendMessage(\"抱歉,我已经遗忘了与您的对话...\");\n return false;\n }\n return true;\n }), \"reChat\", \"reReasoner\")\n , \"deepSeek\", \"DS\", \"深度搜索\");\n\n for (File file : getDataFolder().listFiles()) {\n GROUP_RULES.put(Long.parseLong(file.getName().split(\"\\\\.\")[0]), Files.readString(file.toPath(), StandardCharsets.UTF_8));\n }\n }\n\n private Pair<String, String> talkToDS(long id, String model) { //答复, 思考链\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(id, ChatMessages.of(SingleChatMessage.Role.system, GROUP_RULES.getOrDefault(id, DEFAULT_MSG)\n .replace(\"<USER_NAME>\", UserParser.class.of().parse(id).map(User::getNick).orElse(\"null\"))\n ));\n try {\n ChatMessages chatMessages = CHAT_CACHE.get(id); //获取其缓存\n\n while (chatMessages.getMessage().size() >= MAX_TALK_COUNT + 1) { //只保留指定回合的对话,第一条为System\n chatMessages.getMessage().remove(1); //0是System语句,无需移除。从1开始是对话语句\n }\n\n while (chatMessages.getMessage().size() >= 2 && chatMessages.getMessage().get(chatMessages.getMessage().size() - 1).getRole() == chatMessages.getMessage().get(chatMessages.getMessage().size() - 2).getRole()) {\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除连续的同一角色对话\n }\n\n AIResponse response =\n AIRequest.of()\n .setMessages(chatMessages)\n .setTemperature(1.65f)\n .setModel(model)\n .setTop_p(0.95f)\n .addTool(\n RequestTool.of()\n .setFunction(\n FunctionCalling.of()\n .setName(\"searchSkriptHub\")\n .setDescription(\"在SkriptHub中搜索Skript语法。仅当用户让你编写Skript脚本时,你不清楚语法的情况下调用。该方法返回一个JSONArray\")\n .setParameters(\n Parameters.of()\n .addProperty(\"keyWords\", ParamProperties.of().setType(\"array\").setDescription(\"搜索的关键词,应当为String[]数组。不可为null,不可为长度为0的数组\"))\n .addProperty(\"type\", ParamProperties.of().setType(\"array\").setDescription(\"限制搜索结果的语句类型,应当为String[]数组,允许的类型有[expression, effect, type, condition, event, section, function, structure]。不允许为null,但可以是长度为0的数组\"))\n .addProperty(\"addon\", ParamProperties.of().setType(\"array\").setDescription(\"限制搜索结果的Skript附属插件,应当为String[]数组。不可为null,但可以为长度为0的数组\"))\n )\n )\n )\n .addTool(\n RequestTool.of()\n .setFunction(\n FunctionCalling.of()\n .setName(\"getCurrentTime\")\n .setDescription(\"获取当前的时间,时区为中国(东八区,UTC+8)\")\n )\n )\n .getResponse(\"https://api.deepseek.com/chat/completions\", \"Bearer \" + API_KEY);\n SingleChatMessage firstChoice = response.getChoices().get(0).getMessage();\n String gptSaid = firstChoice.getContent();\n if (gptSaid.trim().endsWith(\"<STOP_HERE>\")) {\n CHAT_CACHE.remove(id);\n return Pair.of(gptSaid.replace(\"<STOP_HERE>\", \"\\n\\n我想我们需要换个新话题了\\n先前的对话记录已清除\"), null);\n }\n chatMessages.plus(SingleChatMessage.Role.assistant, gptSaid);\n return Pair.of(gptSaid, firstChoice.getReasoning_content());\n } catch (IORuntimeException e) {\n handleException(e, true, null);\n return Pair.of(\"网络异常,访问失败: \" + e, null);\n }\n }\n}\n"}, "f3f7bfbe6e3de28b0e744d80f06d443cc6151b41": {"t": 1785759994.3538642, "n": 11664, "h": "5b8bb848b46d1129", "c": "package me.xpyex.plugin.parrot.mirai.module.aichat;\n\nimport cn.hutool.core.io.IORuntimeException;\nimport cn.hutool.core.lang.Pair;\nimport cn.hutool.http.HttpUtil;\nimport cn.hutool.json.JSONUtil;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.WeakHashMap;\nimport lombok.experimental.ExtensionMethod;\nimport me.xpyex.plugin.parrot.api.CommandMenu;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandArguments;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandExecutor;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandNode;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.ArgParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.GroupParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.StrParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.UserParser;\nimport me.xpyex.plugin.parrot.mirai.core.module.Module;\nimport me.xpyex.plugin.parrot.mirai.core.reachable.MiraiContact;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.message.ChatMessages;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.message.SingleChatMessage;\nimport net.mamoe.mirai.contact.Contact;\nimport net.mamoe.mirai.contact.Group;\nimport net.mamoe.mirai.contact.MemberPermission;\nimport net.mamoe.mirai.contact.User;\nimport net.mamoe.mirai.message.data.ForwardMessageBuilder;\nimport net.mamoe.mirai.message.data.PlainText;\n\n@ExtensionMethod(ArgParser.class)\npublic class DeepSeek extends Module {\n private static final String DEFAULT_MSG = \"\";\n private static final String API_KEY = \"\";\n private static final HashMap<Long, String> GROUP_RULES = new HashMap<>();\n private static final WeakHashMap<Long, ChatMessages> CHAT_CACHE = new WeakHashMap<>();\n private static final int MAX_TALK_COUNT = 60;\n\n @Override\n public void register() throws Throwable {\n registerCommand(Contact.class,\n CommandNode.of(arguments ->\n new CommandMenu(arguments)\n .add(\"chat <Content...>\", \"和DeepSeek-Chat-v3模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reasoner <Content...>\", \"和DeepSeek-Reasoner模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reset\", \"开启新话题\")\n .add(\"reChat\", \"按照先前的话题,指定DeepSeek-Chat-v3模型重新生成\")\n .add(\"reReasoner\", \"按照先前的话题,指定DeepSeek-Reasoner模型重新生成\")\n .add(\"groupRule\", \"设定在某个群的System语句\")\n )\n .child(CommandNode.of((source, sender, arguments) -> source.sendMessage(\"你想聊些什么?😊\"))\n .notMatchedArg(new CommandExecutor<>() {\n @Override\n public void execute(MiraiContact<Contact> source, MiraiContact<User> sender, CommandArguments arguments) throws Throwable {\n if (source.isGroup() && source.getContactAsGroup().getBotPermission().getLevel() > sender.getContactAsMember().getPermission().getLevel()) {\n getEvent(source).ifPresent(msgEvent -> {\n recall(msgEvent.getSource());\n });\n }\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(sender.getId(), ChatMessages.of(SingleChatMessage.Role.system, GROUP_RULES.getOrDefault(source.getId(), DEFAULT_MSG).replace(\"<USER_NAME>\", sender.getName())));\n String userMsg = String.join(\" \", arguments.getArguments());\n\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.plus(SingleChatMessage.Role.user, userMsg);\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage obj = chatMessages.getMessage().get(i);\n builder.add(SingleChatMessage.Role.user == obj.getRole() ? sender.getContact() : getBot(), new PlainText(obj.getContent()));\n }\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }\n })\n .executableCheckWithArg((source, sender, args) -> {\n if (!sender.hasPerm(getName() + \".use.\" + args.getLabelReverse(0), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + args.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n return true;\n })\n , \"chat\", \"reasoner\")\n .child(CommandNode.of((source, sender, arguments) -> {\n CHAT_CACHE.remove(sender.getId());\n source.sendMessage(\"已清除连续对话记忆\");\n }), \"reset\")\n .child(CommandNode.of((source, sender, arguments) -> {\n arguments.getArgument(0, GroupParser.class, Group.class).ifPresentOrElse(group -> {\n File ruleFile = new File(getDataFolder(), group.getId() + \".txt\");\n StrParser.class.of().parse(() -> String.join(\" \", Arrays.copyOfRange(arguments.getArguments(), 1, arguments.getArguments().length))).ifPresentOrElse(rule -> {\n try {\n Files.writeString(ruleFile.toPath(), rule, StandardCharsets.UTF_8);\n GROUP_RULES.put(group.getId(), rule);\n source.sendMessage(\"已保存规则\");\n } catch (IOException e) {\n throw new RuntimeException(e);\n }\n }, () -> {\n source.sendMessage(\"未输入具体规则,默认执行清空\");\n GROUP_RULES.remove(group.getId());\n ruleFile.delete();\n });\n }, () -> source.sendMessage(\"未输入群号\"));\n }).permission(getName() + \".setGroupRule\", MemberPermission.ADMINISTRATOR, \"不理你不理你!\"), \"groupRule\")\n .child(CommandNode.of((source, sender, arguments) -> {\n boolean is3 = \"reGo\".equalsIgnoreCase(arguments.getLabelReverse(0));\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除最终的缓存\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage message = chatMessages.getMessage().get(i);\n builder.add(SingleChatMessage.Role.user == message.getRole() ? sender.getContact() : getBot(), new PlainText(message.getContent()));\n }\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }).executableCheckWithArg((source, sender, arguments) -> {\n if (!sender.hasPerm(getName() + \".use.\" + arguments.getLabelReverse(0).substring(2), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + arguments.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n if (!CHAT_CACHE.containsKey(sender.getId())) {\n source.sendMessage(\"抱歉,我已经遗忘了与您的对话...\");\n return false;\n }\n return true;\n }), \"reChat\", \"reReasoner\")\n , \"deepSeek\", \"DS\", \"深度搜索\");\n\n for (File file : getDataFolder().listFiles()) {\n GROUP_RULES.put(Long.parseLong(file.getName().split(\"\\\\.\")[0]), Files.readString(file.toPath(), StandardCharsets.UTF_8));\n }\n }\n\n private Pair<String, String> talkToDS(long id, String model) { //答复, 思考链\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(id, ChatMessages.of(SingleChatMessage.Role.system, GROUP_RULES.getOrDefault(id, DEFAULT_MSG).replace(\"<USER_NAME>\", UserParser.class.of().parse(id).map(User::getNick).orElse(\"null\"))));\n try {\n ChatMessages chatMessages = CHAT_CACHE.get(id); //获取其缓存\n\n while (chatMessages.getMessage().size() >= MAX_TALK_COUNT + 1) { //只保留指定回合的对话,第一条为System\n chatMessages.getMessage().remove(1); //0是System语句,无需移除。从1开始是对话语句\n }\n\n while (chatMessages.getMessage().size() >= 2 && chatMessages.getMessage().get(chatMessages.getMessage().size() - 1).getRole() == chatMessages.getMessage().get(chatMessages.getMessage().size() - 2).getRole()) {\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除连续的同一角色对话\n }\n\n String result = HttpUtil.createPost(\"https://api.deepseek.com/chat/completions\")\n .contentType(\"application/json\")\n .auth(\"Bearer \" + API_KEY)\n .body(info(JSONUtil.toJsonPrettyStr(\n AIRequest.of()\n .setMessages(chatMessages)\n .setTemperature(1.65f)\n .setModel(model)\n .setTop_p(0.95f)\n )\n )\n )\n .execute()\n .body();\n AIResponse response = JSONUtil.toBean(info(result.trim()), AIResponse.class);\n SingleChatMessage firstChoice = response.getChoices().get(0).getMessage();\n String gptSaid = firstChoice.getContent();\n if (gptSaid.trim().endsWith(\"<STOP_HERE>\")) {\n CHAT_CACHE.remove(id);\n return Pair.of(gptSaid.replace(\"<STOP_HERE>\", \"\\n\\n我想我们需要换个新话题了\\n先前的对话记录已清除\"), null);\n }\n chatMessages.plus(SingleChatMessage.Role.assistant, gptSaid);\n return Pair.of(gptSaid, firstChoice.getReasoning_content());\n } catch (IORuntimeException e) {\n handleException(e, true, null);\n return Pair.of(\"网络异常,访问失败: \" + e, null);\n }\n }\n}\n"}, "3cc9e400a16183eb91734f1c67efa76a9db9b871": {"t": 1785759996.1578484, "n": 11324, "h": "c41f4bebf2515955", "c": "package me.xpyex.plugin.parrot.mirai.module.aichat;\n\nimport cn.hutool.core.io.IORuntimeException;\nimport cn.hutool.core.lang.Pair;\nimport cn.hutool.http.HttpUtil;\nimport cn.hutool.json.JSONUtil;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.WeakHashMap;\nimport lombok.experimental.ExtensionMethod;\nimport me.xpyex.plugin.parrot.api.CommandMenu;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandArguments;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandExecutor;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandNode;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.ArgParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.GroupParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.StrParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.UserParser;\nimport me.xpyex.plugin.parrot.mirai.core.module.Module;\nimport me.xpyex.plugin.parrot.mirai.core.reachable.MiraiContact;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.message.ChatMessages;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.message.SingleChatMessage;\nimport net.mamoe.mirai.contact.Contact;\nimport net.mamoe.mirai.contact.Group;\nimport net.mamoe.mirai.contact.MemberPermission;\nimport net.mamoe.mirai.contact.User;\nimport net.mamoe.mirai.message.data.ForwardMessageBuilder;\nimport net.mamoe.mirai.message.data.PlainText;\n\n@ExtensionMethod(ArgParser.class)\npublic class DeepSeek extends Module {\n private static final String DEFAULT_MSG = \"\";\n private static final String API_KEY = \"\";\n private static final HashMap<Long, String> GROUP_RULES = new HashMap<>();\n private static final WeakHashMap<Long, ChatMessages> CHAT_CACHE = new WeakHashMap<>();\n private static final int MAX_TALK_COUNT = 60;\n\n @Override\n public void register() throws Throwable {\n registerCommand(Contact.class,\n CommandNode.of(arguments ->\n new CommandMenu(arguments)\n .add(\"chat <Content...>\", \"和DeepSeek-Chat-v3模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reasoner <Content...>\", \"和DeepSeek-Reasoner模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reset\", \"开启新话题\")\n .add(\"reChat\", \"按照先前的话题,指定DeepSeek-Chat-v3模型重新生成\")\n .add(\"reReasoner\", \"按照先前的话题,指定DeepSeek-Reasoner模型重新生成\")\n .add(\"groupRule\", \"设定在某个群的System语句\")\n )\n .child(CommandNode.of((source, sender, arguments) -> source.sendMessage(\"你想聊些什么?😊\"))\n .notMatchedArg(new CommandExecutor<>() {\n @Override\n public void execute(MiraiContact<Contact> source, MiraiContact<User> sender, CommandArguments arguments) throws Throwable {\n if (source.isGroup() && source.getContactAsGroup().getBotPermission().getLevel() > sender.getContactAsMember().getPermission().getLevel()) {\n getEvent(source).ifPresent(msgEvent -> {\n recall(msgEvent.getSource());\n });\n }\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(sender.getId(), ChatMessages.of(SingleChatMessage.Role.system, GROUP_RULES.getOrDefault(source.getId(), DEFAULT_MSG).replace(\"<USER_NAME>\", sender.getName())));\n String userMsg = String.join(\" \", arguments.getArguments());\n\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.plus(SingleChatMessage.Role.user, userMsg);\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage obj = chatMessages.getMessage().get(i);\n builder.add(SingleChatMessage.Role.user == obj.getRole() ? sender.getContact() : getBot(), new PlainText(obj.getContent()));\n }\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }\n })\n .executableCheckWithArg((source, sender, args) -> {\n if (!sender.hasPerm(getName() + \".use.\" + args.getLabelReverse(0), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + args.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n return true;\n })\n , \"chat\", \"reasoner\")\n .child(CommandNode.of((source, sender, arguments) -> {\n CHAT_CACHE.remove(sender.getId());\n source.sendMessage(\"已清除连续对话记忆\");\n }), \"reset\")\n .child(CommandNode.of((source, sender, arguments) -> {\n arguments.getArgument(0, GroupParser.class, Group.class).ifPresentOrElse(group -> {\n File ruleFile = new File(getDataFolder(), group.getId() + \".txt\");\n StrParser.class.of().parse(() -> String.join(\" \", Arrays.copyOfRange(arguments.getArguments(), 1, arguments.getArguments().length))).ifPresentOrElse(rule -> {\n try {\n Files.writeString(ruleFile.toPath(), rule, StandardCharsets.UTF_8);\n GROUP_RULES.put(group.getId(), rule);\n source.sendMessage(\"已保存规则\");\n } catch (IOException e) {\n throw new RuntimeException(e);\n }\n }, () -> {\n source.sendMessage(\"未输入具体规则,默认执行清空\");\n GROUP_RULES.remove(group.getId());\n ruleFile.delete();\n });\n }, () -> source.sendMessage(\"未输入群号\"));\n }).permission(getName() + \".setGroupRule\", MemberPermission.ADMINISTRATOR, \"不理你不理你!\"), \"groupRule\")\n .child(CommandNode.of((source, sender, arguments) -> {\n boolean is3 = \"reGo\".equalsIgnoreCase(arguments.getLabelReverse(0));\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除最终的缓存\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage message = chatMessages.getMessage().get(i);\n builder.add(SingleChatMessage.Role.user == message.getRole() ? sender.getContact() : getBot(), new PlainText(message.getContent()));\n }\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }).executableCheckWithArg((source, sender, arguments) -> {\n if (!sender.hasPerm(getName() + \".use.\" + arguments.getLabelReverse(0).substring(2), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + arguments.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n if (!CHAT_CACHE.containsKey(sender.getId())) {\n source.sendMessage(\"抱歉,我已经遗忘了与您的对话...\");\n return false;\n }\n return true;\n }), \"reChat\", \"reReasoner\")\n , \"deepSeek\", \"DS\", \"深度搜索\");\n\n for (File file : getDataFolder().listFiles()) {\n GROUP_RULES.put(Long.parseLong(file.getName().split(\"\\\\.\")[0]), Files.readString(file.toPath(), StandardCharsets.UTF_8));\n }\n }\n\n private Pair<String, String> talkToDS(long id, String model) { //答复, 思考链\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(id, ChatMessages.of(SingleChatMessage.Role.system, GROUP_RULES.getOrDefault(id, DEFAULT_MSG).replace(\"<USER_NAME>\", UserParser.class.of().parse(id).map(User::getNick).orElse(\"null\"))));\n try {\n ChatMessages chatMessages = CHAT_CACHE.get(id); //获取其缓存\n\n while (chatMessages.getMessage().size() >= MAX_TALK_COUNT + 1) { //只保留指定回合的对话,第一条为System\n chatMessages.getMessage().remove(1); //0是System语句,无需移除。从1开始是对话语句\n }\n\n String result = HttpUtil.createPost(\"https://api.deepseek.com/chat/completions\")\n .contentType(\"application/json\")\n .auth(\"Bearer \" + API_KEY)\n .body(info(JSONUtil.toJsonPrettyStr(\n AIRequest.of()\n .setMessages(chatMessages)\n .setTemperature(1.65f)\n .setModel(model)\n .setTop_p(0.95f)\n )\n )\n )\n .execute()\n .body();\n AIResponse response = JSONUtil.toBean(info(result.trim()), AIResponse.class);\n SingleChatMessage firstChoice = response.getChoices().get(0).getMessage();\n String gptSaid = firstChoice.getContent();\n if (gptSaid.trim().endsWith(\"<STOP_HERE>\")) {\n CHAT_CACHE.remove(id);\n return Pair.of(gptSaid.replace(\"<STOP_HERE>\", \"\\n\\n我想我们需要换个新话题了\\n先前的对话记录已清除\"), null);\n }\n chatMessages.plus(SingleChatMessage.Role.assistant, gptSaid);\n return Pair.of(gptSaid, firstChoice.getReasoning_content());\n } catch (IORuntimeException e) {\n handleException(e, true, null);\n return Pair.of(\"网络异常,访问失败: \" + e, null);\n }\n }\n}\n"}, "f7b16672758157df702101d5a5de0b9a1a88e9e3": {"t": 1785759997.6440363, "n": 11099, "h": "9fa44e84b6c53c9f", "c": "package me.xpyex.plugin.parrot.mirai.module.aichat;\n\nimport cn.hutool.core.io.IORuntimeException;\nimport cn.hutool.core.lang.Pair;\nimport cn.hutool.http.HttpUtil;\nimport cn.hutool.json.JSONUtil;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.WeakHashMap;\nimport lombok.experimental.ExtensionMethod;\nimport me.xpyex.plugin.parrot.api.CommandMenu;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandArguments;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandExecutor;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandNode;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.ArgParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.GroupParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.StrParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.UserParser;\nimport me.xpyex.plugin.parrot.mirai.core.module.Module;\nimport me.xpyex.plugin.parrot.mirai.core.reachable.MiraiContact;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.message.ChatMessages;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.message.SingleChatMessage;\nimport net.mamoe.mirai.contact.Contact;\nimport net.mamoe.mirai.contact.Group;\nimport net.mamoe.mirai.contact.MemberPermission;\nimport net.mamoe.mirai.contact.User;\nimport net.mamoe.mirai.message.data.ForwardMessageBuilder;\nimport net.mamoe.mirai.message.data.PlainText;\n\n@ExtensionMethod(ArgParser.class)\npublic class DeepSeek extends Module {\n private static final String DEFAULT_MSG = \"\";\n private static final String API_KEY = \"\";\n private static final HashMap<Long, String> GROUP_RULES = new HashMap<>();\n private static final WeakHashMap<Long, ChatMessages> CHAT_CACHE = new WeakHashMap<>();\n private static final int MAX_TALK_COUNT = 60;\n\n @Override\n public void register() throws Throwable {\n registerCommand(Contact.class,\n CommandNode.of(arguments ->\n new CommandMenu(arguments)\n .add(\"chat <Content...>\", \"和DeepSeek-Chat-v3模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reasoner <Content...>\", \"和DeepSeek-Reasoner模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reset\", \"开启新话题\")\n .add(\"reChat\", \"按照先前的话题,指定DeepSeek-Chat-v3模型重新生成\")\n .add(\"reReasoner\", \"按照先前的话题,指定DeepSeek-Reasoner模型重新生成\")\n .add(\"groupRule\", \"设定在某个群的System语句\")\n )\n .child(CommandNode.of((source, sender, arguments) -> source.sendMessage(\"你想聊些什么?😊\"))\n .notMatchedArg(new CommandExecutor<>() {\n @Override\n public void execute(MiraiContact<Contact> source, MiraiContact<User> sender, CommandArguments arguments) throws Throwable {\n if (source.isGroup() && source.getContactAsGroup().getBotPermission().getLevel() > sender.getContactAsMember().getPermission().getLevel()) {\n getEvent(source).ifPresent(msgEvent -> {\n recall(msgEvent.getSource());\n });\n }\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(sender.getId(), ChatMessages.of(SingleChatMessage.Role.system, GROUP_RULES.getOrDefault(source.getId(), DEFAULT_MSG).replace(\"<USER_NAME>\", sender.getName())));\n String userMsg = String.join(\" \", arguments.getArguments());\n\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.plus(SingleChatMessage.Role.user, userMsg);\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage obj = chatMessages.getMessage().get(i);\n builder.add(SingleChatMessage.Role.user == obj.getRole() ? sender.getContact() : getBot(), new PlainText(obj.getContent()));\n }\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }\n })\n .executableCheckWithArg((source, sender, args) -> {\n if (!sender.hasPerm(getName() + \".use.\" + args.getLabelReverse(0), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + args.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n return true;\n })\n , \"chat\", \"reasoner\")\n .child(CommandNode.of((source, sender, arguments) -> {\n CHAT_CACHE.remove(sender.getId());\n source.sendMessage(\"已清除连续对话记忆\");\n }), \"reset\")\n .child(CommandNode.of((source, sender, arguments) -> {\n arguments.getArgument(0, GroupParser.class, Group.class).ifPresentOrElse(group -> {\n StrParser.class.of().parse(() -> String.join(\" \", Arrays.copyOfRange(arguments.getArguments(), 1, arguments.getArguments().length))).ifPresentOrElse(rule -> {\n try {\n Files.writeString(new File(getDataFolder(), group.getId() + \".txt\").toPath(), rule, StandardCharsets.UTF_8);\n GROUP_RULES.put(group.getId(), rule);\n source.sendMessage(\"已保存规则\");\n } catch (IOException e) {\n throw new RuntimeException(e);\n }\n }, () -> source.sendMessage(\"未输入具体规则\"));\n }, () -> source.sendMessage(\"未输入群号\"));\n }).permission(getName() + \".setGroupRule\", MemberPermission.ADMINISTRATOR, \"不理你不理你!\"), \"groupRule\")\n .child(CommandNode.of((source, sender, arguments) -> {\n boolean is3 = \"reGo\".equalsIgnoreCase(arguments.getLabelReverse(0));\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除最终的缓存\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage message = chatMessages.getMessage().get(i);\n builder.add(SingleChatMessage.Role.user == message.getRole() ? sender.getContact() : getBot(), new PlainText(message.getContent()));\n }\n Pair<String, String> response = talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase());\n builder.add(getBot(), new PlainText(response.getKey()));\n if (response.getValue() != null)\n builder.add(getBot(), new PlainText(\"思绪:\\n\" + response.getValue()));\n source.sendMessage(builder.build());\n }).executableCheckWithArg((source, sender, arguments) -> {\n if (!sender.hasPerm(getName() + \".use.\" + arguments.getLabelReverse(0).substring(2), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + arguments.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n if (!CHAT_CACHE.containsKey(sender.getId())) {\n source.sendMessage(\"抱歉,我已经遗忘了与您的对话...\");\n return false;\n }\n return true;\n }), \"reChat\", \"reReasoner\")\n , \"deepSeek\", \"DS\", \"深度搜索\");\n\n for (File file : getDataFolder().listFiles()) {\n GROUP_RULES.put(Long.parseLong(file.getName().split(\"\\\\.\")[0]), Files.readString(file.toPath(), StandardCharsets.UTF_8));\n }\n }\n\n private Pair<String, String> talkToDS(long id, String model) { //答复,思考链\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(id, ChatMessages.of(SingleChatMessage.Role.system, GROUP_RULES.getOrDefault(id, DEFAULT_MSG).replace(\"<USER_NAME>\", UserParser.class.of().parse(id).map(User::getNick).orElse(\"null\"))));\n try {\n ChatMessages chatMessages = CHAT_CACHE.get(id); //获取其缓存\n\n while (chatMessages.getMessage().size() >= MAX_TALK_COUNT + 1) { //只保留指定回合的对话,第一条为System\n chatMessages.getMessage().remove(1); //0是System语句,无需移除。从1开始是对话语句\n }\n\n String result = HttpUtil.createPost(\"https://api.deepseek.com/chat/completions\")\n .contentType(\"application/json\")\n .auth(\"Bearer \" + API_KEY)\n .body(info(JSONUtil.toJsonPrettyStr(\n AIRequest.of()\n .setMessages(chatMessages)\n .setTemperature(1.65f)\n .setModel(model)\n .setTop_p(0.95f)\n )\n )\n )\n .execute()\n .body();\n AIResponse response = JSONUtil.toBean(info(result.trim()), AIResponse.class);\n SingleChatMessage firstChoice = response.getChoices().get(0).getMessage();\n String gptSaid = firstChoice.getContent();\n if (gptSaid.trim().endsWith(\"<STOP_HERE>\")) {\n CHAT_CACHE.remove(id);\n return Pair.of(gptSaid.replace(\"<STOP_HERE>\", \"\\n\\n我想我们需要换个新话题了\\n先前的对话记录已清除\"), null);\n }\n chatMessages.plus(SingleChatMessage.Role.assistant, gptSaid);\n return Pair.of(gptSaid, firstChoice.getReasoning_content());\n } catch (IORuntimeException e) {\n handleException(e, true, null);\n return Pair.of(\"网络异常,访问失败: \" + e, null);\n }\n }\n}\n"}, "85ca73c4cf034aca65d8725647f8bcea4a52e7fc": {"t": 1785759999.168402, "n": 10202, "h": "68c24ab7718f19bf", "c": "package me.xpyex.plugin.parrot.mirai.module.aichat;\n\nimport cn.hutool.core.io.IORuntimeException;\nimport cn.hutool.http.HttpUtil;\nimport cn.hutool.json.JSONUtil;\nimport java.io.File;\nimport java.io.IOException;\nimport java.nio.charset.StandardCharsets;\nimport java.nio.file.Files;\nimport java.util.Arrays;\nimport java.util.HashMap;\nimport java.util.WeakHashMap;\nimport lombok.experimental.ExtensionMethod;\nimport me.xpyex.plugin.parrot.api.CommandMenu;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandArguments;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandExecutor;\nimport me.xpyex.plugin.parrot.mirai.core.command.CommandNode;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.ArgParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.GroupParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.StrParser;\nimport me.xpyex.plugin.parrot.mirai.core.command.parsers.UserParser;\nimport me.xpyex.plugin.parrot.mirai.core.module.Module;\nimport me.xpyex.plugin.parrot.mirai.core.reachable.MiraiContact;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.message.ChatMessages;\nimport me.xpyex.plugin.parrot.mirai.module.aichat.message.SingleChatMessage;\nimport net.mamoe.mirai.contact.Contact;\nimport net.mamoe.mirai.contact.Group;\nimport net.mamoe.mirai.contact.MemberPermission;\nimport net.mamoe.mirai.contact.User;\nimport net.mamoe.mirai.message.data.ForwardMessageBuilder;\nimport net.mamoe.mirai.message.data.PlainText;\n\n@ExtensionMethod(ArgParser.class)\npublic class DeepSeek extends Module {\n private static final String DEFAULT_MSG = \"\";\n private static final String API_KEY = \"\";\n private static final HashMap<Long, String> GROUP_RULES = new HashMap<>();\n private static final WeakHashMap<Long, ChatMessages> CHAT_CACHE = new WeakHashMap<>();\n private static final int MAX_TALK_COUNT = 60;\n\n @Override\n public void register() throws Throwable {\n registerCommand(Contact.class,\n CommandNode.of(arguments ->\n new CommandMenu(arguments)\n .add(\"chat <Content...>\", \"和DeepSeek-Chat-v3模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reasoner <Content...>\", \"和DeepSeek-Reasoner模型对话,每次对话保留\" + MAX_TALK_COUNT / 2 + \" 回合\")\n .add(\"reset\", \"开启新话题\")\n .add(\"reChat\", \"按照先前的话题,指定DeepSeek-Chat-v3模型重新生成\")\n .add(\"reReasoner\", \"按照先前的话题,指定DeepSeek-Reasoner模型重新生成\")\n .add(\"groupRule\", \"设定在某个群的System语句\")\n )\n .child(CommandNode.of((source, sender, arguments) -> source.sendMessage(\"你想聊些什么?😊\"))\n .notMatchedArg(new CommandExecutor<>() {\n @Override\n public void execute(MiraiContact<Contact> source, MiraiContact<User> sender, CommandArguments arguments) throws Throwable {\n if (source.isGroup() && source.getContactAsGroup().getBotPermission().getLevel() > sender.getContactAsMember().getPermission().getLevel()) {\n getEvent(source).ifPresent(msgEvent -> {\n recall(msgEvent.getSource());\n });\n }\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(sender.getId(), ChatMessages.of(ChatMessages.Role.SYSTEM, GROUP_RULES.getOrDefault(source.getId(), DEFAULT_MSG).replace(\"<USER_NAME>\", sender.getName())));\n String userMsg = String.join(\" \", arguments.getArguments());\n\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.plus(ChatMessages.Role.USER, userMsg);\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage obj = chatMessages.getMessage().get(i);\n builder.add(ChatMessages.Role.USER == obj.getRole() ? sender.getContact() : getBot(), new PlainText(obj.getContent()));\n }\n builder.add(getBot(), new PlainText(talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase())));\n source.sendMessage(builder.build());\n }\n })\n .executableCheckWithArg((source, sender, args) -> {\n if (!sender.hasPerm(getName() + \".use.\" + args.getLabelReverse(0), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + args.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n return true;\n })\n , \"chat\", \"reasoner\")\n .child(CommandNode.of((source, sender, arguments) -> {\n CHAT_CACHE.remove(sender.getId());\n source.sendMessage(\"已清除连续对话记忆\");\n }), \"reset\")\n .child(CommandNode.of((source, sender, arguments) -> {\n arguments.getArgument(0, GroupParser.class, Group.class).ifPresentOrElse(group -> {\n StrParser.class.of().parse(() -> String.join(\" \", Arrays.copyOfRange(arguments.getArguments(), 1, arguments.getArguments().length))).ifPresentOrElse(rule -> {\n try {\n Files.writeString(new File(getDataFolder(), group.getId() + \".txt\").toPath(), rule, StandardCharsets.UTF_8);\n GROUP_RULES.put(group.getId(), rule);\n source.sendMessage(\"已保存规则\");\n } catch (IOException e) {\n throw new RuntimeException(e);\n }\n }, () -> source.sendMessage(\"未输入具体规则\"));\n }, () -> source.sendMessage(\"未输入群号\"));\n }).permission(getName() + \".setGroupRule\", MemberPermission.ADMINISTRATOR, \"不理你不理你!\"), \"groupRule\")\n .child(CommandNode.of((source, sender, arguments) -> {\n boolean is3 = \"reGo\".equalsIgnoreCase(arguments.getLabelReverse(0));\n ChatMessages chatMessages = CHAT_CACHE.get(sender.getId()); //获取其缓存\n chatMessages.getMessage().remove(chatMessages.getMessage().size() - 1); //清除最终的缓存\n\n ForwardMessageBuilder builder = new ForwardMessageBuilder(source.getContact());\n for (int i = 1; i < chatMessages.getMessage().size(); i++) {\n SingleChatMessage message = chatMessages.getMessage().get(i);\n builder.add(ChatMessages.Role.USER == message.getRole() ? sender.getContact() : getBot(), new PlainText(message.getContent()));\n }\n builder.add(getBot(), new PlainText(talkToDS(sender.getId(), (\"DeepSeek-\" + arguments.getLabelReverse(0)).toLowerCase())));\n source.sendMessage(builder.build());\n }).executableCheckWithArg((source, sender, arguments) -> {\n if (!sender.hasPerm(getName() + \".use.\" + arguments.getLabelReverse(0).substring(2), MemberPermission.ADMINISTRATOR)) {\n source.sendMessage(\"你没有使用DeepSeek-\" + arguments.getLabelReverse(0) + \"模型的权限\");\n return false;\n }\n if (!CHAT_CACHE.containsKey(sender.getId())) {\n source.sendMessage(\"抱歉,我已经遗忘了与您的对话...\");\n return false;\n }\n return true;\n }), \"reChat\", \"reReasoner\")\n , \"deepSeek\", \"DS\", \"深度搜索\");\n\n for (File file : getDataFolder().listFiles()) {\n GROUP_RULES.put(Long.parseLong(file.getName().split(\"\\\\.\")[0]), Files.readString(file.toPath(), StandardCharsets.UTF_8));\n }\n }\n\n private String talkToDS(long id, String model) {\n //若还没有聊过天,则新建缓存\n CHAT_CACHE.putIfAbsent(id, ChatMessages.of(ChatMessages.Role.SYSTEM, GROUP_RULES.getOrDefault(id, DEFAULT_MSG).replace(\"<USER_NAME>\", UserParser.class.of().parse(id).map(User::getNick).orElse(\"null\"))));\n try {\n ChatMessages chatMessages = CHAT_CACHE.get(id); //获取其缓存\n\n while (chatMessages.getMessage().size() >= MAX_TALK_COUNT + 1) { //只保留指定回合的对话,第一条为System\n chatMessages.getMessage().remove(1); //0是System语句,无需移除。从1开始是对话语句\n }\n\n String result = HttpUtil.createPost(\"https://api.deepseek.com/chat/completions\")\n .contentType(\"application/json\")\n .auth(\"Bearer \" + API_KEY)\n .body(info(JSONUtil.toJsonPrettyStr(\n AIRequest.of().setTemperature(1.65f)\n .setTop_p(0.95f)\n .setMessages(chatMessages))))\n .execute()\n .body();\n AIResponse response = JSONUtil.toBean(result, AIResponse.class);\n String gptSaid = response.getChoices()\n .get(0)\n .getMessage()\n .getContent();\n if (gptSaid.trim().endsWith(\"<STOP_HERE>\")) {\n CHAT_CACHE.remove(id);\n return gptSaid.replace(\"<STOP_HERE>\", \"\\n\\n我想我们需要换个新话题了\\n先前的对话记录已清除\");\n }\n chatMessages.plus(ChatMessages.Role.ASSISTANT, gptSaid);\n return gptSaid;\n } catch (IORuntimeException e) {\n handleException(e, true, null);\n return \"网络异常,访问失败: \" + e;\n }\n }\n}\n"}}}}