feat(plugins): carry token usage on the on_stream_end observer payload - #90077
feat(plugins): carry token usage on the on_stream_end observer payload#90077CocaKova wants to merge 1 commit into
Conversation
|
The
Hook tests on this branch: 14/14 passing ( |
Stream observer plugins can see every token of a turn but none of the numbers behind it, so anything usage-shaped (a context meter, a token dashboard) still needs core patches. on_stream_end already carries the turn's lifecycle (final_text/finished/error); this adds a usage dict in turn_finalizer's existing field vocabulary: prompt/completion/total/ reasoning token counters, api_calls, plus last_prompt_tokens (the final call's prompt size, i.e. the model's current context occupancy) and context_length. Together the last two are exactly a context gauge. All reads are defensive getattr with zero defaults, so a partially initialized agent yields zeroed usage instead of breaking the hook path. Payload documented in the VALID_HOOKS comment block. Consumed by a standalone gateway-side-channel plugin rendering a context ring. Tests: 2 added, 14 passing in tests/run_agent/test_plugin_stream_hooks.py
8d5c92a to
95c528a
Compare
|
Correction to my comment above, and a rebase. The slice-12 failure is resolved — but by #89933 (merged), not by #90080, which I opened for the same one-line change before finding it was a duplicate. #90080 is now closed; #89933 is the fix. Sorry for the misdirection. Rebased onto current main ( Also relevant: #90310 adds the delivery target ( |
Additive and contract-clean: Points:
|
What
on_stream_endobserver callbacks now receive ausagekwarg alongsidefinal_text/finished/error— the turn's token counters inturn_finalizer's existing field vocabulary:Why
Stream observer hooks (added with the
on_stream_start/delta/endfamily) let a plugin watch every token of a turn, but none of the numbers behind it — so anything usage-shaped (a context meter in a client, a token dashboard) still requires core patches, which the plugin policy forbids.last_prompt_tokens+context_lengthare exactly a context gauge; the session counters come along at zero extra cost since they're already on the agent.Real consumer exists: a standalone gateway side-channel plugin that renders a per-turn context ring in a Matrix client. No behavior change for existing callbacks — the payload is additive, observer-only, and every read is a defensive
getattrwith a zero default (a partially initialized agent yields zeroed usage, never a raise).Changes
run_agent.py:_stream_hook_usage_payload()+ wired into_emit_stream_endhermes_cli/plugins.py: payload documented in the VALID_HOOKS comment blocktests/run_agent/test_plugin_stream_hooks.py