Skip to content

fix(anthropic): preserve terminal SSE frames - #316

Merged
Ingwannu merged 1 commit into
devfrom
agent/fix-anthropic-stream-eof
Jul 23, 2026
Merged

fix(anthropic): preserve terminal SSE frames#316
Ingwannu merged 1 commit into
devfrom
agent/fix-anthropic-stream-eof

Conversation

@Ingwannu

@Ingwannu Ingwannu commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Summary

Fixes Anthropic-compatible streaming responses that ended as adapter_eof / zero terminal usage even though the upstream emitted visible text and a valid terminal message_stop (#312).

Root cause

The Anthropic adapter parsed newline-delimited lines directly from each fetch chunk. Event state did not survive arbitrary chunk boundaries, and the final buffer was never flushed at EOF. A terminal message_stop without a trailing newline could therefore be stranded. If the upstream also omitted an intermediate usage snapshot, no fallback done event was emitted and the bridge correctly classified the otherwise successful stream as incomplete.

Changes

  • Add a bounded-responsibility text/event-stream decoder that:
    • preserves event/data state across arbitrary reader chunks;
    • supports CRLF and multiline data;
    • dispatches the final record without a trailing newline or blank delimiter;
    • cancels/releases the body reader safely on early termination.
  • Route Anthropic stream parsing through the decoder.
  • Preserve compatible reasoning / reasoning_delta blocks as internal thinking events without suppressing later visible text.
  • Support the same compatible reasoning block in non-streaming responses.
  • Document the framing and compatibility behavior.

Validation

  • bun run test: 3,616 passed, 0 failed
  • bun run typecheck
  • bun run privacy:scan
  • focused SSE decoder, Anthropic adapter, Responses bridge, Claude Messages, usage, and lifecycle tests
  • adversarial coverage for split event:/data: chunks, no usage snapshot, and no final newline

Fixes #312

Summary by CodeRabbit

  • New Features

    • Added support for displaying reasoning content from Anthropic-compatible models in streaming and non-streaming responses.
    • Improved handling of streamed responses split across arbitrary network chunks.
    • Streams now correctly complete when the final event lacks a trailing newline.
  • Bug Fixes

    • Prevented dropped reasoning or text content during response translation.
    • Improved resilience when processing malformed or empty stream frames.
  • Documentation

    • Clarified streaming event decoding behavior in the adapter reference.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 383f1cd7-ce3d-4957-919d-384ee6d5788a

📥 Commits

Reviewing files that changed from the base of the PR and between d56d294 and 2467ced.

📒 Files selected for processing (5)
  • docs-site/src/content/docs/reference/adapters.md
  • src/adapters/anthropic.ts
  • src/lib/sse-decoder.ts
  • tests/anthropic-compatible-stream.test.ts
  • tests/sse-decoder.test.ts

📝 Walkthrough

Walkthrough

The Anthropic adapter now uses a shared chunk-safe SSE decoder, supports terminal records without trailing newlines, maps reasoning deltas and blocks to thinking_delta, and adds coverage for decoder boundaries, stream bridging, completion, and non-stream parsing.

Changes

Anthropic SSE handling

Layer / File(s) Summary
Chunk-safe SSE decoder
src/lib/sse-decoder.ts, tests/sse-decoder.test.ts
Adds SSE record parsing across arbitrary chunks, multiline data and CRLF framing, EOF dispatch without a trailing delimiter, reader cleanup, and focused tests.
Adapter stream and reasoning integration
src/adapters/anthropic.ts, tests/anthropic-compatible-stream.test.ts, docs-site/src/content/docs/reference/adapters.md
Replaces manual SSE parsing with decodeServerSentEvents, maps reasoning events and blocks to thinking_delta, preserves terminal completion behavior, and documents chunk and EOF handling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AnthropicResponse
  participant decodeServerSentEvents
  participant AnthropicAdapter
  participant CodexEventStream
  AnthropicResponse->>decodeServerSentEvents: stream SSE chunks
  decodeServerSentEvents->>AnthropicAdapter: yield decoded records
  AnthropicAdapter->>CodexEventStream: emit thinking_delta and text_delta
  AnthropicAdapter->>CodexEventStream: emit final done event
Loading

Possibly related issues

Suggested reviewers: lidge-jun

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/fix-anthropic-stream-eof

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant