Events
Instructor dispatches events throughout the extraction and inference lifecycle. These events are automatically bridged to Laravel’s event system by theLaravelEventDispatcher, allowing you to listen and respond using standard Laravel patterns — listeners, subscribers, closures, and queued handlers.
The bridge is implemented by Cognesy\Instructor\Laravel\Events\LaravelEventDispatcher, which lives in the packages/laravel package. It wraps Laravel’s native Illuminate\Contracts\Events\Dispatcher and forwards Instructor events to it based on your configuration.
Event Bridge Configuration
Configure event bridging inconfig/instructor.php:
bridge_events is empty (the default), every Instructor event is forwarded to Laravel’s dispatcher. To reduce overhead in production, list only the event classes your listeners actually need.
The bridge uses instanceof matching, so listing a parent event class also bridges its subclasses.
Available Events
All events extendCognesy\Instructor\Events\StructuredOutputEvent (which extends Cognesy\Events\Event). Events carry data in the $data property (an array or mixed value) rather than typed properties.
Extraction Events
Namespace:Cognesy\Instructor\Events\Extraction
| Event | Description |
|---|---|
ExtractionStarted | Extraction pipeline has begun processing |
ExtractionCompleted | Extraction completed successfully |
ExtractionFailed | All extraction strategies failed |
ExtractionStrategyAttempted | An extraction strategy was attempted |
ExtractionStrategyFailed | An extraction strategy failed |
ExtractionStrategySucceeded | An extraction strategy succeeded |
Response Events
Namespace:Cognesy\Instructor\Events\Response
| Event | Description |
|---|---|
ResponseValidationFailed | Response failed validation |
ResponseValidated | Response passed validation |
ResponseDeserialized | Response was deserialized into an object |
ResponseDeserializationFailed | Response deserialization failed |
ResponseTransformed | Response was transformed |
ResponseTransformationFailed | Response transformation failed |
ResponseGenerationFailed | Response generation failed |
Request Events
Namespace:Cognesy\Instructor\Events\Request
| Event | Description |
|---|---|
NewValidationRecoveryAttempt | A validation recovery retry attempt is being made |
StructuredOutputRecoveryLimitReached | Maximum retries exhausted |
ResponseModelRequested | Response model was requested |
ResponseModelBuilt | Response model schema was built |
Streaming Events
Namespace:Cognesy\Instructor\Events\PartialsGenerator
| Event | Description |
|---|---|
StreamedResponseReceived | Streaming response started |
ChunkReceived | Received a chunk of streaming data |
StreamedResponseFinished | Streaming completed |
PartialResponseGenerated | A partial response object was generated |
StreamedToolCallStarted | A streamed tool call started |
StreamedToolCallUpdated | A streamed tool call was updated |
StreamedToolCallCompleted | A streamed tool call completed |
Listening to Events
Using Event Listeners
Create a dedicated listener class and register it with Laravel’s event system.EventServiceProvider:
Using Closures
For lightweight listeners, register closures directly in a service provider’sboot method.
Using Event Subscribers
Group related event handlers into a single subscriber class. This is convenient when you need to handle multiple Instructor events together.EventServiceProvider:
Common Use Cases
Logging and Monitoring
All events carry data in the$data property (typically an array). Use the name() method to get the event class short name.
Metrics and Analytics
Alerting on Failures
Queued Event Listeners
For CPU-intensive or I/O-heavy processing, implementShouldQueue to push the work onto a queue instead of running it inline.
Wiretap (Direct Event Handling)
Thewiretap method provides direct access to the raw event stream without going through Laravel’s dispatcher. This is useful for low-level debugging or when you need to observe every internal event.
LaravelEventDispatcher itself also supports wiretap for registering global listeners that receive every event, regardless of class. These listeners run at the lowest priority after all class-specific and bridged listeners have executed.
Disabling Event Bridge
To disable event bridging entirely (for example, in high-throughput scenarios where the overhead is unacceptable):Testing Events
Use Laravel’sEvent::fake() to assert that specific events were dispatched during a test.