Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add session context for a user mongodb #7436

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions libs/langchain-azure-cosmosdb/src/chat_histories/mongodb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ export interface AzureCosmosDBMongoChatHistoryDBConfig {
readonly collectionName?: string;
}

export type ChatSession = {
id: string;
context: Record<string, unknown>;
};

const ID_KEY = "sessionId";

export class AzureCosmosDBMongoChatMessageHistory extends BaseListChatMessageHistory {
Expand All @@ -33,6 +38,8 @@ export class AzureCosmosDBMongoChatMessageHistory extends BaseListChatMessageHis

private initPromise?: Promise<void>;

private context: Record<string, unknown> = {};

private readonly client: MongoClient | undefined;

private database: Db;
Expand Down Expand Up @@ -134,10 +141,12 @@ export class AzureCosmosDBMongoChatMessageHistory extends BaseListChatMessageHis
await this.initialize();

const messages = mapChatMessagesToStoredMessages([message]);
const context = await this.getContext();
await this.collection.updateOne(
{ [ID_KEY]: this.sessionId },
{
$push: { messages: { $each: messages } } as PushOperator<Document>,
$set: { context },
},
{ upsert: true }
);
Expand All @@ -152,4 +161,51 @@ export class AzureCosmosDBMongoChatMessageHistory extends BaseListChatMessageHis

await this.collection.deleteOne({ [ID_KEY]: this.sessionId });
}

async getAllSessions(): Promise<ChatSession[]> {
await this.initialize();
const documents = await this.collection.find().toArray();

const chatSessions: ChatSession[] = documents.map((doc) => ({
id: doc[ID_KEY],
context: doc.context || {},
}));

return chatSessions;
}

async clearAllSessions() {
await this.initialize();
try {
await this.collection.deleteMany({});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would delete all sessions for all users, which might not be the intended behavior... I think you missed the user handling here

} catch (error) {
console.log("Error clearing sessions:", error);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be better to throw so these errors can be identified

}
}

async getContext(): Promise<Record<string, unknown>> {
await this.initialize();

const document = await this.collection.findOne({
[ID_KEY]: this.sessionId,
});
this.context = document?.context || this.context;
return this.context;
}

async setContext(context: Record<string, unknown>): Promise<void> {
await this.initialize();

try {
await this.collection.updateOne(
{ [ID_KEY]: this.sessionId },
{
$set: { context },
},
{ upsert: true }
);
} catch (error) {
console.log("Error setting context", error);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be better to throw so these errors can be identified

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,46 @@ test("Test clear Azure Cosmos MongoDB history store", async () => {

await mongoClient.close();
});

test("Test getAllSessions and clearAllSessions", async () => {
expect(process.env.AZURE_COSMOSDB_MONGODB_CONNECTION_STRING).toBeDefined();

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const mongoClient = new MongoClient(
process.env.AZURE_COSMOSDB_MONGODB_CONNECTION_STRING!
);
const dbcfg: AzureCosmosDBMongoChatHistoryDBConfig = {
client: mongoClient,
connectionString: process.env.AZURE_COSMOSDB_MONGODB_CONNECTION_STRING,
databaseName: "langchain",
collectionName: "chathistory",
};

const sessionId1 = new ObjectId().toString();
const sessionId2 = new ObjectId().toString();

const chatHistory1 = new AzureCosmosDBMongoChatMessageHistory(
dbcfg,
sessionId1
);
const chatHistory2 = new AzureCosmosDBMongoChatMessageHistory(
dbcfg,
sessionId2
);

await chatHistory1.addUserMessage("What is AI?");
await chatHistory1.addAIChatMessage("AI stands for Artificial Intelligence.");
await chatHistory2.addUserMessage("What is the best programming language?");
await chatHistory2.addAIChatMessage("It depends on the use case.");

const allSessions = await chatHistory1.getAllSessions();
expect(allSessions.length).toBe(2);
expect(allSessions[0].id).toBe(sessionId1);
expect(allSessions[1].id).toBe(sessionId2);

await chatHistory1.clearAllSessions();
const clearedSessions = await chatHistory1.getAllSessions();
expect(clearedSessions.length).toBe(0);

await mongoClient.close();
});