trace: Claude Code's `<synthetic>` notices count as requests and can make a Claude session price on the fallback curve
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 20/100
Direzione di ricerca
Read tokeneconomizer/trace/claude.py around claude_session_usage and the linked accounting code in tokeneconomizer/plugin/accounting.py. The issue includes a reproduction and expected output; compare how synthetic assistant entries affect request counting and model selection. Done means the reproduction reports one request, the real Claude model, and model pricing. A linked pull request is already open.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
When a request fails, or there is nothing to answer, Claude Code writes its own notice into the session log as an assistant entry. The entry has "model": "<synthetic>", its own message id, and a usage object of zeros. For example:
{"type": "assistant", "isApiErrorMessage": true, "message": {"id": "046e4526-...", "model": "<synthetic>", "role": "assistant", "usage": {"input_tokens": 0, "output_tokens": 0, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, ...}, "content": [{"type": "text", "text": "API Error: Can't reach the API server ..."}]}}
I see these in my own logs for "API Error: ..." and "No response requested.".
claude_session_usage (trace/claude.py#L298-L315) counts each of these entries as a request and as a vote for <synthetic> as the session's model. So:
requestsis too high by one for every notice. This number is in the ledger and inte status.- If the notices outnumber the real replies,
modelbecomes<synthetic>.pricing.weights_forhas no entry for it, soaccounting.effectiveprices a plain Claude session on the fallback curve and recordspriced_by: "fallback". The accounting docstring says Claude ids never need the fallback. The fallback weighs output at 6x, where Claude's curve uses 5x.
The token totals are right, because the notices carry zeros.
Repro (on main at 264e7a7): one real reply, then two notices.
import json, os, tempfile
from tokeneconomizer import trace
from tokeneconomizer.plugin import accounting
def asst(mid, model, usage):
return json.dumps({"type": "assistant", "message": {"id": mid, "model": model,
"role": "assistant", "content": [{"type": "text", "text": "x"}], "usage": usage}})
zero = dict.fromkeys(("input_tokens", "output_tokens", "cache_creation_input_tokens",
"cache_read_input_tokens"), 0)
real = {"input_tokens": 10, "output_tokens": 200, "cache_creation_input_tokens": 1000,
"cache_read_input_tokens": 5000}
p = os.path.join(tempfile.mkdtemp(), "s.jsonl")
open(p, "w").write("\n".join([asst("msg_1", "claude-sonnet-4-5", real),
asst("u-1", "<synthetic>", zero),
asst("u-2", "<synthetic>", zero)]) + "\n")
u = trace.claude_session_usage(p)
print(u["requests"], u["model"], accounting.effective(u))
Expected: 1 claude-sonnet-4-5 (2760.0, 'model')
Actual: 3 <synthetic> (2960.0, 'fallback')
I have a fix with a regression test and will open a PR.
- Lingua principale
- Python
- Stelle
- 5.6k
- Fork
- 344
- Merge medio
- 14h 41m
- PR unite (30g)
- 54
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di microsoft/TokenEconomizer
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
microsoft/TokenEconomizer#193 ·
I maintainer di solito rispondono entro 1 giorno
-
pricing: Claude's 1-hour cache writes are priced at 1.25x, but billed at 2xForse già presa @anascherif l’ha presa oggi. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 25/100
microsoft/TokenEconomizer#191 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 5/5 Più di una settimana Idoneità per principianti 20/100
microsoft/TokenEconomizer#186 ·
I maintainer di solito rispondono entro 1 giorno
-
plugin: the agent-output readers crash on a JSON line that is not an objectForse già presa @rahul05ranjan l’ha presa 1 giorno fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 25/100
microsoft/TokenEconomizer#182 ·
I maintainer di solito rispondono entro 1 giorno
-
trace: the cursor readers crash on a JSON line that is not an objectForse già presa @rahul05ranjan l’ha presa 1 giorno fa. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 25/100
microsoft/TokenEconomizer#180 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di microsoft/TokenEconomizer
Issue simili
-
area: providers/aws priority: p2 size: S type: bug type: testing
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
finos/open-resource-broker#851 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 1-3 ore Idoneità per principianti 88/100
sandialabs/atlas-ui-3#1196 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement triage
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
ShaftHQ/SHAFT_ENGINE#7902 ·
I maintainer di solito rispondono entro 1 giorno
-
[Bug]: GraphML export writes invalid XML when a value contains a control character (e.g. form feed)Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
topoteretes/cognee#6646 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 75/100
DOI-USGS/pywatershed#428 ·