mongodb-rag-core
Version:
Common elements used by MongoDB Chatbot Framework components.
171 lines • 6.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMessageFromOpenAIChatMessage = exports.createMessage = exports.makeMongoDbConversationsService = void 0;
const mongodb_1 = require("mongodb");
const ConversationsService_1 = require("./ConversationsService");
/**
Create {@link ConversationsService} that uses MongoDB as a data store.
*/
function makeMongoDbConversationsService(database, conversationConstants = ConversationsService_1.defaultConversationConstants) {
const conversationsCollection = database.collection("conversations");
return {
conversationConstants,
async create(params) {
const customData = params?.customData;
const initialMessages = params?.initialMessages;
const newConversation = {
_id: new mongodb_1.ObjectId(),
messages: initialMessages
? initialMessages?.map(createMessageFromOpenAIChatMessage)
: [],
createdAt: new Date(),
// Conditionally include `customData` only if it's not undefined
// Otherwise MongoDB adds it as `customData: null`,
// which we don't want.
...(customData !== undefined && { customData }),
};
const insertResult = await conversationsCollection.insertOne(newConversation);
if (!insertResult.acknowledged ||
insertResult.insertedId !== newConversation._id) {
throw new Error("Failed to insert conversation");
}
return newConversation;
},
async addConversationMessage(params) {
const { conversationId, message } = params;
const newMessage = createMessage(message);
const updateResult = await conversationsCollection.updateOne({
_id: conversationId,
}, {
$push: {
messages: newMessage,
},
});
if (!updateResult.acknowledged || updateResult.matchedCount === 0) {
throw new Error("Failed to insert message");
}
return newMessage;
},
async addManyConversationMessages(params) {
const { messages, conversationId } = params;
const newMessages = messages.map(createMessage);
const updateResult = await conversationsCollection.updateOne({
_id: conversationId,
}, {
$push: {
messages: {
$each: newMessages,
},
},
});
if (!updateResult.acknowledged || updateResult.matchedCount === 0) {
throw new Error("Failed to insert message");
}
return newMessages;
},
async findById({ _id }) {
const conversation = await conversationsCollection.findOne({ _id });
return conversation;
},
async rateMessage({ conversationId, messageId, rating, }) {
const updateResult = await conversationsCollection.updateOne({
_id: conversationId,
}, {
$set: {
"messages.$[message].rating": rating,
},
}, {
arrayFilters: [
{ "message.id": messageId, "message.role": "assistant" },
],
});
if (!updateResult.acknowledged || updateResult.matchedCount === 0) {
throw new Error("Failed to rate message");
}
return true;
},
async commentMessage({ conversationId, messageId, comment, }) {
const updateResult = await conversationsCollection.updateOne({
_id: conversationId,
messages: {
$elemMatch: {
id: messageId,
role: "assistant",
},
},
}, {
$set: {
"messages.$[message].userComment": comment,
},
}, {
arrayFilters: [{ "message.id": messageId }],
});
if (!updateResult.acknowledged || updateResult.matchedCount === 0) {
throw new Error("Failed to save comment on message");
}
return true;
},
};
}
exports.makeMongoDbConversationsService = makeMongoDbConversationsService;
function createMessage(messageParams) {
const message = {
...messageParams,
createdAt: new Date(),
id: messageParams.id ?? new mongodb_1.ObjectId(),
};
// Remove undefined customData so that it's
// not persisted to the database as `customData: null`.
if (messageParams.customData === undefined) {
delete message.customData;
}
return message;
}
exports.createMessage = createMessage;
/**
Create a {@link Message} object from the {@link OpenAiChatMessage} object.
*/
function createMessageFromOpenAIChatMessage(chatMessage) {
const dbMessageBase = {
id: new mongodb_1.ObjectId(),
createdAt: new Date(),
...(chatMessage.customData ? { customData: chatMessage.customData } : {}),
};
// Avoid MongoDB inserting null for undefineds
if (chatMessage.role === "user") {
return {
...dbMessageBase,
role: chatMessage.role,
content: chatMessage.content,
embedding: chatMessage.embedding ?? [],
};
}
if (chatMessage.role === "assistant") {
return {
...dbMessageBase,
role: chatMessage.role,
content: chatMessage.content ?? "",
...(chatMessage.functionCall
? { functionCall: chatMessage.functionCall }
: {}),
};
}
if (chatMessage.role === "system") {
return {
...dbMessageBase,
role: chatMessage.role,
content: chatMessage.content,
};
}
if (chatMessage.role === "function") {
return {
...dbMessageBase,
role: chatMessage.role,
content: chatMessage.content ?? "",
name: chatMessage.name,
};
}
throw new Error(`Invalid message for message: ${chatMessage}`);
}
exports.createMessageFromOpenAIChatMessage = createMessageFromOpenAIChatMessage;
//# sourceMappingURL=MongoDbConversations.js.map