diff --git a/shared/fixtures/README.md b/shared/fixtures/README.md index b9367d36..7a7a58fa 100644 --- a/shared/fixtures/README.md +++ b/shared/fixtures/README.md @@ -1,26 +1,75 @@ -# Golden chat fixtures +# Golden protocol fixtures -Machine-generated conformance fixtures for the HAPI chat rendering pipeline. -The **web implementation is the source of truth**: every file under -`chat/` is produced by running the real web pipeline -(`web/src/chat/`: `normalizeDecryptedMessage` → `reduceChatBlocks` → -`buildVisibleChatBlocks`) over hand-authored wire inputs, then applying the -normative projection described below. Native clients (iOS `HapiProtocol`, -Android `:core:protocol`) port that pipeline and must reproduce `expected` -from `input` exactly. +Machine-generated conformance fixtures for the HAPI client protocol. The +**web implementation is the source of truth**: every `expected*` value in +every file is produced by running the real web implementation over +hand-authored wire inputs, then applying the normative projection each suite +documents below. Native clients (iOS `HapiProtocol`, Android +`:core:protocol`) port the same logic and must reproduce the expectations +from the inputs exactly. + +Three suites: + +| Suite | Pins | Web source of truth | +|-------|------|---------------------| +| `chat/` | message decode/render pipeline (normalize → reduce → group) | `web/src/chat/` | +| `sse/` | `session-updated` versioned-patch application | `applySessionDetailPatch` in `web/src/lib/sessionPatch.ts` | +| `pagination/` | message window: paging cursors, epoch resets, optimistic sends, trims | `web/src/lib/message-window-store.ts` + `web/src/lib/messages.ts` | Never edit the JSON by hand — edit the case definitions in -`web/scripts/fixtures/cases/` and regenerate. +`web/scripts/fixtures/` (`cases/`, `sse/cases.ts`, `pagination/cases.ts`) and +regenerate. ## Layout ``` shared/fixtures/ -├── VERSION # current fixtureVersion (single integer + \n) -├── chat/.json # one fixture per case +├── VERSION # current fixtureVersion (single integer + \n) +├── chat/.json # one fixture per case +├── sse/.json +├── pagination/.json └── README.md ``` +## How to consume (all suites) + +- **iOS** (`ios/`, SPM test target): resolve the repo checkout from the test + file's own location and load every `/*.json`, e.g. + `URL(fileURLWithPath: #filePath)` → walk up to the package root → + `../../shared/fixtures`. Decode the inputs, run the ported implementation, + project, and compare against the stored expectations. +- **Android** (`android/`, `:core:protocol` JVM tests): pass the directory via + Gradle — `tasks.withType { systemProperty("hapi.fixtures.dir", + rootDir.resolve("../shared/fixtures")) }` — and read it with + `System.getProperty("hapi.fixtures.dir")` in the test. +- Iterate **all** files in a suite directory (fail on zero files) so newly + added fixtures are picked up without native-side changes. + +### Acceptance bar + +Exact match on the normative projection: serialize your computed output and +the fixture's stored expectation to **canonical JSON** (recursively sorted +object keys; numbers as JSON numbers; no `undefined`/absent-key differences) +and compare for equality. Field order in the files is already canonical +(sorted keys, 4-space indent, LF, trailing newline), so a key-sorted +structural deep-compare is equivalent. + +### fixtureVersion policy + +`fixtureVersion` (mirrored in `VERSION`, shared by all suites) is bumped when +a document schema or a normative projection changes shape. Native suites must +**fail loudly when the on-disk version is newer than the version they +support** (do not silently skip), and should tolerate older versions only if +they explicitly implement them. Additive new fixture *files* and new wire +cases do not bump the version. + +--- + +# Chat suite (`chat/`) + +Runs the real web pipeline (`normalizeDecryptedMessage` → `reduceChatBlocks` +→ `buildVisibleChatBlocks`) over wire messages, then projects. + ## Document schema (`fixtureVersion: 1`) ```jsonc @@ -42,37 +91,8 @@ shared/fixtures/ } ``` -## How to consume - -- **iOS** (`ios/`, SPM test target): resolve the repo checkout from the test - file's own location and load every `chat/*.json`, e.g. - `URL(fileURLWithPath: #filePath)` → walk up to the package root → - `../../shared/fixtures`. Decode `input`, run the ported pipeline, project, - and compare against `expected`. -- **Android** (`android/`, `:core:protocol` JVM tests): pass the directory via - Gradle — `tasks.withType { systemProperty("hapi.fixtures.dir", - rootDir.resolve("../shared/fixtures")) }` — and read it with - `System.getProperty("hapi.fixtures.dir")` in the test. -- Iterate **all** files in `chat/` (fail on zero files) so newly added - fixtures are picked up without native-side changes. - -### Acceptance bar - -Exact match on the normative projection: serialize your projected output and -the fixture's `expected` to **canonical JSON** (recursively sorted object -keys; numbers as JSON numbers; no `undefined`/absent-key differences) and -compare for equality — per fixture, on `blocks`, `hasReadyEvent`, -`latestUsage`, and `visibleBlocks`. Field order in the files is already -canonical (sorted keys, 4-space indent, LF, trailing newline), so a -key-sorted structural deep-compare is equivalent. - -### fixtureVersion policy - -`fixtureVersion` (mirrored in `VERSION`) is bumped when the document schema or -the normative projection changes shape. Native suites must **fail loudly when -the on-disk version is newer than the version they support** (do not silently -skip), and should tolerate older versions only if they explicitly implement -them. Additive new fixture *files* and new wire cases do not bump the version. +Per fixture, the acceptance comparison covers `blocks`, `hasReadyEvent`, +`latestUsage`, and `visibleBlocks`. ## Normative field contract @@ -133,16 +153,166 @@ Tool group: `defaultOpen`, `historyState`, `needsOlderHistory`, `activityTitle`, `presentationMode`, `summary`. Top level: `latestGoal`, `latestUsage.cacheCreation`/`cacheRead`/`model`/`timestamp`. -## Regeneration & drift gate +--- + +# SSE session-patch suite (`sse/`) + +Pins the versioned-patch algorithm for `session-updated` events carrying a +`SessionPatch` (contract: `docs/api/client-contract/sse.md`, "Versioned patch +algorithm"). Expectations are computed by the real web fold — +`applySessionDetailPatch` in `web/src/lib/sessionPatch.ts`. + +## Document schema (`fixtureVersion: 1`) + +```jsonc +{ + "fixtureVersion": 1, + "name": "metadata-newer-version-applied", // equals the file name + "description": "…", + "initialSession": { /* full Session as cached before the first patch */ }, + "patches": [ /* SessionPatch payloads in arrival order */ ], + "expectedPatchResults": [ "applied" | "unchanged", … ], // aligned with patches + "expectedSession": { /* Session after folding all patches */ } +} +``` + +## Replay contract + +Fold over `patches` in order: + +``` +next = applySessionDetailPatch(session, patch) // your port +results[i] = next == null ? "unchanged" : "applied" +session = next ?? session +``` + +Compare `results` against `expectedPatchResults` and the final session +against `expectedSession` (canonical-JSON equality). `unchanged` is +normative: it means the call reported "nothing changed — keep the previous +object identity" (version-gated wrapper, sub-minute `activeAt` keep-alive, +no-op assignment). A port that applies a stale wrapper, or that treats a +keep-alive as a change, fails on the verdict even when the final session +happens to match. + +Both inputs are stored **schema-normalized**: `initialSession` is the parse +output of `SessionSchema` and every patch is the parse output of the strict +`SessionPatchSchema` (zod defaults applied, e.g. `TodoItem.priority`), so +consumers decode the JSON verbatim — no schema re-run needed. The generator +validates every authored patch against the wire schema, and the web +self-check re-validates on every test run, so fixtures cannot drift from +`shared/src/schemas.ts`. + +Behavior deliberately pinned (see the individual descriptions): + +- versioned wrappers (`metadata`/`agentState`/`todos`/`teamState`) apply only + when `version` is **strictly greater** than the cached watermark; equal and + older versions are dropped regardless of value; absent `todosUpdatedAt`/ + `teamStateUpdatedAt` watermarks count as 0 +- `teamState` wrapper with `value: null` clears the field (absent in + `expectedSession`) and still stores the watermark +- `updatedAt` is max-monotonic; an older `updatedAt` alone is `unchanged` +- flat fields are last-write-wins; a `serviceTier` key explicitly present as + `null` clears it +- `activeTurnStartedAt` is **not applied** by the patch path (web behavior: + no assignment branch) — a patch carrying only it is `unchanged` +- a patch whose only effective change is an `activeAt` delta < 60s is + `unchanged` and the cached `activeAt` does **not** move +- `scratchlistUpdatedAt` is a refetch trigger only: `unchanged`, no session + mutation + +--- + +# Pagination suite (`pagination/`) + +Pins the message-window store: paging requests it must issue, epoch-reset +handling, optimistic-send reconciliation, queued-row lifecycle, and window +trimming (contract: `docs/api/client-contract/pagination.md`). Expectations +are recorded from the real web store (`web/src/lib/message-window-store.ts`) +driven by a scripted ApiClient. + +## Document schema (`fixtureVersion: 1`) + +```jsonc +{ + "fixtureVersion": 1, + "name": "older-page-epoch-mismatch-resets", // equals the file name + "description": "…", + "ops": [ /* operation script, in order; see below */ ], + "expectedState": { /* final window projection, see below */ } +} +``` + +## Operations + +Replay each op strictly sequentially against your ported store. Ops that hit +the server carry `responses` — the scripted `GET /messages` replies, consumed +FIFO — and the machine-recorded `expectedRequests`: the exact query objects +the web store sent (`limit` only for a latest page; `beforeAt`+`beforeSeq`+ +`limit` for older pages; `afterAt`+`afterSeq`+`untilAt`+`untilSeq`+`epoch`+ +`limit` for tail catch-up, where `untilAt`/`untilSeq` are `null` on the first +loop request). Your port must issue the same requests in the same order and +consume every scripted response. + +| `op` | Store operation (web name) | Notes | +|------|----------------------------|-------| +| `sync-tail` | `syncTailMessages` | Full tail sync; latest page when no usable cursor, else the after-cursor loop. | +| `fetch-older` | `fetchOlderMessages` | One older page. `expectedOutcome` is `{kind:'applied', hasMore, addedRenderableCount}` or `{kind:'stopped', reason}`. On an epoch mismatch the store runs an internal tail sync — its request/response belong to this same op and the outcome is `stopped`/`epoch-reset`. | +| `sse-messages` | `ingestIncomingMessages` | SSE `message-received` delivery (also advances the newest cursor when an epoch is cached — even past rows the pipeline hides). | +| `append-optimistic` | `appendOptimisticMessage` | Local optimistic row (`id === localId`). Does **not** advance the newest cursor. | +| `update-status` | `updateMessageStatus` | Client send-state transition by `localId`. | +| `messages-consumed` | `markMessagesConsumed` | SSE event: stamp `invokedAt`, flip status to `sent` (skip `failed`), re-sort by position; never advances the newest cursor. | +| `message-cancelled` | `removeOptimisticMessage` | SSE event / optimistic DELETE removal; matches `localId` **or** `id`; idempotent. | +| `cancel-invoked` | remove + append | DELETE answered `{"status":"invoked"}`: remove by `localId`, then ingest the returned `message` with client status `sent` (the harness adds the status). | +| `set-view-mode` | `setMessageViewMode` | `tail` re-entry trims to the visible window and, after a history overflow, forces a latest reset. | +| `queued-state` | reconcile round trip | Collect candidates (user rows with `invokedAt === null`, pinned in `expectedCandidates`, window order), apply `invoked` entries like `messages-consumed`, then drop candidates in neither `queuedLocalIds` nor `invoked`. | + +## `expectedState` projection (normative) + +```jsonc +{ + "messages": [ { "id", "localId", "seq", "createdAt", + "invokedAt"?, // wire tri-state: absent / null / number + "scheduledAt"?, // wire tri-state + "status"?, // client send state when present + "queued": bool, // user row ∧ invokedAt === null ∧ status ≠ 'failed' + "optimistic": bool } ], // localId ∧ id === localId + "hasMore": bool, // older history exists (server flag ∨ trim) + "epoch": number | null, + "viewMode": "tail" | "history", + "olderCursor": { "at", "seq" } | null, // next before-request position + "newestCursor": { "at", "seq" } | null // next after-request position +} +``` + +`messages` order is normative (position order: `at = invokedAt ?? createdAt`, +ties by `seq`). The cursors are the store's compound paging positions (web +internals `oldestPosition*` / `newestPosition*`); everything else that is +web-internal (render/version counters, notification throttling, persistence) +is intentionally NOT part of the contract. + +Determinism notes: the web store's only wall-clock reads gate notification +throttling and never touch this projection, so no time injection is needed — +replays are exact. Fixtures keep every position pair distinct (no `(at, seq)` +ties), so the web's id tie-break (`localeCompare`) never decides an order; +native ports should still break full ties with an ASCII id comparison. + +--- + +# Regeneration & drift gate ```bash bun run gen:fixtures # from the repo root (runs web/scripts/generate-fixtures.ts) ``` Output is byte-deterministic (canonical serialization), so `git status` after -a regeneration is the drift signal: when `web/src/chat/**` changes behavior, -regenerated fixtures differ, the diff gets committed, and the native -conformance suites go red until the ports catch up. The web-side self-check -lives at `web/src/chat/fixtures.test.ts` (runs in `bun run test:web`): it -re-runs the pipeline over every stored `input` and fails on any divergence -from `expected` or from canonical serialization. +a regeneration is the drift signal: when `web/src/chat/**`, +`web/src/lib/sessionPatch.ts`, `web/src/lib/message-window-store.ts` or +`web/src/lib/messages.ts` change behavior, regenerated fixtures differ, the +diff gets committed, and the native conformance suites go red until the ports +catch up. The web-side self-checks (all in `bun run test:web`) re-run every +stored input against the live implementation and fail on any divergence from +the stored expectations or from canonical serialization: + +- `web/src/chat/fixtures.test.ts` — chat suite +- `web/src/lib/sessionPatch.fixtures.test.ts` — sse suite +- `web/src/lib/message-window-store.fixtures.test.ts` — pagination suite diff --git a/shared/fixtures/pagination/cancel-too-late-ingests-invoked-row.json b/shared/fixtures/pagination/cancel-too-late-ingests-invoked-row.json new file mode 100644 index 00000000..93965dd0 --- /dev/null +++ b/shared/fixtures/pagination/cancel-too-late-ingests-invoked-row.json @@ -0,0 +1,91 @@ +{ + "description": "DELETE answered status:invoked (the agent consumed the message before the cancel landed): the queued snapshot must NOT be resurrected — the returned authoritative row is ingested with its server invokedAt and client status sent, landing in the thread at its invocation position.", + "expectedState": { + "epoch": 0, + "hasMore": false, + "messages": [ + { + "createdAt": 1000, + "id": "srv-1", + "invokedAt": 5000, + "localId": "local-1", + "optimistic": false, + "queued": false, + "seq": 1, + "status": "sent" + } + ], + "newestCursor": { + "at": 1000, + "seq": 1 + }, + "olderCursor": { + "at": 1000, + "seq": 1 + }, + "viewMode": "tail" + }, + "fixtureVersion": 1, + "name": "cancel-too-late-ingests-invoked-row", + "ops": [ + { + "expectedRequests": [ + { + "limit": 200 + } + ], + "op": "sync-tail", + "responses": [ + { + "messages": [ + { + "content": { + "content": { + "text": "race with the agent", + "type": "text" + }, + "role": "user" + }, + "createdAt": 1000, + "id": "srv-1", + "invokedAt": null, + "localId": "local-1", + "seq": 1 + } + ], + "page": { + "direction": "latest", + "epoch": 0, + "hasMore": false, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": 1000, + "nextBeforeSeq": 1, + "reset": false, + "snapshotHeadAt": 1000, + "snapshotHeadSeq": 1 + } + } + ] + }, + { + "localId": "local-1", + "message": { + "content": { + "content": { + "text": "race with the agent", + "type": "text" + }, + "role": "user" + }, + "createdAt": 1000, + "id": "srv-1", + "invokedAt": 5000, + "localId": "local-1", + "seq": 1 + }, + "op": "cancel-invoked" + } + ] +} diff --git a/shared/fixtures/pagination/fetch-older-before-cursor.json b/shared/fixtures/pagination/fetch-older-before-cursor.json new file mode 100644 index 00000000..2994a5a9 --- /dev/null +++ b/shared/fixtures/pagination/fetch-older-before-cursor.json @@ -0,0 +1,135 @@ +{ + "description": "Older pagination sends the compound (beforeAt, beforeSeq) pair from the current older cursor, prepends the rows, and adopts the response page.nextBefore as the new older cursor and page.hasMore as the exhaustion flag.", + "expectedState": { + "epoch": 4, + "hasMore": false, + "messages": [ + { + "createdAt": 9000, + "id": "a-9", + "invokedAt": 9000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 9 + }, + { + "createdAt": 10000, + "id": "a-10", + "invokedAt": 10000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 10 + } + ], + "newestCursor": { + "at": 10000, + "seq": 10 + }, + "olderCursor": { + "at": 9000, + "seq": 9 + }, + "viewMode": "tail" + }, + "fixtureVersion": 1, + "name": "fetch-older-before-cursor", + "ops": [ + { + "expectedRequests": [ + { + "limit": 200 + } + ], + "op": "sync-tail", + "responses": [ + { + "messages": [ + { + "content": { + "content": { + "data": { + "message": "a-10", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 10000, + "id": "a-10", + "invokedAt": 10000, + "localId": null, + "seq": 10 + } + ], + "page": { + "direction": "latest", + "epoch": 4, + "hasMore": true, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": 10000, + "nextBeforeSeq": 10, + "reset": false, + "snapshotHeadAt": 10000, + "snapshotHeadSeq": 10 + } + } + ] + }, + { + "expectedOutcome": { + "addedRenderableCount": 1, + "hasMore": false, + "kind": "applied" + }, + "expectedRequests": [ + { + "beforeAt": 10000, + "beforeSeq": 10, + "limit": 200 + } + ], + "op": "fetch-older", + "responses": [ + { + "messages": [ + { + "content": { + "content": { + "data": { + "message": "a-9", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 9000, + "id": "a-9", + "invokedAt": 9000, + "localId": null, + "seq": 9 + } + ], + "page": { + "direction": "before", + "epoch": 4, + "hasMore": false, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": 9000, + "nextBeforeSeq": 9, + "reset": false, + "snapshotHeadAt": null, + "snapshotHeadSeq": null + } + } + ] + } + ] +} diff --git a/shared/fixtures/pagination/latest-page-then-sse-ingest.json b/shared/fixtures/pagination/latest-page-then-sse-ingest.json new file mode 100644 index 00000000..3293a500 --- /dev/null +++ b/shared/fixtures/pagination/latest-page-then-sse-ingest.json @@ -0,0 +1,132 @@ +{ + "description": "Cold start: a latest page seeds the window, epoch, older cursor (page.nextBefore) and newest cursor (page.snapshotHead); a live SSE message appends and advances the newest cursor to its position.", + "expectedState": { + "epoch": 0, + "hasMore": true, + "messages": [ + { + "createdAt": 1000, + "id": "a-1", + "invokedAt": 1000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 1 + }, + { + "createdAt": 2000, + "id": "a-2", + "invokedAt": 2000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 2 + }, + { + "createdAt": 3000, + "id": "a-3", + "invokedAt": 3000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 3 + } + ], + "newestCursor": { + "at": 3000, + "seq": 3 + }, + "olderCursor": { + "at": 1000, + "seq": 1 + }, + "viewMode": "tail" + }, + "fixtureVersion": 1, + "name": "latest-page-then-sse-ingest", + "ops": [ + { + "expectedRequests": [ + { + "limit": 200 + } + ], + "op": "sync-tail", + "responses": [ + { + "messages": [ + { + "content": { + "content": { + "data": { + "message": "a-1", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 1000, + "id": "a-1", + "invokedAt": 1000, + "localId": null, + "seq": 1 + }, + { + "content": { + "content": { + "data": { + "message": "a-2", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 2000, + "id": "a-2", + "invokedAt": 2000, + "localId": null, + "seq": 2 + } + ], + "page": { + "direction": "latest", + "epoch": 0, + "hasMore": true, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": 1000, + "nextBeforeSeq": 1, + "reset": false, + "snapshotHeadAt": 2000, + "snapshotHeadSeq": 2 + } + } + ] + }, + { + "messages": [ + { + "content": { + "content": { + "data": { + "message": "a-3", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 3000, + "id": "a-3", + "invokedAt": 3000, + "localId": null, + "seq": 3 + } + ], + "op": "sse-messages" + } + ] +} diff --git a/shared/fixtures/pagination/message-cancelled-removes-queued-row.json b/shared/fixtures/pagination/message-cancelled-removes-queued-row.json new file mode 100644 index 00000000..5f0de523 --- /dev/null +++ b/shared/fixtures/pagination/message-cancelled-removes-queued-row.json @@ -0,0 +1,41 @@ +{ + "description": "message-cancelled removes the queued row by localId; a repeat delivery is an idempotent no-op on the already-empty window.", + "expectedState": { + "epoch": null, + "hasMore": false, + "messages": [], + "newestCursor": null, + "olderCursor": null, + "viewMode": "tail" + }, + "fixtureVersion": 1, + "name": "message-cancelled-removes-queued-row", + "ops": [ + { + "message": { + "content": { + "content": { + "text": "cancel me", + "type": "text" + }, + "role": "user" + }, + "createdAt": 1000, + "id": "local-1", + "invokedAt": null, + "localId": "local-1", + "seq": null, + "status": "queued" + }, + "op": "append-optimistic" + }, + { + "localId": "local-1", + "op": "message-cancelled" + }, + { + "localId": "local-1", + "op": "message-cancelled" + } + ] +} diff --git a/shared/fixtures/pagination/messages-consumed-stamps-invoked-at.json b/shared/fixtures/pagination/messages-consumed-stamps-invoked-at.json new file mode 100644 index 00000000..88afbe11 --- /dev/null +++ b/shared/fixtures/pagination/messages-consumed-stamps-invoked-at.json @@ -0,0 +1,106 @@ +{ + "description": "messages-consumed stamps invokedAt and flips status to sent: the row leaves the queued bar and moves to its invocation position (after the agent row), while the newest cursor does NOT advance from this out-of-band update.", + "expectedState": { + "epoch": 0, + "hasMore": false, + "messages": [ + { + "createdAt": 2000, + "id": "a-2", + "invokedAt": 2000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 2 + }, + { + "createdAt": 1000, + "id": "q-1", + "invokedAt": 3000, + "localId": "local-1", + "optimistic": false, + "queued": false, + "seq": 1, + "status": "sent" + } + ], + "newestCursor": { + "at": 2000, + "seq": 2 + }, + "olderCursor": { + "at": 1000, + "seq": 1 + }, + "viewMode": "tail" + }, + "fixtureVersion": 1, + "name": "messages-consumed-stamps-invoked-at", + "ops": [ + { + "expectedRequests": [ + { + "limit": 200 + } + ], + "op": "sync-tail", + "responses": [ + { + "messages": [ + { + "content": { + "content": { + "text": "queued question", + "type": "text" + }, + "role": "user" + }, + "createdAt": 1000, + "id": "q-1", + "invokedAt": null, + "localId": "local-1", + "seq": 1 + }, + { + "content": { + "content": { + "data": { + "message": "a-2", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 2000, + "id": "a-2", + "invokedAt": 2000, + "localId": null, + "seq": 2 + } + ], + "page": { + "direction": "latest", + "epoch": 0, + "hasMore": false, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": 1000, + "nextBeforeSeq": 1, + "reset": false, + "snapshotHeadAt": 2000, + "snapshotHeadSeq": 2 + } + } + ] + }, + { + "invokedAt": 3000, + "localIds": [ + "local-1" + ], + "op": "messages-consumed" + } + ] +} diff --git a/shared/fixtures/pagination/older-page-epoch-mismatch-resets.json b/shared/fixtures/pagination/older-page-epoch-mismatch-resets.json new file mode 100644 index 00000000..c9ceeef6 --- /dev/null +++ b/shared/fixtures/pagination/older-page-epoch-mismatch-resets.json @@ -0,0 +1,144 @@ +{ + "description": "An older page answering with a different epoch invalidates every cursor: the load stops with epoch-reset, the window is discarded, and a fresh latest request (issued by the store within the same operation) replaces it wholesale.", + "expectedState": { + "epoch": 2, + "hasMore": false, + "messages": [ + { + "createdAt": 20000, + "id": "f-20", + "invokedAt": 20000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 20 + } + ], + "newestCursor": { + "at": 20000, + "seq": 20 + }, + "olderCursor": { + "at": 20000, + "seq": 20 + }, + "viewMode": "tail" + }, + "fixtureVersion": 1, + "name": "older-page-epoch-mismatch-resets", + "ops": [ + { + "expectedRequests": [ + { + "limit": 200 + } + ], + "op": "sync-tail", + "responses": [ + { + "messages": [ + { + "content": { + "content": { + "data": { + "message": "a-10", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 10000, + "id": "a-10", + "invokedAt": 10000, + "localId": null, + "seq": 10 + } + ], + "page": { + "direction": "latest", + "epoch": 1, + "hasMore": true, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": 10000, + "nextBeforeSeq": 10, + "reset": false, + "snapshotHeadAt": 10000, + "snapshotHeadSeq": 10 + } + } + ] + }, + { + "expectedOutcome": { + "kind": "stopped", + "reason": "epoch-reset" + }, + "expectedRequests": [ + { + "beforeAt": 10000, + "beforeSeq": 10, + "limit": 200 + }, + { + "limit": 200 + } + ], + "op": "fetch-older", + "responses": [ + { + "messages": [], + "page": { + "direction": "before", + "epoch": 2, + "hasMore": false, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": null, + "nextBeforeSeq": null, + "reset": false, + "snapshotHeadAt": null, + "snapshotHeadSeq": null + } + }, + { + "messages": [ + { + "content": { + "content": { + "data": { + "message": "f-20", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 20000, + "id": "f-20", + "invokedAt": 20000, + "localId": null, + "seq": 20 + } + ], + "page": { + "direction": "latest", + "epoch": 2, + "hasMore": false, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": 20000, + "nextBeforeSeq": 20, + "reset": false, + "snapshotHeadAt": 20000, + "snapshotHeadSeq": 20 + } + } + ] + } + ] +} diff --git a/shared/fixtures/pagination/optimistic-echo-reconciles-by-localid.json b/shared/fixtures/pagination/optimistic-echo-reconciles-by-localid.json new file mode 100644 index 00000000..ba0fee09 --- /dev/null +++ b/shared/fixtures/pagination/optimistic-echo-reconciles-by-localid.json @@ -0,0 +1,68 @@ +{ + "description": "The message-received echo of the caller's own send (server id, real seq, same localId) replaces the optimistic row while preserving the client-side status; only one row remains and it is no longer optimistic.", + "expectedState": { + "epoch": null, + "hasMore": false, + "messages": [ + { + "createdAt": 1000, + "id": "srv-1", + "invokedAt": null, + "localId": "local-1", + "optimistic": false, + "queued": true, + "seq": 1, + "status": "queued" + } + ], + "newestCursor": null, + "olderCursor": null, + "viewMode": "tail" + }, + "fixtureVersion": 1, + "name": "optimistic-echo-reconciles-by-localid", + "ops": [ + { + "message": { + "content": { + "content": { + "text": "hello agent", + "type": "text" + }, + "role": "user" + }, + "createdAt": 1000, + "id": "local-1", + "invokedAt": null, + "localId": "local-1", + "seq": null, + "status": "sending" + }, + "op": "append-optimistic" + }, + { + "localId": "local-1", + "op": "update-status", + "status": "queued" + }, + { + "messages": [ + { + "content": { + "content": { + "text": "hello agent", + "type": "text" + }, + "role": "user" + }, + "createdAt": 1000, + "id": "srv-1", + "invokedAt": null, + "localId": "local-1", + "seq": 1 + } + ], + "op": "sse-messages" + } + ] +} diff --git a/shared/fixtures/pagination/queued-state-reconciliation-drops-deleted.json b/shared/fixtures/pagination/queued-state-reconciliation-drops-deleted.json new file mode 100644 index 00000000..0c571ae9 --- /dev/null +++ b/shared/fixtures/pagination/queued-state-reconciliation-drops-deleted.json @@ -0,0 +1,127 @@ +{ + "description": "Queued-state recovery after a resume gap: candidates are the user rows with invokedAt strictly null; the server verdict stamps invoked ones like messages-consumed, keeps the still-queued one, and drops candidates in neither list (deleted server-side).", + "expectedState": { + "epoch": 0, + "hasMore": false, + "messages": [ + { + "createdAt": 2000, + "id": "u-2", + "invokedAt": null, + "localId": "local-kept", + "optimistic": false, + "queued": true, + "seq": 2 + }, + { + "createdAt": 3000, + "id": "u-3", + "invokedAt": 4000, + "localId": "local-consumed", + "optimistic": false, + "queued": false, + "seq": 3, + "status": "sent" + } + ], + "newestCursor": { + "at": 3000, + "seq": 3 + }, + "olderCursor": { + "at": 1000, + "seq": 1 + }, + "viewMode": "tail" + }, + "fixtureVersion": 1, + "name": "queued-state-reconciliation-drops-deleted", + "ops": [ + { + "expectedRequests": [ + { + "limit": 200 + } + ], + "op": "sync-tail", + "responses": [ + { + "messages": [ + { + "content": { + "content": { + "text": "deleted server-side", + "type": "text" + }, + "role": "user" + }, + "createdAt": 1000, + "id": "u-1", + "invokedAt": null, + "localId": "local-stale", + "seq": 1 + }, + { + "content": { + "content": { + "text": "still queued", + "type": "text" + }, + "role": "user" + }, + "createdAt": 2000, + "id": "u-2", + "invokedAt": null, + "localId": "local-kept", + "seq": 2 + }, + { + "content": { + "content": { + "text": "consumed during the gap", + "type": "text" + }, + "role": "user" + }, + "createdAt": 3000, + "id": "u-3", + "invokedAt": null, + "localId": "local-consumed", + "seq": 3 + } + ], + "page": { + "direction": "latest", + "epoch": 0, + "hasMore": false, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": 1000, + "nextBeforeSeq": 1, + "reset": false, + "snapshotHeadAt": 3000, + "snapshotHeadSeq": 3 + } + } + ] + }, + { + "expectedCandidates": [ + "local-stale", + "local-kept", + "local-consumed" + ], + "invoked": [ + { + "invokedAt": 4000, + "localId": "local-consumed" + } + ], + "op": "queued-state", + "queuedLocalIds": [ + "local-kept" + ] + } + ] +} diff --git a/shared/fixtures/pagination/reset-latest-preserves-optimistic.json b/shared/fixtures/pagination/reset-latest-preserves-optimistic.json new file mode 100644 index 00000000..63fdd4b2 --- /dev/null +++ b/shared/fixtures/pagination/reset-latest-preserves-optimistic.json @@ -0,0 +1,152 @@ +{ + "description": "A tail sync that gets page.reset:true replaces every server row from before the request but keeps optimistic rows (id === localId): the not-yet-echoed send survives the epoch bump and the window adopts the new epoch and cursors.", + "expectedState": { + "epoch": 2, + "hasMore": false, + "messages": [ + { + "createdAt": 1500, + "id": "local-1", + "invokedAt": null, + "localId": "local-1", + "optimistic": true, + "queued": true, + "seq": null, + "status": "sending" + }, + { + "createdAt": 2000, + "id": "fresh-2", + "invokedAt": 2000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 2 + } + ], + "newestCursor": { + "at": 2000, + "seq": 2 + }, + "olderCursor": { + "at": 2000, + "seq": 2 + }, + "viewMode": "tail" + }, + "fixtureVersion": 1, + "name": "reset-latest-preserves-optimistic", + "ops": [ + { + "expectedRequests": [ + { + "limit": 200 + } + ], + "op": "sync-tail", + "responses": [ + { + "messages": [ + { + "content": { + "content": { + "data": { + "message": "old-1", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 1000, + "id": "old-1", + "invokedAt": 1000, + "localId": null, + "seq": 1 + } + ], + "page": { + "direction": "latest", + "epoch": 1, + "hasMore": false, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": 1000, + "nextBeforeSeq": 1, + "reset": false, + "snapshotHeadAt": 1000, + "snapshotHeadSeq": 1 + } + } + ] + }, + { + "message": { + "content": { + "content": { + "text": "optimistic send", + "type": "text" + }, + "role": "user" + }, + "createdAt": 1500, + "id": "local-1", + "invokedAt": null, + "localId": "local-1", + "seq": null, + "status": "sending" + }, + "op": "append-optimistic" + }, + { + "expectedRequests": [ + { + "afterAt": 1000, + "afterSeq": 1, + "epoch": 1, + "limit": 200, + "untilAt": null, + "untilSeq": null + } + ], + "op": "sync-tail", + "responses": [ + { + "messages": [ + { + "content": { + "content": { + "data": { + "message": "fresh-2", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 2000, + "id": "fresh-2", + "invokedAt": 2000, + "localId": null, + "seq": 2 + } + ], + "page": { + "direction": "latest", + "epoch": 2, + "hasMore": false, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": 2000, + "nextBeforeSeq": 2, + "reset": true, + "snapshotHeadAt": 2000, + "snapshotHeadSeq": 2 + } + } + ] + } + ] +} diff --git a/shared/fixtures/pagination/sse-hidden-rows-advance-cursor-only.json b/shared/fixtures/pagination/sse-hidden-rows-advance-cursor-only.json new file mode 100644 index 00000000..c50a3e08 --- /dev/null +++ b/shared/fixtures/pagination/sse-hidden-rows-advance-cursor-only.json @@ -0,0 +1,123 @@ +{ + "description": "SSE rows the chat pipeline hides (e.g. meta system output) are not retained in the window, but the newest cursor still advances past their position so a later tail sync does not refetch them.", + "expectedState": { + "epoch": 0, + "hasMore": false, + "messages": [ + { + "createdAt": 1000, + "id": "a-1", + "invokedAt": 1000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 1 + }, + { + "createdAt": 2000, + "id": "a-2", + "invokedAt": 2000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 2 + } + ], + "newestCursor": { + "at": 3000, + "seq": 3 + }, + "olderCursor": { + "at": 1000, + "seq": 1 + }, + "viewMode": "tail" + }, + "fixtureVersion": 1, + "name": "sse-hidden-rows-advance-cursor-only", + "ops": [ + { + "expectedRequests": [ + { + "limit": 200 + } + ], + "op": "sync-tail", + "responses": [ + { + "messages": [ + { + "content": { + "content": { + "data": { + "message": "a-1", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 1000, + "id": "a-1", + "invokedAt": 1000, + "localId": null, + "seq": 1 + } + ], + "page": { + "direction": "latest", + "epoch": 0, + "hasMore": false, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": 1000, + "nextBeforeSeq": 1, + "reset": false, + "snapshotHeadAt": 1000, + "snapshotHeadSeq": 1 + } + } + ] + }, + { + "messages": [ + { + "content": { + "content": { + "data": { + "message": "a-2", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 2000, + "id": "a-2", + "invokedAt": 2000, + "localId": null, + "seq": 2 + }, + { + "content": { + "content": { + "data": { + "isMeta": true, + "type": "system" + }, + "type": "output" + }, + "role": "agent" + }, + "createdAt": 3000, + "id": "hidden-3", + "invokedAt": 3000, + "localId": null, + "seq": 3 + } + ], + "op": "sse-messages" + } + ] +} diff --git a/shared/fixtures/pagination/trim-preserves-queued-and-recomputes-cursor.json b/shared/fixtures/pagination/trim-preserves-queued-and-recomputes-cursor.json new file mode 100644 index 00000000..f6363cab --- /dev/null +++ b/shared/fixtures/pagination/trim-preserves-queued-and-recomputes-cursor.json @@ -0,0 +1,10485 @@ +{ + "description": "Tail-mode overflow past the 400-row visible window trims the oldest regular rows: queued rows are never trimmed (the regular budget shrinks by their count), hasMore flips true, and the older cursor is recomputed from the oldest kept row.", + "expectedState": { + "epoch": 0, + "hasMore": true, + "messages": [ + { + "createdAt": 3000, + "id": "a-003", + "invokedAt": 3000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 3 + }, + { + "createdAt": 4000, + "id": "a-004", + "invokedAt": 4000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 4 + }, + { + "createdAt": 5000, + "id": "a-005", + "invokedAt": 5000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 5 + }, + { + "createdAt": 6000, + "id": "a-006", + "invokedAt": 6000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 6 + }, + { + "createdAt": 7000, + "id": "a-007", + "invokedAt": 7000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 7 + }, + { + "createdAt": 8000, + "id": "a-008", + "invokedAt": 8000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 8 + }, + { + "createdAt": 9000, + "id": "a-009", + "invokedAt": 9000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 9 + }, + { + "createdAt": 10000, + "id": "a-010", + "invokedAt": 10000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 10 + }, + { + "createdAt": 11000, + "id": "a-011", + "invokedAt": 11000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 11 + }, + { + "createdAt": 12000, + "id": "a-012", + "invokedAt": 12000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 12 + }, + { + "createdAt": 13000, + "id": "a-013", + "invokedAt": 13000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 13 + }, + { + "createdAt": 14000, + "id": "a-014", + "invokedAt": 14000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 14 + }, + { + "createdAt": 15000, + "id": "a-015", + "invokedAt": 15000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 15 + }, + { + "createdAt": 16000, + "id": "a-016", + "invokedAt": 16000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 16 + }, + { + "createdAt": 17000, + "id": "a-017", + "invokedAt": 17000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 17 + }, + { + "createdAt": 18000, + "id": "a-018", + "invokedAt": 18000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 18 + }, + { + "createdAt": 19000, + "id": "a-019", + "invokedAt": 19000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 19 + }, + { + "createdAt": 20000, + "id": "a-020", + "invokedAt": 20000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 20 + }, + { + "createdAt": 21000, + "id": "a-021", + "invokedAt": 21000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 21 + }, + { + "createdAt": 22000, + "id": "a-022", + "invokedAt": 22000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 22 + }, + { + "createdAt": 23000, + "id": "a-023", + "invokedAt": 23000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 23 + }, + { + "createdAt": 24000, + "id": "a-024", + "invokedAt": 24000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 24 + }, + { + "createdAt": 25000, + "id": "a-025", + "invokedAt": 25000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 25 + }, + { + "createdAt": 26000, + "id": "a-026", + "invokedAt": 26000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 26 + }, + { + "createdAt": 27000, + "id": "a-027", + "invokedAt": 27000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 27 + }, + { + "createdAt": 28000, + "id": "a-028", + "invokedAt": 28000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 28 + }, + { + "createdAt": 29000, + "id": "a-029", + "invokedAt": 29000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 29 + }, + { + "createdAt": 30000, + "id": "a-030", + "invokedAt": 30000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 30 + }, + { + "createdAt": 31000, + "id": "a-031", + "invokedAt": 31000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 31 + }, + { + "createdAt": 32000, + "id": "a-032", + "invokedAt": 32000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 32 + }, + { + "createdAt": 33000, + "id": "a-033", + "invokedAt": 33000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 33 + }, + { + "createdAt": 34000, + "id": "a-034", + "invokedAt": 34000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 34 + }, + { + "createdAt": 35000, + "id": "a-035", + "invokedAt": 35000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 35 + }, + { + "createdAt": 36000, + "id": "a-036", + "invokedAt": 36000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 36 + }, + { + "createdAt": 37000, + "id": "a-037", + "invokedAt": 37000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 37 + }, + { + "createdAt": 38000, + "id": "a-038", + "invokedAt": 38000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 38 + }, + { + "createdAt": 39000, + "id": "a-039", + "invokedAt": 39000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 39 + }, + { + "createdAt": 40000, + "id": "a-040", + "invokedAt": 40000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 40 + }, + { + "createdAt": 41000, + "id": "a-041", + "invokedAt": 41000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 41 + }, + { + "createdAt": 42000, + "id": "a-042", + "invokedAt": 42000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 42 + }, + { + "createdAt": 43000, + "id": "a-043", + "invokedAt": 43000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 43 + }, + { + "createdAt": 44000, + "id": "a-044", + "invokedAt": 44000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 44 + }, + { + "createdAt": 45000, + "id": "a-045", + "invokedAt": 45000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 45 + }, + { + "createdAt": 46000, + "id": "a-046", + "invokedAt": 46000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 46 + }, + { + "createdAt": 47000, + "id": "a-047", + "invokedAt": 47000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 47 + }, + { + "createdAt": 48000, + "id": "a-048", + "invokedAt": 48000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 48 + }, + { + "createdAt": 49000, + "id": "a-049", + "invokedAt": 49000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 49 + }, + { + "createdAt": 50000, + "id": "a-050", + "invokedAt": 50000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 50 + }, + { + "createdAt": 51000, + "id": "a-051", + "invokedAt": 51000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 51 + }, + { + "createdAt": 52000, + "id": "a-052", + "invokedAt": 52000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 52 + }, + { + "createdAt": 53000, + "id": "a-053", + "invokedAt": 53000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 53 + }, + { + "createdAt": 54000, + "id": "a-054", + "invokedAt": 54000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 54 + }, + { + "createdAt": 55000, + "id": "a-055", + "invokedAt": 55000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 55 + }, + { + "createdAt": 56000, + "id": "a-056", + "invokedAt": 56000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 56 + }, + { + "createdAt": 57000, + "id": "a-057", + "invokedAt": 57000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 57 + }, + { + "createdAt": 58000, + "id": "a-058", + "invokedAt": 58000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 58 + }, + { + "createdAt": 59000, + "id": "a-059", + "invokedAt": 59000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 59 + }, + { + "createdAt": 60000, + "id": "a-060", + "invokedAt": 60000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 60 + }, + { + "createdAt": 61000, + "id": "a-061", + "invokedAt": 61000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 61 + }, + { + "createdAt": 62000, + "id": "a-062", + "invokedAt": 62000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 62 + }, + { + "createdAt": 63000, + "id": "a-063", + "invokedAt": 63000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 63 + }, + { + "createdAt": 64000, + "id": "a-064", + "invokedAt": 64000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 64 + }, + { + "createdAt": 65000, + "id": "a-065", + "invokedAt": 65000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 65 + }, + { + "createdAt": 66000, + "id": "a-066", + "invokedAt": 66000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 66 + }, + { + "createdAt": 67000, + "id": "a-067", + "invokedAt": 67000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 67 + }, + { + "createdAt": 68000, + "id": "a-068", + "invokedAt": 68000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 68 + }, + { + "createdAt": 69000, + "id": "a-069", + "invokedAt": 69000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 69 + }, + { + "createdAt": 70000, + "id": "a-070", + "invokedAt": 70000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 70 + }, + { + "createdAt": 71000, + "id": "a-071", + "invokedAt": 71000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 71 + }, + { + "createdAt": 72000, + "id": "a-072", + "invokedAt": 72000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 72 + }, + { + "createdAt": 73000, + "id": "a-073", + "invokedAt": 73000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 73 + }, + { + "createdAt": 74000, + "id": "a-074", + "invokedAt": 74000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 74 + }, + { + "createdAt": 75000, + "id": "a-075", + "invokedAt": 75000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 75 + }, + { + "createdAt": 76000, + "id": "a-076", + "invokedAt": 76000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 76 + }, + { + "createdAt": 77000, + "id": "a-077", + "invokedAt": 77000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 77 + }, + { + "createdAt": 78000, + "id": "a-078", + "invokedAt": 78000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 78 + }, + { + "createdAt": 79000, + "id": "a-079", + "invokedAt": 79000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 79 + }, + { + "createdAt": 80000, + "id": "a-080", + "invokedAt": 80000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 80 + }, + { + "createdAt": 81000, + "id": "a-081", + "invokedAt": 81000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 81 + }, + { + "createdAt": 82000, + "id": "a-082", + "invokedAt": 82000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 82 + }, + { + "createdAt": 83000, + "id": "a-083", + "invokedAt": 83000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 83 + }, + { + "createdAt": 84000, + "id": "a-084", + "invokedAt": 84000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 84 + }, + { + "createdAt": 85000, + "id": "a-085", + "invokedAt": 85000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 85 + }, + { + "createdAt": 86000, + "id": "a-086", + "invokedAt": 86000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 86 + }, + { + "createdAt": 87000, + "id": "a-087", + "invokedAt": 87000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 87 + }, + { + "createdAt": 88000, + "id": "a-088", + "invokedAt": 88000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 88 + }, + { + "createdAt": 89000, + "id": "a-089", + "invokedAt": 89000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 89 + }, + { + "createdAt": 90000, + "id": "a-090", + "invokedAt": 90000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 90 + }, + { + "createdAt": 91000, + "id": "a-091", + "invokedAt": 91000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 91 + }, + { + "createdAt": 92000, + "id": "a-092", + "invokedAt": 92000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 92 + }, + { + "createdAt": 93000, + "id": "a-093", + "invokedAt": 93000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 93 + }, + { + "createdAt": 94000, + "id": "a-094", + "invokedAt": 94000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 94 + }, + { + "createdAt": 95000, + "id": "a-095", + "invokedAt": 95000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 95 + }, + { + "createdAt": 96000, + "id": "a-096", + "invokedAt": 96000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 96 + }, + { + "createdAt": 97000, + "id": "a-097", + "invokedAt": 97000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 97 + }, + { + "createdAt": 98000, + "id": "a-098", + "invokedAt": 98000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 98 + }, + { + "createdAt": 99000, + "id": "a-099", + "invokedAt": 99000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 99 + }, + { + "createdAt": 100000, + "id": "a-100", + "invokedAt": 100000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 100 + }, + { + "createdAt": 101000, + "id": "a-101", + "invokedAt": 101000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 101 + }, + { + "createdAt": 102000, + "id": "a-102", + "invokedAt": 102000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 102 + }, + { + "createdAt": 103000, + "id": "a-103", + "invokedAt": 103000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 103 + }, + { + "createdAt": 104000, + "id": "a-104", + "invokedAt": 104000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 104 + }, + { + "createdAt": 105000, + "id": "a-105", + "invokedAt": 105000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 105 + }, + { + "createdAt": 106000, + "id": "a-106", + "invokedAt": 106000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 106 + }, + { + "createdAt": 107000, + "id": "a-107", + "invokedAt": 107000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 107 + }, + { + "createdAt": 108000, + "id": "a-108", + "invokedAt": 108000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 108 + }, + { + "createdAt": 109000, + "id": "a-109", + "invokedAt": 109000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 109 + }, + { + "createdAt": 110000, + "id": "a-110", + "invokedAt": 110000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 110 + }, + { + "createdAt": 111000, + "id": "a-111", + "invokedAt": 111000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 111 + }, + { + "createdAt": 112000, + "id": "a-112", + "invokedAt": 112000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 112 + }, + { + "createdAt": 113000, + "id": "a-113", + "invokedAt": 113000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 113 + }, + { + "createdAt": 114000, + "id": "a-114", + "invokedAt": 114000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 114 + }, + { + "createdAt": 115000, + "id": "a-115", + "invokedAt": 115000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 115 + }, + { + "createdAt": 116000, + "id": "a-116", + "invokedAt": 116000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 116 + }, + { + "createdAt": 117000, + "id": "a-117", + "invokedAt": 117000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 117 + }, + { + "createdAt": 118000, + "id": "a-118", + "invokedAt": 118000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 118 + }, + { + "createdAt": 119000, + "id": "a-119", + "invokedAt": 119000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 119 + }, + { + "createdAt": 120000, + "id": "a-120", + "invokedAt": 120000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 120 + }, + { + "createdAt": 121000, + "id": "a-121", + "invokedAt": 121000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 121 + }, + { + "createdAt": 122000, + "id": "a-122", + "invokedAt": 122000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 122 + }, + { + "createdAt": 123000, + "id": "a-123", + "invokedAt": 123000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 123 + }, + { + "createdAt": 124000, + "id": "a-124", + "invokedAt": 124000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 124 + }, + { + "createdAt": 125000, + "id": "a-125", + "invokedAt": 125000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 125 + }, + { + "createdAt": 126000, + "id": "a-126", + "invokedAt": 126000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 126 + }, + { + "createdAt": 127000, + "id": "a-127", + "invokedAt": 127000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 127 + }, + { + "createdAt": 128000, + "id": "a-128", + "invokedAt": 128000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 128 + }, + { + "createdAt": 129000, + "id": "a-129", + "invokedAt": 129000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 129 + }, + { + "createdAt": 130000, + "id": "a-130", + "invokedAt": 130000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 130 + }, + { + "createdAt": 131000, + "id": "a-131", + "invokedAt": 131000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 131 + }, + { + "createdAt": 132000, + "id": "a-132", + "invokedAt": 132000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 132 + }, + { + "createdAt": 133000, + "id": "a-133", + "invokedAt": 133000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 133 + }, + { + "createdAt": 134000, + "id": "a-134", + "invokedAt": 134000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 134 + }, + { + "createdAt": 135000, + "id": "a-135", + "invokedAt": 135000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 135 + }, + { + "createdAt": 136000, + "id": "a-136", + "invokedAt": 136000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 136 + }, + { + "createdAt": 137000, + "id": "a-137", + "invokedAt": 137000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 137 + }, + { + "createdAt": 138000, + "id": "a-138", + "invokedAt": 138000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 138 + }, + { + "createdAt": 139000, + "id": "a-139", + "invokedAt": 139000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 139 + }, + { + "createdAt": 140000, + "id": "a-140", + "invokedAt": 140000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 140 + }, + { + "createdAt": 141000, + "id": "a-141", + "invokedAt": 141000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 141 + }, + { + "createdAt": 142000, + "id": "a-142", + "invokedAt": 142000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 142 + }, + { + "createdAt": 143000, + "id": "a-143", + "invokedAt": 143000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 143 + }, + { + "createdAt": 144000, + "id": "a-144", + "invokedAt": 144000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 144 + }, + { + "createdAt": 145000, + "id": "a-145", + "invokedAt": 145000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 145 + }, + { + "createdAt": 146000, + "id": "a-146", + "invokedAt": 146000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 146 + }, + { + "createdAt": 147000, + "id": "a-147", + "invokedAt": 147000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 147 + }, + { + "createdAt": 148000, + "id": "a-148", + "invokedAt": 148000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 148 + }, + { + "createdAt": 149000, + "id": "a-149", + "invokedAt": 149000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 149 + }, + { + "createdAt": 150000, + "id": "a-150", + "invokedAt": 150000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 150 + }, + { + "createdAt": 151000, + "id": "a-151", + "invokedAt": 151000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 151 + }, + { + "createdAt": 152000, + "id": "a-152", + "invokedAt": 152000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 152 + }, + { + "createdAt": 153000, + "id": "a-153", + "invokedAt": 153000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 153 + }, + { + "createdAt": 154000, + "id": "a-154", + "invokedAt": 154000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 154 + }, + { + "createdAt": 155000, + "id": "a-155", + "invokedAt": 155000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 155 + }, + { + "createdAt": 156000, + "id": "a-156", + "invokedAt": 156000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 156 + }, + { + "createdAt": 157000, + "id": "a-157", + "invokedAt": 157000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 157 + }, + { + "createdAt": 158000, + "id": "a-158", + "invokedAt": 158000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 158 + }, + { + "createdAt": 159000, + "id": "a-159", + "invokedAt": 159000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 159 + }, + { + "createdAt": 160000, + "id": "a-160", + "invokedAt": 160000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 160 + }, + { + "createdAt": 161000, + "id": "a-161", + "invokedAt": 161000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 161 + }, + { + "createdAt": 162000, + "id": "a-162", + "invokedAt": 162000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 162 + }, + { + "createdAt": 163000, + "id": "a-163", + "invokedAt": 163000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 163 + }, + { + "createdAt": 164000, + "id": "a-164", + "invokedAt": 164000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 164 + }, + { + "createdAt": 165000, + "id": "a-165", + "invokedAt": 165000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 165 + }, + { + "createdAt": 166000, + "id": "a-166", + "invokedAt": 166000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 166 + }, + { + "createdAt": 167000, + "id": "a-167", + "invokedAt": 167000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 167 + }, + { + "createdAt": 168000, + "id": "a-168", + "invokedAt": 168000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 168 + }, + { + "createdAt": 169000, + "id": "a-169", + "invokedAt": 169000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 169 + }, + { + "createdAt": 170000, + "id": "a-170", + "invokedAt": 170000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 170 + }, + { + "createdAt": 171000, + "id": "a-171", + "invokedAt": 171000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 171 + }, + { + "createdAt": 172000, + "id": "a-172", + "invokedAt": 172000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 172 + }, + { + "createdAt": 173000, + "id": "a-173", + "invokedAt": 173000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 173 + }, + { + "createdAt": 174000, + "id": "a-174", + "invokedAt": 174000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 174 + }, + { + "createdAt": 175000, + "id": "a-175", + "invokedAt": 175000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 175 + }, + { + "createdAt": 176000, + "id": "a-176", + "invokedAt": 176000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 176 + }, + { + "createdAt": 177000, + "id": "a-177", + "invokedAt": 177000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 177 + }, + { + "createdAt": 178000, + "id": "a-178", + "invokedAt": 178000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 178 + }, + { + "createdAt": 179000, + "id": "a-179", + "invokedAt": 179000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 179 + }, + { + "createdAt": 180000, + "id": "a-180", + "invokedAt": 180000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 180 + }, + { + "createdAt": 181000, + "id": "a-181", + "invokedAt": 181000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 181 + }, + { + "createdAt": 182000, + "id": "a-182", + "invokedAt": 182000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 182 + }, + { + "createdAt": 183000, + "id": "a-183", + "invokedAt": 183000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 183 + }, + { + "createdAt": 184000, + "id": "a-184", + "invokedAt": 184000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 184 + }, + { + "createdAt": 185000, + "id": "a-185", + "invokedAt": 185000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 185 + }, + { + "createdAt": 186000, + "id": "a-186", + "invokedAt": 186000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 186 + }, + { + "createdAt": 187000, + "id": "a-187", + "invokedAt": 187000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 187 + }, + { + "createdAt": 188000, + "id": "a-188", + "invokedAt": 188000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 188 + }, + { + "createdAt": 189000, + "id": "a-189", + "invokedAt": 189000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 189 + }, + { + "createdAt": 190000, + "id": "a-190", + "invokedAt": 190000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 190 + }, + { + "createdAt": 191000, + "id": "a-191", + "invokedAt": 191000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 191 + }, + { + "createdAt": 192000, + "id": "a-192", + "invokedAt": 192000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 192 + }, + { + "createdAt": 193000, + "id": "a-193", + "invokedAt": 193000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 193 + }, + { + "createdAt": 194000, + "id": "a-194", + "invokedAt": 194000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 194 + }, + { + "createdAt": 195000, + "id": "a-195", + "invokedAt": 195000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 195 + }, + { + "createdAt": 196000, + "id": "a-196", + "invokedAt": 196000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 196 + }, + { + "createdAt": 197000, + "id": "a-197", + "invokedAt": 197000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 197 + }, + { + "createdAt": 198000, + "id": "a-198", + "invokedAt": 198000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 198 + }, + { + "createdAt": 199000, + "id": "a-199", + "invokedAt": 199000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 199 + }, + { + "createdAt": 201000, + "id": "a-201", + "invokedAt": 201000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 201 + }, + { + "createdAt": 202000, + "id": "a-202", + "invokedAt": 202000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 202 + }, + { + "createdAt": 203000, + "id": "a-203", + "invokedAt": 203000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 203 + }, + { + "createdAt": 204000, + "id": "a-204", + "invokedAt": 204000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 204 + }, + { + "createdAt": 205000, + "id": "a-205", + "invokedAt": 205000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 205 + }, + { + "createdAt": 206000, + "id": "a-206", + "invokedAt": 206000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 206 + }, + { + "createdAt": 207000, + "id": "a-207", + "invokedAt": 207000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 207 + }, + { + "createdAt": 208000, + "id": "a-208", + "invokedAt": 208000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 208 + }, + { + "createdAt": 209000, + "id": "a-209", + "invokedAt": 209000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 209 + }, + { + "createdAt": 210000, + "id": "a-210", + "invokedAt": 210000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 210 + }, + { + "createdAt": 211000, + "id": "a-211", + "invokedAt": 211000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 211 + }, + { + "createdAt": 212000, + "id": "a-212", + "invokedAt": 212000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 212 + }, + { + "createdAt": 213000, + "id": "a-213", + "invokedAt": 213000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 213 + }, + { + "createdAt": 214000, + "id": "a-214", + "invokedAt": 214000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 214 + }, + { + "createdAt": 215000, + "id": "a-215", + "invokedAt": 215000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 215 + }, + { + "createdAt": 216000, + "id": "a-216", + "invokedAt": 216000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 216 + }, + { + "createdAt": 217000, + "id": "a-217", + "invokedAt": 217000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 217 + }, + { + "createdAt": 218000, + "id": "a-218", + "invokedAt": 218000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 218 + }, + { + "createdAt": 219000, + "id": "a-219", + "invokedAt": 219000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 219 + }, + { + "createdAt": 220000, + "id": "a-220", + "invokedAt": 220000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 220 + }, + { + "createdAt": 221000, + "id": "a-221", + "invokedAt": 221000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 221 + }, + { + "createdAt": 222000, + "id": "a-222", + "invokedAt": 222000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 222 + }, + { + "createdAt": 223000, + "id": "a-223", + "invokedAt": 223000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 223 + }, + { + "createdAt": 224000, + "id": "a-224", + "invokedAt": 224000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 224 + }, + { + "createdAt": 225000, + "id": "a-225", + "invokedAt": 225000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 225 + }, + { + "createdAt": 226000, + "id": "a-226", + "invokedAt": 226000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 226 + }, + { + "createdAt": 227000, + "id": "a-227", + "invokedAt": 227000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 227 + }, + { + "createdAt": 228000, + "id": "a-228", + "invokedAt": 228000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 228 + }, + { + "createdAt": 229000, + "id": "a-229", + "invokedAt": 229000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 229 + }, + { + "createdAt": 230000, + "id": "a-230", + "invokedAt": 230000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 230 + }, + { + "createdAt": 231000, + "id": "a-231", + "invokedAt": 231000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 231 + }, + { + "createdAt": 232000, + "id": "a-232", + "invokedAt": 232000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 232 + }, + { + "createdAt": 233000, + "id": "a-233", + "invokedAt": 233000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 233 + }, + { + "createdAt": 234000, + "id": "a-234", + "invokedAt": 234000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 234 + }, + { + "createdAt": 235000, + "id": "a-235", + "invokedAt": 235000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 235 + }, + { + "createdAt": 236000, + "id": "a-236", + "invokedAt": 236000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 236 + }, + { + "createdAt": 237000, + "id": "a-237", + "invokedAt": 237000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 237 + }, + { + "createdAt": 238000, + "id": "a-238", + "invokedAt": 238000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 238 + }, + { + "createdAt": 239000, + "id": "a-239", + "invokedAt": 239000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 239 + }, + { + "createdAt": 240000, + "id": "a-240", + "invokedAt": 240000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 240 + }, + { + "createdAt": 241000, + "id": "a-241", + "invokedAt": 241000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 241 + }, + { + "createdAt": 242000, + "id": "a-242", + "invokedAt": 242000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 242 + }, + { + "createdAt": 243000, + "id": "a-243", + "invokedAt": 243000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 243 + }, + { + "createdAt": 244000, + "id": "a-244", + "invokedAt": 244000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 244 + }, + { + "createdAt": 245000, + "id": "a-245", + "invokedAt": 245000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 245 + }, + { + "createdAt": 246000, + "id": "a-246", + "invokedAt": 246000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 246 + }, + { + "createdAt": 247000, + "id": "a-247", + "invokedAt": 247000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 247 + }, + { + "createdAt": 248000, + "id": "a-248", + "invokedAt": 248000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 248 + }, + { + "createdAt": 249000, + "id": "a-249", + "invokedAt": 249000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 249 + }, + { + "createdAt": 250000, + "id": "a-250", + "invokedAt": 250000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 250 + }, + { + "createdAt": 251000, + "id": "a-251", + "invokedAt": 251000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 251 + }, + { + "createdAt": 252000, + "id": "a-252", + "invokedAt": 252000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 252 + }, + { + "createdAt": 253000, + "id": "a-253", + "invokedAt": 253000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 253 + }, + { + "createdAt": 254000, + "id": "a-254", + "invokedAt": 254000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 254 + }, + { + "createdAt": 255000, + "id": "a-255", + "invokedAt": 255000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 255 + }, + { + "createdAt": 256000, + "id": "a-256", + "invokedAt": 256000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 256 + }, + { + "createdAt": 257000, + "id": "a-257", + "invokedAt": 257000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 257 + }, + { + "createdAt": 258000, + "id": "a-258", + "invokedAt": 258000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 258 + }, + { + "createdAt": 259000, + "id": "a-259", + "invokedAt": 259000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 259 + }, + { + "createdAt": 260000, + "id": "a-260", + "invokedAt": 260000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 260 + }, + { + "createdAt": 261000, + "id": "a-261", + "invokedAt": 261000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 261 + }, + { + "createdAt": 262000, + "id": "a-262", + "invokedAt": 262000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 262 + }, + { + "createdAt": 263000, + "id": "a-263", + "invokedAt": 263000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 263 + }, + { + "createdAt": 264000, + "id": "a-264", + "invokedAt": 264000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 264 + }, + { + "createdAt": 265000, + "id": "a-265", + "invokedAt": 265000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 265 + }, + { + "createdAt": 266000, + "id": "a-266", + "invokedAt": 266000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 266 + }, + { + "createdAt": 267000, + "id": "a-267", + "invokedAt": 267000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 267 + }, + { + "createdAt": 268000, + "id": "a-268", + "invokedAt": 268000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 268 + }, + { + "createdAt": 269000, + "id": "a-269", + "invokedAt": 269000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 269 + }, + { + "createdAt": 270000, + "id": "a-270", + "invokedAt": 270000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 270 + }, + { + "createdAt": 271000, + "id": "a-271", + "invokedAt": 271000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 271 + }, + { + "createdAt": 272000, + "id": "a-272", + "invokedAt": 272000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 272 + }, + { + "createdAt": 273000, + "id": "a-273", + "invokedAt": 273000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 273 + }, + { + "createdAt": 274000, + "id": "a-274", + "invokedAt": 274000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 274 + }, + { + "createdAt": 275000, + "id": "a-275", + "invokedAt": 275000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 275 + }, + { + "createdAt": 276000, + "id": "a-276", + "invokedAt": 276000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 276 + }, + { + "createdAt": 277000, + "id": "a-277", + "invokedAt": 277000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 277 + }, + { + "createdAt": 278000, + "id": "a-278", + "invokedAt": 278000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 278 + }, + { + "createdAt": 279000, + "id": "a-279", + "invokedAt": 279000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 279 + }, + { + "createdAt": 280000, + "id": "a-280", + "invokedAt": 280000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 280 + }, + { + "createdAt": 281000, + "id": "a-281", + "invokedAt": 281000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 281 + }, + { + "createdAt": 282000, + "id": "a-282", + "invokedAt": 282000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 282 + }, + { + "createdAt": 283000, + "id": "a-283", + "invokedAt": 283000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 283 + }, + { + "createdAt": 284000, + "id": "a-284", + "invokedAt": 284000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 284 + }, + { + "createdAt": 285000, + "id": "a-285", + "invokedAt": 285000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 285 + }, + { + "createdAt": 286000, + "id": "a-286", + "invokedAt": 286000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 286 + }, + { + "createdAt": 287000, + "id": "a-287", + "invokedAt": 287000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 287 + }, + { + "createdAt": 288000, + "id": "a-288", + "invokedAt": 288000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 288 + }, + { + "createdAt": 289000, + "id": "a-289", + "invokedAt": 289000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 289 + }, + { + "createdAt": 290000, + "id": "a-290", + "invokedAt": 290000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 290 + }, + { + "createdAt": 291000, + "id": "a-291", + "invokedAt": 291000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 291 + }, + { + "createdAt": 292000, + "id": "a-292", + "invokedAt": 292000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 292 + }, + { + "createdAt": 293000, + "id": "a-293", + "invokedAt": 293000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 293 + }, + { + "createdAt": 294000, + "id": "a-294", + "invokedAt": 294000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 294 + }, + { + "createdAt": 295000, + "id": "a-295", + "invokedAt": 295000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 295 + }, + { + "createdAt": 296000, + "id": "a-296", + "invokedAt": 296000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 296 + }, + { + "createdAt": 297000, + "id": "a-297", + "invokedAt": 297000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 297 + }, + { + "createdAt": 298000, + "id": "a-298", + "invokedAt": 298000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 298 + }, + { + "createdAt": 299000, + "id": "a-299", + "invokedAt": 299000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 299 + }, + { + "createdAt": 300000, + "id": "a-300", + "invokedAt": 300000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 300 + }, + { + "createdAt": 301000, + "id": "a-301", + "invokedAt": 301000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 301 + }, + { + "createdAt": 302000, + "id": "a-302", + "invokedAt": 302000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 302 + }, + { + "createdAt": 303000, + "id": "a-303", + "invokedAt": 303000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 303 + }, + { + "createdAt": 304000, + "id": "a-304", + "invokedAt": 304000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 304 + }, + { + "createdAt": 305000, + "id": "a-305", + "invokedAt": 305000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 305 + }, + { + "createdAt": 306000, + "id": "a-306", + "invokedAt": 306000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 306 + }, + { + "createdAt": 307000, + "id": "a-307", + "invokedAt": 307000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 307 + }, + { + "createdAt": 308000, + "id": "a-308", + "invokedAt": 308000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 308 + }, + { + "createdAt": 309000, + "id": "a-309", + "invokedAt": 309000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 309 + }, + { + "createdAt": 310000, + "id": "a-310", + "invokedAt": 310000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 310 + }, + { + "createdAt": 311000, + "id": "a-311", + "invokedAt": 311000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 311 + }, + { + "createdAt": 312000, + "id": "a-312", + "invokedAt": 312000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 312 + }, + { + "createdAt": 313000, + "id": "a-313", + "invokedAt": 313000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 313 + }, + { + "createdAt": 314000, + "id": "a-314", + "invokedAt": 314000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 314 + }, + { + "createdAt": 315000, + "id": "a-315", + "invokedAt": 315000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 315 + }, + { + "createdAt": 316000, + "id": "a-316", + "invokedAt": 316000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 316 + }, + { + "createdAt": 317000, + "id": "a-317", + "invokedAt": 317000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 317 + }, + { + "createdAt": 318000, + "id": "a-318", + "invokedAt": 318000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 318 + }, + { + "createdAt": 319000, + "id": "a-319", + "invokedAt": 319000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 319 + }, + { + "createdAt": 320000, + "id": "a-320", + "invokedAt": 320000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 320 + }, + { + "createdAt": 321000, + "id": "a-321", + "invokedAt": 321000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 321 + }, + { + "createdAt": 322000, + "id": "a-322", + "invokedAt": 322000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 322 + }, + { + "createdAt": 323000, + "id": "a-323", + "invokedAt": 323000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 323 + }, + { + "createdAt": 324000, + "id": "a-324", + "invokedAt": 324000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 324 + }, + { + "createdAt": 325000, + "id": "a-325", + "invokedAt": 325000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 325 + }, + { + "createdAt": 326000, + "id": "a-326", + "invokedAt": 326000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 326 + }, + { + "createdAt": 327000, + "id": "a-327", + "invokedAt": 327000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 327 + }, + { + "createdAt": 328000, + "id": "a-328", + "invokedAt": 328000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 328 + }, + { + "createdAt": 329000, + "id": "a-329", + "invokedAt": 329000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 329 + }, + { + "createdAt": 330000, + "id": "a-330", + "invokedAt": 330000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 330 + }, + { + "createdAt": 331000, + "id": "a-331", + "invokedAt": 331000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 331 + }, + { + "createdAt": 332000, + "id": "a-332", + "invokedAt": 332000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 332 + }, + { + "createdAt": 333000, + "id": "a-333", + "invokedAt": 333000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 333 + }, + { + "createdAt": 334000, + "id": "a-334", + "invokedAt": 334000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 334 + }, + { + "createdAt": 335000, + "id": "a-335", + "invokedAt": 335000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 335 + }, + { + "createdAt": 336000, + "id": "a-336", + "invokedAt": 336000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 336 + }, + { + "createdAt": 337000, + "id": "a-337", + "invokedAt": 337000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 337 + }, + { + "createdAt": 338000, + "id": "a-338", + "invokedAt": 338000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 338 + }, + { + "createdAt": 339000, + "id": "a-339", + "invokedAt": 339000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 339 + }, + { + "createdAt": 340000, + "id": "a-340", + "invokedAt": 340000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 340 + }, + { + "createdAt": 341000, + "id": "a-341", + "invokedAt": 341000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 341 + }, + { + "createdAt": 342000, + "id": "a-342", + "invokedAt": 342000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 342 + }, + { + "createdAt": 343000, + "id": "a-343", + "invokedAt": 343000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 343 + }, + { + "createdAt": 344000, + "id": "a-344", + "invokedAt": 344000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 344 + }, + { + "createdAt": 345000, + "id": "a-345", + "invokedAt": 345000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 345 + }, + { + "createdAt": 346000, + "id": "a-346", + "invokedAt": 346000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 346 + }, + { + "createdAt": 347000, + "id": "a-347", + "invokedAt": 347000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 347 + }, + { + "createdAt": 348000, + "id": "a-348", + "invokedAt": 348000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 348 + }, + { + "createdAt": 349000, + "id": "a-349", + "invokedAt": 349000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 349 + }, + { + "createdAt": 350000, + "id": "q-200", + "invokedAt": null, + "localId": "local-q", + "optimistic": false, + "queued": true, + "seq": 200 + }, + { + "createdAt": 350000, + "id": "a-350", + "invokedAt": 350000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 350 + }, + { + "createdAt": 351000, + "id": "a-351", + "invokedAt": 351000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 351 + }, + { + "createdAt": 352000, + "id": "a-352", + "invokedAt": 352000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 352 + }, + { + "createdAt": 353000, + "id": "a-353", + "invokedAt": 353000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 353 + }, + { + "createdAt": 354000, + "id": "a-354", + "invokedAt": 354000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 354 + }, + { + "createdAt": 355000, + "id": "a-355", + "invokedAt": 355000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 355 + }, + { + "createdAt": 356000, + "id": "a-356", + "invokedAt": 356000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 356 + }, + { + "createdAt": 357000, + "id": "a-357", + "invokedAt": 357000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 357 + }, + { + "createdAt": 358000, + "id": "a-358", + "invokedAt": 358000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 358 + }, + { + "createdAt": 359000, + "id": "a-359", + "invokedAt": 359000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 359 + }, + { + "createdAt": 360000, + "id": "a-360", + "invokedAt": 360000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 360 + }, + { + "createdAt": 361000, + "id": "a-361", + "invokedAt": 361000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 361 + }, + { + "createdAt": 362000, + "id": "a-362", + "invokedAt": 362000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 362 + }, + { + "createdAt": 363000, + "id": "a-363", + "invokedAt": 363000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 363 + }, + { + "createdAt": 364000, + "id": "a-364", + "invokedAt": 364000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 364 + }, + { + "createdAt": 365000, + "id": "a-365", + "invokedAt": 365000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 365 + }, + { + "createdAt": 366000, + "id": "a-366", + "invokedAt": 366000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 366 + }, + { + "createdAt": 367000, + "id": "a-367", + "invokedAt": 367000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 367 + }, + { + "createdAt": 368000, + "id": "a-368", + "invokedAt": 368000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 368 + }, + { + "createdAt": 369000, + "id": "a-369", + "invokedAt": 369000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 369 + }, + { + "createdAt": 370000, + "id": "a-370", + "invokedAt": 370000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 370 + }, + { + "createdAt": 371000, + "id": "a-371", + "invokedAt": 371000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 371 + }, + { + "createdAt": 372000, + "id": "a-372", + "invokedAt": 372000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 372 + }, + { + "createdAt": 373000, + "id": "a-373", + "invokedAt": 373000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 373 + }, + { + "createdAt": 374000, + "id": "a-374", + "invokedAt": 374000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 374 + }, + { + "createdAt": 375000, + "id": "a-375", + "invokedAt": 375000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 375 + }, + { + "createdAt": 376000, + "id": "a-376", + "invokedAt": 376000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 376 + }, + { + "createdAt": 377000, + "id": "a-377", + "invokedAt": 377000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 377 + }, + { + "createdAt": 378000, + "id": "a-378", + "invokedAt": 378000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 378 + }, + { + "createdAt": 379000, + "id": "a-379", + "invokedAt": 379000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 379 + }, + { + "createdAt": 380000, + "id": "a-380", + "invokedAt": 380000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 380 + }, + { + "createdAt": 381000, + "id": "a-381", + "invokedAt": 381000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 381 + }, + { + "createdAt": 382000, + "id": "a-382", + "invokedAt": 382000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 382 + }, + { + "createdAt": 383000, + "id": "a-383", + "invokedAt": 383000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 383 + }, + { + "createdAt": 384000, + "id": "a-384", + "invokedAt": 384000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 384 + }, + { + "createdAt": 385000, + "id": "a-385", + "invokedAt": 385000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 385 + }, + { + "createdAt": 386000, + "id": "a-386", + "invokedAt": 386000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 386 + }, + { + "createdAt": 387000, + "id": "a-387", + "invokedAt": 387000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 387 + }, + { + "createdAt": 388000, + "id": "a-388", + "invokedAt": 388000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 388 + }, + { + "createdAt": 389000, + "id": "a-389", + "invokedAt": 389000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 389 + }, + { + "createdAt": 390000, + "id": "a-390", + "invokedAt": 390000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 390 + }, + { + "createdAt": 391000, + "id": "a-391", + "invokedAt": 391000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 391 + }, + { + "createdAt": 392000, + "id": "a-392", + "invokedAt": 392000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 392 + }, + { + "createdAt": 393000, + "id": "a-393", + "invokedAt": 393000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 393 + }, + { + "createdAt": 394000, + "id": "a-394", + "invokedAt": 394000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 394 + }, + { + "createdAt": 395000, + "id": "a-395", + "invokedAt": 395000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 395 + }, + { + "createdAt": 396000, + "id": "a-396", + "invokedAt": 396000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 396 + }, + { + "createdAt": 397000, + "id": "a-397", + "invokedAt": 397000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 397 + }, + { + "createdAt": 398000, + "id": "a-398", + "invokedAt": 398000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 398 + }, + { + "createdAt": 399000, + "id": "a-399", + "invokedAt": 399000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 399 + }, + { + "createdAt": 400000, + "id": "a-400", + "invokedAt": 400000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 400 + }, + { + "createdAt": 401000, + "id": "a-401", + "invokedAt": 401000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 401 + }, + { + "createdAt": 402000, + "id": "a-402", + "invokedAt": 402000, + "localId": null, + "optimistic": false, + "queued": false, + "seq": 402 + } + ], + "newestCursor": { + "at": 402000, + "seq": 402 + }, + "olderCursor": { + "at": 3000, + "seq": 3 + }, + "viewMode": "tail" + }, + "fixtureVersion": 1, + "name": "trim-preserves-queued-and-recomputes-cursor", + "ops": [ + { + "expectedRequests": [ + { + "limit": 200 + } + ], + "op": "sync-tail", + "responses": [ + { + "messages": [ + { + "content": { + "content": { + "data": { + "message": "a-001", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 1000, + "id": "a-001", + "invokedAt": 1000, + "localId": null, + "seq": 1 + }, + { + "content": { + "content": { + "data": { + "message": "a-002", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 2000, + "id": "a-002", + "invokedAt": 2000, + "localId": null, + "seq": 2 + }, + { + "content": { + "content": { + "data": { + "message": "a-003", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 3000, + "id": "a-003", + "invokedAt": 3000, + "localId": null, + "seq": 3 + }, + { + "content": { + "content": { + "data": { + "message": "a-004", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 4000, + "id": "a-004", + "invokedAt": 4000, + "localId": null, + "seq": 4 + }, + { + "content": { + "content": { + "data": { + "message": "a-005", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 5000, + "id": "a-005", + "invokedAt": 5000, + "localId": null, + "seq": 5 + }, + { + "content": { + "content": { + "data": { + "message": "a-006", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 6000, + "id": "a-006", + "invokedAt": 6000, + "localId": null, + "seq": 6 + }, + { + "content": { + "content": { + "data": { + "message": "a-007", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 7000, + "id": "a-007", + "invokedAt": 7000, + "localId": null, + "seq": 7 + }, + { + "content": { + "content": { + "data": { + "message": "a-008", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 8000, + "id": "a-008", + "invokedAt": 8000, + "localId": null, + "seq": 8 + }, + { + "content": { + "content": { + "data": { + "message": "a-009", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 9000, + "id": "a-009", + "invokedAt": 9000, + "localId": null, + "seq": 9 + }, + { + "content": { + "content": { + "data": { + "message": "a-010", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 10000, + "id": "a-010", + "invokedAt": 10000, + "localId": null, + "seq": 10 + }, + { + "content": { + "content": { + "data": { + "message": "a-011", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 11000, + "id": "a-011", + "invokedAt": 11000, + "localId": null, + "seq": 11 + }, + { + "content": { + "content": { + "data": { + "message": "a-012", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 12000, + "id": "a-012", + "invokedAt": 12000, + "localId": null, + "seq": 12 + }, + { + "content": { + "content": { + "data": { + "message": "a-013", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 13000, + "id": "a-013", + "invokedAt": 13000, + "localId": null, + "seq": 13 + }, + { + "content": { + "content": { + "data": { + "message": "a-014", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 14000, + "id": "a-014", + "invokedAt": 14000, + "localId": null, + "seq": 14 + }, + { + "content": { + "content": { + "data": { + "message": "a-015", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 15000, + "id": "a-015", + "invokedAt": 15000, + "localId": null, + "seq": 15 + }, + { + "content": { + "content": { + "data": { + "message": "a-016", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 16000, + "id": "a-016", + "invokedAt": 16000, + "localId": null, + "seq": 16 + }, + { + "content": { + "content": { + "data": { + "message": "a-017", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 17000, + "id": "a-017", + "invokedAt": 17000, + "localId": null, + "seq": 17 + }, + { + "content": { + "content": { + "data": { + "message": "a-018", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 18000, + "id": "a-018", + "invokedAt": 18000, + "localId": null, + "seq": 18 + }, + { + "content": { + "content": { + "data": { + "message": "a-019", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 19000, + "id": "a-019", + "invokedAt": 19000, + "localId": null, + "seq": 19 + }, + { + "content": { + "content": { + "data": { + "message": "a-020", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 20000, + "id": "a-020", + "invokedAt": 20000, + "localId": null, + "seq": 20 + }, + { + "content": { + "content": { + "data": { + "message": "a-021", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 21000, + "id": "a-021", + "invokedAt": 21000, + "localId": null, + "seq": 21 + }, + { + "content": { + "content": { + "data": { + "message": "a-022", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 22000, + "id": "a-022", + "invokedAt": 22000, + "localId": null, + "seq": 22 + }, + { + "content": { + "content": { + "data": { + "message": "a-023", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 23000, + "id": "a-023", + "invokedAt": 23000, + "localId": null, + "seq": 23 + }, + { + "content": { + "content": { + "data": { + "message": "a-024", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 24000, + "id": "a-024", + "invokedAt": 24000, + "localId": null, + "seq": 24 + }, + { + "content": { + "content": { + "data": { + "message": "a-025", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 25000, + "id": "a-025", + "invokedAt": 25000, + "localId": null, + "seq": 25 + }, + { + "content": { + "content": { + "data": { + "message": "a-026", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 26000, + "id": "a-026", + "invokedAt": 26000, + "localId": null, + "seq": 26 + }, + { + "content": { + "content": { + "data": { + "message": "a-027", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 27000, + "id": "a-027", + "invokedAt": 27000, + "localId": null, + "seq": 27 + }, + { + "content": { + "content": { + "data": { + "message": "a-028", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 28000, + "id": "a-028", + "invokedAt": 28000, + "localId": null, + "seq": 28 + }, + { + "content": { + "content": { + "data": { + "message": "a-029", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 29000, + "id": "a-029", + "invokedAt": 29000, + "localId": null, + "seq": 29 + }, + { + "content": { + "content": { + "data": { + "message": "a-030", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 30000, + "id": "a-030", + "invokedAt": 30000, + "localId": null, + "seq": 30 + }, + { + "content": { + "content": { + "data": { + "message": "a-031", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 31000, + "id": "a-031", + "invokedAt": 31000, + "localId": null, + "seq": 31 + }, + { + "content": { + "content": { + "data": { + "message": "a-032", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 32000, + "id": "a-032", + "invokedAt": 32000, + "localId": null, + "seq": 32 + }, + { + "content": { + "content": { + "data": { + "message": "a-033", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 33000, + "id": "a-033", + "invokedAt": 33000, + "localId": null, + "seq": 33 + }, + { + "content": { + "content": { + "data": { + "message": "a-034", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 34000, + "id": "a-034", + "invokedAt": 34000, + "localId": null, + "seq": 34 + }, + { + "content": { + "content": { + "data": { + "message": "a-035", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 35000, + "id": "a-035", + "invokedAt": 35000, + "localId": null, + "seq": 35 + }, + { + "content": { + "content": { + "data": { + "message": "a-036", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 36000, + "id": "a-036", + "invokedAt": 36000, + "localId": null, + "seq": 36 + }, + { + "content": { + "content": { + "data": { + "message": "a-037", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 37000, + "id": "a-037", + "invokedAt": 37000, + "localId": null, + "seq": 37 + }, + { + "content": { + "content": { + "data": { + "message": "a-038", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 38000, + "id": "a-038", + "invokedAt": 38000, + "localId": null, + "seq": 38 + }, + { + "content": { + "content": { + "data": { + "message": "a-039", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 39000, + "id": "a-039", + "invokedAt": 39000, + "localId": null, + "seq": 39 + }, + { + "content": { + "content": { + "data": { + "message": "a-040", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 40000, + "id": "a-040", + "invokedAt": 40000, + "localId": null, + "seq": 40 + }, + { + "content": { + "content": { + "data": { + "message": "a-041", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 41000, + "id": "a-041", + "invokedAt": 41000, + "localId": null, + "seq": 41 + }, + { + "content": { + "content": { + "data": { + "message": "a-042", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 42000, + "id": "a-042", + "invokedAt": 42000, + "localId": null, + "seq": 42 + }, + { + "content": { + "content": { + "data": { + "message": "a-043", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 43000, + "id": "a-043", + "invokedAt": 43000, + "localId": null, + "seq": 43 + }, + { + "content": { + "content": { + "data": { + "message": "a-044", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 44000, + "id": "a-044", + "invokedAt": 44000, + "localId": null, + "seq": 44 + }, + { + "content": { + "content": { + "data": { + "message": "a-045", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 45000, + "id": "a-045", + "invokedAt": 45000, + "localId": null, + "seq": 45 + }, + { + "content": { + "content": { + "data": { + "message": "a-046", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 46000, + "id": "a-046", + "invokedAt": 46000, + "localId": null, + "seq": 46 + }, + { + "content": { + "content": { + "data": { + "message": "a-047", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 47000, + "id": "a-047", + "invokedAt": 47000, + "localId": null, + "seq": 47 + }, + { + "content": { + "content": { + "data": { + "message": "a-048", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 48000, + "id": "a-048", + "invokedAt": 48000, + "localId": null, + "seq": 48 + }, + { + "content": { + "content": { + "data": { + "message": "a-049", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 49000, + "id": "a-049", + "invokedAt": 49000, + "localId": null, + "seq": 49 + }, + { + "content": { + "content": { + "data": { + "message": "a-050", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 50000, + "id": "a-050", + "invokedAt": 50000, + "localId": null, + "seq": 50 + }, + { + "content": { + "content": { + "data": { + "message": "a-051", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 51000, + "id": "a-051", + "invokedAt": 51000, + "localId": null, + "seq": 51 + }, + { + "content": { + "content": { + "data": { + "message": "a-052", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 52000, + "id": "a-052", + "invokedAt": 52000, + "localId": null, + "seq": 52 + }, + { + "content": { + "content": { + "data": { + "message": "a-053", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 53000, + "id": "a-053", + "invokedAt": 53000, + "localId": null, + "seq": 53 + }, + { + "content": { + "content": { + "data": { + "message": "a-054", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 54000, + "id": "a-054", + "invokedAt": 54000, + "localId": null, + "seq": 54 + }, + { + "content": { + "content": { + "data": { + "message": "a-055", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 55000, + "id": "a-055", + "invokedAt": 55000, + "localId": null, + "seq": 55 + }, + { + "content": { + "content": { + "data": { + "message": "a-056", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 56000, + "id": "a-056", + "invokedAt": 56000, + "localId": null, + "seq": 56 + }, + { + "content": { + "content": { + "data": { + "message": "a-057", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 57000, + "id": "a-057", + "invokedAt": 57000, + "localId": null, + "seq": 57 + }, + { + "content": { + "content": { + "data": { + "message": "a-058", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 58000, + "id": "a-058", + "invokedAt": 58000, + "localId": null, + "seq": 58 + }, + { + "content": { + "content": { + "data": { + "message": "a-059", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 59000, + "id": "a-059", + "invokedAt": 59000, + "localId": null, + "seq": 59 + }, + { + "content": { + "content": { + "data": { + "message": "a-060", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 60000, + "id": "a-060", + "invokedAt": 60000, + "localId": null, + "seq": 60 + }, + { + "content": { + "content": { + "data": { + "message": "a-061", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 61000, + "id": "a-061", + "invokedAt": 61000, + "localId": null, + "seq": 61 + }, + { + "content": { + "content": { + "data": { + "message": "a-062", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 62000, + "id": "a-062", + "invokedAt": 62000, + "localId": null, + "seq": 62 + }, + { + "content": { + "content": { + "data": { + "message": "a-063", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 63000, + "id": "a-063", + "invokedAt": 63000, + "localId": null, + "seq": 63 + }, + { + "content": { + "content": { + "data": { + "message": "a-064", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 64000, + "id": "a-064", + "invokedAt": 64000, + "localId": null, + "seq": 64 + }, + { + "content": { + "content": { + "data": { + "message": "a-065", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 65000, + "id": "a-065", + "invokedAt": 65000, + "localId": null, + "seq": 65 + }, + { + "content": { + "content": { + "data": { + "message": "a-066", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 66000, + "id": "a-066", + "invokedAt": 66000, + "localId": null, + "seq": 66 + }, + { + "content": { + "content": { + "data": { + "message": "a-067", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 67000, + "id": "a-067", + "invokedAt": 67000, + "localId": null, + "seq": 67 + }, + { + "content": { + "content": { + "data": { + "message": "a-068", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 68000, + "id": "a-068", + "invokedAt": 68000, + "localId": null, + "seq": 68 + }, + { + "content": { + "content": { + "data": { + "message": "a-069", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 69000, + "id": "a-069", + "invokedAt": 69000, + "localId": null, + "seq": 69 + }, + { + "content": { + "content": { + "data": { + "message": "a-070", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 70000, + "id": "a-070", + "invokedAt": 70000, + "localId": null, + "seq": 70 + }, + { + "content": { + "content": { + "data": { + "message": "a-071", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 71000, + "id": "a-071", + "invokedAt": 71000, + "localId": null, + "seq": 71 + }, + { + "content": { + "content": { + "data": { + "message": "a-072", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 72000, + "id": "a-072", + "invokedAt": 72000, + "localId": null, + "seq": 72 + }, + { + "content": { + "content": { + "data": { + "message": "a-073", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 73000, + "id": "a-073", + "invokedAt": 73000, + "localId": null, + "seq": 73 + }, + { + "content": { + "content": { + "data": { + "message": "a-074", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 74000, + "id": "a-074", + "invokedAt": 74000, + "localId": null, + "seq": 74 + }, + { + "content": { + "content": { + "data": { + "message": "a-075", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 75000, + "id": "a-075", + "invokedAt": 75000, + "localId": null, + "seq": 75 + }, + { + "content": { + "content": { + "data": { + "message": "a-076", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 76000, + "id": "a-076", + "invokedAt": 76000, + "localId": null, + "seq": 76 + }, + { + "content": { + "content": { + "data": { + "message": "a-077", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 77000, + "id": "a-077", + "invokedAt": 77000, + "localId": null, + "seq": 77 + }, + { + "content": { + "content": { + "data": { + "message": "a-078", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 78000, + "id": "a-078", + "invokedAt": 78000, + "localId": null, + "seq": 78 + }, + { + "content": { + "content": { + "data": { + "message": "a-079", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 79000, + "id": "a-079", + "invokedAt": 79000, + "localId": null, + "seq": 79 + }, + { + "content": { + "content": { + "data": { + "message": "a-080", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 80000, + "id": "a-080", + "invokedAt": 80000, + "localId": null, + "seq": 80 + }, + { + "content": { + "content": { + "data": { + "message": "a-081", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 81000, + "id": "a-081", + "invokedAt": 81000, + "localId": null, + "seq": 81 + }, + { + "content": { + "content": { + "data": { + "message": "a-082", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 82000, + "id": "a-082", + "invokedAt": 82000, + "localId": null, + "seq": 82 + }, + { + "content": { + "content": { + "data": { + "message": "a-083", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 83000, + "id": "a-083", + "invokedAt": 83000, + "localId": null, + "seq": 83 + }, + { + "content": { + "content": { + "data": { + "message": "a-084", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 84000, + "id": "a-084", + "invokedAt": 84000, + "localId": null, + "seq": 84 + }, + { + "content": { + "content": { + "data": { + "message": "a-085", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 85000, + "id": "a-085", + "invokedAt": 85000, + "localId": null, + "seq": 85 + }, + { + "content": { + "content": { + "data": { + "message": "a-086", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 86000, + "id": "a-086", + "invokedAt": 86000, + "localId": null, + "seq": 86 + }, + { + "content": { + "content": { + "data": { + "message": "a-087", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 87000, + "id": "a-087", + "invokedAt": 87000, + "localId": null, + "seq": 87 + }, + { + "content": { + "content": { + "data": { + "message": "a-088", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 88000, + "id": "a-088", + "invokedAt": 88000, + "localId": null, + "seq": 88 + }, + { + "content": { + "content": { + "data": { + "message": "a-089", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 89000, + "id": "a-089", + "invokedAt": 89000, + "localId": null, + "seq": 89 + }, + { + "content": { + "content": { + "data": { + "message": "a-090", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 90000, + "id": "a-090", + "invokedAt": 90000, + "localId": null, + "seq": 90 + }, + { + "content": { + "content": { + "data": { + "message": "a-091", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 91000, + "id": "a-091", + "invokedAt": 91000, + "localId": null, + "seq": 91 + }, + { + "content": { + "content": { + "data": { + "message": "a-092", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 92000, + "id": "a-092", + "invokedAt": 92000, + "localId": null, + "seq": 92 + }, + { + "content": { + "content": { + "data": { + "message": "a-093", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 93000, + "id": "a-093", + "invokedAt": 93000, + "localId": null, + "seq": 93 + }, + { + "content": { + "content": { + "data": { + "message": "a-094", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 94000, + "id": "a-094", + "invokedAt": 94000, + "localId": null, + "seq": 94 + }, + { + "content": { + "content": { + "data": { + "message": "a-095", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 95000, + "id": "a-095", + "invokedAt": 95000, + "localId": null, + "seq": 95 + }, + { + "content": { + "content": { + "data": { + "message": "a-096", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 96000, + "id": "a-096", + "invokedAt": 96000, + "localId": null, + "seq": 96 + }, + { + "content": { + "content": { + "data": { + "message": "a-097", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 97000, + "id": "a-097", + "invokedAt": 97000, + "localId": null, + "seq": 97 + }, + { + "content": { + "content": { + "data": { + "message": "a-098", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 98000, + "id": "a-098", + "invokedAt": 98000, + "localId": null, + "seq": 98 + }, + { + "content": { + "content": { + "data": { + "message": "a-099", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 99000, + "id": "a-099", + "invokedAt": 99000, + "localId": null, + "seq": 99 + }, + { + "content": { + "content": { + "data": { + "message": "a-100", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 100000, + "id": "a-100", + "invokedAt": 100000, + "localId": null, + "seq": 100 + }, + { + "content": { + "content": { + "data": { + "message": "a-101", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 101000, + "id": "a-101", + "invokedAt": 101000, + "localId": null, + "seq": 101 + }, + { + "content": { + "content": { + "data": { + "message": "a-102", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 102000, + "id": "a-102", + "invokedAt": 102000, + "localId": null, + "seq": 102 + }, + { + "content": { + "content": { + "data": { + "message": "a-103", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 103000, + "id": "a-103", + "invokedAt": 103000, + "localId": null, + "seq": 103 + }, + { + "content": { + "content": { + "data": { + "message": "a-104", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 104000, + "id": "a-104", + "invokedAt": 104000, + "localId": null, + "seq": 104 + }, + { + "content": { + "content": { + "data": { + "message": "a-105", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 105000, + "id": "a-105", + "invokedAt": 105000, + "localId": null, + "seq": 105 + }, + { + "content": { + "content": { + "data": { + "message": "a-106", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 106000, + "id": "a-106", + "invokedAt": 106000, + "localId": null, + "seq": 106 + }, + { + "content": { + "content": { + "data": { + "message": "a-107", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 107000, + "id": "a-107", + "invokedAt": 107000, + "localId": null, + "seq": 107 + }, + { + "content": { + "content": { + "data": { + "message": "a-108", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 108000, + "id": "a-108", + "invokedAt": 108000, + "localId": null, + "seq": 108 + }, + { + "content": { + "content": { + "data": { + "message": "a-109", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 109000, + "id": "a-109", + "invokedAt": 109000, + "localId": null, + "seq": 109 + }, + { + "content": { + "content": { + "data": { + "message": "a-110", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 110000, + "id": "a-110", + "invokedAt": 110000, + "localId": null, + "seq": 110 + }, + { + "content": { + "content": { + "data": { + "message": "a-111", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 111000, + "id": "a-111", + "invokedAt": 111000, + "localId": null, + "seq": 111 + }, + { + "content": { + "content": { + "data": { + "message": "a-112", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 112000, + "id": "a-112", + "invokedAt": 112000, + "localId": null, + "seq": 112 + }, + { + "content": { + "content": { + "data": { + "message": "a-113", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 113000, + "id": "a-113", + "invokedAt": 113000, + "localId": null, + "seq": 113 + }, + { + "content": { + "content": { + "data": { + "message": "a-114", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 114000, + "id": "a-114", + "invokedAt": 114000, + "localId": null, + "seq": 114 + }, + { + "content": { + "content": { + "data": { + "message": "a-115", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 115000, + "id": "a-115", + "invokedAt": 115000, + "localId": null, + "seq": 115 + }, + { + "content": { + "content": { + "data": { + "message": "a-116", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 116000, + "id": "a-116", + "invokedAt": 116000, + "localId": null, + "seq": 116 + }, + { + "content": { + "content": { + "data": { + "message": "a-117", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 117000, + "id": "a-117", + "invokedAt": 117000, + "localId": null, + "seq": 117 + }, + { + "content": { + "content": { + "data": { + "message": "a-118", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 118000, + "id": "a-118", + "invokedAt": 118000, + "localId": null, + "seq": 118 + }, + { + "content": { + "content": { + "data": { + "message": "a-119", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 119000, + "id": "a-119", + "invokedAt": 119000, + "localId": null, + "seq": 119 + }, + { + "content": { + "content": { + "data": { + "message": "a-120", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 120000, + "id": "a-120", + "invokedAt": 120000, + "localId": null, + "seq": 120 + }, + { + "content": { + "content": { + "data": { + "message": "a-121", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 121000, + "id": "a-121", + "invokedAt": 121000, + "localId": null, + "seq": 121 + }, + { + "content": { + "content": { + "data": { + "message": "a-122", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 122000, + "id": "a-122", + "invokedAt": 122000, + "localId": null, + "seq": 122 + }, + { + "content": { + "content": { + "data": { + "message": "a-123", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 123000, + "id": "a-123", + "invokedAt": 123000, + "localId": null, + "seq": 123 + }, + { + "content": { + "content": { + "data": { + "message": "a-124", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 124000, + "id": "a-124", + "invokedAt": 124000, + "localId": null, + "seq": 124 + }, + { + "content": { + "content": { + "data": { + "message": "a-125", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 125000, + "id": "a-125", + "invokedAt": 125000, + "localId": null, + "seq": 125 + }, + { + "content": { + "content": { + "data": { + "message": "a-126", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 126000, + "id": "a-126", + "invokedAt": 126000, + "localId": null, + "seq": 126 + }, + { + "content": { + "content": { + "data": { + "message": "a-127", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 127000, + "id": "a-127", + "invokedAt": 127000, + "localId": null, + "seq": 127 + }, + { + "content": { + "content": { + "data": { + "message": "a-128", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 128000, + "id": "a-128", + "invokedAt": 128000, + "localId": null, + "seq": 128 + }, + { + "content": { + "content": { + "data": { + "message": "a-129", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 129000, + "id": "a-129", + "invokedAt": 129000, + "localId": null, + "seq": 129 + }, + { + "content": { + "content": { + "data": { + "message": "a-130", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 130000, + "id": "a-130", + "invokedAt": 130000, + "localId": null, + "seq": 130 + }, + { + "content": { + "content": { + "data": { + "message": "a-131", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 131000, + "id": "a-131", + "invokedAt": 131000, + "localId": null, + "seq": 131 + }, + { + "content": { + "content": { + "data": { + "message": "a-132", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 132000, + "id": "a-132", + "invokedAt": 132000, + "localId": null, + "seq": 132 + }, + { + "content": { + "content": { + "data": { + "message": "a-133", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 133000, + "id": "a-133", + "invokedAt": 133000, + "localId": null, + "seq": 133 + }, + { + "content": { + "content": { + "data": { + "message": "a-134", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 134000, + "id": "a-134", + "invokedAt": 134000, + "localId": null, + "seq": 134 + }, + { + "content": { + "content": { + "data": { + "message": "a-135", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 135000, + "id": "a-135", + "invokedAt": 135000, + "localId": null, + "seq": 135 + }, + { + "content": { + "content": { + "data": { + "message": "a-136", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 136000, + "id": "a-136", + "invokedAt": 136000, + "localId": null, + "seq": 136 + }, + { + "content": { + "content": { + "data": { + "message": "a-137", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 137000, + "id": "a-137", + "invokedAt": 137000, + "localId": null, + "seq": 137 + }, + { + "content": { + "content": { + "data": { + "message": "a-138", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 138000, + "id": "a-138", + "invokedAt": 138000, + "localId": null, + "seq": 138 + }, + { + "content": { + "content": { + "data": { + "message": "a-139", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 139000, + "id": "a-139", + "invokedAt": 139000, + "localId": null, + "seq": 139 + }, + { + "content": { + "content": { + "data": { + "message": "a-140", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 140000, + "id": "a-140", + "invokedAt": 140000, + "localId": null, + "seq": 140 + }, + { + "content": { + "content": { + "data": { + "message": "a-141", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 141000, + "id": "a-141", + "invokedAt": 141000, + "localId": null, + "seq": 141 + }, + { + "content": { + "content": { + "data": { + "message": "a-142", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 142000, + "id": "a-142", + "invokedAt": 142000, + "localId": null, + "seq": 142 + }, + { + "content": { + "content": { + "data": { + "message": "a-143", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 143000, + "id": "a-143", + "invokedAt": 143000, + "localId": null, + "seq": 143 + }, + { + "content": { + "content": { + "data": { + "message": "a-144", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 144000, + "id": "a-144", + "invokedAt": 144000, + "localId": null, + "seq": 144 + }, + { + "content": { + "content": { + "data": { + "message": "a-145", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 145000, + "id": "a-145", + "invokedAt": 145000, + "localId": null, + "seq": 145 + }, + { + "content": { + "content": { + "data": { + "message": "a-146", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 146000, + "id": "a-146", + "invokedAt": 146000, + "localId": null, + "seq": 146 + }, + { + "content": { + "content": { + "data": { + "message": "a-147", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 147000, + "id": "a-147", + "invokedAt": 147000, + "localId": null, + "seq": 147 + }, + { + "content": { + "content": { + "data": { + "message": "a-148", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 148000, + "id": "a-148", + "invokedAt": 148000, + "localId": null, + "seq": 148 + }, + { + "content": { + "content": { + "data": { + "message": "a-149", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 149000, + "id": "a-149", + "invokedAt": 149000, + "localId": null, + "seq": 149 + }, + { + "content": { + "content": { + "data": { + "message": "a-150", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 150000, + "id": "a-150", + "invokedAt": 150000, + "localId": null, + "seq": 150 + }, + { + "content": { + "content": { + "data": { + "message": "a-151", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 151000, + "id": "a-151", + "invokedAt": 151000, + "localId": null, + "seq": 151 + }, + { + "content": { + "content": { + "data": { + "message": "a-152", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 152000, + "id": "a-152", + "invokedAt": 152000, + "localId": null, + "seq": 152 + }, + { + "content": { + "content": { + "data": { + "message": "a-153", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 153000, + "id": "a-153", + "invokedAt": 153000, + "localId": null, + "seq": 153 + }, + { + "content": { + "content": { + "data": { + "message": "a-154", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 154000, + "id": "a-154", + "invokedAt": 154000, + "localId": null, + "seq": 154 + }, + { + "content": { + "content": { + "data": { + "message": "a-155", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 155000, + "id": "a-155", + "invokedAt": 155000, + "localId": null, + "seq": 155 + }, + { + "content": { + "content": { + "data": { + "message": "a-156", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 156000, + "id": "a-156", + "invokedAt": 156000, + "localId": null, + "seq": 156 + }, + { + "content": { + "content": { + "data": { + "message": "a-157", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 157000, + "id": "a-157", + "invokedAt": 157000, + "localId": null, + "seq": 157 + }, + { + "content": { + "content": { + "data": { + "message": "a-158", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 158000, + "id": "a-158", + "invokedAt": 158000, + "localId": null, + "seq": 158 + }, + { + "content": { + "content": { + "data": { + "message": "a-159", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 159000, + "id": "a-159", + "invokedAt": 159000, + "localId": null, + "seq": 159 + }, + { + "content": { + "content": { + "data": { + "message": "a-160", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 160000, + "id": "a-160", + "invokedAt": 160000, + "localId": null, + "seq": 160 + }, + { + "content": { + "content": { + "data": { + "message": "a-161", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 161000, + "id": "a-161", + "invokedAt": 161000, + "localId": null, + "seq": 161 + }, + { + "content": { + "content": { + "data": { + "message": "a-162", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 162000, + "id": "a-162", + "invokedAt": 162000, + "localId": null, + "seq": 162 + }, + { + "content": { + "content": { + "data": { + "message": "a-163", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 163000, + "id": "a-163", + "invokedAt": 163000, + "localId": null, + "seq": 163 + }, + { + "content": { + "content": { + "data": { + "message": "a-164", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 164000, + "id": "a-164", + "invokedAt": 164000, + "localId": null, + "seq": 164 + }, + { + "content": { + "content": { + "data": { + "message": "a-165", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 165000, + "id": "a-165", + "invokedAt": 165000, + "localId": null, + "seq": 165 + }, + { + "content": { + "content": { + "data": { + "message": "a-166", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 166000, + "id": "a-166", + "invokedAt": 166000, + "localId": null, + "seq": 166 + }, + { + "content": { + "content": { + "data": { + "message": "a-167", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 167000, + "id": "a-167", + "invokedAt": 167000, + "localId": null, + "seq": 167 + }, + { + "content": { + "content": { + "data": { + "message": "a-168", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 168000, + "id": "a-168", + "invokedAt": 168000, + "localId": null, + "seq": 168 + }, + { + "content": { + "content": { + "data": { + "message": "a-169", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 169000, + "id": "a-169", + "invokedAt": 169000, + "localId": null, + "seq": 169 + }, + { + "content": { + "content": { + "data": { + "message": "a-170", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 170000, + "id": "a-170", + "invokedAt": 170000, + "localId": null, + "seq": 170 + }, + { + "content": { + "content": { + "data": { + "message": "a-171", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 171000, + "id": "a-171", + "invokedAt": 171000, + "localId": null, + "seq": 171 + }, + { + "content": { + "content": { + "data": { + "message": "a-172", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 172000, + "id": "a-172", + "invokedAt": 172000, + "localId": null, + "seq": 172 + }, + { + "content": { + "content": { + "data": { + "message": "a-173", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 173000, + "id": "a-173", + "invokedAt": 173000, + "localId": null, + "seq": 173 + }, + { + "content": { + "content": { + "data": { + "message": "a-174", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 174000, + "id": "a-174", + "invokedAt": 174000, + "localId": null, + "seq": 174 + }, + { + "content": { + "content": { + "data": { + "message": "a-175", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 175000, + "id": "a-175", + "invokedAt": 175000, + "localId": null, + "seq": 175 + }, + { + "content": { + "content": { + "data": { + "message": "a-176", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 176000, + "id": "a-176", + "invokedAt": 176000, + "localId": null, + "seq": 176 + }, + { + "content": { + "content": { + "data": { + "message": "a-177", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 177000, + "id": "a-177", + "invokedAt": 177000, + "localId": null, + "seq": 177 + }, + { + "content": { + "content": { + "data": { + "message": "a-178", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 178000, + "id": "a-178", + "invokedAt": 178000, + "localId": null, + "seq": 178 + }, + { + "content": { + "content": { + "data": { + "message": "a-179", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 179000, + "id": "a-179", + "invokedAt": 179000, + "localId": null, + "seq": 179 + }, + { + "content": { + "content": { + "data": { + "message": "a-180", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 180000, + "id": "a-180", + "invokedAt": 180000, + "localId": null, + "seq": 180 + }, + { + "content": { + "content": { + "data": { + "message": "a-181", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 181000, + "id": "a-181", + "invokedAt": 181000, + "localId": null, + "seq": 181 + }, + { + "content": { + "content": { + "data": { + "message": "a-182", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 182000, + "id": "a-182", + "invokedAt": 182000, + "localId": null, + "seq": 182 + }, + { + "content": { + "content": { + "data": { + "message": "a-183", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 183000, + "id": "a-183", + "invokedAt": 183000, + "localId": null, + "seq": 183 + }, + { + "content": { + "content": { + "data": { + "message": "a-184", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 184000, + "id": "a-184", + "invokedAt": 184000, + "localId": null, + "seq": 184 + }, + { + "content": { + "content": { + "data": { + "message": "a-185", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 185000, + "id": "a-185", + "invokedAt": 185000, + "localId": null, + "seq": 185 + }, + { + "content": { + "content": { + "data": { + "message": "a-186", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 186000, + "id": "a-186", + "invokedAt": 186000, + "localId": null, + "seq": 186 + }, + { + "content": { + "content": { + "data": { + "message": "a-187", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 187000, + "id": "a-187", + "invokedAt": 187000, + "localId": null, + "seq": 187 + }, + { + "content": { + "content": { + "data": { + "message": "a-188", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 188000, + "id": "a-188", + "invokedAt": 188000, + "localId": null, + "seq": 188 + }, + { + "content": { + "content": { + "data": { + "message": "a-189", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 189000, + "id": "a-189", + "invokedAt": 189000, + "localId": null, + "seq": 189 + }, + { + "content": { + "content": { + "data": { + "message": "a-190", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 190000, + "id": "a-190", + "invokedAt": 190000, + "localId": null, + "seq": 190 + }, + { + "content": { + "content": { + "data": { + "message": "a-191", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 191000, + "id": "a-191", + "invokedAt": 191000, + "localId": null, + "seq": 191 + }, + { + "content": { + "content": { + "data": { + "message": "a-192", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 192000, + "id": "a-192", + "invokedAt": 192000, + "localId": null, + "seq": 192 + }, + { + "content": { + "content": { + "data": { + "message": "a-193", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 193000, + "id": "a-193", + "invokedAt": 193000, + "localId": null, + "seq": 193 + }, + { + "content": { + "content": { + "data": { + "message": "a-194", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 194000, + "id": "a-194", + "invokedAt": 194000, + "localId": null, + "seq": 194 + }, + { + "content": { + "content": { + "data": { + "message": "a-195", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 195000, + "id": "a-195", + "invokedAt": 195000, + "localId": null, + "seq": 195 + }, + { + "content": { + "content": { + "data": { + "message": "a-196", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 196000, + "id": "a-196", + "invokedAt": 196000, + "localId": null, + "seq": 196 + }, + { + "content": { + "content": { + "data": { + "message": "a-197", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 197000, + "id": "a-197", + "invokedAt": 197000, + "localId": null, + "seq": 197 + }, + { + "content": { + "content": { + "data": { + "message": "a-198", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 198000, + "id": "a-198", + "invokedAt": 198000, + "localId": null, + "seq": 198 + }, + { + "content": { + "content": { + "data": { + "message": "a-199", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 199000, + "id": "a-199", + "invokedAt": 199000, + "localId": null, + "seq": 199 + }, + { + "content": { + "content": { + "text": "still queued", + "type": "text" + }, + "role": "user" + }, + "createdAt": 350000, + "id": "q-200", + "invokedAt": null, + "localId": "local-q", + "seq": 200 + } + ], + "page": { + "direction": "latest", + "epoch": 0, + "hasMore": false, + "limit": 200, + "nextAfterAt": null, + "nextAfterSeq": null, + "nextBeforeAt": 1000, + "nextBeforeSeq": 1, + "reset": false, + "snapshotHeadAt": 350000, + "snapshotHeadSeq": 200 + } + } + ] + }, + { + "messages": [ + { + "content": { + "content": { + "data": { + "message": "a-201", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 201000, + "id": "a-201", + "invokedAt": 201000, + "localId": null, + "seq": 201 + }, + { + "content": { + "content": { + "data": { + "message": "a-202", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 202000, + "id": "a-202", + "invokedAt": 202000, + "localId": null, + "seq": 202 + }, + { + "content": { + "content": { + "data": { + "message": "a-203", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 203000, + "id": "a-203", + "invokedAt": 203000, + "localId": null, + "seq": 203 + }, + { + "content": { + "content": { + "data": { + "message": "a-204", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 204000, + "id": "a-204", + "invokedAt": 204000, + "localId": null, + "seq": 204 + }, + { + "content": { + "content": { + "data": { + "message": "a-205", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 205000, + "id": "a-205", + "invokedAt": 205000, + "localId": null, + "seq": 205 + }, + { + "content": { + "content": { + "data": { + "message": "a-206", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 206000, + "id": "a-206", + "invokedAt": 206000, + "localId": null, + "seq": 206 + }, + { + "content": { + "content": { + "data": { + "message": "a-207", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 207000, + "id": "a-207", + "invokedAt": 207000, + "localId": null, + "seq": 207 + }, + { + "content": { + "content": { + "data": { + "message": "a-208", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 208000, + "id": "a-208", + "invokedAt": 208000, + "localId": null, + "seq": 208 + }, + { + "content": { + "content": { + "data": { + "message": "a-209", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 209000, + "id": "a-209", + "invokedAt": 209000, + "localId": null, + "seq": 209 + }, + { + "content": { + "content": { + "data": { + "message": "a-210", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 210000, + "id": "a-210", + "invokedAt": 210000, + "localId": null, + "seq": 210 + }, + { + "content": { + "content": { + "data": { + "message": "a-211", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 211000, + "id": "a-211", + "invokedAt": 211000, + "localId": null, + "seq": 211 + }, + { + "content": { + "content": { + "data": { + "message": "a-212", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 212000, + "id": "a-212", + "invokedAt": 212000, + "localId": null, + "seq": 212 + }, + { + "content": { + "content": { + "data": { + "message": "a-213", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 213000, + "id": "a-213", + "invokedAt": 213000, + "localId": null, + "seq": 213 + }, + { + "content": { + "content": { + "data": { + "message": "a-214", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 214000, + "id": "a-214", + "invokedAt": 214000, + "localId": null, + "seq": 214 + }, + { + "content": { + "content": { + "data": { + "message": "a-215", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 215000, + "id": "a-215", + "invokedAt": 215000, + "localId": null, + "seq": 215 + }, + { + "content": { + "content": { + "data": { + "message": "a-216", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 216000, + "id": "a-216", + "invokedAt": 216000, + "localId": null, + "seq": 216 + }, + { + "content": { + "content": { + "data": { + "message": "a-217", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 217000, + "id": "a-217", + "invokedAt": 217000, + "localId": null, + "seq": 217 + }, + { + "content": { + "content": { + "data": { + "message": "a-218", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 218000, + "id": "a-218", + "invokedAt": 218000, + "localId": null, + "seq": 218 + }, + { + "content": { + "content": { + "data": { + "message": "a-219", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 219000, + "id": "a-219", + "invokedAt": 219000, + "localId": null, + "seq": 219 + }, + { + "content": { + "content": { + "data": { + "message": "a-220", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 220000, + "id": "a-220", + "invokedAt": 220000, + "localId": null, + "seq": 220 + }, + { + "content": { + "content": { + "data": { + "message": "a-221", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 221000, + "id": "a-221", + "invokedAt": 221000, + "localId": null, + "seq": 221 + }, + { + "content": { + "content": { + "data": { + "message": "a-222", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 222000, + "id": "a-222", + "invokedAt": 222000, + "localId": null, + "seq": 222 + }, + { + "content": { + "content": { + "data": { + "message": "a-223", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 223000, + "id": "a-223", + "invokedAt": 223000, + "localId": null, + "seq": 223 + }, + { + "content": { + "content": { + "data": { + "message": "a-224", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 224000, + "id": "a-224", + "invokedAt": 224000, + "localId": null, + "seq": 224 + }, + { + "content": { + "content": { + "data": { + "message": "a-225", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 225000, + "id": "a-225", + "invokedAt": 225000, + "localId": null, + "seq": 225 + }, + { + "content": { + "content": { + "data": { + "message": "a-226", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 226000, + "id": "a-226", + "invokedAt": 226000, + "localId": null, + "seq": 226 + }, + { + "content": { + "content": { + "data": { + "message": "a-227", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 227000, + "id": "a-227", + "invokedAt": 227000, + "localId": null, + "seq": 227 + }, + { + "content": { + "content": { + "data": { + "message": "a-228", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 228000, + "id": "a-228", + "invokedAt": 228000, + "localId": null, + "seq": 228 + }, + { + "content": { + "content": { + "data": { + "message": "a-229", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 229000, + "id": "a-229", + "invokedAt": 229000, + "localId": null, + "seq": 229 + }, + { + "content": { + "content": { + "data": { + "message": "a-230", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 230000, + "id": "a-230", + "invokedAt": 230000, + "localId": null, + "seq": 230 + }, + { + "content": { + "content": { + "data": { + "message": "a-231", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 231000, + "id": "a-231", + "invokedAt": 231000, + "localId": null, + "seq": 231 + }, + { + "content": { + "content": { + "data": { + "message": "a-232", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 232000, + "id": "a-232", + "invokedAt": 232000, + "localId": null, + "seq": 232 + }, + { + "content": { + "content": { + "data": { + "message": "a-233", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 233000, + "id": "a-233", + "invokedAt": 233000, + "localId": null, + "seq": 233 + }, + { + "content": { + "content": { + "data": { + "message": "a-234", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 234000, + "id": "a-234", + "invokedAt": 234000, + "localId": null, + "seq": 234 + }, + { + "content": { + "content": { + "data": { + "message": "a-235", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 235000, + "id": "a-235", + "invokedAt": 235000, + "localId": null, + "seq": 235 + }, + { + "content": { + "content": { + "data": { + "message": "a-236", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 236000, + "id": "a-236", + "invokedAt": 236000, + "localId": null, + "seq": 236 + }, + { + "content": { + "content": { + "data": { + "message": "a-237", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 237000, + "id": "a-237", + "invokedAt": 237000, + "localId": null, + "seq": 237 + }, + { + "content": { + "content": { + "data": { + "message": "a-238", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 238000, + "id": "a-238", + "invokedAt": 238000, + "localId": null, + "seq": 238 + }, + { + "content": { + "content": { + "data": { + "message": "a-239", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 239000, + "id": "a-239", + "invokedAt": 239000, + "localId": null, + "seq": 239 + }, + { + "content": { + "content": { + "data": { + "message": "a-240", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 240000, + "id": "a-240", + "invokedAt": 240000, + "localId": null, + "seq": 240 + }, + { + "content": { + "content": { + "data": { + "message": "a-241", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 241000, + "id": "a-241", + "invokedAt": 241000, + "localId": null, + "seq": 241 + }, + { + "content": { + "content": { + "data": { + "message": "a-242", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 242000, + "id": "a-242", + "invokedAt": 242000, + "localId": null, + "seq": 242 + }, + { + "content": { + "content": { + "data": { + "message": "a-243", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 243000, + "id": "a-243", + "invokedAt": 243000, + "localId": null, + "seq": 243 + }, + { + "content": { + "content": { + "data": { + "message": "a-244", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 244000, + "id": "a-244", + "invokedAt": 244000, + "localId": null, + "seq": 244 + }, + { + "content": { + "content": { + "data": { + "message": "a-245", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 245000, + "id": "a-245", + "invokedAt": 245000, + "localId": null, + "seq": 245 + }, + { + "content": { + "content": { + "data": { + "message": "a-246", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 246000, + "id": "a-246", + "invokedAt": 246000, + "localId": null, + "seq": 246 + }, + { + "content": { + "content": { + "data": { + "message": "a-247", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 247000, + "id": "a-247", + "invokedAt": 247000, + "localId": null, + "seq": 247 + }, + { + "content": { + "content": { + "data": { + "message": "a-248", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 248000, + "id": "a-248", + "invokedAt": 248000, + "localId": null, + "seq": 248 + }, + { + "content": { + "content": { + "data": { + "message": "a-249", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 249000, + "id": "a-249", + "invokedAt": 249000, + "localId": null, + "seq": 249 + }, + { + "content": { + "content": { + "data": { + "message": "a-250", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 250000, + "id": "a-250", + "invokedAt": 250000, + "localId": null, + "seq": 250 + }, + { + "content": { + "content": { + "data": { + "message": "a-251", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 251000, + "id": "a-251", + "invokedAt": 251000, + "localId": null, + "seq": 251 + }, + { + "content": { + "content": { + "data": { + "message": "a-252", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 252000, + "id": "a-252", + "invokedAt": 252000, + "localId": null, + "seq": 252 + }, + { + "content": { + "content": { + "data": { + "message": "a-253", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 253000, + "id": "a-253", + "invokedAt": 253000, + "localId": null, + "seq": 253 + }, + { + "content": { + "content": { + "data": { + "message": "a-254", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 254000, + "id": "a-254", + "invokedAt": 254000, + "localId": null, + "seq": 254 + }, + { + "content": { + "content": { + "data": { + "message": "a-255", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 255000, + "id": "a-255", + "invokedAt": 255000, + "localId": null, + "seq": 255 + }, + { + "content": { + "content": { + "data": { + "message": "a-256", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 256000, + "id": "a-256", + "invokedAt": 256000, + "localId": null, + "seq": 256 + }, + { + "content": { + "content": { + "data": { + "message": "a-257", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 257000, + "id": "a-257", + "invokedAt": 257000, + "localId": null, + "seq": 257 + }, + { + "content": { + "content": { + "data": { + "message": "a-258", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 258000, + "id": "a-258", + "invokedAt": 258000, + "localId": null, + "seq": 258 + }, + { + "content": { + "content": { + "data": { + "message": "a-259", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 259000, + "id": "a-259", + "invokedAt": 259000, + "localId": null, + "seq": 259 + }, + { + "content": { + "content": { + "data": { + "message": "a-260", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 260000, + "id": "a-260", + "invokedAt": 260000, + "localId": null, + "seq": 260 + }, + { + "content": { + "content": { + "data": { + "message": "a-261", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 261000, + "id": "a-261", + "invokedAt": 261000, + "localId": null, + "seq": 261 + }, + { + "content": { + "content": { + "data": { + "message": "a-262", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 262000, + "id": "a-262", + "invokedAt": 262000, + "localId": null, + "seq": 262 + }, + { + "content": { + "content": { + "data": { + "message": "a-263", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 263000, + "id": "a-263", + "invokedAt": 263000, + "localId": null, + "seq": 263 + }, + { + "content": { + "content": { + "data": { + "message": "a-264", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 264000, + "id": "a-264", + "invokedAt": 264000, + "localId": null, + "seq": 264 + }, + { + "content": { + "content": { + "data": { + "message": "a-265", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 265000, + "id": "a-265", + "invokedAt": 265000, + "localId": null, + "seq": 265 + }, + { + "content": { + "content": { + "data": { + "message": "a-266", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 266000, + "id": "a-266", + "invokedAt": 266000, + "localId": null, + "seq": 266 + }, + { + "content": { + "content": { + "data": { + "message": "a-267", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 267000, + "id": "a-267", + "invokedAt": 267000, + "localId": null, + "seq": 267 + }, + { + "content": { + "content": { + "data": { + "message": "a-268", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 268000, + "id": "a-268", + "invokedAt": 268000, + "localId": null, + "seq": 268 + }, + { + "content": { + "content": { + "data": { + "message": "a-269", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 269000, + "id": "a-269", + "invokedAt": 269000, + "localId": null, + "seq": 269 + }, + { + "content": { + "content": { + "data": { + "message": "a-270", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 270000, + "id": "a-270", + "invokedAt": 270000, + "localId": null, + "seq": 270 + }, + { + "content": { + "content": { + "data": { + "message": "a-271", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 271000, + "id": "a-271", + "invokedAt": 271000, + "localId": null, + "seq": 271 + }, + { + "content": { + "content": { + "data": { + "message": "a-272", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 272000, + "id": "a-272", + "invokedAt": 272000, + "localId": null, + "seq": 272 + }, + { + "content": { + "content": { + "data": { + "message": "a-273", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 273000, + "id": "a-273", + "invokedAt": 273000, + "localId": null, + "seq": 273 + }, + { + "content": { + "content": { + "data": { + "message": "a-274", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 274000, + "id": "a-274", + "invokedAt": 274000, + "localId": null, + "seq": 274 + }, + { + "content": { + "content": { + "data": { + "message": "a-275", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 275000, + "id": "a-275", + "invokedAt": 275000, + "localId": null, + "seq": 275 + }, + { + "content": { + "content": { + "data": { + "message": "a-276", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 276000, + "id": "a-276", + "invokedAt": 276000, + "localId": null, + "seq": 276 + }, + { + "content": { + "content": { + "data": { + "message": "a-277", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 277000, + "id": "a-277", + "invokedAt": 277000, + "localId": null, + "seq": 277 + }, + { + "content": { + "content": { + "data": { + "message": "a-278", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 278000, + "id": "a-278", + "invokedAt": 278000, + "localId": null, + "seq": 278 + }, + { + "content": { + "content": { + "data": { + "message": "a-279", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 279000, + "id": "a-279", + "invokedAt": 279000, + "localId": null, + "seq": 279 + }, + { + "content": { + "content": { + "data": { + "message": "a-280", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 280000, + "id": "a-280", + "invokedAt": 280000, + "localId": null, + "seq": 280 + }, + { + "content": { + "content": { + "data": { + "message": "a-281", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 281000, + "id": "a-281", + "invokedAt": 281000, + "localId": null, + "seq": 281 + }, + { + "content": { + "content": { + "data": { + "message": "a-282", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 282000, + "id": "a-282", + "invokedAt": 282000, + "localId": null, + "seq": 282 + }, + { + "content": { + "content": { + "data": { + "message": "a-283", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 283000, + "id": "a-283", + "invokedAt": 283000, + "localId": null, + "seq": 283 + }, + { + "content": { + "content": { + "data": { + "message": "a-284", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 284000, + "id": "a-284", + "invokedAt": 284000, + "localId": null, + "seq": 284 + }, + { + "content": { + "content": { + "data": { + "message": "a-285", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 285000, + "id": "a-285", + "invokedAt": 285000, + "localId": null, + "seq": 285 + }, + { + "content": { + "content": { + "data": { + "message": "a-286", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 286000, + "id": "a-286", + "invokedAt": 286000, + "localId": null, + "seq": 286 + }, + { + "content": { + "content": { + "data": { + "message": "a-287", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 287000, + "id": "a-287", + "invokedAt": 287000, + "localId": null, + "seq": 287 + }, + { + "content": { + "content": { + "data": { + "message": "a-288", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 288000, + "id": "a-288", + "invokedAt": 288000, + "localId": null, + "seq": 288 + }, + { + "content": { + "content": { + "data": { + "message": "a-289", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 289000, + "id": "a-289", + "invokedAt": 289000, + "localId": null, + "seq": 289 + }, + { + "content": { + "content": { + "data": { + "message": "a-290", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 290000, + "id": "a-290", + "invokedAt": 290000, + "localId": null, + "seq": 290 + }, + { + "content": { + "content": { + "data": { + "message": "a-291", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 291000, + "id": "a-291", + "invokedAt": 291000, + "localId": null, + "seq": 291 + }, + { + "content": { + "content": { + "data": { + "message": "a-292", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 292000, + "id": "a-292", + "invokedAt": 292000, + "localId": null, + "seq": 292 + }, + { + "content": { + "content": { + "data": { + "message": "a-293", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 293000, + "id": "a-293", + "invokedAt": 293000, + "localId": null, + "seq": 293 + }, + { + "content": { + "content": { + "data": { + "message": "a-294", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 294000, + "id": "a-294", + "invokedAt": 294000, + "localId": null, + "seq": 294 + }, + { + "content": { + "content": { + "data": { + "message": "a-295", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 295000, + "id": "a-295", + "invokedAt": 295000, + "localId": null, + "seq": 295 + }, + { + "content": { + "content": { + "data": { + "message": "a-296", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 296000, + "id": "a-296", + "invokedAt": 296000, + "localId": null, + "seq": 296 + }, + { + "content": { + "content": { + "data": { + "message": "a-297", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 297000, + "id": "a-297", + "invokedAt": 297000, + "localId": null, + "seq": 297 + }, + { + "content": { + "content": { + "data": { + "message": "a-298", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 298000, + "id": "a-298", + "invokedAt": 298000, + "localId": null, + "seq": 298 + }, + { + "content": { + "content": { + "data": { + "message": "a-299", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 299000, + "id": "a-299", + "invokedAt": 299000, + "localId": null, + "seq": 299 + }, + { + "content": { + "content": { + "data": { + "message": "a-300", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 300000, + "id": "a-300", + "invokedAt": 300000, + "localId": null, + "seq": 300 + }, + { + "content": { + "content": { + "data": { + "message": "a-301", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 301000, + "id": "a-301", + "invokedAt": 301000, + "localId": null, + "seq": 301 + }, + { + "content": { + "content": { + "data": { + "message": "a-302", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 302000, + "id": "a-302", + "invokedAt": 302000, + "localId": null, + "seq": 302 + }, + { + "content": { + "content": { + "data": { + "message": "a-303", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 303000, + "id": "a-303", + "invokedAt": 303000, + "localId": null, + "seq": 303 + }, + { + "content": { + "content": { + "data": { + "message": "a-304", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 304000, + "id": "a-304", + "invokedAt": 304000, + "localId": null, + "seq": 304 + }, + { + "content": { + "content": { + "data": { + "message": "a-305", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 305000, + "id": "a-305", + "invokedAt": 305000, + "localId": null, + "seq": 305 + }, + { + "content": { + "content": { + "data": { + "message": "a-306", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 306000, + "id": "a-306", + "invokedAt": 306000, + "localId": null, + "seq": 306 + }, + { + "content": { + "content": { + "data": { + "message": "a-307", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 307000, + "id": "a-307", + "invokedAt": 307000, + "localId": null, + "seq": 307 + }, + { + "content": { + "content": { + "data": { + "message": "a-308", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 308000, + "id": "a-308", + "invokedAt": 308000, + "localId": null, + "seq": 308 + }, + { + "content": { + "content": { + "data": { + "message": "a-309", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 309000, + "id": "a-309", + "invokedAt": 309000, + "localId": null, + "seq": 309 + }, + { + "content": { + "content": { + "data": { + "message": "a-310", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 310000, + "id": "a-310", + "invokedAt": 310000, + "localId": null, + "seq": 310 + }, + { + "content": { + "content": { + "data": { + "message": "a-311", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 311000, + "id": "a-311", + "invokedAt": 311000, + "localId": null, + "seq": 311 + }, + { + "content": { + "content": { + "data": { + "message": "a-312", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 312000, + "id": "a-312", + "invokedAt": 312000, + "localId": null, + "seq": 312 + }, + { + "content": { + "content": { + "data": { + "message": "a-313", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 313000, + "id": "a-313", + "invokedAt": 313000, + "localId": null, + "seq": 313 + }, + { + "content": { + "content": { + "data": { + "message": "a-314", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 314000, + "id": "a-314", + "invokedAt": 314000, + "localId": null, + "seq": 314 + }, + { + "content": { + "content": { + "data": { + "message": "a-315", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 315000, + "id": "a-315", + "invokedAt": 315000, + "localId": null, + "seq": 315 + }, + { + "content": { + "content": { + "data": { + "message": "a-316", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 316000, + "id": "a-316", + "invokedAt": 316000, + "localId": null, + "seq": 316 + }, + { + "content": { + "content": { + "data": { + "message": "a-317", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 317000, + "id": "a-317", + "invokedAt": 317000, + "localId": null, + "seq": 317 + }, + { + "content": { + "content": { + "data": { + "message": "a-318", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 318000, + "id": "a-318", + "invokedAt": 318000, + "localId": null, + "seq": 318 + }, + { + "content": { + "content": { + "data": { + "message": "a-319", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 319000, + "id": "a-319", + "invokedAt": 319000, + "localId": null, + "seq": 319 + }, + { + "content": { + "content": { + "data": { + "message": "a-320", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 320000, + "id": "a-320", + "invokedAt": 320000, + "localId": null, + "seq": 320 + }, + { + "content": { + "content": { + "data": { + "message": "a-321", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 321000, + "id": "a-321", + "invokedAt": 321000, + "localId": null, + "seq": 321 + }, + { + "content": { + "content": { + "data": { + "message": "a-322", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 322000, + "id": "a-322", + "invokedAt": 322000, + "localId": null, + "seq": 322 + }, + { + "content": { + "content": { + "data": { + "message": "a-323", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 323000, + "id": "a-323", + "invokedAt": 323000, + "localId": null, + "seq": 323 + }, + { + "content": { + "content": { + "data": { + "message": "a-324", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 324000, + "id": "a-324", + "invokedAt": 324000, + "localId": null, + "seq": 324 + }, + { + "content": { + "content": { + "data": { + "message": "a-325", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 325000, + "id": "a-325", + "invokedAt": 325000, + "localId": null, + "seq": 325 + }, + { + "content": { + "content": { + "data": { + "message": "a-326", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 326000, + "id": "a-326", + "invokedAt": 326000, + "localId": null, + "seq": 326 + }, + { + "content": { + "content": { + "data": { + "message": "a-327", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 327000, + "id": "a-327", + "invokedAt": 327000, + "localId": null, + "seq": 327 + }, + { + "content": { + "content": { + "data": { + "message": "a-328", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 328000, + "id": "a-328", + "invokedAt": 328000, + "localId": null, + "seq": 328 + }, + { + "content": { + "content": { + "data": { + "message": "a-329", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 329000, + "id": "a-329", + "invokedAt": 329000, + "localId": null, + "seq": 329 + }, + { + "content": { + "content": { + "data": { + "message": "a-330", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 330000, + "id": "a-330", + "invokedAt": 330000, + "localId": null, + "seq": 330 + }, + { + "content": { + "content": { + "data": { + "message": "a-331", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 331000, + "id": "a-331", + "invokedAt": 331000, + "localId": null, + "seq": 331 + }, + { + "content": { + "content": { + "data": { + "message": "a-332", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 332000, + "id": "a-332", + "invokedAt": 332000, + "localId": null, + "seq": 332 + }, + { + "content": { + "content": { + "data": { + "message": "a-333", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 333000, + "id": "a-333", + "invokedAt": 333000, + "localId": null, + "seq": 333 + }, + { + "content": { + "content": { + "data": { + "message": "a-334", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 334000, + "id": "a-334", + "invokedAt": 334000, + "localId": null, + "seq": 334 + }, + { + "content": { + "content": { + "data": { + "message": "a-335", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 335000, + "id": "a-335", + "invokedAt": 335000, + "localId": null, + "seq": 335 + }, + { + "content": { + "content": { + "data": { + "message": "a-336", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 336000, + "id": "a-336", + "invokedAt": 336000, + "localId": null, + "seq": 336 + }, + { + "content": { + "content": { + "data": { + "message": "a-337", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 337000, + "id": "a-337", + "invokedAt": 337000, + "localId": null, + "seq": 337 + }, + { + "content": { + "content": { + "data": { + "message": "a-338", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 338000, + "id": "a-338", + "invokedAt": 338000, + "localId": null, + "seq": 338 + }, + { + "content": { + "content": { + "data": { + "message": "a-339", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 339000, + "id": "a-339", + "invokedAt": 339000, + "localId": null, + "seq": 339 + }, + { + "content": { + "content": { + "data": { + "message": "a-340", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 340000, + "id": "a-340", + "invokedAt": 340000, + "localId": null, + "seq": 340 + }, + { + "content": { + "content": { + "data": { + "message": "a-341", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 341000, + "id": "a-341", + "invokedAt": 341000, + "localId": null, + "seq": 341 + }, + { + "content": { + "content": { + "data": { + "message": "a-342", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 342000, + "id": "a-342", + "invokedAt": 342000, + "localId": null, + "seq": 342 + }, + { + "content": { + "content": { + "data": { + "message": "a-343", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 343000, + "id": "a-343", + "invokedAt": 343000, + "localId": null, + "seq": 343 + }, + { + "content": { + "content": { + "data": { + "message": "a-344", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 344000, + "id": "a-344", + "invokedAt": 344000, + "localId": null, + "seq": 344 + }, + { + "content": { + "content": { + "data": { + "message": "a-345", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 345000, + "id": "a-345", + "invokedAt": 345000, + "localId": null, + "seq": 345 + }, + { + "content": { + "content": { + "data": { + "message": "a-346", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 346000, + "id": "a-346", + "invokedAt": 346000, + "localId": null, + "seq": 346 + }, + { + "content": { + "content": { + "data": { + "message": "a-347", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 347000, + "id": "a-347", + "invokedAt": 347000, + "localId": null, + "seq": 347 + }, + { + "content": { + "content": { + "data": { + "message": "a-348", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 348000, + "id": "a-348", + "invokedAt": 348000, + "localId": null, + "seq": 348 + }, + { + "content": { + "content": { + "data": { + "message": "a-349", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 349000, + "id": "a-349", + "invokedAt": 349000, + "localId": null, + "seq": 349 + }, + { + "content": { + "content": { + "data": { + "message": "a-350", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 350000, + "id": "a-350", + "invokedAt": 350000, + "localId": null, + "seq": 350 + }, + { + "content": { + "content": { + "data": { + "message": "a-351", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 351000, + "id": "a-351", + "invokedAt": 351000, + "localId": null, + "seq": 351 + }, + { + "content": { + "content": { + "data": { + "message": "a-352", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 352000, + "id": "a-352", + "invokedAt": 352000, + "localId": null, + "seq": 352 + }, + { + "content": { + "content": { + "data": { + "message": "a-353", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 353000, + "id": "a-353", + "invokedAt": 353000, + "localId": null, + "seq": 353 + }, + { + "content": { + "content": { + "data": { + "message": "a-354", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 354000, + "id": "a-354", + "invokedAt": 354000, + "localId": null, + "seq": 354 + }, + { + "content": { + "content": { + "data": { + "message": "a-355", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 355000, + "id": "a-355", + "invokedAt": 355000, + "localId": null, + "seq": 355 + }, + { + "content": { + "content": { + "data": { + "message": "a-356", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 356000, + "id": "a-356", + "invokedAt": 356000, + "localId": null, + "seq": 356 + }, + { + "content": { + "content": { + "data": { + "message": "a-357", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 357000, + "id": "a-357", + "invokedAt": 357000, + "localId": null, + "seq": 357 + }, + { + "content": { + "content": { + "data": { + "message": "a-358", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 358000, + "id": "a-358", + "invokedAt": 358000, + "localId": null, + "seq": 358 + }, + { + "content": { + "content": { + "data": { + "message": "a-359", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 359000, + "id": "a-359", + "invokedAt": 359000, + "localId": null, + "seq": 359 + }, + { + "content": { + "content": { + "data": { + "message": "a-360", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 360000, + "id": "a-360", + "invokedAt": 360000, + "localId": null, + "seq": 360 + }, + { + "content": { + "content": { + "data": { + "message": "a-361", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 361000, + "id": "a-361", + "invokedAt": 361000, + "localId": null, + "seq": 361 + }, + { + "content": { + "content": { + "data": { + "message": "a-362", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 362000, + "id": "a-362", + "invokedAt": 362000, + "localId": null, + "seq": 362 + }, + { + "content": { + "content": { + "data": { + "message": "a-363", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 363000, + "id": "a-363", + "invokedAt": 363000, + "localId": null, + "seq": 363 + }, + { + "content": { + "content": { + "data": { + "message": "a-364", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 364000, + "id": "a-364", + "invokedAt": 364000, + "localId": null, + "seq": 364 + }, + { + "content": { + "content": { + "data": { + "message": "a-365", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 365000, + "id": "a-365", + "invokedAt": 365000, + "localId": null, + "seq": 365 + }, + { + "content": { + "content": { + "data": { + "message": "a-366", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 366000, + "id": "a-366", + "invokedAt": 366000, + "localId": null, + "seq": 366 + }, + { + "content": { + "content": { + "data": { + "message": "a-367", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 367000, + "id": "a-367", + "invokedAt": 367000, + "localId": null, + "seq": 367 + }, + { + "content": { + "content": { + "data": { + "message": "a-368", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 368000, + "id": "a-368", + "invokedAt": 368000, + "localId": null, + "seq": 368 + }, + { + "content": { + "content": { + "data": { + "message": "a-369", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 369000, + "id": "a-369", + "invokedAt": 369000, + "localId": null, + "seq": 369 + }, + { + "content": { + "content": { + "data": { + "message": "a-370", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 370000, + "id": "a-370", + "invokedAt": 370000, + "localId": null, + "seq": 370 + }, + { + "content": { + "content": { + "data": { + "message": "a-371", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 371000, + "id": "a-371", + "invokedAt": 371000, + "localId": null, + "seq": 371 + }, + { + "content": { + "content": { + "data": { + "message": "a-372", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 372000, + "id": "a-372", + "invokedAt": 372000, + "localId": null, + "seq": 372 + }, + { + "content": { + "content": { + "data": { + "message": "a-373", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 373000, + "id": "a-373", + "invokedAt": 373000, + "localId": null, + "seq": 373 + }, + { + "content": { + "content": { + "data": { + "message": "a-374", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 374000, + "id": "a-374", + "invokedAt": 374000, + "localId": null, + "seq": 374 + }, + { + "content": { + "content": { + "data": { + "message": "a-375", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 375000, + "id": "a-375", + "invokedAt": 375000, + "localId": null, + "seq": 375 + }, + { + "content": { + "content": { + "data": { + "message": "a-376", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 376000, + "id": "a-376", + "invokedAt": 376000, + "localId": null, + "seq": 376 + }, + { + "content": { + "content": { + "data": { + "message": "a-377", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 377000, + "id": "a-377", + "invokedAt": 377000, + "localId": null, + "seq": 377 + }, + { + "content": { + "content": { + "data": { + "message": "a-378", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 378000, + "id": "a-378", + "invokedAt": 378000, + "localId": null, + "seq": 378 + }, + { + "content": { + "content": { + "data": { + "message": "a-379", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 379000, + "id": "a-379", + "invokedAt": 379000, + "localId": null, + "seq": 379 + }, + { + "content": { + "content": { + "data": { + "message": "a-380", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 380000, + "id": "a-380", + "invokedAt": 380000, + "localId": null, + "seq": 380 + }, + { + "content": { + "content": { + "data": { + "message": "a-381", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 381000, + "id": "a-381", + "invokedAt": 381000, + "localId": null, + "seq": 381 + }, + { + "content": { + "content": { + "data": { + "message": "a-382", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 382000, + "id": "a-382", + "invokedAt": 382000, + "localId": null, + "seq": 382 + }, + { + "content": { + "content": { + "data": { + "message": "a-383", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 383000, + "id": "a-383", + "invokedAt": 383000, + "localId": null, + "seq": 383 + }, + { + "content": { + "content": { + "data": { + "message": "a-384", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 384000, + "id": "a-384", + "invokedAt": 384000, + "localId": null, + "seq": 384 + }, + { + "content": { + "content": { + "data": { + "message": "a-385", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 385000, + "id": "a-385", + "invokedAt": 385000, + "localId": null, + "seq": 385 + }, + { + "content": { + "content": { + "data": { + "message": "a-386", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 386000, + "id": "a-386", + "invokedAt": 386000, + "localId": null, + "seq": 386 + }, + { + "content": { + "content": { + "data": { + "message": "a-387", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 387000, + "id": "a-387", + "invokedAt": 387000, + "localId": null, + "seq": 387 + }, + { + "content": { + "content": { + "data": { + "message": "a-388", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 388000, + "id": "a-388", + "invokedAt": 388000, + "localId": null, + "seq": 388 + }, + { + "content": { + "content": { + "data": { + "message": "a-389", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 389000, + "id": "a-389", + "invokedAt": 389000, + "localId": null, + "seq": 389 + }, + { + "content": { + "content": { + "data": { + "message": "a-390", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 390000, + "id": "a-390", + "invokedAt": 390000, + "localId": null, + "seq": 390 + }, + { + "content": { + "content": { + "data": { + "message": "a-391", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 391000, + "id": "a-391", + "invokedAt": 391000, + "localId": null, + "seq": 391 + }, + { + "content": { + "content": { + "data": { + "message": "a-392", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 392000, + "id": "a-392", + "invokedAt": 392000, + "localId": null, + "seq": 392 + }, + { + "content": { + "content": { + "data": { + "message": "a-393", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 393000, + "id": "a-393", + "invokedAt": 393000, + "localId": null, + "seq": 393 + }, + { + "content": { + "content": { + "data": { + "message": "a-394", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 394000, + "id": "a-394", + "invokedAt": 394000, + "localId": null, + "seq": 394 + }, + { + "content": { + "content": { + "data": { + "message": "a-395", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 395000, + "id": "a-395", + "invokedAt": 395000, + "localId": null, + "seq": 395 + }, + { + "content": { + "content": { + "data": { + "message": "a-396", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 396000, + "id": "a-396", + "invokedAt": 396000, + "localId": null, + "seq": 396 + }, + { + "content": { + "content": { + "data": { + "message": "a-397", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 397000, + "id": "a-397", + "invokedAt": 397000, + "localId": null, + "seq": 397 + }, + { + "content": { + "content": { + "data": { + "message": "a-398", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 398000, + "id": "a-398", + "invokedAt": 398000, + "localId": null, + "seq": 398 + }, + { + "content": { + "content": { + "data": { + "message": "a-399", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 399000, + "id": "a-399", + "invokedAt": 399000, + "localId": null, + "seq": 399 + }, + { + "content": { + "content": { + "data": { + "message": "a-400", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 400000, + "id": "a-400", + "invokedAt": 400000, + "localId": null, + "seq": 400 + }, + { + "content": { + "content": { + "data": { + "message": "a-401", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 401000, + "id": "a-401", + "invokedAt": 401000, + "localId": null, + "seq": 401 + }, + { + "content": { + "content": { + "data": { + "message": "a-402", + "type": "message" + }, + "type": "codex" + }, + "role": "agent" + }, + "createdAt": 402000, + "id": "a-402", + "invokedAt": 402000, + "localId": null, + "seq": 402 + } + ], + "op": "sse-messages" + } + ] +} diff --git a/shared/fixtures/sse/active-turn-started-at-not-applied.json b/shared/fixtures/sse/active-turn-started-at-not-applied.json new file mode 100644 index 00000000..c3e33dcd --- /dev/null +++ b/shared/fixtures/sse/active-turn-started-at-not-applied.json @@ -0,0 +1,70 @@ +{ + "description": "Pins actual web behavior: applySessionDetailPatch has no branch for activeTurnStartedAt, so a patch carrying only it is a no-op, and in a mixed patch the other fields apply while activeTurnStartedAt keeps its cached value. (Clients relying on this field must take it from full-session payloads.)", + "expectedPatchResults": [ + "unchanged", + "applied" + ], + "expectedSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": true, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "fixtureVersion": 1, + "initialSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "name": "active-turn-started-at-not-applied", + "patches": [ + { + "activeTurnStartedAt": 1755000005000 + }, + { + "activeTurnStartedAt": 1755000005000, + "thinking": true + } + ] +} diff --git a/shared/fixtures/sse/agent-state-out-of-order-versions.json b/shared/fixtures/sse/agent-state-out-of-order-versions.json new file mode 100644 index 00000000..06869e14 --- /dev/null +++ b/shared/fixtures/sse/agent-state-out-of-order-versions.json @@ -0,0 +1,105 @@ +{ + "description": "Out-of-order arrival across the two SSE connections: version 7 lands first and applies; the older version 6 arrives second and is dropped. Final state is the v7 value.", + "expectedPatchResults": [ + "applied", + "unchanged" + ], + "expectedSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": { + "requests": { + "req-2": { + "arguments": { + "file_path": "/home/dev/project/README.md" + }, + "createdAt": 1755000002000, + "tool": "Write" + } + } + }, + "agentStateVersion": 7, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "fixtureVersion": 1, + "initialSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "name": "agent-state-out-of-order-versions", + "patches": [ + { + "agentState": { + "value": { + "requests": { + "req-2": { + "arguments": { + "file_path": "/home/dev/project/README.md" + }, + "createdAt": 1755000002000, + "tool": "Write" + } + } + }, + "version": 7 + } + }, + { + "agentState": { + "value": { + "requests": { + "req-1": { + "arguments": { + "command": "ls" + }, + "createdAt": 1755000001000, + "tool": "Bash" + } + } + }, + "version": 6 + } + } + ] +} diff --git a/shared/fixtures/sse/agent-state-stale-version-dropped.json b/shared/fixtures/sse/agent-state-stale-version-dropped.json new file mode 100644 index 00000000..379b6caa --- /dev/null +++ b/shared/fixtures/sse/agent-state-stale-version-dropped.json @@ -0,0 +1,106 @@ +{ + "description": "An agentState wrapper older than the cached agentStateVersion is rejected: applying it would resurrect a permission request that was already resolved into completedRequests.", + "expectedPatchResults": [ + "unchanged" + ], + "expectedSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": { + "completedRequests": { + "req-1": { + "arguments": { + "command": "rm -rf build" + }, + "completedAt": 1754999980000, + "createdAt": 1754999970000, + "decision": "approved", + "status": "approved", + "tool": "Bash" + } + }, + "requests": null + }, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "fixtureVersion": 1, + "initialSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": { + "completedRequests": { + "req-1": { + "arguments": { + "command": "rm -rf build" + }, + "completedAt": 1754999980000, + "createdAt": 1754999970000, + "decision": "approved", + "status": "approved", + "tool": "Bash" + } + }, + "requests": null + }, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "name": "agent-state-stale-version-dropped", + "patches": [ + { + "agentState": { + "value": { + "requests": { + "req-1": { + "arguments": { + "command": "rm -rf build" + }, + "createdAt": 1754999970000, + "tool": "Bash" + } + } + }, + "version": 4 + } + } + ] +} diff --git a/shared/fixtures/sse/flat-fields-last-write-wins.json b/shared/fixtures/sse/flat-fields-last-write-wins.json new file mode 100644 index 00000000..1bd810cc --- /dev/null +++ b/shared/fixtures/sse/flat-fields-last-write-wins.json @@ -0,0 +1,74 @@ +{ + "description": "Flat fields (active, thinking, model, modelReasoningEffort, effort, permissionMode) are last-write-wins assignments with no version gate; serviceTier additionally honors an explicit null (key present) as a clear.", + "expectedPatchResults": [ + "applied", + "applied" + ], + "expectedSession": { + "active": false, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": "high", + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-opus-4-6", + "modelReasoningEffort": "high", + "namespace": "default", + "permissionMode": "acceptEdits", + "seq": 12, + "serviceTier": null, + "thinking": true, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "fixtureVersion": 1, + "initialSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": "standard", + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "name": "flat-fields-last-write-wins", + "patches": [ + { + "active": false, + "effort": "high", + "model": "claude-opus-4-6", + "modelReasoningEffort": "high", + "permissionMode": "acceptEdits", + "thinking": true + }, + { + "serviceTier": null + } + ] +} diff --git a/shared/fixtures/sse/keepalive-subminute-active-at-dropped.json b/shared/fixtures/sse/keepalive-subminute-active-at-dropped.json new file mode 100644 index 00000000..a5efa874 --- /dev/null +++ b/shared/fixtures/sse/keepalive-subminute-active-at-dropped.json @@ -0,0 +1,73 @@ +{ + "description": "Keep-alive noise gate: a patch whose only effective change is an activeAt delta below 60s is render-irrelevant and returns unchanged (the cached activeAt does NOT move); a delta of at least 60s applies.", + "expectedPatchResults": [ + "unchanged", + "applied" + ], + "expectedSession": { + "active": true, + "activeAt": 1755000060000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "fixtureVersion": 1, + "initialSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "name": "keepalive-subminute-active-at-dropped", + "patches": [ + { + "active": true, + "activeAt": 1755000010000, + "thinking": false + }, + { + "active": true, + "activeAt": 1755000060000, + "thinking": false + } + ] +} diff --git a/shared/fixtures/sse/metadata-equal-version-dropped.json b/shared/fixtures/sse/metadata-equal-version-dropped.json new file mode 100644 index 00000000..b6b93e9c --- /dev/null +++ b/shared/fixtures/sse/metadata-equal-version-dropped.json @@ -0,0 +1,73 @@ +{ + "description": "A metadata wrapper whose version equals the cached metadataVersion is dropped even though its value differs — the gate is strictly-greater on version, never a value comparison (dual SSE connections can replay the same version).", + "expectedPatchResults": [ + "unchanged" + ], + "expectedSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "fixtureVersion": 1, + "initialSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "name": "metadata-equal-version-dropped", + "patches": [ + { + "metadata": { + "value": { + "flavor": "claude", + "host": "devbox", + "name": "renamed-should-not-apply", + "path": "/home/dev/project" + }, + "version": 3 + } + } + ] +} diff --git a/shared/fixtures/sse/metadata-newer-version-applied.json b/shared/fixtures/sse/metadata-newer-version-applied.json new file mode 100644 index 00000000..6fcb6fbf --- /dev/null +++ b/shared/fixtures/sse/metadata-newer-version-applied.json @@ -0,0 +1,82 @@ +{ + "description": "A metadata wrapper with version strictly greater than the cached metadataVersion replaces the value and stores the version; the accompanying newer updatedAt advances.", + "expectedPatchResults": [ + "applied" + ], + "expectedSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project", + "summary": { + "text": "Add retry to upload path", + "updatedAt": 1755000009000 + } + }, + "metadataVersion": 4, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000010000 + }, + "fixtureVersion": 1, + "initialSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "name": "metadata-newer-version-applied", + "patches": [ + { + "metadata": { + "value": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project", + "summary": { + "text": "Add retry to upload path", + "updatedAt": 1755000009000 + } + }, + "version": 4 + }, + "updatedAt": 1755000010000 + } + ] +} diff --git a/shared/fixtures/sse/mixed-flat-and-versioned-patch.json b/shared/fixtures/sse/mixed-flat-and-versioned-patch.json new file mode 100644 index 00000000..a4862308 --- /dev/null +++ b/shared/fixtures/sse/mixed-flat-and-versioned-patch.json @@ -0,0 +1,93 @@ +{ + "description": "One patch carrying flat fields, a newer metadata wrapper, and a stale agentState wrapper: the flat fields and metadata apply, the stale agentState is rejected, and all of it happens in a single applied call.", + "expectedPatchResults": [ + "applied" + ], + "expectedSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": { + "controlledByUser": false + }, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project-renamed", + "path": "/home/dev/project" + }, + "metadataVersion": 5, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": true, + "thinkingAt": 0, + "updatedAt": 1755000030000 + }, + "fixtureVersion": 1, + "initialSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": { + "controlledByUser": false + }, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "name": "mixed-flat-and-versioned-patch", + "patches": [ + { + "agentState": { + "value": { + "requests": { + "req-stale": { + "arguments": { + "command": "echo stale" + }, + "createdAt": 1754999940000, + "tool": "Bash" + } + } + }, + "version": 2 + }, + "metadata": { + "value": { + "flavor": "claude", + "host": "devbox", + "name": "project-renamed", + "path": "/home/dev/project" + }, + "version": 5 + }, + "thinking": true, + "updatedAt": 1755000030000 + } + ] +} diff --git a/shared/fixtures/sse/scratchlist-updated-at-trigger-only.json b/shared/fixtures/sse/scratchlist-updated-at-trigger-only.json new file mode 100644 index 00000000..5c66104d --- /dev/null +++ b/shared/fixtures/sse/scratchlist-updated-at-trigger-only.json @@ -0,0 +1,65 @@ +{ + "description": "scratchlistUpdatedAt is a refetch trigger, not session state: the patch validates and is render-relevant, but applySessionDetailPatch stores nothing and reports unchanged. Clients react by refetching the scratchlist endpoint, never by mutating the session.", + "expectedPatchResults": [ + "unchanged" + ], + "expectedSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "fixtureVersion": 1, + "initialSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "name": "scratchlist-updated-at-trigger-only", + "patches": [ + { + "scratchlistUpdatedAt": 1755000900000 + } + ] +} diff --git a/shared/fixtures/sse/team-state-null-clear.json b/shared/fixtures/sse/team-state-null-clear.json new file mode 100644 index 00000000..bbc8e89b --- /dev/null +++ b/shared/fixtures/sse/team-state-null-clear.json @@ -0,0 +1,86 @@ +{ + "description": "teamState with value null means \"team deleted\": a strictly newer version clears the field entirely (absent in the expected session) and stores the watermark so a lagged pre-delete patch cannot resurrect the team.", + "expectedPatchResults": [ + "applied" + ], + "expectedSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "teamStateUpdatedAt": 1755000200000, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "fixtureVersion": 1, + "initialSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "teamState": { + "members": [ + { + "agentType": "claude", + "name": "lead", + "status": "active" + }, + { + "agentType": "claude", + "name": "reviewer", + "status": "idle" + } + ], + "teamName": "hapi-dev", + "updatedAt": 1754999900000 + }, + "teamStateUpdatedAt": 1754999900000, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "name": "team-state-null-clear", + "patches": [ + { + "teamState": { + "value": null, + "version": 1755000200000 + } + } + ] +} diff --git a/shared/fixtures/sse/todos-version-watermark-from-absent.json b/shared/fixtures/sse/todos-version-watermark-from-absent.json new file mode 100644 index 00000000..176cba9c --- /dev/null +++ b/shared/fixtures/sse/todos-version-watermark-from-absent.json @@ -0,0 +1,113 @@ +{ + "description": "todos wrappers gate on todosUpdatedAt with an absent watermark treated as 0: the first patch applies, then an older-versioned todos replay is dropped instead of resurrecting the pre-update list.", + "expectedPatchResults": [ + "applied", + "unchanged" + ], + "expectedSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "todos": [ + { + "content": "Wire the SSE reconnect backoff", + "id": "todo-1", + "priority": "high", + "status": "completed" + }, + { + "activeForm": "Porting the patch gate to native", + "content": "Port the patch gate to native", + "id": "todo-2", + "priority": "medium", + "status": "in_progress" + } + ], + "todosUpdatedAt": 1755000300000, + "updatedAt": 1755000000000 + }, + "fixtureVersion": 1, + "initialSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "name": "todos-version-watermark-from-absent", + "patches": [ + { + "todos": { + "value": [ + { + "content": "Wire the SSE reconnect backoff", + "id": "todo-1", + "priority": "high", + "status": "completed" + }, + { + "activeForm": "Porting the patch gate to native", + "content": "Port the patch gate to native", + "id": "todo-2", + "priority": "medium", + "status": "in_progress" + } + ], + "version": 1755000300000 + } + }, + { + "todos": { + "value": [ + { + "activeForm": "Wiring the SSE reconnect backoff", + "content": "Wire the SSE reconnect backoff", + "id": "todo-1", + "priority": "high", + "status": "in_progress" + } + ], + "version": 1755000200000 + } + } + ] +} diff --git a/shared/fixtures/sse/updated-at-max-monotonic.json b/shared/fixtures/sse/updated-at-max-monotonic.json new file mode 100644 index 00000000..7da39a46 --- /dev/null +++ b/shared/fixtures/sse/updated-at-max-monotonic.json @@ -0,0 +1,74 @@ +{ + "description": "updatedAt is max-monotonic: a patch carrying an older updatedAt applies its other fields without rewinding the clock; a newer updatedAt advances it; an older updatedAt alone is a no-op (unchanged).", + "expectedPatchResults": [ + "applied", + "applied", + "unchanged" + ], + "expectedSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": true, + "thinkingAt": 0, + "updatedAt": 1755000005000 + }, + "fixtureVersion": 1, + "initialSession": { + "active": true, + "activeAt": 1755000000000, + "activeTurnStartedAt": null, + "agentState": null, + "agentStateVersion": 5, + "createdAt": 1754996400000, + "effort": null, + "id": "sess-sse-fixture", + "metadata": { + "flavor": "claude", + "host": "devbox", + "name": "project", + "path": "/home/dev/project" + }, + "metadataVersion": 3, + "model": "claude-sonnet-4-6", + "modelReasoningEffort": null, + "namespace": "default", + "permissionMode": "default", + "seq": 12, + "serviceTier": null, + "thinking": false, + "thinkingAt": 0, + "updatedAt": 1755000000000 + }, + "name": "updated-at-max-monotonic", + "patches": [ + { + "thinking": true, + "updatedAt": 1754999995000 + }, + { + "updatedAt": 1755000005000 + }, + { + "updatedAt": 1754999998000 + } + ] +} diff --git a/web/scripts/fixtures/generate.ts b/web/scripts/fixtures/generate.ts index 30ad9fe7..93c5cfd0 100644 --- a/web/scripts/fixtures/generate.ts +++ b/web/scripts/fixtures/generate.ts @@ -3,8 +3,12 @@ import { join } from 'node:path' import { fileURLToPath } from 'node:url' import { fixtureCases } from './cases' import { FIXTURE_VERSION, toFixtureInput, type FixtureCase, type FixtureDocument, type FixtureInput } from './fixtureTypes' +import { buildPaginationFixtureDocument } from './pagination/build' +import { paginationFixtureCases } from './pagination/cases' import { runFixturePipeline } from './pipeline' import { toCanonicalJson } from './serialize' +import { buildSseFixtureDocument } from './sse/build' +import { sseFixtureCases } from './sse/cases' const FIXTURES_DIR = fileURLToPath(new URL('../../../shared/fixtures', import.meta.url)) @@ -23,31 +27,60 @@ export function buildFixtureDocument(fixtureCase: FixtureCase): FixtureDocument } } -export function generateAllFixtures(): void { - const chatDir = join(FIXTURES_DIR, 'chat') - mkdirSync(chatDir, { recursive: true }) +type SuiteWriter = { + dir: string + names: Set +} - const names = new Set() +function openSuite(suite: string): SuiteWriter { + const dir = join(FIXTURES_DIR, suite) + mkdirSync(dir, { recursive: true }) + return { dir, names: new Set() } +} + +function writeSuiteDocument(writer: SuiteWriter, name: string, document: unknown): void { + if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name)) { + throw new Error(`Fixture name must be kebab-case: ${name}`) + } + if (writer.names.has(name)) { + throw new Error(`Duplicate fixture name: ${name}`) + } + writer.names.add(name) + writeFileSync(join(writer.dir, `${name}.json`), toCanonicalJson(document)) +} + +// Remove stale fixtures from renamed/deleted cases so natives never keep +// passing against a file the web pipeline no longer generates. +function pruneSuite(writer: SuiteWriter): void { + for (const entry of readdirSync(writer.dir)) { + if (entry.endsWith('.json') && !writer.names.has(entry.slice(0, -'.json'.length))) { + unlinkSync(join(writer.dir, entry)) + } + } +} + +export async function generateAllFixtures(): Promise { + const chat = openSuite('chat') for (const fixtureCase of fixtureCases) { - if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(fixtureCase.name)) { - throw new Error(`Fixture name must be kebab-case: ${fixtureCase.name}`) - } - if (names.has(fixtureCase.name)) { - throw new Error(`Duplicate fixture name: ${fixtureCase.name}`) - } - names.add(fixtureCase.name) - const document = buildFixtureDocument(fixtureCase) - writeFileSync(join(chatDir, `${fixtureCase.name}.json`), toCanonicalJson(document)) + writeSuiteDocument(chat, fixtureCase.name, buildFixtureDocument(fixtureCase)) } + pruneSuite(chat) - // Remove stale fixtures from renamed/deleted cases so natives never keep - // passing against a file the web pipeline no longer generates. - for (const entry of readdirSync(chatDir)) { - if (entry.endsWith('.json') && !names.has(entry.slice(0, -'.json'.length))) { - unlinkSync(join(chatDir, entry)) - } + const sse = openSuite('sse') + for (const fixtureCase of sseFixtureCases) { + writeSuiteDocument(sse, fixtureCase.name, buildSseFixtureDocument(fixtureCase)) } + pruneSuite(sse) + + const pagination = openSuite('pagination') + for (const fixtureCase of paginationFixtureCases) { + writeSuiteDocument(pagination, fixtureCase.name, await buildPaginationFixtureDocument(fixtureCase)) + } + pruneSuite(pagination) writeFileSync(join(FIXTURES_DIR, 'VERSION'), `${FIXTURE_VERSION}\n`) - console.log(`Wrote ${names.size} chat fixtures (fixtureVersion ${FIXTURE_VERSION}) to ${chatDir}`) + console.log( + `Wrote ${chat.names.size} chat + ${sse.names.size} sse + ${pagination.names.size} pagination fixtures ` + + `(fixtureVersion ${FIXTURE_VERSION}) to ${FIXTURES_DIR}` + ) } diff --git a/web/scripts/fixtures/pagination/build.ts b/web/scripts/fixtures/pagination/build.ts new file mode 100644 index 00000000..801e6865 --- /dev/null +++ b/web/scripts/fixtures/pagination/build.ts @@ -0,0 +1,130 @@ +import { DecryptedMessageSchema } from '@hapi/protocol/schemas' +import type { DecryptedMessage, MessagesResponse } from '@/types/api' +import { FIXTURE_VERSION } from '../fixtureTypes' +import { toCanonicalJson } from '../serialize' +import { + mergeOpObservations, + paginationFixtureSessionId, + runPaginationScript +} from './runner' +import type { PaginationFixtureCase, PaginationFixtureDocument, PaginationOp } from './types' + +const MESSAGE_STATUSES = new Set(['queued', 'sending', 'sent', 'failed']) +const PAGE_DIRECTIONS = new Set(['latest', 'before', 'after']) +const PAGE_KEYS = [ + 'direction', 'limit', 'epoch', 'reset', + 'nextBeforeAt', 'nextBeforeSeq', 'nextAfterAt', 'nextAfterSeq', + 'snapshotHeadAt', 'snapshotHeadSeq', 'hasMore' +] as const + +function fail(label: string, reason: string): never { + throw new Error(`${label}: ${reason}`) +} + +/** Validate a wire DecryptedMessage. The protocol schema gates the required + * envelope; on top of it only the client-side `status` extension is allowed + * so authored inputs cannot smuggle non-wire keys into fixtures. */ +function validateMessage(message: DecryptedMessage, label: string): void { + const result = DecryptedMessageSchema.safeParse(message) + if (!result.success) { + fail(label, `invalid DecryptedMessage: ${result.error.message}`) + } + const allowed = new Set([...Object.keys(DecryptedMessageSchema.shape), 'status']) + for (const key of Object.keys(message)) { + if (!allowed.has(key)) { + fail(label, `unexpected DecryptedMessage key '${key}'`) + } + } + if (message.status !== undefined && !MESSAGE_STATUSES.has(message.status)) { + fail(label, `invalid status '${String(message.status)}'`) + } +} + +function isNullableNumber(value: unknown): boolean { + return value === null || typeof value === 'number' +} + +/** Structural gate for a scripted MessagesResponse (`shared/src/apiTypes.ts` + * has no zod schema for it — mirror the wire contract by hand). */ +function validateResponse(response: MessagesResponse, label: string): void { + if (!Array.isArray(response.messages)) { + fail(label, 'messages must be an array') + } + response.messages.forEach((message, index) => validateMessage(message, `${label}.messages[${index}]`)) + const page = response.page as Record + if (!page || typeof page !== 'object') { + fail(label, 'page must be an object') + } + for (const key of Object.keys(page)) { + if (!PAGE_KEYS.includes(key as typeof PAGE_KEYS[number])) { + fail(label, `unexpected page key '${key}'`) + } + } + if (!PAGE_DIRECTIONS.has(page.direction as string)) fail(label, 'invalid page.direction') + if (typeof page.limit !== 'number' || !Number.isInteger(page.limit)) fail(label, 'page.limit must be an integer') + if (typeof page.epoch !== 'number' || !Number.isInteger(page.epoch) || page.epoch < 0) { + fail(label, 'page.epoch must be a non-negative integer') + } + if (typeof page.reset !== 'boolean') fail(label, 'page.reset must be a boolean') + if (typeof page.hasMore !== 'boolean') fail(label, 'page.hasMore must be a boolean') + for (const key of ['nextBeforeAt', 'nextBeforeSeq', 'nextAfterAt', 'nextAfterSeq', 'snapshotHeadAt', 'snapshotHeadSeq'] as const) { + if (!isNullableNumber(page[key])) fail(label, `page.${key} must be a number or null`) + } + for (const [atKey, seqKey] of [ + ['nextBeforeAt', 'nextBeforeSeq'], + ['nextAfterAt', 'nextAfterSeq'], + ['snapshotHeadAt', 'snapshotHeadSeq'] + ] as const) { + if ((page[atKey] === null) !== (page[seqKey] === null)) { + fail(label, `${atKey}/${seqKey} must be paired (both null or both numbers)`) + } + } +} + +function validateOp(op: PaginationOp, label: string): void { + switch (op.op) { + case 'sync-tail': + case 'fetch-older': + op.responses.forEach((response, index) => validateResponse(response, `${label}.responses[${index}]`)) + return + case 'sse-messages': + op.messages.forEach((message, index) => validateMessage(message, `${label}.messages[${index}]`)) + return + case 'append-optimistic': + validateMessage(op.message, `${label}.message`) + return + case 'cancel-invoked': + validateMessage(op.message, `${label}.message`) + return + case 'update-status': + case 'messages-consumed': + case 'message-cancelled': + case 'set-view-mode': + case 'queued-state': + return + default: { + const exhaustive: never = op + fail(label, `unknown op ${JSON.stringify(exhaustive)}`) + } + } +} + +export async function buildPaginationFixtureDocument( + fixtureCase: PaginationFixtureCase +): Promise { + // Round-trip the ops through canonical JSON before running, so the + // expectations are computed from exactly the bytes the file will carry. + const ops = JSON.parse(toCanonicalJson(fixtureCase.ops)) as PaginationOp[] + ops.forEach((op, index) => validateOp(op, `${fixtureCase.name}: ops[${index}]`)) + const { observations, expectedState } = await runPaginationScript( + paginationFixtureSessionId(fixtureCase.name), + ops + ) + return { + fixtureVersion: FIXTURE_VERSION, + name: fixtureCase.name, + description: fixtureCase.description, + ops: mergeOpObservations(ops, observations), + expectedState + } +} diff --git a/web/scripts/fixtures/pagination/cases.ts b/web/scripts/fixtures/pagination/cases.ts new file mode 100644 index 00000000..2477d052 --- /dev/null +++ b/web/scripts/fixtures/pagination/cases.ts @@ -0,0 +1,460 @@ +import type { DecryptedMessage, MessageStatus, MessagesResponse } from '@/types/api' +import type { PaginationFixtureCase } from './types' + +/** + * Hand-authored window-store scenarios. Positions use small millisecond + * values (the protocol only compares them); `at = invokedAt ?? createdAt` + * and every cursor is an (at, seq) pair. Cases avoid position ties so the + * merge order never depends on the id tie-breaker (web uses localeCompare — + * keep ids ASCII and positions distinct). + */ + +function agentMessage(init: { id: string; seq: number; at: number }): DecryptedMessage { + return { + id: init.id, + seq: init.seq, + localId: null, + content: { + role: 'agent', + content: { type: 'codex', data: { type: 'message', message: init.id } } + }, + createdAt: init.at, + invokedAt: init.at + } +} + +/** A row the chat pipeline hides (normalizes to null): meta system output. */ +function hiddenAgentMessage(init: { id: string; seq: number; at: number }): DecryptedMessage { + return { + id: init.id, + seq: init.seq, + localId: null, + content: { + role: 'agent', + content: { type: 'output', data: { type: 'system', isMeta: true } } + }, + createdAt: init.at, + invokedAt: init.at + } +} + +function userMessage(init: { + id: string + seq?: number | null + localId?: string | null + createdAt: number + invokedAt?: number | null + status?: MessageStatus + text?: string +}): DecryptedMessage { + return { + id: init.id, + seq: init.seq ?? null, + localId: init.localId ?? null, + content: { + role: 'user', + content: { type: 'text', text: init.text ?? init.id } + }, + createdAt: init.createdAt, + ...(init.invokedAt !== undefined ? { invokedAt: init.invokedAt } : {}), + ...(init.status !== undefined ? { status: init.status } : {}) + } +} + +type Position = { at: number; seq: number } + +function pageResponse( + messages: DecryptedMessage[], + page: { + direction: 'latest' | 'before' | 'after' + epoch: number + hasMore: boolean + reset?: boolean + nextBefore?: Position | null + nextAfter?: Position | null + snapshotHead?: Position | null + } +): MessagesResponse { + return { + messages, + page: { + direction: page.direction, + limit: 200, + epoch: page.epoch, + reset: page.reset ?? false, + nextBeforeAt: page.nextBefore?.at ?? null, + nextBeforeSeq: page.nextBefore?.seq ?? null, + nextAfterAt: page.nextAfter?.at ?? null, + nextAfterSeq: page.nextAfter?.seq ?? null, + snapshotHeadAt: page.snapshotHead?.at ?? null, + snapshotHeadSeq: page.snapshotHead?.seq ?? null, + hasMore: page.hasMore + } + } +} + +function paddedAgentRun(fromSeq: number, toSeq: number): DecryptedMessage[] { + const rows: DecryptedMessage[] = [] + for (let seq = fromSeq; seq <= toSeq; seq += 1) { + rows.push(agentMessage({ id: `a-${String(seq).padStart(3, '0')}`, seq, at: seq * 1000 })) + } + return rows +} + +export const paginationFixtureCases: PaginationFixtureCase[] = [ + { + name: 'latest-page-then-sse-ingest', + description: 'Cold start: a latest page seeds the window, epoch, older cursor (page.nextBefore) and newest cursor (page.snapshotHead); a live SSE message appends and advances the newest cursor to its position.', + ops: [ + { + op: 'sync-tail', + responses: [ + pageResponse([ + agentMessage({ id: 'a-1', seq: 1, at: 1_000 }), + agentMessage({ id: 'a-2', seq: 2, at: 2_000 }) + ], { + direction: 'latest', + epoch: 0, + hasMore: true, + nextBefore: { at: 1_000, seq: 1 }, + snapshotHead: { at: 2_000, seq: 2 } + }) + ] + }, + { + op: 'sse-messages', + messages: [agentMessage({ id: 'a-3', seq: 3, at: 3_000 })] + } + ] + }, + { + name: 'fetch-older-before-cursor', + description: 'Older pagination sends the compound (beforeAt, beforeSeq) pair from the current older cursor, prepends the rows, and adopts the response page.nextBefore as the new older cursor and page.hasMore as the exhaustion flag.', + ops: [ + { + op: 'sync-tail', + responses: [ + pageResponse([agentMessage({ id: 'a-10', seq: 10, at: 10_000 })], { + direction: 'latest', + epoch: 4, + hasMore: true, + nextBefore: { at: 10_000, seq: 10 }, + snapshotHead: { at: 10_000, seq: 10 } + }) + ] + }, + { + op: 'fetch-older', + responses: [ + pageResponse([agentMessage({ id: 'a-9', seq: 9, at: 9_000 })], { + direction: 'before', + epoch: 4, + hasMore: false, + nextBefore: { at: 9_000, seq: 9 } + }) + ] + } + ] + }, + { + name: 'older-page-epoch-mismatch-resets', + description: 'An older page answering with a different epoch invalidates every cursor: the load stops with epoch-reset, the window is discarded, and a fresh latest request (issued by the store within the same operation) replaces it wholesale.', + ops: [ + { + op: 'sync-tail', + responses: [ + pageResponse([agentMessage({ id: 'a-10', seq: 10, at: 10_000 })], { + direction: 'latest', + epoch: 1, + hasMore: true, + nextBefore: { at: 10_000, seq: 10 }, + snapshotHead: { at: 10_000, seq: 10 } + }) + ] + }, + { + op: 'fetch-older', + responses: [ + pageResponse([], { + direction: 'before', + epoch: 2, + hasMore: false, + nextBefore: null + }), + pageResponse([agentMessage({ id: 'f-20', seq: 20, at: 20_000 })], { + direction: 'latest', + epoch: 2, + hasMore: false, + nextBefore: { at: 20_000, seq: 20 }, + snapshotHead: { at: 20_000, seq: 20 } + }) + ] + } + ] + }, + { + name: 'reset-latest-preserves-optimistic', + description: 'A tail sync that gets page.reset:true replaces every server row from before the request but keeps optimistic rows (id === localId): the not-yet-echoed send survives the epoch bump and the window adopts the new epoch and cursors.', + ops: [ + { + op: 'sync-tail', + responses: [ + pageResponse([agentMessage({ id: 'old-1', seq: 1, at: 1_000 })], { + direction: 'latest', + epoch: 1, + hasMore: false, + nextBefore: { at: 1_000, seq: 1 }, + snapshotHead: { at: 1_000, seq: 1 } + }) + ] + }, + { + op: 'append-optimistic', + message: userMessage({ + id: 'local-1', + localId: 'local-1', + createdAt: 1_500, + invokedAt: null, + status: 'sending', + text: 'optimistic send' + }) + }, + { + op: 'sync-tail', + responses: [ + pageResponse([agentMessage({ id: 'fresh-2', seq: 2, at: 2_000 })], { + direction: 'latest', + epoch: 2, + hasMore: false, + reset: true, + nextBefore: { at: 2_000, seq: 2 }, + snapshotHead: { at: 2_000, seq: 2 } + }) + ] + } + ] + }, + { + name: 'optimistic-echo-reconciles-by-localid', + description: 'The message-received echo of the caller\'s own send (server id, real seq, same localId) replaces the optimistic row while preserving the client-side status; only one row remains and it is no longer optimistic.', + ops: [ + { + op: 'append-optimistic', + message: userMessage({ + id: 'local-1', + localId: 'local-1', + createdAt: 1_000, + invokedAt: null, + status: 'sending', + text: 'hello agent' + }) + }, + { op: 'update-status', localId: 'local-1', status: 'queued' }, + { + op: 'sse-messages', + messages: [ + userMessage({ + id: 'srv-1', + seq: 1, + localId: 'local-1', + createdAt: 1_000, + invokedAt: null, + text: 'hello agent' + }) + ] + } + ] + }, + { + name: 'messages-consumed-stamps-invoked-at', + description: 'messages-consumed stamps invokedAt and flips status to sent: the row leaves the queued bar and moves to its invocation position (after the agent row), while the newest cursor does NOT advance from this out-of-band update.', + ops: [ + { + op: 'sync-tail', + responses: [ + pageResponse([ + userMessage({ + id: 'q-1', + seq: 1, + localId: 'local-1', + createdAt: 1_000, + invokedAt: null, + text: 'queued question' + }), + agentMessage({ id: 'a-2', seq: 2, at: 2_000 }) + ], { + direction: 'latest', + epoch: 0, + hasMore: false, + nextBefore: { at: 1_000, seq: 1 }, + snapshotHead: { at: 2_000, seq: 2 } + }) + ] + }, + { op: 'messages-consumed', localIds: ['local-1'], invokedAt: 3_000 } + ] + }, + { + name: 'message-cancelled-removes-queued-row', + description: 'message-cancelled removes the queued row by localId; a repeat delivery is an idempotent no-op on the already-empty window.', + ops: [ + { + op: 'append-optimistic', + message: userMessage({ + id: 'local-1', + localId: 'local-1', + createdAt: 1_000, + invokedAt: null, + status: 'queued', + text: 'cancel me' + }) + }, + { op: 'message-cancelled', localId: 'local-1' }, + { op: 'message-cancelled', localId: 'local-1' } + ] + }, + { + name: 'cancel-too-late-ingests-invoked-row', + description: 'DELETE answered status:invoked (the agent consumed the message before the cancel landed): the queued snapshot must NOT be resurrected — the returned authoritative row is ingested with its server invokedAt and client status sent, landing in the thread at its invocation position.', + ops: [ + { + op: 'sync-tail', + responses: [ + pageResponse([ + userMessage({ + id: 'srv-1', + seq: 1, + localId: 'local-1', + createdAt: 1_000, + invokedAt: null, + text: 'race with the agent' + }) + ], { + direction: 'latest', + epoch: 0, + hasMore: false, + nextBefore: { at: 1_000, seq: 1 }, + snapshotHead: { at: 1_000, seq: 1 } + }) + ] + }, + { + op: 'cancel-invoked', + localId: 'local-1', + message: userMessage({ + id: 'srv-1', + seq: 1, + localId: 'local-1', + createdAt: 1_000, + invokedAt: 5_000, + text: 'race with the agent' + }) + } + ] + }, + { + name: 'sse-hidden-rows-advance-cursor-only', + description: 'SSE rows the chat pipeline hides (e.g. meta system output) are not retained in the window, but the newest cursor still advances past their position so a later tail sync does not refetch them.', + ops: [ + { + op: 'sync-tail', + responses: [ + pageResponse([agentMessage({ id: 'a-1', seq: 1, at: 1_000 })], { + direction: 'latest', + epoch: 0, + hasMore: false, + nextBefore: { at: 1_000, seq: 1 }, + snapshotHead: { at: 1_000, seq: 1 } + }) + ] + }, + { + op: 'sse-messages', + messages: [ + agentMessage({ id: 'a-2', seq: 2, at: 2_000 }), + hiddenAgentMessage({ id: 'hidden-3', seq: 3, at: 3_000 }) + ] + } + ] + }, + { + name: 'trim-preserves-queued-and-recomputes-cursor', + description: 'Tail-mode overflow past the 400-row visible window trims the oldest regular rows: queued rows are never trimmed (the regular budget shrinks by their count), hasMore flips true, and the older cursor is recomputed from the oldest kept row.', + ops: [ + { + op: 'sync-tail', + responses: [ + pageResponse([ + ...paddedAgentRun(1, 199), + userMessage({ + id: 'q-200', + seq: 200, + localId: 'local-q', + createdAt: 350_000, + invokedAt: null, + text: 'still queued' + }) + ], { + direction: 'latest', + epoch: 0, + hasMore: false, + nextBefore: { at: 1_000, seq: 1 }, + snapshotHead: { at: 350_000, seq: 200 } + }) + ] + }, + { + op: 'sse-messages', + messages: paddedAgentRun(201, 402) + } + ] + }, + { + name: 'queued-state-reconciliation-drops-deleted', + description: 'Queued-state recovery after a resume gap: candidates are the user rows with invokedAt strictly null; the server verdict stamps invoked ones like messages-consumed, keeps the still-queued one, and drops candidates in neither list (deleted server-side).', + ops: [ + { + op: 'sync-tail', + responses: [ + pageResponse([ + userMessage({ + id: 'u-1', + seq: 1, + localId: 'local-stale', + createdAt: 1_000, + invokedAt: null, + text: 'deleted server-side' + }), + userMessage({ + id: 'u-2', + seq: 2, + localId: 'local-kept', + createdAt: 2_000, + invokedAt: null, + text: 'still queued' + }), + userMessage({ + id: 'u-3', + seq: 3, + localId: 'local-consumed', + createdAt: 3_000, + invokedAt: null, + text: 'consumed during the gap' + }) + ], { + direction: 'latest', + epoch: 0, + hasMore: false, + nextBefore: { at: 1_000, seq: 1 }, + snapshotHead: { at: 3_000, seq: 3 } + }) + ] + }, + { + op: 'queued-state', + queuedLocalIds: ['local-kept'], + invoked: [{ localId: 'local-consumed', invokedAt: 4_000 }] + } + ] + } +] diff --git a/web/scripts/fixtures/pagination/runner.ts b/web/scripts/fixtures/pagination/runner.ts new file mode 100644 index 00000000..277e422f --- /dev/null +++ b/web/scripts/fixtures/pagination/runner.ts @@ -0,0 +1,252 @@ +import type { ApiClient } from '@/api/client' +import { + clearMessageWindow, + fetchOlderMessages, + getMessageWindowState, + getQueuedReconcileCandidateLocalIds, + ingestIncomingMessages, + appendOptimisticMessage, + markMessagesConsumed, + reconcileQueuedLocalIds, + removeOptimisticMessage, + setMessageViewMode, + syncTailMessages, + updateMessageStatus, + type MessageWindowState, + type OlderLoadOutcome +} from '@/lib/message-window-store' +import { isQueuedForInvocation } from '@/lib/messages' +import type { DecryptedMessage, MessagesResponse } from '@/types/api' +import { toCanonicalJson } from '../serialize' +import type { + PageRequest, + PaginationOp, + PaginationOpObservation, + ProjectedOlderOutcome, + ProjectedWindowMessage, + ProjectedWindowState +} from './types' + +/** + * The op-script harness: drives the REAL web message-window store with a + * scripted ApiClient and records what the store did (requests issued, older + * -load outcomes, reconcile candidates) plus the final normative projection. + * Shared by the fixture generator and the self-conformance vitest so the + * stored expectations can never diverge from a fresh replay. + * + * Ops run strictly sequentially (each awaited to completion). Determinism: + * the store's only wall-clock reads (`Date.now`) gate notification + * throttling, which never touches the state this harness observes. + */ + +export function paginationFixtureSessionId(name: string): string { + return `fixture-pagination-${name}` +} + +type ScriptedApi = { + api: ApiClient + requests: PageRequest[] + queue: MessagesResponse[] +} + +function createScriptedApi(responses: MessagesResponse[]): ScriptedApi { + const scripted: ScriptedApi = { + requests: [], + queue: [...responses], + api: undefined as unknown as ApiClient + } + const getMessages: ApiClient['getMessages'] = async (_sessionId, options) => { + scripted.requests.push(JSON.parse(toCanonicalJson(options ?? {})) as PageRequest) + const next = scripted.queue.shift() + if (!next) { + throw new Error('scripted ApiClient exhausted: unexpected getMessages request') + } + return next + } + scripted.api = { getMessages } as ApiClient + return scripted +} + +function projectOutcome(outcome: OlderLoadOutcome): ProjectedOlderOutcome { + if (outcome.kind === 'applied') { + return { + kind: 'applied', + hasMore: outcome.hasMore, + addedRenderableCount: outcome.addedRenderableCount + } + } + if (outcome.kind === 'stopped') { + return { kind: 'stopped', reason: outcome.reason } + } + throw new Error(`older-page load failed: ${outcome.error.message}`) +} + +function projectMessage(message: DecryptedMessage): ProjectedWindowMessage { + return { + id: message.id, + localId: message.localId ?? null, + seq: message.seq ?? null, + createdAt: message.createdAt, + ...(message.invokedAt !== undefined ? { invokedAt: message.invokedAt } : {}), + ...(message.scheduledAt !== undefined ? { scheduledAt: message.scheduledAt } : {}), + ...(message.status !== undefined ? { status: message.status } : {}), + queued: isQueuedForInvocation(message), + optimistic: Boolean(message.localId && message.id === message.localId) + } +} + +/** The store's compound paging cursors live on the internal state object + * behind `MessageWindowState`. The `in` guards fail loudly if the web store + * renames them, so the fixtures cannot silently pin nulls. */ +type InternalCursorFields = { + oldestPositionAt: number | null + oldestPositionSeq: number | null + newestPositionAt: number | null + newestPositionSeq: number | null +} + +function projectCursor(at: unknown, seq: unknown): { at: number; seq: number } | null { + return typeof at === 'number' && typeof seq === 'number' ? { at, seq } : null +} + +export function projectWindowState(sessionId: string): ProjectedWindowState { + const state = getMessageWindowState(sessionId) as MessageWindowState & Partial + if (!('oldestPositionAt' in state) || !('newestPositionAt' in state)) { + throw new Error('message-window-store internals renamed: update the pagination fixture runner') + } + return { + messages: state.messages.map(projectMessage), + hasMore: state.hasMore, + epoch: state.epoch, + viewMode: state.viewMode, + olderCursor: projectCursor(state.oldestPositionAt, state.oldestPositionSeq), + newestCursor: projectCursor(state.newestPositionAt, state.newestPositionSeq) + } +} + +function assertSettled(sessionId: string, opIndex: number, scripted: ScriptedApi): void { + if (scripted.queue.length > 0) { + throw new Error(`ops[${opIndex}]: ${scripted.queue.length} scripted response(s) left unconsumed`) + } + const state = getMessageWindowState(sessionId) + if (state.warning !== null) { + throw new Error(`ops[${opIndex}]: store reported a warning: ${state.warning}`) + } + if (state.isSyncingTail || state.isLoadingMore) { + throw new Error(`ops[${opIndex}]: store still busy after the op settled`) + } +} + +async function executeOp( + sessionId: string, + op: PaginationOp, + opIndex: number +): Promise { + switch (op.op) { + case 'sync-tail': { + const scripted = createScriptedApi(op.responses) + await syncTailMessages(scripted.api, sessionId) + assertSettled(sessionId, opIndex, scripted) + return { requests: scripted.requests } + } + case 'fetch-older': { + const scripted = createScriptedApi(op.responses) + const outcome = await fetchOlderMessages(scripted.api, sessionId) + assertSettled(sessionId, opIndex, scripted) + return { requests: scripted.requests, outcome: projectOutcome(outcome) } + } + case 'sse-messages': + ingestIncomingMessages(sessionId, op.messages) + return {} + case 'append-optimistic': + appendOptimisticMessage(sessionId, op.message) + return {} + case 'update-status': + updateMessageStatus(sessionId, op.localId, op.status) + return {} + case 'messages-consumed': + markMessagesConsumed(sessionId, op.localIds, op.invokedAt) + return {} + case 'message-cancelled': + removeOptimisticMessage(sessionId, op.localId) + return {} + case 'cancel-invoked': + // Mirrors useCancelQueuedMessage: optimistic removal on mutate, + // then the invoked-race response re-ingests the server row as + // status 'sent' so the chip lands in the thread, not the bar. + removeOptimisticMessage(sessionId, op.localId) + appendOptimisticMessage(sessionId, { ...op.message, status: 'sent' }) + return {} + case 'set-view-mode': + setMessageViewMode(sessionId, op.mode) + return {} + case 'queued-state': { + // Mirrors reconcileQueuedStateAfterConnect (post tail-sync half): + // collect candidates, apply invoked verdicts grouped by + // timestamp, then drop candidates in neither list. + const candidates = getQueuedReconcileCandidateLocalIds(sessionId) + const invokedByTimestamp = new Map() + for (const entry of op.invoked) { + const localIds = invokedByTimestamp.get(entry.invokedAt) ?? [] + localIds.push(entry.localId) + invokedByTimestamp.set(entry.invokedAt, localIds) + } + for (const [invokedAt, localIds] of invokedByTimestamp) { + markMessagesConsumed(sessionId, localIds, invokedAt) + } + reconcileQueuedLocalIds(sessionId, candidates, op.queuedLocalIds) + return { candidates } + } + default: { + const exhaustive: never = op + throw new Error(`unknown op: ${JSON.stringify(exhaustive)}`) + } + } +} + +export async function runPaginationScript( + sessionId: string, + ops: PaginationOp[] +): Promise<{ observations: PaginationOpObservation[]; expectedState: ProjectedWindowState }> { + clearMessageWindow(sessionId) + const observations: PaginationOpObservation[] = [] + for (const [opIndex, op] of ops.entries()) { + observations.push(await executeOp(sessionId, op, opIndex)) + } + return { observations, expectedState: projectWindowState(sessionId) } +} + +/** Fill the machine-generated `expected*` fields into the authored ops. */ +export function mergeOpObservations( + ops: PaginationOp[], + observations: PaginationOpObservation[] +): PaginationOp[] { + return ops.map((op, index) => { + const observation = observations[index] ?? {} + return { + ...op, + ...(observation.requests !== undefined ? { expectedRequests: observation.requests } : {}), + ...(observation.outcome !== undefined ? { expectedOutcome: observation.outcome } : {}), + ...(observation.candidates !== undefined ? { expectedCandidates: observation.candidates } : {}) + } as PaginationOp + }) +} + +/** Read the stored `expected*` fields back out, shaped like fresh + * observations, for exact-match comparison in the conformance tests. */ +export function extractOpExpectations(ops: PaginationOp[]): PaginationOpObservation[] { + return ops.map((op) => { + const record = op as Record + return { + ...(record.expectedRequests !== undefined + ? { requests: record.expectedRequests as PageRequest[] } + : {}), + ...(record.expectedOutcome !== undefined + ? { outcome: record.expectedOutcome as ProjectedOlderOutcome } + : {}), + ...(record.expectedCandidates !== undefined + ? { candidates: record.expectedCandidates as string[] } + : {}) + } + }) +} diff --git a/web/scripts/fixtures/pagination/types.ts b/web/scripts/fixtures/pagination/types.ts new file mode 100644 index 00000000..1fe8cab6 --- /dev/null +++ b/web/scripts/fixtures/pagination/types.ts @@ -0,0 +1,145 @@ +import type { DecryptedMessage, MessageStatus, MessagesResponse } from '@/types/api' + +/** Exact argument object the store passed to `getMessages` (canonicalized: + * sorted keys, `undefined` entries stripped, `null` entries preserved). */ +export type PageRequest = Record + +/** Projection of `fetchOlderMessages`' outcome. `historyVersion` (a web + * render counter) is dropped; `failed` outcomes are never scripted. */ +export type ProjectedOlderOutcome = + | { kind: 'applied'; hasMore: boolean; addedRenderableCount: number } + | { kind: 'stopped'; reason: 'unavailable' | 'busy' | 'invalidated' | 'epoch-reset' | 'exhausted' } + +/** + * One scripted operation against the message-window store. Fields named + * `expected*` are machine-generated observations of the real web store — + * absent from hand-authored cases, present in the emitted document. + */ +export type PaginationOp = + | { + /** Run a full tail sync (`syncTailMessages`). `responses` feed the + * scripted ApiClient in order; every response must be consumed. */ + op: 'sync-tail' + responses: MessagesResponse[] + expectedRequests?: PageRequest[] + } + | { + /** Load one older page (`fetchOlderMessages`). On an epoch mismatch + * the store runs an internal tail sync, whose responses (and + * recorded requests) belong to this same op. */ + op: 'fetch-older' + responses: MessagesResponse[] + expectedRequests?: PageRequest[] + expectedOutcome?: ProjectedOlderOutcome + } + | { + /** SSE `message-received` delivery (`ingestIncomingMessages`). */ + op: 'sse-messages' + messages: DecryptedMessage[] + } + | { + /** Local optimistic send append (`appendOptimisticMessage`). The + * message is optimistic iff `id === localId`. */ + op: 'append-optimistic' + message: DecryptedMessage + } + | { + /** Client-side send-state transition (`updateMessageStatus`). */ + op: 'update-status' + localId: string + status: MessageStatus + } + | { + /** SSE `messages-consumed` event (`markMessagesConsumed`). */ + op: 'messages-consumed' + localIds: string[] + invokedAt: number + } + | { + /** SSE `message-cancelled` event, or the optimistic removal before a + * DELETE (`removeOptimisticMessage`; matches localId OR id). */ + op: 'message-cancelled' + localId: string + } + | { + /** Client handling of a DELETE answered `{"status":"invoked"}`: + * remove the queued row by localId, then re-ingest the returned + * authoritative message with client status `sent` (the harness adds + * the status, mirroring the web mutation). */ + op: 'cancel-invoked' + localId: string + message: DecryptedMessage + } + | { + /** Switch view mode (`setMessageViewMode`). */ + op: 'set-view-mode' + mode: 'tail' | 'history' + } + | { + /** Queued-state recovery round trip after a `resume: 'gap'`: + * candidates are collected from the window + * (`getQueuedReconcileCandidateLocalIds` — pinned in + * `expectedCandidates`), the scripted server verdict is applied via + * `markMessagesConsumed` per invoked entry, then + * `reconcileQueuedLocalIds` drops candidates in neither list. */ + op: 'queued-state' + queuedLocalIds: string[] + invoked: Array<{ localId: string; invokedAt: number }> + expectedCandidates?: string[] + } + +/** Observation of one executed op, recorded from the real store. */ +export type PaginationOpObservation = { + requests?: PageRequest[] + outcome?: ProjectedOlderOutcome + candidates?: string[] +} + +/** Normative projection of one window row. `invokedAt` / `scheduledAt` + * mirror the wire tri-state (absent / null / number); `status` is the + * client-side optimistic send state when present. `queued` and `optimistic` + * are the derived predicates natives must reproduce. */ +export type ProjectedWindowMessage = { + id: string + localId: string | null + seq: number | null + createdAt: number + invokedAt?: number | null + scheduledAt?: number | null + status?: MessageStatus + queued: boolean + optimistic: boolean +} + +/** Normative projection of the window state after all ops. The cursors are + * the store's compound paging positions: `olderCursor` feeds the next + * before-request, `newestCursor` the next after-request. */ +export type ProjectedWindowState = { + messages: ProjectedWindowMessage[] + hasMore: boolean + epoch: number | null + viewMode: 'tail' | 'history' + olderCursor: { at: number; seq: number } | null + newestCursor: { at: number; seq: number } | null +} + +/** + * A hand-authored pagination case: op scripts with wire-shaped inputs only. + * The emitted document carries the same ops with `expected*` observations + * filled in, plus the final `expectedState` — all machine-generated by + * driving the real web store. + */ +export type PaginationFixtureCase = { + /** Kebab-case name; becomes shared/fixtures/pagination/.json */ + name: string + description: string + ops: PaginationOp[] +} + +export type PaginationFixtureDocument = { + fixtureVersion: number + name: string + description: string + ops: PaginationOp[] + expectedState: ProjectedWindowState +} diff --git a/web/scripts/fixtures/sse/apply.ts b/web/scripts/fixtures/sse/apply.ts new file mode 100644 index 00000000..b3301e5c --- /dev/null +++ b/web/scripts/fixtures/sse/apply.ts @@ -0,0 +1,23 @@ +import { applySessionDetailPatch } from '@/lib/sessionPatch' +import type { Session, SessionPatch } from '@/types/api' +import type { SessionPatchResult } from './types' + +/** + * The exact fold a client must implement for `session-updated` patches on a + * detail session cache: apply patches in arrival order; a `null` return means + * "nothing changed, keep the previous object". Shared by the fixture + * generator and the self-conformance vitest so the two can never diverge. + */ +export function runSessionPatchScript( + initialSession: Session, + patches: SessionPatch[] +): { expectedPatchResults: SessionPatchResult[]; expectedSession: Session } { + let session = initialSession + const expectedPatchResults: SessionPatchResult[] = [] + for (const patch of patches) { + const next = applySessionDetailPatch(session, patch) + expectedPatchResults.push(next === null ? 'unchanged' : 'applied') + session = next ?? session + } + return { expectedPatchResults, expectedSession: session } +} diff --git a/web/scripts/fixtures/sse/build.ts b/web/scripts/fixtures/sse/build.ts new file mode 100644 index 00000000..b87e4611 --- /dev/null +++ b/web/scripts/fixtures/sse/build.ts @@ -0,0 +1,55 @@ +import { SessionPatchSchema, SessionSchema } from '@hapi/protocol/schemas' +import type { Session, SessionPatch } from '@/types/api' +import { FIXTURE_VERSION } from '../fixtureTypes' +import { toCanonicalJson } from '../serialize' +import { runSessionPatchScript } from './apply' +import type { SseFixtureCase, SseFixtureDocument } from './types' + +/** Parse `value` with `schema` and require the stored (parsed) form to be a + * fixed point of the schema: parsing it again must be byte-identical. This + * guarantees natives can decode the document verbatim without re-running + * zod defaults/transforms, and that authored inputs cannot drift from the + * wire schema. */ +function parseToNormalForm( + schema: { parse: (input: unknown) => T }, + value: unknown, + label: string +): T { + const parsed = schema.parse(JSON.parse(toCanonicalJson(value))) + const reparsed = schema.parse(JSON.parse(toCanonicalJson(parsed))) + if (toCanonicalJson(reparsed) !== toCanonicalJson(parsed)) { + throw new Error(`${label} is not schema-normalized: author it in parsed form`) + } + return JSON.parse(toCanonicalJson(parsed)) as T +} + +export function buildSseFixtureDocument(fixtureCase: SseFixtureCase): SseFixtureDocument { + const initialSession = parseToNormalForm( + SessionSchema, + fixtureCase.initialSession, + `${fixtureCase.name}: initialSession` + ) + const patches = fixtureCase.patches.map((patch, index) => { + const parsed = parseToNormalForm( + SessionPatchSchema, + patch, + `${fixtureCase.name}: patches[${index}]` + ) + if (Object.keys(parsed).length === 0) { + throw new Error(`${fixtureCase.name}: patches[${index}] is empty`) + } + return parsed + }) + const { expectedPatchResults, expectedSession } = runSessionPatchScript(initialSession, patches) + // Patch application must never produce a schema-invalid session. + SessionSchema.parse(JSON.parse(toCanonicalJson(expectedSession))) + return { + fixtureVersion: FIXTURE_VERSION, + name: fixtureCase.name, + description: fixtureCase.description, + initialSession, + patches, + expectedPatchResults, + expectedSession: JSON.parse(toCanonicalJson(expectedSession)) as Session + } +} diff --git a/web/scripts/fixtures/sse/cases.ts b/web/scripts/fixtures/sse/cases.ts new file mode 100644 index 00000000..9016962b --- /dev/null +++ b/web/scripts/fixtures/sse/cases.ts @@ -0,0 +1,291 @@ +import type { Session } from '@/types/api' +import { T0 } from '../cases/support' +import type { SseFixtureCase } from './types' + +/** + * Hand-authored versioned-patch scenarios. Every case pins how + * `applySessionDetailPatch` treats a `session-updated` SessionPatch against a + * cached detail Session: flat fields are last-write-wins, `updatedAt` is + * max-monotonic, and the four versioned wrappers (metadata / agentState / + * todos / teamState) apply only when strictly newer than the cached + * watermark. Timestamps derive from the fixed T0 so output is deterministic. + */ + +/** Baseline cached session; cases override the fields under test. All + * schema-defaulted fields are explicit so the stored document equals its own + * `SessionSchema.parse` (asserted by the generator). */ +function baseSession(overrides: Partial = {}): Session { + return { + id: 'sess-sse-fixture', + namespace: 'default', + seq: 12, + createdAt: T0 - 3_600_000, + updatedAt: T0, + active: true, + activeAt: T0, + metadata: { + path: '/home/dev/project', + host: 'devbox', + name: 'project', + flavor: 'claude' + }, + metadataVersion: 3, + agentState: null, + agentStateVersion: 5, + thinking: false, + thinkingAt: 0, + activeTurnStartedAt: null, + model: 'claude-sonnet-4-6', + modelReasoningEffort: null, + effort: null, + serviceTier: null, + permissionMode: 'default', + ...overrides + } +} + +export const sseFixtureCases: SseFixtureCase[] = [ + { + name: 'metadata-newer-version-applied', + description: 'A metadata wrapper with version strictly greater than the cached metadataVersion replaces the value and stores the version; the accompanying newer updatedAt advances.', + initialSession: baseSession(), + patches: [ + { + updatedAt: T0 + 10_000, + metadata: { + version: 4, + value: { + path: '/home/dev/project', + host: 'devbox', + name: 'project', + flavor: 'claude', + summary: { text: 'Add retry to upload path', updatedAt: T0 + 9_000 } + } + } + } + ] + }, + { + name: 'metadata-equal-version-dropped', + description: 'A metadata wrapper whose version equals the cached metadataVersion is dropped even though its value differs — the gate is strictly-greater on version, never a value comparison (dual SSE connections can replay the same version).', + initialSession: baseSession(), + patches: [ + { + metadata: { + version: 3, + value: { + path: '/home/dev/project', + host: 'devbox', + name: 'renamed-should-not-apply', + flavor: 'claude' + } + } + } + ] + }, + { + name: 'agent-state-stale-version-dropped', + description: 'An agentState wrapper older than the cached agentStateVersion is rejected: applying it would resurrect a permission request that was already resolved into completedRequests.', + initialSession: baseSession({ + agentState: { + requests: null, + completedRequests: { + 'req-1': { + tool: 'Bash', + arguments: { command: 'rm -rf build' }, + createdAt: T0 - 30_000, + completedAt: T0 - 20_000, + status: 'approved', + decision: 'approved' + } + } + }, + agentStateVersion: 5 + }), + patches: [ + { + agentState: { + version: 4, + value: { + requests: { + 'req-1': { + tool: 'Bash', + arguments: { command: 'rm -rf build' }, + createdAt: T0 - 30_000 + } + } + } + } + } + ] + }, + { + name: 'agent-state-out-of-order-versions', + description: 'Out-of-order arrival across the two SSE connections: version 7 lands first and applies; the older version 6 arrives second and is dropped. Final state is the v7 value.', + initialSession: baseSession(), + patches: [ + { + agentState: { + version: 7, + value: { + requests: { + 'req-2': { + tool: 'Write', + arguments: { file_path: '/home/dev/project/README.md' }, + createdAt: T0 + 2_000 + } + } + } + } + }, + { + agentState: { + version: 6, + value: { + requests: { + 'req-1': { + tool: 'Bash', + arguments: { command: 'ls' }, + createdAt: T0 + 1_000 + } + } + } + } + } + ] + }, + { + name: 'todos-version-watermark-from-absent', + description: 'todos wrappers gate on todosUpdatedAt with an absent watermark treated as 0: the first patch applies, then an older-versioned todos replay is dropped instead of resurrecting the pre-update list.', + initialSession: baseSession(), + patches: [ + { + todos: { + version: T0 + 300_000, + value: [ + { content: 'Wire the SSE reconnect backoff', status: 'completed', priority: 'high', id: 'todo-1' }, + { content: 'Port the patch gate to native', status: 'in_progress', priority: 'medium', id: 'todo-2', activeForm: 'Porting the patch gate to native' } + ] + } + }, + { + todos: { + version: T0 + 200_000, + value: [ + { content: 'Wire the SSE reconnect backoff', status: 'in_progress', priority: 'high', id: 'todo-1', activeForm: 'Wiring the SSE reconnect backoff' } + ] + } + } + ] + }, + { + name: 'team-state-null-clear', + description: 'teamState with value null means "team deleted": a strictly newer version clears the field entirely (absent in the expected session) and stores the watermark so a lagged pre-delete patch cannot resurrect the team.', + initialSession: baseSession({ + teamState: { + teamName: 'hapi-dev', + members: [ + { name: 'lead', agentType: 'claude', status: 'active' }, + { name: 'reviewer', agentType: 'claude', status: 'idle' } + ], + updatedAt: T0 - 100_000 + }, + teamStateUpdatedAt: T0 - 100_000 + }), + patches: [ + { + teamState: { + version: T0 + 200_000, + value: null + } + } + ] + }, + { + name: 'updated-at-max-monotonic', + description: 'updatedAt is max-monotonic: a patch carrying an older updatedAt applies its other fields without rewinding the clock; a newer updatedAt advances it; an older updatedAt alone is a no-op (unchanged).', + initialSession: baseSession(), + patches: [ + { updatedAt: T0 - 5_000, thinking: true }, + { updatedAt: T0 + 5_000 }, + { updatedAt: T0 - 2_000 } + ] + }, + { + name: 'flat-fields-last-write-wins', + description: 'Flat fields (active, thinking, model, modelReasoningEffort, effort, permissionMode) are last-write-wins assignments with no version gate; serviceTier additionally honors an explicit null (key present) as a clear.', + initialSession: baseSession({ serviceTier: 'standard' }), + patches: [ + { + active: false, + thinking: true, + model: 'claude-opus-4-6', + modelReasoningEffort: 'high', + effort: 'high', + permissionMode: 'acceptEdits' + }, + { serviceTier: null } + ] + }, + { + name: 'active-turn-started-at-not-applied', + description: 'Pins actual web behavior: applySessionDetailPatch has no branch for activeTurnStartedAt, so a patch carrying only it is a no-op, and in a mixed patch the other fields apply while activeTurnStartedAt keeps its cached value. (Clients relying on this field must take it from full-session payloads.)', + initialSession: baseSession(), + patches: [ + { activeTurnStartedAt: T0 + 5_000 }, + { activeTurnStartedAt: T0 + 5_000, thinking: true } + ] + }, + { + name: 'keepalive-subminute-active-at-dropped', + description: 'Keep-alive noise gate: a patch whose only effective change is an activeAt delta below 60s is render-irrelevant and returns unchanged (the cached activeAt does NOT move); a delta of at least 60s applies.', + initialSession: baseSession(), + patches: [ + { active: true, thinking: false, activeAt: T0 + 10_000 }, + { active: true, thinking: false, activeAt: T0 + 60_000 } + ] + }, + { + name: 'mixed-flat-and-versioned-patch', + description: 'One patch carrying flat fields, a newer metadata wrapper, and a stale agentState wrapper: the flat fields and metadata apply, the stale agentState is rejected, and all of it happens in a single applied call.', + initialSession: baseSession({ + agentState: { controlledByUser: false }, + agentStateVersion: 5 + }), + patches: [ + { + thinking: true, + updatedAt: T0 + 30_000, + metadata: { + version: 5, + value: { + path: '/home/dev/project', + host: 'devbox', + name: 'project-renamed', + flavor: 'claude' + } + }, + agentState: { + version: 2, + value: { + requests: { + 'req-stale': { + tool: 'Bash', + arguments: { command: 'echo stale' }, + createdAt: T0 - 60_000 + } + } + } + } + } + ] + }, + { + name: 'scratchlist-updated-at-trigger-only', + description: 'scratchlistUpdatedAt is a refetch trigger, not session state: the patch validates and is render-relevant, but applySessionDetailPatch stores nothing and reports unchanged. Clients react by refetching the scratchlist endpoint, never by mutating the session.', + initialSession: baseSession(), + patches: [ + { scratchlistUpdatedAt: T0 + 900_000 } + ] + } +] diff --git a/web/scripts/fixtures/sse/types.ts b/web/scripts/fixtures/sse/types.ts new file mode 100644 index 00000000..b571b346 --- /dev/null +++ b/web/scripts/fixtures/sse/types.ts @@ -0,0 +1,35 @@ +import type { Session, SessionPatch } from '@/types/api' + +/** Per-patch verdict of `applySessionDetailPatch`: `applied` when the call + * returned a new session object, `unchanged` when it returned null (keep the + * previous object — version-gated, render-irrelevant, or no-op patch). */ +export type SessionPatchResult = 'applied' | 'unchanged' + +/** + * A hand-authored SSE session-patch case. `initialSession` and every patch + * are wire-shaped inputs; the emitted document stores them schema-normalized + * (`SessionSchema.parse` / `SessionPatchSchema.parse`) and everything under + * `expected*` is machine-generated by running the real web patch fold + * (`applySessionDetailPatch`) — never hand-written. + */ +export type SseFixtureCase = { + /** Kebab-case name; becomes shared/fixtures/sse/.json */ + name: string + description: string + /** Full Session as cached before the first patch arrives. */ + initialSession: Session + /** SessionPatch payloads of `session-updated` events, in arrival order. */ + patches: SessionPatch[] +} + +export type SseFixtureDocument = { + fixtureVersion: number + name: string + description: string + initialSession: Session + patches: SessionPatch[] + /** Aligned with `patches`: verdict of each applySessionDetailPatch call. */ + expectedPatchResults: SessionPatchResult[] + /** Session state after folding all patches. */ + expectedSession: Session +} diff --git a/web/scripts/generate-fixtures.ts b/web/scripts/generate-fixtures.ts index 44bb627b..c3c28786 100644 --- a/web/scripts/generate-fixtures.ts +++ b/web/scripts/generate-fixtures.ts @@ -3,4 +3,4 @@ // `cd web && bun scripts/generate-fixtures.ts`. Output is byte-deterministic. import { generateAllFixtures } from './fixtures/generate' -generateAllFixtures() +await generateAllFixtures() diff --git a/web/src/lib/message-window-store.fixtures.test.ts b/web/src/lib/message-window-store.fixtures.test.ts new file mode 100644 index 00000000..598d69f9 --- /dev/null +++ b/web/src/lib/message-window-store.fixtures.test.ts @@ -0,0 +1,70 @@ +import { readdirSync, readFileSync } from 'node:fs' +import { join, resolve } from 'node:path' +import { afterEach, describe, expect, it } from 'vitest' +import { clearMessageWindow } from '@/lib/message-window-store' +import { FIXTURE_VERSION } from '../../scripts/fixtures/fixtureTypes' +import { + extractOpExpectations, + paginationFixtureSessionId, + runPaginationScript +} from '../../scripts/fixtures/pagination/runner' +import type { PaginationFixtureDocument } from '../../scripts/fixtures/pagination/types' +import { toCanonicalJson } from '../../scripts/fixtures/serialize' + +// Self-conformance for the pagination fixtures in shared/fixtures/pagination: +// replaying every stored op script through the REAL message-window store must +// reproduce the stored request log, older-load outcomes, reconcile candidates +// and final window projection, and every file must be canonically serialized. +// A failure here means the web store (or the projection) drifted — rerun +// `bun run gen:fixtures` from the repo root and commit the diff, which is what +// flips the native iOS/Android conformance suites red. + +const fixturesDir = resolve(process.cwd(), '../shared/fixtures') +const paginationDir = join(fixturesDir, 'pagination') +const fixtureFiles = readdirSync(paginationDir).filter((name) => name.endsWith('.json')).sort() + +function canonical(value: unknown): unknown { + return JSON.parse(toCanonicalJson(value)) +} + +afterEach(() => { + for (const file of fixtureFiles) { + clearMessageWindow(paginationFixtureSessionId(file.slice(0, -'.json'.length))) + } + sessionStorage.clear() +}) + +describe('shared/fixtures/pagination golden fixtures', () => { + it('has generated fixtures on disk', () => { + expect(fixtureFiles.length).toBeGreaterThan(0) + }) + + it('VERSION matches the generator fixtureVersion', () => { + expect(readFileSync(join(fixturesDir, 'VERSION'), 'utf8')).toBe(`${FIXTURE_VERSION}\n`) + }) + + for (const file of fixtureFiles) { + describe(file, () => { + const raw = readFileSync(join(paginationDir, file), 'utf8') + const document = JSON.parse(raw) as PaginationFixtureDocument + + it('is canonically serialized (sorted keys, 4-space indent, trailing LF)', () => { + expect(toCanonicalJson(document)).toBe(raw) + }) + + it('carries the current fixtureVersion and a name matching its file', () => { + expect(document.fixtureVersion).toBe(FIXTURE_VERSION) + expect(`${document.name}.json`).toBe(file) + }) + + it('replaying the ops against the real store matches the stored expectations', async () => { + const { observations, expectedState } = await runPaginationScript( + paginationFixtureSessionId(document.name), + document.ops + ) + expect(canonical(observations)).toEqual(canonical(extractOpExpectations(document.ops))) + expect(canonical(expectedState)).toEqual(canonical(document.expectedState)) + }) + }) + } +}) diff --git a/web/src/lib/sessionPatch.fixtures.test.ts b/web/src/lib/sessionPatch.fixtures.test.ts new file mode 100644 index 00000000..670aebb9 --- /dev/null +++ b/web/src/lib/sessionPatch.fixtures.test.ts @@ -0,0 +1,71 @@ +import { readdirSync, readFileSync } from 'node:fs' +import { join, resolve } from 'node:path' +import { describe, expect, it } from 'vitest' +import { SessionPatchSchema, SessionSchema } from '@hapi/protocol/schemas' +import { FIXTURE_VERSION } from '../../scripts/fixtures/fixtureTypes' +import { toCanonicalJson } from '../../scripts/fixtures/serialize' +import { runSessionPatchScript } from '../../scripts/fixtures/sse/apply' +import type { SseFixtureDocument } from '../../scripts/fixtures/sse/types' + +// Self-conformance for the SSE session-patch fixtures in shared/fixtures/sse: +// the stored expectations must equal a fresh applySessionDetailPatch fold over +// the stored initialSession + patches, every input must round-trip through the +// wire schemas unchanged, and every file must be canonically serialized. A +// failure here means the web patch rules (or the schemas) drifted — rerun +// `bun run gen:fixtures` from the repo root and commit the diff, which is what +// flips the native iOS/Android conformance suites red. + +const fixturesDir = resolve(process.cwd(), '../shared/fixtures') +const sseDir = join(fixturesDir, 'sse') +const fixtureFiles = readdirSync(sseDir).filter((name) => name.endsWith('.json')).sort() + +function canonical(value: unknown): unknown { + return JSON.parse(toCanonicalJson(value)) +} + +describe('shared/fixtures/sse golden fixtures', () => { + it('has generated fixtures on disk', () => { + expect(fixtureFiles.length).toBeGreaterThan(0) + }) + + it('VERSION matches the generator fixtureVersion', () => { + expect(readFileSync(join(fixturesDir, 'VERSION'), 'utf8')).toBe(`${FIXTURE_VERSION}\n`) + }) + + for (const file of fixtureFiles) { + describe(file, () => { + const raw = readFileSync(join(sseDir, file), 'utf8') + const document = JSON.parse(raw) as SseFixtureDocument + + it('is canonically serialized (sorted keys, 4-space indent, trailing LF)', () => { + expect(toCanonicalJson(document)).toBe(raw) + }) + + it('carries the current fixtureVersion and a name matching its file', () => { + expect(document.fixtureVersion).toBe(FIXTURE_VERSION) + expect(`${document.name}.json`).toBe(file) + }) + + it('stores schema-normalized wire inputs (SessionSchema / strict SessionPatchSchema)', () => { + // Parsing the stored form must be a no-op: natives can decode + // the document verbatim, and a wire-schema change that would + // alter parsing shows up as a diff here. + expect(canonical(SessionSchema.parse(document.initialSession))) + .toEqual(canonical(document.initialSession)) + expect(document.patches.length).toBeGreaterThan(0) + for (const patch of document.patches) { + expect(canonical(SessionPatchSchema.parse(patch))).toEqual(canonical(patch)) + } + }) + + it('expected outcome matches a fresh applySessionDetailPatch fold over the inputs', () => { + const { expectedPatchResults, expectedSession } = runSessionPatchScript( + document.initialSession, + document.patches + ) + expect(expectedPatchResults).toEqual(document.expectedPatchResults) + expect(canonical(expectedSession)).toEqual(canonical(document.expectedSession)) + }) + }) + } +})