alemonjs-aichat 1.0.26 → 1.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,6 +4,7 @@ import fs from 'fs';
4
4
  import { uploadImageToR2 } from '../s3.js';
5
5
  import { TTSClient } from './tts.js';
6
6
  import { loadSkillDetail } from './loadSkill.js';
7
+ import help from '../data/help.json.js';
7
8
 
8
9
  const value = getConfigValue().aiChat || {};
9
10
  const getPrompt = async (text) => {
@@ -209,6 +210,17 @@ const tools = [
209
210
  },
210
211
  },
211
212
  },
213
+ {
214
+ type: "function",
215
+ function: {
216
+ name: "GetCommand",
217
+ description: "获取当前框架可用的指令, 查看当前框架每个命令的使用方法和说明. 当用户需要获取指令列表时, 可以调用这个工具来获取当前框架可用的指令列表. 例如, 当用户输入'帮助'或'指令列表'等类似的关键词时, 你可以调用这个工具来获取指令列表并回复给用户. 指令列表会包含每个指令的文本和说明, 例如: [{ command: '帮助', description: '获取帮助信息' }, { command: '看看配置', description: '查看当前AI配置' }]",
218
+ parameters: {
219
+ type: "object",
220
+ properties: {},
221
+ },
222
+ },
223
+ },
212
224
  ];
213
225
  const availableTools = {
214
226
  /**
@@ -653,6 +665,14 @@ const availableTools = {
653
665
  const skill = loadSkillDetail(skillName);
654
666
  return skill;
655
667
  },
668
+ /**
669
+ * 获取Help命令列表
670
+ * @returns Help命令列表
671
+ * 命令列表格式: [{ command: "命令文本", description: "命令说明" }]
672
+ */
673
+ GetCommand: async () => {
674
+ return help;
675
+ },
656
676
  };
657
677
 
658
678
  export { availableTools, tools };
