Skip to content

feat(sessions): relay live frames to every authorized reader behind AGENTA_SESSIONS_SHARED_READER - #6522

Merged
mmabrouk merged 16 commits into
feat/session-live-eventsfrom
feat/session-live-relay
Sep 5, 2026
Merged

feat(sessions): relay live frames to every authorized reader behind AGENTA_SESSIONS_SHARED_READER#6522
mmabrouk merged 16 commits into
feat/session-live-eventsfrom
feat/session-live-relay

Conversation

@mmabrouk

@mmabrouk mmabrouk commented Sep 4, 2026

Copy link
Copy Markdown
Member

Context

Only the browser that starts a turn sees its live text and tool progress; every other client waits for change notices and reloads completed records. This is increment 4, part one, of the session-control design on PR #6495: shared live output for secondary readers. The sender keeps its invoke stream; snapshot and replay come in part two.

Changes

  • Runner: while a turn runs, the existing invoke events (text and reasoning deltas, tool input and output progress) are also sent to the existing records ingest route as temporary frames, wrapped in the envelope from live-frame-envelope.md: kind: frame, execution_id, a monotonic frame_index, entity_id, the unchanged event type, payload, created_at. Fire-and-forget with a bounded buffer and a drop counter; behind the runner setting AGENTA_RUNNER_LIVE_FRAMES (default off).
  • API ingest: frames ride the same Redis stream as records; the records worker skips them; the stream gets a MAXLEN sized from the measured long case (about 3,200 frames per turn).
  • API relay: a consumer group tails the stream and fans frames out to SSE readers of GET /sessions/{id}/events, beside the existing watch route. Authorization is the transcript's project check, re-checked on an interval; a slow reader is closed with a frame that says why and never blocks the consumer. Behind AGENTA_SESSIONS_SHARED_READER (default off; the route returns 404 when off).
  • Client: a reader in @agenta/chat and @agenta/entities renders live text and tool progress for a session this browser did not start, keyed by (execution_id, frame_index) with entity_id for updates; on disconnect it discards previews and refetches the transcript. Desktop wired in AgentChatSlice; mobile if the hook fits (see the status file).

Tests

  • Runner: 2,687 passed; API live-frame, ingest, worker, watch, and relay tests 30 and 27 passed; sessions suite 544 passed on Postgres; web chat 639, entities 1,469, oss 442 passed. Ruff and lint clean.
  • Whole-PR review by an Opus agent: ship after fixes, eight inline comments on the PR. Two items were found and fixed in round 2 (42ce70dcd5, 7ae0792252): frames are now trimmed by age and never past the records worker's acknowledged frontier, so a worker stall cannot evict an unconsumed durable record, and the worker drains consumed durable records again; the client preview is bounded per entity (5,000-delta test). Re-review verdict: ship. The first live proof on its own stack showed the server side working end to end (synthetic frames reached a real browser reader within a second; two consumer groups at lag 0; flag off gave 404 and on gave 200) and found two gaps in this PR's scope: the desktop chat never wired the shared reader (only mobile did), and the runner compose service did not pass AGENTA_RUNNER_LIVE_FRAMES. Round 3 (2146213306) wires the desktop through the shared hook and passes the flag through every compose file, the Railway template, and the Helm chart with production defaults off, and documents the relay settings in the env examples. Live proof on 2146213306 (stack agenta-ee-dev-session-inc4, screenshots r3-* under ~/agenta-qa-evidence/2026-09-04-inc4-relay/):
Scenario Result
Two browsers pass: the second tab got the events route (200) and showed the same live tool progress and text within about a second
Mobile joins pass on connection and final state (events 200, transcript identical across seven turns); the live moment itself was not captured because the shared browser daemon dropped tabs
Late joiner pass
Reconnect pass: a fresh events request, six growing record refetches, a clean transcript, zero duplicated paragraphs across 166
Slow reader pass: 10,000 frames in 3.4 s; the fast reader got 1,668 chunks uninterrupted; the stalled reader received relay-close with reason slow_reader
Flag off and on pass: 404 then 200, capability false then true

Both consumer groups stayed at lag 0 through the burst.

Agent-generated, low weight. Not merged.

https://claude.ai/code/session_01GAqSs7fw6QRi2n1ZJ2tmAV

@vercel

vercel Bot commented Sep 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
agenta-documentation Ready Ready Preview Sep 5, 2026 10:13am UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

🗂️ Base branches to auto review (1)
  • release/.*

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Team

Run ID: 85807b68-82b6-4f62-b7b6-82072f627339

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Summary

Summary by CodeRabbit

  • New Features
    • Added opt-in live session previews for runs handled in another browser or client.
    • Conversations now display temporary streaming text, reasoning, tool inputs, and tool outputs in near real time.
    • Added automatic reconnection, authorization checks, heartbeats, and fallback to durable session records.
    • Added configuration options for live frames, retention, buffering, and authorization refresh intervals.
  • Bug Fixes
    • Improved handling of stale sessions, disconnected readers, slow consumers, interrupted updates, and oversized live-frame payloads.
    • Prevented live-relay startup failures from blocking durable session processing.

Walkthrough

This change adds an opt-in live session frame relay. Runners publish temporary frames, Redis workers relay them through SSE, and shared readers render the frames until durable records become available.

Changes

Live session relay

Layer / File(s) Summary
Frame contracts and stream retention
api/oss/src/apis/fastapi/sessions/models.py, api/oss/src/core/sessions/records/*, api/oss/src/core/sessions/streams/dtos.py, api/oss/src/dbs/redis/sessions/contract.py, api/oss/src/utils/env.py, api/oss/src/apis/fastapi/sessions/utils.py, api/oss/tests/pytest/unit/sessions/test_live_frame_ingest.py
Defines live-frame request and stream models, shared-reader capabilities, Redis channel naming, size limits, stream retention, and durable-record separation.
Runner publication and relay workers
services/runner/src/sessions/*, services/runner/tests/unit/live-frames.test.ts, api/oss/src/tasks/asyncio/sessions/*, api/entrypoints/worker_streams.py, api/oss/tests/pytest/unit/sessions/test_live_relay.py, api/oss/tests/pytest/unit/sessions/test_worker_streams_startup.py, hosting/docker-compose/*, hosting/kubernetes/helm/*, hosting/railway/oss/*
Projects runner events into bounded queues, publishes live frames, relays frames from Redis streams to session channels, and isolates relay initialization failures from durable consumers.
Authorized SSE delivery
api/oss/src/apis/fastapi/sessions/live_events.py, api/oss/src/apis/fastapi/sessions/router.py, web/packages/agenta-chat/src/transport/*, api/oss/tests/pytest/unit/sessions/test_live_relay.py
Adds the authorized /sessions/{session_id}/events SSE endpoint, heartbeats, relay-close events, authorization rechecks, bounded buffering, cleanup, and browser EventSource handling.
Shared-reader preview rendering
web/packages/agenta-entities/src/session/*, web/packages/agenta-chat/src/model/*, web/packages/agenta-chat/src/hooks/*, web/oss/src/components/AgentChatSlice/*, web/mobile/src/features/chat/*, web/packages/agenta-chat/tests/unit/model/livePreview.test.ts, web/packages/agenta-chat/tests/unit/transport/sessionLiveEvents.test.ts
Adds session preview state, frame reduction, remote-run subscription rules, transcript merging, disconnect refreshes, gap handling, and mobile shared-reader propagation.
Design and deployment configuration
docs/design/session-control-and-live-events/*, hosting/docker-compose/*, hosting/kubernetes/helm/*, hosting/railway/oss/*
Documents the live-event envelope, retention, authorization, recovery, release switches, and deployment settings for live-frame publication.

Estimated code review effort: 4 (Complex) | ~60 minutes

Merge Risk: 🟡 Moderate · up to 38df3

The opt-in live relay can expose runner authorization through its fallback transport and may show inconsistent shared-reader previews when frames are retried or reuse conflicting identities. These issues should be resolved before merge or explicitly accepted.

Sequence Diagram(s)

sequenceDiagram
  participant LiveFramePublisher
  participant SessionStreamsRouter
  participant RedisStream
  participant LiveRelayWorker
  participant live_event_stream
  participant EventSource
  LiveFramePublisher->>SessionStreamsRouter: POST live frame
  SessionStreamsRouter->>RedisStream: publish_live_frame
  LiveRelayWorker->>RedisStream: consume live frame
  LiveRelayWorker->>SessionStreamsRouter: publish session-channel frame
  SessionStreamsRouter->>live_event_stream: authorize SSE connection
  live_event_stream->>EventSource: emit SSE frame
  EventSource->>EventSource: reduce and render preview
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.58% which is insufficient. The required threshold is 60.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 66 functions across 37 files. (1 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly identifies the main change: relaying live session frames to authorized readers behind AGENTA_SESSIONS_SHARED_READER.
Description check ✅ Passed The description directly explains the live-frame relay implementation, configuration flags, client behavior, tests, and rollout scope.
Full details: Docstring Coverage

Explanation

Docstring coverage is 7.58% which is insufficient. The required threshold is 60.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 66 functions across 37 files. (1 skipped: 1 unsupported.)

✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/session-live-relay

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AGENT-GENERATED review, low weight. One agent read the branch as a mergeable unit. Treat every line as a pointer to check, not a gate.

Reading guide (5 lines):

  1. Verdict: ship after fixes. The design is followed on nearly every judged point; two items to fix or accept before the flag turns on in production.
  2. P1 (streaming.py / records_worker.py): durable records now share one global MAXLEN=100000 stream with the frame flood, and XDEL drain is removed unconditionally. The contract set retention per session.
  3. P2 (client livePreview.ts): every frame of a turn is retained and re-reduced, roughly O(n^2), with no trim; fine at the measured 3161 frames, not at the 100000 cap.
  4. Verified: one ingress and one stream, envelope roles, producer-set monotonic frame_index, non-blocking ingress and relay, records-worker skips frames, flag-off 404, cross-replica pub/sub, client dedup/order/tool-by-entity, sender stream untouched, tests per behavior.
  5. Cross-replica and slow-reader paths both check out; the durability risk is the one thing that needs a decision.

Comment thread api/oss/src/core/sessions/records/streaming.py
Comment thread api/oss/src/tasks/asyncio/sessions/records_worker.py Outdated
Comment thread web/packages/agenta-chat/src/model/livePreview.ts Outdated
Comment thread services/runner/src/sessions/live-frames.ts
Comment thread api/oss/src/apis/fastapi/sessions/router.py
Comment thread api/oss/src/apis/fastapi/sessions/live_events.py
Comment thread api/oss/src/tasks/asyncio/sessions/live_relay_worker.py
Comment thread api/oss/src/apis/fastapi/sessions/utils.py

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AGENT-GENERATED follow-up, low weight. Round 2 re-review at 7ae0792252. Both round-1 findings are addressed. Verdict: ship.

P1 durability (42ce70d). Durable records no longer share a global count cap. Frames are trimmed by age via MINID at min(age_cutoff, records_ack_frontier), so a durable entry newer than the records worker's acknowledged/pending frontier is never trimmed. The records worker XDELs consumed durable records after XACK and leaves frames for the relay. The count MAXLEN is now a caught-up-only safety valve (pending==0 and lag==0), raised to 100M. The flood-with-stalled-worker test, the post-ACK durable-only deletion test, and the MINID age-trim test all assert these invariants.

P2 client memory (7ae0792). Preview state is per entity plus lastFrameIndex, with no frame array or frame-id set, so memory is bounded by entity count, not frame count. The 5,000-delta test keeps one entity and the same final text.

Capability wording now matches decisions.md (deployment-wide switch, no version-one project allowlist).

Tests I ran for this re-review: the relay and ingest files (test_live_relay.py, test_live_frame_ingest.py) 12 passed against integration Postgres on 5440 (Redis stream semantics on fakeredis, since the stack Redis is not host-published); the chat package suite 641 passed including the 5 livePreview reducer tests.

Two non-blocking notes remain: trim_live_stream runs inline in the ingest path every 64 frames and trims the whole global stream, which repeats redundantly under concurrency (turn is not blocked); and the client now drops out-of-order frames rather than reordering, which is safe under the in-order sequential pump and reconnect-clears-preview.

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AGENT-GENERATED follow-up, low weight. Round 3 at 2146213306: ship. Desktop now subscribes through the shared useSessionLivePreview hook via the centralized sharedReaderAdvertised && runningElsewhere predicate (one subscription, sender's invoke stream untouched); the AGENTA_RUNNER_LIVE_FRAMES passthrough is in all 7 Compose files, Railway template + configure.sh, and the Helm runner deployment/schema/values with production defaults off, and the 4 env examples document the settings. Verified: 7/7 docker compose config pass, Helm renders the var true/false when set and omits it by default, chat 645 and oss 442 (1 skip) pass, and the subscription predicate has a 4-case test.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Team

Run ID: fc76bded-8b12-4eb0-8bee-bbf242c80e71

📥 Commits

Reviewing files that changed from the base of the PR and between ded2cc3 and 2146213.

📒 Files selected for processing (50)
  • api/entrypoints/worker_streams.py
  • api/oss/src/apis/fastapi/sessions/live_events.py
  • api/oss/src/apis/fastapi/sessions/models.py
  • api/oss/src/apis/fastapi/sessions/router.py
  • api/oss/src/apis/fastapi/sessions/utils.py
  • api/oss/src/core/sessions/records/dtos.py
  • api/oss/src/core/sessions/records/streaming.py
  • api/oss/src/core/sessions/streams/dtos.py
  • api/oss/src/dbs/redis/sessions/contract.py
  • api/oss/src/tasks/asyncio/sessions/live_relay_worker.py
  • api/oss/src/tasks/asyncio/sessions/records_worker.py
  • api/oss/src/utils/env.py
  • api/oss/tests/pytest/unit/sessions/test_live_frame_ingest.py
  • api/oss/tests/pytest/unit/sessions/test_live_relay.py
  • hosting/docker-compose/ee/docker-compose.dev.yml
  • hosting/docker-compose/ee/docker-compose.gh.local.yml
  • hosting/docker-compose/ee/docker-compose.gh.yml
  • hosting/docker-compose/ee/env.ee.dev.example
  • hosting/docker-compose/ee/env.ee.gh.example
  • hosting/docker-compose/oss/docker-compose.dev.yml
  • hosting/docker-compose/oss/docker-compose.gh.local.yml
  • hosting/docker-compose/oss/docker-compose.gh.ssl.yml
  • hosting/docker-compose/oss/docker-compose.gh.yml
  • hosting/docker-compose/oss/env.oss.dev.example
  • hosting/docker-compose/oss/env.oss.gh.example
  • hosting/kubernetes/helm/templates/runner-deployment.yaml
  • hosting/kubernetes/helm/values.schema.json
  • hosting/kubernetes/helm/values.yaml
  • hosting/railway/oss/scripts/configure.sh
  • hosting/railway/oss/template/template.json
  • services/runner/src/sessions/live-frames.ts
  • services/runner/src/sessions/persist.ts
  • services/runner/tests/unit/live-frames.test.ts
  • web/mobile/src/features/chat/ChatScreen.tsx
  • web/mobile/src/features/chat/LiveConversation.tsx
  • web/oss/src/components/AgentChatSlice/AgentConversation.tsx
  • web/oss/src/components/AgentChatSlice/hooks/useAgentChatSession.ts
  • web/oss/src/components/AgentChatSlice/hooks/useSessionHydration.ts
  • web/oss/src/components/AgentChatSlice/state/liveness.ts
  • web/packages/agenta-chat/src/hooks/index.ts
  • web/packages/agenta-chat/src/hooks/useAgentConversation.ts
  • web/packages/agenta-chat/src/hooks/useSessionLivePreview.ts
  • web/packages/agenta-chat/src/model/index.ts
  • web/packages/agenta-chat/src/model/livePreview.ts
  • web/packages/agenta-chat/src/transport/index.ts
  • web/packages/agenta-chat/src/transport/sessionLiveEvents.ts
  • web/packages/agenta-chat/tests/unit/model/livePreview.test.ts
  • web/packages/agenta-entities/src/session/core/schema.ts
  • web/packages/agenta-entities/src/session/index.ts
  • web/packages/agenta-entities/src/session/state/livePreview.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 4 remain after this review.

Comment thread api/oss/src/apis/fastapi/sessions/models.py
Comment thread api/oss/src/apis/fastapi/sessions/router.py Outdated
Comment thread api/oss/src/tasks/asyncio/sessions/records_worker.py Outdated
Comment thread services/runner/src/sessions/live-frames.ts
Comment thread web/packages/agenta-chat/src/hooks/useAgentConversation.ts Outdated
Comment thread web/packages/agenta-chat/src/transport/sessionLiveEvents.ts Outdated
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Status Destroyed (PR closed)

Updated at 2026-09-05T10:39:18.050Z

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mmabrouk mmabrouk added the lgtm This PR has been approved by a maintainer label Sep 4, 2026

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 The AI agent says:

This PR relays live frames to other clients while preserving the durable record consumer.

Focused simplification review using the new simplify skill: one non-blocking suggestion below. This is a static design/code review, not a rerun of the live release gate or a replacement for existing correctness reviews.

Comment thread api/oss/src/core/sessions/records/streaming.py Outdated
@mmabrouk

mmabrouk commented Sep 4, 2026

Copy link
Copy Markdown
Member Author

🤖 The AI agent says:

Correctness follow-up at 21462133066f56de06d42d1b5f78a027e587b1df: reviewed frame ingestion authorization, relay delivery, retention boundaries, and preview reduction, with the simplify principles in mind. I found no additional actionable correctness issue beyond the existing review threads. This was a focused static pass; I did not rerun the frontend, runner, or live release-gate suites. Existing unresolved findings remain for their owners to address.

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

📘 Docs preview

Status ✅ Ready
Preview https://pr-6522-agenta-docs-preview.mahmoud-637.workers.dev/docs
Inspect Actions run
Commit ecb22148adf56b7e49937ae98eb5cad536fd3ba6

This comment updates in place on every push.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
api/oss/src/apis/fastapi/sessions/router.py (1)

847-862: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Enforce frame idempotency before publication.

Lines 847-862 publish every accepted frame. An identical retry after a lost response creates another Redis entry and SSE emission. A conflicting payload that reuses frame_or_event_id or frame_index is also accepted. Atomically compare and store the frame identity and payload fingerprint. Treat identical retries as no-ops and reject conflicting reuse.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Team

Run ID: fa687350-e735-4372-8c94-0ac3a777917f

📥 Commits

Reviewing files that changed from the base of the PR and between 2146213 and 29337bd.

📒 Files selected for processing (22)
  • api/entrypoints/worker_streams.py
  • api/oss/src/apis/fastapi/sessions/models.py
  • api/oss/src/apis/fastapi/sessions/router.py
  • api/oss/src/core/sessions/records/dtos.py
  • api/oss/src/core/sessions/records/streaming.py
  • api/oss/src/tasks/asyncio/sessions/live_relay_worker.py
  • api/oss/src/tasks/asyncio/sessions/records_worker.py
  • api/oss/src/utils/env.py
  • api/oss/tests/pytest/unit/sessions/test_live_frame_ingest.py
  • api/oss/tests/pytest/unit/sessions/test_live_relay.py
  • docs/design/session-control-and-live-events/contracts/events.md
  • docs/design/session-control-and-live-events/decisions.md
  • docs/design/session-control-and-live-events/live-frame-envelope.md
  • hosting/docker-compose/ee/env.ee.dev.example
  • hosting/docker-compose/ee/env.ee.gh.example
  • hosting/docker-compose/oss/env.oss.dev.example
  • hosting/docker-compose/oss/env.oss.gh.example
  • web/oss/src/components/AgentChatSlice/AgentConversation.tsx
  • web/oss/src/components/AgentChatSlice/hooks/useSessionHydration.ts
  • web/packages/agenta-chat/src/hooks/useAgentConversation.ts
  • web/packages/agenta-chat/src/transport/sessionLiveEvents.ts
  • web/packages/agenta-chat/tests/unit/transport/sessionLiveEvents.test.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • hosting/docker-compose/ee/env.ee.gh.example
  • api/oss/src/apis/fastapi/sessions/models.py
  • api/entrypoints/worker_streams.py
  • hosting/docker-compose/oss/env.oss.gh.example
  • web/oss/src/components/AgentChatSlice/hooks/useSessionHydration.ts
  • web/oss/src/components/AgentChatSlice/AgentConversation.tsx
  • web/packages/agenta-chat/src/hooks/useAgentConversation.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent-generated Codex review, low weight.

SHIP AFTER FIXES

The dedicated live stream correctly isolates live trimming and acknowledgement from durable records, and the ownership, slow-reader, capability, and non-blocking failure paths are otherwise well covered. I found three release-relevant gaps: frame discontinuities are rendered instead of rejected, the flag-off durable queue no longer has its base retention cap, and a relay-only startup failure can prevent every durable consumer from starting. The new event-contract document also describes the next sender/replay increment as if it shipped here. Details and requested regressions are inline.

I reviewed ded2cc3...29337bd and all 15 resolved threads. I did not rerun the already-passing focused suites; two preview end-to-end CI jobs were still pending at review time.

Comment thread web/packages/agenta-chat/src/model/livePreview.ts
Comment thread api/oss/src/core/sessions/records/streaming.py
Comment thread api/entrypoints/worker_streams.py Outdated
Comment thread docs/design/session-control-and-live-events/contracts/events.md Outdated

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent-generated Codex review, low weight.

SHIP

No findings in 29337bdfbd..38df392a17.

The reducer now rejects an initial index above zero and any internal gap, clears and suppresses the preview, and triggers durable revalidation; a reader receiving 0, 1, ... still renders immediately. Durable records restore the base MAXLEN=100000 with approximate trimming in both flag states. Relay construction, XGROUP, and prune failures share one logged relay-only boundary after durable initialization, so durable consumers still run. events.md now separates shipped frame-only SSE behavior from later durable sender/replay work and matches the implementation.

Verification: the focused worker-streams startup test passed (1 test, no xdist, nice 19), and the correction diff passes git diff --check.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Team

Run ID: f206cfe0-6c56-4af6-93bd-e2877f437981

📥 Commits

Reviewing files that changed from the base of the PR and between 29337bd and 38df392.

📒 Files selected for processing (9)
  • api/entrypoints/worker_streams.py
  • api/oss/src/core/sessions/records/streaming.py
  • api/oss/tests/pytest/unit/sessions/test_live_frame_ingest.py
  • api/oss/tests/pytest/unit/sessions/test_worker_streams_startup.py
  • docs/design/session-control-and-live-events/contracts/events.md
  • web/packages/agenta-chat/src/hooks/useSessionLivePreview.ts
  • web/packages/agenta-chat/src/model/livePreview.ts
  • web/packages/agenta-chat/tests/unit/model/livePreview.test.ts
  • web/packages/agenta-entities/src/session/state/livePreview.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.

Comment thread docs/design/session-control-and-live-events/contracts/events.md
Comment thread docs/design/session-control-and-live-events/contracts/events.md
@mmabrouk
mmabrouk force-pushed the feat/session-live-relay branch from 38df392 to 3cfea3a Compare September 5, 2026 00:47
@mmabrouk
mmabrouk changed the base branch from main to feat/session-live-events September 5, 2026 00:47

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agent-generated Codex review, low weight.

SHIP

No findings in the seven adapted commit pairs. The adaptations preserve milestone-1 Stop models, records-worker ACK/retry behavior, the runner Stop path, and watchdog behavior while retaining PR 6522 behavior: a separate bounded live stream, the 64 KiB limit, relay startup isolation, gap rejection, and no-store.

The rebased 54-file lane contains no files outside the original 55-file PR set. records_worker.py is the sole old-only file because the rebased final version is byte-identical to milestone 1. I relied on the assembly post-rebase validation and did not rerun a test.

Publish temporary session frames to a dedicated bounded Redis Stream. Restore the durable records queue and both consumers to independent ACK and delete behavior, with count and age retention tests.

Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
Reject live frames above 64 KiB during request validation and immediately before Redis publication. Apply the same limit to declared HTTP request bodies and cover each boundary with regression tests.

Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
Mark the identity-scoped session event stream as no-store so intermediaries and browsers do not retain live session content. Pin the response header in a route regression test.

Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
Document one HTTP ingress with separate durable-record and disposable-frame Redis Streams. Record the deployment-wide frame bounds and clarify that clients receive the global shared-reader capability.

Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
Validate session live events with the shared diagnostic helper and cover invalid-frame logging. Shorten the three reviewed live-relay comments without changing behavior.

Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
Require each live execution to start at frame zero and advance contiguously. Suppress the preview after a gap and refresh durable session records.

Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
Restore the base branch's 100,000-entry approximate trim for durable record publication. Pin the flag-off Redis stream arguments in a regression test.

Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
Initialize durable consumers before the optional live relay. Log relay setup failures and continue running the durable stream consumers.

Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
Document the live-frame relay and gap handling as the shipped contract. Mark sender handoff, durable event envelopes, sequences, watermarks, and Postgres replay as later target behavior.

Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
@mmabrouk
mmabrouk force-pushed the feat/session-live-relay branch from 3cfea3a to ecb2214 Compare September 5, 2026 10:11
@mmabrouk
mmabrouk merged commit 0cb6549 into feat/session-live-events Sep 5, 2026
73 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant