halbot 1990.1.65 → 1990.1.67
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/README.md +7 -5
- package/bin/halbot.mjs +15 -15
- package/index.mjs +6 -2
- package/package.json +7 -7
- package/skills/{engine.mjs → 10_engine.mjs} +21 -4
- package/skills/{wording.mjs → 40_wording.mjs} +8 -7
- package/skills/50_execute.mjs +16 -0
- package/skills/{prepare.mjs → 60_prepare.mjs} +10 -11
- package/skills/{chat.mjs → 70_chat.mjs} +15 -18
- package/skills/execute.mjs +0 -17
- /package/skills/{instant.mjs → 20_instant.mjs} +0 -0
- /package/skills/{prompt.mjs → 30_prompt.mjs} +0 -0
package/README.md
CHANGED
|
@@ -103,10 +103,10 @@ All supported configuration fields:
|
|
|
103
103
|
"help": "[[help information]]",
|
|
104
104
|
|
|
105
105
|
// OPTIONAL, object.
|
|
106
|
-
//
|
|
106
|
+
// Sessions/conversations storage, support MariaDB/MySQL and Redis for now.
|
|
107
107
|
// If omitted, the bot will use memory storage and sync to this file.
|
|
108
108
|
// Example: (Compatibility: https://github.com/sidorares/node-mysql2)
|
|
109
|
-
"
|
|
109
|
+
"storage": {
|
|
110
110
|
"type": "[["MARIADB" || "MYSQL"]]",
|
|
111
111
|
"host": "[[DATABASE HOST]]",
|
|
112
112
|
"database": "[[DATABASE NAME]]",
|
|
@@ -115,7 +115,7 @@ All supported configuration fields:
|
|
|
115
115
|
...[[OTHER DATABASE OPTIONS]],
|
|
116
116
|
},
|
|
117
117
|
// OR: (Compatibility: https://github.com/luin/ioredis)
|
|
118
|
-
"
|
|
118
|
+
"storage": {
|
|
119
119
|
"type": "REDIS",
|
|
120
120
|
"host": "[[REDIS HOST]]",
|
|
121
121
|
"password": "[[REDIS PASSWORD]]",
|
|
@@ -201,8 +201,10 @@ const config = {
|
|
|
201
201
|
skillPath: [[pathToYourMiddlewares]],
|
|
202
202
|
|
|
203
203
|
// OPTIONAL, object.
|
|
204
|
-
// Using customized
|
|
205
|
-
|
|
204
|
+
// Using customized storage engine.
|
|
205
|
+
// `storage` should Should be compatible with the `Map` interface:
|
|
206
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
|
|
207
|
+
storage: {
|
|
206
208
|
get: async (key) => { /* return session object by chatId. */ },
|
|
207
209
|
set: async (key, session) => { /* save session object by chatId. */ },
|
|
208
210
|
},
|
package/bin/halbot.mjs
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { cache, dbio, memory, storage, utilitas } from 'utilitas';
|
|
3
|
+
import { cache, dbio, memory, storage as _storage, utilitas } from 'utilitas';
|
|
4
4
|
import halbot from '../index.mjs';
|
|
5
5
|
|
|
6
6
|
const debug = utilitas.humanReadableBoolean(process.env['DEBUG']);
|
|
7
7
|
const log = content => utilitas.log(content, import.meta.url);
|
|
8
|
-
const
|
|
8
|
+
const MEMORY = 'memory';
|
|
9
|
+
const _getConfig = async () => await _storage.getConfig();
|
|
10
|
+
const getConfig = async key => (await _getConfig())?.config?.[key];
|
|
9
11
|
|
|
10
|
-
let
|
|
11
|
-
get: async key => (await getConfig())?.
|
|
12
|
-
set: async (k, v) => await
|
|
12
|
+
let storage = {
|
|
13
|
+
get: async key => (await getConfig(MEMORY))?.[key],
|
|
14
|
+
set: async (k, v) => await _storage.setConfig({ [MEMORY]: { [k]: v } }),
|
|
13
15
|
};
|
|
14
16
|
|
|
15
17
|
try {
|
|
16
|
-
const { filename, config } = await
|
|
18
|
+
const { filename, config } = await _getConfig();
|
|
17
19
|
assert(utilitas.countKeys(config), `Error loading config from ${filename}.`);
|
|
18
|
-
const sessionType = utilitas.trim(config.
|
|
19
|
-
if (config.
|
|
20
|
+
const sessionType = utilitas.trim(config.storage?.type, { case: 'UP' });
|
|
21
|
+
if (config.storage?.type) { delete config.storage.type; }
|
|
20
22
|
switch (sessionType) {
|
|
21
23
|
case 'MARIADB': case 'MYSQL':
|
|
22
|
-
await dbio.init(config.
|
|
23
|
-
await memory.init();
|
|
24
|
-
session = memory;
|
|
24
|
+
await dbio.init(config.storage);
|
|
25
|
+
storage = await memory.init();
|
|
25
26
|
break;
|
|
26
27
|
case 'REDIS':
|
|
27
|
-
await cache.init(config.
|
|
28
|
-
session = cache;
|
|
28
|
+
storage = await cache.init(config.storage);
|
|
29
29
|
break;
|
|
30
30
|
default:
|
|
31
|
-
config.
|
|
31
|
+
config.storage && utilitas.throwError('Invalid storage config.');
|
|
32
32
|
}
|
|
33
|
-
await halbot({ ...config,
|
|
33
|
+
await halbot({ ...config, storage });
|
|
34
34
|
} catch (err) { debug ? utilitas.throwError(err) : log(err); }
|
package/index.mjs
CHANGED
|
@@ -31,6 +31,7 @@ const init = async (options) => {
|
|
|
31
31
|
assert(options?.telegramToken, 'Telegram Bot API Token is required.');
|
|
32
32
|
const [pkg, ai, _speech] = [await utilitas.which(), {}, {}];
|
|
33
33
|
const info = bot.lines([`[${bot.EMOJI_BOT} ${pkg.title}](${pkg.homepage})`, pkg.description]);
|
|
34
|
+
const cacheOptions = options?.storage ? { store: options.storage } : null;
|
|
34
35
|
if (options?.googleApiKey) {
|
|
35
36
|
const apiKey = { apiKey: options?.googleApiKey };
|
|
36
37
|
await Promise.all([
|
|
@@ -41,17 +42,19 @@ const init = async (options) => {
|
|
|
41
42
|
if (options?.chatGptKey) {
|
|
42
43
|
ai['ChatGPT'] = await hal.init({
|
|
43
44
|
provider: 'CHATGPT', clientOptions: { apiKey: options.chatGptKey },
|
|
45
|
+
cacheOptions,
|
|
44
46
|
});
|
|
45
47
|
}
|
|
46
48
|
if (options?.bingToken) {
|
|
47
49
|
ai['Bing'] = await hal.init({
|
|
48
50
|
provider: 'BING', clientOptions: { userToken: options.bingToken },
|
|
51
|
+
cacheOptions,
|
|
49
52
|
});
|
|
50
53
|
}
|
|
51
54
|
assert(utilitas.countKeys(ai), 'No AI provider is configured.');
|
|
52
55
|
const _bot = await bot.init({
|
|
53
|
-
ai, auth: options?.auth,
|
|
54
56
|
args: options?.args,
|
|
57
|
+
auth: options?.auth,
|
|
55
58
|
botToken: options?.telegramToken,
|
|
56
59
|
chatType: options?.chatType,
|
|
57
60
|
cmds: options?.cmds,
|
|
@@ -62,11 +65,12 @@ const init = async (options) => {
|
|
|
62
65
|
magicWord: options?.magicWord,
|
|
63
66
|
private: options?.private,
|
|
64
67
|
provider: 'telegram',
|
|
65
|
-
session: options?.
|
|
68
|
+
session: options?.storage,
|
|
66
69
|
skillPath: options?.skillPath || skillPath,
|
|
67
70
|
speech: options?.googleApiKey && speech,
|
|
68
71
|
vision: options?.googleApiKey && vision,
|
|
69
72
|
});
|
|
73
|
+
_bot._.ai = ai; // Should be an array of a map of AIs.
|
|
70
74
|
_bot._.lang = options?.lang || 'English';
|
|
71
75
|
_bot._.prompts = await fetchPrompts();
|
|
72
76
|
return _bot;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "halbot",
|
|
3
3
|
"description": "Just another ChatGPT/Bing Chat Telegram bob, which is simple design, easy to use, extendable and fun.",
|
|
4
|
-
"version": "1990.1.
|
|
4
|
+
"version": "1990.1.67",
|
|
5
5
|
"private": false,
|
|
6
6
|
"homepage": "https://github.com/Leask/halbot",
|
|
7
7
|
"type": "module",
|
|
@@ -29,17 +29,17 @@
|
|
|
29
29
|
"url": "https://github.com/Leask/halbot.git"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@google-cloud/speech": "^5.4.
|
|
33
|
-
"@google-cloud/text-to-speech": "^4.2.
|
|
34
|
-
"@google-cloud/vision": "^3.1.
|
|
32
|
+
"@google-cloud/speech": "^5.4.1",
|
|
33
|
+
"@google-cloud/text-to-speech": "^4.2.2",
|
|
34
|
+
"@google-cloud/vision": "^3.1.3",
|
|
35
35
|
"@mozilla/readability": "^0.4.4",
|
|
36
|
-
"@waylaidwanderer/chatgpt-api": "
|
|
36
|
+
"@waylaidwanderer/chatgpt-api": "github:Leask/node-chatgpt-api",
|
|
37
37
|
"csv-parse": "^5.3.6",
|
|
38
38
|
"ioredis": "^5.3.1",
|
|
39
39
|
"jsdom": "^21.1.1",
|
|
40
|
-
"mysql2": "^3.2.
|
|
40
|
+
"mysql2": "^3.2.1",
|
|
41
41
|
"telegraf": "^4.12.2",
|
|
42
|
-
"utilitas": "^
|
|
42
|
+
"utilitas": "^1994.0.3",
|
|
43
43
|
"youtube-transcript": "^1.0.5"
|
|
44
44
|
}
|
|
45
45
|
}
|
|
@@ -6,11 +6,15 @@ const bingTones = [balanced, 'creative', 'precise'];
|
|
|
6
6
|
let configuredAi;
|
|
7
7
|
|
|
8
8
|
const action = async (ctx, next) => {
|
|
9
|
+
ctx.session.context || (ctx.session.context = {});
|
|
10
|
+
ctx.session.latest || (ctx.session.latest = {});
|
|
9
11
|
ctx.isDefaultAi = name => name === ctx.firstAi;
|
|
10
|
-
ctx.clear =
|
|
12
|
+
ctx.clear = context => (ctx.selectedAi || []).map(n => {
|
|
11
13
|
ctx._.ai[n].clear(ctx.chatId);
|
|
12
|
-
ctx.
|
|
13
|
-
|
|
14
|
+
delete ctx.session.context[n];
|
|
15
|
+
delete ctx.session.latest[n];
|
|
16
|
+
context && (ctx.session.context[n] = context);
|
|
17
|
+
}) && ctx.hello(context?.prompt);
|
|
14
18
|
ctx.firstAi = (configuredAi = Object.keys(ctx._.ai))[0];
|
|
15
19
|
switch (ctx.session.config?.ai) {
|
|
16
20
|
case '': ctx.selectedAi = [ctx.firstAi]; break;
|
|
@@ -49,12 +53,21 @@ export const { run, priority, func, help, args } = {
|
|
|
49
53
|
'¶ Tweak enhanced output rendering.',
|
|
50
54
|
'Example 1: /set --render on',
|
|
51
55
|
'Example 2: /set --render off',
|
|
56
|
+
// '¶ Select between [OpenAI models](https://platform.openai.com/docs/models).',
|
|
57
|
+
// "Tip !!!4!!!: Set `gptmodel=''` to use default OpenAI model.",
|
|
58
|
+
// 'Popular models:',
|
|
59
|
+
// '- [gpt-4](https://platform.openai.com/docs/models/gpt-4): 8192 tokens, trained Sep 2021 (Limited beta).',
|
|
60
|
+
// '- [gpt-4-32k](https://platform.openai.com/docs/models/gpt-4): 32768 tokens, trained Sep 2021 (Limited beta).',
|
|
61
|
+
// '- [gpt-3.5-turbo](https://platform.openai.com/docs/models/gpt-3-5): 4096 tokens, trained Sep 2021.',
|
|
62
|
+
// '- [text-davinci-003](https://platform.openai.com/docs/models/gpt-3-5): 4097 tokens, trained Sep 2021.',
|
|
63
|
+
// '- [text-davinci-002](https://platform.openai.com/docs/models/gpt-3-5): 4097 tokens, trained Sep 2021.',
|
|
64
|
+
// '- [code-davinci-002](https://platform.openai.com/docs/models/gpt-3-5): 8001 tokens, trained Sep 2021 (Coding Optimized).',
|
|
52
65
|
'¶ Set tone-style for Bing.',
|
|
53
66
|
"Tip 4: Set `tone=''` to use default tone-style.",
|
|
54
67
|
]),
|
|
55
68
|
args: {
|
|
56
69
|
hello: {
|
|
57
|
-
type: 'string', short: '
|
|
70
|
+
type: 'string', short: 's', default: 'You are ChatGPT, a large...',
|
|
58
71
|
desc: "Change initial prompt: /set --hello 'Bonjour!'",
|
|
59
72
|
},
|
|
60
73
|
ai: {
|
|
@@ -67,6 +80,10 @@ export const { run, priority, func, help, args } = {
|
|
|
67
80
|
desc: `\`(${bot.BINARY_STRINGS.join(', ')})\` Enable/Disable enhanced output rendering.`,
|
|
68
81
|
validate: utilitas.humanReadableBoolean,
|
|
69
82
|
},
|
|
83
|
+
// gptmodel: {
|
|
84
|
+
// type: 'string', short: 'g', default: 'gpt-3.5-turbo',
|
|
85
|
+
// desc: 'Set OpenAI model: /set --gptmodel=`MODEL`.',
|
|
86
|
+
// },
|
|
70
87
|
tone: {
|
|
71
88
|
type: 'string', short: 't', default: balanced,
|
|
72
89
|
desc: `\`(${bingTones.join(', ')})\` Set tone-style for Bing.`,
|
|
@@ -26,15 +26,16 @@ const action = async (ctx, next) => {
|
|
|
26
26
|
}
|
|
27
27
|
const cnf = {
|
|
28
28
|
...ctx.session.config = {
|
|
29
|
-
...ctx.session.config,
|
|
29
|
+
...ctx.session.config,
|
|
30
|
+
...ctx.config = {
|
|
30
31
|
lang: ctx.cmd.args,
|
|
31
|
-
hello: `Please reply in ${ctx.cmd.args}. Hello
|
|
32
|
-
}
|
|
32
|
+
hello: `Please reply in ${ctx.cmd.args}. Hello!`,
|
|
33
|
+
},
|
|
33
34
|
}
|
|
34
35
|
};
|
|
35
|
-
Object.keys(ctx.config).map(x => cnf[x]
|
|
36
|
-
ctx.
|
|
37
|
-
|
|
36
|
+
Object.keys(ctx.config).map(x => cnf[x] += ' <-- SET');
|
|
37
|
+
ctx.result = bot.map(cnf);
|
|
38
|
+
ctx.hello();
|
|
38
39
|
break;
|
|
39
40
|
case 'translate': promptTranslate(ctx, ctx.cmd.args || ctx.session.config?.lang || ctx._.lang); break;
|
|
40
41
|
case 'polish': promptPolish(ctx); break;
|
|
@@ -48,7 +49,7 @@ const action = async (ctx, next) => {
|
|
|
48
49
|
|
|
49
50
|
export const { run, priority, func, cmds, help } = {
|
|
50
51
|
run: true,
|
|
51
|
-
priority:
|
|
52
|
+
priority: 40,
|
|
52
53
|
func: action,
|
|
53
54
|
help: bot.lines([
|
|
54
55
|
'¶ Set your default language.',
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
|
|
2
|
+
const action = async (ctx, next) => {
|
|
3
|
+
const cmd = ctx.cmd?.cmd;
|
|
4
|
+
if (!ctx.context) {
|
|
5
|
+
const prompt = ctx.session.prompts?.[cmd] || ctx._.prompts?.[cmd]?.prompt;
|
|
6
|
+
prompt && (ctx.context = { cmd, prompt });
|
|
7
|
+
}
|
|
8
|
+
ctx.context && ctx.clear(ctx.context);
|
|
9
|
+
await next();
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const { run, priority, func } = {
|
|
13
|
+
run: true,
|
|
14
|
+
priority: 50,
|
|
15
|
+
func: action,
|
|
16
|
+
};
|
|
@@ -5,16 +5,16 @@ const countTokens = text => text.split(/[^a-z0-9]/i).length;
|
|
|
5
5
|
|
|
6
6
|
const action = async (ctx, next) => {
|
|
7
7
|
// avatar
|
|
8
|
-
if (ctx.
|
|
8
|
+
if (ctx.result) {
|
|
9
9
|
ctx.avatar = '⚙️';
|
|
10
10
|
} else if (ctx.msg?.voice) {
|
|
11
|
-
ctx.avatar = bot.EMOJI_SPEECH; ctx.
|
|
11
|
+
ctx.avatar = bot.EMOJI_SPEECH; ctx.result = utilitas.trim(ctx.text);
|
|
12
12
|
} else if (ctx.msg?.data) {
|
|
13
|
-
ctx.avatar = '🔘'; ctx.
|
|
13
|
+
ctx.avatar = '🔘'; ctx.result = utilitas.trim(ctx.text);
|
|
14
14
|
} else if (ctx.msg?.poll) {
|
|
15
15
|
ctx.avatar = '📊';
|
|
16
16
|
} else if (ctx.cmd?.cmd && ctx.cmd?.cmd !== 'clear') {
|
|
17
|
-
ctx.avatar = '🚀'; ctx.
|
|
17
|
+
ctx.avatar = '🚀'; ctx.result = utilitas.trim(ctx.text);
|
|
18
18
|
} else {
|
|
19
19
|
ctx.avatar = '😸';
|
|
20
20
|
}
|
|
@@ -22,16 +22,15 @@ const action = async (ctx, next) => {
|
|
|
22
22
|
const additionInfo = ctx.collected.length ? ctx.collected.map(
|
|
23
23
|
x => x.content
|
|
24
24
|
).join('\n').split(' ') : [];
|
|
25
|
-
ctx.
|
|
26
|
-
while (countTokens(ctx.
|
|
27
|
-
ctx.
|
|
25
|
+
ctx.prompt = (ctx.text || '') + '\n\n';
|
|
26
|
+
while (countTokens(ctx.prompt) < 2250 && additionInfo.length) {
|
|
27
|
+
ctx.prompt += ` ${additionInfo.shift()}`;
|
|
28
28
|
}
|
|
29
|
-
ctx.
|
|
30
|
-
additionInfo.filter(x => x).length && (ctx.
|
|
29
|
+
ctx.prompt = utilitas.trim(ctx.prompt);
|
|
30
|
+
additionInfo.filter(x => x).length && (ctx.prompt += '...');
|
|
31
31
|
// next
|
|
32
32
|
ctx.carry = {
|
|
33
|
-
|
|
34
|
-
context: ctx.context,
|
|
33
|
+
sessionId: ctx.chatId,
|
|
35
34
|
toneStyle: ctx.session.config?.tone,
|
|
36
35
|
};
|
|
37
36
|
await next();
|
|
@@ -7,22 +7,22 @@ const enrich = name => name === 'Bing' ? `${name} (Sydney)` : name;
|
|
|
7
7
|
const log = content => utilitas.log(content, import.meta.url);
|
|
8
8
|
|
|
9
9
|
const action = async (ctx, next) => {
|
|
10
|
-
if (!ctx.
|
|
11
|
-
const [YOU, msgs,
|
|
12
|
-
= [`${ctx.avatar} You:`, {}, {}, {}, [], {}];
|
|
10
|
+
if (!ctx.prompt) { return await next(); }
|
|
11
|
+
const [YOU, msgs, tts, pms, extra] = [`${ctx.avatar} You:`, {}, {}, [], {}];
|
|
13
12
|
let [lastMsg, lastSent] = [null, 0];
|
|
14
13
|
const packMsg = options => {
|
|
15
|
-
const said = !options?.tts && ctx.
|
|
14
|
+
const said = !options?.tts && ctx.result ? ctx.result : '';
|
|
16
15
|
const packed = [...said ? [joinL2([YOU, said])] : []];
|
|
17
16
|
const source = options?.tts ? tts : msgs;
|
|
18
17
|
const pure = [];
|
|
19
18
|
ctx.selectedAi.map(n => {
|
|
20
19
|
const content = source[n] || '';
|
|
20
|
+
const cmd = ctx.session.context[n]?.cmd;
|
|
21
|
+
const context = cmd && ` > \`${cmd}\` (exit by /clear)` || '';
|
|
21
22
|
pure.push(content);
|
|
22
23
|
packed.push(joinL2([
|
|
23
|
-
...ctx.multiAi || !ctx.isDefaultAi(n) || said ||
|
|
24
|
-
`${BOT}${enrich(n)}${
|
|
25
|
-
] : [], content,
|
|
24
|
+
...ctx.multiAi || !ctx.isDefaultAi(n) || said || context
|
|
25
|
+
? [`${BOT}${enrich(n)}${context}:`] : [], content,
|
|
26
26
|
]));
|
|
27
27
|
});
|
|
28
28
|
return options?.tts && !pure.join('').trim().length ? '' : joinL1(packed);
|
|
@@ -39,18 +39,19 @@ const action = async (ctx, next) => {
|
|
|
39
39
|
for (let n of ctx.selectedAi) {
|
|
40
40
|
pms.push((async () => {
|
|
41
41
|
try {
|
|
42
|
-
const
|
|
42
|
+
const response = await ctx._.ai[n].send(ctx.prompt, {
|
|
43
|
+
...ctx.carry, session: ctx.session.latest[n], // promptPrefix: '',
|
|
44
|
+
}, token => {
|
|
43
45
|
msgs[n] = `${(msgs[n] || '')}${token}`;
|
|
44
46
|
ok(onProgress);
|
|
45
47
|
});
|
|
46
|
-
ctxs[n] = resp.context;
|
|
47
48
|
msgs[n] = ctx.session.config?.render === false
|
|
48
|
-
?
|
|
49
|
-
tts[n] = msgs[n].split('\n').some(x => /^```/.test(x)) ? '' :
|
|
50
|
-
extra.buttons =
|
|
49
|
+
? response.response : response.responseRendered;
|
|
50
|
+
tts[n] = msgs[n].split('\n').some(x => /^```/.test(x)) ? '' : response.spokenText;
|
|
51
|
+
extra.buttons = response?.suggestedResponses?.map?.(label => ({
|
|
51
52
|
label, text: `/bing@${ctx.botInfo.username} ${label}`,
|
|
52
53
|
}));
|
|
53
|
-
return
|
|
54
|
+
return ctx.session.latest[n] = response;
|
|
54
55
|
} catch (err) {
|
|
55
56
|
msgs[n] = err?.message || err;
|
|
56
57
|
tts[n] = msgs[n];
|
|
@@ -58,11 +59,7 @@ const action = async (ctx, next) => {
|
|
|
58
59
|
}
|
|
59
60
|
})());
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
-
prompt: ctx.text,
|
|
63
|
-
carry: ctx.carry,
|
|
64
|
-
responses: await Promise.all(pms),
|
|
65
|
-
};
|
|
62
|
+
await Promise.all(pms);
|
|
66
63
|
await ok();
|
|
67
64
|
// ctx.responses = msgs; // save responses-to-user for next middleware
|
|
68
65
|
ctx.tts = packMsg({ tts: true });
|
package/skills/execute.mjs
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
const action = async (ctx, next) => {
|
|
3
|
-
const cmd = ctx.cmd?.cmd;
|
|
4
|
-
const prompt = ctx.session.prompts?.[cmd] || ctx._.prompts?.[cmd]?.prompt;
|
|
5
|
-
if (prompt) {
|
|
6
|
-
ctx.clear();
|
|
7
|
-
ctx.context = { cmd, prompt };
|
|
8
|
-
ctx.collect(prompt);
|
|
9
|
-
}
|
|
10
|
-
await next();
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export const { run, priority, func } = {
|
|
14
|
-
run: true,
|
|
15
|
-
priority: 40,
|
|
16
|
-
func: action,
|
|
17
|
-
};
|
|
File without changes
|
|
File without changes
|