feat(core): make turn cancellation explicit

This commit is contained in:
Yichen Jiang
2026-07-16 18:12:34 +08:00
parent b1e19d8b69
commit c238992fbb
55 changed files with 884 additions and 383 deletions

View File

@@ -0,0 +1,31 @@
/** Turn-scoped cancellation ownership for the concrete AgentLoop driver. @module dsh-agent-loop/cancellation */
import type { AgentCancelCause } from '@deepseek-ai/dsh-agent'
/** Stable runtime-only reason used when lifecycle teardown interrupts a turn. */
export const DISPOSED_INTERRUPT_REASON = Object.freeze({ kind: 'disposed' } as const)
/**
* Owns the single controller shared by every asynchronous boundary of one turn.
* The first request wins because a later caller must not rewrite the cause
* observed by earlier listeners.
*/
export class TurnCancellation {
readonly #controller = new AbortController()
/** The explicit signal passed through this turn's execution boundaries. */
get signal(): AbortSignal {
return this.#controller.signal
}
/**
* Abort the turn once.
* @param reason - a validated caller cause or lifecycle disposal marker.
* @returns whether this request established the signal reason.
*/
request(reason: AgentCancelCause | typeof DISPOSED_INTERRUPT_REASON): boolean {
if (this.signal.aborted) return false
this.#controller.abort(reason)
return true
}
}