Skip to content

fix(accountant): Credit cachesplit, report the summarize splice, mark the manual ping estimate - #929

Draft
boazdavid wants to merge 4 commits into
integ/batch1from
fix/accountant-pricing2
Draft

boazdavid wants to merge 4 commits into
integ/batch1from
fix/accountant-pricing2

Conversation

@boazdavid

Copy link
Copy Markdown
Collaborator

Summary

What changed

Issue Problem Cause Fix Before / after (fake upstream)
#909 cachesplit_saved_usd 0, split_credited 0 on the live path In the library, not the proxy path. On a short conversation the stable half the provider reads is within the read tolerance (128 tokens + 2%) of the whole previous entry. The B* rule took the read as proof that nothing broke and moved B* past the changed system block. The split effect was dropped. The proxy sent the right operation and facts. accountant fix/split-short-turn: the rule skips a delivered split on a changed system block. Pin bumped. Proxy test with a short conversation added. 0 and 0 -> 0.04433 and 3 (truth 3 x 4325 x 3.45/1M = 0.04477). Per-request column and /api/stats now agree.
#910 ops_dropped on 6 of 10 requests, net -0.00274 The splice was reported. The rebuild after the count change matched a kept message to the first unused slot with the same bytes. A user message with a tool_result and the text "CALL_TOOL again" has the same bytes every turn. A kept message took the slot of a removed turn. The forwarded body held that turn's orphan tool_result, so sizes failed wireSizes and all ops were dropped. rebuildCountChanged prefers a slot of a wire message that a kept tool message already names by tool_call_id. net -0.00274 -> +0.00404, fallbacks 6 -> 0. Truth from the fake's log (control 0.0721437 - treatment 0.0681045) = +0.00404.
#913 Fear: next request after a manual ping is cold Not reproduced. The pinned library takes a billed read that covers the previous extent as proof of life (R45), so no LastPing is needed. No phase change. Test pins hot at 100,000 tokens, with an automatic ping as control. The manual run books no rescue. The manual figure is now labelled "estimate" in the Overview and docs. Phase hot for both. No figure changes.

Side effect of the #910 fix: before it, the forwarded body for such transcripts held an orphan tool_result. It is now correct. This is a behavior change for summarize on transcripts with repeated sibling text.

Skipped: storing facts for a manual ping with the rescue disabled, and a KeepAliveManual row flag. #913 shows no wrong phase, so it would add state and a column for no change. A human can decide if they still want it.

Data dependence: no stored field is added. docs/dashboard.md says the manual figure is an estimate.

How it was tested

  • Harness /tmp/review-893/features, before and after, against the fake upstream's own cost log.
  • New tests: TestSavings_ASplitBooksItsEffectOnAShortConversationWhenTheTailMoves (fails on the old pin), TestSpliceKeepsSurvivorsWithIdenticalSiblingText (fails before the fix), TestTheRequestAfterAManualPingIsHotNotCold. In accountant: case split/short-conversation/tail-changed.
  • go test -count=1 ./proxy ./dash: ok. ./apply/... ./keepalive/... ./components/...: ok. gofmt -l, go vet ./..., go build ./..., go mod tidy -diff: clean.

Assisted-By: Claude (Anthropic AI) noreply@anthropic.com

The new library adds a per-breakpoint TTL phase, media pricing and
validation bounds. The suite for dash, proxy, apply, keepalive and
components passes unchanged, so no figure changes.

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: DAVID BOAZ <DAVIDBO@il.ibm.com>
…#909)

The live path booked no split credit. The cause was in the library, not
in the proxy path. On a short conversation the stable half the provider
reads is within the library's read tolerance (128 tokens plus 2%) of the
whole previous entry. The library took that read as proof that nothing
broke, moved B* past the changed system block and dropped the split
effect. The proxy sent the right facts and the right split operation.

The fix is accountant fix/split-short-turn (23e2ed1). This commit pins
that version and adds a proxy test with a short conversation, which fails
on the old pin and passes on the new one.

Before (fake upstream, 4 requests, tail moves each turn): cachesplit_saved_usd 0,
split_credited 0. After: 0.04433, split_credited 3. Truth: 3 x 4325 x
(3.75 - 0.30) / 1M = 0.04477.

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: DAVID BOAZ <DAVIDBO@il.ibm.com>
#910)

Summarize hit ops_dropped on most requests, so it booked its model cost
and no saving. The splice itself was reported. The rebuild after a
count change broke the sizes. It matched a kept message to the first
unused slot with the same bytes. A user message that holds a tool_result
and a text block (for example "continue") has the same bytes on every
turn. A kept message took the slot of a removed turn, so the forwarded
body held that turn's orphan tool_result and not the kept message. The
byte sizes then failed wireSizes and the library dropped all operations.

A byte match now prefers a slot of a wire message that a kept tool
message already names by its tool_call_id.

Before (fake upstream, 10 requests): net_saved_usd -0.00274, 6 requests
ops_dropped. After: +0.00404, 0 fallbacks. Truth from the fake's own log
(control 0.0721437 minus treatment 0.0681045): +0.00404.

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: DAVID BOAZ <DAVIDBO@il.ibm.com>
…the manual figure an estimate (#913)

The issue feared that a manual ping, which stores no facts, would leave
the next request cold. The scenario was run with the pinned library:
request at t0 writes 100,000 tokens, manual ping at t0+4m reads them,
request at t0+8m reads them again. The gap is 8 minutes, past the 5
minute TTL. The phase is hot, not cold. The library takes a billed read
that covers the previous extent as proof that the entry was alive, so it
needs no LastPing. The same request after an automatic ping is hot too
and books a rescue. The manual run books none, so the write is not
counted twice.

No code change was needed for the phase. The test pins it. Storing the
facts with the rescue disabled, as the issue suggested, would add state
and a row flag for no change in any figure, so it is not done.

ManualSavedUSD is the user's estimate of the avoided write. The
Overview now labels the line 'estimate' and the Cache info text and
docs/dashboard.md say it is not a measurement.

Assisted-By: Claude (Anthropic AI) <noreply@anthropic.com>
Signed-off-by: DAVID BOAZ <DAVIDBO@il.ibm.com>

This branch has not been deployed

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

Labels

None yet

Projects

Status: New/ToDo

Development

Successfully merging this pull request may close these issues.

1 participant