@@ -0,0 +1 @@
1
+ *,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }/*! tailwindcss v3.4.19 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-feature-settings:normal;font-variation-settings:normal;-moz-tab-size:4;tab-size:4;-webkit-tap-highlight-color:transparent}body{line-height:inherit}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-size:1em;font-variation-settings:normal}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-feature-settings:inherit;font-size:100%;font-variation-settings:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]:where(:not([hidden=until-found])){display:none}.absolute{position:absolute}.relative{position:relative}.-left-4{left:-1rem}.-top-4{top:-1rem}.-z-0{z-index:0}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.box-border{box-sizing:border-box}.flex{display:flex}.grid{display:grid}.hidden{display:none}.h-0\.5{height:.125rem}.h-1\.5{height:.375rem}.h-24{height:6rem}.min-h-\[120px\]{min-height:120px}.w-1\.5{width:.375rem}.w-1\/3{width:33.333333%}.w-12{width:3rem}.w-20{width:5rem}.w-24{width:6rem}.auto-rows-auto{grid-auto-rows:auto}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-between{justify-content:space-between}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(.75rem*var(--tw-space-y-reverse));margin-top:calc(.75rem*(1 - var(--tw-space-y-reverse)))}.self-start{align-self:flex-start}.overflow-hidden{overflow:hidden}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-amber-400\/20{border-color:rgba(251,191,36,.2)}.border-amber-400\/30{border-color:rgba(251,191,36,.3)}.border-blue-500\/30{border-color:rgba(59,130,246,.3)}.border-green-500\/30{border-color:rgba(34,197,94,.3)}.border-purple-400\/30{border-color:rgba(192,132,252,.3)}.border-red-500\/20{border-color:rgba(239,68,68,.2)}.border-white\/10{border-color:hsla(0,0%,100%,.1)}.border-white\/20{border-color:hsla(0,0%,100%,.2)}.border-yellow-500\/30{border-color:rgba(234,179,8,.3)}.bg-amber-400{--tw-bg-opacity:1;background-color:rgb(251 191 36/var(--tw-bg-opacity,1))}.bg-amber-500\/10{background-color:rgba(245,158,11,.1)}.bg-amber-500\/20{background-color:rgba(245,158,11,.2)}.bg-black\/30{background-color:rgba(0,0,0,.3)}.bg-black\/60{background-color:rgba(0,0,0,.6)}.bg-blue-400{--tw-bg-opacity:1;background-color:rgb(96 165 250/var(--tw-bg-opacity,1))}.bg-blue-500\/20{background-color:rgba(59,130,246,.2)}.bg-green-400{--tw-bg-opacity:1;background-color:rgb(74 222 128/var(--tw-bg-opacity,1))}.bg-green-500\/20{background-color:rgba(34,197,94,.2)}.bg-purple-400\/20{background-color:rgba(192,132,252,.2)}.bg-red-500\/10{background-color:rgba(239,68,68,.1)}.bg-white\/30{background-color:hsla(0,0%,100%,.3)}.bg-white\/5{background-color:hsla(0,0%,100%,.05)}.bg-yellow-500\/20{background-color:rgba(234,179,8,.2)}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-amber-300{--tw-gradient-from:#fcd34d var(--tw-gradient-from-position);--tw-gradient-to:rgba(252,211,77,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-amber-400{--tw-gradient-from:#fbbf24 var(--tw-gradient-from-position);--tw-gradient-to:rgba(251,191,36,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-gray-900\/90{--tw-gradient-from:rgba(17,24,39,.9) var(--tw-gradient-from-position);--tw-gradient-to:rgba(17,24,39,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.from-purple-500\/20{--tw-gradient-from:rgba(168,85,247,.2) var(--tw-gradient-from-position);--tw-gradient-to:rgba(168,85,247,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.via-yellow-200{--tw-gradient-to:hsla(53,98%,77%,0) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),#fef08a var(--tw-gradient-via-position),var(--tw-gradient-to)}.to-amber-300{--tw-gradient-to:#fcd34d var(--tw-gradient-to-position)}.to-black\/80{--tw-gradient-to:rgba(0,0,0,.8) var(--tw-gradient-to-position)}.to-pink-500\/20{--tw-gradient-to:rgba(236,72,153,.2) var(--tw-gradient-to-position)}.to-purple-400{--tw-gradient-to:#c084fc var(--tw-gradient-to-position)}.bg-cover{background-size:cover}.bg-clip-text{background-clip:text}.p-2{padding:.5rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-0\.5{padding-bottom:.125rem;padding-top:.125rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.pl-1{padding-left:.25rem}.pt-2{padding-top:.5rem}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.italic{font-style:italic}.leading-relaxed{line-height:1.625}.tracking-wide{letter-spacing:.025em}.text-\[\#B8AE8E\]{--tw-text-opacity:1;color:rgb(184 174 142/var(--tw-text-opacity,1))}.text-amber-100{--tw-text-opacity:1;color:rgb(254 243 199/var(--tw-text-opacity,1))}.text-amber-200{--tw-text-opacity:1;color:rgb(253 230 138/var(--tw-text-opacity,1))}.text-amber-300{--tw-text-opacity:1;color:rgb(252 211 77/var(--tw-text-opacity,1))}.text-blue-300{--tw-text-opacity:1;color:rgb(147 197 253/var(--tw-text-opacity,1))}.text-green-300{--tw-text-opacity:1;color:rgb(134 239 172/var(--tw-text-opacity,1))}.text-purple-200{--tw-text-opacity:1;color:rgb(233 213 255/var(--tw-text-opacity,1))}.text-red-300{--tw-text-opacity:1;color:rgb(252 165 165/var(--tw-text-opacity,1))}.text-transparent{color:transparent}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity,1))}.text-white\/40{color:hsla(0,0%,100%,.4)}.text-white\/50{color:hsla(0,0%,100%,.5)}.text-white\/60{color:hsla(0,0%,100%,.6)}.text-white\/70{color:hsla(0,0%,100%,.7)}.text-white\/80{color:hsla(0,0%,100%,.8)}.text-yellow-300{--tw-text-opacity:1;color:rgb(253 224 71/var(--tw-text-opacity,1))}.shadow-xl{--tw-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 8px 10px -6px rgba(0,0,0,.1);--tw-shadow-colored:0 20px 25px -5px var(--tw-shadow-color),0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.blur-2xl{--tw-blur:blur(40px)}.blur-2xl,.drop-shadow-lg{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.drop-shadow-lg{--tw-drop-shadow:drop-shadow(0 10px 8px rgba(0,0,0,.04)) drop-shadow(0 4px 3px rgba(0,0,0,.1))}.backdrop-blur-md{--tw-backdrop-blur:blur(12px)}.backdrop-blur-md,.backdrop-blur-sm{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur:blur(4px)}.transition-colors{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1)}body{display:flex;flex-direction:column;margin:0;padding:0}.backdrop-blur-xs{backdrop-filter:blur(4px)}.last\:border-0:last-child{border-width:0}.hover\:bg-white\/5:hover{background-color:hsla(0,0%,100%,.05)}@media (min-width:640px){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:768px){.md\:block{display:block}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:border-l{border-left-width:1px}.md\:border-r-0{border-right-width:0}}
@@ -1,4 +1,4 @@
1
1
  const reg = ['win32'].includes(process.platform) ? /^file:\/\/\// : /^file:\/\// ;
2
- const fileUrl = new URL('main.css-JBKqe5f4.css', import.meta.url).href.replace(reg, '');
2
+ const fileUrl = new URL('main.css-DyNxEN6e.css', import.meta.url).href.replace(reg, '');
3
3
 
4
4
  export { fileUrl as default };
package/lib/config.js CHANGED
@@ -29,6 +29,8 @@ class db {
29
29
  async setPromptOptimization(guid, value) {
30
30
  await this.redis.set(`ai:prompt_optimization:${guid}`, value);
31
31
  }
32
+ /** --------------------------------------------------------- */
33
+ /** 工具相关配置 */
32
34
  /** 获取工具开关状态 */
