@langchain/community
Version:
Third-party integrations for LangChain.js
139 lines (138 loc) • 4.63 kB
JavaScript
import { __exportAll } from "../../_virtual/_rolldown/runtime.js";
import { mapChatMessagesToStoredMessages, mapStoredMessagesToChatMessages } from "@langchain/core/messages";
import { BaseListChatMessageHistory } from "@langchain/core/chat_history";
import { getApps, initializeApp } from "firebase-admin/app";
import { FieldValue, getFirestore } from "firebase-admin/firestore";
//#region src/stores/message/firestore.ts
var firestore_exports = /* @__PURE__ */ __exportAll({ FirestoreChatMessageHistory: () => FirestoreChatMessageHistory });
/**
* Class for managing chat message history using Google's Firestore as a
* storage backend. Extends the BaseListChatMessageHistory class.
* @example
* ```typescript
* const chatHistory = new FirestoreChatMessageHistory({
* collectionName: "langchain",
* sessionId: "lc-example",
* userId: "a@example.com",
* config: { projectId: "your-project-id" },
* });
*
* const chain = new ConversationChain({
* llm: new ChatOpenAI({ model: "gpt-4o-mini" }),
* memory: new BufferMemory({ chatHistory }),
* });
*
* const response = await chain.invoke({
* input: "What did I just say my name was?",
* });
* console.log({ response });
* ```
*/
var FirestoreChatMessageHistory = class extends BaseListChatMessageHistory {
lc_namespace = [
"langchain",
"stores",
"message",
"firestore"
];
collections;
docs;
sessionId;
userId;
appIdx;
config;
firestoreClient;
document;
constructor({ collections, docs, sessionId, userId, appIdx = 0, config }) {
super();
if (collections || docs) {
if (!(collections?.length === docs?.length || collections?.length === 1 && !docs)) throw new Error("Collections and docs options must have the same length, or collections must have a length of 1 if docs is not defined.");
}
this.collections = collections || [];
this.docs = docs || [sessionId];
this.sessionId = sessionId;
this.userId = userId;
this.document = null;
this.appIdx = appIdx;
if (config) this.config = config;
try {
this.ensureFirestore();
} catch {
throw new Error(`Unknown response type`);
}
}
ensureFirestore() {
let app;
if (!getApps().length) app = initializeApp(this.config);
else app = getApps()[this.appIdx];
this.firestoreClient = getFirestore(app);
this.document = this.collections.reduce((acc, collection, index) => acc.collection(collection).doc(this.docs[index]), this.firestoreClient);
}
/**
* Method to retrieve all messages from the Firestore collection
* associated with the current session. Returns an array of BaseMessage
* objects.
* @returns Array of stored messages
*/
async getMessages() {
if (!this.document) throw new Error("Document not initialized");
const querySnapshot = await this.document.collection("messages").orderBy("createdAt", "asc").get().catch((err) => {
throw new Error(`Unknown response type: ${err.toString()}`);
});
const response = [];
querySnapshot.forEach((doc) => {
const { type, data } = doc.data();
response.push({
type,
data
});
});
return mapStoredMessagesToChatMessages(response);
}
/**
* Method to add a new message to the Firestore collection. The message is
* passed as a BaseMessage object.
* @param message The message to be added as a BaseMessage object.
*/
async addMessage(message) {
const messages = mapChatMessagesToStoredMessages([message]);
await this.upsertMessage(messages[0]);
}
async upsertMessage(message) {
if (!this.document) throw new Error("Document not initialized");
await this.document.set({
id: this.sessionId,
user_id: this.userId
}, { merge: true });
await this.document.collection("messages").add({
type: message.type,
data: message.data,
createdBy: this.userId,
createdAt: FieldValue.serverTimestamp()
}).catch((err) => {
throw new Error(`Unknown response type: ${err.toString()}`);
});
}
/**
* Method to delete all messages from the Firestore collection associated
* with the current session.
*/
async clear() {
if (!this.document) throw new Error("Document not initialized");
await this.document.collection("messages").get().then((querySnapshot) => {
querySnapshot.docs.forEach((snapshot) => {
snapshot.ref.delete().catch((err) => {
throw new Error(`Unknown response type: ${err.toString()}`);
});
});
}).catch((err) => {
throw new Error(`Unknown response type: ${err.toString()}`);
});
await this.document.delete().catch((err) => {
throw new Error(`Unknown response type: ${err.toString()}`);
});
}
};
//#endregion
export { FirestoreChatMessageHistory, firestore_exports };
//# sourceMappingURL=firestore.js.map