@@ -88,6 +88,7 @@ const MAX_FAILING_CHECKS_IN_PROMPT = 20
8888const MAX_REVIEW_PROMPT_BYTES = 250_000
8989const MAX_CHECK_PROMPT_BYTES = 400_000
9090const MIN_ROUND_BUDGET_MS = 5 * 60 * 1000
91+ const ROUND_FINALIZATION_RESERVE_MS = 2 * FINALIZE_TIMEOUT_MS
9192
9293const BABYSIT_GUIDANCE =
9394 'You are fixing an existing pull request in a long-lived automated sandbox. Make only minimal ' +
@@ -248,12 +249,6 @@ function buildRoundPrompt(
248249 detailsUrl : check . detailsUrl ,
249250 diagnostics : diagnostics . get ( check . key ) ,
250251 } ) )
251- if ( checks . failing . length > MAX_FAILING_CHECKS_IN_PROMPT ) {
252- throw new BabysitGitHubError (
253- 'bounds_exceeded' ,
254- `Babysit found ${ checks . failing . length } failing checks; at most ${ MAX_FAILING_CHECKS_IN_PROMPT } fit in one trusted round.`
255- )
256- }
257252 const reviewJson = untrustedJson ( reviewPayload )
258253 const checkJson = untrustedJson ( checkPayload )
259254 if ( new TextEncoder ( ) . encode ( reviewJson ) . byteLength > MAX_REVIEW_PROMPT_BYTES ) {
@@ -340,7 +335,8 @@ async function runRoundAgent(
340335 signal : AbortSignal ,
341336 prompt : string ,
342337 secrets : readonly string [ ] ,
343- keyEnvVar : string
338+ keyEnvVar : string ,
339+ timeoutMs : number
344340) : Promise < PiRunTotals > {
345341 await raceAbort (
346342 runner . run ( `rm -f ${ BABYSIT_ROUND_PATH } ` , { timeoutMs : FINALIZE_TIMEOUT_MS } ) ,
@@ -379,7 +375,7 @@ async function runRoundAgent(
379375 }
380376 : { } ) ,
381377 } ,
382- timeoutMs : PI_TIMEOUT_MS ,
378+ timeoutMs,
383379 onStdout : handleChunk ,
384380 }
385381 ) ,
@@ -656,7 +652,10 @@ export async function runBabysitPiWithOptions(
656652 latestThreads ! . actionable . length > 0 || latestChecks ! . blockingFailing . length > 0
657653 if ( ! needsAgent ) {
658654 const remaining = lifetime - ( Date . now ( ) - startedAt )
659- if ( remaining <= options . roundWaitMs + MIN_ROUND_BUDGET_MS ) {
655+ if (
656+ remaining <=
657+ options . roundWaitMs + MIN_ROUND_BUDGET_MS + ROUND_FINALIZATION_RESERVE_MS
658+ ) {
660659 const reason = outstandingReason (
661660 'budget_exhausted' ,
662661 latestThreads ! ,
@@ -699,7 +698,10 @@ export async function runBabysitPiWithOptions(
699698 )
700699 return resultFor ( totals , reason , progress , threadsClean , latestChecks ! . checksGreen )
701700 }
702- if ( Date . now ( ) - startedAt + MIN_ROUND_BUDGET_MS > lifetime ) {
701+ if (
702+ Date . now ( ) - startedAt + MIN_ROUND_BUDGET_MS + ROUND_FINALIZATION_RESERVE_MS >
703+ lifetime
704+ ) {
703705 const reason = outstandingReason (
704706 'budget_exhausted' ,
705707 latestThreads ! ,
@@ -708,6 +710,18 @@ export async function runBabysitPiWithOptions(
708710 )
709711 return resultFor ( totals , reason , progress , threadsClean , latestChecks ! . checksGreen )
710712 }
713+ if ( latestChecks ! . failing . length > MAX_FAILING_CHECKS_IN_PROMPT ) {
714+ progress . notes . push (
715+ `Babysit found ${ latestChecks ! . failing . length } failing checks; at most ${ MAX_FAILING_CHECKS_IN_PROMPT } fit in one trusted round.`
716+ )
717+ return resultFor (
718+ totals ,
719+ 'bounds_exceeded' ,
720+ progress ,
721+ threadsClean ,
722+ latestChecks ! . checksGreen
723+ )
724+ }
711725
712726 const diagnostics = await fetchBabysitCheckDiagnostics (
713727 params ,
@@ -716,6 +730,19 @@ export async function runBabysitPiWithOptions(
716730 signal
717731 )
718732 const prompt = buildRoundPrompt ( params , latestThreads ! , latestChecks ! , diagnostics , secrets )
733+ const agentTimeoutMs = Math . min (
734+ PI_TIMEOUT_MS ,
735+ lifetime - ( Date . now ( ) - startedAt ) - ROUND_FINALIZATION_RESERVE_MS
736+ )
737+ if ( agentTimeoutMs < MIN_ROUND_BUDGET_MS ) {
738+ const reason = outstandingReason (
739+ 'budget_exhausted' ,
740+ latestThreads ! ,
741+ latestChecks ! ,
742+ awaitingReview
743+ )
744+ return resultFor ( totals , reason , progress , threadsClean , latestChecks ! . checksGreen )
745+ }
719746 progress . rounds += 1
720747 context . onEvent ( { type : 'text' , text : `Babysit round ${ progress . rounds } started.\n` } )
721748 try {
@@ -726,7 +753,8 @@ export async function runBabysitPiWithOptions(
726753 signal ,
727754 prompt ,
728755 secrets ,
729- keyEnvVar
756+ keyEnvVar ,
757+ agentTimeoutMs
730758 )
731759 mergeRoundTotals ( totals , roundTotals )
732760 } catch ( error ) {
@@ -926,7 +954,8 @@ export async function runBabysitPiWithOptions(
926954 const remainingBeforeWait = lifetime - ( Date . now ( ) - startedAt )
927955 if (
928956 options . roundWaitMs > 0 &&
929- remainingBeforeWait > options . roundWaitMs + MIN_ROUND_BUDGET_MS
957+ remainingBeforeWait >
958+ options . roundWaitMs + MIN_ROUND_BUDGET_MS + ROUND_FINALIZATION_RESERVE_MS
930959 ) {
931960 await sleepUntilAborted ( options . roundWaitMs , signal )
932961 if ( signal . aborted ) throw new Error ( 'Pi run aborted' )
0 commit comments