diff --git a/langchain-core/src/runnables/history.ts b/langchain-core/src/runnables/history.ts index 1ba5a378b4d8..fbf12f89c551 100644 --- a/langchain-core/src/runnables/history.ts +++ b/langchain-core/src/runnables/history.ts @@ -27,13 +27,14 @@ type GetSessionHistoryCallable = ( export interface RunnableWithMessageHistoryInputs extends Omit< RunnableBindingArgs, - "bound" + "bound" | "config" > { runnable: Runnable; getMessageHistory: GetSessionHistoryCallable; inputMessagesKey?: string; outputMessagesKey?: string; historyMessagesKey?: string; + config?: RunnableConfig; } export class RunnableWithMessageHistory< @@ -70,8 +71,11 @@ export class RunnableWithMessageHistory< ) .withConfig({ runName: "RunnableWithMessageHistory" }); + const config = fields.config ?? {}; + super({ ...fields, + config, bound, }); this.runnable = fields.runnable; diff --git a/langchain-core/src/runnables/tests/runnable_history.test.ts b/langchain-core/src/runnables/tests/runnable_history.test.ts index 4f9e688142c5..3d9628478bfd 100644 --- a/langchain-core/src/runnables/tests/runnable_history.test.ts +++ b/langchain-core/src/runnables/tests/runnable_history.test.ts @@ -8,8 +8,10 @@ import { } from "../../chat_history.js"; import { FakeChatMessageHistory, + FakeLLM, FakeListChatMessageHistory, } from "../../utils/testing/index.js"; +import { ChatPromptTemplate, MessagesPlaceholder } from "../../prompts/chat.js"; // For `BaseChatMessageHistory` async function getGetSessionHistory(): Promise< @@ -90,3 +92,31 @@ test("Runnable with message history work with chat list memory", async () => { output = await withHistory.invoke([new HumanMessage("good bye")], config); expect(output).toBe("you said: hello\ngood bye"); }); + +test("Runnable with message history and RunnableSequence", async () => { + const prompt = ChatPromptTemplate.fromMessages([ + ["ai", "You are a helpful assistant"], + new MessagesPlaceholder("history"), + ["human", "{input}"], + ]); + const model = new FakeLLM({}); + const chain = prompt.pipe(model); + + const getListMessageHistory = await getListSessionHistory(); + const withHistory = new RunnableWithMessageHistory({ + runnable: chain, + config: {}, + getMessageHistory: getListMessageHistory, + inputMessagesKey: "input", + historyMessagesKey: "history", + }); + const config: RunnableConfig = { configurable: { sessionId: "1" } }; + let output = await withHistory.invoke({ input: "hello" }, config); + expect(output).toBe("AI: You are a helpful assistant\nHuman: hello"); + output = await withHistory.invoke({ input: "good bye" }, config); + expect(output).toBe(`AI: You are a helpful assistant +Human: hello +AI: AI: You are a helpful assistant +Human: hello +Human: good bye`); +});