Skip to content

Commit

Permalink
chatgpt: max-tokens increases & other improvements (#81)
Browse files Browse the repository at this point in the history
feat: increasses max tokes to 300 from 150, adds a 10% change of sarcastic answer ;)
  • Loading branch information
en3sis authored Dec 12, 2023
1 parent 17b4042 commit 5e5c7ff
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 61 deletions.
34 changes: 20 additions & 14 deletions src/commands/ask.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { SlashCommandBuilder } from '@discordjs/builders'
import { CommandInteraction } from 'discord.js'
import { resolveGuildPlugins } from '../controllers/bot/plugins.controller'
import { chatGptCommandHandler, chatGptUsage } from '../controllers/plugins/chat-gpt3.controller'
import { chatGptCommandHandler, chatGptUsage } from '../controllers/plugins/chat-gpt.controller'
import { GuildPluginChatGTPMetadata } from '../types/plugins'
import { getTimeRemainingUntilMidnight } from '../utils/dates'
import { logger } from '../utils/debugging'

Expand All @@ -21,36 +22,41 @@ module.exports = {
try {
const {
enabled,
metadata: guildPlugin,
data: guild,
} = await resolveGuildPlugins(interaction.guildId!, 'chatGtp')
metadata: guildPluginData,
data: guildData,
} = (await resolveGuildPlugins(interaction.guildId!, 'chatGtp')) as GuildPluginChatGTPMetadata

if (!enabled)
return await interaction.editReply('This plugin is not enabled for this server.')

// Handles regular guilds
if (!guild.premium) {
if (!guildData.premium) {
// If the guild set its API Key, uses it
if (guildPlugin?.api_key && guildPlugin?.org) {
return await chatGptCommandHandler(interaction, guild, guildPlugin)
if (guildPluginData?.api_key && guildPluginData?.org) {
return await chatGptCommandHandler(interaction, guildData, guildPluginData)
}

if (guildPlugin === null || guildPlugin?.usage === undefined) {
await chatGptCommandHandler(interaction, guild, guildPlugin, 99)
return await chatGptUsage(guildPlugin, interaction.guildId!)
if (guildPluginData === null || guildPluginData?.usage === undefined) {
await chatGptCommandHandler(interaction, guildData, guildPluginData, 99)
return await chatGptUsage(guildPluginData, interaction.guildId!)
}

if (guildPlugin?.usage !== 0) {
await chatGptCommandHandler(interaction, guild, guildPlugin, guildPlugin?.usage)
return await chatGptUsage(guildPlugin, interaction.guildId!)
if (guildPluginData?.usage !== 0) {
await chatGptCommandHandler(
interaction,
guildData,
guildPluginData,
guildPluginData?.usage,
)
return await chatGptUsage(guildPluginData, interaction.guildId!)
} else {
return await interaction.editReply(
`You have reached the daily limit of using the command. It will restart ⏳ ${getTimeRemainingUntilMidnight()}. An personal API key can be securely added using \`/plugins chatGtp\` command for unlimited usage in this server.`,
)
}
} else {
// Handles premium guilds
await chatGptCommandHandler(interaction, guild, guildPlugin)
await chatGptCommandHandler(interaction, guildData, guildPluginData)
}
} catch (error) {
logger('❌ Command: ask: ', error)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
import { CommandInteraction } from 'discord.js'
import { Configuration, OpenAIApi } from 'openai'
import supabase from '../../libs/supabase'
import { GenericObjectT } from '../../types/objects'
import { GuildPluginChatGTPMetadata } from '../../types/plugins'
import { DEFAULT_COLOR } from '../../utils/colors'
import { CHATGPT_COMMANDS_USAGE_DAILY } from '../../utils/constants'
import { decrypt } from '../../utils/crypto'
import { ROLE_MENTION_REGEX } from '../../utils/regex'
import { GuildPlugin } from '../bot/guilds.controller'

export const gpt3Controller = async (prompt: string, apiKey: string, organization: string) => {
interface IOpenAIRequestSettings {
model?: string
input: string
max_tokens?: number
temperature?: number
presence_penalty?: number
frequency_penalty?: number
apiKey: string
organization: string
}

type PluginMetadata = GuildPluginChatGTPMetadata['metadata']

export const chatGTPController = async (prompt: string, apiKey: string, organization: string) => {
try {
const { response, token } = await sendPrompt({
input: `${prompt}`,
version: '003',
max_tokens: 150,
input: prompt,
apiKey,
organization,
})
Expand All @@ -23,32 +34,21 @@ export const gpt3Controller = async (prompt: string, apiKey: string, organizatio
token,
}
} catch (error) {
console.log('❌ gpt3Controller(): ', error)
console.log('❌ chatGTPController(): ', error)
throw Error(error.message)
}
}

interface IOpenAIRequestSettings {
model?: 'ada' | 'davinci'
version?: '003' | '001'
input: string
max_tokens?: number
temperature?: number
presence_penalty?: number
frequency_penalty?: number
apiKey: string
organization: string
}

/**
* OpenAI API request
* @param IOpenAIRequestSettings
* @returns Promise<string>
*/
export const sendPrompt = async ({
input,
max_tokens = 500,
temperature = 0.3,
model = 'gpt-3.5-turbo',
max_tokens = 300,
temperature = 0.7,
presence_penalty = 0.5,
frequency_penalty = 0.5,
apiKey,
Expand All @@ -62,8 +62,11 @@ export const sendPrompt = async ({
}),
)

// INFO: 10% chance of being sarcastic, spice things up a bit.
const sarcasm = Math.random() < 0.1 ? 'My answer is extremely sarcastic and clever' : ''

const completion = await OPEN_AI_CLIENT.createChatCompletion({
model: 'gpt-3.5-turbo',
model,
n: 1,
temperature: temperature,
max_tokens: max_tokens,
Expand All @@ -73,9 +76,12 @@ export const sendPrompt = async ({
messages: [
{
role: 'system',
content: `You are ChatGPT, a large language model trained by OpenAI. Answer as concisely as possible, sometimes you can be sarcastic. Current date: ${new Date().toLocaleDateString()}`,
content: `I'm Hans, your all-knowing assistant. ${sarcasm}. Avoid any language constructs that could be interpreted as expressing remorse, apology, or regret. Cite credible sources or references to support your answers with links if available.Current date: ${new Date().toLocaleDateString()}`,
},
{
role: 'user',
content: input,
},
{ role: 'user', content: input },
],
})

Expand All @@ -93,7 +99,7 @@ export const sendPrompt = async ({
export const chatGptCommandHandler = async (
interaction: CommandInteraction,
guild: GuildPlugin & { premium: boolean },
guildPlugin: GenericObjectT | any,
guildPlugin: PluginMetadata,
usage?: number,
) => {
try {
Expand All @@ -104,7 +110,7 @@ export const chatGptCommandHandler = async (
guild.premium || usage > 0 ? process.env.OPENAI_ORGANIZATION_ID : decrypt(guildPlugin.org)

const prompt = interaction.options.get('prompt')!.value as string
const answer = await gpt3Controller(prompt, API_KEY, ORGANIZATION)
const answer = await chatGTPController(prompt, API_KEY, ORGANIZATION)

if (!answer?.response || answer?.response === '' || answer?.response === undefined)
return await interaction.editReply('💢 Something went wrong, please try again later.')
Expand Down Expand Up @@ -141,9 +147,9 @@ export const chatGptCommandHandler = async (
}

export const chatGptUsage = async (
guildPlugin: any,
guildPlugin: PluginMetadata,
guild_id: string,
): Promise<GuildPlugin | any> => {
): Promise<GuildPlugin> => {
try {
const { data: currentSettings } = await supabase
.from('guilds_plugins')
Expand All @@ -154,25 +160,17 @@ export const chatGptUsage = async (

const _metadata = JSON.parse(JSON.stringify(currentSettings?.metadata)) || {}

if (guildPlugin === null) {
const { data } = await supabase
.from('guilds_plugins')
.update({ metadata: { ..._metadata, usage: CHATGPT_COMMANDS_USAGE_DAILY - 1 } })
.eq('owner', guild_id)
.eq('name', 'chatGtp')
.select()

return data
} else {
const { data } = await supabase
.from('guilds_plugins')
.update({ metadata: { ..._metadata, usage: guildPlugin.usage - 1 } })
.eq('owner', guild_id)
.eq('name', 'chatGtp')
.select()

return data
}
const usage = guildPlugin === null ? CHATGPT_COMMANDS_USAGE_DAILY - 1 : guildPlugin.usage - 1

const { data } = await supabase
.from('guilds_plugins')
.update({ metadata: { ..._metadata, usage } })
.eq('owner', guild_id)
.eq('name', 'chatGtp')
.select()
.single()

return data
} catch (error) {
console.error('❌ chatGptUsage(): ', error)
throw Error(error.message)
Expand Down
11 changes: 10 additions & 1 deletion src/types/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,17 @@ export type PluginsThreadsSettings = {
metadata: PluginsThreadsMetadata
}

export type GuildPluginData = {
export interface GuildPluginData {
enabled: boolean
metadata: any
data: GuildPlugin | any
}

// Define metadata of Plugins
export interface GuildPluginChatGTPMetadata extends GuildPluginData {
metadata: {
api_key: string
org: string
usage: number
}
}

0 comments on commit 5e5c7ff

Please sign in to comment.