Skip to content

fix(httpapi): encode event stream timestamps as epoch millis#28852

Open
faern wants to merge 2 commits into
anomalyco:devfrom
faern:fix/session-next-timestamp-wire-format
Open

fix(httpapi): encode event stream timestamps as epoch millis#28852
faern wants to merge 2 commits into
anomalyco:devfrom
faern:fix/session-next-timestamp-wire-format

Conversation

@faern
Copy link
Copy Markdown

@faern faern commented May 22, 2026

Issue for this PR

Closes #28847

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

The OpenAPI spec declares session.next.* event timestamp as a number (epoch millis), but the SSE streams sent it as an ISO 8601 string. Bus payloads carry Effect DateTime objects, and JSON.stringify serializes those via DateTime.toJSON() (ISO string) instead of the schema-encoded epoch millis. The shared eventData SSE serializer now walks the payload and converts any DateTime to epoch millis before stringifying, so /event and /global/event
match the spec.

The vast majority of this PR adds the tests. The first commit is the actual fix. We can merge only the fix if you think the tests add too much complexity.

How did you verify your code works?

I ran a build of this branch locally and interacted with the API, making sure it now returns the unix epoch integer. I also added regression tests for /event, /global/event (nested sync events), and the eventData serializer. Also ran the full opencode test suite, typecheck, and the httpapi exerciser gates locally.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

faern added 2 commits May 22, 2026 14:15
Effect `DateTime` values serialize through `toJSON()` as ISO 8601
strings. The `/event` and `/global/event` SSE handlers ran bus payloads
through a plain `JSON.stringify`, so every `session.next.*` event sent
its `timestamp` as a string. The OpenAPI spec declares `timestamp` as a
number (the encoded form of `V2Schema.DateTimeUtcFromMillis`), so a
strict typed client cannot decode any `session.next.*` event and the
event stream dies on the first prompt.

Encode `DateTime` values to epoch millis before serializing, matching
the spec and every other timestamp in the API.
Guard against regressing the `session.next.*` `timestamp` wire format.
Tests assert epoch-millis numbers on the `/event` and `/global/event`
SSE streams, and that `eventData` encodes nested `DateTime` values.
@github-actions
Copy link
Copy Markdown
Contributor

Hey! Your PR title Fix/session next timestamp wire format doesn't follow conventional commit format.

Please update it to start with one of:

  • feat: or feat(scope): new feature
  • fix: or fix(scope): bug fix
  • docs: or docs(scope): documentation changes
  • chore: or chore(scope): maintenance tasks
  • refactor: or refactor(scope): code refactoring
  • test: or test(scope): adding or updating tests

Where scope is the package name (e.g., app, desktop, opencode).

See CONTRIBUTING.md for details.

@faern faern changed the title Fix/session next timestamp wire format Fix timestamp wire format in session.next.* events. May 22, 2026
@faern faern changed the title Fix timestamp wire format in session.next.* events. fix(httpapi): encode event stream timestamps as epoch millis May 22, 2026
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.

OpenAPI spec types session.next.* event timestamp as a number, but the server sends an ISO 8601 string

1 participant