Skip to content

Commit a2df2d4

Browse files
fix(summary-middleware): use summaryPrefix or fall back to default prefix (#9630)
Co-authored-by: Thomas Pischulski <thomas@blackhorne.de> Co-authored-by: Christian Bromann <git@bromann.dev>
1 parent a01877d commit a2df2d4

File tree

3 files changed

+85
-1
lines changed

3 files changed

+85
-1
lines changed

.changeset/two-ducks-double.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"langchain": patch
3+
---
4+
5+
fix(summary-middleware): use summaryPrefix or fall back to default prefix

libs/langchain/src/agents/middleware/summarization.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Messages to summarize:
5353
{messages}
5454
</messages>`;
5555

56+
const DEFAULT_SUMMARY_PREFIX = "Here is a summary of the conversation to date:";
5657
const DEFAULT_MESSAGES_TO_KEEP = 20;
5758
const DEFAULT_TRIM_TOKEN_LIMIT = 4000;
5859
const DEFAULT_FALLBACK_MESSAGE_COUNT = 15;
@@ -385,6 +386,10 @@ export function summarizationMiddleware(
385386
: runtime.context?.summaryPrompt ??
386387
userOptions.summaryPrompt ??
387388
DEFAULT_SUMMARY_PROMPT;
389+
const summaryPrefix =
390+
runtime.context.summaryPrefix ??
391+
userOptions.summaryPrefix ??
392+
DEFAULT_SUMMARY_PREFIX;
388393
const trimTokensToSummarize =
389394
runtime.context?.trimTokensToSummarize !== undefined
390395
? runtime.context.trimTokensToSummarize
@@ -440,7 +445,7 @@ export function summarizationMiddleware(
440445
);
441446

442447
const summaryMessage = new HumanMessage({
443-
content: `Here is a summary of the conversation to date:\n\n${summary}`,
448+
content: `${summaryPrefix}\n\n${summary}`,
444449
id: uuid(),
445450
});
446451

libs/langchain/src/agents/middleware/tests/summarization.test.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,4 +830,78 @@ describe("summarizationMiddleware", () => {
830830
!(AIMessage.isInstance(firstPreserved) && hasToolCalls(firstPreserved))
831831
).toBe(true);
832832
});
833+
834+
it("should use default summaryPrefix when not provided", async () => {
835+
const summarizationModel = createMockSummarizationModel();
836+
const model = createMockMainModel();
837+
838+
const middleware = summarizationMiddleware({
839+
model: summarizationModel as any,
840+
trigger: { tokens: 50 },
841+
keep: { messages: 2 },
842+
});
843+
844+
const agent = createAgent({
845+
model,
846+
middleware: [middleware],
847+
});
848+
849+
const messages = [
850+
new HumanMessage(`Message 1: ${"x".repeat(200)}`),
851+
new AIMessage(`Response 1: ${"x".repeat(200)}`),
852+
new HumanMessage(`Message 2: ${"x".repeat(200)}`),
853+
new AIMessage(`Response 2: ${"x".repeat(200)}`),
854+
new HumanMessage("Final question"),
855+
];
856+
857+
const result = await agent.invoke({ messages });
858+
859+
// Verify summarization was triggered
860+
expect(summarizationModel.invoke).toHaveBeenCalled();
861+
862+
// Verify the default prefix is used
863+
const summaryMessage = result.messages[0] as HumanMessage;
864+
expect(summaryMessage.content).toContain(
865+
"Here is a summary of the conversation to date:"
866+
);
867+
});
868+
869+
it("should use custom summaryPrefix when provided", async () => {
870+
const summarizationModel = createMockSummarizationModel();
871+
const model = createMockMainModel();
872+
873+
const customPrefix = "Custom summary prefix for testing:";
874+
875+
const middleware = summarizationMiddleware({
876+
model: summarizationModel as any,
877+
trigger: { tokens: 50 },
878+
keep: { messages: 2 },
879+
summaryPrefix: customPrefix,
880+
});
881+
882+
const agent = createAgent({
883+
model,
884+
middleware: [middleware],
885+
});
886+
887+
const messages = [
888+
new HumanMessage(`Message 1: ${"x".repeat(200)}`),
889+
new AIMessage(`Response 1: ${"x".repeat(200)}`),
890+
new HumanMessage(`Message 2: ${"x".repeat(200)}`),
891+
new AIMessage(`Response 2: ${"x".repeat(200)}`),
892+
new HumanMessage("Final question"),
893+
];
894+
895+
const result = await agent.invoke({ messages });
896+
897+
// Verify summarization was triggered
898+
expect(summarizationModel.invoke).toHaveBeenCalled();
899+
900+
// Verify the custom prefix is used
901+
const summaryMessage = result.messages[0] as HumanMessage;
902+
expect(summaryMessage.content).toContain(customPrefix);
903+
expect(summaryMessage.content).not.toContain(
904+
"Here is a summary of the conversation to date:"
905+
);
906+
});
833907
});

0 commit comments

Comments
 (0)