@sema-agent/core
Version:
Stateless, task-oriented AI agent core
26 lines (25 loc) • 1.55 kB
TypeScript
/**
* The run's ONE caller-stop gate: tripped by every channel through which the run's CALLER asks it to stop — the
* `halt()`, `interrupt()` and `destroy()` verbs (`stop()`) and the caller's own `TaskSpec.signal` (composed into
* `signal` at the mint) — at any moment until the run publishes its result, the loop's end included. It answers one
* question, "did the caller ask this run to stop?", and every compaction pass of the run reads it the same way: a
* tripped gate admits no pass, and a pass in flight carries it both as an abort and as its withdrawal signal, so a
* stop landing mid-pass cuts the summary call and the pass reports a cancel. It is not an attribution: who OWNS the
* run's ending stays on the loop latch's first-writer seats, and an engine stop (a limit, an output retry cap, a
* gate) never trips it.
*
* Minted once per run beside the loop latch and carried on it (`LiveHandle.loop.callerStop`), so the verbs and the
* run body hold the same object.
*/
export interface CallerStopGate {
/** The verbs' write face; idempotent. */
stop(): void;
/** The read face: aborted once any caller channel fired. */
readonly signal: AbortSignal;
}
/**
* The caller's own signal is COMPOSED into the read face, not listened to: there is nothing to release, so the gate
* keeps answering after the leg dropped its own listener on that signal — which is exactly when the end-of-task
* pass runs.
*/
export declare function mintCallerStopGate(callerSignal: AbortSignal | undefined): CallerStopGate;