2023-06-08 06:31:35 +02:00
const { v4 : uuidv4 } = require ( "uuid" ) ;
2023-07-28 21:09:49 +02:00
const { OpenAi } = require ( "../AiProviders/openAi" ) ;
2023-06-08 06:31:35 +02:00
const { WorkspaceChats } = require ( "../../models/workspaceChats" ) ;
2023-06-04 04:28:07 +02:00
const { resetMemory } = require ( "./commands/reset" ) ;
2023-06-08 06:31:35 +02:00
const moment = require ( "moment" ) ;
2023-08-04 23:56:27 +02:00
const { getVectorDbClass , getLLMProvider } = require ( "../helpers" ) ;
const { AzureOpenAi } = require ( "../AiProviders/azureOpenAi" ) ;
2023-06-04 04:28:07 +02:00
function convertToChatHistory ( history = [ ] ) {
2023-06-08 06:31:35 +02:00
const formattedHistory = [ ] ;
2023-06-04 04:28:07 +02:00
history . forEach ( ( history ) => {
2023-06-08 06:31:35 +02:00
const { prompt , response , createdAt } = history ;
2023-06-04 04:28:07 +02:00
const data = JSON . parse ( response ) ;
formattedHistory . push ( [
{
2023-06-08 06:31:35 +02:00
role : "user" ,
2023-06-04 04:28:07 +02:00
content : prompt ,
sentAt : moment ( createdAt ) . unix ( ) ,
} ,
{
2023-06-08 06:31:35 +02:00
role : "assistant" ,
2023-06-04 04:28:07 +02:00
content : data . text ,
sources : data . sources || [ ] ,
sentAt : moment ( createdAt ) . unix ( ) ,
} ,
2023-06-08 06:31:35 +02:00
] ) ;
} ) ;
2023-06-04 04:28:07 +02:00
2023-06-08 06:31:35 +02:00
return formattedHistory . flat ( ) ;
2023-06-04 04:28:07 +02:00
}
function convertToPromptHistory ( history = [ ] ) {
2023-06-08 06:31:35 +02:00
const formattedHistory = [ ] ;
2023-06-04 04:28:07 +02:00
history . forEach ( ( history ) => {
2023-06-08 06:31:35 +02:00
const { prompt , response } = history ;
2023-06-04 04:28:07 +02:00
const data = JSON . parse ( response ) ;
formattedHistory . push ( [
2023-06-08 06:31:35 +02:00
{ role : "user" , content : prompt } ,
{ role : "assistant" , content : data . text } ,
] ) ;
} ) ;
return formattedHistory . flat ( ) ;
2023-06-04 04:28:07 +02:00
}
const VALID _COMMANDS = {
2023-06-08 06:31:35 +02:00
"/reset" : resetMemory ,
} ;
2023-06-04 04:28:07 +02:00
function grepCommand ( message ) {
const availableCommands = Object . keys ( VALID _COMMANDS ) ;
for ( let i = 0 ; i < availableCommands . length ; i ++ ) {
const cmd = availableCommands [ i ] ;
const re = new RegExp ( ` ^( ${ cmd } ) ` , "i" ) ;
if ( re . test ( message ) ) {
return cmd ;
}
}
2023-06-08 06:31:35 +02:00
return null ;
2023-06-04 04:28:07 +02:00
}
2023-07-25 19:37:04 +02:00
async function chatWithWorkspace (
workspace ,
message ,
chatMode = "chat" ,
user = null
) {
2023-06-04 04:28:07 +02:00
const uuid = uuidv4 ( ) ;
2023-08-04 23:56:27 +02:00
const LLMConnector = getLLMProvider ( ) ;
2023-06-08 06:31:35 +02:00
const VectorDb = getVectorDbClass ( ) ;
const command = grepCommand ( message ) ;
2023-06-04 04:28:07 +02:00
if ( ! ! command && Object . keys ( VALID _COMMANDS ) . includes ( command ) ) {
2023-07-25 19:37:04 +02:00
return await VALID _COMMANDS [ command ] ( workspace , message , uuid , user ) ;
2023-06-04 04:28:07 +02:00
}
2023-08-04 23:56:27 +02:00
const { safe , reasons = [ ] } = await LLMConnector . isSafe ( message ) ;
2023-06-04 04:28:07 +02:00
if ( ! safe ) {
return {
id : uuid ,
2023-06-08 06:31:35 +02:00
type : "abort" ,
2023-06-04 04:28:07 +02:00
textResponse : null ,
sources : [ ] ,
close : true ,
2023-06-08 06:31:35 +02:00
error : ` This message was moderated and will not be allowed. Violations for ${ reasons . join (
", "
) } found . ` ,
2023-06-04 04:28:07 +02:00
} ;
}
2023-06-08 06:31:35 +02:00
const hasVectorizedSpace = await VectorDb . hasNamespace ( workspace . slug ) ;
2023-07-25 19:37:04 +02:00
const embeddingsCount = await VectorDb . namespaceCount ( workspace . slug ) ;
if ( ! hasVectorizedSpace || embeddingsCount === 0 ) {
2023-06-08 06:31:35 +02:00
const rawHistory = await WorkspaceChats . forWorkspace ( workspace . id ) ;
2023-06-04 04:28:07 +02:00
const chatHistory = convertToPromptHistory ( rawHistory ) ;
2023-08-04 23:56:27 +02:00
const response = await LLMConnector . sendChat (
chatHistory ,
message ,
workspace
) ;
2023-06-08 06:31:35 +02:00
const data = { text : response , sources : [ ] , type : "chat" } ;
2023-06-04 04:28:07 +02:00
2023-06-08 06:31:35 +02:00
await WorkspaceChats . new ( {
workspaceId : workspace . id ,
prompt : message ,
response : data ,
2023-07-25 19:37:04 +02:00
user ,
2023-06-08 06:31:35 +02:00
} ) ;
2023-06-04 04:28:07 +02:00
return {
id : uuid ,
2023-06-08 06:31:35 +02:00
type : "textResponse" ,
2023-06-04 04:28:07 +02:00
textResponse : response ,
sources : [ ] ,
close : true ,
error : null ,
} ;
} else {
2023-06-28 21:53:26 +02:00
var messageLimit = workspace ? . openAiHistory ;
2023-06-28 21:54:18 +02:00
const rawHistory = await WorkspaceChats . forWorkspace (
workspace . id ,
messageLimit
) ;
2023-06-27 00:08:47 +02:00
const chatHistory = convertToPromptHistory ( rawHistory ) ;
2023-06-08 06:31:35 +02:00
const {
response ,
sources ,
message : error ,
2023-06-15 08:12:59 +02:00
} = await VectorDb [ chatMode ] ( {
namespace : workspace . slug ,
input : message ,
workspace ,
2023-06-27 00:08:47 +02:00
chatHistory ,
2023-06-15 08:12:59 +02:00
} ) ;
2023-06-04 04:28:07 +02:00
if ( ! response ) {
return {
id : uuid ,
2023-06-08 06:31:35 +02:00
type : "abort" ,
2023-06-04 04:28:07 +02:00
textResponse : null ,
sources : [ ] ,
close : true ,
error ,
} ;
}
2023-06-08 06:31:35 +02:00
const data = { text : response , sources , type : chatMode } ;
await WorkspaceChats . new ( {
workspaceId : workspace . id ,
prompt : message ,
response : data ,
2023-07-25 19:37:04 +02:00
user ,
2023-06-08 06:31:35 +02:00
} ) ;
2023-06-04 04:28:07 +02:00
return {
id : uuid ,
2023-06-08 06:31:35 +02:00
type : "textResponse" ,
2023-06-04 04:28:07 +02:00
textResponse : response ,
sources ,
close : true ,
error ,
} ;
}
}
2023-07-20 20:14:23 +02:00
function chatPrompt ( workspace ) {
return (
workspace ? . openAiPrompt ? ?
"Given the following conversation, relevant context, and a follow up question, reply with an answer to the current question the user is asking. Return only your response to the question given the above information following the users instructions as needed."
) ;
}
2023-06-04 04:28:07 +02:00
module . exports = {
convertToChatHistory ,
2023-06-08 06:31:35 +02:00
chatWithWorkspace ,
2023-07-20 20:14:23 +02:00
chatPrompt ,
2023-06-08 06:31:35 +02:00
} ;