@@ -14,18 +14,21 @@ vi.mock("./commands-compact.runtime.js", () => ({
1414 formatContextUsageShort : vi . fn ( ( ) => "Context 12.1k" ) ,
1515 formatTokenCount : vi . fn ( ( value : number ) => `${ value } ` ) ,
1616 incrementCompactionCount : vi . fn ( ) ,
17- isEmbeddedAgentRunActive : vi . fn ( ) . mockReturnValue ( false ) ,
17+ isEmbeddedAgentRunAbortableForCompaction : vi . fn ( ) . mockReturnValue ( false ) ,
1818 resolveFreshSessionTotalTokens : vi . fn ( ( ) => 12_345 ) ,
1919 resolveSessionFilePath : vi . fn ( ( ) => "/tmp/session.json" ) ,
2020 resolveSessionFilePathOptions : vi . fn ( ( ) => ( { } ) ) ,
2121 waitForEmbeddedAgentRunEnd : vi . fn ( ) . mockResolvedValue ( undefined ) ,
2222} ) ) ;
2323
2424const {
25+ abortEmbeddedAgentRun,
2526 compactEmbeddedAgentSession,
2627 formatContextUsageShort,
2728 incrementCompactionCount,
29+ isEmbeddedAgentRunAbortableForCompaction,
2830 resolveSessionFilePathOptions,
31+ waitForEmbeddedAgentRunEnd,
2932} = await import ( "./commands-compact.runtime.js" ) ;
3033const { handleCompactCommand } = await import ( "./commands-compact.js" ) ;
3134
@@ -191,6 +194,62 @@ describe("handleCompactCommand", () => {
191194 expect ( call . senderE164 ) . toBe ( "+15551234567" ) ;
192195 expect ( call . agentDir ) . toBe ( "/tmp/openclaw-agent-compact" ) ;
193196 expect ( call . authProfileId ) . toBe ( "github-copilot:work" ) ;
197+ expect ( vi . mocked ( abortEmbeddedAgentRun ) ) . not . toHaveBeenCalled ( ) ;
198+ expect ( vi . mocked ( waitForEmbeddedAgentRunEnd ) ) . not . toHaveBeenCalled ( ) ;
199+ } ) ;
200+
201+ it ( "does not abort the command reply run before compacting" , async ( ) => {
202+ vi . mocked ( isEmbeddedAgentRunAbortableForCompaction ) . mockReturnValueOnce ( false ) ;
203+ vi . mocked ( compactEmbeddedAgentSession ) . mockResolvedValueOnce ( {
204+ ok : true ,
205+ compacted : false ,
206+ } ) ;
207+
208+ const result = await handleCompactCommand (
209+ {
210+ ...buildCompactParams ( "/compact" , {
211+ commands : { text : true } ,
212+ channels : { whatsapp : { allowFrom : [ "*" ] } } ,
213+ } as OpenClawConfig ) ,
214+ sessionEntry : {
215+ sessionId : "session-1" ,
216+ updatedAt : Date . now ( ) ,
217+ } ,
218+ } as HandleCommandsParams ,
219+ true ,
220+ ) ;
221+
222+ expect ( result ?. shouldContinue ) . toBe ( false ) ;
223+ expect ( vi . mocked ( isEmbeddedAgentRunAbortableForCompaction ) ) . toHaveBeenCalledWith ( "session-1" ) ;
224+ expect ( vi . mocked ( abortEmbeddedAgentRun ) ) . not . toHaveBeenCalled ( ) ;
225+ expect ( vi . mocked ( waitForEmbeddedAgentRunEnd ) ) . not . toHaveBeenCalled ( ) ;
226+ expect ( vi . mocked ( compactEmbeddedAgentSession ) ) . toHaveBeenCalledOnce ( ) ;
227+ } ) ;
228+
229+ it ( "aborts an active embedded run before compacting" , async ( ) => {
230+ vi . mocked ( isEmbeddedAgentRunAbortableForCompaction ) . mockReturnValueOnce ( true ) ;
231+ vi . mocked ( compactEmbeddedAgentSession ) . mockResolvedValueOnce ( {
232+ ok : true ,
233+ compacted : false ,
234+ } ) ;
235+
236+ await handleCompactCommand (
237+ {
238+ ...buildCompactParams ( "/compact" , {
239+ commands : { text : true } ,
240+ channels : { whatsapp : { allowFrom : [ "*" ] } } ,
241+ } as OpenClawConfig ) ,
242+ sessionEntry : {
243+ sessionId : "session-1" ,
244+ updatedAt : Date . now ( ) ,
245+ } ,
246+ } as HandleCommandsParams ,
247+ true ,
248+ ) ;
249+
250+ expect ( vi . mocked ( abortEmbeddedAgentRun ) ) . toHaveBeenCalledWith ( "session-1" ) ;
251+ expect ( vi . mocked ( waitForEmbeddedAgentRunEnd ) ) . toHaveBeenCalledWith ( "session-1" , 15_000 ) ;
252+ expect ( vi . mocked ( compactEmbeddedAgentSession ) ) . toHaveBeenCalledOnce ( ) ;
194253 } ) ;
195254
196255 it ( "treats already-under-target manual compaction as skipped" , async ( ) => {
0 commit comments