@@ -89,6 +89,7 @@ const MAX_REVIEW_PROMPT_BYTES = 250_000
8989const MAX_CHECK_PROMPT_BYTES = 400_000
9090const MIN_ROUND_BUDGET_MS = 5 * 60 * 1000
9191const ROUND_FINALIZATION_RESERVE_MS = 2 * FINALIZE_TIMEOUT_MS
92+ const SANDBOX_KEEPALIVE_INTERVAL_MS = 4 * 60 * 1000
9293
9394const BABYSIT_GUIDANCE =
9495 'You are fixing an existing pull request in a long-lived automated sandbox. Make only minimal ' +
@@ -487,6 +488,25 @@ async function waitForHeadConvergence(
487488 return 'lagging'
488489}
489490
491+ async function waitWithSandboxKeepalive (
492+ runner : PiSandboxRunner ,
493+ durationMs : number ,
494+ signal : AbortSignal
495+ ) : Promise < void > {
496+ let remainingMs = durationMs
497+ while ( remainingMs > 0 ) {
498+ const intervalMs = Math . min ( remainingMs , SANDBOX_KEEPALIVE_INTERVAL_MS )
499+ await sleepUntilAborted ( intervalMs , signal )
500+ if ( signal . aborted ) throw new Error ( 'Pi run aborted' )
501+ const keepalive = await raceAbort (
502+ runner . run ( 'true' , { timeoutMs : FINALIZE_TIMEOUT_MS } ) ,
503+ signal
504+ )
505+ if ( keepalive . exitCode !== 0 ) throw new Error ( 'Babysit sandbox keepalive failed' )
506+ remainingMs -= intervalMs
507+ }
508+ }
509+
490510function outstandingReason (
491511 fallback : BabysitStopReason ,
492512 threads : BabysitThreadsState ,
@@ -664,8 +684,7 @@ export async function runBabysitPiWithOptions(
664684 )
665685 return resultFor ( totals , reason , progress , threadsClean , latestChecks ! . checksGreen )
666686 }
667- await sleepUntilAborted ( options . roundWaitMs , signal )
668- if ( signal . aborted ) throw new Error ( 'Pi run aborted' )
687+ await waitWithSandboxKeepalive ( runner , options . roundWaitMs , signal )
669688 snapshot = await fetchBabysitSnapshot ( params , signal )
670689 assertBabysitPinned (
671690 { headSha : pinnedHeadSha , headRef : pinnedHeadRef , baseRef : pinnedBaseRef } ,
@@ -957,8 +976,7 @@ export async function runBabysitPiWithOptions(
957976 remainingBeforeWait >
958977 options . roundWaitMs + MIN_ROUND_BUDGET_MS + ROUND_FINALIZATION_RESERVE_MS
959978 ) {
960- await sleepUntilAborted ( options . roundWaitMs , signal )
961- if ( signal . aborted ) throw new Error ( 'Pi run aborted' )
979+ await waitWithSandboxKeepalive ( runner , options . roundWaitMs , signal )
962980 }
963981
964982 snapshot = await fetchBabysitSnapshot ( params , signal )
0 commit comments