alemonjs-aichat 1.0.24 → 1.0.26
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.
- package/lib/api/aitools.js +3 -3
- package/lib/api/loadSkill.js +3 -3
- package/lib/assets/main.css-JBKqe5f4.css +1 -0
- package/lib/assets/main.css.js +1 -1
- package/lib/config.js +82 -12
- package/lib/data/help.json.js +17 -5
- package/lib/image/conponent/AiConfig.js +99 -0
- package/lib/image/conponent/help.js +12 -10
- package/lib/index.js +15 -0
- package/lib/middleware/mw.js +56 -52
- package/lib/redis.js +1 -1
- package/lib/response/config/res.js +24 -2
- package/lib/response/help/res.js +3 -3
- package/lib/response/setting/res.js +54 -9
- package/lib/response/zreply/res.js +15 -5
- package/lib/routes/commands.js +1 -6
- package/lib/s3.js +7 -18
- package/package.json +58 -62
package/lib/api/aitools.js
CHANGED
|
@@ -161,7 +161,7 @@ const tools = [
|
|
|
161
161
|
{
|
|
162
162
|
type: "function",
|
|
163
163
|
function: {
|
|
164
|
-
name: "
|
|
164
|
+
name: "exec",
|
|
165
165
|
description: "执行终端命令, 请勿执行高危险性指令, 例如rm -rf /等, 否则可能会导致服务器数据丢失或系统崩溃. 你可以使用这个工具来执行一些简单的命令, 例如查看当前目录下的文件ls, 查看系统状态top等. 当你想要执行一个命令时, 请提供具体的命令文本, 例如'ls -la'或'top -n 1'. 执行结果将会返回给你, 但请注意, 由于安全限制, 某些命令可能无法执行或返回受限的结果",
|
|
166
166
|
parameters: {
|
|
167
167
|
type: "object",
|
|
@@ -606,10 +606,10 @@ const availableTools = {
|
|
|
606
606
|
},
|
|
607
607
|
/**
|
|
608
608
|
* 运行cmd命令
|
|
609
|
-
* @param
|
|
609
|
+
* @param exec 命令字符串
|
|
610
610
|
* @returns 命令执行结果
|
|
611
611
|
*/
|
|
612
|
-
|
|
612
|
+
exec: async ({ command }) => {
|
|
613
613
|
const { exec } = await import('child_process');
|
|
614
614
|
return new Promise((resolve) => {
|
|
615
615
|
exec(command, (error, stdout, stderr) => {
|
package/lib/api/loadSkill.js
CHANGED
|
@@ -51,7 +51,7 @@ const loadSkills = () => {
|
|
|
51
51
|
// 根据name和description去重
|
|
52
52
|
const uniqueSkills = allSkills.filter((skill, index, self) => index ===
|
|
53
53
|
self.findIndex((s) => s.name === skill.name && s.description === skill.description));
|
|
54
|
-
console.log(`加载技能: ${uniqueSkills.length}个`);
|
|
54
|
+
// console.log(`加载技能: ${uniqueSkills.length}个`);
|
|
55
55
|
return uniqueSkills;
|
|
56
56
|
};
|
|
57
57
|
// 获取某个技能的详情, 通过技能名称匹配对应文件夹下的所有md文件,将内容一并返回
|
|
@@ -109,12 +109,12 @@ const loadExternalSkills = () => {
|
|
|
109
109
|
const allSkills = value.skills_dir.flatMap((dir) => {
|
|
110
110
|
return loadSkillsFromPath(dir);
|
|
111
111
|
});
|
|
112
|
-
console.log(`加载外部技能: ${allSkills.length}个`);
|
|
112
|
+
// console.log(`加载外部技能: ${allSkills.length}个`);
|
|
113
113
|
return allSkills;
|
|
114
114
|
}
|
|
115
115
|
const skillsDir = value.skills_dir || path.join(currentDir, "../../skills");
|
|
116
116
|
const skills = loadSkillsFromPath(skillsDir);
|
|
117
|
-
console.log(`加载外部技能: ${skills.length}个`);
|
|
117
|
+
// console.log(`加载外部技能: ${skills.length}个`);
|
|
118
118
|
return skills;
|
|
119
119
|
};
|
|
120
120
|
|
|
@@ -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-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}}
|
package/lib/assets/main.css.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
const reg = ['win32'].includes(process.platform) ? /^file:\/\/\// : /^file:\/\// ;
|
|
2
|
-
const fileUrl = new URL('main.css-
|
|
2
|
+
const fileUrl = new URL('main.css-JBKqe5f4.css', import.meta.url).href.replace(reg, '');
|
|
3
3
|
|
|
4
4
|
export { fileUrl as default };
|
package/lib/config.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Redis from 'ioredis';
|
|
2
2
|
import { getConfigValue } from 'alemonjs';
|
|
3
|
+
import { tools } from './api/aitools.js';
|
|
3
4
|
|
|
4
5
|
class db {
|
|
5
6
|
redis;
|
|
@@ -123,7 +124,7 @@ class db {
|
|
|
123
124
|
async switchAI(guid, name) {
|
|
124
125
|
const aiConfigStr = await this.redis.get(`ai:list:${name}`);
|
|
125
126
|
if (!aiConfigStr) {
|
|
126
|
-
console.log("切换失败,
|
|
127
|
+
console.log("切换失败, 无此AI");
|
|
127
128
|
await this.setAIConfig(guid, db.defaultAIConfig);
|
|
128
129
|
return null;
|
|
129
130
|
}
|
|
@@ -131,13 +132,19 @@ class db {
|
|
|
131
132
|
const currentConfig = await this.getAIConfig(guid);
|
|
132
133
|
aiConfig.systemPrompt = currentConfig.systemPrompt;
|
|
133
134
|
await this.setAIConfig(guid, aiConfig);
|
|
135
|
+
// 记录当前切换的ai名字
|
|
136
|
+
await this.redis.set(`ai:currentAI:${guid}`, name);
|
|
134
137
|
return aiConfig;
|
|
135
138
|
}
|
|
139
|
+
/** 获取当前使用的AI名称 */
|
|
140
|
+
async getCurrentAI(guid) {
|
|
141
|
+
return (await this.redis.get(`ai:currentAI:${guid}`)) || "";
|
|
142
|
+
}
|
|
136
143
|
/** 切换AI的RAPI模式 */
|
|
137
144
|
async switchModelRAPI(aiName, enable) {
|
|
138
145
|
const aiConfigStr = await this.redis.get(`ai:list:${aiName}`);
|
|
139
146
|
if (!aiConfigStr) {
|
|
140
|
-
console.log("切换失败,
|
|
147
|
+
console.log("切换失败, 无此AI");
|
|
141
148
|
return;
|
|
142
149
|
}
|
|
143
150
|
const aiConfig = JSON.parse(aiConfigStr);
|
|
@@ -215,6 +222,14 @@ class db {
|
|
|
215
222
|
}
|
|
216
223
|
await this.redis.del(`ai:history:${guid}`);
|
|
217
224
|
}
|
|
225
|
+
/** 清理最后的N条聊天记录 */
|
|
226
|
+
async clearLastNChatHistory(guid, n) {
|
|
227
|
+
const history = await this.getAIChatHistory(guid);
|
|
228
|
+
while (history.length > n) {
|
|
229
|
+
history.shift();
|
|
230
|
+
}
|
|
231
|
+
await this.setAIChatHistory(guid, history);
|
|
232
|
+
}
|
|
218
233
|
/** 获取好感度 */
|
|
219
234
|
async getAffectionLevel(guid, userKey) {
|
|
220
235
|
const levelStr = await this.redis.get(`ai:affection:${guid}:${userKey}`);
|
|
@@ -266,21 +281,13 @@ class db {
|
|
|
266
281
|
}
|
|
267
282
|
/** 设置语音回复开关 */
|
|
268
283
|
async setTTSResponseSwitch(guid, enable) {
|
|
269
|
-
await this.redis.set(`
|
|
284
|
+
await this.redis.set(`ai:tts:response:${guid}`, enable ? "1" : "0");
|
|
270
285
|
}
|
|
271
286
|
/** 获取语音回复开关 */
|
|
272
287
|
async getTTSResponseSwitch(guid) {
|
|
273
|
-
const switchStr = (await this.redis.get(`
|
|
288
|
+
const switchStr = (await this.redis.get(`ai:tts:response:${guid}`)) || "0";
|
|
274
289
|
return switchStr;
|
|
275
290
|
}
|
|
276
|
-
/** 设置 bot id */
|
|
277
|
-
async setBotID(id) {
|
|
278
|
-
await this.redis.set("bot:id", id);
|
|
279
|
-
}
|
|
280
|
-
/** 获取 bot id */
|
|
281
|
-
async getBotID() {
|
|
282
|
-
return await this.redis.get("bot:id");
|
|
283
|
-
}
|
|
284
291
|
/** 添加图片URL */
|
|
285
292
|
async addImgUrl(guid, url) {
|
|
286
293
|
const id = guid ?? "global";
|
|
@@ -302,9 +309,72 @@ class db {
|
|
|
302
309
|
async getDeepThoughtSwitch(guid) {
|
|
303
310
|
return (await this.redis.get(`ai:deep_thought:switch:${guid}`)) || "0";
|
|
304
311
|
}
|
|
312
|
+
/** 设置深度思考开关 */
|
|
305
313
|
async setDeepThoughtSwitch(guid, enable) {
|
|
306
314
|
await this.redis.set(`ai:deep_thought:switch:${guid}`, enable ? "1" : "0");
|
|
307
315
|
}
|
|
316
|
+
/** 仅艾特触发 */
|
|
317
|
+
async getAtTriggerSwitch(guid) {
|
|
318
|
+
return (await this.redis.get(`ai:at_trigger:switch:${guid}`)) || "1";
|
|
319
|
+
}
|
|
320
|
+
/** 设置仅艾特触发开关 */
|
|
321
|
+
async setAtTriggerSwitch(guid, enable) {
|
|
322
|
+
await this.redis.set(`ai:at_trigger:switch:${guid}`, enable ? "1" : "0");
|
|
323
|
+
}
|
|
324
|
+
/** 禁用工具 */
|
|
325
|
+
async disableTool(guid, toolName) {
|
|
326
|
+
await this.redis.set(`ai:tool:disable:${guid}:${toolName}`, "1");
|
|
327
|
+
}
|
|
328
|
+
/** 启用工具 */
|
|
329
|
+
async enableTool(guid, toolName) {
|
|
330
|
+
await this.redis.del(`ai:tool:disable:${guid}:${toolName}`);
|
|
331
|
+
}
|
|
332
|
+
/** 获取工具状态 */
|
|
333
|
+
async getToolStatus(guid, toolName) {
|
|
334
|
+
const status = (await this.redis.get(`ai:tool:disable:${guid}:${toolName}`)) || "0";
|
|
335
|
+
return status;
|
|
336
|
+
}
|
|
337
|
+
/** 获取所有工具状态 */
|
|
338
|
+
async getAllToolStatus(guid) {
|
|
339
|
+
const status = {};
|
|
340
|
+
for (const tool of tools) {
|
|
341
|
+
const toolName = tool.type === "function" ? tool.function.name : "";
|
|
342
|
+
status[toolName] = await this.getToolStatus(guid, toolName);
|
|
343
|
+
}
|
|
344
|
+
return status;
|
|
345
|
+
}
|
|
346
|
+
// 获取所有可用工具,返回完整工具
|
|
347
|
+
async getAvailableTools(guid) {
|
|
348
|
+
const toolStatus = await this.getAllToolStatus(guid);
|
|
349
|
+
const availableTools = tools.filter((tool) => {
|
|
350
|
+
const toolName = tool.type === "function" ? tool.function.name : "";
|
|
351
|
+
return !toolStatus[toolName] || toolStatus[toolName] === "0";
|
|
352
|
+
});
|
|
353
|
+
return availableTools;
|
|
354
|
+
}
|
|
355
|
+
/** 装载工具 */
|
|
356
|
+
async loadTools(guid) {
|
|
357
|
+
const toolStatus = await this.getAllToolStatus(guid);
|
|
358
|
+
const allTools = tools.map((tool) => tool.type === "function" ? tool.function.name : "");
|
|
359
|
+
// 默认禁用的危险工具
|
|
360
|
+
const defaultDisabledTools = ["exec", "EvalCode"];
|
|
361
|
+
// 给工具添加默认状态
|
|
362
|
+
const toolsWithStatus = allTools.map((tool) => ({
|
|
363
|
+
name: tool,
|
|
364
|
+
disabled: (toolStatus[tool] && toolStatus[tool] === "1") ||
|
|
365
|
+
(!toolStatus[tool] && defaultDisabledTools.includes(tool)),
|
|
366
|
+
}));
|
|
367
|
+
// 存储工具状态
|
|
368
|
+
for (const tool of toolsWithStatus) {
|
|
369
|
+
if (tool.disabled) {
|
|
370
|
+
await this.disableTool(guid, tool.name);
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
await this.enableTool(guid, tool.name);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return toolsWithStatus.map((tool) => tool.name);
|
|
377
|
+
}
|
|
308
378
|
}
|
|
309
379
|
const configValue = getConfigValue();
|
|
310
380
|
const aiChatConfig = configValue.aiChat || {};
|
package/lib/data/help.json.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var title = "IA聊天插件";
|
|
2
|
-
var name = "aichat";
|
|
3
|
-
var version = "v1.0.
|
|
2
|
+
var name = "alemonjs-aichat";
|
|
3
|
+
var version = "v1.0.25";
|
|
4
4
|
var by = "AlemonJS";
|
|
5
5
|
var list = [
|
|
6
6
|
{
|
|
@@ -80,17 +80,21 @@ var list = [
|
|
|
80
80
|
cmd: "/[开启|关闭]主动搭话",
|
|
81
81
|
desc: "开启或关闭主动搭话功能。"
|
|
82
82
|
},
|
|
83
|
+
{
|
|
84
|
+
cmd: "/[开启|关闭]仅艾特触发",
|
|
85
|
+
desc: "开启或关闭仅艾特触发功能, 避免群内有多个AI时互相干扰。"
|
|
86
|
+
},
|
|
83
87
|
{
|
|
84
88
|
cmd: "/[开启|关闭]好感度",
|
|
85
89
|
desc: "开启或关闭好感度功能。"
|
|
86
90
|
},
|
|
87
91
|
{
|
|
88
92
|
cmd: "/[开启|关闭]语音回复",
|
|
89
|
-
desc: "[限QQ平台]开启或关闭语音回复功能。"
|
|
93
|
+
desc: "[限QQ平台][需部署gpt-sovits]开启或关闭语音回复功能。"
|
|
90
94
|
},
|
|
91
95
|
{
|
|
92
|
-
cmd: "/[开启|关闭]
|
|
93
|
-
desc: "
|
|
96
|
+
cmd: "/[开启|关闭]工具",
|
|
97
|
+
desc: "开启或关闭工具功能。部分AI模型可能不支持该功能。"
|
|
94
98
|
},
|
|
95
99
|
{
|
|
96
100
|
cmd: "/[开启|关闭]复杂回复",
|
|
@@ -163,6 +167,14 @@ var list = [
|
|
|
163
167
|
{
|
|
164
168
|
cmd: "/[可以|不可以]涩涩",
|
|
165
169
|
desc: "开启或关闭涩涩功能, 开启后AI可能会生成一些R18的内容, 请谨慎使用。"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
cmd: "/[开启|关闭]工具[工具名]",
|
|
173
|
+
desc: "开启或关闭指定工具功能,部分工具可能会有安全风险,请谨慎使用。"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
cmd: "/工具列表",
|
|
177
|
+
desc: "查看当前所有工具的状态。"
|
|
166
178
|
}
|
|
167
179
|
]
|
|
168
180
|
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import fileUrl from '../../assets/main.css.js';
|
|
3
|
+
import help from '../../data/help.json.js';
|
|
4
|
+
import { LinkStyleSheet } from 'jsxp';
|
|
5
|
+
import fileUrl$1 from '../../assets/113574575_p0_master1200.jpg.js';
|
|
6
|
+
|
|
7
|
+
const cmds = [
|
|
8
|
+
{ cmd: "/切换AI <AI名称>", desc: "切换当前使用的AI模型" },
|
|
9
|
+
{ cmd: "/切换模型 <模型名称>", desc: "切换当前使用的AI模型" },
|
|
10
|
+
{ cmd: "/<开启|关闭>仅艾特触发", desc: "开启或关闭仅艾特触发功能" },
|
|
11
|
+
{ cmd: "/<开启|关闭>工具", desc: "开启或关闭AI工具" },
|
|
12
|
+
{ cmd: "/<开启|关闭>复杂输出", desc: "开启或关闭复杂输出" },
|
|
13
|
+
{ cmd: "/<开启|关闭>好感度", desc: "开启或关闭好感度系统" },
|
|
14
|
+
{ cmd: "/清空对话", desc: "清空当前对话历史" },
|
|
15
|
+
];
|
|
16
|
+
const StatusItem = ({ label, value, isDeep, }) => {
|
|
17
|
+
const getStatusStyle = () => {
|
|
18
|
+
if (isDeep && value === "默认") {
|
|
19
|
+
return "bg-yellow-500/20 text-yellow-300 border-yellow-500/30";
|
|
20
|
+
}
|
|
21
|
+
if (value) {
|
|
22
|
+
return "bg-green-500/20 text-green-300 border-green-500/30";
|
|
23
|
+
}
|
|
24
|
+
return "bg-red-500/10 text-red-300 border-red-500/20";
|
|
25
|
+
};
|
|
26
|
+
return (React.createElement("div", { className: "flex items-center justify-between py-2 px-2 rounded-lg bg-white/5" },
|
|
27
|
+
React.createElement("span", { className: " text-white/70" }, label),
|
|
28
|
+
React.createElement("span", { className: `px-3 py-0.5 rounded-full text-xs font-mono font-medium border ${getStatusStyle()}` }, isDeep && value === "默认" ? "默认" : value ? "开启" : "关闭")));
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* @param param0
|
|
32
|
+
* @returns
|
|
33
|
+
*/
|
|
34
|
+
function App(data) {
|
|
35
|
+
return (React.createElement("html", null,
|
|
36
|
+
React.createElement("head", null,
|
|
37
|
+
React.createElement(LinkStyleSheet, { src: fileUrl })),
|
|
38
|
+
React.createElement("body", { className: "bg-cover p-4", style: { backgroundImage: `url(${fileUrl$1})` } },
|
|
39
|
+
React.createElement("div", { className: "relative mb-6" },
|
|
40
|
+
React.createElement("div", { className: "absolute -left-4 -top-4 w-24 h-24 bg-purple-400/20 rounded-full blur-2xl -z-0" }),
|
|
41
|
+
React.createElement("h2", { className: "relative text-3xl font-bold bg-gradient-to-r from-amber-300 via-yellow-200 to-amber-300 bg-clip-text text-transparent drop-shadow-lg tracking-wide" }, "AI\u914D\u7F6E\u8BE6\u60C5"),
|
|
42
|
+
React.createElement("div", { className: "mt-2 flex items-center gap-2" },
|
|
43
|
+
React.createElement("div", { className: "h-0.5 w-12 bg-gradient-to-r from-amber-400 to-purple-400 rounded-full" }),
|
|
44
|
+
React.createElement("div", { className: "h-0.5 w-20 bg-white/30 rounded-full" })),
|
|
45
|
+
React.createElement("div", { className: "flex items-center gap-2 mt-3 " },
|
|
46
|
+
React.createElement("span", { className: "px-2 py-0.5 bg-amber-500/20 rounded-md text-amber-200 font-mono text-xs border border-amber-400/30" }, help.name),
|
|
47
|
+
React.createElement("span", { className: "text-amber-300 text-xs font-mono font-medium" }, help.version),
|
|
48
|
+
React.createElement("span", { className: "text-white/50 text-xs" }, "\u2022"),
|
|
49
|
+
React.createElement("span", { className: "text-white/60 text-xs" }, "by"),
|
|
50
|
+
React.createElement("span", { className: "text-amber-200 text-xs font-medium tracking-wide" }, help.by))),
|
|
51
|
+
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" },
|
|
52
|
+
React.createElement("div", { className: "px-5 py-3 bg-white/5 border-b border-white/10 backdrop-blur-sm" },
|
|
53
|
+
React.createElement("p", { className: "text-base font-medium tracking-wide flex items-center gap-2" },
|
|
54
|
+
React.createElement("span", { className: "w-1.5 h-1.5 bg-blue-400 rounded-full" }),
|
|
55
|
+
"\u5F53\u524DAI\u914D\u7F6E")),
|
|
56
|
+
React.createElement("div", { className: "p-5 space-y-3" },
|
|
57
|
+
React.createElement("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-3" },
|
|
58
|
+
React.createElement(StatusItem, { label: "\u603B\u5F00\u5173", value: data.switch }),
|
|
59
|
+
React.createElement(StatusItem, { label: "\u5DE5\u5177", value: data.tools }),
|
|
60
|
+
React.createElement(StatusItem, { label: "\u590D\u6742\u8F93\u51FA", value: data.complex }),
|
|
61
|
+
React.createElement(StatusItem, { label: "\u597D\u611F\u5EA6\u5F00\u5173", value: data.affection }),
|
|
62
|
+
React.createElement(StatusItem, { label: "\u8BED\u97F3\u56DE\u590D\u5F00\u5173", value: data.tts }),
|
|
63
|
+
React.createElement(StatusItem, { label: "\u6DF1\u5EA6\u601D\u8003", value: data.deep, isDeep: true }),
|
|
64
|
+
React.createElement(StatusItem, { label: "\u4EC5\u827E\u7279\u89E6\u53D1", value: data.atTrigger })),
|
|
65
|
+
React.createElement("div", { className: "pt-2 border-t border-white/10" },
|
|
66
|
+
React.createElement("div", { className: "flex items-center justify-between py-2" },
|
|
67
|
+
React.createElement("span", { className: " text-white/60" }, "\u5F53\u524D\u4F7F\u7528\u6A21\u578B"),
|
|
68
|
+
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 || "未设置",
|
|
70
|
+
" / ",
|
|
71
|
+
data.model || "未设置")),
|
|
72
|
+
React.createElement("div", { className: "py-2" },
|
|
73
|
+
React.createElement("div", { className: " text-white/60 mb-1" }, "\u63D0\u793A\u8BCD"),
|
|
74
|
+
React.createElement("div", { className: "px-3 py-2 bg-white/5 rounded-lg text-white/80 border border-white/10" }, data.prompt || "未设置")),
|
|
75
|
+
React.createElement("div", { className: "py-2" },
|
|
76
|
+
React.createElement("div", { className: " text-white/60 mb-2" }, "AI\u5217\u8868"),
|
|
77
|
+
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"))))))),
|
|
78
|
+
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
|
+
React.createElement("div", { className: "px-5 py-3 bg-white/5 border-b border-white/10 backdrop-blur-sm" },
|
|
80
|
+
React.createElement("p", { className: "text-base font-semibold tracking-wide flex items-center gap-2" },
|
|
81
|
+
React.createElement("span", { className: "w-1.5 h-1.5 bg-amber-400 rounded-full shadow-glow" }),
|
|
82
|
+
React.createElement("span", { className: "text-amber-100" }, "\u63A8\u8350\u6307\u4EE4"))),
|
|
83
|
+
React.createElement("div", { className: "p-5" },
|
|
84
|
+
React.createElement("div", { className: "grid grid-cols-1 md:grid-cols-2 auto-rows-auto" },
|
|
85
|
+
cmds.map((item, idx) => {
|
|
86
|
+
const isLastInRow = (idx + 1) % 2 === 0 || idx === cmds.length - 1;
|
|
87
|
+
const isSecondCol = idx % 2 === 1;
|
|
88
|
+
return (React.createElement("div", { key: idx, className: `relative flex flex-col gap-1.5 p-4 transition-colors hover:bg-white/5
|
|
89
|
+
${isSecondCol ? "md:border-l border-white/10" : ""}
|
|
90
|
+
${idx >= 2 ? "border-t border-white/10" : ""}
|
|
91
|
+
${isLastInRow && idx < cmds.length - 1 ? "md:border-r-0" : ""}
|
|
92
|
+
` },
|
|
93
|
+
React.createElement("code", { className: "text-amber-300 font-mono font-semibold tracking-wide bg-amber-500/10 px-2 py-0.5 rounded-md self-start border border-amber-400/20" }, item.cmd),
|
|
94
|
+
React.createElement("span", { className: "text-white/80 leading-relaxed pl-1" }, item.desc)));
|
|
95
|
+
}),
|
|
96
|
+
cmds.length % 2 !== 0 && (React.createElement("div", { className: "hidden md:block relative min-h-[120px] p-4 border-t border-white/10" }))))))));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export { App as default };
|
|
@@ -13,16 +13,18 @@ function App() {
|
|
|
13
13
|
React.createElement("head", null,
|
|
14
14
|
React.createElement(LinkStyleSheet, { src: fileUrl })),
|
|
15
15
|
React.createElement("body", { className: "bg-cover p-4", style: { backgroundImage: `url(${fileUrl$1})` } },
|
|
16
|
-
React.createElement("
|
|
17
|
-
|
|
18
|
-
React.createElement("
|
|
19
|
-
|
|
20
|
-
" ",
|
|
21
|
-
|
|
22
|
-
" ",
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
16
|
+
React.createElement("div", { className: "relative mb-6" },
|
|
17
|
+
React.createElement("div", { className: "absolute -left-4 -top-4 w-24 h-24 bg-purple-400/20 rounded-full blur-2xl -z-0" }),
|
|
18
|
+
React.createElement("h2", { className: "relative text-3xl font-bold bg-gradient-to-r from-amber-300 via-yellow-200 to-amber-300 bg-clip-text text-transparent drop-shadow-lg tracking-wide" }, help.title),
|
|
19
|
+
React.createElement("div", { className: "mt-2 flex items-center gap-2" },
|
|
20
|
+
React.createElement("div", { className: "h-0.5 w-12 bg-gradient-to-r from-amber-400 to-purple-400 rounded-full" }),
|
|
21
|
+
React.createElement("div", { className: "h-0.5 w-20 bg-white/30 rounded-full" })),
|
|
22
|
+
React.createElement("div", { className: "flex items-center gap-2 mt-3 text-sm" },
|
|
23
|
+
React.createElement("span", { className: "px-2 py-0.5 bg-amber-500/20 rounded-md text-amber-200 font-mono text-xs border border-amber-400/30" }, help.name),
|
|
24
|
+
React.createElement("span", { className: "text-amber-300 text-xs font-mono font-medium" }, help.version),
|
|
25
|
+
React.createElement("span", { className: "text-white/50 text-xs" }, "\u2022"),
|
|
26
|
+
React.createElement("span", { className: "text-white/60 text-xs" }, "by"),
|
|
27
|
+
React.createElement("span", { className: "text-amber-200 text-xs font-medium tracking-wide" }, help.by))),
|
|
26
28
|
help.list.map((item, index) => (React.createElement("div", { key: index, className: " border-b last:border-0 bg-black/60 rounded-lg overflow-hidden mb-4 text-white backdrop-blur-xs" },
|
|
27
29
|
React.createElement("div", { className: "p-4 bg-black/30 border-b border-white/20" },
|
|
28
30
|
React.createElement("p", { className: "text-lg font-semibold" }, item.group.title),
|
package/lib/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { redis } from './redis.js';
|
|
1
2
|
import commands from './routes/commands.js';
|
|
2
3
|
import middleware from './routes/middleware.js';
|
|
3
4
|
|
|
@@ -12,6 +13,20 @@ var index = defineChildren({
|
|
|
12
13
|
logger.info({
|
|
13
14
|
message: "本地测试启动",
|
|
14
15
|
});
|
|
16
|
+
redis
|
|
17
|
+
.get("ai:list")
|
|
18
|
+
.then((value) => {
|
|
19
|
+
logger.info({
|
|
20
|
+
message: "Redis连接成功,测试键值已获取",
|
|
21
|
+
value: value,
|
|
22
|
+
});
|
|
23
|
+
})
|
|
24
|
+
.catch((error) => {
|
|
25
|
+
logger.error({
|
|
26
|
+
message: "Redis连接失败",
|
|
27
|
+
error: error.message,
|
|
28
|
+
});
|
|
29
|
+
});
|
|
15
30
|
},
|
|
16
31
|
});
|
|
17
32
|
|
package/lib/middleware/mw.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import { getConfigValue, useClient } from 'alemonjs';
|
|
2
2
|
import { API } from '@alemonjs/onebot';
|
|
3
|
-
import
|
|
3
|
+
import redisClient from '../config.js';
|
|
4
4
|
|
|
5
|
-
// import { API as ScbbsAPI } from "@alemonjs/scbbs";
|
|
6
5
|
const selects = onSelects(["message.create", "private.message.create"]);
|
|
7
6
|
// 中间件
|
|
8
7
|
var mw = onMiddleware(selects, async (event, next) => {
|
|
9
8
|
getConfigValue().aiChat || {};
|
|
10
|
-
console.log("原始事件:", event.value);
|
|
9
|
+
// console.log("原始事件:", event.value);
|
|
11
10
|
// 新增字段
|
|
12
11
|
event["user_id"] = event.UserId; // 用户QQ号
|
|
13
12
|
event["msg"] = event.MessageText; // 消息内容
|
|
@@ -135,55 +134,56 @@ var mw = onMiddleware(selects, async (event, next) => {
|
|
|
135
134
|
}
|
|
136
135
|
}
|
|
137
136
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
137
|
+
if (event.Platform == "scbbs") {
|
|
138
|
+
const ScbbsAPI = await import('@alemonjs/scbbs');
|
|
139
|
+
const [client] = useClient(event, ScbbsAPI);
|
|
140
|
+
event["msg"] = `${event["msg"]}`; // 消息内容包含at机器人昵称
|
|
141
|
+
event["self_id"] = event.value.toUser.id; // 机器人ID
|
|
142
|
+
event["originalMsg"] = event.value.content; // 原始消息内容
|
|
143
|
+
event["atBot"] =
|
|
144
|
+
event.name === "private.message.create" && event.Platform == "scbbs";
|
|
145
|
+
// 处理图片消息
|
|
146
|
+
event["img"] = (event.value.content || [])
|
|
147
|
+
.filter((item) => item.type === "image")
|
|
148
|
+
.map((item) => item.data.url.replace("!/fwfh/368x238", ""));
|
|
149
|
+
// 判断是否为群管理员
|
|
150
|
+
event["isAdmin"] =
|
|
151
|
+
event.value.author.roles?.filter((role) => role.id == 1 || role.id == 2).length > 0;
|
|
152
|
+
event["bot"] = {
|
|
153
|
+
nickname: event.value.toUser.nickname,
|
|
154
|
+
user_id: event.value.toUser.id,
|
|
155
|
+
}; // 机器人信息
|
|
156
|
+
event["raw_message"] = event.value.content
|
|
157
|
+
.map((item) => {
|
|
158
|
+
if (item.type === "text") {
|
|
159
|
+
return item.data.text;
|
|
160
|
+
}
|
|
161
|
+
else if (item.type === "image") {
|
|
162
|
+
return `[CQ:image,${item.data.url}]`;
|
|
163
|
+
}
|
|
164
|
+
else if (item.type === "at") {
|
|
165
|
+
return `[CQ:at,qq=${item.data.id}]`;
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
return `[${item.type.toUpperCase()}]`;
|
|
169
|
+
}
|
|
170
|
+
})
|
|
171
|
+
.join("");
|
|
172
|
+
if (event.replyId && event.replyId !== "-1") {
|
|
173
|
+
const replyMsg = await client.getMessage(event.replyId);
|
|
174
|
+
console.log("获取回复", replyMsg);
|
|
175
|
+
if (replyMsg) {
|
|
176
|
+
event["reply"] = replyMsg[0].data;
|
|
177
|
+
if (replyMsg[0].data.fromUserId == event.self_id) {
|
|
178
|
+
event["atBot"] = true;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
184
183
|
if (event.Platform == "bubble") {
|
|
184
|
+
const BubbleAPI = await import('@alemonjs/bubble');
|
|
185
185
|
const CDN_URL = "https://bubble-oss-files.alemonjs.com/";
|
|
186
|
-
const [client] = useClient(event,
|
|
186
|
+
const [client] = useClient(event, BubbleAPI);
|
|
187
187
|
event["uidkey"] = `${event["guid"]}:${event.value.author}(${event.UserId})`; // 唯一标识
|
|
188
188
|
event["nickname"] =
|
|
189
189
|
`${event.name == "private.message.create" ? "[私信]" : ""}${event.value.author}(${event.UserId})`; // 昵称(用户名+QQ号)
|
|
@@ -258,8 +258,12 @@ var mw = onMiddleware(selects, async (event, next) => {
|
|
|
258
258
|
event["reply"] = replyData;
|
|
259
259
|
}
|
|
260
260
|
}
|
|
261
|
-
|
|
262
|
-
|
|
261
|
+
const atTriggerSwitch = await redisClient.getAtTriggerSwitch(event.ChannelId ?? event.UserId);
|
|
262
|
+
if (atTriggerSwitch === "1" && event.Platform !== "testone") {
|
|
263
|
+
if (!event["atBot"] && event.name !== "private.message.create") {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
263
267
|
next();
|
|
264
268
|
});
|
|
265
269
|
|
package/lib/redis.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getConfigValue } from 'alemonjs';
|
|
2
2
|
import Redis from 'ioredis';
|
|
3
3
|
|
|
4
|
-
const value = getConfigValue().aiChat || {};
|
|
4
|
+
const value = getConfigValue().aiChat || getConfigValue() || {};
|
|
5
5
|
const redisConfig = {
|
|
6
6
|
host: value.redis?.host ?? "localhost",
|
|
7
7
|
port: value.redis?.port ?? 6379,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import redisClient from '../../config.js';
|
|
2
|
-
import
|
|
2
|
+
import App from '../../image/conponent/AiConfig.js';
|
|
3
|
+
import { useMessage, Image, Text } from 'alemonjs';
|
|
4
|
+
import { renderComponentIsHtmlToBuffer } from 'jsxp';
|
|
3
5
|
|
|
4
6
|
const selects = onSelects(["message.create", "private.message.create"]);
|
|
5
7
|
// inline regex used directly in condition checks
|
|
@@ -15,9 +17,29 @@ var res = onResponse(selects, async (e, next) => {
|
|
|
15
17
|
const isOpenTTSReply = await redisClient.getTTSResponseSwitch(e.guid); // TTS回复开关
|
|
16
18
|
const toolsIsOpen = await redisClient.getToolSwitch(e.guid); // 工具开关
|
|
17
19
|
const deepThinkingIsOpen = await redisClient.getDeepThoughtSwitch(e.guid); // 深度思考开关
|
|
20
|
+
const atTriggerSwitch = await redisClient.getAtTriggerSwitch(e.guid); // 仅艾特触发
|
|
21
|
+
const currentAI = await redisClient.getCurrentAI(e.guid); // 当前AI名称
|
|
18
22
|
const aiList = await redisClient.getAIList();
|
|
19
23
|
// 发送消息
|
|
20
|
-
|
|
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)));
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
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
|
+
}
|
|
21
43
|
}
|
|
22
44
|
// 查看AI列表
|
|
23
45
|
if (/^(\/|#)ai列表$/i.test(e.msg)) {
|
package/lib/response/help/res.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { useMessage, Image, Text } from 'alemonjs';
|
|
2
|
-
import {
|
|
3
|
-
import App from '../../image/conponent/
|
|
2
|
+
import { renderComponentIsHtmlToBuffer } from 'jsxp';
|
|
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"]);
|
|
7
7
|
var res = onResponse(selects, async (e) => {
|
|
8
8
|
// 创建
|
|
9
9
|
const [message] = useMessage(e);
|
|
10
|
-
const img = await
|
|
10
|
+
const img = await renderComponentIsHtmlToBuffer(App, {});
|
|
11
11
|
if (img)
|
|
12
12
|
message.send(format(Image(img)));
|
|
13
13
|
const config = await redisClient.getAIConfig(e.guid);
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { availableTools } from '../../api/aitools.js';
|
|
2
|
-
import { loadSkills } from '../../api/loadSkill.js';
|
|
3
2
|
import redisClient from '../../config.js';
|
|
4
3
|
import { useMessage, Text, getConfigValue } from 'alemonjs';
|
|
5
|
-
import { log } from 'console';
|
|
6
4
|
|
|
7
|
-
getConfigValue().aiChat || {};
|
|
5
|
+
const value = getConfigValue().aiChat || {};
|
|
8
6
|
const selects = onSelects(["message.create", "private.message.create"]);
|
|
9
7
|
// inline regex checks are used in-place; keep `test` as shorthand
|
|
10
8
|
const test = /(\/|#)测试$/i;
|
|
@@ -13,11 +11,11 @@ var res = onResponse(selects, async (e, next) => {
|
|
|
13
11
|
const [message] = useMessage(e);
|
|
14
12
|
// 测试
|
|
15
13
|
if (test.test(e.msg)) {
|
|
16
|
-
// 1. 获取技能列表(简要信息)
|
|
17
|
-
const skills = loadSkills();
|
|
18
|
-
console.log(skills);
|
|
19
|
-
log(JSON.stringify(e, null, 2));
|
|
20
14
|
message.send(format(Text("测试消息")));
|
|
15
|
+
// 1. 获取技能列表(简要信息)
|
|
16
|
+
// const skills = loadSkills();
|
|
17
|
+
// console.log(skills);
|
|
18
|
+
// log(JSON.stringify(e, null, 2));
|
|
21
19
|
// let img =
|
|
22
20
|
// "https://imgen.x.ai/xai-imgen/xai-tmp-imgen-597ead9b-8db9-4f43-a501-ee4f32d9b4d0.jpeg";
|
|
23
21
|
// if (img.startsWith("https://imgen.x.ai")) {
|
|
@@ -285,8 +283,11 @@ var res = onResponse(selects, async (e, next) => {
|
|
|
285
283
|
return;
|
|
286
284
|
}
|
|
287
285
|
const [, , action] = match;
|
|
288
|
-
console.log("涩涩action", action);
|
|
289
286
|
const enable = /(关闭|禁止|不可以|不允许)/.test(action) ? false : true;
|
|
287
|
+
if (!value.baidu?.ak && !value.baidu?.sk && !enable) {
|
|
288
|
+
message.send(format(Text("未配置百度AI审核接口,无法停止涩涩!请在配置文件中添加百度AI的AK和SK。")));
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
290
291
|
await redisClient.setR18Switch(e.guid, enable);
|
|
291
292
|
message.send(format(Text(`已${enable ? "允许" : "禁止"}涩涩功能 !`)));
|
|
292
293
|
return;
|
|
@@ -342,7 +343,51 @@ var res = onResponse(selects, async (e, next) => {
|
|
|
342
343
|
message.send(format(Text(`已${enable ? "开启" : "关闭"} AI ${aiName.trim()} 的 RAPI 模式 !`)));
|
|
343
344
|
}
|
|
344
345
|
}
|
|
345
|
-
//
|
|
346
|
+
// 设置仅艾特触发
|
|
347
|
+
if (/(\/|#)(开启|关闭)仅艾特触发$/i.test(e.msg)) {
|
|
348
|
+
const match = e.msg.match(/(\/|#)(开启|关闭)仅艾特触发$/i);
|
|
349
|
+
if (!match) {
|
|
350
|
+
message.send(format(Text("格式错误,请按照 格式:/开启仅艾特触发 或 /关闭仅艾特触发 进行设置")));
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
const [, , action] = match;
|
|
354
|
+
const enable = action === "开启";
|
|
355
|
+
await redisClient.setAtTriggerSwitch(e.guid, enable);
|
|
356
|
+
message.send(format(Text(`已${enable ? "开启" : "关闭"}仅艾特触发功能 !`)));
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
// 获取所有ai工具列表
|
|
360
|
+
if (/(\/|#)工具列表$/i.test(e.msg)) {
|
|
361
|
+
const tools = await redisClient.getAllToolStatus(e.guid);
|
|
362
|
+
const toolList = Object.entries(tools)
|
|
363
|
+
.map(([tool, status]) => `${tool}: ${status === "0" ? "开启" : "关闭"}`)
|
|
364
|
+
.join("\n");
|
|
365
|
+
message.send(format(Text(`当前工具列表及状态:\n${toolList}`)));
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
// 控制工具开关
|
|
369
|
+
if (/(\/|#)(开启|关闭)工具 (.*)$/i.test(e.msg)) {
|
|
370
|
+
if (!e.IsMaster || String(e.UserId) != "3501869534") {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
const match = e.msg.match(/(\/|#)(开启|关闭)工具 (.*)$/i);
|
|
374
|
+
if (!match) {
|
|
375
|
+
message.send(format(Text("格式错误,请按照 格式:/开启工具 <工具名称> 或 /关闭工具 <工具名称> 进行设置")));
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const [, , action, toolName] = match;
|
|
379
|
+
const enable = action === "开启";
|
|
380
|
+
if (enable) {
|
|
381
|
+
redisClient.enableTool(e.guid, toolName.trim());
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
{
|
|
385
|
+
redisClient.disableTool(e.guid, toolName.trim());
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
message.send(format(Text(`已${enable ? "开启" : "关闭"}工具 ${toolName.trim()} !`)));
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
346
391
|
next();
|
|
347
392
|
});
|
|
348
393
|
|
|
@@ -6,7 +6,7 @@ import { log } from 'console';
|
|
|
6
6
|
import OpenAi from 'openai';
|
|
7
7
|
import { TTSClient } from '../../api/tts.js';
|
|
8
8
|
import { getTimeString } from '../../api/format.js';
|
|
9
|
-
import {
|
|
9
|
+
import { availableTools, tools } from '../../api/aitools.js';
|
|
10
10
|
import { loadSkills } from '../../api/loadSkill.js';
|
|
11
11
|
import redisClient from '../../config.js';
|
|
12
12
|
import fileUrl from '../../assets/error.png.js';
|
|
@@ -272,7 +272,7 @@ ${e.ClientError ? `当前错误信息:${e.ClientError}` : ""}
|
|
|
272
272
|
messages: messages,
|
|
273
273
|
};
|
|
274
274
|
if (isTool === "1") {
|
|
275
|
-
createParams["tools"] =
|
|
275
|
+
createParams["tools"] = await redisClient.getAvailableTools(e.guid);
|
|
276
276
|
createParams["tool_choice"] = "auto";
|
|
277
277
|
}
|
|
278
278
|
if (deepThoughtSwitch === "0") {
|
|
@@ -364,8 +364,16 @@ ${e.ClientError ? `当前错误信息:${e.ClientError}` : ""}
|
|
|
364
364
|
}
|
|
365
365
|
else {
|
|
366
366
|
try {
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
if ((await redisClient.getToolStatus(e.guid, functionName)) === "1") {
|
|
368
|
+
console.error(`工具被禁用:${functionName}`);
|
|
369
|
+
functionResult = {
|
|
370
|
+
ok: false,
|
|
371
|
+
error: `工具被禁用:${functionName}`,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
functionResult = await functionToCall(functionArgs);
|
|
376
|
+
}
|
|
369
377
|
}
|
|
370
378
|
catch (err) {
|
|
371
379
|
console.error(`工具执行失败:${functionName}`, err);
|
|
@@ -512,7 +520,9 @@ ${e.ClientError ? `当前错误信息:${e.ClientError}` : ""}
|
|
|
512
520
|
}
|
|
513
521
|
catch (error) {
|
|
514
522
|
console.error("AI回复出错", error);
|
|
515
|
-
|
|
523
|
+
// 清理聊天记录
|
|
524
|
+
await redisClient.clearLastNChatHistory(e.guid, 5);
|
|
525
|
+
message.send(format(Text("AI回复出错了, 已清理聊天记录~\n" + error)));
|
|
516
526
|
next();
|
|
517
527
|
}
|
|
518
528
|
});
|
package/lib/routes/commands.js
CHANGED
|
@@ -20,7 +20,7 @@ var commands = defineRouter([
|
|
|
20
20
|
},
|
|
21
21
|
// setting (包含大量子命令)
|
|
22
22
|
{
|
|
23
|
-
regular: Regular.or(/(\/|#)添加ai$/i, /(\/|#)添加ai\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/i, /(\/|#)(切换)(ai|配置) ?(.*)/i, /(\/|#)添加提示词$/i, /(\/|#)添加提示词 (\S+) ([\s\S]+)/i, /(\/|#)(删除)(提示词|提示词列表) ?(.*)/i, /(\/|#)(切换|设置)提示词 ?(.*)$/i, /(\/|#)清空提示词$/i, /(\/|#)删除ai\s(\S+)$/i, /(\/|#)(开启|启用|关闭|禁用)好感度$/i, /(\/|#)(开启|关闭)(全部)?聊天$/i, /(\/|#)(开启|关闭)语音回复$/i, /(\/|#)(开启|关闭)(MCP)?工具$/i, /(\/|#)切换图床(.*)$/i, /(\/|#)修改 ?(.+) ?模型 ?(.+)$/i, /(\/|#)(关闭|开启)复杂(输出|回复)$/i, /(\/|#)(关闭|禁止|不可以|不允许|开启|可以|允许)(涩涩|色色)$/i, /(\/|#)切换模型(.*)$/i, /(\/|#)(关闭|开启)主动(搭话|回复)$/i, /(\/|#)(开启|关闭)深度思考$/i, /(\/|#)(设置|修改)(ai)?(.*)rapi模式(开启|关闭)$/i, /(\/|#)测试$/i),
|
|
23
|
+
regular: Regular.or(/(\/|#)添加ai$/i, /(\/|#)添加ai\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/i, /(\/|#)(切换)(ai|配置) ?(.*)/i, /(\/|#)添加提示词$/i, /(\/|#)添加提示词 (\S+) ([\s\S]+)/i, /(\/|#)(删除)(提示词|提示词列表) ?(.*)/i, /(\/|#)(切换|设置)提示词 ?(.*)$/i, /(\/|#)清空提示词$/i, /(\/|#)删除ai\s(\S+)$/i, /(\/|#)(开启|启用|关闭|禁用)好感度$/i, /(\/|#)(开启|关闭)(全部)?聊天$/i, /(\/|#)(开启|关闭)语音回复$/i, /(\/|#)(开启|关闭)(MCP)?工具$/i, /(\/|#)切换图床(.*)$/i, /(\/|#)修改 ?(.+) ?模型 ?(.+)$/i, /(\/|#)(关闭|开启)复杂(输出|回复)$/i, /(\/|#)(关闭|禁止|不可以|不允许|开启|可以|允许)(涩涩|色色)$/i, /(\/|#)切换模型(.*)$/i, /(\/|#)(关闭|开启)主动(搭话|回复)$/i, /(\/|#)(开启|关闭)深度思考$/i, /(\/|#)(设置|修改)(ai)?(.*)rapi模式(开启|关闭)$/i, /(\/|#)(开启|关闭)仅艾特触发$/i, /(\/|#)工具列表$/i, /(\/|#)(开启|关闭)工具 (.*)$/i, /(\/|#)测试$/i),
|
|
24
24
|
handler: lazy(() => import('../response/setting/res.js')),
|
|
25
25
|
},
|
|
26
26
|
// affection
|
|
@@ -38,11 +38,6 @@ var commands = defineRouter([
|
|
|
38
38
|
regular: /.*/,
|
|
39
39
|
handler: lazy(() => import('../response/zreply/res.js')),
|
|
40
40
|
},
|
|
41
|
-
// fallback: zreply - 最低优先级,处理普通对话
|
|
42
|
-
// {
|
|
43
|
-
// regular: /.*/,
|
|
44
|
-
// handler: lazy(() => import("../response/zreply/rapi.res")),
|
|
45
|
-
// },
|
|
46
41
|
]);
|
|
47
42
|
|
|
48
43
|
export { commands as default };
|
package/lib/s3.js
CHANGED
|
@@ -2,7 +2,6 @@ import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
|
|
|
2
2
|
import fs from 'fs/promises';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import mime from 'mime-types';
|
|
5
|
-
import { redis } from './redis.js';
|
|
6
5
|
import sharp from 'sharp';
|
|
7
6
|
import { getConfigValue } from 'alemonjs';
|
|
8
7
|
|
|
@@ -180,23 +179,13 @@ const uploadImageToR2 = async (source, key, processOptions = {}) => {
|
|
|
180
179
|
const { buffer: originalBuffer, contentType: originalContentType, fileName: originalFileName, } = await getImageBuffer(source);
|
|
181
180
|
// 2. 预处理图片(转换格式、压缩、处理动图)
|
|
182
181
|
const { buffer: processedBuffer, contentType, format, wasAnimated, } = await preprocessImage(originalBuffer, originalContentType, processOptions);
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
publicDomain: "https://r2img.ccxk.top",
|
|
191
|
-
endpoint: "https://b24a196dc2ee578845bb555d53812508.r2.cloudflarestorage.com",
|
|
192
|
-
}
|
|
193
|
-
: {
|
|
194
|
-
accessKeyId: "pCLV51yDLbntzsfUkgBSjo5fJSor3nr5",
|
|
195
|
-
secretAccessKey: "5672e62135be31808f1afbd35862839e",
|
|
196
|
-
bucket: "schub-image",
|
|
197
|
-
publicDomain: "https://s3img.suancaixianyu.cn",
|
|
198
|
-
endpoint: "https://s3.api.upyun.com",
|
|
199
|
-
};
|
|
182
|
+
const R2_CONFIG = {
|
|
183
|
+
accessKeyId: "f8f0d360d3156a1667c527c5ea4b18d7",
|
|
184
|
+
secretAccessKey: "365f44cf6079054ad99923dd32966d0aba4e4d2d24726cadcd0102a7c2e7bc08",
|
|
185
|
+
bucket: "images",
|
|
186
|
+
publicDomain: "https://r2img.ccxk.top",
|
|
187
|
+
endpoint: "https://b24a196dc2ee578845bb555d53812508.r2.cloudflarestorage.com",
|
|
188
|
+
};
|
|
200
189
|
// 4. 创建S3客户端
|
|
201
190
|
const s3Client = new S3Client({
|
|
202
191
|
region: "auto",
|
package/package.json
CHANGED
|
@@ -1,63 +1,59 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "alemonjs-aichat",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "alemonjs-aichat",
|
|
5
|
-
"author": "suancaixianyu",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"main": "lib/index.js",
|
|
8
|
-
"type": "module",
|
|
9
|
-
"scripts": {
|
|
10
|
-
"dev": "npx lvy dev",
|
|
11
|
-
"build": "npx lvy build",
|
|
12
|
-
"review": "npx alemonc start",
|
|
13
|
-
"start": "npx pm2 startOrRestart pm2.config.cjs",
|
|
14
|
-
"stop": "npx pm2 stop pm2.config.cjs",
|
|
15
|
-
"delete": "npx pm2 delete pm2.config.cjs",
|
|
16
|
-
"update": "npm publish"
|
|
17
|
-
},
|
|
18
|
-
"devDependencies": {
|
|
19
|
-
"@alemonjs/bubble": "^2.1.
|
|
20
|
-
"@alemonjs/db": "^0.0.16",
|
|
21
|
-
"@alemonjs/onebot": "^2.1.14",
|
|
22
|
-
"@types/node": "^22",
|
|
23
|
-
"alemonjs": "2.1.
|
|
24
|
-
"cssnano": "^7",
|
|
25
|
-
"jsxp": "^1.3.0",
|
|
26
|
-
"lvyjs": "^0.2.25",
|
|
27
|
-
"pm2": "^5",
|
|
28
|
-
"tailwindcss": "3"
|
|
29
|
-
},
|
|
30
|
-
"export": {
|
|
31
|
-
".": "./lib/index.js",
|
|
32
|
-
"./package": "./package.json",
|
|
33
|
-
"./desktop": "./lib/desktop.js"
|
|
34
|
-
},
|
|
35
|
-
"exports": {
|
|
36
|
-
".": "./lib/index.js",
|
|
37
|
-
"./package": "./package.json",
|
|
38
|
-
"./desktop": "./lib/desktop.js"
|
|
39
|
-
},
|
|
40
|
-
"publishConfig": {
|
|
41
|
-
"registry": "https://registry.npmjs.org",
|
|
42
|
-
"access": "public"
|
|
43
|
-
},
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
|
|
59
|
-
"openai": "^6.34.0",
|
|
60
|
-
"sharp": "^0.34.5",
|
|
61
|
-
"zod": "^4.3.6"
|
|
62
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "alemonjs-aichat",
|
|
3
|
+
"version": "1.0.26",
|
|
4
|
+
"description": "alemonjs-aichat",
|
|
5
|
+
"author": "suancaixianyu",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"main": "lib/index.js",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "npx lvy dev",
|
|
11
|
+
"build": "npx lvy build",
|
|
12
|
+
"review": "npx alemonc start",
|
|
13
|
+
"start": "npx pm2 startOrRestart pm2.config.cjs",
|
|
14
|
+
"stop": "npx pm2 stop pm2.config.cjs",
|
|
15
|
+
"delete": "npx pm2 delete pm2.config.cjs",
|
|
16
|
+
"update": "npm publish"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@alemonjs/bubble": "^2.1.10",
|
|
20
|
+
"@alemonjs/db": "^0.0.16",
|
|
21
|
+
"@alemonjs/onebot": "^2.1.14",
|
|
22
|
+
"@types/node": "^22",
|
|
23
|
+
"alemonjs": "2.1.57",
|
|
24
|
+
"cssnano": "^7",
|
|
25
|
+
"jsxp": "^1.3.0",
|
|
26
|
+
"lvyjs": "^0.2.25",
|
|
27
|
+
"pm2": "^5",
|
|
28
|
+
"tailwindcss": "3"
|
|
29
|
+
},
|
|
30
|
+
"export": {
|
|
31
|
+
".": "./lib/index.js",
|
|
32
|
+
"./package": "./package.json",
|
|
33
|
+
"./desktop": "./lib/desktop.js"
|
|
34
|
+
},
|
|
35
|
+
"exports": {
|
|
36
|
+
".": "./lib/index.js",
|
|
37
|
+
"./package": "./package.json",
|
|
38
|
+
"./desktop": "./lib/desktop.js"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"registry": "https://registry.npmjs.org",
|
|
42
|
+
"access": "public"
|
|
43
|
+
},
|
|
44
|
+
"workspaces": [
|
|
45
|
+
"packages/*"
|
|
46
|
+
],
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@ai-sdk/xai": "^3.0.60",
|
|
49
|
+
"@aws-sdk/client-s3": "^3.975.0",
|
|
50
|
+
"@aws-sdk/s3-request-presigner": "^3.975.0",
|
|
51
|
+
"ai": "^6.0.105",
|
|
52
|
+
"alemonjs-aichat": "^1.0.25",
|
|
53
|
+
"mime-types": "^3.0.2",
|
|
54
|
+
"node-fetch": "^3.3.2",
|
|
55
|
+
"openai": "^6.34.0",
|
|
56
|
+
"sharp": "^0.34.5",
|
|
57
|
+
"zod": "^4.3.6"
|
|
58
|
+
}
|
|
63
59
|
}
|