docs(run-journal): specify live-only metering and optional writes (#7272)
This commit is contained in:
1 parent
87338e8098
commit
9b3c749302
2 files changed
+27
-2
No files matched your search
+1
-1
@@ -454,7 +454,7 @@ class RunJournalWriter:
|
||||
self._path = _run_path(self.session_id, self.run_id, session_dir=self.session_dir)
|
||||
self._lock = _lock_for(self._path)
|
||||
|
||||
def append_sse_event(self, event_name: str, payload=None) -> dict:
|
||||
def append_sse_event(self, event_name: str, payload=None) -> dict | None:
|
||||
# Live-UI-only telemetry (metering) has no recovery value in the journal:
|
||||
# nothing reads those rows back for recovery, and journaling them at ~10 Hz
|
||||
# on marathon runs balloons the durable file (12+ MB of a single 18 MB run
|
||||
|
||||
@@ -183,7 +183,7 @@ when integrating with the live chat SSE relay.
|
||||
| `cancel` | Run cancelled |
|
||||
| `done` | Turn finalized (session payload); title/`stream_end` may follow |
|
||||
| `stream_end` | SSE fence — close the client EventSource |
|
||||
| `metering` | Token/cost metering snapshot |
|
||||
| `metering` | Best-effort live token/cost metering snapshot; not journal-replayed |
|
||||
| `context_status` | Context window / usage status |
|
||||
| `goal` | Goal / plan card update |
|
||||
| `goal_continue` | Goal continuation signal |
|
||||
@@ -228,6 +228,31 @@ A future implementation must replay from the run journal via the existing
|
||||
`_replay_run_journal()` path (in `api/routes.py`) and fall back to the
|
||||
snapshot mechanism when journal entries are unavailable for a given cursor.
|
||||
|
||||
### Live-only metering (implemented replay behavior)
|
||||
|
||||
`metering` is best-effort live telemetry, not durable recovery content.
|
||||
`RunJournalWriter.append_sse_event()` returns `None` for metering without
|
||||
writing a row or allocating a sequence number. Other journaled events retain
|
||||
contiguous sequence numbers. Local-agent and gateway producers carry an
|
||||
explicit per-frame event ID, including `None`, through `StreamChannel`;
|
||||
an unjournaled metering frame emits no new SSE `id:` and must not borrow the
|
||||
previous frame's journal ID. The last-ID fallback is limited to legacy
|
||||
two-element queue entries.
|
||||
|
||||
Existing journals are not rewritten. Direct readers (`read_run_events()` and
|
||||
`read_session_run_events()`) retain legacy metering rows for cursor validation
|
||||
and gap/coverage checks. Both run-level and per-session journal replay emitters
|
||||
apply `journal_replay_visible()` to omit those rows from reconnect delivery.
|
||||
Consequently, replayed legacy event IDs can have gaps where metering was
|
||||
filtered; clients must not infer missing durable content from those gaps.
|
||||
Metering missed while disconnected is not recovered from the journal; fresh
|
||||
live updates remain available. This exception does not remove token, reasoning,
|
||||
tool, or terminal events from durable replay.
|
||||
|
||||
Coverage: `tests/test_run_journal.py`, `tests/test_run_journal_routes.py`,
|
||||
`tests/test_issue4812_session_sse_stream.py`, and
|
||||
`tests/test_stage364_opus_live_sse_event_id.py`.
|
||||
|
||||
## Snapshot fallback
|
||||
|
||||
When the `Last-Event-ID` cursor is evicted, expired, unknown, or refers to a
|
||||
|
||||
Reference in new issue
Block a user