fix(agent): handle partial room timestamps without crashing
This commit is contained in:
@@ -627,6 +627,25 @@ messages/DOM grow with explicit older loads and live updates. Offscreen web rows
|
||||
use CSS `content-visibility: auto`, which skips rendering work while retaining
|
||||
chronological DOM, selection, find and accessibility; it is not DOM virtualization.
|
||||
|
||||
Every room message, including protected tool rows and `activity.queuedMessages`,
|
||||
has a string `id`, `role`, `content`, and ISO-8601 `createdAt`. Privacy filtering
|
||||
retains this envelope and tool lifecycle metadata (`kind`, `toolCallId`,
|
||||
`toolName`, `entryId`, `status`, and available `startedAt`/`completedAt`). Protected
|
||||
tools use their public tool name as `content`; private arguments, previews, and
|
||||
errors are withheld. Result-only pages may omit initiation metadata.
|
||||
|
||||
Historical entries without a known time use `1970-01-01T00:00:00.000Z` as an
|
||||
unknown-time sentinel. For compatibility with older partial responses, clients
|
||||
may recover missing/invalid `createdAt` from `metadata.startedAt`, then
|
||||
`metadata.completedAt`, or use that sentinel; never substitute the current time.
|
||||
Older redacted tool rows containing only `id`, `role`, and `name` can retain their
|
||||
identity with a tool-name label until a complete upsert arrives. The web client
|
||||
uses the same normalization for REST, WebSocket, and queued activity, retains
|
||||
known times across partial upserts, and orders by time, numeric `entryId` (when
|
||||
present, before absent), then stable `id`. Unknown times display as “Earlier”
|
||||
without a clock time. Invalid identities or non-tool message bodies reject the
|
||||
page before advancing its replay cursor; timestamps never replace cursors.
|
||||
|
||||
### `POST /v1/agent/messages`
|
||||
|
||||
Body: `{ "content": "Check the oven", "requestId": "client-generated-uuid" }`.
|
||||
|
||||
@@ -326,6 +326,14 @@ with `metadata.kind: "tool_call"`, matching Sybil's tool renderer. REST pages an
|
||||
socket messages are upserts keyed by stable `id`. Save each returned cursor after
|
||||
applying its entire frame, even when it contains no visible messages.
|
||||
|
||||
Both message frames and queued activity use the required message envelope and
|
||||
historical timestamp compatibility rules in [REST room history](./rest.md#get-v1agentmessages).
|
||||
Protected tool redaction preserves `createdAt`, a safe string `content`, and
|
||||
available lifecycle metadata; it does not remove the row's identity or replay
|
||||
metadata. Partial tool results may omit `args`/`startedAt`; merge them without
|
||||
losing a known creation time or downgrading a completed tool on replay. Validate
|
||||
and normalize all rows before applying a frame or advancing its cursor.
|
||||
|
||||
Clients may send `{ "type": "ping" }` (receiving `{ "type": "pong" }`) or
|
||||
`{ "type": "subscribe", "after": "44" }` to change the replay cursor. Transport
|
||||
ping/pong heartbeats detect dead connections. Other writes belong on REST.
|
||||
|
||||
Reference in New Issue
Block a user