Skip to content

spec(api-server): add SessionEvent Kind for durable AG-UI event store#1475

Draft
jsell-rh wants to merge 4 commits intoambient-code:mainfrom
jsell-rh:feat/session-events-api
Draft

spec(api-server): add SessionEvent Kind for durable AG-UI event store#1475
jsell-rh wants to merge 4 commits intoambient-code:mainfrom
jsell-rh:feat/session-events-api

Conversation

@jsell-rh
Copy link
Copy Markdown
Contributor

Introduces SessionEvent as the canonical append-only record of all AG-UI protocol events in a session, replacing agui-events.jsonl and the overloaded non-user rows that grpc_push_middleware wrote to session_messages.

Key design decisions:

  • SessionMessage narrowed to runner inbox (user messages only); matches the existing WatchSessionMessages watcher which discards non-user events
  • SessionEvent stores raw AG-UI JSON verbatim; SSE replay pipes payload directly without transformation (fixes the legacy wrapper format bug)
  • run_id and thread_id are first-class columns enabling per-run compaction and targeted queries
  • Compaction: TEXT_MESSAGE_CONTENT rows marked superseded=true after RUN_FINISHED; MESSAGES_SNAPSHOT appended as canonical transcript
  • /agui-events endpoint with since= (reconnect) and run_id= filters
  • grpc_push_middleware must migrate to PushSessionEvent; GRPCMessageWriter is retired

Introduces SessionEvent as the canonical append-only record of all AG-UI
protocol events in a session, replacing agui-events.jsonl and the overloaded
non-user rows that grpc_push_middleware wrote to session_messages.

Key design decisions:
- SessionMessage narrowed to runner inbox (user messages only); matches
  the existing WatchSessionMessages watcher which discards non-user events
- SessionEvent stores raw AG-UI JSON verbatim; SSE replay pipes payload
  directly without transformation (fixes the legacy wrapper format bug)
- run_id and thread_id are first-class columns enabling per-run compaction
  and targeted queries
- Compaction: TEXT_MESSAGE_CONTENT rows marked superseded=true after
  RUN_FINISHED; MESSAGES_SNAPSHOT appended as canonical transcript
- /agui-events endpoint with since=<seq> (reconnect) and run_id= filters
- grpc_push_middleware must migrate to PushSessionEvent; GRPCMessageWriter
  is retired

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 28, 2026

Deploy Preview for cheerful-kitten-f556a0 ready!

Name Link
🔨 Latest commit d2453f0
🔍 Latest deploy log https://app.netlify.com/projects/cheerful-kitten-f556a0/deploys/69f128d8a81aa7000832099c
😎 Deploy Preview https://deploy-preview-1475--cheerful-kitten-f556a0.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 28, 2026

Important

Review skipped

Draft detected.

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: dee9bcf9-6789-49a0-9f7d-320033e5a69d

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
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

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 and usage tips.

jsell-rh and others added 3 commits April 28, 2026 20:23
Fix all 8 blockers and 7 majors identified by the 10-agent review:

B1/B7: Add PushSessionEvent proto contract with run_id + thread_id fields
B2: Specify session_events DB migration requirement (table + indexes)
B3: Document AGUIEvents handler migration from ephemeral proxy to DB-backed
B4: Document DeriveAgentStatus() migration path from JSONL to session_events
B5: Fix event type enum — remove nonexistent TOOL_CALL_RESULT, add STEP_*,
    STATE_DELTA, ACTIVITY_SNAPSHOT/DELTA, REASONING_MESSAGE_* (5 new types)
B6: Expand compaction scope — supersede all streaming deltas (TEXT_MESSAGE_CONTENT,
    TOOL_CALL_ARGS, REASONING_MESSAGE_CONTENT, STATE_DELTA, ACTIVITY_DELTA),
    not just TEXT_MESSAGE_CONTENT as previously stated
B8: Correct seq to global BIGSERIAL (not per-session unique); add design decision

M1: Add required indexes: (session_id, seq), (session_id, run_id), replay partial
M2: Define live-tail mechanism (subscribe-before-replay fan-out pattern)
M3: Add retention note and ?limit parameter
M4: Document write throughput guidance (individual inserts ok; batching future)
M5: Add RBAC requirements for GET /agui-events and PushSessionEvent gRPC
M6: Document StreamTextMessages() migration from session_messages to session_events

T1: Fix Overview "Message" bullet to reference SessionEvent
T2: Fix String Tree "SessionMessage is one turn" — add SessionEvent line
T3: Fix Inbox comparison table "Created by" to user-only

Also: document payload encoding bug (model_dump needs by_alias=True),
GRPCMessageWriter retirement, and session_messages narrowing cleanup path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolves all design-level inputs and second-round factual issues:

- Fix endpoint path: agui-events → agui/events (slash, sub-resource)
- Add TOOL_CALL_RESULT to event_type enum; remove incorrect denial
- Add THINKING_* deprecation note (match agui.go, not ag_ui library)
- Fix compaction SQL: IS NOT DISTINCT FROM for nullable run_id
- Fix live-tail: PostgreSQL LISTEN/NOTIFY replaces in-memory channel
  (cross-replica fan-out); add 4-step subscribe/replay/drain/live procedure
- Fix gRPC auth: service-caller boolean (IsServiceCaller), not RBAC role
- Fix run_id/thread_id plumbing: extend grpc_push_middleware signature,
  remove wrong grpc_transport.py:281-282 attribution
- PushSessionEventResponse now returns seq for reconnect cursor
- Add explicit CREATE TABLE DDL for session_events with all column types,
  NOT NULL constraints, DEFAULT FALSE on superseded
- Add migration registration guidance (function name, ID format, rollback)
- StreamTextMessages: implement+register route from session_events;
  acpctl session messages migrates to this endpoint
- DeriveAgentStatus: event-type-filtered query instead of LIMIT 50;
  document case-insensitive + non-alpha-strip normalization for AskUserQuestion
- GRPCMessageWriter: add _synthesize_run_error dependency; atomic
  deployment requirement; 7-step implementation checklist including
  buf generate and Go handler authorship

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
"inbox" is reserved for the Inbox Kind (Agent persistent message queue).
Replace all session_messages-related uses of "inbox" with "delivery queue"
or "runner delivery queue":

- ERD comment: runner inbox → runner delivery queue
- ERD relationship label: "inbox" → "messages"
- Event streams table description
- API reference descriptions for GET/POST /sessions/{id}/messages
- String Tree description of SessionMessage
- Design Decisions table entry
- Section heading: Runner Inbox → Runner Delivery Queue

No Inbox Kind references changed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant