@@ -106,6 +106,10 @@ type CompactEmbeddedAgentSessionParams = {
106106 sandboxSessionKey ?: string ;
107107 currentTokenCount ?: number ;
108108 cwd ?: string ;
109+ force ?: boolean ;
110+ forcePreflight ?: boolean ;
111+ preflightRequired ?: boolean ;
112+ preflightCompactionTrigger ?: string ;
109113 sessionFile ?: string ;
110114 sessionId ?: string ;
111115 trigger ?: string ;
@@ -999,6 +1003,10 @@ describe("runMemoryFlushIfNeeded", () => {
9991003 expect ( compactEmbeddedAgentSessionMock ) . toHaveBeenCalledTimes ( 1 ) ;
10001004 expect ( requireCompactEmbeddedAgentSessionCall ( ) ) . toMatchObject ( {
10011005 trigger : "budget" ,
1006+ force : true ,
1007+ forcePreflight : true ,
1008+ preflightRequired : true ,
1009+ preflightCompactionTrigger : "tokens" ,
10021010 deferOwningContextEngineCompaction : false ,
10031011 contextTokenBudget : 100 ,
10041012 } ) ;
@@ -1112,7 +1120,7 @@ describe("runMemoryFlushIfNeeded", () => {
11121120 [ "stale_thread_binding" , "thread not found: <codex-thread-id>" ] ,
11131121 [ "missing_thread_binding" , "no thread binding for session" ] ,
11141122 ] ) (
1115- "continues after recoverable native harness %s failure during preflight compaction " ,
1123+ "fails required preflight compaction after native harness %s failure" ,
11161124 async ( failureReason , reason ) => {
11171125 const sessionFile = path . join ( rootDir , "session.jsonl" ) ;
11181126 await fs . writeFile (
@@ -1143,30 +1151,31 @@ describe("runMemoryFlushIfNeeded", () => {
11431151 } ;
11441152 const sessionStore = { "agent:main:telegram:group:redacted" : sessionEntry } ;
11451153
1146- const entry = await runPreflightCompactionIfNeeded ( {
1147- cfg : { agents : { defaults : { compaction : { memoryFlush : { } } } } } ,
1148- followupRun : createTestFollowupRun ( {
1149- sessionId : "session" ,
1150- sessionFile,
1154+ await expect (
1155+ runPreflightCompactionIfNeeded ( {
1156+ cfg : { agents : { defaults : { compaction : { memoryFlush : { } } } } } ,
1157+ followupRun : createTestFollowupRun ( {
1158+ sessionId : "session" ,
1159+ sessionFile,
1160+ sessionKey : "agent:main:telegram:group:redacted" ,
1161+ } ) ,
1162+ defaultModel : "anthropic/claude-opus-4-6" ,
1163+ agentCfgContextTokens : 100 ,
1164+ sessionEntry,
1165+ sessionStore,
11511166 sessionKey : "agent:main:telegram:group:redacted" ,
1167+ storePath : path . join ( rootDir , "sessions.json" ) ,
1168+ isHeartbeat : false ,
1169+ replyOperation : createReplyOperation ( ) ,
11521170 } ) ,
1153- defaultModel : "anthropic/claude-opus-4-6" ,
1154- agentCfgContextTokens : 100 ,
1155- sessionEntry,
1156- sessionStore,
1157- sessionKey : "agent:main:telegram:group:redacted" ,
1158- storePath : path . join ( rootDir , "sessions.json" ) ,
1159- isHeartbeat : false ,
1160- replyOperation : createReplyOperation ( ) ,
1161- } ) ;
1171+ ) . rejects . toThrow ( `Preflight compaction required but failed: ${ reason } ` ) ;
11621172
1163- expect ( entry ) . toBe ( sessionEntry ) ;
11641173 expect ( compactEmbeddedAgentSessionMock ) . toHaveBeenCalledTimes ( 1 ) ;
11651174 expect ( incrementCompactionCountMock ) . not . toHaveBeenCalled ( ) ;
11661175 } ,
11671176 ) ;
11681177
1169- it ( "continues after an unstructured thread-not-found preflight compaction failure" , async ( ) => {
1178+ it ( "fails required preflight compaction after an unstructured thread-not-found failure" , async ( ) => {
11701179 const sessionFile = path . join ( rootDir , "session.jsonl" ) ;
11711180 await fs . writeFile (
11721181 sessionFile ,
@@ -1195,24 +1204,27 @@ describe("runMemoryFlushIfNeeded", () => {
11951204 } ;
11961205 const sessionStore = { "agent:main:telegram:group:redacted" : sessionEntry } ;
11971206
1198- const entry = await runPreflightCompactionIfNeeded ( {
1199- cfg : { agents : { defaults : { compaction : { memoryFlush : { } } } } } ,
1200- followupRun : createTestFollowupRun ( {
1201- sessionId : "session" ,
1202- sessionFile,
1207+ await expect (
1208+ runPreflightCompactionIfNeeded ( {
1209+ cfg : { agents : { defaults : { compaction : { memoryFlush : { } } } } } ,
1210+ followupRun : createTestFollowupRun ( {
1211+ sessionId : "session" ,
1212+ sessionFile,
1213+ sessionKey : "agent:main:telegram:group:redacted" ,
1214+ } ) ,
1215+ defaultModel : "anthropic/claude-opus-4-6" ,
1216+ agentCfgContextTokens : 100 ,
1217+ sessionEntry,
1218+ sessionStore,
12031219 sessionKey : "agent:main:telegram:group:redacted" ,
1220+ storePath : path . join ( rootDir , "sessions.json" ) ,
1221+ isHeartbeat : false ,
1222+ replyOperation : createReplyOperation ( ) ,
12041223 } ) ,
1205- defaultModel : "anthropic/claude-opus-4-6" ,
1206- agentCfgContextTokens : 100 ,
1207- sessionEntry,
1208- sessionStore,
1209- sessionKey : "agent:main:telegram:group:redacted" ,
1210- storePath : path . join ( rootDir , "sessions.json" ) ,
1211- isHeartbeat : false ,
1212- replyOperation : createReplyOperation ( ) ,
1213- } ) ;
1224+ ) . rejects . toThrow (
1225+ "Preflight compaction required but failed: thread not found: <codex-thread-id>" ,
1226+ ) ;
12141227
1215- expect ( entry ) . toBe ( sessionEntry ) ;
12161228 expect ( compactEmbeddedAgentSessionMock ) . toHaveBeenCalledTimes ( 1 ) ;
12171229 expect ( incrementCompactionCountMock ) . not . toHaveBeenCalled ( ) ;
12181230 } ) ;
@@ -1469,7 +1481,7 @@ describe("runMemoryFlushIfNeeded", () => {
14691481 expect ( runEmbeddedAgentMock ) . toHaveBeenCalledTimes ( 1 ) ;
14701482 } ) ;
14711483
1472- it ( "continues when preflight compaction returns a successful no-op" , async ( ) => {
1484+ it ( "fails when required preflight compaction returns an unknown successful no-op" , async ( ) => {
14731485 compactEmbeddedAgentSessionMock . mockResolvedValueOnce ( {
14741486 ok : true ,
14751487 compacted : false ,
@@ -1485,23 +1497,24 @@ describe("runMemoryFlushIfNeeded", () => {
14851497 const sessionStore = { main : sessionEntry } ;
14861498 const replyOperation = createReplyOperation ( ) ;
14871499
1488- const entry = await runPreflightCompactionIfNeeded ( {
1489- cfg : { agents : { defaults : { compaction : { memoryFlush : { } } } } } ,
1490- followupRun : createTestFollowupRun ( {
1491- sessionId : "session" ,
1500+ await expect (
1501+ runPreflightCompactionIfNeeded ( {
1502+ cfg : { agents : { defaults : { compaction : { memoryFlush : { } } } } } ,
1503+ followupRun : createTestFollowupRun ( {
1504+ sessionId : "session" ,
1505+ sessionKey : "main" ,
1506+ } ) ,
1507+ defaultModel : "anthropic/claude-opus-4-6" ,
1508+ agentCfgContextTokens : 200_000 ,
1509+ sessionEntry,
1510+ sessionStore,
14921511 sessionKey : "main" ,
1512+ storePath : path . join ( rootDir , "sessions.json" ) ,
1513+ isHeartbeat : false ,
1514+ replyOperation,
14931515 } ) ,
1494- defaultModel : "anthropic/claude-opus-4-6" ,
1495- agentCfgContextTokens : 200_000 ,
1496- sessionEntry,
1497- sessionStore,
1498- sessionKey : "main" ,
1499- storePath : path . join ( rootDir , "sessions.json" ) ,
1500- isHeartbeat : false ,
1501- replyOperation,
1502- } ) ;
1516+ ) . rejects . toThrow ( "Preflight compaction required but failed: plugin already stored this turn" ) ;
15031517
1504- expect ( entry ) . toBe ( sessionEntry ) ;
15051518 expect ( compactEmbeddedAgentSessionMock ) . toHaveBeenCalledTimes ( 1 ) ;
15061519 const compactCall = requireCompactEmbeddedAgentSessionCall ( ) ;
15071520 expect ( compactCall . contextTokenBudget ) . toBe ( 200_000 ) ;
0 commit comments