33
35
  async getToolSwitch(guid) {
34
36
  return (await this.redis.get(`ai:tool:switch:${guid}`)) || "1";
@@ -37,6 +39,31 @@ class db {
37
39
  async setToolSwitch(guid, enable) {
38
40
  await this.redis.set(`ai:tool:switch:${guid}`, enable ? "1" : "0");
39
41
  }
42
+ /** 工具调用时是否发送提示 */
43
+ async getToolPromptSwitch(guid) {
44
+ return (await this.redis.get(`ai:tool_prompt:switch:${guid}`)) || "0";
45
+ }
46
+ /** 设置工具调用提示开关状态 */
47
+ async setToolPromptSwitch(guid, enable) {
48
+ await this.redis.set(`ai:tool_prompt:switch:${guid}`, enable ? "1" : "0");
49
+ }
50
+ /** 工具调用时发送的提示是否撤回 */
51
+ async getToolPromptRevokeSwitch(guid) {
52
+ return ((await this.redis.get(`ai:tool_prompt_revoke:switch:${guid}`)) || "0");
53
+ }
54
+ /** 设置工具调用提示撤回开关状态 */
55
+ async setToolPromptRevokeSwitch(guid, enable) {
56
+ await this.redis.set(`ai:tool_prompt_revoke:switch:${guid}`, enable ? "1" : "0");
57
+ }
58
+ /** 工具调用时发送的提示是否显示传参 */
59
+ async getToolPromptArgsSwitch(guid) {
60
+ return (await this.redis.get(`ai:tool_prompt_args:switch:${guid}`)) || "0";
61
+ }
62
+ /** 设置工具调用提示显示传参开关状态 */
63
+ async setToolPromptArgsSwitch(guid, enable) {
64
+ await this.redis.set(`ai:tool_prompt_args:switch:${guid}`, enable ? "1" : "0");
65
+ }
66
+ /** --------------------------------------------------------- */
40
67
  /** 获取复杂输出开关状态 */
41
68
  async getComplexOutput(guid) {
42
69
  return (await this.redis.get(`ai:complex_output:${guid}`)) || "1";
@@ -205,8 +232,7 @@ class db {
205
232
  /** 添加聊天历史 */
206
233
  async addAIChatHistory(guid, data) {
207
234
  const history = await this.getAIChatHistory(guid);
208
- while (history.length >= 40)
209
- history.shift();
235
+ // while (history.length >= 40) history.shift();
210
236
  history.push(data);
211
237
  await this.setAIChatHistory(guid, history);
212
238
  return history;
@@ -1,6 +1,7 @@
1
1
  var title = "IA聊天插件";
2
+ var desc = "一个基于AI的聊天插件,支持多种AI模型和丰富的功能配置,适用于各种聊天场景。";
2
3
  var name = "alemonjs-aichat";
3
- var version = "v1.0.25";
4
+ var version = "v1.0.28";
4
5
  var by = "AlemonJS";
5
6
  var list = [
6
7
  {
@@ -92,10 +93,6 @@ var list = [
92
93
  cmd: "/[开启|关闭]语音回复",
93
94
  desc: "[限QQ平台][需部署gpt-sovits]开启或关闭语音回复功能。"
94
95
  },
95
- {
96
- cmd: "/[开启|关闭]工具",
97
- desc: "开启或关闭工具功能。部分AI模型可能不支持该功能。"
98
- },
99
96
  {
100
97
  cmd: "/[开启|关闭]复杂回复",
101
98
  desc: "当模型不支持json输出时关闭该功能可以让AI以纯文本形式回复,关闭后无法识别图片 使用工具 好感度等功能,适合本地部署的ai"
@@ -147,6 +144,38 @@ var list = [
147
144
  ]
148
145
  }
149
146
  },
147
+ {
148
+ group: {
149
+ title: "工具操作",
150
+ desc: "这里的功能用于控制工具的使用, 部分功能需要管理员权限",
151
+ items: [
152
+ {
153
+ cmd: "/[开启|关闭]工具",
154
+ desc: "开启或关闭工具功能。部分AI模型可能不支持该功能。"
155
+ },
156
+ {
157
+ cmd: "/[开启|关闭]工具[工具名]",
158
+ desc: "开启或关闭指定工具功能,部分工具可能会有安全风险,请谨慎使用。"
159
+ },
160
+ {
161
+ cmd: "/工具列表",
162
+ desc: "查看当前所有工具的状态。"
163
+ },
164
+ {
165
+ cmd: "/[开启|关闭]工具提示",
166
+ desc: "开启或关闭工具调用提示功能。开启后每次调用工具都会有提示消息。"
167
+ },
168
+ {
169
+ cmd: "/[开启|关闭]工具提示撤回",
170
+ desc: "开启或关闭工具调用提示撤回功能。开启后工具调用的提示消息会在一段时间后自动撤回。"
171
+ },
172
+ {
173
+ cmd: "/[开启|关闭]工具提示详情",
174
+ desc: "开启或关闭工具调用提示详情功能。开启后工具调用的提示消息会包含更多的详情信息。"
175
+ }
176
+ ]
177
+ }
178
+ },
150
179
  {
151
180
  group: {
152
181
  title: "管理员设置",
@@ -167,14 +196,6 @@ var list = [
167
196
  {
168
197
  cmd: "/[可以|不可以]涩涩",
169
198
  desc: "开启或关闭涩涩功能, 开启后AI可能会生成一些R18的内容, 请谨慎使用。"
170
- },
171
- {
172
- cmd: "/[开启|关闭]工具[工具名]",
173
- desc: "开启或关闭指定工具功能,部分工具可能会有安全风险,请谨慎使用。"
174
- },
175
- {
176
- cmd: "/工具列表",
177
- desc: "查看当前所有工具的状态。"
178
199
  }
179
200
  ]
180
201
  }
@@ -182,10 +203,11 @@ var list = [
182
203
  ];
183
204
  var help = {
184
205
  title: title,
206
+ desc: desc,
185
207
  name: name,
186
208
  version: version,
187
209
  by: by,
188
210
  list: list
189
211
  };
190
212
 
191
- export { by, help as default, list, name, title, version };
213
+ export { by, help as default, desc, list, name, title, version };
@@ -56,17 +56,21 @@ function App(data) {
56
56
  React.createElement("div", { className: "p-5 space-y-3" },
57
57
  React.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3" },
58
58
  React.createElement(StatusItem, { label: "\u603B\u5F00\u5173", value: data.switch }),
59
- React.createElement(StatusItem, { label: "\u5DE5\u5177", value: data.tools }),
60
59
  React.createElement(StatusItem, { label: "\u590D\u6742\u8F93\u51FA", value: data.complex }),
61
60
  React.createElement(StatusItem, { label: "\u597D\u611F\u5EA6\u5F00\u5173", value: data.affection }),
62
61
  React.createElement(StatusItem, { label: "\u8BED\u97F3\u56DE\u590D\u5F00\u5173", value: data.tts }),
63
62
  React.createElement(StatusItem, { label: "\u6DF1\u5EA6\u601D\u8003", value: data.deep, isDeep: true }),
64
63
  React.createElement(StatusItem, { label: "\u4EC5\u827E\u7279\u89E6\u53D1", value: data.atTrigger })),
64
+ React.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3 border-t border-white/10 pt-2" },
65
+ React.createElement(StatusItem, { label: "\u5DE5\u5177\u603B\u5F00\u5173", value: data.tools }),
66
+ React.createElement(StatusItem, { label: "\u5DE5\u5177\u63D0\u793A", value: data.toolPromptSwitch }),
67
+ React.createElement(StatusItem, { label: "\u5DE5\u5177\u63D0\u793A\u64A4\u56DE", value: data.toolPromptRevokeSwitch }),
68
+ React.createElement(StatusItem, { label: "\u5DE5\u5177\u63D0\u793A\u4F20\u53C2", value: data.toolPromptArgsSwitch })),
65
69
  React.createElement("div", { className: "pt-2 border-t border-white/10" },
66
70
  React.createElement("div", { className: "flex items-center justify-between py-2" },
67
71
  React.createElement("span", { className: " text-white/60" }, "\u5F53\u524D\u4F7F\u7528\u6A21\u578B"),
68
72
  React.createElement("span", { className: "px-3 py-1 bg-blue-500/20 rounded-full font-mono text-blue-300 border border-blue-500/30" },
69
- data.currentAI || "未设置",
73
+ data.currentAI || "无法获取",
70
74
  " / ",
71
75
  data.model || "未设置")),
72
76
  React.createElement("div", { className: "py-2" },
@@ -75,6 +79,13 @@ function App(data) {
75
79
  React.createElement("div", { className: "py-2" },
76
80
  React.createElement("div", { className: " text-white/60 mb-2" }, "AI\u5217\u8868"),
77
81
  React.createElement("div", { className: "flex flex-wrap gap-2" }, data.aiList.length ? (data.aiList.map((ai, idx) => (React.createElement("span", { key: idx, className: "px-2.5 py-1 text-xs rounded-full bg-gradient-to-r from-purple-500/20 to-pink-500/20 text-purple-200 border border-purple-400/30 backdrop-blur-sm font-medium" }, ai)))) : (React.createElement("span", { className: " text-white/40 italic" }, "\u6682\u65E0AI\u914D\u7F6E"))))))),
82
+ React.createElement("div", { className: "bg-gradient-to-br from-gray-900/90 to-black/80 backdrop-blur-md rounded-2xl border border-white/20 shadow-xl overflow-hidden mb-4 text-white" },
83
+ React.createElement("div", { className: "px-5 py-3 bg-white/5 border-b border-white/10 backdrop-blur-sm" },
84
+ React.createElement("p", { className: "text-base font-medium tracking-wide flex items-center gap-2" },
85
+ React.createElement("span", { className: "w-1.5 h-1.5 bg-green-400 rounded-full" }),
86
+ "\u5DE5\u5177\u5217\u8868")),
87
+ React.createElement("div", { className: "p-5 space-y-3" },
88
+ React.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3" }, Object.entries(data.toolList).length ? (Object.entries(data.toolList).map(([tool, status]) => (React.createElement(StatusItem, { key: `tool-${tool}`, label: tool, value: status === "0" })))) : (React.createElement("span", { className: " text-white/40 italic" }, "\u6682\u65E0\u5DE5\u5177\u914D\u7F6E"))))),
78
89
  React.createElement("div", { className: "bg-gradient-to-br from-gray-900/90 to-black/80 backdrop-blur-md rounded-2xl border border-white/20 shadow-xl overflow-hidden mb-4" },
79
90
  React.createElement("div", { className: "px-5 py-3 bg-white/5 border-b border-white/10 backdrop-blur-sm" },
80
91
  React.createElement("p", { className: "text-base font-semibold tracking-wide flex items-center gap-2" },
package/lib/index.js CHANGED
@@ -13,17 +13,9 @@ var index = defineChildren({
13
13
  logger.info({
14
14
  message: "本地测试启动",
15
15
  });
16
- redis
17
- .get("ai:list")
18
- .then((value) => {
19
- logger.info({
20
- message: "Redis连接成功,测试键值已获取",
21
- value: value,
22
- });
23
- })
24
- .catch((error) => {
16
+ redis.get("ai:list").catch((error) => {
25
17
  logger.error({
26
- message: "Redis连接失败",
18
+ message: "Redis连接失败, 大部分功能将无法使用",
27
19
  error: error.message,
28
20
  });
29
21
  });
@@ -1,6 +1,7 @@
1
1
  import { getConfigValue, useClient } from 'alemonjs';
2
2
  import { API } from '@alemonjs/onebot';
3
3
  import redisClient from '../config.js';
4
+ import { CApiReply } from '../response/zreply/capi.js';
4
5
 
5
6
  const selects = onSelects(["message.create", "private.message.create"]);
6
7
  // 中间件
@@ -8,14 +9,13 @@ var mw = onMiddleware(selects, async (event, next) => {
8
9
  getConfigValue().aiChat || {};
9
10
  // console.log("原始事件:", event.value);
10
11
  // 新增字段
12
+ event["Xianyu"] = true; // 默认继续执行后续的处理函数
11
13
  event["user_id"] = event.UserId; // 用户QQ号
12
14
  event["msg"] = event.MessageText; // 消息内容
13
15
  event["guid"] = event.ChannelId ?? event.UserId; // 群号或用户QQ号
14
16
  event["uidkey"] = `${event["guid"]}:${event.UserName}(${event.UserId})`; // 唯一标识
15
17
  event["nickname"] =
16
- `${event.name == "private.message.create" ? "[私信]" : ""}${event.UserName}(${event.UserId})`; // 昵称(用户名+QQ号)
17
- // console.log('event["nickname"]', event["nickname"]);
18
- // console.log("event.IsMaster", event.UserId, config.master_id, event.IsMaster);
18
+ `${event.name === "private.message.create" ? "[私信]" : ""}${event.UserName}(${event.UserId})`; // 昵称(用户名+QQ号)
19
19
  if (event.Platform == "testone") {
20
20
  // 处理图片消息
21
21
  event["img"] = event.value
@@ -261,7 +261,22 @@ var mw = onMiddleware(selects, async (event, next) => {
261
261
  const atTriggerSwitch = await redisClient.getAtTriggerSwitch(event.ChannelId ?? event.UserId);
262
262
  if (atTriggerSwitch === "1" && event.Platform !== "testone") {
263
263
  if (!event["atBot"] && event.name !== "private.message.create") {
264
- return;
264
+ event["Xianyu"] = false; // 跳过所有指令,继续执行后续的处理函数
265
+ }
266
+ }
267
+ if (event["Xianyu"]) {
268
+ // 执行ai回复, 方便ai控制后续指令
269
+ const aiconfig = await redisClient.getAIConfig(event.guid);
270
+ if (aiconfig && aiconfig.model && aiconfig.key) {
271
+ const ReplyRes = await CApiReply(event);
272
+ console.log("res", ReplyRes);
273
+ if (ReplyRes) {
274
+ event["Xianyu"] = ReplyRes.next; // 根据AI回复决定是否继续执行后续的处理函数
275
+ if (ReplyRes.commands && ReplyRes.commands.length > 0) {
276
+ event.MessageText = ReplyRes.commands[0];
277
+ event["msg"] = ReplyRes.commands[0];
278
+ }
279
+ }
265
280
  }
266
281
  }
267
282
  next();
@@ -20,24 +20,37 @@ var res = onResponse(selects, async (e, next) => {
20
20
  const atTriggerSwitch = await redisClient.getAtTriggerSwitch(e.guid); // 仅艾特触发
21
21
  const currentAI = await redisClient.getCurrentAI(e.guid); // 当前AI名称
22
22
  const aiList = await redisClient.getAIList();
23
+ const toolList = await redisClient.getAllToolStatus(e.guid);
24
+ const toolPromptSwitch = await redisClient.getToolPromptSwitch(e.guid); // 工具提示开关
25
+ const toolPromptRevokeSwitch = await redisClient.getToolPromptRevokeSwitch(e.guid); // 工具提示撤回开关
26
+ const toolPromptArgsSwitch = await redisClient.getToolPromptArgsSwitch(e.guid); // 工具提示传参开关
23
27
  // 发送消息
24
- const img = await renderComponentIsHtmlToBuffer(App, {
25
- switch: config.model != "",
26
- tools: toolsIsOpen == "1",
27
- complex: complexResponse == "1",
28
- affection: affectionIsOpen == "1",
29
- tts: isOpenTTSReply == "1",
30
- deep: deepThinkingIsOpen == "1",
31
- model: config.model,
32
- prompt: config.systemPrompt,
33
- atTrigger: atTriggerSwitch == "1",
34
- aiList: aiList,
35
- currentAI: currentAI,
36
- });
37
- if (img) {
38
- message.send(format(Image(img)));
28
+ try {
29
+ const img = await renderComponentIsHtmlToBuffer(App, {
30
+ switch: config.model != "",
31
+ tools: toolsIsOpen == "1",
32
+ complex: complexResponse == "1",
33
+ affection: affectionIsOpen == "1",
34
+ tts: isOpenTTSReply == "1",
35
+ deep: deepThinkingIsOpen == "1",
36
+ model: config.model,
37
+ prompt: config.systemPrompt,
38
+ atTrigger: atTriggerSwitch == "1",
39
+ aiList: aiList,
40
+ currentAI: currentAI,
41
+ toolList: toolList,
42
+ toolPromptSwitch: toolPromptSwitch == "1",
43
+ toolPromptRevokeSwitch: toolPromptRevokeSwitch == "1",
44
+ toolPromptArgsSwitch: toolPromptArgsSwitch == "1",
45
+ });
46
+ if (img) {
47
+ message.send(format(Image(img)));
48
+ }
49
+ else {
50
+ message.send(format(Text(`当前AI配置:\n`), Text(`总开关: ${config.model != "" ? "开启" : "关闭"}\n`), Text(`工具: ${toolsIsOpen == "1" ? "开启" : "关闭"}\n`), Text(`复杂输出: ${complexResponse == "1" ? "开启" : "关闭"}\n`), Text(`好感度开关: ${affectionIsOpen == "1" ? "开启" : "关闭"}\n`), Text(`TTS回复开关: ${isOpenTTSReply == "1" ? "开启" : "关闭"}\n`), Text(`深度思考: ${deepThinkingIsOpen == "1" ? "默认" : "关闭"}\n`), Text(`仅艾特触发: ${atTriggerSwitch == "1" ? "开启" : "关闭"}\n`), Text(`模型: ${config.model || "未设置"}\n`), Text(`提示词: ${config.systemPrompt || "未设置"}\n`), Text(`当前AI: ${currentAI || "未设置"}\n`), Text(`AI数量: ${aiList.length ? aiList.length : "暂无AI配置"}`)));
51
+ }
39
52
  }
40
- else {
53
+ catch (error) {
41
54
  message.send(format(Text(`当前AI配置:\n`), Text(`总开关: ${config.model != "" ? "开启" : "关闭"}\n`), Text(`工具: ${toolsIsOpen == "1" ? "开启" : "关闭"}\n`), Text(`复杂输出: ${complexResponse == "1" ? "开启" : "关闭"}\n`), Text(`好感度开关: ${affectionIsOpen == "1" ? "开启" : "关闭"}\n`), Text(`TTS回复开关: ${isOpenTTSReply == "1" ? "开启" : "关闭"}\n`), Text(`深度思考: ${deepThinkingIsOpen == "1" ? "默认" : "关闭"}\n`), Text(`仅艾特触发: ${atTriggerSwitch == "1" ? "开启" : "关闭"}\n`), Text(`模型: ${config.model || "未设置"}\n`), Text(`提示词: ${config.systemPrompt || "未设置"}\n`), Text(`当前AI: ${currentAI || "未设置"}\n`), Text(`AI数量: ${aiList.length ? aiList.length : "暂无AI配置"}`)));
42
55
  }
43
56
  }
@@ -1,6 +1,6 @@
1
1
  import { useMessage, Image, Text } from 'alemonjs';
2
2
  import { renderComponentIsHtmlToBuffer } from 'jsxp';
3
- import App from '../../image/conponent/Help.js';
3
+ import App from '../../image/conponent/help.js';
4
4
  import redisClient from '../../config.js';
5
5
 
6
6
  const selects = onSelects(["message.create", "private.message.create"]);
@@ -0,0 +1,10 @@
1
+ var mw = onMiddleware(onSelects(["message.create", "private.message.create"]), async (event, next) => {
2
+ if (event.Xianyu) {
3
+ return true; // 继续执行后续的处理函数
4
+ }
5
+ else {
6
+ return next(); // 跳过所有指令,继续执行后续的处理函数
7
+ }
8
+ });
9
+
10
+ export { mw as default };
@@ -1,6 +1,7 @@
1
1
  import { availableTools } from '../../api/aitools.js';
2
2
  import redisClient from '../../config.js';
3
3
  import { useMessage, Text, getConfigValue } from 'alemonjs';
4
+ import { log } from 'console';
4
5
 
5
6
  const value = getConfigValue().aiChat || {};
6
7
  const selects = onSelects(["message.create", "private.message.create"]);
@@ -359,6 +360,7 @@ var res = onResponse(selects, async (e, next) => {
359
360
  // 获取所有ai工具列表
360
361
  if (/(\/|#)工具列表$/i.test(e.msg)) {
361
362
  const tools = await redisClient.getAllToolStatus(e.guid);
363
+ log("工具列表:", Object.entries(tools));
362
364
  const toolList = Object.entries(tools)
363
365
  .map(([tool, status]) => `${tool}: ${status === "0" ? "开启" : "关闭"}`)
364
366
  .join("\n");
@@ -366,11 +368,11 @@ var res = onResponse(selects, async (e, next) => {
366
368
  return;
367
369
  }
368
370
  // 控制工具开关
369
- if (/(\/|#)(开启|关闭)工具 (.*)$/i.test(e.msg)) {
371
+ if (/(\/|#)(开启|关闭)工具(.*)$/i.test(e.msg)) {
370
372
  if (!e.IsMaster || String(e.UserId) != "3501869534") {
371
373
  return;
372
374
  }
373
- const match = e.msg.match(/(\/|#)(开启|关闭)工具 (.*)$/i);
375
+ const match = e.msg.match(/(\/|#)(开启|关闭)工具(.*)$/i);
374
376
  if (!match) {
375
377
  message.send(format(Text("格式错误,请按照 格式:/开启工具 <工具名称> 或 /关闭工具 <工具名称> 进行设置")));
376
378
  return;
@@ -388,6 +390,54 @@ var res = onResponse(selects, async (e, next) => {
388
390
  message.send(format(Text(`已${enable ? "开启" : "关闭"}工具 ${toolName.trim()} !`)));
389
391
  return;
390
392
  }
393
+ // 控制工具提示开关
394
+ if (/(\/|#)(开启|关闭)工具(调用)?提示$/i.test(e.msg)) {
395
+ if (!e.IsMaster || String(e.UserId) != "3501869534") {
396
+ return;
397
+ }
398
+ const match = e.msg.match(/(\/|#)(开启|关闭)工具(调用)?提示$/i);
399
+ if (!match) {
400
+ message.send(format(Text("格式错误,请按照 格式:/开启工具提示 或 /关闭工具提示 进行设置")));
401
+ return;
402
+ }
403
+ const [, , action] = match;
404
+ const enable = action === "开启";
405
+ await redisClient.setToolPromptSwitch(e.guid, enable);
406
+ message.send(format(Text(`已${enable ? "开启" : "关闭"}工具提示功能 !`)));
407
+ return;
408
+ }
409
+ // 控制工具提示撤回开关
410
+ if (/(\/|#)(开启|关闭)工具(调用)?提示撤回$/i.test(e.msg)) {
411
+ if (!e.IsMaster || String(e.UserId) != "3501869534") {
412
+ return;
413
+ }
414
+ const match = e.msg.match(/(\/|#)(开启|关闭)工具(调用)?提示撤回$/i);
415
+ if (!match) {
416
+ message.send(format(Text("格式错误,请按照 格式:/开启工具提示撤回 或 /关闭工具提示撤回 进行设置")));
417
+ return;
418
+ }
419
+ const [, , action] = match;
420
+ const enable = action === "开启";
421
+ await redisClient.setToolPromptRevokeSwitch(e.guid, enable);
422
+ message.send(format(Text(`已${enable ? "开启" : "关闭"}工具提示撤回功能 !`)));
423
+ return;
424
+ }
425
+ // 控制工具调用提示详情开关
426
+ if (/(\/|#)(开启|关闭)工具(调用)?提示详情$/i.test(e.msg)) {
427
+ if (!e.IsMaster || String(e.UserId) != "3501869534") {
428
+ return;
429
+ }
430
+ const match = e.msg.match(/(\/|#)(开启|关闭)工具(调用)?提示详情$/i);
431
+ if (!match) {
432
+ message.send(format(Text("格式错误,请按照 格式:/开启工具提示详情 或 /关闭工具提示详情 进行设置")));
433
+ return;
434
+ }
435
+ const [, , action] = match;
436
+ const enable = action === "开启";
437
+ await redisClient.setToolPromptArgsSwitch(e.guid, enable);
438
+ message.send(format(Text(`已${enable ? "开启" : "关闭"}工具提示详情功能 !`)));
439
+ return;
440
+ }
391
441
  next();
392
442
  });
393
443
 
@@ -1,11 +1,11 @@
1
- import { getConfigValue, useMessage, Text, ImageURL, Image, Mention, Video } from 'alemonjs';
1
+ import { getConfigValue, useMessage, Text, ImageURL, Image, Mention, Video, Audio } from 'alemonjs';
2
2
  import OpenAi from 'openai';
3
- import { sendTTSMessage } from '../zreply/res.js';
4
3
  import { availableTools } from '../../api/aitools.js';
5
4
  import { TTSClient } from '../../api/tts.js';
6
5
  import redisClient from '../../config.js';
7
6
  import { imageReview } from '../../api/review.js';
8
7
  import { uploadImageToR2 } from '../../s3.js';
8
+ import { createTTSMessage } from '../zreply/tts.js';
9
9
 
10
10
  const selects = onSelects(["message.create", "private.message.create"]);
11
11
  // inline regex will be used directly in condition checks
@@ -256,7 +256,10 @@ var res = onResponse(selects, async (e) => {
256
256
  return;
257
257
  }
258
258
  const ttsclient = new TTSClient();
259
- sendTTSMessage(content, e, ttsclient, `${speaker}-默认`);
259
+ const audioUrl = await createTTSMessage(content, ttsclient, `${speaker}-默认`);
260
+ if (audioUrl !== "") {
261
+ await message.send(format(Audio(audioUrl)));
262
+ }
260
263
  }
261
264
  // 安装语音模型
262
265
  if (/^(\/|#)安装语音(模型)?(.+)$/i.test(e.msg)) {