Claude calls on Anthropic's own Messages API with prompt caching; the ledger prices cached tokens #119

Closed
opened 2026-10-18 04:38:48 +00:00 by teahubxyz · 3 comments
Owner

Today's ledger shows where the money goes: #95's failed run was 43 steps, each re-sending the whole conversation (up to 58k tokens) at full input price, $2.80 for nothing. The engine talks to Claude through Anthropic's OpenAI-compatible endpoint, which has no prompt caching (their docs say so outright); the native Messages API does.

  • anthropic_messages() posts to /v1/messages, speaking the engine's OpenAI shape on both sides: to_messages() turns system/user/assistant/tool messages and the tool list into the native request, with two cache breakpoints (tools + system prompt; the conversation so far), so each step pays for the previous step's context at a tenth of the price. An assistant turn that issued tool calls goes back exactly as the API gave it (thinking blocks included, which the API requires); the tool results of one turn travel in one user message. from_messages() turns the reply back into choices[0].message with tool_calls, and keeps the cache split in usage.
  • book() prices cache reads at 0.1x and cache writes at 1.25x the input price and writes cached / written on the ledger line; in still counts every prompt token, so old lines and new ones read alike.
  • TIME_ANTHROPIC_API=compat goes back to the old endpoint (the kill switch if the native path misbehaves live); the doctor lists it.

Tests: the fake Anthropic endpoint in test_time.py now speaks the Messages API and checks the headers and the request shape; the cached-token pricing, the compat switch and the translation (tools, tool calls, merged tool results, verbatim turns, the two breakpoints) are covered. Suite: ALL OK locally; CI runs the same.

PR: #120

DONE: PR open; python3 .github/time/test_time.py passes; CI green; the first worker run after the merge books ledger lines with cached > 0.

Today's ledger shows where the money goes: #95's failed run was 43 steps, each re-sending the whole conversation (up to 58k tokens) at full input price, $2.80 for nothing. The engine talks to Claude through Anthropic's OpenAI-compatible endpoint, which has no prompt caching (their docs say so outright); the native Messages API does. - `anthropic_messages()` posts to `/v1/messages`, speaking the engine's OpenAI shape on both sides: `to_messages()` turns system/user/assistant/tool messages and the tool list into the native request, with two cache breakpoints (tools + system prompt; the conversation so far), so each step pays for the previous step's context at a tenth of the price. An assistant turn that issued tool calls goes back exactly as the API gave it (thinking blocks included, which the API requires); the tool results of one turn travel in one user message. `from_messages()` turns the reply back into `choices[0].message` with `tool_calls`, and keeps the cache split in `usage`. - `book()` prices cache reads at 0.1x and cache writes at 1.25x the input price and writes `cached` / `written` on the ledger line; `in` still counts every prompt token, so old lines and new ones read alike. - `TIME_ANTHROPIC_API=compat` goes back to the old endpoint (the kill switch if the native path misbehaves live); the doctor lists it. Tests: the fake Anthropic endpoint in `test_time.py` now speaks the Messages API and checks the headers and the request shape; the cached-token pricing, the compat switch and the translation (tools, tool calls, merged tool results, verbatim turns, the two breakpoints) are covered. Suite: ALL OK locally; CI runs the same. PR: #120 DONE: PR open; `python3 .github/time/test_time.py` passes; CI green; the first worker run after the merge books ledger lines with `cached` > 0.
teahubxyz added the planned label 2026-10-18 04:38:48 +00:00
teahubxyz added ready and removed planned labels 2026-10-18 04:40:53 +00:00

⏱️ Time: adopted PR #120, built outside the worker. haiku reviewed it on the PR.

⏱️ Time: adopted PR #120, built outside the worker. `haiku` reviewed it on the PR. <!-- time {"beat":"pr","pr":120,"adopted":true,"launched":false,"review":"venice","seat":"haiku","as":"seat"} -->

⏱️ Time: approved, but checks are failing on PR #120. Waiting for a fix.

⏱️ Time: approved, but checks are failing on PR #120. Waiting for a fix. <!-- time {"beat":"checks-failed","pr":120} -->
time closed this issue 2026-10-18 04:59:21 +00:00

⏱️ Time: approved and green, merged PR #120. Card done.

⏱️ Time: approved and green, merged PR #120. Card done. <!-- time {"beat":"merged","pr":120} -->
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: teahubxyz/time#119