SessionEvent
Every message from Copilot is aRevolution\Copilot\Types\SessionEvent class.
Because this is the class you use most often, Laravel-native conveniences are added on top.
content()
Get the most important response message from the AI.
__toString() also returns the message content.
Checking the event type
isAssistantMessage(), isUserMessage(), isIdle(), and isAssistantMessageDelta() are available.
Additional helpers may be added for commonly used event types.
Use is() to check for any EventType.
type() returns the string value of the SessionEventType enum.
failed() / successful()
When the event type is SESSION_ERROR, failed() returns true.
successful() is the opposite.
Renamed from isError() to match Laravel’s naming.
throw()
Just like Laravel’s HTTP or Process API, errors are retained and can be raised via throw().
If there’s no error it does nothing, so you can write:
SESSION_ERROR, Revolution\Copilot\Exceptions\SessionErrorException is thrown.
On timeout, Revolution\Copilot\Exceptions\SessionTimeoutException is thrown.
For JSON-RPC errors, Revolution\Copilot\Exceptions\JsonRpcException is thrown.
Conditionable
when() and unless() are available.
Dumpable
dump() and dd() are available.
Tappable
tap() is available.
InteractsWithData
This feature applies only to SessionEvent’s$data property.
Familiar helpers such as all(), has(), only(), and collect() are available.
See InteractsWithData for details.
Because SessionEvent’s $data shape differs per EventType, this is handy for accessing event-specific values.
content() also uses InteractsWithData under the hood.
toArray() / toJson()
You can convert the entire SessionEvent to an array or JSON.
collect() method for the event as a whole, since InteractsWithData already provides collect() for $data.
To perform collection operations on the whole event, use Laravel’s collect() helper.
broadcast() / broadcastNow()
You can broadcast with the same interface as the Laravel AI SDK’s StreamEvent.
The AI SDK uses it during streaming, but for SessionEvent you can use it with any EventType.
broadcastNow() broadcasts immediately without going through a queue.
Event metadata
Starting with Copilot CLI 1.0.99, some events include additional metadata. The SDK keeps these values as-is in$data, so you can access them through $event->data or the InteractsWithData helpers.
Compaction events
data.compactionAttemptId on session.compaction_start and session.compaction_complete is an ID that links the start event to the complete event.
When the compaction involves a model switch, switchTargetModel is also included.
When the target model has a different prompt token budget, targetPromptTokenLimit is also included.
The complete event may include initialModel, model, outcome, outcomeReason, failureReason, tokenAccountingBasis, and more.
outcome and the reason fields are strings that may gain new values in the future.
Don’t treat them as a fixed enum, and preserve unknown values as-is.
A missing field means the value wasn’t provided. Don’t infer a default value.
Tool execution usage
data.toolUsage on tool.execution_complete is the provider-reported usage for runtime-owned tool operations.
It is separate from the conversation model’s assistant.usage.
It may include reported usage even when the tool execution failed.
toolUsage.model is the model requested by the tool operation, not the conversation model.
Token counts and billing information may be only partially provided.
A missing field means the value is unavailable, not zero tokens.
inputTokensDetails and outputTokensDetails are breakdowns included in their respective totals. Don’t add them to the totals.
toolUsage.requestId is an ID the runtime uses to deduplicate redelivery and replay. It is not an upstream billing identifier.
data.toolUsageRequestIds on session.usage_checkpoint and session.shutdown is also runtime-internal deduplication metadata that identifies the tool operations included in the accounting snapshot.
Don’t treat it as an upstream billing ID.
Fusion resolved events
data.selectedRuleId on session.fusion_resolved identifies the server rule when server-side routing selects a different workflow than the local rule.
It is omitted when there is no override.
MCP server tools loaded events
SessionEventType::SESSION_MCP_SERVER_TOOLS_LOADED (session.mcp_server_tools_loaded) fires when an MCP server’s tool list becomes available.
It is an ephemeral event that fires once per connection and is not persisted.
It includes data.serverName and data.toolCount.
An MCP server reaching connected does not mean its tools have finished loading.
After the server leaves the connected state, treat it as loading until you receive this event again.
When cached tools are used, this event may arrive before connected.
For the latest updates, see the GitHub repository.