@trazum/core 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * This is NOT a real tokenizer: it is a heuristic calibrated per character
5
5
  * class. It is built to keep the typical error on ordinary text
6
- * (English/Spanish, markdown, code) inside ±15%, which is plenty for comparing
6
+ * (English/Spanish, markdown, code) inside ±10%, which is plenty for comparing
7
7
  * two versions of the same prompt — but do NOT bill anyone from it.
8
8
  *
9
9
  * **That band is a design target that has not been measured.** It is printed on
@@ -23,36 +23,43 @@
23
23
  /**
24
24
  * The error band this estimator is published under, as a percentage.
25
25
  *
26
- * **Measured, not chosen.** It was `15` for eight releases — a design target
27
- * nobody had checked — and the first run of `scripts/measure-token-band.mjs`
28
- * against the official counting endpoint found two of eight samples outside it,
29
- * both underestimating. Underestimating tokens means under-reporting cost, which
30
- * is the flattering direction and the worst one for this tool.
26
+ * **Measured, not chosen, and it has moved three times.** It was `15` for eight
27
+ * releases as a design target nobody had checked; the first measurement found two
28
+ * of eight samples outside it and it went to `25`; fixing the digit divisor and
29
+ * calibrating per language brought it back to `15`. This is the fourth value and
30
+ * the first one that is comfortably above what the corpus actually shows.
31
31
  *
32
- * `15` is the measured worst case rounded up, by the same rule that briefly made
33
- * it 25: the corpus now tops out at 11.2%, on Japanese. It landing back on the
34
- * number that was a guess for eight releases is a coincidence and not a
35
- * restoration — that 15 bounded nothing, and this one bounds eleven measured
36
- * samples across four languages and six text types.
32
+ * ```
33
+ * worst measured error 6.4% (code-heavy, which nothing is fitted to)
34
+ * published band 10%
35
+ * ```
37
36
  *
38
- * **Read one caveat before trusting it.** Four of those samples are the Latin
39
- * languages whose divisors in `DIVISOR_BY_LANGUAGE` were calibrated on one or two
40
- * samples each, so their residuals are in-sample and optimistic by construction.
41
- * The band is set by the seven samples nothing was fitted to — worst 11.2% — and
42
- * the honest test of it is the next held-out sample in Spanish, French or German.
43
- * The corpus grows one sample at a time now, so that test is cheap to run.
37
+ * **The margin is deliberate and it is not slack.** 6.4 rounded up is 7, and
38
+ * publishing 7 would be a tighter claim than twenty-one samples across six text
39
+ * types can support: the corpus has no Korean, no Arabic, no Cyrillic prose, no
40
+ * mixed-script document, and a seventh text type could easily land at eight. A
41
+ * band that becomes false the first time somebody measures something new is the
42
+ * exact fault this whole exercise was fixing. Overstating the uncertainty is the
43
+ * safe direction for a tool that reports money.
44
44
  *
45
- * **What got it there was not accents.** A Spanish sample with zero accented
46
- * characters measured -22.9% against -22.1% for accented Spanish, which killed
47
- * diacritics as a signal. Languages differ in how many tokens their words cost
48
- * English 3.44 characters per token, German 2.02 so the estimator detects the
49
- * language and divides accordingly. See `language.ts`.
45
+ * What earned the drop from 15 was **splitting kana from han**. Every CJK
46
+ * character was charged one token, which put Japanese at +11.2% the worst error
47
+ * anywhere in the corpus while Chinese sat at −3.2% under the same rule. Kana
48
+ * measure 0.75 tokens per character and han 1.05, and that pair takes the two
49
+ * samples to −1.5% and +1.3%. See `KANA_TOKENS_PER_CHAR`.
50
50
  *
51
- * Exported so every report, README and tool description reads the same number.
52
- * It was a literal in twenty-four files before this, with the only machine-
53
- * readable copy in a test.
51
+ * **Which samples the band rests on matters more than the number.** Eight of the
52
+ * twenty-one had a constant fitted to them seven Latin divisors and the digit
53
+ * divisor so their residuals are optimistic by construction. The two worst
54
+ * errors in the corpus, `code-heavy` at 6.4% and `punctuation-heavy` at 5.7%, are
55
+ * fitted to nothing at all, and they are what sets this figure.
56
+ *
57
+ * Exported so every report, README and tool description reads the same number. It
58
+ * was a literal in twenty-four files before this, with the only machine-readable
59
+ * copy in a test, and `token-band.test.js` now fails any file that states a
60
+ * different one.
54
61
  */
55
- export declare const ESTIMATE_ERROR_BAND_PCT = 15;
62
+ export declare const ESTIMATE_ERROR_BAND_PCT = 10;
56
63
  /**
57
64
  * Estimates how many tokens `text` occupies.
58
65
  *
@@ -1 +1 @@
1
- {"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../src/tokenizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAwD1C;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA0GnD;AAED,sDAAsD;AACtD,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAElE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,gFAAgF;IAChF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,iBAAiB,CA6BxF"}
1
+ {"version":3,"file":"tokenizer.d.ts","sourceRoot":"","sources":["../src/tokenizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAmG1C;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAuHnD;AAED,sDAAsD;AACtD,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAElE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,gFAAgF;IAChF,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,uBAAuB,GAAG,iBAAiB,CA6BxF"}
package/dist/tokenizer.js CHANGED
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * This is NOT a real tokenizer: it is a heuristic calibrated per character
5
5
  * class. It is built to keep the typical error on ordinary text
6
- * (English/Spanish, markdown, code) inside ±15%, which is plenty for comparing
6
+ * (English/Spanish, markdown, code) inside ±10%, which is plenty for comparing
7
7
  * two versions of the same prompt — but do NOT bill anyone from it.
8
8
  *
9
9
  * **That band is a design target that has not been measured.** It is printed on
@@ -25,37 +25,65 @@ import { SAFE_FETCH_INIT, checkedEndpoint } from './net.js';
25
25
  /**
26
26
  * The error band this estimator is published under, as a percentage.
27
27
  *
28
- * **Measured, not chosen.** It was `15` for eight releases — a design target
29
- * nobody had checked — and the first run of `scripts/measure-token-band.mjs`
30
- * against the official counting endpoint found two of eight samples outside it,
31
- * both underestimating. Underestimating tokens means under-reporting cost, which
32
- * is the flattering direction and the worst one for this tool.
33
- *
34
- * `15` is the measured worst case rounded up, by the same rule that briefly made
35
- * it 25: the corpus now tops out at 11.2%, on Japanese. It landing back on the
36
- * number that was a guess for eight releases is a coincidence and not a
37
- * restoration — that 15 bounded nothing, and this one bounds eleven measured
38
- * samples across four languages and six text types.
39
- *
40
- * **Read one caveat before trusting it.** Four of those samples are the Latin
41
- * languages whose divisors in `DIVISOR_BY_LANGUAGE` were calibrated on one or two
42
- * samples each, so their residuals are in-sample and optimistic by construction.
43
- * The band is set by the seven samples nothing was fitted to worst 11.2% — and
44
- * the honest test of it is the next held-out sample in Spanish, French or German.
45
- * The corpus grows one sample at a time now, so that test is cheap to run.
46
- *
47
- * **What got it there was not accents.** A Spanish sample with zero accented
48
- * characters measured -22.9% against -22.1% for accented Spanish, which killed
49
- * diacritics as a signal. Languages differ in how many tokens their words cost
50
- * English 3.44 characters per token, German 2.02 so the estimator detects the
51
- * language and divides accordingly. See `language.ts`.
52
- *
53
- * Exported so every report, README and tool description reads the same number.
54
- * It was a literal in twenty-four files before this, with the only machine-
55
- * readable copy in a test.
28
+ * **Measured, not chosen, and it has moved three times.** It was `15` for eight
29
+ * releases as a design target nobody had checked; the first measurement found two
30
+ * of eight samples outside it and it went to `25`; fixing the digit divisor and
31
+ * calibrating per language brought it back to `15`. This is the fourth value and
32
+ * the first one that is comfortably above what the corpus actually shows.
33
+ *
34
+ * ```
35
+ * worst measured error 6.4% (code-heavy, which nothing is fitted to)
36
+ * published band 10%
37
+ * ```
38
+ *
39
+ * **The margin is deliberate and it is not slack.** 6.4 rounded up is 7, and
40
+ * publishing 7 would be a tighter claim than twenty-one samples across six text
41
+ * types can support: the corpus has no Korean, no Arabic, no Cyrillic prose, no
42
+ * mixed-script document, and a seventh text type could easily land at eight. A
43
+ * band that becomes false the first time somebody measures something new is the
44
+ * exact fault this whole exercise was fixing. Overstating the uncertainty is the
45
+ * safe direction for a tool that reports money.
46
+ *
47
+ * What earned the drop from 15 was **splitting kana from han**. Every CJK
48
+ * character was charged one token, which put Japanese at +11.2% the worst error
49
+ * anywhere in the corpus while Chinese sat at −3.2% under the same rule. Kana
50
+ * measure 0.75 tokens per character and han 1.05, and that pair takes the two
51
+ * samples to −1.5% and +1.3%. See `KANA_TOKENS_PER_CHAR`.
52
+ *
53
+ * **Which samples the band rests on matters more than the number.** Eight of the
54
+ * twenty-one had a constant fitted to them seven Latin divisors and the digit
55
+ * divisor so their residuals are optimistic by construction. The two worst
56
+ * errors in the corpus, `code-heavy` at 6.4% and `punctuation-heavy` at 5.7%, are
57
+ * fitted to nothing at all, and they are what sets this figure.
58
+ *
59
+ * Exported so every report, README and tool description reads the same number. It
60
+ * was a literal in twenty-four files before this, with the only machine-readable
61
+ * copy in a test, and `token-band.test.js` now fails any file that states a
62
+ * different one.
56
63
  */
