fix(agent-loop): suppress cancel-requested for a no-op keepInbox cancel

cancel() emitted agent/cancel-requested whenever queued or steering work
existed, even under keepInbox with no active turn — a call the contract
documents as a no-op. Consumers could misread that notification as a real
cancellation. Emit only when the call actually aborts the active turn or
discards pending work, matching the "effective call" contract.
This commit is contained in:
_Kerman
2026-07-27 01:22:19 +08:00
parent 9ef55cda98
commit 9676696a31
2 changed files with 11 additions and 2 deletions
+5 -1
View File
@@ -150,7 +150,11 @@ export class ReactLoopAgent implements Agent {
* all owned by the factory.
*/
cancel(cause: AgentInterruptReason, options: CancelOptions = {}): void {
if (this.abort !== undefined || this.queued.length > 0 || this.outbox.length > 0) {
// Effective only when it aborts the active turn or actually discards
// pending work: a keepInbox call with no active turn is a documented
// no-op, so it must not emit cancel-requested for consumers to misread.
const discards = !options.keepInbox && (this.queued.length > 0 || this.outbox.length > 0)
if (this.abort !== undefined || discards) {
// Observe-only: coordination consumers update their state before the
// inboxes clear; listener failures are contained by the dispatcher.
if (cause.kind !== 'disposed') emitAgentEvent(this.loopCtx, this, 'agent/cancel-requested', cause)