@@ -4,12 +4,12 @@ import { Readable } from 'node:stream';
44
55import { DisposableStore } from '#/_base/di/lifecycle' ;
66import { createServices } from '#/_base/di/test' ;
7- import { Event } from '#/_base/event' ;
7+ import { Emitter , Event } from '#/_base/event' ;
88import { IAgentBlobService } from '#/agent/blob/agentBlobService' ;
99import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory' ;
1010import type { ContextMessage } from '#/agent/contextMemory/types' ;
1111import type { ContentPart } from '#/kosong/contract/message' ;
12- import { IAgentFullCompactionService } from '#/agent/fullCompaction/fullCompaction' ;
12+ import { IAgentFullCompactionService , type FullCompactionTask } from '#/agent/fullCompaction/fullCompaction' ;
1313import { IAgentLoopService } from '#/agent/loop/loop' ;
1414import { TurnSteer } from '#/agent/loop/turnOps' ;
1515import { IAgentPromptService } from '#/agent/prompt/prompt' ;
@@ -74,13 +74,19 @@ function harness(loopOptions: StubLoopOptions = { pendingTurnResult: true }) {
7474 } ,
7575 } ) ;
7676 const loop = stubLoopWithHooks ( loopOptions ) ;
77- const fullCompaction = {
77+ let activeTask : FullCompactionTask | null = null ;
78+ const finishCompactionEmitter = new Emitter < FullCompactionTask > ( ) ;
79+ disposables . add ( finishCompactionEmitter ) ;
80+ const fullCompaction : IAgentFullCompactionService = {
7881 _serviceBrand : undefined ,
79- compacting : null ,
82+ get compacting ( ) {
83+ return activeTask ;
84+ } ,
8085 begin : ( ) => false ,
86+ cancel : ( ) => { } ,
8187 hooks : createHooks ( [ 'onWillCompact' ] ) ,
82- onDidFinishCompaction : Event . None ,
83- } as unknown as IAgentFullCompactionService ;
88+ onDidFinishCompaction : finishCompactionEmitter . event ,
89+ } ;
8490 const intake = {
8591 get : vi . fn ( async ( ) => ( {
8692 meta : {
@@ -124,7 +130,21 @@ function harness(loopOptions: StubLoopOptions = { pendingTurnResult: true }) {
124130 ( ix . get ( IEventBus ) as ISessionEventBus ) . activateAgent (
125131 ix . get ( IAgentScopeContext ) . agentContext ,
126132 ) ;
127- return { prompt : ix . get ( IAgentPromptService ) , loop, context, fullCompaction, eventBus : ix . get ( IEventBus ) , intake } ;
133+ return {
134+ prompt : ix . get ( IAgentPromptService ) ,
135+ loop,
136+ context,
137+ fullCompaction,
138+ eventBus : ix . get ( IEventBus ) ,
139+ intake,
140+ setCompacting : ( task : FullCompactionTask | null ) => {
141+ activeTask = task ;
142+ } ,
143+ finishCompaction : ( task : FullCompactionTask ) => {
144+ activeTask = null ;
145+ finishCompactionEmitter . fire ( task ) ;
146+ } ,
147+ } ;
128148}
129149
130150describe ( 'AgentPromptService' , ( ) => {
@@ -305,14 +325,23 @@ describe('AgentPromptService', () => {
305325 } ) ;
306326
307327 it ( 'parks a queued prompt while compaction runs instead of recursing' , async ( ) => {
308- const { prompt, fullCompaction } = harness ( ) ;
309- ( fullCompaction as unknown as { compacting : unknown } ) . compacting = { promise : new Promise ( ( ) => { } ) , abortController : new AbortController ( ) } ;
328+ const { prompt, setCompacting, finishCompaction } = harness ( ) ;
329+ const task : FullCompactionTask = {
330+ promise : new Promise ( ( ) => { } ) ,
331+ abortController : new AbortController ( ) ,
332+ trigger : 'manual' ,
333+ tokenCount : 100 ,
334+ } ;
335+ setCompacting ( task ) ;
310336 const handle = await prompt . enqueue ( { id : 'parked' , message : message ( 'later' ) } ) ;
311337 expect ( handle . state ) . toBe ( 'pending' ) ;
312- await ( prompt as unknown as { startNext ( ) : Promise < void > } ) . startNext ( ) ;
313- await ( prompt as unknown as { startNext ( ) : Promise < void > } ) . startNext ( ) ;
314338 expect ( prompt . list ( ) . pending . map ( ( item ) => item . id ) ) . toEqual ( [ 'parked' ] ) ;
315339 expect ( prompt . list ( ) . active ) . toBeUndefined ( ) ;
340+
341+ finishCompaction ( task ) ;
342+ await expect ( handle . launched ) . resolves . toBeDefined ( ) ;
343+ expect ( prompt . list ( ) . pending ) . toEqual ( [ ] ) ;
344+ expect ( prompt . list ( ) . active ?. id ) . toBe ( 'parked' ) ;
316345 } ) ;
317346
318347 it ( 'aborts pending prompts and settles completion' , async ( ) => {
0 commit comments