pub enum ProtocolEvent {
Show 54 variants
SessionStarted {
session_id: String,
seq: i64,
created_at: String,
title: Option<String>,
},
SessionTitleUpdated {
session_id: String,
seq: i64,
created_at: String,
title: String,
},
AssistantDelta {
session_id: String,
seq: i64,
created_at: String,
text: String,
is_reasoning: bool,
},
AssistantMessageCompleted {
session_id: String,
seq: i64,
created_at: String,
message: TranscriptMessage,
},
ToolCallStarted {
session_id: String,
seq: i64,
created_at: String,
call: ToolCall,
},
ToolApprovalRequested {
session_id: String,
seq: i64,
created_at: String,
call: ToolCall,
risk_label: String,
proposed_change: Option<String>,
policy_source: Option<String>,
middleware_decisions: Vec<MiddlewareDecisionEvidence>,
},
ToolApprovalResolved {
session_id: String,
seq: i64,
created_at: String,
tool_call_id: String,
approved: bool,
},
ToolApprovalReviewed {
session_id: String,
seq: i64,
created_at: String,
tool_call_id: String,
tool_name: String,
correlation_id: String,
verdict: String,
reason: String,
reviewer_configured: bool,
},
ToolResultAdded {
session_id: String,
seq: i64,
created_at: String,
result: TranscriptMessage,
},
SessionTurnFinished {
session_id: String,
seq: i64,
created_at: String,
turn_id: String,
status: String,
},
StreamResyncRequired {
session_id: String,
seq: i64,
created_at: String,
after_seq: i64,
oldest_available_seq: i64,
high_water_mark: i64,
},
PersistenceFailed {
session_id: String,
seq: i64,
created_at: String,
reason: String,
},
Overloaded {
session_id: String,
seq: i64,
created_at: String,
scope: String,
limit: u64,
current: u64,
retry_after_ms: u64,
},
ProviderRetrying {
session_id: String,
seq: i64,
created_at: String,
provider: String,
reason: String,
attempt: u32,
max_attempts: u32,
delay_ms: u64,
},
SessionCompactionStarted {
session_id: String,
seq: i64,
created_at: String,
trigger: String,
command_id: String,
},
VerificationFinished {
session_id: String,
seq: i64,
created_at: String,
summary: String,
passed: bool,
tool: String,
issue_count: i32,
issues: Vec<VerificationIssue>,
},
TaskGraphUpdated {
session_id: String,
seq: i64,
created_at: String,
summary: String,
tasks: Vec<TaskNode>,
},
TaskStatusUpdated {
session_id: String,
seq: i64,
created_at: String,
task_id: String,
context_id: String,
state: String,
task: Value,
},
TaskArtifactUpdated {
session_id: String,
seq: i64,
created_at: String,
task_id: String,
context_id: String,
artifact_id: String,
artifact: Value,
},
ArtifactLineageUpdated {
session_id: String,
seq: i64,
created_at: String,
task_id: String,
context_id: String,
artifact_id: String,
lineage: Value,
},
RunInterrupted {
session_id: String,
seq: i64,
created_at: String,
reason: Option<String>,
},
RunFailed {
session_id: String,
seq: i64,
created_at: String,
error: String,
kind: String,
hint: String,
},
SessionCompacted {
session_id: String,
seq: i64,
created_at: String,
summary: String,
dropped_count: i32,
tier: String,
tokens_before: u64,
tokens_after: u64,
epoch: u64,
command_id: String,
retained_turns: u32,
},
SessionContextFolded {
session_id: String,
seq: i64,
created_at: String,
subtask_id: String,
start_marker: String,
end_marker: String,
fold: TranscriptMessage,
},
UsageUpdated {
session_id: String,
seq: i64,
created_at: String,
prompt_tokens: i32,
completion_tokens: i32,
cost_usd: f64,
context_tokens: i32,
context_percent: f64,
cache_read_tokens: i32,
cache_creation_tokens: i32,
cost_known: bool,
},
TurnUsage {Show 13 fields
session_id: String,
seq: i64,
created_at: String,
input_tokens: i64,
cached_input_tokens: i64,
cache_creation_tokens: i64,
output_tokens: i64,
reasoning_tokens: i64,
context_window: i64,
context_used_tokens: i64,
context_used_pct: f64,
cache_hit_pct: f64,
session_cache_hit_pct: f64,
},
PromptCacheBreak {
session_id: String,
seq: i64,
created_at: String,
reason: String,
expected: bool,
tokens_lost: i64,
estimated_cost_lost: Option<f64>,
turn: i64,
detail: String,
previous_cache_read_tokens: i64,
cache_read_tokens: i64,
cache_creation_tokens: i64,
},
ToolOutputDelta {
session_id: String,
seq: i64,
created_at: String,
call_id: String,
stream: String,
text: String,
},
BackgroundShellExited {
session_id: String,
seq: i64,
created_at: String,
shell_id: String,
command: String,
status: ShellExitStatus,
output_bytes: u64,
},
BudgetExceeded {
session_id: String,
seq: i64,
created_at: String,
scope: String,
current_usd: f64,
ceiling_usd: f64,
hint: String,
},
ProviderRouteUpdated {
session_id: String,
seq: i64,
created_at: String,
state: String,
provider: String,
model: String,
failure_kind: String,
detail: String,
},
AccountRateLimited {Show 15 fields
session_id: String,
seq: i64,
created_at: String,
provider: String,
account: String,
account_id: Option<String>,
account_kind: Option<String>,
email: Option<String>,
organization: Option<String>,
status: String,
rate_limit_type: Option<String>,
resets_at: Option<u64>,
utilization: Option<f64>,
overage_status: Option<String>,
error_code: Option<String>,
},
AccountUsageReported {Show 16 fields
session_id: String,
seq: i64,
created_at: String,
provider: String,
account: String,
account_id: Option<String>,
account_kind: Option<String>,
email: Option<String>,
total_cost_usd: Option<f64>,
duration_ms: Option<u64>,
num_turns: Option<u64>,
input_tokens: u64,
output_tokens: u64,
cache_read_tokens: u64,
cache_creation_tokens: u64,
models: Vec<String>,
},
DispatchDecided {
session_id: String,
seq: i64,
created_at: String,
strategy: String,
rationale: String,
},
OrchestrationObservationRecorded {
session_id: String,
seq: i64,
created_at: String,
observation: OrchestrationObservation,
},
AgentQueryIssued {
session_id: String,
seq: i64,
created_at: String,
query_id: String,
from_role: String,
to_role: String,
query_type: String,
expected_format: String,
},
AgentQueryResponded {
session_id: String,
seq: i64,
created_at: String,
query_id: String,
from_role: String,
to_role: String,
confidence: f64,
},
HumanSteeringInjected {
session_id: String,
seq: i64,
created_at: String,
injected_by: String,
content_preview: String,
text: Option<String>,
},
SubAgentSpawned {
session_id: String,
seq: i64,
created_at: String,
sub_session_id: String,
role: String,
task_title: String,
},
SubAgentCompleted {
session_id: String,
seq: i64,
created_at: String,
sub_session_id: String,
role: String,
success: bool,
summary: String,
outcome: String,
outcome_detail: String,
},
SubAgentCancelled {
session_id: String,
seq: i64,
created_at: String,
sub_session_id: String,
role: String,
cancelled_by: String,
},
UserMessageSubmitted {
session_id: String,
seq: i64,
created_at: String,
text: String,
nonce: Option<String>,
trust: Option<TrustEnvelope>,
attachments: Vec<ReferenceMeta>,
},
UserQuestionAsked {
session_id: String,
seq: i64,
created_at: String,
question_id: String,
questions: Vec<UserQuestion>,
},
McpElicitationRequested {
session_id: String,
seq: i64,
created_at: String,
request: ElicitationRequestEvent,
},
CredentialRequested {
session_id: String,
seq: i64,
created_at: String,
tool_call_id: String,
provider: String,
},
CredentialResolved {
session_id: String,
seq: i64,
created_at: String,
tool_call_id: String,
outcome: String,
},
UserQuestionAnswered {
session_id: String,
seq: i64,
created_at: String,
question_id: String,
},
PlanPresented {
session_id: String,
seq: i64,
created_at: String,
plan_id: String,
plan: String,
},
AgentRosterUpdated {
session_id: String,
seq: i64,
created_at: String,
agents: Vec<AgentRosterRow>,
},
CheckRunCompleted {
session_id: String,
seq: i64,
created_at: String,
check_id: String,
command: String,
exit_code: i32,
attempts: u32,
duration_ms: u64,
passed: bool,
jury_skipped: bool,
},
GoalProgressUpdated {
session_id: String,
seq: i64,
created_at: String,
snapshot: GoalSnapshotV1,
},
SelfReviewProposalReceived {
session_id: String,
seq: i64,
created_at: String,
proposal: SelfReviewProposalDraft,
},
ModelRouteDecision {
session_id: String,
seq: i64,
created_at: String,
decision: ModelRouteDecisionPayload,
},
RunGovernanceRejected {
session_id: String,
seq: i64,
created_at: String,
kind: RunFailureKind,
tool_call_id: String,
budget: Option<RunBudgetExhausted>,
ownership: Option<RunOwnershipFailure>,
origin: Option<RunOriginFailure>,
},
}Variants§
SessionStarted
SessionTitleUpdated
AssistantDelta
AssistantMessageCompleted
ToolCallStarted
ToolApprovalRequested
Fields
middleware_decisions: Vec<MiddlewareDecisionEvidence>ToolApprovalResolved
ToolApprovalReviewed
Typed verdict of the approval review stage for one mutating tool call,
emitted durably before the normal permission/approval gate. verdict
is allow (reviewer echoed the exact request identity; the normal
approval still applies), block (reviewer blocked, errored, or answered
uncorrelated; the call is denied), or unavailable (no reviewer is
configured; nothing is auto-approved and the human gate decides).
correlation_id is the same token the approval and denial records use
for this tool call.
Fields
ToolResultAdded
SessionTurnFinished
A turn reached a typed terminal state. Consumers can distinguish a completed turn from a transport disconnect without inferring it from presentation events.
StreamResyncRequired
The requested replay cursor predates contiguous conduit coverage. Drivers must resync from durable session state before reconnecting.
Fields
PersistenceFailed
Session persistence latched as failed: later durable facts are refused and
in-flight tools are cancelled. Live-only by design (never persisted,
since persistence is what failed); reason is the first latch reason.
Overloaded
Admission rejected work before it could consume an unbounded queue.
Fields
ProviderRetrying
A provider call failed transiently and the adapter is backing off
before retry attempt of max_attempts.
Fields
SessionCompactionStarted
Context compaction began; the matching sessionCompacted follows on
success. trigger is automatic, manual or overflow.
VerificationFinished
Fields
issues: Vec<VerificationIssue>TaskGraphUpdated
TaskStatusUpdated
Fields
TaskArtifactUpdated
Fields
ArtifactLineageUpdated
Fields
RunInterrupted
RunFailed
Fields
SessionCompacted
Fields
tier: StringCompaction tier that produced this event: summary (tier 2,
model-authored structured session-state summary), overflow
(tier 3, reactive provider-rejection recovery) or manual.
SessionContextFolded
A completed sub-trajectory was replaced by a recoverable fold marker. Marker strings are persisted so restart replay applies the same structural replacement to the model-facing and visible transcripts.
Fields
fold: TranscriptMessageUsageUpdated
Fields
cost_known: boolWhether cost_usd came from curated pricing for the active model
(vs. a conservative estimate for an unpriced model). Consumers that
surface cost to operators (session rows, agents --json) must
treat false as “cost unknown” — report null, not this number.
Defaults to true for older senders that predate this field, to
preserve their existing (assumed-correct) cost display.
TurnUsage
Per-model-call usage for live prompt-cache / context displays. Emitted
once per provider response, in addition to the cumulative
usageUpdated. inputTokens is the FULL prompt size
(uncached + cached + cache-write); cachedInputTokens is the
cache-read subset. reasoningTokens is a subset of outputTokens.
contextWindow is 0 when the model’s window is unknown, in which case
contextUsedPct is 0. contextUsedPct is 0.0-100.0.
Fields
PromptCacheBreak
A provider response whose cache read fell materially below what the
previous request’s cached prefix promised (donor
promptCacheBreakDetection.ts). reason is the primary attributed
cause (system, tools, model, params, cacheControl,
messagesEdited, compaction, ttlExpiry1h, ttlExpiry5m,
serverSide, unknown); detail lists every observed change.
expected is true for breaks the host app caused deliberately
(compaction, model switch, explicit tool-set change, idle TTL expiry)
and false for everything that is silently burning money.
estimatedCostLost is absent when the active model has no curated
pricing. turn is the 1-based provider request number in the session.
Fields
ToolOutputDelta
Live output chunk from a running shell/exec tool. Coalesced by the
emitter (at most one event per stream per ~100ms); toolResultAdded
remains the authoritative final output.
Fields
BackgroundShellExited
A background shell reached a terminal state. Emitted once per shell,
only after the child was reaped, so consumers are notified instead of
polling get_shell_output (which keeps working). Durable: it is the
settled fact that the process is gone.
Fields
status: ShellExitStatusBudgetExceeded
Fields
ProviderRouteUpdated
Fields
AccountRateLimited
A vendor account reported rate-limit telemetry. status is
allowed, allowed_warning or rejected; when rejected, the UI
shows “account X capped until resetsAt” and offers a manual
“continue on another account”. the host app never switches accounts
automatically.
Fields
AccountUsageReported
Per-turn cost and token usage reported by a vendor CLI, attributed to the account that ran the turn.
Fields
DispatchDecided
OrchestrationObservationRecorded
AgentQueryIssued
Fields
AgentQueryResponded
Fields
HumanSteeringInjected
Fields
SubAgentSpawned
Emitted on the parent session when the orchestrator spawns a sub-agent.
Fields
SubAgentCompleted
Emitted on the parent session when a sub-agent finishes (success or failure).
Fields
outcome: StringThe sub-agent’s true completion state (parity P-2):
"complete" | "partial_with_limit" | "api_error". Defaults
to "complete" for older senders that predate this field, so a
rolling deploy never fabricates a false partial/error state —
only new senders that actually detected a cutoff/error set it.
SubAgentCancelled
Emitted on the parent session when a sub-agent is stopped before completing.
cancelled_by: “user” | “budget” | “governance” | “error”
Fields
UserMessageSubmitted
A user/operator turn was submitted to the session. Emitted so the event log is the single source of truth for replay (the user side of the conversation, not just the assistant/tool side).
Fields
trust: Option<TrustEnvelope>attachments: Vec<ReferenceMeta>Metadata-only references attached to this user turn. Defaulting preserves replay compatibility with events written before rich references existed.
UserQuestionAsked
The agent is blocking on a structured question to the operator. The UI
renders the choices and POSTs answers back, keyed by question_id.
Fields
questions: Vec<UserQuestion>McpElicitationRequested
An MCP stdio server issued a bounded elicitation request to the client.
The operator response is correlated by request.id and returned to the
waiting server request; form values remain opaque JSON data.
CredentialRequested
A running tool needs one provider credential before it can continue. Carries request identity and provider metadata only; secret input is returned through the correlated response channel, never this event.
CredentialResolved
UserQuestionAnswered
The operator answered (or the question was otherwise resolved).
PlanPresented
The agent presented a plan via exit_plan_mode and is blocking on
approval. The UI renders the plan and POSTs the decision back keyed by
plan_id; on approval the session leaves Plan mode.
AgentRosterUpdated
Per-sub-agent roster snapshot for the session agent rail (F1).
CheckRunCompleted
A deterministic pre-gate check finished (F3). jury_skipped is true when
this (failing) check short-circuited the jury for the run.
Fields
GoalProgressUpdated
A persistent Goal advanced or closed (F2). Emitted on every continuation
and on close; status is the GoalState status string.
SelfReviewProposalReceived
A self-review proposal generated by the background self-review fork.
ModelRouteDecision
The capability/cost router (Lane R1a-L3/L4, ADR §D5) picked a model
for a sub-agent spawn. Emitted at the router_seam.rs spawn seam
alongside the existing tracing::info! line — never in place of it.
est_cost_usd is a PRE-CALL estimate (the UI chip’s “est.” label is
mandatory, never implied actuals); actual spend still reconciles
through UsageUpdated.
RunGovernanceRejected
Run-governance typed failure. Emitted when the engine rejects a tool dispatch on a budget, ownership, or origin invariant (Lane B3/C3). The variant’s payload is the typed counterexample — both the desktop UI and the event log can render the discriminator plus context.
Fields
kind: RunFailureKindbudget: Option<RunBudgetExhausted>ownership: Option<RunOwnershipFailure>origin: Option<RunOriginFailure>Implementations§
Source§impl ProtocolEvent
impl ProtocolEvent
Sourcepub fn durability(&self) -> EventDurability
pub fn durability(&self) -> EventDurability
Conservative classification: only events that are unambiguously presentation/control projections are non-durable. New variants default to durable by virtue of the explicit catch-all arm.
pub fn is_durable_fact(&self) -> bool
Source§impl ProtocolEvent
impl ProtocolEvent
pub fn meta(&self) -> ProtocolEventMeta
pub fn session_id(&self) -> &str
pub fn seq(&self) -> i64
pub fn created_at(&self) -> &str
Sourcepub fn set_seq(&mut self, new_seq: i64)
pub fn set_seq(&mut self, new_seq: i64)
Exhaustive set_seq. Used by decode_event_row and by Conduit::publish
when the caller has determined the canonical sequence for this event.
Sourcepub fn canonicalize_identity(&mut self, authoritative_seq: i64)
pub fn canonicalize_identity(&mut self, authoritative_seq: i64)
Canonicalize every identity-bearing field against authoritative_seq.
seq is rewritten for every variant; TranscriptMessage::id on each
nested message is rewritten too so producer-chosen constant IDs (final,
forced-stop) cannot survive a row-replay.