Cloudflare D1-Backed Chat Memory
info
This integration is only supported in Cloudflare Workers.
For longer-term persistence across chat sessions, you can swap out the default in-memory chatHistory that backs chat memory classes like BufferMemory for a Cloudflare D1 instance.
Setup
If you are using TypeScript, you may need to install Cloudflare types if they aren't already present:
- npm
 - Yarn
 - pnpm
 
npm install -S @cloudflare/workers-types
yarn add @cloudflare/workers-types
pnpm add @cloudflare/workers-types
Set up a D1 instance for your worker by following the official documentation. Your project's wrangler.toml file should
look something like this:
name = "YOUR_PROJECT_NAME"
main = "src/index.ts"
compatibility_date = "2023-09-18"
[vars]
ANTHROPIC_API_KEY = "YOUR_ANTHROPIC_KEY"
[[d1_databases]]
binding = "DB"                                       # available in your Worker as env.DB
database_name = "YOUR_D1_DB_NAME"
database_id = "YOUR_D1_DB_ID"
Usage
You can then use D1 to store your history as follows:
import type { D1Database } from "@cloudflare/workers-types";
import { BufferMemory } from "langchain/memory";
import { CloudflareD1MessageHistory } from "langchain/stores/message/cloudflare_d1";
import { ChatAnthropic } from "langchain/chat_models/anthropic";
import { ChatPromptTemplate, MessagesPlaceholder } from "langchain/prompts";
import { RunnableSequence } from "langchain/schema/runnable";
import { StringOutputParser } from "langchain/schema/output_parser";
export interface Env {
  DB: D1Database;
  ANTHROPIC_API_KEY: string;
}
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    try {
      const { searchParams } = new URL(request.url);
      const input = searchParams.get("input");
      if (!input) {
        throw new Error(`Missing "input" parameter`);
      }
      const memory = new BufferMemory({
        returnMessages: true,
        chatHistory: new CloudflareD1MessageHistory({
          tableName: "stored_message",
          sessionId: "example",
          database: env.DB,
        }),
      });
      const prompt = ChatPromptTemplate.fromPromptMessages([
        ["system", "You are a helpful chatbot"],
        new MessagesPlaceholder("history"),
        ["human", "{input}"],
      ]);
      const model = new ChatAnthropic({
        anthropicApiKey: env.ANTHROPIC_API_KEY,
      });
      const chain = RunnableSequence.from([
        {
          input: (initialInput) => initialInput.input,
          memory: () => memory.loadMemoryVariables({}),
        },
        {
          input: (previousOutput) => previousOutput.input,
          history: (previousOutput) => previousOutput.memory.history,
        },
        prompt,
        model,
        new StringOutputParser(),
      ]);
      const chainInput = { input };
      const res = await chain.invoke(chainInput);
      await memory.saveContext(chainInput, {
        output: res,
      });
      return new Response(JSON.stringify(res), {
        headers: { "content-type": "application/json" },
      });
    } catch (err: any) {
      console.log(err.message);
      return new Response(err.message, { status: 500 });
    }
  },
};
API Reference:
- BufferMemory from 
langchain/memory - CloudflareD1MessageHistory from 
langchain/stores/message/cloudflare_d1 - ChatAnthropic from 
langchain/chat_models/anthropic - ChatPromptTemplate from 
langchain/prompts - MessagesPlaceholder from 
langchain/prompts - RunnableSequence from 
langchain/schema/runnable - StringOutputParser from 
langchain/schema/output_parser