Skip to content

Commit 4b376ab

Browse files
committed
add aliases; add sentiment analysis; add alpaca UC; misc. fixes
1 parent 07eeb75 commit 4b376ab

22 files changed

+2511
-317
lines changed

config/default.js

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,27 @@ const _config = {
194194
openai: {
195195
secretKey: null,
196196
model: 'text-davinci-003',
197-
temperature: 0.7,
198-
maxTokens: 4000
197+
chatModel: 'gpt-3.5-turbo',
198+
temperature: 0.9,
199+
maxTokens: 3700,
200+
viaHTML: 'the <a href="https://beta.openai.com/docs/guides/completion" target="_blank">OpenAI text completion API</a>'
201+
},
202+
203+
alpaca: {
204+
/*
205+
hosts: {
206+
// will result in queries to:
207+
// https://alpaca.example.com/prompt and https://alpaca-ht.example.com/prompt
208+
"example.com": {
209+
models: ["alpaca", "alpaca-ht"],
210+
scheme: "https"
211+
}
212+
}
213+
*/
214+
hosts: {},
215+
waitTimeSeconds: 5,
216+
viaHTML: '<a href="https://github.com/edfletcher/alpaca.http" target="_blank">alpaca.http</a> running the <a href="https://huggingface.co/Sosaka/Alpaca-native-4bit-ggml/blob/main/ggml-alpaca-7b-q4.bin" target="_blank">7 billion 4-bit weights Alpaca model</a>',
217+
camelidaeFrontendAvailable: false
199218
},
200219

201220
_secretKeys: SECRET_KEYS,

discord.js

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const { plotMpmData } = require('./discord/plotting');
1515
const eventHandlers = require('./discord/events');
1616
const registerContextMenus = require('./discord/contextMenus');
1717
const parsers = require('./lib/parsers');
18+
const { loadAliases, tryResolvingAlias } = require('./discord/lib/ucAliases');
1819
const UCHistory = require('./discord/userCommandHistory');
1920
const {
2021
PREFIX,
@@ -235,6 +236,9 @@ const formatForAllowedSpeakerResponse = (s, raw = false) =>
235236

236237
let clientOnSigint = () => {};
237238
client.once('ready', async () => {
239+
const commandAliases = await loadAliases();
240+
console.log(`Loaded ${Object.keys(commandAliases).length} user command aliases`);
241+
238242
console.log('Ready!');
239243

240244
client.user.setStatus('idle');
@@ -364,7 +368,7 @@ client.once('ready', async () => {
364368

365369
sendToBotChan({
366370
embeds: [
367-
new MessageEmbed().setDescription('\n```\n' + (await banner('Hello!')) + '\n```\n\n')
371+
new MessageEmbed().setDescription('\n```\n' + (await banner('Hi!')) + '\n```\n\n')
368372
]
369373
}, true);
370374

@@ -392,10 +396,17 @@ client.once('ready', async () => {
392396
return pipedHandler();
393397
}
394398

395-
let { command, args } = parsers.parseCommandAndArgs(trimContent, { autoPrefixCurrentCommandChar });
396-
console.log(trimContent, '-> user command parsed ->', { command, args });
397-
args = parsers.parseArgsForQuotes(args);
398-
console.debug('args parsed for quotes', args);
399+
const aliasedTCList = trimContent.slice(autoPrefixCurrentCommandChar ? 0 : 1).split(/\s+/);
400+
const aliased = tryResolvingAlias(aliasedTCList[0]);
401+
console.warn('USE', aliased ? [aliased, ...aliasedTCList.slice(1)].join(' ') : trimContent);
402+
let { command, args } = parsers.parseCommandAndArgs(
403+
aliased ? [aliased, ...aliasedTCList.slice(1)].join(' ') : trimContent,
404+
{
405+
// must auto-prefix if aliased
406+
autoPrefixCurrentCommandChar: !!(aliased ?? autoPrefixCurrentCommandChar)
407+
}
408+
);
409+
console.log(trimContent, '-> user command parsed ->', { command, args, aliased });
399410

400411
const fmtedCmdStr = '`' + `${command} ${args.join(' ')}` + '`';
401412
const redis = new Redis(config.redis.url);
@@ -406,6 +417,9 @@ client.once('ready', async () => {
406417
const cmdFunc = userCommands(command);
407418
resolvedName = cmdFunc?.__resolvedFullCommandName ?? command;
408419

420+
args = parsers.parseArgsForQuotes(args);
421+
console.debug('args parsed for quotes', args);
422+
409423
// this should be removed ASAP in favor of scopedRedisClient,
410424
// but need to find all uses of it first...
411425
const publish = async (publishObj) => redis.publish(PREFIX, JSON.stringify(publishObj));
@@ -449,7 +463,7 @@ client.once('ready', async () => {
449463
}
450464

451465
if (!cmdFunc) {
452-
localSender(`\`${command}\` is not a valid DRC user command. Run \`!help\` to see all available commands.`);
466+
localSender(`\`${command}\` is not a valid DRC user command. Run \`${config.app.allowedSpeakersCommandPrefixCharacter}help\` to see all available commands.`);
453467
throw new UserCommandNotFound();
454468
}
455469

@@ -481,7 +495,9 @@ client.once('ready', async () => {
481495
}
482496

483497
const result = await cmdFunc(context, ...args);
484-
console.log(`Executed user command "${command}" (${resolvedName}) with result -->\n`, result);
498+
console.log(`Executed user command "${command}" (${resolvedName}) ` +
499+
(aliased ? `from alias "${aliasedTCList[0]}"` : '') +
500+
' with result -->\n', result);
485501

486502
let toBotChan;
487503
if (result && result.__drcFormatter) {

discord/common.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const { MessageMentions: { CHANNELS_PATTERN } } = require('discord.js');
1010
const senderNickFromMessage = require('./lib/senderNickFromMessage');
1111
const { serveMessages } = require('./lib/serveMessages');
1212
const { isHTTPRunning } = require('../lib/isXRunning');
13+
const { attachSentimentToMessages, averageSentiments, transformAveragesForDigestHTTP, roundSentimentScoreOnMessages } = require('../lib/sentiments');
1314

1415
function createArgObjOnContext (context, data, subaction, noNetworkFirstArg = false) {
1516
const tmplArr = [senderNickFromMessage(data?.message)];
@@ -37,7 +38,15 @@ async function clearSquelched (context, ...a) {
3738
async function digest (context, ...a) {
3839
const data = (await context.redis.lrange([context.key, 'squelch'].join(':'), 0, -1)).map(JSON.parse).reverse();
3940

40-
await serveMessages(context, data, { ttl: 1440 });
41+
const sentiments = await attachSentimentToMessages(null, data.map(({ data }) => data), null, context.options);
42+
const sentimentsAvg = averageSentiments(sentiments);
43+
roundSentimentScoreOnMessages(data.map(({ data }) => data));
44+
await serveMessages(context, data, {
45+
ttl: 1440,
46+
extra: {
47+
sentiments: transformAveragesForDigestHTTP(sentimentsAvg)
48+
}
49+
});
4150

4251
if (!context.options.keep) {
4352
clearSquelched(context);

discord/events/messageReactionAdd.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,15 @@ async function isUserHere (context, data) {
3131
return userCommands('isUserHere')(context, ...createArgObjOnContext(context, data, null, true));
3232
}
3333

34+
async function gptQuestion (context, data) {
35+
console.log('CREATED', createArgObjOnContext(context, data, 'gpt'));
36+
console.log('CONTENT?', data?.message?.content);
37+
// return userCommands('gpt')(context, ...createArgObjOnContext(context, data, 'gpt'));
38+
}
39+
3440
const allowedReactions = {
41+
'%F0%9F%87%AC': gptQuestion, // "🇬"
42+
3543
'%F0%9F%87%BC': whois, // "🇼"
3644
'%E2%9D%94': whois, // "❔"
3745
'%E2%9D%93': whois, // "❓"

discord/lib/listMgmtUCGenerators.js

Lines changed: 79 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,52 @@ const {
77
simpleEscapeForDiscord
88
} = require('./strings');
99

10+
function attachHelp (cmdFunc, commandName, additionalCommands, { overrideHelpFields = {} } = {}) {
11+
const addlCommandsHelp = Object.entries(additionalCommands ?? {})
12+
.filter(([k]) => k.indexOf('_') !== 0)
13+
.reduce((a, [k, v]) => ({
14+
[k]: {
15+
text: k
16+
},
17+
...a
18+
}), {});
19+
20+
const defaultHelp = {
21+
title: `Add or remove strings to the \`${commandName}\` list.`,
22+
usage: 'network subcommand [string]',
23+
subcommands: {
24+
add: {
25+
header: 'Notes',
26+
text: `Adds \`string\` to the \`${commandName}\` list.`
27+
},
28+
remove: {
29+
header: 'Notes',
30+
text: `Removes \`string\` from the \`${commandName}\` list.`
31+
},
32+
clear: {
33+
header: 'Notes',
34+
text: `Removes all strings from the \`${commandName}\` list.`
35+
},
36+
...addlCommandsHelp
37+
}
38+
};
39+
40+
cmdFunc.__drcHelp = () => {
41+
return {
42+
...defaultHelp,
43+
...overrideHelpFields
44+
};
45+
};
46+
}
47+
1048
// keySubstitue only applies (if set) to additionalCommands!
11-
function generateListManagementUCExport (commandName, additionalCommands, disallowClear = false, keySubstitute = null) {
49+
function generateListManagementUCExport (commandName,
50+
additionalCommands,
51+
disallowClear = false,
52+
keySubstitute = null,
53+
callOnChange = null,
54+
overrideHelpFields = {}
55+
) {
1256
const f = async function (context, ...a) {
1357
const [netStub, cmd] = a;
1458

@@ -35,10 +79,21 @@ function generateListManagementUCExport (commandName, additionalCommands, disall
3579
return convertDiscordChannelsToIRCInString(a.slice(2).join(' '), context);
3680
};
3781

82+
const addRmArgs = async () => [key, await argStr()];
83+
84+
let onChangeWrapper = async (a) => a;
85+
if (callOnChange) {
86+
onChangeWrapper = async (changed) => {
87+
if (changed) {
88+
await callOnChange(context, ...await addRmArgs());
89+
}
90+
};
91+
}
92+
3893
return scopedRedisClient(async (redis) => {
3994
switch (cmd) {
4095
case 'add':
41-
await redis.sadd(key, await argStr());
96+
await onChangeWrapper(await redis.sadd(...await addRmArgs()));
4297
break;
4398
case 'clear':
4499
// this really should be a button for confirmation instead of hardcoded!
@@ -47,7 +102,7 @@ function generateListManagementUCExport (commandName, additionalCommands, disall
47102
}
48103
break;
49104
case 'remove':
50-
await redis.srem(key, await argStr());
105+
await onChangeWrapper(await redis.srem(...await addRmArgs()));
51106
break;
52107
}
53108

@@ -68,42 +123,22 @@ function generateListManagementUCExport (commandName, additionalCommands, disall
68123
});
69124
};
70125

71-
const addlCommandsHelp = Object.entries(additionalCommands ?? {})
72-
.filter(([k]) => k.indexOf('_') !== 0)
73-
.reduce((a, [k, v]) => ({
74-
[k]: {
75-
text: k
76-
},
77-
...a
78-
}), {});
79-
80-
f.__drcHelp = () => {
81-
return {
82-
title: `Add or remove strings to the \`${commandName}\` list.`,
83-
usage: 'network subcommand [string]',
84-
subcommands: {
85-
add: {
86-
header: 'Notes',
87-
text: `Adds \`string\` to the \`${commandName}\` list.`
88-
},
89-
remove: {
90-
header: 'Notes',
91-
text: `Removes \`string\` from the \`${commandName}\` list.`
92-
},
93-
clear: {
94-
header: 'Notes',
95-
text: `Removes all strings from the \`${commandName}\` list.`
96-
},
97-
...addlCommandsHelp
98-
}
99-
};
100-
};
101-
126+
attachHelp(f, commandName, additionalCommands, { overrideHelpFields });
102127
return f;
103128
}
104129

105-
function generatePerChanListManagementUCExport (commandName, additionalCommands, enforceChannelSpec = true) {
106-
return function (context, ...a) {
130+
function generateListManagementUCExportOpts (commandName, {
131+
additionalCommands,
132+
disallowClear = false,
133+
keySubstitute = null,
134+
callOnChange = null,
135+
overrideHelpFields = {}
136+
} = {}) {
137+
return generateListManagementUCExport(commandName, additionalCommands, disallowClear, keySubstitute, callOnChange, overrideHelpFields);
138+
}
139+
140+
function generatePerChanListManagementUCExport (commandName, additionalCommands, enforceChannelSpec = true, options = {}) {
141+
const cmdFunc = function (context, ...a) {
107142
const [netStub, channelIdSpec] = context.options._;
108143
const { network } = matchNetwork(netStub);
109144
let channel = channelIdSpec;
@@ -122,17 +157,24 @@ function generatePerChanListManagementUCExport (commandName, additionalCommands,
122157
return addlCmd({ key, network, ...context }, ...a);
123158
}
124159

125-
const cmdFunctor = generateListManagementUCExport(`${commandName}_${key}`, additionalCommands);
160+
const cmdFunctor = generateListManagementUCExportOpts(`${commandName}_${key}`, {
161+
...options,
162+
additionalCommands
163+
});
126164

127165
context.options._[1] = context.options._[0];
128166
a[1] = a[0];
129167
context.options._.shift();
130168
a.shift();
131169
return cmdFunctor(context, ...a);
132170
};
171+
172+
attachHelp(cmdFunc, commandName, additionalCommands, options);
173+
return cmdFunc;
133174
}
134175

135176
module.exports = {
136177
generateListManagementUCExport,
178+
generateListManagementUCExportOpts,
137179
generatePerChanListManagementUCExport
138180
};

discord/lib/serveMessages.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,18 +58,14 @@ async function serveMessages (context, data, opts = {}) {
5858

5959
const name = nanoid();
6060

61-
if (!data.length) {
62-
context.sendToBotChan(`No messages for \`${context.network}\` were found.`);
63-
return;
64-
}
65-
6661
context.registerOneTimeHandler('http:get-req:' + name, name, async () => {
6762
await scopedRedisClient(async (r) => {
6863
await r.publish(PREFIX, JSON.stringify({
6964
type: 'http:get-res:' + name,
7065
data: {
7166
network: context.network,
72-
elements: data
67+
elements: data,
68+
extra: opts.extra ?? {}
7369
}
7470
}));
7571
});

0 commit comments

Comments
 (0)