account for system prompt when estimating new context size

This commit is contained in:
Canyon Robins 2025-05-19 18:28:30 -07:00 committed by hannesrudolph
parent 440ed6e79c
commit 46fcd370c5
3 changed files with 9 additions and 1 deletions

View file

@ -62,6 +62,7 @@ export type SummarizeResponse = {
export async function summarizeConversation(
messages: ApiMessage[],
apiHandler: ApiHandler,
systemPrompt?: string,
): Promise<SummarizeResponse> {
const response: SummarizeResponse = { messages, cost: 0, summary: "" }
const messagesToSummarize = getMessagesSinceLastSummary(messages.slice(0, -N_MESSAGES_TO_KEEP))
@ -111,6 +112,9 @@ export async function summarizeConversation(
// Count the tokens in the context for the next API request
// We only estimate the tokens in summaryMesage if outputTokens is 0, otherwise we use outputTokens
const contextMessages = outputTokens ? [...keepMessages] : [summaryMessage, ...keepMessages]
if (systemPrompt) {
contextMessages.unshift({ role: "user", content: systemPrompt })
}
const contextBlocks = contextMessages.flatMap((message) =>
typeof message.content === "string" ? [{ text: message.content, type: "text" as const }] : message.content,
)

View file

@ -53,6 +53,7 @@ export function truncateConversation(messages: ApiMessage[], fracToRemove: numbe
* @param {number} maxTokens - The maximum number of tokens allowed.
* @param {ApiHandler} apiHandler - The API handler to use for token counting.
* @param {boolean} autoCondenseContext - Whether to use LLM summarization or sliding window implementation
* @param {string} systemPrompt - The system prompt, used for estimating the new context size after summarizing.
* @returns {ApiMessage[]} The original or truncated conversation messages.
*/
@ -63,6 +64,7 @@ type TruncateOptions = {
maxTokens?: number | null
apiHandler: ApiHandler
autoCondenseContext?: boolean
systemPrompt?: string
}
type TruncateResponse = SummarizeResponse & { prevContextTokens: number }
@ -81,6 +83,7 @@ export async function truncateConversationIfNeeded({
maxTokens,
apiHandler,
autoCondenseContext,
systemPrompt,
}: TruncateOptions): Promise<TruncateResponse> {
// Calculate the maximum tokens reserved for response
const reservedTokens = maxTokens || contextWindow * 0.2
@ -103,7 +106,7 @@ export async function truncateConversationIfNeeded({
if (effectiveTokens <= allowedTokens) {
return { messages, summary: "", cost: 0, prevContextTokens: effectiveTokens }
} else if (autoCondenseContext) {
const result = await summarizeConversation(messages, apiHandler)
const result = await summarizeConversation(messages, apiHandler, systemPrompt)
if (messages !== result.messages) {
return { ...result, prevContextTokens: effectiveTokens }
}

View file

@ -1479,6 +1479,7 @@ export class Task extends EventEmitter<ClineEvents> {
contextWindow,
apiHandler: this.api,
autoCondenseContext,
systemPrompt,
})
if (truncateResult.messages !== this.apiConversationHistory) {
await this.overwriteApiConversationHistory(truncateResult.messages)