feat: Add Option to Disable Titling, Config Titling Model, and Title Prompt Improvements (#977)

* feat: add option to disable titling as well as decide what model to use for OpenAI titling
refactor: truncate conversation text so it caps around 200 tokens for titling requests, optimize some of the title prompts

* feat: disable bing titling with TITLE_CONVO as well
This commit is contained in:
Danny Avila 2023-09-20 18:45:56 -04:00 committed by GitHub
parent d13a7b1a74
commit 1d3e336e1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 43 additions and 6 deletions

View file

@ -73,6 +73,16 @@ OPENAI_API_KEY=user_provided
# Leave it blank to use internal settings.
# OPENAI_MODELS=gpt-3.5-turbo,gpt-3.5-turbo-16k,gpt-3.5-turbo-0301,text-davinci-003,gpt-4,gpt-4-0314,gpt-4-0613
# Titling is enabled by default when initiating a conversation.
# Uncomment the following variable to disable this feature.
# TITLE_CONVO=false
# The model used for titling by default is gpt-3.5-turbo-0613 to assure it works with the default method.
# gpt-3.5-turbo should also work when using the official API (and not a reverse proxy).
# You can change the model used by uncommenting the following and setting it to the model you want
# Must be compatible with the OpenAI Endpoint.
# OPENAI_TITLE_MODEL=gpt-3.5-turbo
# Reverse proxy settings for OpenAI:
# https://github.com/waylaidwanderer/node-chatgpt-api#using-a-reverse-proxy
# OPENAI_REVERSE_PROXY=

View file

@ -2,6 +2,7 @@ const BaseClient = require('./BaseClient');
const ChatGPTClient = require('./ChatGPTClient');
const { encoding_for_model: encodingForModel, get_encoding: getEncoding } = require('tiktoken');
const { maxTokensMap, genAzureChatCompletion } = require('../../utils');
const { truncateText } = require('./prompts');
const { runTitleChain } = require('./chains');
const { createLLM } = require('./llm');
@ -406,12 +407,14 @@ class OpenAIClient extends BaseClient {
async titleConvo({ text, responseText = '' }) {
let title = 'New Chat';
const convo = `||>User:
"${text}"
"${truncateText(text)}"
||>Response:
"${JSON.stringify(responseText)}"`;
"${JSON.stringify(truncateText(responseText))}"`;
const { OPENAI_TITLE_MODEL } = process.env ?? {};
const modelOptions = {
model: 'gpt-3.5-turbo-0613',
model: OPENAI_TITLE_MODEL ?? 'gpt-3.5-turbo-0613',
temperature: 0.2,
presence_penalty: 0,
frequency_penalty: 0,
@ -446,7 +449,7 @@ class OpenAIClient extends BaseClient {
} catch (e) {
console.error(e.message);
console.log('There was an issue generating title with LangChain, trying the old method...');
modelOptions.model = 'gpt-3.5-turbo';
modelOptions.model = OPENAI_TITLE_MODEL ?? 'gpt-3.5-turbo';
const instructionsPayload = [
{
role: 'system',

View file

@ -15,7 +15,7 @@ const createLanguageChain = ({ llm }) =>
});
const titleSchema = z.object({
title: z.string().describe('The title-cased title of the conversation in the given language.'),
title: z.string().describe('The conversation title in title-case, in the given language.'),
});
const createTitleChain = ({ llm, convo }) => {
const titlePrompt = createTitlePrompt({ convo });

View file

@ -1,9 +1,11 @@
const instructions = require('./instructions');
const titlePrompts = require('./titlePrompts');
const refinePrompts = require('./refinePrompts');
const truncateText = require('./truncateText');
module.exports = {
...refinePrompts,
...instructions,
...titlePrompts,
truncateText,
};

View file

@ -16,7 +16,7 @@ const createTitlePrompt = ({ convo }) => {
const titlePrompt = new ChatPromptTemplate({
promptMessages: [
SystemMessagePromptTemplate.fromTemplate(
`Write a concise title for this conversation in the given language. Title in 5 Words or Less. No Punctuation or Quotation. All first letters of every word must be capitalized (resembling title-case), written in the given Language.
`Write a concise title for this conversation in the given language. Title in 5 Words or Less. No Punctuation or Quotation. Must be in Title Case, written in the given Language.
${convo}`,
),
HumanMessagePromptTemplate.fromTemplate('Language: {language}'),

View file

@ -0,0 +1,10 @@
const MAX_CHAR = 255;
function truncateText(text) {
if (text.length > MAX_CHAR) {
return `${text.slice(0, MAX_CHAR)}... [text truncated for brevity]`;
}
return text;
}
module.exports = truncateText;

View file

@ -1,7 +1,13 @@
const { isEnabled } = require('../server/utils');
const throttle = require('lodash/throttle');
const titleConvo = async ({ text, response }) => {
let title = 'New Chat';
const { TITLE_CONVO = 'true' } = process.env ?? {};
if (!isEnabled(TITLE_CONVO)) {
return title;
}
const { BingAIClient } = await import('@waylaidwanderer/chatgpt-api');
const titleGenerator = new BingAIClient({
userToken: process.env.BINGAI_TOKEN,

View file

@ -1,6 +1,12 @@
const { isEnabled } = require('../../../utils');
const { saveConvo } = require('../../../../models');
const addTitle = async (req, { text, response, client }) => {
const { TITLE_CONVO = 'true' } = process.env ?? {};
if (!isEnabled(TITLE_CONVO)) {
return;
}
const title = await client.titleConvo({ text, responseText: response?.text });
await saveConvo(req.user.id, {
conversationId: response.conversationId,