Skip to content

agent_end: forward willRetry to extension-visible event (mirror of #4716) #6827

Description

@neilwashere

What do you want to change?

Forward willRetry to the extension-visible agent_end event too. Today AgentSession._handleAgentEvent computes willRetry and attaches it only to the internal _emit() used by session/RPC listeners — the payload passed to _emitExtensionEvent() one line earlier is the raw event, without it:

// packages/coding-agent/src/core/agent-session.ts (dist agent-session.js:346-349)
await this._emitExtensionEvent(event);                          // raw event, no willRetry
this._emit(event.type === "agent_end"
  ? { ...event, willRetry: this._willRetryAfterAgentEnd(event) } // enriched, but only here
  : event);

AgentEndEvent in extensions/types.ts has no willRetry field.

Why?

This is the same problem #4716 fixed, on the other consumer surface. #4716 gave session/RPC listeners agent_end.willRetry so they don't finalize while pi's own retry is still going to fire. Extensions have the identical problem and no signal: an agent_end handler that wants to react to a failed turn (switch model, alert, log) can't tell "pi will auto-retry this in 2-8s" from "pi has given up," so it either preempts pi's built-in retry or has to reconstruct the answer heuristically.

Two published extensions already work around this with a timer instead of a real signal, specifically because this field isn't there: cad0p/pi-fallback-provider waits 20s (longer than 3 retries' backoff) before acting; 99degree/pi-retry-fallback-model does something similar. I imagine both authors would prefer a clean signal rather than just guesswork.

How? (optional)

_willRetryAfterAgentEnd(event) is already computed once per agent_end. Reuse the same value for both emits instead of recomputing it only for _emit:

const willRetry = this._willRetryAfterAgentEnd(event);
await this._emitExtensionEvent(willRetry !== undefined ? { ...event, willRetry } : event);
this._emit(event.type === "agent_end" ? { ...event, willRetry } : event);

Add willRetry: boolean to AgentEndEvent in extensions/types.ts, mirroring the existing AgentSessionEvent.agent_end.willRetry shape from #4716.

Pure additive field, no behavior change for existing extensions. Have a local patch against 0.80.10 I can send as a PR if this gets lgtm.

Metadata

Metadata

Assignees

No one assigned

    Labels

    no-actionThis issue has been rejected after triage

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions