Skip to content

Commit

Permalink
fix(chat): Use separate settings page for 'chat with emails' feature
Browse files Browse the repository at this point in the history
  • Loading branch information
andris9 committed Sep 29, 2023
1 parent ed07c87 commit c66e3ba
Show file tree
Hide file tree
Showing 13 changed files with 751 additions and 727 deletions.
54 changes: 47 additions & 7 deletions lib/api-routes/chat-routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ const getSecret = require('../get-secret');
const Boom = require('@hapi/boom');
const Joi = require('joi');
const { failAction } = require('../tools');
const settings = require('../settings');

const { accountIdSchema } = require('../schemas');
const { accountIdSchema, addressSchema } = require('../schemas');

async function init(args) {
const { server, call, CORS_CONFIG } = args;
Expand All @@ -22,12 +23,35 @@ async function init(args) {
let accountObject = new Account({ redis, account: request.params.account, call, secret: await getSecret() });
await accountObject.loadAccountData();

let documentStoreEnabled = await settings.get('documentStoreEnabled');
let documentStoreGenerateEmbeddings = (await settings.get('documentStoreGenerateEmbeddings')) || false;
let hasOpenAiAPIKey = !!(await settings.get('openAiAPIKey'));

if (!documentStoreEnabled) {
let error = Boom.boomify(new Error('Document store is not enabled'), { statusCode: 403 });
error.output.payload.code = 'DocumentStoreDisabled';
throw error;
}

if (!documentStoreGenerateEmbeddings) {
let error = Boom.boomify(new Error('Chat is not enabled'), { statusCode: 403 });
error.output.payload.code = 'ChatDisabled';
throw error;
}

if (!hasOpenAiAPIKey) {
let error = Boom.boomify(new Error('OpenAI API key not set'), { statusCode: 403 });
error.output.payload.code = 'ApiKeyNotSet';
throw error;
}

const esClient = await h.getESClient(request.logger);
const { index, client } = esClient;

// Step 1. Embeddings for the request

let embeddingsResult = await call({ cmd: 'generateChunkEmbeddings', data: { message: request.payload.message } });
let embeddingsResult = await call({ cmd: 'generateChunkEmbeddings', data: { message: request.payload.question } });

if (!embeddingsResult || !embeddingsResult.embedding) {
let error = new Error('Failed to generate embeddings for query');
throw error;
Expand Down Expand Up @@ -57,7 +81,8 @@ async function init(args) {
if (!knnResult?.hits?.hits?.length) {
return {
success: true,
response: null
response: null,
description: 'No matching emails found'
};
}

Expand Down Expand Up @@ -99,7 +124,7 @@ async function init(args) {
let queryResponse = await call({
cmd: 'embeddingsQuery',
data: {
question: request.payload.message,
question: request.payload.question,
contextChunks: payloadData.join('\n\n')
},
timeout: 3 * 60 * 1000
Expand Down Expand Up @@ -176,7 +201,7 @@ async function init(args) {

options: {
description: 'Chat with emails',
notes: 'Use OpenAI API and embeddings stored in the Document Store to "chat" with account emails.',
notes: 'Use OpenAI API and embeddings stored in the Document Store to "chat" with account emails. Requires Document Store indexing and the "Chat with emails" feature to be enabled.',
tags: ['api', 'Chat'],

plugins: {},
Expand All @@ -200,7 +225,7 @@ async function init(args) {
}),

payload: Joi.object({
message: Joi.string()
question: Joi.string()
.trim()
.max(1024)
.example('When did Jason last message me?')
Expand All @@ -212,7 +237,22 @@ async function init(args) {

response: {
schema: Joi.object({
response: Joi.string().trim().example('Last tuesday').description('Chat response').label('ChatResponse').required()
success: Joi.boolean().example(true).description('Was the request successful').label('ReturnChatResponseSuccess'),
answer: Joi.string().trim().example('Last tuesday').description('Chat response').label('ChatResponse').required(),
message: Joi.object({
id: Joi.string().example('AAAAAgAACrI').description('Message ID').label('ChatMessageId'),
path: Joi.string().example('INBOX').description('Folder this message was found from').label('ChatMessagePath'),
from: addressSchema.example({ name: 'From Me', address: '[email protected]' }).description('The From address').label('FromAddress'),

to: Joi.array()
.items(addressSchema)
.single()
.description('List of addresses')
.example([{ address: '[email protected]' }])
.label('AddressList')
})
.description('Email that best matched the question')
.label('ChatResponseMessage')
}).label('ReturnChatResponse'),
failAction: 'log'
}
Expand Down
Loading

0 comments on commit c66e3ba

Please sign in to comment.