57
- export const ESTIMATE_ERROR_BAND_PCT = 15;
64
+ export const ESTIMATE_ERROR_BAND_PCT = 10;
58
65
  const CJK = /[぀-ヿ㐀-䶿一-鿿가-힯]/;
66
+ /**
67
+ * Kana, separated from the rest of CJK because they do not cost the same.
68
+ *
69
+ * **This was the largest error left in the corpus.** Every CJK character was
70
+ * charged one token, and measured against the counting endpoint that put Japanese
71
+ * at **+11.2%** — the worst figure anywhere in twenty-one samples — while Chinese
72
+ * came out at −3.2% under the identical rule. One constant cannot be right for
73
+ * both, and the reason is visible in the samples: the Japanese one is 58% kana and
74
+ * the Chinese one is 0%.
75
+ *
76
+ * Kana are a small syllabary that appears in every sentence, so the merge table
77
+ * covers runs of them and several characters share a token. Han are tens of
78
+ * thousands of rare characters; a merge table cannot cover them and they cost
79
+ * about one each, sometimes more.
80
+ *
81
+ * The signal needs no detector. A character is kana or it is not, and the two
82
+ * samples separate perfectly — 58.3% against 0.00% — so this is a property of the
83
+ * character rather than a guess about the document. That is the difference between
84
+ * this and `language.ts`, which has to decide and is allowed to refuse.
85
+ */
86
+ const KANA = /[぀-ヿ]/;
59
87
  const LETTER = /[A-Za-zÀ-ɏͰ-ϿЀ-ӿ]/;
60
88
  const DIGIT = /[0-9]/;
61
89
  /**
@@ -90,6 +118,26 @@ const DIVISOR_BY_LANGUAGE = {
90
118
  pt: 3.05,
91
119
  nl: 2.65,
92
120
  };
121
+ /**
122
+ * Tokens per character for the two halves of CJK, measured.
123
+ *
124
+ * `0.75` and `1.05` come from a search over the two CJK samples in
125
+ * `test/fixtures/token-ground-truth.json`, and they take that pair from
126
+ * +11.2% / −3.2% to −1.5% / +1.3%.
127
+ *
128
+ * **Two samples fitted two constants, so those residuals are in-sample and
129
+ * optimistic by construction** — the same caveat the Latin divisors carry, stated
130
+ * for the same reason. What makes them worth having anyway is the size of the
131
+ * error they replace and the fact that they move in opposite directions: a single
132
+ * constant could not have been within four points of both, whatever it was set to.
133
+ * The honest test is a third CJK sample, and the corpus grows one at a time.
134
+ *
135
+ * Hangul keeps the old cost of 1, because nothing here measures Korean. Guessing
136
+ * it from Japanese would be inventing a figure — the two scripts have nothing in
137
+ * common that would make one predict the other.
138
+ */
139
+ const KANA_TOKENS_PER_CHAR = 0.75;
140
+ const HAN_TOKENS_PER_CHAR = 1.05;
93
141
  /**
94
142
  * What a prompt gets when the language could not be told.
95
143
  *
@@ -126,6 +174,11 @@ export function estimateTokens(text) {
126
174
  const language = detectTextLanguage(text);
127
175
  const divisor = (language === null ? undefined : DIVISOR_BY_LANGUAGE[language]) ?? DEFAULT_DIVISOR;
128
176
  let total = 0;
177
+ /**
178
+ * CJK is summed separately because it is the one class counted in fractions of
179
+ * a token. Everything else is whole tokens by the character class it belongs to.
180
+ */
181
+ let cjkTokens = 0;
129
182
  let i = 0;
130
183
  const chars = Array.from(text);
131
184
  while (i < chars.length) {
@@ -144,12 +197,19 @@ export function estimateTokens(text) {
144
197
  continue;
145
198
  }
146
199
  if (CJK.test(ch)) {
147
- let n = 0;
200
+ /**
201
+ * Accumulated as a fraction and rounded once, at the end.
202
+ *
203
+ * Rounding up per run was the first attempt and it was wrong by five
204
+ * points. Ordinary Japanese alternates kana and han inside every sentence,
205
+ * so the runs are short and there are many of them — and a `Math.ceil` per
206
+ * run charges most of a token for each boundary. That is an artefact of
207
+ * where the loop happens to break, not of what the text costs.
208
+ */
148
209
  while (i < chars.length && CJK.test(chars[i])) {
149
- n++;
210
+ cjkTokens += KANA.test(chars[i]) ? KANA_TOKENS_PER_CHAR : HAN_TOKENS_PER_CHAR;
150
211
  i++;
151
212
  }
152
- total += n;
153
213
  continue;
154
214
  }
155
215
  if (LETTER.test(ch)) {
@@ -212,7 +272,8 @@ export function estimateTokens(text) {
212
272
  total += Math.ceil(n / 2);
213
273
  }
214
274
  }
215
- return total;
275
+ // Rounded once, over the whole document, rather than per run — see the CJK branch.
276
+ return total + Math.ceil(cjkTokens);
216
277
  }
217
278
  /**
218
279
  * Exact counter using the official `/v1/messages/count_tokens` endpoint.
@@ -1 +1 @@
1
- {"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../src/tokenizer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../src/tokenizer.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -39,7 +39,7 @@ export interface RuleResult {
39
39
  /** Severity of an advisory: the higher it is, the more money is usually at stake. */
40
40
  export type AdvisorySeverity = 'info' | 'opportunity' | 'warning';
41
41
  /** Every advisory the core can emit. */
