Task 10 — Wire Anthropic /v1/messages
Depends on: 06
Unblocks: 11
Goal
Both streaming and non-streaming Anthropic /v1/messages requests record one
row each, using normalizeAnthropicMessage or the Anthropic stream
accumulator.
Scope
In src/routes/messages/handler.ts (and any proxy code that fans events to
the client):
- Non-stream: parse
response.usage via normalizeAnthropicMessage.
- Stream:
- Build an
createAnthropicAccumulator().
- Feed every event passing through.
- On
message_stop (final event): recordUsage(... finalize() ..., status: 'ok').
- On abort:
status: 'aborted'.
- On error:
status: 'error'.
endpoint = 'messages', upstreamFormat = 'anthropic'.
Edge cases
- The Anthropic stream's
output_tokens in message_delta.usage is
cumulative — accumulator must track the maximum, not sum.
- Tool calls and thinking blocks: counted via
output_tokens in the cumulative
delta. reasoningTokens stays at 0 in v1.
Definition of Done
Task 10 — Wire Anthropic
/v1/messagesDepends on: 06
Unblocks: 11
Goal
Both streaming and non-streaming Anthropic
/v1/messagesrequests record onerow each, using
normalizeAnthropicMessageor the Anthropic streamaccumulator.
Scope
In
src/routes/messages/handler.ts(and any proxy code that fans events tothe client):
response.usagevianormalizeAnthropicMessage.createAnthropicAccumulator().message_stop(final event):recordUsage(... finalize() ..., status: 'ok').status: 'aborted'.status: 'error'.endpoint = 'messages',upstreamFormat = 'anthropic'.Edge cases
output_tokensinmessage_delta.usageiscumulative — accumulator must track the maximum, not sum.
output_tokensin the cumulativedelta.
reasoningTokensstays at 0 in v1.Definition of Done
/v1/messagesproduces a row withupstream_format = 'anthropic'./v1/messagesproduces a row whoseoutput_tokensmatchesthe final
message_delta.usage.output_tokens(not the sum of deltas).cached_input_tokensand add intoinput_tokensper the rules in design doc 02.docs/tasks/10-wire-anthropic-messages.mddocs/design/