@@ -273,6 +273,74 @@ describe("runCliTurnCompactionLifecycle", () => {
273273 ) ;
274274 } ) ;
275275
276+ it ( "treats already-compacted CLI transcript compaction as a no-op" , async ( ) => {
277+ const sessionKey = "agent:main:qwen-already-compacted" ;
278+ const sessionId = "session-qwen-already-compacted" ;
279+ const sessionFile = path . join ( tmpDir , "session-qwen-already-compacted.jsonl" ) ;
280+ const storePath = path . join ( tmpDir , "sessions-qwen-already-compacted.json" ) ;
281+ await writeSessionFile ( { sessionFile, sessionId } ) ;
282+
283+ const sessionEntry : SessionEntry = {
284+ sessionId,
285+ updatedAt : Date . now ( ) ,
286+ sessionFile,
287+ contextTokens : 1_000 ,
288+ totalTokens : 950 ,
289+ totalTokensFresh : true ,
290+ } ;
291+ const sessionStore : Record < string , SessionEntry > = { [ sessionKey ] : sessionEntry } ;
292+ await fs . writeFile ( storePath , JSON . stringify ( sessionStore , null , 2 ) , "utf-8" ) ;
293+
294+ const compactCalls : Array < Parameters < ContextEngine [ "compact" ] > [ 0 ] > = [ ] ;
295+ const maintenance = vi . fn ( async ( ) => ( { changed : false , bytesFreed : 0 , rewrittenEntries : 0 } ) ) ;
296+ const recordCliCompactionInStore = vi . fn ( ) ;
297+ setCliCompactionTestDeps ( {
298+ resolveContextEngine : async ( ) => ( {
299+ ...buildContextEngine ( { compactCalls } ) ,
300+ async compact ( compactParams ) {
301+ compactCalls . push ( compactParams ) ;
302+ throw new Error ( "Already compacted" ) ;
303+ } ,
304+ } ) ,
305+ createPreparedEmbeddedAgentSettingsManager : async ( ) => ( {
306+ getCompactionReserveTokens : ( ) => 200 ,
307+ getCompactionKeepRecentTokens : ( ) => 0 ,
308+ applyOverrides : ( ) => { } ,
309+ } ) ,
310+ shouldPreemptivelyCompactBeforePrompt : ( ) => ( {
311+ route : "fits" ,
312+ shouldCompact : false ,
313+ estimatedPromptTokens : 600 ,
314+ promptBudgetBeforeReserve : 800 ,
315+ overflowTokens : 0 ,
316+ toolResultReducibleChars : 0 ,
317+ effectiveReserveTokens : 200 ,
318+ } ) ,
319+ resolveLiveToolResultMaxChars : ( ) => 20_000 ,
320+ runContextEngineMaintenance : maintenance ,
321+ recordCliCompactionInStore,
322+ } ) ;
323+
324+ const updatedEntry = await runCliTurnCompactionLifecycle ( {
325+ cfg : { } as OpenClawConfig ,
326+ sessionId,
327+ sessionKey,
328+ sessionEntry,
329+ sessionStore,
330+ storePath,
331+ sessionAgentId : "main" ,
332+ workspaceDir : tmpDir ,
333+ agentDir : tmpDir ,
334+ provider : "ollama" ,
335+ model : "qwen3:14b" ,
336+ } ) ;
337+
338+ expect ( compactCalls ) . toHaveLength ( 1 ) ;
339+ expect ( maintenance ) . not . toHaveBeenCalled ( ) ;
340+ expect ( recordCliCompactionInStore ) . not . toHaveBeenCalled ( ) ;
341+ expect ( updatedEntry ) . toBe ( sessionEntry ) ;
342+ } ) ;
343+
276344 it ( "routes OpenAI Codex harness CLI compaction through native harness compaction" , async ( ) => {
277345 const sessionKey = "agent:main:codex" ;
278346 const sessionId = "session-codex" ;
0 commit comments