@@ -3,6 +3,7 @@ import { ApiHandler } from "../../api"
33import { ApiMessage } from "../task-persistence/apiMessages"
44
55const CONTEXT_FRAC_FOR_SUMMARY = 0.5 // TODO(canyon): make this configurable
6+ const N_MESSAGES_TO_KEEP = 3
67
78const SUMMARY_PROMPT = `\
89Your task is to create a detailed summary of the conversation so far, paying close attention to the user's explicit requests and your previous actions.
@@ -67,19 +68,21 @@ export async function summarizeConversationIfNeeded(
6768}
6869
6970async function summarizeConversation ( messages : ApiMessage [ ] , apiHandler : ApiHandler ) : Promise < ApiMessage [ ] > {
70- if ( messages . length <= 2 ) {
71- return messages
71+ const messagesToSummarize = getMessagesSinceLastSummary ( messages . slice ( 0 , - N_MESSAGES_TO_KEEP ) )
72+ if ( messagesToSummarize . length <= 1 ) {
73+ return messages // Not enough messages to warrant a summary
7274 }
73- if ( messages [ messages . length - 2 ] . isSummary || messages [ messages . length - 1 ] . isSummary ) {
74- return messages
75+ const keepMessages = messages . slice ( - N_MESSAGES_TO_KEEP )
76+ for ( const message of keepMessages ) {
77+ if ( message . isSummary ) {
78+ return messages // We recently summarized these messages; it's too soon to summarize again.
79+ }
7580 }
7681 const finalRequestMessage : Anthropic . MessageParam = {
7782 role : "user" ,
7883 content : "Summarize the conversation so far, as described in the prompt instructions." ,
7984 }
80- const messagesToSummarize = [ ...messages . slice ( 0 , - 1 ) , finalRequestMessage ]
81-
82- const stream = apiHandler . createMessage ( SUMMARY_PROMPT , messagesToSummarize )
85+ const stream = apiHandler . createMessage ( SUMMARY_PROMPT , [ ...messagesToSummarize , finalRequestMessage ] )
8386 let summary = ""
8487 for await ( const chunk of stream ) {
8588 if ( chunk . type === "text" ) {
@@ -98,5 +101,15 @@ async function summarizeConversation(messages: ApiMessage[], apiHandler: ApiHand
98101 isSummary : true ,
99102 }
100103
101- return [ ...messages . slice ( 0 , - 1 ) , summaryMessage , messages [ messages . length - 1 ] ]
104+ return [ ...messages . slice ( 0 , - N_MESSAGES_TO_KEEP ) , summaryMessage , ...keepMessages ]
105+ }
106+
107+ /* Returns the list of all messages since the last summary message, including the summary. Returns all messages if there is no summary. */
108+ export function getMessagesSinceLastSummary ( messages : ApiMessage [ ] ) : ApiMessage [ ] {
109+ let lastSummaryIndexReverse = [ ...messages ] . reverse ( ) . findIndex ( ( message ) => message . isSummary )
110+ if ( lastSummaryIndexReverse === - 1 ) {
111+ return messages
112+ }
113+ const lastSummaryIndex = messages . length - lastSummaryIndexReverse - 1
114+ return messages . slice ( lastSummaryIndex )
102115}
0 commit comments