Skip to content

test(gateway): correct the Anthropic SSE stub to the shape the API emits - #181

Merged
adrian-lorenzo merged 4 commits into
theam:mainfrom
ophiocus:test/gateway-anthropic-stub-shape
Aug 28, 2026
Merged

test(gateway): correct the Anthropic SSE stub to the shape the API emits#181
adrian-lorenzo merged 4 commits into
theam:mainfrom
ophiocus:test/gateway-anthropic-stub-shape

Conversation

@ophiocus

Copy link
Copy Markdown
Contributor

What changes

anthropicSseBody() and the abort-stream stub now emit the frames api.anthropic.com actually sends:
usage at the top level of message_delta, as a sibling of delta, with delta carrying only the stop
fields; a full Message envelope on message_start; and the null cache counters an uncached request
reports.

No production code changes. The suite passes unchanged.

Why

The stub is what every Anthropic streaming assertion in gateway.test.ts is measured against, and it
encodes a frame the provider never sends. usage is a sibling of delta — the shape is typed in a
dependency this repo already has, @anthropic-ai/sdk, resources/messages/messages.d.ts:

export interface RawMessageDeltaEvent {
    delta: RawMessageDeltaEvent.Delta;   // container, stop_details, stop_reason, stop_sequence
    type: 'message_delta';
    usage: MessageDeltaUsage;            // <- sibling of delta, not inside it
}

That matters for what the tests can catch. UsageTee reads usage from the top-level parsed object and
from parsed.delta; on the real wire the first is what meters every streamed output token and the second
never fires. With the old stub the coverage is inverted — mutating services/gateway/src/usage.ts on
main:

mutation old stub corrected stub
drop the parsed.delta read — dead against the real wire streaming assertions fail unaffected
drop the top-level parsed read — meters real streamed output streaming assertions still pass fails

So the suite pinned dead code and left the live metering path unpinned. Cost from that path lands in
spend_counters and is enforced by hardBudgetBlock, which is why it seemed worth correcting rather than
leaving.

The shape has been in the stub since a6553e9 (2020-07-03), so this is independent of any open work. PR #148
copies the same shape into new unit tests; I have left the detail on that thread rather than touching it
here, since its production fix is correct.

Verification

pnpm --filter @facility/gateway test     # 52 passed, unchanged by this PR
pnpm exec biome check services/gateway/test/gateway.test.ts

Beyond the suite: the mutation table above, run both ways on main. Postgres from
docker-compose.dev.yml; without it the DB-backed cases skip and the count drops to 20 passed | 1 skipped.

  • pnpm verify passes locally — not run. Gateway package suite + biome only. Say the word if you want the full run before review.
  • Behaviour verified beyond the test suite — the two mutations above.
  • Documentation updated, or no user-facing change — no user-facing change.

anthropicSseBody() puts `usage` inside `delta` on message_delta. The API puts it
at the top level, as a sibling of `delta`, and `delta` carries only the stop
fields — see RawMessageDeltaEvent in @anthropic-ai/sdk, already a dependency of
services/api. message_start is also thin: the real frame carries a full Message
envelope, and usage there reports output_tokens alongside the input and cache
counts.

The shape matters because the stub is what every Anthropic streaming assertion
in this suite is measured against. Reading the top-level `usage` is what meters
streamed output tokens in production, and no test exercised that path: with the
old stub, deleting the top-level source from UsageTee left the streaming tests
green. The corrected stub also sends the null cache counters an uncached request
reports, so the merge behaviour is exercised rather than assumed.

No production behaviour changes; the suite passes unchanged (52/52).

@adrian-lorenzo adrian-lorenzo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the contribution!

Since #148 has now landed, please update this branch and also correct the MESSAGE_DELTA fixture in services/gateway/test/usage.test.ts, plus the comment in services/gateway/src/usage.ts that still says output usage is under delta.usage. Otherwise the integration stub will match Anthropic’s wire format while the new unit fixtures and production documentation continue to encode the old shape.

ophiocus and others added 2 commits August 24, 2026 08:41
… shape

Review follow-up on theam#181, after theam#148 landed: the integration stub now matches
Anthropic's wire format, but the `MESSAGE_DELTA` unit fixture in
`usage.test.ts` still nested `usage` inside `delta`, and the comment in
`usage.ts` still documented output usage as living under `delta.usage`.

The fixture now emits the real frame — `usage` as a sibling of `delta`, with
`delta` carrying only the stop fields — and the comment states that shape.
The `parsed.delta` merge source is deliberately kept as tolerance for relays
that nest usage inside the delta, and the comment now says so.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ophiocus

Copy link
Copy Markdown
Contributor Author

Since #148 has now landed, please update this branch and also correct the MESSAGE_DELTA fixture in services/gateway/test/usage.test.ts, plus the comment in services/gateway/src/usage.ts that still says output usage is under delta.usage. Otherwise the integration stub will match Anthropic’s wire format while the new unit fixtures and production documentation continue to encode the old shape.

Done — and since this is the branch's first update: it is updated by merge, not rebase, so the commit you reviewed stays as it was.

Gateway suite 57/57 against facility_gw; biome and typecheck clean.

@adrian-lorenzo adrian-lorenzo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the solid contribution!

@adrian-lorenzo
adrian-lorenzo merged commit eb0aa74 into theam:main Aug 28, 2026
10 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.

2 participants