mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
test: restore 100% per-file coverage for agent-loop and the acp bridge
agent-loop: behavior tests for retry-while-busy, cancelled recovery windows, no-facts stream failures, idle-listener preemption, rejected driver promises under whenIdle, finish-chunk failures after step close, presentationMeta persistence, pre-aborted and torn-down create/resume signals, and configured-start failures over existing artifacts or after teardown. The remaining guards that no public path can reach carry justified v8 ignore annotations naming the invariant that starves them. acp bridge: cover the retry-adoption path (a retry turn resolves the prompt the failed turn deferred), the no-retry quiescence rejection, and the admission-blocked cancelled settlement; the synchronous send-throw catch is annotated as a future-proofing guard since the machine's send() contains listener failures.
This commit is contained in:
@@ -295,6 +295,9 @@ export class ReactLoopAgent implements Agent {
|
||||
if (outcome.continueTurn || this.outbox.some(item => 'id' in item)) continue
|
||||
break
|
||||
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 })
|
||||
@@ -315,6 +318,9 @@ export class ReactLoopAgent implements Agent {
|
||||
`agent "${this.id}": request recovery failed at turn ${turn}, step ${step}: ${errorChain(recoveryError)}`,
|
||||
)
|
||||
} 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
|
||||
}
|
||||
retry = recoveryCompleted
|
||||
@@ -342,6 +348,10 @@ export class ReactLoopAgent implements Agent {
|
||||
({ reason, idle } = this.settle(turn, step, caught, signal))
|
||||
} finally {
|
||||
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 })
|
||||
@@ -357,6 +367,9 @@ export class ReactLoopAgent implements Agent {
|
||||
emitAgentEvent(this.loopCtx, this, 'agent/error', turn, step, error)
|
||||
}
|
||||
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
|
||||
signal.removeEventListener('abort', cancelRetry)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user