#2779·ag-ui

[Feature]: let the Strands producer turn off terminal-event token usage

Author: ChrisTitosCreated Sep 17, 2026Updated Sep 17, 2026
Labelsenhancement

Pre-flight Checklist

  • I have searched existing issues and this hasn't been requested yet.

Problem or Motivation

Since #2617 both Strands bridges attach usage to RUN_FINISHED and RUN_ERROR on every run. There is no way for a deployment to decline, in either bridge.

We run a user-facing assistant on Bedrock AgentCore, and we want no part of that entry on the wire. Not the counts, and not the provider and model labels, which tell every browser which model backs the product. We already collect the same numbers in our own tracing backend, so the copy on the wire buys us nothing and discloses something we would rather not.

Proposed Solution

Add a producer-side switch to StrandsAgentConfig in both bridges:

  • Python: emit_token_usage: bool = True
  • TypeScript: emitTokenUsage?: boolean

Defaulting to today's behaviour, so nothing changes for existing users.

When false, the terminal events omit usage entirely rather than sending an empty list. That preserves the contract _collect_run_usage already documents, where an absent field reads as "not measured" rather than as zero. The cheapest implementation is to skip _record_metadata_usage, so the counts are never collected in the first place.

StrandsAgentConfig already gates emitted output with plain booleans that have exact camelCase twins, so this follows an established shape:

Python TypeScript
emit_messages_snapshot: bool = True emitMessagesSnapshot?: boolean
replay_history_into_strands: bool = True replayHistoryIntoStrands?: boolean
emitChunkEvents?: boolean

emit_messages_snapshot is the closest precedent. It exists because raw AG-UI consumers that reconstruct messages themselves do not want a whole event class on the wire. The same reasoning applies here to a field.

Alternatives Considered

Stripping the field in our own stream loop. This works today, and it is what we are doing. It is brittle: every AG-UI producer that wants this writes the same patch, and it breaks silently the moment a new terminal path is added upstream.

Per-field control, such as suppressing the labels but keeping the counts. This would not resolve it for us. We want the whole usage field gone, which is why this asks for one boolean rather than field-level configuration.

Additional Context

No response