mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-08-28 05:27:41 +00:00
docs(events): remove events that are never serialized
`agent.output.start` was not the only phantom entry in the event catalog. Cross-checking every documented `### \`name\`` heading against `is_known_event_name()` turned up six more, in three kinds: Filtered before the durable pipeline. `agent.output.replace`, `agent.text.delta`, `agent.reasoning.delta`, and `agent.tool.output.delta` are real `AgentEvent` variants, but `is_streaming_noise()` drops them before the emitter builds a `RunEvent`, so they never reach the run store, SSE, `fabro events`, or a JSONL sink. Each was documented with a full envelope example including `id`, `ts`, and `node_id` — fields they never get. Replaced with one section that names them and says why they have no envelope, since their existence is worth knowing and their non-durability is exactly what the examples obscured. Does not exist at all. `agent.skill.expanded` had its own section, and a note elsewhere claiming `AgentEvent::SkillExpanded` "remains classified as streaming noise". That variant was removed from the code; `rg SkillExpanded lib/` returns nothing. Slash-skill expansion is reported through the durable `agent.skill.activated` with `source == "slash"`. Wrong name. `asset.captured` documents properties that match `ArtifactCapturedProps` field for field, but the emitted name is `artifact.captured`. A consumer matching the documented string would silently never fire. The catalog opens by describing itself as every serialized envelope, so an entry in it is a claim a consumer can write code against. All documented names now resolve. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6659ae768a
commit
ab8dd985ca
2 changed files with 29 additions and 109 deletions
|
|
@ -1022,28 +1022,6 @@ replays the turn.
|
|||
| `kind` | string | `reasoning`, `text`, or `tool_call` — observed, not inferred |
|
||||
| `visit` | number | Graph visit |
|
||||
|
||||
### `agent.output.replace`
|
||||
|
||||
Replaces the current in-progress assistant output buffers.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "...", "ts": "...", "run_id": "...",
|
||||
"event": "agent.output.replace",
|
||||
"node_id": "code", "node_label": "code",
|
||||
"session_id": "ses_abc",
|
||||
"properties": {
|
||||
"text": "I'll fix the login bug by...",
|
||||
"reasoning": "The user wants..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `text` | string | Replacement assistant text |
|
||||
| `reasoning` | string? | Replacement reasoning text |
|
||||
|
||||
### `agent.message`
|
||||
|
||||
Emitted when the assistant produces a complete message.
|
||||
|
|
@ -1085,46 +1063,6 @@ Emitted when the assistant produces a complete message.
|
|||
| `usage.raw` | object? | Raw provider-specific usage |
|
||||
| `tool_call_count` | number | Number of tool calls in this turn |
|
||||
|
||||
### `agent.text.delta`
|
||||
|
||||
Streaming text chunk from the assistant.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "...", "ts": "...", "run_id": "...",
|
||||
"event": "agent.text.delta",
|
||||
"node_id": "code", "node_label": "code",
|
||||
"session_id": "ses_abc",
|
||||
"properties": {
|
||||
"delta": "I'll start by reading"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `delta` | string | Text chunk |
|
||||
|
||||
### `agent.reasoning.delta`
|
||||
|
||||
Streaming reasoning/thinking chunk from the assistant.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "...", "ts": "...", "run_id": "...",
|
||||
"event": "agent.reasoning.delta",
|
||||
"node_id": "code", "node_label": "code",
|
||||
"session_id": "ses_abc",
|
||||
"properties": {
|
||||
"delta": "The user needs me to..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `delta` | string | Reasoning text chunk |
|
||||
|
||||
### `agent.tool.started`
|
||||
|
||||
Emitted when the agent begins a tool call.
|
||||
|
|
@ -1149,26 +1087,6 @@ Emitted when the agent begins a tool call.
|
|||
| `tool_call_id` | string | Unique tool call id |
|
||||
| `arguments` | object | Tool call arguments |
|
||||
|
||||
### `agent.tool.output.delta`
|
||||
|
||||
Streaming tool output chunk.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "...", "ts": "...", "run_id": "...",
|
||||
"event": "agent.tool.output.delta",
|
||||
"node_id": "code", "node_label": "code",
|
||||
"session_id": "ses_abc",
|
||||
"properties": {
|
||||
"delta": "fn login(user: &str)..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `delta` | string | Output text chunk |
|
||||
|
||||
### `agent.tool.completed`
|
||||
|
||||
Emitted when a tool call finishes.
|
||||
|
|
@ -1253,24 +1171,6 @@ Emitted when the agent detects a tool-use loop.
|
|||
|
||||
No properties.
|
||||
|
||||
### `agent.skill.expanded`
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "...", "ts": "...", "run_id": "...",
|
||||
"event": "agent.skill.expanded",
|
||||
"node_id": "code", "node_label": "code",
|
||||
"session_id": "ses_abc",
|
||||
"properties": {
|
||||
"skill_name": "read_file"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Property | Type | Description |
|
||||
|----------|------|-------------|
|
||||
| `skill_name` | string | Expanded skill name |
|
||||
|
||||
### `agent.steering.injected`
|
||||
|
||||
```json
|
||||
|
|
@ -1618,10 +1518,10 @@ Emitted whenever a skill is activated in the running session. Sources:
|
|||
| `source` | string | `"slash"` for `/skill-name` expansion, `"tool"` for `use_skill` activations |
|
||||
| `visit` | number | Stage visit count |
|
||||
|
||||
> `agent.skill.expanded` is no longer surfaced as a durable run event. The
|
||||
> internal `AgentEvent::SkillExpanded` variant remains classified as streaming
|
||||
> noise and is not persisted; slash-skill expansion is reported through
|
||||
> `agent.skill.activated` with `source == "slash"` instead.
|
||||
> `agent.skill.expanded` does not exist. The `AgentEvent::SkillExpanded`
|
||||
> variant this note once described has since been removed from the code
|
||||
> entirely; slash-skill expansion is reported through `agent.skill.activated`
|
||||
> with `source == "slash"` instead.
|
||||
|
||||
### `agent.failover`
|
||||
|
||||
|
|
@ -1651,6 +1551,25 @@ Emitted when the agent fails over to a different LLM provider/model.
|
|||
| `to_model` | string | Failover model |
|
||||
| `error` | string | Error that triggered failover |
|
||||
|
||||
### Agent events that are never serialized
|
||||
|
||||
`AgentEvent` also has variants that exist only on the agent session's
|
||||
in-process broadcast channel. `is_streaming_noise()` filters them out before
|
||||
the workflow emitter builds a `RunEvent`, so they never reach the run store,
|
||||
SSE, `fabro events`, or a JSONL sink — they have no envelope, and no external
|
||||
consumer can observe them:
|
||||
|
||||
- `AssistantOutputReplace` — clears in-progress output buffers when a turn is
|
||||
replayed
|
||||
- `TextDelta`, `ReasoningDelta` — streaming assistant chunks
|
||||
- `ToolCallOutputDelta` — streaming tool output chunks
|
||||
|
||||
They were previously documented here as though they were durable events, with
|
||||
full envelope examples. If any of them ever needs to be durable, it belongs in
|
||||
a separate transient stream rather than the canonical persisted contract —
|
||||
long autonomous runs would generate orders of magnitude more delta traffic
|
||||
than the interactive sessions surface handles.
|
||||
|
||||
---
|
||||
|
||||
## Subgraph events
|
||||
|
|
@ -2225,14 +2144,14 @@ These legacy events may appear in older run logs. Current CLI backend runs do no
|
|||
|----------|------|-------------|
|
||||
| `error` | string | Error message |
|
||||
|
||||
## Asset events
|
||||
## Artifact events
|
||||
|
||||
### `asset.captured`
|
||||
### `artifact.captured`
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "...", "ts": "...", "run_id": "...",
|
||||
"event": "asset.captured",
|
||||
"event": "artifact.captured",
|
||||
"node_id": "code",
|
||||
"node_label": "code",
|
||||
"properties": {
|
||||
|
|
|
|||
|
|
@ -423,9 +423,10 @@ These stay outside the durable persisted contract:
|
|||
- `agent.text.delta`
|
||||
- `agent.reasoning.delta`
|
||||
- `agent.tool.output.delta`
|
||||
- `agent.skill.expanded`
|
||||
|
||||
`agent.skill.expanded` stays in this non-durable bucket because it is display-oriented expansion metadata, not a durable workflow fact.
|
||||
(`agent.skill.expanded` was previously listed here. No such event exists — the
|
||||
`AgentEvent::SkillExpanded` variant was removed, and slash-skill expansion is
|
||||
reported through the durable `agent.skill.activated` with `source == "slash"`.)
|
||||
|
||||
If Fabro needs those for UI, they belong in a separate transient stream, not in the canonical persisted Rust event contract.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue