ecc1430977
* Python: defer turn-scoped after_run providers to the agent loop boundary Each AgentLoopMiddleware iteration is a full agent run, so CompactionProvider.after_run fired per iteration and rewrote persisted history mid-task (#7236). Providers can now opt into turn scope with after_run_once_per_turn; iterations defer them via a contextvar, and the loop fires them once at the boundary. CompactionProvider opts in; HistoryProvider keeps its incremental per-run persistence. * Python: key loop suppression to the looping agent and pass run options through Two review follow-ups: the contextvar now carries the agent instance so a nested agent.run() inside a loop iteration is not suppressed as if it were an iteration, and the boundary SessionContext forwards the original run options to turn-scoped providers. * fix(core): carry the loop-iteration stamp in run options, not a contextvar The contextvar marker leaked in two ways. Held across a streamed yield it bled into the caller's context, suppressing turn-scoped providers on an unrelated same-agent run while the stream was paused, and a reset from a different consuming task raised on the token. Keyed to the agent instance, it also swallowed the boundary flush of a nested loop on the same agent with its own session. Stamp the runs the loop drives through their options instead. Run options reach only the inner runs (they never enter the model request), a nested or concurrent run starts with fresh options and keeps its own turn, and there is no token to reset, so stream consumption is safe from any task. * Python: annotate custom option keys in the after_run provider test * fix: nosec the loop-iteration options key (bandit B105 false positive) * Python: fix: suppress the loop-token key lint with ruff: ignore * Python: fix: silence the two pyright private-usage flags the repo's own idiom covers --------- Co-authored-by: Giles Odigwe <79032838+giles17@users.noreply.github.com> Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com>