[Snyk] Upgrade discord.js from 14.16.3 to 14.17.3 (#155)

This commit is contained in:
Jonathan Smoley
2025-01-31 16:23:31 -08:00
committed by GitHub
parent 2a39e20fee
commit 5b542aca1a
23 changed files with 324 additions and 316 deletions

View File

@@ -22,7 +22,9 @@ export const Capacity: SlashCommand = {
if (!channel || !UserCommand.includes(channel.type)) return
// set state of bot chat features
openConfig(`${interaction.user.username}-config.json`, interaction.commandName, interaction.options.get('context-capacity')?.value)
openConfig(`${interaction.user.username}-config.json`, interaction.commandName,
interaction.options.get('context-capacity')?.value
)
interaction.reply({
content: `Max message history is now set to \`${interaction.options.get('context-capacity')?.value}\``,

View File

@@ -14,19 +14,21 @@ export const ClearUserChannelHistory: SlashCommand = {
if (!channel || !UserCommand.includes(channel.type)) return
// clear channel info for user
const successfulWipe = await clearChannelInfo(interaction.channelId,
interaction.channel as TextChannel,
interaction.user.username)
const successfulWipe = await clearChannelInfo(
interaction.channelId,
interaction.channel as TextChannel,
interaction.user.username
)
// check result of clearing history
if (successfulWipe)
interaction.reply({
content: `History cleared in **this channel** cleared for **${interaction.user.username}**.`,
interaction.reply({
content: `History cleared in **this channel** cleared for **${interaction.user.username}**.`,
ephemeral: true
})
else
interaction.reply({
content: `History was not be found for **${interaction.user.username}** in **this channel**.\n\nPlease chat with **${client.user?.username}** to start a chat history.`,
interaction.reply({
content: `History was not be found for **${interaction.user.username}** in **this channel**.\n\nPlease chat with **${client.user?.username}** to start a chat history.`,
ephemeral: true
})
}

View File

@@ -6,7 +6,7 @@ import { ModelResponse } from 'ollama'
export const DeleteModel: SlashCommand = {
name: 'delete-model',
description: 'deletes a model from the local list of models. Administrator Only.',
// set available user options to pass to the command
options: [
{

View File

@@ -31,10 +31,12 @@ export const Disable: SlashCommand = {
}
// set state of bot chat features
openConfig(`${interaction.guildId}-config.json`, interaction.commandName, interaction.options.get('enabled')?.value)
openConfig(`${interaction.guildId}-config.json`, interaction.commandName,
interaction.options.get('enabled')?.value
)
interaction.reply({
content: `${client.user?.username} is now **${interaction.options.get('enabled')?.value ? "enabled" : "disabled" }**.`,
content: `${client.user?.username} is now **${interaction.options.get('enabled')?.value ? "enabled" : "disabled"}**.`,
ephemeral: true
})
}

View File

@@ -22,7 +22,9 @@ export const MessageStream: SlashCommand = {
if (!channel || !UserCommand.includes(channel.type)) return
// save value to json and write to it
openConfig(`${interaction.user.username}-config.json`, interaction.commandName, interaction.options.get('stream')?.value)
openConfig(`${interaction.user.username}-config.json`, interaction.commandName,
interaction.options.get('stream')?.value
)
interaction.reply({
content: `Message streaming is now set to: \`${interaction.options.get('stream')?.value}\``,

View File

@@ -28,6 +28,7 @@ export const Shutoff: SlashCommand = {
content: `${client.user?.tag} is shutting down.`,
ephemeral: true
})
console.log(`[Command: shutoff] ${client.user?.tag} is shutting down.`)
// clean up client instance and stop

View File

@@ -31,20 +31,20 @@ export const SwitchModel: SlashCommand = {
// Phase 1: Switch to the model
let switchSuccess = false
await ollama.list()
.then(response => {
for (const model in response.models) {
const currentModel: ModelResponse = response.models[model]
if (currentModel.name.startsWith(modelInput)) {
openConfig(`${interaction.user.username}-config.json`, interaction.commandName, modelInput)
.then(response => {
for (const model in response.models) {
const currentModel: ModelResponse = response.models[model]
if (currentModel.name.startsWith(modelInput)) {
openConfig(`${interaction.user.username}-config.json`, interaction.commandName, modelInput)
// successful switch
interaction.editReply({
content: `Successfully switched to **${modelInput}** as the preferred model for ${interaction.user.username}.`
})
switchSuccess = true
// successful switch
interaction.editReply({
content: `Successfully switched to **${modelInput}** as the preferred model for ${interaction.user.username}.`
})
switchSuccess = true
}
}
}
})
})
// todo: problem can be here if async messes up
if (switchSuccess) {
// set model now that it exists
@@ -55,7 +55,7 @@ export const SwitchModel: SlashCommand = {
// Phase 2: Notify user of failure to find model.
interaction.editReply({
content: `Could not find **${modelInput}** in local model library.\n\nPlease contact an server admin for access to this model.`
})
})
} catch (error) {
// could not resolve user model switch
interaction.editReply({

View File

@@ -21,9 +21,7 @@ export const ThreadCreate: SlashCommand = {
thread.send(`Hello ${interaction.user} and others! \n\nIt's nice to meet you. Please talk to me by typing **@${client.user?.username}** with your message.`)
// handle storing this chat channel
openChannelInfo(thread.id,
thread as ThreadChannel,
interaction.user.tag)
openChannelInfo(thread.id, thread as ThreadChannel, interaction.user.tag)
// user only reply
return interaction.reply({

View File

@@ -22,10 +22,7 @@ export const PrivateThreadCreate: SlashCommand = {
// handle storing this chat channel
// store: thread.id, thread.name
openChannelInfo(thread.id,
thread as ThreadChannel,
interaction.user.tag
)
openChannelInfo(thread.id, thread as ThreadChannel, interaction.user.tag)
// user only reply
return interaction.reply({

View File

@@ -6,14 +6,15 @@ import commands from '../commands/index.js'
* @param interaction the interaction received from the server
*/
export default event(Events.InteractionCreate, async ({ log, client }, interaction) => {
if (!interaction.isCommand() || !interaction.isChatInputCommand()) return
log(`Interaction called \'${interaction.commandName}\' from ${interaction.user.tag}.`)
if (!interaction.isCommand() || !interaction.isChatInputCommand()) return
// ensure command exists, otherwise kill event
const command = commands.find(command => command.name === interaction.commandName)
if (!command) return
log(`Interaction called \'${interaction.commandName}\' from ${interaction.user.tag}.`)
// the command exists, execute it
command.run(client, interaction)
})
// ensure command exists, otherwise kill event
const command = commands.find(command => command.name === interaction.commandName)
if (!command) return
// the command exists, execute it
command.run(client, interaction)
}
)

View File

@@ -1,6 +1,9 @@
import { TextChannel } from 'discord.js'
import { event, Events, normalMessage, UserMessage, clean, getTextFileAttachmentData } from '../utils/index.js'
import { getChannelInfo, getServerConfig, getUserConfig, openChannelInfo, openConfig, UserConfig, getAttachmentData } from '../utils/index.js'
import { event, Events, normalMessage, UserMessage, clean } from '../utils/index.js'
import {
getChannelInfo, getServerConfig, getUserConfig, openChannelInfo,
openConfig, UserConfig, getAttachmentData, getTextFileAttachmentData
} from '../utils/index.js'
/**
* Max Message length for free users is 2000 characters (bot or not).
@@ -13,129 +16,129 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client
let cleanedMessage = clean(message.content, clientId)
log(`Message \"${cleanedMessage}\" from ${message.author.tag} in channel/thread ${message.channelId}.`)
// Do not respond if bot talks in the chat
if (message.author.username === message.client.user.username) return
// Do not respond if bot talks in the chat
if (message.author.username === message.client.user.username) return
// Only respond if message mentions the bot
if (!message.mentions.has(clientId)) return
// Only respond if message mentions the bot
if (!message.mentions.has(clientId)) return
// default stream to false
let shouldStream = false
// default stream to false
let shouldStream = false
// Params for Preferences Fetching
const maxRetries = 3
const delay = 1000 // in millisecons
try {
// Retrieve Server/Guild Preferences
let attempt = 0
while (attempt < maxRetries) {
try {
await new Promise((resolve, reject) => {
getServerConfig(`${message.guildId}-config.json`, (config) => {
// check if config.json exists
if (config === undefined) {
// Allowing chat options to be available
openConfig(`${message.guildId}-config.json`, 'toggle-chat', true)
reject(new Error('Failed to locate or create Server Preferences\n\nPlease try chatting again...'))
}
// check if chat is disabled
else if (!config.options['toggle-chat'])
reject(new Error('Admin(s) have disabled chat features.\n\n Please contact your server\'s admin(s).'))
else
resolve(config)
// Params for Preferences Fetching
const maxRetries = 3
const delay = 1000 // in millisecons
try {
// Retrieve Server/Guild Preferences
let attempt = 0
while (attempt < maxRetries) {
try {
await new Promise((resolve, reject) => {
getServerConfig(`${message.guildId}-config.json`, (config) => {
// check if config.json exists
if (config === undefined) {
// Allowing chat options to be available
openConfig(`${message.guildId}-config.json`, 'toggle-chat', true)
reject(new Error('Failed to locate or create Server Preferences\n\nPlease try chatting again...'))
}
// check if chat is disabled
else if (!config.options['toggle-chat'])
reject(new Error('Admin(s) have disabled chat features.\n\n Please contact your server\'s admin(s).'))
else
resolve(config)
})
})
})
break // successful
} catch (error) {
++attempt
if (attempt < maxRetries) {
log(`Attempt ${attempt} failed for Server Preferences. Retrying in ${delay}ms...`)
await new Promise(ret => setTimeout(ret, delay))
} else
throw new Error(`Could not retrieve Server Preferences, please try chatting again...`)
}
}
// Reset attempts for User preferences
attempt = 0
let userConfig: UserConfig | undefined
while (attempt < maxRetries) {
try {
// Retrieve User Preferences
userConfig = await new Promise((resolve, reject) => {
getUserConfig(`${message.author.username}-config.json`, (config) => {
if (config === undefined) {
openConfig(`${message.author.username}-config.json`, 'message-style', false)
openConfig(`${message.author.username}-config.json`, 'switch-model', defaultModel)
reject(new Error('No User Preferences is set up.\n\nCreating preferences file with \`message-style\` set as \`false\` for regular message style.\nPlease try chatting again.'))
return
}
// check if there is a set capacity in config
else if (typeof config.options['modify-capacity'] !== 'number')
log(`Capacity is undefined, using default capacity of ${msgHist.capacity}.`)
else if (config.options['modify-capacity'] === msgHist.capacity)
log(`Capacity matches config as ${msgHist.capacity}, no changes made.`)
else {
log(`New Capacity found. Setting Context Capacity to ${config.options['modify-capacity']}.`)
msgHist.capacity = config.options['modify-capacity']
}
// set stream state
shouldStream = config.options['message-stream'] as boolean || false
if (typeof config.options['switch-model'] !== 'string')
reject(new Error(`No Model was set. Please set a model by running \`/switch-model <model of choice>\`.\n\nIf you do not have any models. Run \`/pull-model <model name>\`.`))
resolve(config)
})
})
break // successful
} catch (error) {
++attempt
if (attempt < maxRetries) {
log(`Attempt ${attempt} failed for User Preferences. Retrying in ${delay}ms...`)
await new Promise(ret => setTimeout(ret, delay))
} else
throw new Error(`Could not retrieve User Preferences, please try chatting again...`)
}
}
// need new check for "open/active" threads/channels here!
let chatMessages: UserMessage[] = await new Promise((resolve) => {
// set new queue to modify
getChannelInfo(`${message.channelId}-${message.author.username}.json`, (channelInfo) => {
if (channelInfo?.messages)
resolve(channelInfo.messages)
else {
log(`Channel/Thread ${message.channel}-${message.author.username} does not exist. File will be created shortly...`)
resolve([])
break // successful
} catch (error) {
++attempt
if (attempt < maxRetries) {
log(`Attempt ${attempt} failed for Server Preferences. Retrying in ${delay}ms...`)
await new Promise(ret => setTimeout(ret, delay))
} else
throw new Error(`Could not retrieve Server Preferences, please try chatting again...`)
}
})
})
}
if (chatMessages.length === 0) {
chatMessages = await new Promise((resolve, reject) => {
openChannelInfo(message.channelId,
message.channel as TextChannel,
message.author.tag
)
// Reset attempts for User preferences
attempt = 0
let userConfig: UserConfig | undefined
while (attempt < maxRetries) {
try {
// Retrieve User Preferences
userConfig = await new Promise((resolve, reject) => {
getUserConfig(`${message.author.username}-config.json`, (config) => {
if (config === undefined) {
openConfig(`${message.author.username}-config.json`, 'message-style', false)
openConfig(`${message.author.username}-config.json`, 'switch-model', defaultModel)
reject(new Error('No User Preferences is set up.\n\nCreating preferences file with \`message-style\` set as \`false\` for regular message style.\nPlease try chatting again.'))
return
}
// check if there is a set capacity in config
else if (typeof config.options['modify-capacity'] !== 'number')
log(`Capacity is undefined, using default capacity of ${msgHist.capacity}.`)
else if (config.options['modify-capacity'] === msgHist.capacity)
log(`Capacity matches config as ${msgHist.capacity}, no changes made.`)
else {
log(`New Capacity found. Setting Context Capacity to ${config.options['modify-capacity']}.`)
msgHist.capacity = config.options['modify-capacity']
}
// set stream state
shouldStream = config.options['message-stream'] as boolean || false
if (typeof config.options['switch-model'] !== 'string')
reject(new Error(`No Model was set. Please set a model by running \`/switch-model <model of choice>\`.\n\nIf you do not have any models. Run \`/pull-model <model name>\`.`))
resolve(config)
})
})
break // successful
} catch (error) {
++attempt
if (attempt < maxRetries) {
log(`Attempt ${attempt} failed for User Preferences. Retrying in ${delay}ms...`)
await new Promise(ret => setTimeout(ret, delay))
} else
throw new Error(`Could not retrieve User Preferences, please try chatting again...`)
}
}
// need new check for "open/active" threads/channels here!
let chatMessages: UserMessage[] = await new Promise((resolve) => {
// set new queue to modify
getChannelInfo(`${message.channelId}-${message.author.username}.json`, (channelInfo) => {
if (channelInfo?.messages)
resolve(channelInfo.messages)
else {
log(`Channel/Thread ${message.channel}-${message.author.username} does not exist. File will be created shortly...`)
reject(new Error(`Failed to find ${message.author.username}'s history. Try chatting again.`))
resolve([])
}
})
})
}
if (!userConfig)
throw new Error(`Failed to initialize User Preference for **${message.author.username}**.\n\nIt's likely you do not have a model set. Please use the \`switch-model\` command to do that.`)
if (chatMessages.length === 0) {
chatMessages = await new Promise((resolve, reject) => {
openChannelInfo(message.channelId,
message.channel as TextChannel,
message.author.tag
)
getChannelInfo(`${message.channelId}-${message.author.username}.json`, (channelInfo) => {
if (channelInfo?.messages)
resolve(channelInfo.messages)
else {
log(`Channel/Thread ${message.channel}-${message.author.username} does not exist. File will be created shortly...`)
reject(new Error(`Failed to find ${message.author.username}'s history. Try chatting again.`))
}
})
})
}
if (!userConfig)
throw new Error(`Failed to initialize User Preference for **${message.author.username}**.\n\nIt's likely you do not have a model set. Please use the \`switch-model\` command to do that.`)
// get message attachment if exists
const attachment = message.attachments.first()
@@ -148,43 +151,44 @@ export default event(Events.MessageCreate, async ({ log, msgHist, ollama, client
const model: string = userConfig.options['switch-model']
// set up new queue
msgHist.setQueue(chatMessages)
// set up new queue
msgHist.setQueue(chatMessages)
// check if we can push, if not, remove oldest
while (msgHist.size() >= msgHist.capacity) msgHist.dequeue()
// check if we can push, if not, remove oldest
while (msgHist.size() >= msgHist.capacity) msgHist.dequeue()
// push user response before ollama query
msgHist.enqueue({
role: 'user',
content: cleanedMessage,
images: messageAttachment || []
})
// response string for ollama to put its response
const response: string = await normalMessage(message, ollama, model, msgHist, shouldStream)
// push user response before ollama query
msgHist.enqueue({
role: 'user',
content: cleanedMessage,
images: messageAttachment || []
})
// If something bad happened, remove user query and stop
if (response == undefined) { msgHist.pop(); return }
// response string for ollama to put its response
const response: string = await normalMessage(message, ollama, model, msgHist, shouldStream)
// if queue is full, remove the oldest message
while (msgHist.size() >= msgHist.capacity) msgHist.dequeue()
// If something bad happened, remove user query and stop
if (response == undefined) { msgHist.pop(); return }
// successful query, save it in context history
msgHist.enqueue({
role: 'assistant',
content: response,
images: messageAttachment || []
})
// if queue is full, remove the oldest message
while (msgHist.size() >= msgHist.capacity) msgHist.dequeue()
// only update the json on success
openChannelInfo(message.channelId,
message.channel as TextChannel,
message.author.tag,
msgHist.getItems()
)
} catch (error: any) {
msgHist.pop() // remove message because of failure
message.reply(`**Error Occurred:**\n\n**Reason:** *${error.message}*`)
// successful query, save it in context history
msgHist.enqueue({
role: 'assistant',
content: response,
images: messageAttachment || []
})
// only update the json on success
openChannelInfo(message.channelId,
message.channel as TextChannel,
message.author.tag,
msgHist.getItems()
)
} catch (error: any) {
msgHist.pop() // remove message because of failure
message.reply(`**Error Occurred:**\n\n**Reason:** *${error.message}*`)
}
}
})
)

View File

@@ -4,14 +4,15 @@ import commands from '../commands/index.js'
// Log when the bot successfully logs in and export it
export default event(Events.ClientReady, ({ log }, client) => {
// Register the commands associated with the bot upon loggin in
registerCommands(client, commands)
// Register the commands associated with the bot upon loggin in
registerCommands(client, commands)
// set status of the bot
client.user.setActivity({
name: 'Powered by Ollama',
type: ActivityType.Custom
})
// set status of the bot
client.user.setActivity({
name: 'Powered by Ollama',
type: ActivityType.Custom
})
log(`Logged in as ${client.user.username}.`)
})
log(`Logged in as ${client.user.username}.`)
}
)

View File

@@ -6,35 +6,36 @@ import fs from 'fs'
* Event to remove the associated .json file for a thread once deleted
*/
export default event(Events.ThreadDelete, async ({ log }, thread: ThreadChannel) => {
// iterate through every guild member in the thread and delete their history, except the bot
try {
log(`Number of User Guild Members in Thread being deleted: ${thread.memberCount!! - 1}`)
const dirPath = 'data/'
// iterate through every guild member in the thread and delete their history, except the bot
try {
log(`Number of User Guild Members in Thread being deleted: ${thread.memberCount!! - 1}`)
const dirPath = 'data/'
// read all files in data/
fs.readdir(dirPath, (error, files) => {
if (error) {
log(`Error reading directory ${dirPath}`, error)
return
}
// read all files in data/
fs.readdir(dirPath, (error, files) => {
if (error) {
log(`Error reading directory ${dirPath}`, error)
return
}
// filter files by thread id being deleted
const filesToDiscard = files.filter(
file => file.startsWith(`${thread.id}-`) &&
// filter files by thread id being deleted
const filesToDiscard = files.filter(
file => file.startsWith(`${thread.id}-`) &&
file.endsWith('.json'))
// remove files by unlinking
filesToDiscard.forEach(file => {
const filePath = dirPath + file
fs.unlink(filePath, error => {
if (error)
log(`Error deleting file ${filePath}`, error)
else
log(`Successfully deleted ${filePath} thread information`)
// remove files by unlinking
filesToDiscard.forEach(file => {
const filePath = dirPath + file
fs.unlink(filePath, error => {
if (error)
log(`Error deleting file ${filePath}`, error)
else
log(`Successfully deleted ${filePath} thread information`)
})
})
})
})
} catch (error) {
log(`Issue deleting user history files from ${thread.id}`)
}
})
} catch (error) {
log(`Issue deleting user history files from ${thread.id}`)
}
}
)

View File

@@ -21,14 +21,13 @@ export function getEnvVar(name: string, fallback?: string): string {
throw new Error(`Environment variable ${name} is not set.`)
// validate User-Generated Discord Application Tokens
if (name === "CLIENT_TOKEN")
if (value.length < 72) throw new Error(`The "CLIENT_TOKEN" provided is not of at least length 72.
if (name === "CLIENT_TOKEN" && value.length > 72)
throw new Error(`The "CLIENT_TOKEN" provided is not of at least length 72.
This is probably an invalid token unless Discord updated their token policy. Please provide a valid token.`)
// validate IPv4 address found in environment variables
if (name.endsWith("_IP") || name.endsWith("_ADDRESS"))
if (!ipValidate.test(value))
throw new Error(`Environment variable ${name} does not follow IPv4 formatting.`)
if ((name.endsWith("_IP") || name.endsWith("_ADDRESS")) && !ipValidate.test(value))
throw new Error(`Environment variable ${name} does not follow IPv4 formatting.`)
// return env variable
return value

View File

@@ -15,8 +15,8 @@ export type EventKeys = keyof ClientEvents // only wants keys of ClientEvents ob
* @param msgHist message history
*/
export type ChatParams = {
model: string,
ollama: Ollama,
model: string,
ollama: Ollama,
msgHist: UserMessage[]
}
@@ -24,6 +24,7 @@ export type ChatParams = {
* Format for the messages to be stored when communicating when the bot
* @param role either assistant, user, or system
* @param content string of the message the user or assistant provided
* @param images array of images that the user or assistant provided
*/
export type UserMessage = {
role: string,
@@ -33,12 +34,18 @@ export type UserMessage = {
// Event properties
export interface EventProps {
client: Client
log: LogMethod
msgHist: Queue<UserMessage>
client: Client,
log: LogMethod,
msgHist: Queue<UserMessage>,
ollama: Ollama,
defaultModel: String
}
/**
* Format for the callback function tied to an event
* @param props the properties of the event
* @param args the arguments of the event
*/
export type EventCallback<T extends EventKeys> = (
props: EventProps,
...args: ClientEvents[T]
@@ -50,6 +57,12 @@ export interface Event<T extends EventKeys = EventKeys> {
callback: EventCallback<T>
}
/**
* Method to create an event object
* @param key type of event
* @param callback function to run when event is triggered
* @returns event object
*/
export function event<T extends EventKeys>(key: T, callback: EventCallback<T>): Event<T> {
return { key, callback }
}
@@ -62,8 +75,8 @@ export function event<T extends EventKeys>(key: T, callback: EventCallback<T>):
* @param ollama the initialized ollama instance
*/
export function registerEvents(
client: Client,
events: Event[],
client: Client,
events: Event[],
msgHist: Queue<UserMessage>,
ollama: Ollama,
defaultModel: String

View File

@@ -80,7 +80,14 @@ export async function openChannelInfo(filename: string, channel: TextChannel | T
}
})
} else { // file doesn't exist, create it
const object: Configuration = JSON.parse(`{ \"id\": \"${channel?.id}\", \"name\": \"${channel?.name}\", \"user\": \"${user}\", \"messages\": []}`)
const object: Configuration = JSON.parse(
`{
\"id\": \"${channel?.id}\",
\"name\": \"${channel?.name}\",
\"user\": \"${user}\",
\"messages\": []
}`
)
const directory = path.dirname(fullFileName)
if (!fs.existsSync(directory))
@@ -103,7 +110,7 @@ export async function getChannelInfo(filename: string, callback: (config: Channe
if (fs.existsSync(fullFileName)) {
fs.readFile(fullFileName, 'utf8', (error, data) => {
if (error) {
callback(undefined)
callback(undefined)
return // something went wrong... stop
}
callback(JSON.parse(data))

View File

@@ -12,7 +12,7 @@ import path from 'path'
// add type of change (server, user)
export function openConfig(filename: string, key: string, value: any) {
const fullFileName = `data/${filename}`
// check if the file exists, if not then make the config file
if (fs.existsSync(fullFileName)) {
fs.readFile(fullFileName, 'utf8', (error, data) => {
@@ -58,7 +58,7 @@ export async function getServerConfig(filename: string, callback: (config: Serve
if (fs.existsSync(fullFileName)) {
fs.readFile(fullFileName, 'utf8', (error, data) => {
if (error) {
callback(undefined)
callback(undefined)
return // something went wrong... stop
}
callback(JSON.parse(data))
@@ -81,7 +81,7 @@ export async function getUserConfig(filename: string, callback: (config: UserCon
if (fs.existsSync(fullFileName)) {
fs.readFile(fullFileName, 'utf8', (error, data) => {
if (error) {
callback(undefined)
callback(undefined)
return // something went wrong... stop
}
callback(JSON.parse(data))

View File

@@ -5,7 +5,7 @@ import { AbortableAsyncIterator } from "ollama/src/utils.js"
/**
* Method to query the Ollama client for async generation
* @param params
* @returns Asyn
* @returns AsyncIterator<ChatResponse> generated by the Ollama client
*/
export async function streamResponse(params: ChatParams): Promise<AbortableAsyncIterator<ChatResponse>> {
return await params.ollama.chat({

View File

@@ -28,7 +28,7 @@ export async function normalMessage(
model: model,
ollama: ollama,
msgHist: msgHist.getItems()
}
}
// run query based on stream preference, true = stream, false = block
if (stream) {
@@ -40,14 +40,15 @@ export async function normalMessage(
result = portion.message.content
// new message block, wait for it to send and assign new block to respond.
await channel.send("Creating new stream block...").then(sentMessage => { messageBlock = sentMessage })
await channel.send("Creating new stream block...")
.then(sentMessage => { messageBlock = sentMessage })
} else {
result += portion.message.content
// ensure block is not empty
if (result.length > 5)
messageBlock.edit(result)
}
messageBlock.edit(result)
}
console.log(result)
}
}
@@ -70,8 +71,8 @@ export async function normalMessage(
channel.send(result)
} else // edit the 'generic' response to new message since <2000
sentMessage.edit(result)
}
} catch(error: any) {
}
} catch (error: any) {
console.log(`[Util: messageNormal] Error creating message: ${error.message}`)
if (error.message.includes('try pulling it first'))
sentMessage.edit(`**Response generation failed.**\n\nReason: You do not have the ${model} downloaded. Ask an admin to pull it using the \`pull-model\` command.`)