Browse Source

refactor(agent-loop): state slot invariants directly instead of guarding them

The coverage pass left agent.ts with eight v8 ignore annotations — well
above this repo's density elsewhere. Six guarded conditions the
surrounding invariants already exclude; expressing the invariant directly
deletes the dead arm instead of excusing it: admission/run teardown
releases the abort slot unconditionally (no writer can replace the owner
mid-flight), the request-failed branch closes its always-open step
unconditionally, the recovery finally retires the window it installed,
and the driver finally drops its dead last-resort step close (every path
already closes the step). kick()'s dequeue states the non-empty-queue
invariant as a non-null assertion. The two remaining ignores are the
assertNever exhaustiveness guard and the retry()/run() slot-race guard,
both repo-wide conventions.
_Kerman 2 months ago
parent
commit
5e8225505c
1 changed files with 17 additions and 26 deletions
  1. 17 26
      packages/core/agent-loop/src/agent.ts

+ 17 - 26
packages/core/agent-loop/src/agent.ts

@@ -196,10 +196,10 @@ export class ReactLoopAgent implements Agent {
   /** Claim and admit the next queued prompt, then start its turn. */
   private kick(): void {
     if (this.abort !== undefined || !this.queued.some(item => item.wakeup)) return
-    const item = this.queued.shift()
-    /* v8 ignore next -- unreachable: the some() guard above proves the queue is non-empty */
-    if (item === undefined) return
-    const { message } = item
+    // The some() guard above proves the queue is non-empty; the non-null
+    // assertion expresses that invariant.
+    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+    const { message } = this.queued.shift()!
 
     emitAgentEvent(this.loopCtx, this, 'agent/inbox/dequeue', message)
     const admission = new AbortController()
@@ -232,9 +232,8 @@ export class ReactLoopAgent implements Agent {
 
       // cancel() aborts but never clears the slot, and kick()/run()/retry()
       // all refuse to install a new owner while one exists, so the admission
-      // still owns the slot here.
-      /* v8 ignore next -- unreachable false arm: no writer replaces the abort owner mid-admission */
-      if (this.abort === admission) this.abort = undefined
+      // still owns the slot here and releasing it unconditionally is exact.
+      this.abort = undefined
       if (admitted === undefined) {
         this.continueOrIdle()
         return
@@ -297,11 +296,8 @@ export class ReactLoopAgent implements Agent {
           case 'request-failed': {
             // step() reports request failures only after step/start commits
             // and before its own step/end, so the step is always open here.
-            /* v8 ignore next -- unreachable false arm, see above */
-            if (this.stepOpen) {
-              this.stepOpen = false
-              this.session.append('step/end', { turn, step })
-            }
+            this.stepOpen = false
+            this.session.append('step/end', { turn, step })
             if (agentInterruptReasonOf(signal) === undefined) {
               const retryWindow = { requested: false }
               this.retryWindow = retryWindow
@@ -319,9 +315,9 @@ export class ReactLoopAgent implements Agent {
                 )
               } finally {
                 // Nothing else writes the window while the waterfall runs:
-                // cancel() only flips `requested` and a second run cannot start.
-                /* v8 ignore next -- unreachable false arm, see above */
-                if (this.retryWindow === retryWindow) this.retryWindow = undefined
+                // cancel() only flips `requested` and a second run cannot
+                // start, so unconditional retirement is exact.
+                this.retryWindow = undefined
               }
               retry = recoveryCompleted
                 && agentInterruptReasonOf(signal) === undefined
@@ -347,15 +343,10 @@ export class ReactLoopAgent implements Agent {
       }
       ({ reason, idle } = this.settle(turn, step, caught, signal))
     } finally {
+      // Every step-close happens before this point on both success and
+      // failure paths (step(), the request-failed branch, the catch), so the
+      // finally owes only the turn boundary.
       try {
-        // Every step-close before this point clears the flag on both success
-        // and failure paths (step(), the request-failed branch, the catch),
-        // so the finally never finds a step still open.
-        /* v8 ignore next 4 -- unreachable last-resort step close, see above */
-        if (this.stepOpen) {
-          this.stepOpen = false
-          this.session.append('step/end', { turn, step })
-        }
         if (this.turnOpen) {
           // Re-entrant turn/end listeners must route new input to a later turn.
           this.turnOpen = false
@@ -368,9 +359,9 @@ export class ReactLoopAgent implements Agent {
       }
       this.retryWindow = undefined
       // cancel() aborts but never clears the slot, and no second run can
-      // install a controller while this one is still unwinding.
-      /* v8 ignore next -- unreachable false arm, see above */
-      if (this.abort === controller) this.abort = undefined
+      // install a controller while this one is still unwinding, so the slot
+      // is still this run's controller here.
+      this.abort = undefined
       signal.removeEventListener('abort', cancelRetry)
     }