[release] v0.115.1 - #6586
Merged
Merged
Conversation
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
The two Postgres-backed records tests declared an async autouse fixture with the plain pytest decorator, which pytest-asyncio 1.x does not collect, so both files errored at setup before any query ran. With the pytest_asyncio decorator both files run: 3 passed against the proof stack database. Claude-Session: https://claude.ai/code/session_01GAqSs7fw6QRi2n1ZJ2tmAV
Await replay queue capacity so a finite durable backlog cannot be mistaken for a live producer outrunning its reader. Keep the existing drop-and-reconnect policy for live frames and cover replay larger than the configured buffer. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
Route live frames and committed durable events through one bounded relay-stream append path while leaving record ingest retention unchanged. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
Acquire per-session sequence cursors in a stable order while preserving record order inside each session. Leave every project batch message pending when its transactional append fails. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
feat(sessions): relay live frames to every authorized reader behind AGENTA_SESSIONS_SHARED_READER
feat(sessions): durable reconnect with a per-session sequence, snapshot, and replay
feat(sessions): let the sender read from the shared path and detach the run from its request
`_direct_event` read `payload` straight out of `record.attributes`, an open dict filled from the ingest wire. A record whose `payload` was a string, a list or a number reached `payload.get(...)` and raised `AttributeError` outside the projection's try block. That propagated into `RecordsWorker.process_batch` after the batch's rows were already committed, so the message ids were never acknowledged and the same poison record came back on every redelivery. A non-dict payload now reads exactly like a missing one. Reported by CodeRabbit on #6572. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
`XADD` ran an exact `MAXLEN` trim on every live relay message, and `trim_live_stream` ran an exact `XTRIM MINID`. Exact trimming is O(N) in the evicted entries and sits on the producer's hot path. The stream carries disposable frames, so a few extra entries per listpack cost nothing. The record stream already used approximate trimming. Reported by CodeRabbit on #6572. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
The fixture replaced `_analytics_engine` with `None` without closing it, so an engine an earlier test module created kept its connection pool open for the rest of the run. Teardown only closed the engine the fixture itself created. Reported by CodeRabbit on #6572. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
The coding guidelines call for cursor pagination through the shared `Windowing` type. `SessionTranscriptWindowing` is a deliberate exception, and the reason now sits next to the model instead of in a review thread. Reported by CodeRabbit on #6572. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
`session-accepted` switches the client to shared delivery: live text stops arriving on the invoke stream and starts arriving on the session events route. The runner emitted it at the top of the request, before the attachment-count check and before the first heartbeat answered the admission question. A turn the runner was about to refuse therefore moved the client onto a channel that would serve it nothing. Acceptance now rides the same admission path as the `turn` event, so a refused turn tells the client only what it already told it: a `session_turn_in_use` error and a failed terminal result. Reported by CodeRabbit on #6572. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
`postFrames` had no application-level timeout. An ingest endpoint that stalled before response headers left `pump()` pending, and `persist.ts` waits on `whenIdle()` in `flush()`, so a stalled socket delayed turn completion for as long as it stayed open. The POST now carries a 5 s abort signal and a timed-out batch counts as dropped, like any other send failure. `postTimeoutMs` is the test seam. Reported by CodeRabbit on #6572. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
`busyRef` folds `acceptedRunPending` into `busy`, and the transcript adoption guard read it. A shared-delivered turn renders from the live frames, not from a local stream, so this made `shouldAdoptServerTranscript` refuse for the whole accepted window. `revalidate` could then neither adopt nor confirm a candidate ahead of the client's watermark, and `hydrateAndOpen` only opens the events stream once one of the two succeeds. A shared turn whose stream dropped mid-run therefore reconnected on a growing backoff and never came back until it settled. The adoption guard now reads a ref that tracks only a stream this client renders. `busyRef` is unchanged for the preserve-at-unmount verdict, regenerate and rewind, which do want the accepted window. Reported by CodeRabbit on #6572. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
The schema transform always emits `sequence`, so both fixtures were annotated as `SessionRecord` while missing a required property. The package's `types:check` covers `src/` only, so this never failed a build, but the annotation was wrong. Reported by CodeRabbit on #6572. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
Three doubles accepted the flag and dropped it. The fake runner backend now hands it to `request_to_wire`, so the integration transport test drives the real detached payload, and both unit conftests record it. The service handler gains a direct assertion: nothing else in that package pinned `flags.detached` at the backend boundary, so a handler that stopped forwarding it passed every other invoke test. Reported by CodeRabbit on #6572. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
The events contract still told clients that the route sends no durable events, sequences,
watermarks or replayed rows, and kept the whole durable-event section under a "not shipped"
heading in the future tense. Milestone 2 shipped replay over `GET /sessions/{id}/events`
and browser fan-out. The decisions log now marks fan-out delivered and records the
approximate trimming, leaving redaction as the open item under O-004.
Reported by CodeRabbit on #6572.
Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
…abbit [fix] Address CodeRabbit review for milestone 2 live events
Create and drop the records sequence index concurrently from Alembic autocommit blocks so populated tracing tables remain writable during the index operation. Cover empty and populated-table upgrades and downgrades in a disposable tracing database. Claude-Session: https://claude.ai/code/session_0164kzT6ttwpBtzvcDC6YzYk
[fix] Build the records sequence index concurrently
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
[feat] Session control milestone 2: live events
Contributor
Author
📘 Docs preview
This comment updates in place on every push. |
Contributor
Author
Railway Preview Environment
Updated at 2026-09-05T22:44:05.698Z |
[fix] Stop accepted shared session executions
mmabrouk
approved these changes
Sep 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
New version v0.115.1 in