11import fs from "node:fs/promises" ;
22import os from "node:os" ;
33import path from "node:path" ;
4+ import type { AgentMessage } from "@mariozechner/pi-agent-core" ;
5+ import type { AssistantMessage } from "@mariozechner/pi-ai" ;
46import { SessionManager } from "@mariozechner/pi-coding-agent" ;
57import { afterEach , describe , expect , it } from "vitest" ;
68import { hardenManualCompactionBoundary } from "./manual-compaction-boundary.js" ;
@@ -19,7 +21,36 @@ afterEach(async () => {
1921 }
2022} ) ;
2123
22- function messageText ( message : { content ?: unknown } ) : string {
24+ function createAssistantTextMessage ( text : string , timestamp : number ) : AssistantMessage {
25+ return {
26+ role : "assistant" ,
27+ content : [ { type : "text" , text } ] ,
28+ api : "responses" ,
29+ provider : "openai" ,
30+ model : "gpt-test" ,
31+ usage : {
32+ input : 1 ,
33+ output : 1 ,
34+ cacheRead : 0 ,
35+ cacheWrite : 0 ,
36+ totalTokens : 2 ,
37+ cost : {
38+ input : 0 ,
39+ output : 0 ,
40+ cacheRead : 0 ,
41+ cacheWrite : 0 ,
42+ total : 0 ,
43+ } ,
44+ } ,
45+ stopReason : "stop" ,
46+ timestamp,
47+ } ;
48+ }
49+
50+ function messageText ( message : AgentMessage ) : string {
51+ if ( ! ( "content" in message ) ) {
52+ return "" ;
53+ }
2354 const content = message . content ;
2455 if ( typeof content === "string" ) {
2556 return content ;
@@ -43,21 +74,15 @@ describe("hardenManualCompactionBoundary", () => {
4374 const session = SessionManager . create ( dir , dir ) ;
4475
4576 session . appendMessage ( { role : "user" , content : "old question" , timestamp : 1 } ) ;
46- session . appendMessage ( {
47- role : "assistant" ,
48- content : [ { type : "text" , text : "very long old answer" } ] ,
49- timestamp : 2 ,
50- } ) ;
77+ session . appendMessage ( createAssistantTextMessage ( "very long old answer" , 2 ) ) ;
5178 const firstKeepId = session . getBranch ( ) . at ( - 1 ) ?. id ;
5279 expect ( firstKeepId ) . toBeTruthy ( ) ;
5380 session . appendCompaction ( "old summary" , firstKeepId ! , 100 ) ;
5481
5582 session . appendMessage ( { role : "user" , content : "new question" , timestamp : 3 } ) ;
56- session . appendMessage ( {
57- role : "assistant" ,
58- content : [ { type : "text" , text : "detailed new answer that should be summarized away" } ] ,
59- timestamp : 4 ,
60- } ) ;
83+ session . appendMessage (
84+ createAssistantTextMessage ( "detailed new answer that should be summarized away" , 4 ) ,
85+ ) ;
6186 const secondKeepId = session . getBranch ( ) . at ( - 1 ) ?. id ;
6287 expect ( secondKeepId ) . toBeTruthy ( ) ;
6388 const latestCompactionId = session . appendCompaction ( "fresh summary" , secondKeepId ! , 200 ) ;
@@ -78,7 +103,10 @@ describe("hardenManualCompactionBoundary", () => {
78103 const reopened = SessionManager . open ( sessionFile ! ) ;
79104 const latest = reopened . getLeafEntry ( ) ;
80105 expect ( latest ?. type ) . toBe ( "compaction" ) ;
81- expect ( latest ?. firstKeptEntryId ) . toBe ( latestCompactionId ) ;
106+ if ( ! latest || latest . type !== "compaction" ) {
107+ throw new Error ( "expected latest leaf to be a compaction entry" ) ;
108+ }
109+ expect ( latest . firstKeptEntryId ) . toBe ( latestCompactionId ) ;
82110
83111 reopened . appendMessage ( { role : "user" , content : "what was happening?" , timestamp : 5 } ) ;
84112 const after = SessionManager . open ( sessionFile ! ) ;
@@ -94,11 +122,7 @@ describe("hardenManualCompactionBoundary", () => {
94122 const dir = await makeTmpDir ( ) ;
95123 const session = SessionManager . create ( dir , dir ) ;
96124 session . appendMessage ( { role : "user" , content : "hello" , timestamp : 1 } ) ;
97- session . appendMessage ( {
98- role : "assistant" ,
99- content : [ { type : "text" , text : "hi" } ] ,
100- timestamp : 2 ,
101- } ) ;
125+ session . appendMessage ( createAssistantTextMessage ( "hi" , 2 ) ) ;
102126 const sessionFile = session . getSessionFile ( ) ;
103127 expect ( sessionFile ) . toBeTruthy ( ) ;
104128
0 commit comments