Skip to content

feat: add hosted HTTP SSE transport#240

Merged
roackb2 merged 1 commit into
mainfrom
codex/http-sse-run-transport
Jul 12, 2026
Merged

feat: add hosted HTTP SSE transport#240
roackb2 merged 1 commit into
mainfrom
codex/http-sse-run-transport

Conversation

@roackb2

@roackb2 roackb2 commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Summary

  • add @roackb2/heddle/hosted/http-sse for strict replay cursors, canonical SSE frames, backpressure, and subscriber-only disconnect cleanup on Node HTTP
  • add @roackb2/heddle-remote/http-sse for browser-safe REST/fetch lifecycle, accepted/cancel validation, incremental SSE parsing, reader cleanup, and event identity checks
  • keep auth, authorization, public schemas, route registration, retry timers, cursor persistence, UI state, CORS, and limits host-owned
  • refactor the hosted example to remove its duplicated Node SSE writer and ~180-line browser transport client
  • document the opt-in import paths and assumption boundaries for coding agents

API shape

import {
  parseConversationRunSseReplayCursor,
  streamConversationRunSse,
} from '@roackb2/heddle/hosted/http-sse'

import {
  ConversationRunHttpSseClient,
} from '@roackb2/heddle-remote/http-sse'

The preset intentionally standardizes only the conventional POST /runs, GET /runs/:runId/events, and POST /runs/:runId/cancel resource. tRPC, WebSocket, IPC, and other transports continue to use the neutral base layer.

Verification

  • yarn test:unit — 660 passed
  • yarn test:integration — 291 passed, including the real HTTP hosted-stack flow
  • yarn remote:build
  • yarn build
  • focused lint/typecheck
  • npm pack ./packages/heddle-remote --dry-run/http-sse declarations and runtime files included

PR #239 is merged; this branch is rebased onto the resulting main.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 448600010d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +60 to +62
const events = options.subscribe(signal);
setSseHeaders(options.response);
for await (const event of events) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Delay SSE headers until subscription lookup can fail

When subscribe is implemented as an async generator or otherwise defers run lookup/authorization until iteration, this flushes the 200 SSE headers before that lookup can throw. In that context the host's route can no longer return its JSON 404/401 policy (the Express handler only does so before headers are sent), so clients see a successful SSE response that closes instead of the intended error.

Useful? React with 👍 / 👎.

Comment on lines +64 to +66
this.baseUrl = options.baseUrl.trim().replace(/\/+$/, '');
if (!this.baseUrl) {
throw new ConversationRunHttpSseClientError('Conversation run baseUrl cannot be empty.');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve root-relative base URLs

For deployments that mount the conventional resource at the origin root (/runs), callers naturally pass baseUrl: '/'; this normalization strips it to an empty string and then throws, so the HTTP/SSE client cannot be used for that valid route layout. Reject only originally blank values or preserve / as the normalized base.

Useful? React with 👍 / 👎.

@roackb2 roackb2 merged commit fc12fcf into main Jul 12, 2026
5 checks passed
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