Extension point for custom stream projections.
Transformers observe protocol events flowing through the StreamMux and build typed derived projections (StreamChannels, promises, etc.).
Set _native = True on a transformer to have its projection keys
exposed as direct attributes on the run stream (in addition to
appearing in run.extensions).
Subclasses must implement init and override at least one of
process / aprocess. The finalize / afinalize and fail /
afail hooks are optional — the default implementations are no-ops.
StreamChannel instances in the projection dict are auto-closed /
auto-failed by the mux, so most transformers don't need finalize
or fail at all.
Transformers that need async work pick the async lane by:
aprocess (and optionally afinalize / afail), orself.schedule(coro) from inside a sync process, orrequires_async = True explicitly.The mux detects these cases at registration and raises if they're
used under sync stream() — they only work under astream().
Use aprocess when the pump must wait for async work before the
next transformer sees the event (e.g. PII redaction that mutates
event in place). Use schedule() for decoupled async work whose
result lands on an independent projection (e.g. async moderation
scoring, cost lookup, external tracing).