v0.2.0: Add SSE resume, run export/compare, and crash recovery#1
Merged
ajit-zer07 merged 1 commit intomainfrom Mar 20, 2026
Merged
v0.2.0: Add SSE resume, run export/compare, and crash recovery#1ajit-zer07 merged 1 commit intomainfrom
ajit-zer07 merged 1 commit intomainfrom
Conversation
- Rewrite /runs/:id/stream to support resumable SSE via afterSeq query
param and Last-Event-ID header, with backfill from DB, dedup, and
configurable heartbeat
- Add run export endpoint (GET /runs/:id/export) for full run bundles
including session, projection, events, artifacts, and metrics
- Add run comparison endpoint (POST /runs/compare) for side-by-side
diffing of status, duration, confidence, participants, and signals
- Add RunRecoveryService to reconnect active runs on startup, with
binding_session promotion and recovery event emission
- Add progress column to run_projections, bump projection schema to v3
- Add listCanonicalRange and listRawByRun to EventRepository
- Fix stream consumer: reset retry counter on success, fix timer leak
in withIdleTimeout, unref timers to avoid blocking shutdown
- Add indexes on run_events_raw for (run_id, ts) and (run_id, seq)
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.
PR Description
Summary
Resumable SSE streams: The
/runs/:id/streamendpoint now supportsafterSeq/Last-Event-IDfor gap-free reconnection. Missed events arebackfilled from the database in batches, deduplicated against the live hub,
and each SSE frame carries an
idfield for browser-native resume. Aconfigurable heartbeat (
STREAM_SSE_HEARTBEAT_MS, default 15s) keepsconnections alive through proxies.
Run insights: New
GET /runs/:id/exportbundles the full run state(run record, session, projection, metrics, artifacts, canonical + raw events)
into a single JSON payload. New
POST /runs/comparediffs two runs on status,duration, confidence, participants, and signals.
Crash recovery:
RunRecoveryServiceruns on application bootstrap,queries for active runs (
running/binding_session), promotes stalledbinding_sessionruns, emits asession.stream.openedrecovery event,and re-attaches stream consumers from
lastEventSeq. Controlled viaRUN_RECOVERY_ENABLED(defaulttrue).Progress projection: Adds a
progressJSONB column torun_projections(migration
0003), wires it through the projection repository and service,and bumps
PROJECTION_SCHEMA_VERSIONto 3. Removes the(row as any)cast.Stream consumer reliability: Resets the retry counter after each
successful event, fixes a timer leak in
withIdleTimeout(clears timeout +calls
iterator.return()), and unrefs timers to avoid blocking gracefulshutdown.
New files
drizzle/0003_v2_progress_and_export.sqlsrc/controllers/run-insights.controller.tssrc/insights/run-insights.service.tssrc/runs/run-recovery.service.tssrc/dto/compare-runs.dto.tssrc/dto/export-run-query.dto.tssrc/dto/stream-run-query.dto.tsModified files
src/controllers/runs.controller.tsstreamRunwith resume/backfill/heartbeatsrc/runs/stream-consumer.service.tssrc/storage/event.repository.tslistCanonicalRange,listRawByRunsrc/storage/projection.repository.tsprogresson upsertsrc/projection/projection.service.tssrc/db/schema.tsprogresscolumn onrunProjectionssrc/contracts/control-plane.tsRunExportBundle,RunComparisonResultsrc/dto/run-responses.dto.tsRunBundleExportDto,RunComparisonResultDtosrc/config/app-config.service.tsstreamSseHeartbeatMs,runRecoveryEnabledsrc/app.module.ts.env.examplepackage.jsonTest plan
npm test— all 17 suites pass (new specs for recovery, insights, event repo, controllers)/runs/:id/stream?afterSeq=5, confirm backfilled events arrive before live ones, noduplicates
GET /runs/:id/exportreturns a complete bundle withincludeRaw=truePOST /runs/comparewith two completed runs, verify participant/signal diffsRunRecoveryServicereconnects streamsdrizzle:migrateto apply0003, verifyprogresscolumn exists