42
- export type AdvisoryId = 'context-overflow' | 'prompt-caching' | 'prompt-caching-not-worth-it' | 'below-cache-minimum' | 'cache-prefix-reorder' | 'batch-api' | 'model-downgrade' | 'output-dominated' | 'promo-pricing' | 'contradictory-instructions' | 'redundant-examples' | 'restated-output-format' | 'movable-output-schema';
42
+ export type AdvisoryId = 'context-overflow' | 'context-near-limit' | 'prompt-caching' | 'prompt-caching-not-worth-it' | 'below-cache-minimum' | 'cache-prefix-reorder' | 'batch-api' | 'model-downgrade' | 'output-dominated' | 'promo-pricing' | 'contradictory-instructions' | 'redundant-examples' | 'restated-output-format' | 'movable-output-schema';
43
43
  /** A recommendation that does NOT modify the prompt, only informs. */
44
44
  export interface Advisory {
45
45
  id: AdvisoryId;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,219 @@
1
+ import type { PricingCatalogue } from './pricing.js';
2
+ /**
3
+ * Where the money actually went, from calls that actually happened.
4
+ *
5
+ * ## Why this exists
6
+ *
7
+ * Everything else in this package reads a **prompt file** and reasons about what
8
+ * it would cost. That is the smallest line item on most bills, and the gap is not
9
+ * small enough to argue about: measured on an ordinary support prompt, the
10
+ * deterministic rules recover about **1%** of the monthly figure, while output
11
+ * tokens alone were **87%** of it. A tool that reads `prompts/*.txt` cannot see
12
+ * retrieved context, conversation history, tool results or answers, and on a RAG
13
+ * or agent workload those are nearly the whole invoice.
14
+ *
15
+ * So this reads the other direction: **what the provider actually charged**, per
16
+ * call, and says where it went. The sentence it is built to produce is "63% of
17
+ * your bill is retrieved context and nothing is watching it", which is a fact
18
+ * about a system rather than an estimate about a file.
19
+ *
20
+ * ## It reads a file, and that is the design
21
+ *
22
+ * Not a proxy, not an SDK wrapper, not a callback. Trazum's whole security
23
+ * position is that prompts do not leave the machine they are on — asserted by
24
+ * tests, not promised — and a tool that sits in the request path trades that away
25
+ * for convenience. A JSON Lines file is something you already have or can produce
26
+ * in three lines, and it keeps the guarantee intact.
27
+ *
28
+ * ## The format is the one the API already gives you
29
+ *
30
+ * Nothing is invented here. Every Anthropic response carries a `usage` object
31
+ * with exactly these fields, so recording a call is:
32
+ *
33
+ * ```ts
34
+ * appendFileSync('usage.jsonl', JSON.stringify({
35
+ * model: response.model,
36
+ * ...response.usage,
37
+ * }) + '\n');
38
+ * ```
39
+ *
40
+ * OpenAI's `usage` maps onto the same shape with different names, and
41
+ * `parseUsageLine` accepts both. Asking somebody to transform their logs into a
42
+ * bespoke schema before a tool will read them is how a tool goes unused.
43
+ *
44
+ * ## What it refuses to do
45
+ *
46
+ * **It does not read prompt text and there is nowhere to put it.** The record
47
+ * shape has no field for content, so a usage log handed to Trazum cannot contain
48
+ * a prompt even by accident. That is a stronger promise than "we do not look at
49
+ * it", and it is the reason this takes counts rather than calls.
50
+ *
51
+ * **It reports no saving.** Attributing "you could have saved X" to a call that
52
+ * already happened means guessing what the call should have been, and this module
53
+ * exists precisely because guessing is what the rest of the package has to do.
54
+ * It reports what was spent, split by where it went. What to do about it is a
55
+ * different question and belongs to the advisories.
56
+ */
57
+ /** One recorded call, after parsing. All counts, no content. */
58
+ export interface UsageRecord {
59
+ /** Model id as the provider reported it. */
60
+ model: string;
61
+ /** Uncached input tokens billed at the full rate. */
62
+ inputTokens: number;
63
+ /** Tokens billed at the cache-read rate. Zero when nothing was cached. */
64
+ cacheReadTokens: number;
65
+ /** Cache writes at the 5-minute rate — 1.25x input on Anthropic. */
66
+ cacheWrite5mTokens: number;
67
+ /** Cache writes at the 1-hour rate, which is **2x** input, not 1.25x. */
68
+ cacheWrite1hTokens: number;
69
+ /**
70
+ * Whether the log said which TTL those writes used.
71
+ *
72
+ * `false` when only the flat `cache_creation_input_tokens` was present and it
73
+ * was non-zero: the writes are then priced at the cheaper 5-minute rate because
74
+ * one of the two has to be assumed, and the report says so. Choosing the cheaper
75
+ * rate silently understates a 1-hour workload by 37.5% on its largest line.
76
+ */
77
+ writeTtlKnown: boolean;
78
+ outputTokens: number;
79
+ /**
80
+ * Optional label for grouping — an endpoint, a feature, a prompt name.
81
+ *
82
+ * The whole value of a profile is answering "which part of the product costs
83
+ * this", and without a label every call looks alike. Unlabelled records are
84
+ * grouped under a single bucket rather than dropped, because a profile that
85
+ * refuses to read a log until it is annotated is a profile nobody runs.
86
+ */
87
+ label: string | null;
88
+ }
89
+ /** What a set of calls cost, split by where the money went. */
90
+ export interface UsageBreakdown {
91
+ calls: number;
92
+ inputTokens: number;
93
+ cacheReadTokens: number;
94
+ cacheWriteTokens: number;
95
+ outputTokens: number;
96
+ /**
97
+ * Calls whose cache-write TTL the log did not state, so the cheaper rate was
98
+ * assumed. Non-zero means this total is a floor on those calls, not a figure.
99
+ */
100
+ assumedWriteTtlCalls: number;
101
+ inputUsd: number;
102
+ cacheReadUsd: number;
103
+ cacheWriteUsd: number;
104
+ outputUsd: number;
105
+ totalUsd: number;
106
+ }
107
+ export interface UsageProfileReport {
108
+ /** Everything, combined. */
109
+ total: UsageBreakdown;
110
+ /** Per `label`, largest bill first — the order somebody would act in. */
111
+ byLabel: Array<{
112
+ label: string;
113
+ breakdown: UsageBreakdown;
114
+ }>;
115
+ /** Per model, largest bill first. */
116
+ byModel: Array<{
117
+ model: string;
118
+ breakdown: UsageBreakdown;
119
+ }>;
120
+ /**
121
+ * Models in the log that the pricing catalogue does not know.
122
+ *
123
+ * Named rather than silently costed at zero. A profile that quietly omits a
124
+ * model reports a total lower than the real bill, which is the flattering
125
+ * direction and the one this repository refuses.
126
+ */
127
+ unpricedModels: string[];
128
+ /**
129
+ * What those models used, kept entirely out of `total`.
130
+ *
131
+ * The first version added their **tokens** to the totals and their **dollars**
132
+ * to nothing, because pricing failed after the counts had been accumulated. So
133
+ * `total.inputTokens` included them and `total.inputUsd` did not, and anybody
134
+ * dividing one by the other got a cost per token that was wrong by however much
135
+ * of the log was unpriced — silently, and low.
136
+ *
137
+ * They are separated now. `total` is what could be priced, tokens and dollars
138
+ * describing the same calls. This is what could not, so the size of the gap is
139
+ * visible instead of being folded into a number that looks complete.
140
+ */
141
+ unpriced: UsageBreakdown;
142
+ /**
143
+ * Lines that could not be read, with their 1-based position.
144
+ *
145
+ * Reported rather than thrown on. A log with three malformed lines out of forty
146
+ * thousand should still produce a profile, and a parser that dies on the first
147
+ * one makes the tool unusable on real data — but a parser that skips quietly
148
+ * produces a total that is wrong by an unknown amount.
149
+ */
150
+ skippedLines: number[];
151
+ }
152
+ /** The share of the bill each part accounts for, as fractions of 1. */
153
+ export interface UsageShares {
154
+ input: number;
155
+ cacheRead: number;
156
+ cacheWrite: number;
157
+ output: number;
158
+ }
159
+ /**
160
+ * One line of a usage log, or `null` when it is not one.
161
+ *
162
+ * Accepts the Anthropic shape and the OpenAI one, because those are the two
163
+ * things people actually have. The alternative — a Trazum-specific schema — asks
164
+ * for a transformation step before the tool will read anything, and a tool with a
165
+ * setup cost that exceeds its payoff does not get run twice.
166
+ *
167
+ * `null` in three cases, and the third is the one that was wrong:
168
+ *
169
+ * 1. Not JSON, or not an object, or no `model`.
170
+ * 2. **No** token counts at all — counting it would inflate the call count while
171
+ * contributing nothing, which lowers every per-call figure.
172
+ * 3. **Any** count present but unreadable. A field that is there and unusable is
173
+ * corruption, and a corrupt line belongs in `skippedLines` where the report
174
+ * names it, not in the totals as a silent zero.
175
+ */
176
+ export declare function parseUsageLine(line: string): UsageRecord | null;
177
+ /** The bucket unlabelled calls land in, named so a report can say so. */
178
+ export declare const UNLABELLED = "unlabelled";
179
+ export interface UsageProfileOptions {
180
+ catalogue: PricingCatalogue;
181
+ /** Date the prices are read at, so a promotional rate resolves the same way. */
182
+ on?: Date;
183
+ }
184
+ /**
185
+ * Reads a usage log and says where the money went.
186
+ *
187
+ * Takes the whole text rather than a stream: a usage log is measured in megabytes
188
+ * and this package imports no Node builtins, so streaming would mean an interface
189
+ * the browser build cannot satisfy. `@trazum/core/node` is where file reading
190
+ * lives, and it can chunk if it ever needs to.
191
+ */
192
+ export declare function profileUsage(text: string, options: UsageProfileOptions): UsageProfileReport;
193
+ /**
194
+ * What share of the bill each part is.
195
+ *
196
+ * The point of the whole module in one function: a caller can print "output is
197
+ * 87% of this" without doing arithmetic that would drift from the arithmetic
198
+ * here.
199
+ *
200
+ * All zeroes when nothing was spent, rather than `NaN`. A profile of an empty log
201
+ * is a legitimate result — no calls yet — and a report full of `NaN%` is a bug
202
+ * report from somebody who did nothing wrong.
203
+ */
204
+ export declare function sharesOf(breakdown: UsageBreakdown): UsageShares;
205
+ /**
206
+ * How much of the input that could have been cached was.
207
+ *
208
+ * `null` when nothing was cacheable-looking at all — no reads and no writes —
209
+ * because a hit rate over zero attempts is not zero, it is undefined, and
210
+ * printing "0% cache hit rate" for somebody who never turned caching on is a
211
+ * finding about nothing.
212
+ *
213
+ * Reads against reads-plus-full-price-input, deliberately. Cache *writes* are
214
+ * excluded from the denominator: a write is the cost of establishing an entry,
215
+ * not a missed read, and counting it as a miss makes a healthy cache look broken
216
+ * on the day it warms.
217
+ */
218
+ export declare function cacheHitRate(breakdown: UsageBreakdown): number | null;
219
+ //# sourceMappingURL=usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage.d.ts","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,gEAAgE;AAChE,MAAM,WAAW,WAAW;IAC1B,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,eAAe,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;;;OAOG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,4BAA4B;IAC5B,KAAK,EAAE,cAAc,CAAC;IACtB,yEAAyE;IACzE,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;IAC7D,qCAAqC;IACrC,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,cAAc,CAAA;KAAE,CAAC,CAAC;IAC7D;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;;;;;;;;OAYG;IACH,QAAQ,EAAE,cAAc,CAAC;IACzB;;;;;;;OAOG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAoDD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAuF/D;AAED,yEAAyE;AACzE,eAAO,MAAM,UAAU,eAAe,CAAC;AAiDvC,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,gFAAgF;IAChF,EAAE,CAAC,EAAE,IAAI,CAAC;CACX;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,kBAAkB,CAyD3F;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,cAAc,GAAG,WAAW,CAS/D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAKrE"}