Skip to content

Commit 9765612

Browse files
committed
add unit tests for condense
1 parent 7c3f799 commit 9765612

File tree

1 file changed

+57
-8
lines changed

1 file changed

+57
-8
lines changed

src/core/condense/__tests__/index.test.ts

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,11 @@ describe("summarizeConversation", () => {
6969
// Reset mocks
7070
jest.clearAllMocks()
7171

72-
// Setup mock stream
72+
// Setup mock stream with usage information
7373
mockStream = (async function* () {
7474
yield { type: "text" as const, text: "This is " }
7575
yield { type: "text" as const, text: "a summary" }
76+
yield { type: "usage" as const, totalCost: 0.05, outputTokens: 150 }
7677
})()
7778

7879
// Setup mock API handler
@@ -103,7 +104,10 @@ describe("summarizeConversation", () => {
103104
]
104105

105106
const result = await summarizeConversation(messages, mockApiHandler)
106-
expect(result).toEqual(messages)
107+
expect(result.messages).toEqual(messages)
108+
expect(result.cost).toBe(0)
109+
expect(result.summary).toBe("")
110+
expect(result.newContextTokens).toBeUndefined()
107111
expect(mockApiHandler.createMessage).not.toHaveBeenCalled()
108112
})
109113

@@ -119,7 +123,10 @@ describe("summarizeConversation", () => {
119123
]
120124

121125
const result = await summarizeConversation(messages, mockApiHandler)
122-
expect(result).toEqual(messages)
126+
expect(result.messages).toEqual(messages)
127+
expect(result.cost).toBe(0)
128+
expect(result.summary).toBe("")
129+
expect(result.newContextTokens).toBeUndefined()
123130
expect(mockApiHandler.createMessage).not.toHaveBeenCalled()
124131
})
125132

@@ -142,17 +149,22 @@ describe("summarizeConversation", () => {
142149

143150
// Verify the structure of the result
144151
// The result should be: original messages (except last N) + summary + last N messages
145-
expect(result.length).toBe(messages.length + 1) // Original + summary
152+
expect(result.messages.length).toBe(messages.length + 1) // Original + summary
146153

147154
// Check that the summary message was inserted correctly
148-
const summaryMessage = result[result.length - N_MESSAGES_TO_KEEP - 1]
155+
const summaryMessage = result.messages[result.messages.length - N_MESSAGES_TO_KEEP - 1]
149156
expect(summaryMessage.role).toBe("assistant")
150157
expect(summaryMessage.content).toBe("This is a summary")
151158
expect(summaryMessage.isSummary).toBe(true)
152159

153160
// Check that the last N_MESSAGES_TO_KEEP messages are preserved
154161
const lastMessages = messages.slice(-N_MESSAGES_TO_KEEP)
155-
expect(result.slice(-N_MESSAGES_TO_KEEP)).toEqual(lastMessages)
162+
expect(result.messages.slice(-N_MESSAGES_TO_KEEP)).toEqual(lastMessages)
163+
164+
// Check the cost and token counts
165+
expect(result.cost).toBe(0.05)
166+
expect(result.summary).toBe("This is a summary")
167+
expect(result.newContextTokens).toBe(250) // 150 output tokens + 100 from countTokens
156168
})
157169

158170
it("should handle empty summary response", async () => {
@@ -172,9 +184,10 @@ describe("summarizeConversation", () => {
172184
const mockWarn = jest.fn()
173185
console.warn = mockWarn
174186

175-
// Setup empty summary response
187+
// Setup empty summary response with usage information
176188
const emptyStream = (async function* () {
177189
yield { type: "text" as const, text: "" }
190+
yield { type: "usage" as const, totalCost: 0.02, outputTokens: 0 }
178191
})()
179192

180193
// Create a new mock for createMessage that returns empty stream
@@ -189,7 +202,10 @@ describe("summarizeConversation", () => {
189202
const result = await summarizeConversation(messages, mockApiHandler)
190203

191204
// Should return original messages when summary is empty
192-
expect(result).toEqual(messages)
205+
expect(result.messages).toEqual(messages)
206+
expect(result.cost).toBe(0.02)
207+
expect(result.summary).toBe("")
208+
expect(result.newContextTokens).toBe(100) // Only from countTokens since outputTokens is 0
193209
expect(mockWarn).toHaveBeenCalledWith("Received empty summary from API")
194210

195211
// Restore console.warn
@@ -225,4 +241,37 @@ describe("summarizeConversation", () => {
225241
const mockCallArgs = (maybeRemoveImageBlocks as jest.Mock).mock.calls[0][0] as any[]
226242
expect(mockCallArgs[mockCallArgs.length - 1]).toEqual(expectedFinalMessage)
227243
})
244+
245+
it("should calculate newContextTokens correctly with systemPrompt", async () => {
246+
const messages: ApiMessage[] = [
247+
{ role: "user", content: "Hello", ts: 1 },
248+
{ role: "assistant", content: "Hi there", ts: 2 },
249+
{ role: "user", content: "How are you?", ts: 3 },
250+
{ role: "assistant", content: "I'm good", ts: 4 },
251+
{ role: "user", content: "What's new?", ts: 5 },
252+
{ role: "assistant", content: "Not much", ts: 6 },
253+
{ role: "user", content: "Tell me more", ts: 7 },
254+
]
255+
256+
const systemPrompt = "You are a helpful assistant."
257+
258+
// Create a stream with usage information
259+
const streamWithUsage = (async function* () {
260+
yield { type: "text" as const, text: "This is a summary with system prompt" }
261+
yield { type: "usage" as const, totalCost: 0.06, outputTokens: 200 }
262+
})()
263+
264+
// Override the mock for this test
265+
mockApiHandler.createMessage = jest.fn().mockReturnValue(streamWithUsage) as any
266+
267+
const result = await summarizeConversation(messages, mockApiHandler, systemPrompt)
268+
269+
// Verify that countTokens was called with the correct messages including system prompt
270+
expect(mockApiHandler.countTokens).toHaveBeenCalled()
271+
272+
// Check the newContextTokens calculation includes system prompt
273+
expect(result.newContextTokens).toBe(300) // 200 output tokens + 100 from countTokens
274+
expect(result.cost).toBe(0.06)
275+
expect(result.summary).toBe("This is a summary with system prompt")
276+
})
228277
})

0 commit comments

Comments
 (0)