@@ -26,6 +26,87 @@ const useTwoAuthProfiles = () => {
2626 } ) ) ;
2727} ;
2828
29+ type CompactRuntimeContext = {
30+ promptCache ?: {
31+ retention ?: string ;
32+ lastCallUsage ?: {
33+ input ?: number ;
34+ cacheRead ?: number ;
35+ } ;
36+ observation ?: {
37+ broke ?: boolean ;
38+ cacheRead ?: number ;
39+ } ;
40+ lastCacheTouchAt ?: number ;
41+ } ;
42+ trigger ?: string ;
43+ attempt ?: number ;
44+ maxAttempts ?: number ;
45+ messageChannel ?: string ;
46+ messageProvider ?: string ;
47+ agentAccountId ?: string ;
48+ currentChannelId ?: string ;
49+ currentThreadTs ?: string ;
50+ currentMessageId ?: string ;
51+ senderId ?: string ;
52+ senderIsOwner ?: boolean ;
53+ authProfileId ?: string ;
54+ } ;
55+
56+ type CompactParams = {
57+ sessionId ?: string ;
58+ sessionFile ?: string ;
59+ tokenBudget ?: number ;
60+ force ?: boolean ;
61+ compactionTarget ?: string ;
62+ runtimeContext ?: CompactRuntimeContext ;
63+ } ;
64+
65+ type AttemptParams = {
66+ sessionId ?: string ;
67+ sessionFile ?: string ;
68+ authProfileId ?: string ;
69+ } ;
70+
71+ type HookEvent = {
72+ messageCount ?: number ;
73+ compactedCount ?: number ;
74+ tokenCount ?: number ;
75+ sessionFile ?: string ;
76+ } ;
77+
78+ type HookContext = {
79+ sessionKey ?: string ;
80+ } ;
81+
82+ function compactCallAt ( index : number ) : CompactParams {
83+ const call = mockedCompactDirect . mock . calls [ index ] ;
84+ if ( ! call ) {
85+ throw new Error ( `expected compact call ${ index + 1 } ` ) ;
86+ }
87+ return call [ 0 ] as CompactParams ;
88+ }
89+
90+ function attemptCallAt ( index : number ) : AttemptParams {
91+ const call = mockedRunEmbeddedAttempt . mock . calls [ index ] ;
92+ if ( ! call ) {
93+ throw new Error ( `expected embedded attempt call ${ index + 1 } ` ) ;
94+ }
95+ return call [ 0 ] as AttemptParams ;
96+ }
97+
98+ function hookCallAt ( index : number , kind : "before" | "after" ) : [ HookEvent , HookContext ] {
99+ const mock =
100+ kind === "before"
101+ ? mockedGlobalHookRunner . runBeforeCompaction
102+ : mockedGlobalHookRunner . runAfterCompaction ;
103+ const call = mock . mock . calls [ index ] ;
104+ if ( ! call ) {
105+ throw new Error ( `expected ${ kind } compaction hook call ${ index + 1 } ` ) ;
106+ }
107+ return call as unknown as [ HookEvent , HookContext ] ;
108+ }
109+
29110describe ( "timeout-triggered compaction" , ( ) => {
30111 beforeAll ( async ( ) => {
31112 ( { runEmbeddedPiAgent } = await loadRunOverflowCompactionHarness ( ) ) ;
@@ -72,32 +153,21 @@ describe("timeout-triggered compaction", () => {
72153 const result = await runEmbeddedPiAgent ( overflowBaseRunParams ) ;
73154
74155 expect ( mockedCompactDirect ) . toHaveBeenCalledTimes ( 1 ) ;
75- expect ( mockedCompactDirect ) . toHaveBeenCalledWith (
76- expect . objectContaining ( {
77- sessionId : "test-session" ,
78- sessionFile : "/tmp/session.json" ,
79- tokenBudget : 200000 ,
80- force : true ,
81- compactionTarget : "budget" ,
82- runtimeContext : expect . objectContaining ( {
83- promptCache : expect . objectContaining ( {
84- retention : "short" ,
85- lastCallUsage : expect . objectContaining ( {
86- input : 150000 ,
87- cacheRead : 32000 ,
88- } ) ,
89- observation : expect . objectContaining ( {
90- broke : false ,
91- cacheRead : 32000 ,
92- } ) ,
93- lastCacheTouchAt : 1_700_000_000_000 ,
94- } ) ,
95- trigger : "timeout_recovery" ,
96- attempt : 1 ,
97- maxAttempts : 2 ,
98- } ) ,
99- } ) ,
100- ) ;
156+ const compactParams = compactCallAt ( 0 ) ;
157+ expect ( compactParams . sessionId ) . toBe ( "test-session" ) ;
158+ expect ( compactParams . sessionFile ) . toBe ( "/tmp/session.json" ) ;
159+ expect ( compactParams . tokenBudget ) . toBe ( 200000 ) ;
160+ expect ( compactParams . force ) . toBe ( true ) ;
161+ expect ( compactParams . compactionTarget ) . toBe ( "budget" ) ;
162+ expect ( compactParams . runtimeContext ?. promptCache ?. retention ) . toBe ( "short" ) ;
163+ expect ( compactParams . runtimeContext ?. promptCache ?. lastCallUsage ?. input ) . toBe ( 150000 ) ;
164+ expect ( compactParams . runtimeContext ?. promptCache ?. lastCallUsage ?. cacheRead ) . toBe ( 32000 ) ;
165+ expect ( compactParams . runtimeContext ?. promptCache ?. observation ?. broke ) . toBe ( false ) ;
166+ expect ( compactParams . runtimeContext ?. promptCache ?. observation ?. cacheRead ) . toBe ( 32000 ) ;
167+ expect ( compactParams . runtimeContext ?. promptCache ?. lastCacheTouchAt ) . toBe ( 1_700_000_000_000 ) ;
168+ expect ( compactParams . runtimeContext ?. trigger ) . toBe ( "timeout_recovery" ) ;
169+ expect ( compactParams . runtimeContext ?. attempt ) . toBe ( 1 ) ;
170+ expect ( compactParams . runtimeContext ?. maxAttempts ) . toBe ( 2 ) ;
101171 expect ( mockedRunEmbeddedAttempt ) . toHaveBeenCalledTimes ( 2 ) ;
102172 expect ( result . meta . error ) . toBeUndefined ( ) ;
103173 expect ( result . meta . agentMeta ?. compactionTokensAfter ) . toBe ( 80_000 ) ;
@@ -136,13 +206,9 @@ describe("timeout-triggered compaction", () => {
136206
137207 // Verify the loop continued (retry happened)
138208 expect ( mockedRunEmbeddedAttempt ) . toHaveBeenCalledTimes ( 2 ) ;
139- expect ( mockedRunEmbeddedAttempt ) . toHaveBeenNthCalledWith (
140- 2 ,
141- expect . objectContaining ( {
142- sessionId : "timeout-rotated-session" ,
143- sessionFile : "/tmp/timeout-rotated-session.json" ,
144- } ) ,
145- ) ;
209+ const retryParams = attemptCallAt ( 1 ) ;
210+ expect ( retryParams . sessionId ) . toBe ( "timeout-rotated-session" ) ;
211+ expect ( retryParams . sessionFile ) . toBe ( "/tmp/timeout-rotated-session.json" ) ;
146212 expect ( mockedRunPostCompactionSideEffects ) . not . toHaveBeenCalled ( ) ;
147213 expect ( result . meta . error ) . toBeUndefined ( ) ;
148214 } ) ;
@@ -177,20 +243,16 @@ describe("timeout-triggered compaction", () => {
177243 senderIsOwner : true ,
178244 } ) ;
179245
180- expect ( mockedCompactDirect ) . toHaveBeenCalledWith (
181- expect . objectContaining ( {
182- runtimeContext : expect . objectContaining ( {
183- messageChannel : "slack" ,
184- messageProvider : "slack" ,
185- agentAccountId : "acct-1" ,
186- currentChannelId : "channel-1" ,
187- currentThreadTs : "thread-1" ,
188- currentMessageId : "message-1" ,
189- senderId : "sender-1" ,
190- senderIsOwner : true ,
191- } ) ,
192- } ) ,
193- ) ;
246+ expect ( mockedCompactDirect ) . toHaveBeenCalledTimes ( 1 ) ;
247+ const compactParams = compactCallAt ( 0 ) ;
248+ expect ( compactParams . runtimeContext ?. messageChannel ) . toBe ( "slack" ) ;
249+ expect ( compactParams . runtimeContext ?. messageProvider ) . toBe ( "slack" ) ;
250+ expect ( compactParams . runtimeContext ?. agentAccountId ) . toBe ( "acct-1" ) ;
251+ expect ( compactParams . runtimeContext ?. currentChannelId ) . toBe ( "channel-1" ) ;
252+ expect ( compactParams . runtimeContext ?. currentThreadTs ) . toBe ( "thread-1" ) ;
253+ expect ( compactParams . runtimeContext ?. currentMessageId ) . toBe ( "message-1" ) ;
254+ expect ( compactParams . runtimeContext ?. senderId ) . toBe ( "sender-1" ) ;
255+ expect ( compactParams . runtimeContext ?. senderIsOwner ) . toBe ( true ) ;
194256 } ) ;
195257
196258 it ( "falls through to normal handling when timeout compaction fails" , async ( ) => {
@@ -448,23 +510,17 @@ describe("timeout-triggered compaction", () => {
448510
449511 await runEmbeddedPiAgent ( overflowBaseRunParams ) ;
450512
451- expect ( mockedGlobalHookRunner . runBeforeCompaction ) . toHaveBeenCalledWith (
452- { messageCount : - 1 , sessionFile : "/tmp/session.json" } ,
453- expect . objectContaining ( {
454- sessionKey : "test-key" ,
455- } ) ,
456- ) ;
457- expect ( mockedGlobalHookRunner . runAfterCompaction ) . toHaveBeenCalledWith (
458- {
459- messageCount : - 1 ,
460- compactedCount : - 1 ,
461- tokenCount : 70 ,
462- sessionFile : "/tmp/session.json" ,
463- } ,
464- expect . objectContaining ( {
465- sessionKey : "test-key" ,
466- } ) ,
467- ) ;
513+ const [ beforeEvent , beforeContext ] = hookCallAt ( 0 , "before" ) ;
514+ expect ( beforeEvent ) . toEqual ( { messageCount : - 1 , sessionFile : "/tmp/session.json" } ) ;
515+ expect ( beforeContext . sessionKey ) . toBe ( "test-key" ) ;
516+ const [ afterEvent , afterContext ] = hookCallAt ( 0 , "after" ) ;
517+ expect ( afterEvent ) . toEqual ( {
518+ messageCount : - 1 ,
519+ compactedCount : - 1 ,
520+ tokenCount : 70 ,
521+ sessionFile : "/tmp/session.json" ,
522+ } ) ;
523+ expect ( afterContext . sessionKey ) . toBe ( "test-key" ) ;
468524 expect ( mockedRunPostCompactionSideEffects ) . toHaveBeenCalledTimes ( 1 ) ;
469525 } ) ;
470526
@@ -506,26 +562,14 @@ describe("timeout-triggered compaction", () => {
506562 const result = await runEmbeddedPiAgent ( overflowBaseRunParams ) ;
507563
508564 expect ( mockedCompactDirect ) . toHaveBeenCalledTimes ( 2 ) ;
509- expect ( mockedCompactDirect ) . toHaveBeenNthCalledWith (
510- 1 ,
511- expect . objectContaining ( {
512- runtimeContext : expect . objectContaining ( {
513- authProfileId : "profile-a" ,
514- attempt : 1 ,
515- maxAttempts : 2 ,
516- } ) ,
517- } ) ,
518- ) ;
519- expect ( mockedCompactDirect ) . toHaveBeenNthCalledWith (
520- 2 ,
521- expect . objectContaining ( {
522- runtimeContext : expect . objectContaining ( {
523- authProfileId : "profile-b" ,
524- attempt : 2 ,
525- maxAttempts : 2 ,
526- } ) ,
527- } ) ,
528- ) ;
565+ const firstCompact = compactCallAt ( 0 ) ;
566+ expect ( firstCompact . runtimeContext ?. authProfileId ) . toBe ( "profile-a" ) ;
567+ expect ( firstCompact . runtimeContext ?. attempt ) . toBe ( 1 ) ;
568+ expect ( firstCompact . runtimeContext ?. maxAttempts ) . toBe ( 2 ) ;
569+ const secondCompact = compactCallAt ( 1 ) ;
570+ expect ( secondCompact . runtimeContext ?. authProfileId ) . toBe ( "profile-b" ) ;
571+ expect ( secondCompact . runtimeContext ?. attempt ) . toBe ( 2 ) ;
572+ expect ( secondCompact . runtimeContext ?. maxAttempts ) . toBe ( 2 ) ;
529573 expect ( mockedRunEmbeddedAttempt ) . toHaveBeenCalledTimes ( 2 ) ;
530574 expect ( result . payloads ?. [ 0 ] ?. isError ) . toBe ( true ) ;
531575 expect ( result . payloads ?. [ 0 ] ?. text ) . toContain ( "timed out" ) ;
@@ -562,14 +606,8 @@ describe("timeout-triggered compaction", () => {
562606
563607 expect ( mockedCompactDirect ) . toHaveBeenCalledTimes ( 2 ) ;
564608 expect ( mockedRunEmbeddedAttempt ) . toHaveBeenCalledTimes ( 2 ) ;
565- expect ( mockedRunEmbeddedAttempt ) . toHaveBeenNthCalledWith (
566- 1 ,
567- expect . objectContaining ( { authProfileId : "profile-a" } ) ,
568- ) ;
569- expect ( mockedRunEmbeddedAttempt ) . toHaveBeenNthCalledWith (
570- 2 ,
571- expect . objectContaining ( { authProfileId : "profile-b" } ) ,
572- ) ;
609+ expect ( attemptCallAt ( 0 ) . authProfileId ) . toBe ( "profile-a" ) ;
610+ expect ( attemptCallAt ( 1 ) . authProfileId ) . toBe ( "profile-b" ) ;
573611 expect ( result . payloads ?. [ 0 ] ?. isError ) . toBe ( true ) ;
574612 expect ( result . payloads ?. [ 0 ] ?. text ) . toContain ( "timed out" ) ;
575613 } ) ;
0 commit comments