Listening to Events
Both inference and embeddings runtimes expose two ways to listen to events:Targeted Listeners
UseonEvent() to listen for a specific event class:
Wiretap
Usewiretap() to receive all events regardless of type. This is useful for debugging and general-purpose logging:
Inference Events
The inference lifecycle dispatches events in this order:Execution-Level Events
These events bracket the entire inference operation, including any retry attempts.
InferenceCompleted is dispatched exactly once per execution, whether it succeeded or failed.
Attempt-Level Events
Each retry attempt dispatches its own events:
When retries are configured, you may see multiple
InferenceAttemptStarted/InferenceAttemptFailed pairs before a final InferenceAttemptSucceeded event. The attemptNumber field tracks which attempt is running.
Response Events
Streaming Events
The
StreamFirstChunkReceived event is particularly useful for measuring time-to-first-chunk (TTFC), as it includes the requestStartedAt timestamp.
Driver Events
Sensitive configuration values (API keys, tokens, secrets) are automatically redacted in the
InferenceDriverBuilt event payload.
Embeddings Events
The embeddings lifecycle dispatches a smaller set of events:Practical Examples
Logging Token Usage
Measuring Time-to-First-Chunk
Tracking Retry Attempts
Monitoring Execution Outcomes
Event Dispatcher
Events are dispatched through anEventDispatcher that implements CanHandleEvents (which extends Psr\EventDispatcher\EventDispatcherInterface). When a runtime is created without an explicit event dispatcher, it creates a default one named 'polyglot.inference.runtime' or 'polyglot.embeddings.runtime'.
You can inject a shared event dispatcher to correlate events across multiple runtimes or integrate with your application’s existing event system: