@trazum/core 1.10.0 → 1.25.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.
- package/dist/against.d.ts +32 -0
- package/dist/against.d.ts.map +1 -0
- package/dist/against.js +34 -0
- package/dist/against.js.map +1 -0
- package/dist/config-schema.d.ts +42 -1
- package/dist/config-schema.d.ts.map +1 -1
- package/dist/config-schema.js +61 -0
- package/dist/config-schema.js.map +1 -1
- package/dist/conversation.d.ts +121 -0
- package/dist/conversation.d.ts.map +1 -0
- package/dist/conversation.js +157 -0
- package/dist/conversation.js.map +1 -0
- package/dist/csv.d.ts +61 -0
- package/dist/csv.d.ts.map +1 -0
- package/dist/csv.js +149 -0
- package/dist/csv.js.map +1 -0
- package/dist/evaluate.d.ts +24 -0
- package/dist/evaluate.d.ts.map +1 -1
- package/dist/evaluate.js +5 -2
- package/dist/evaluate.js.map +1 -1
- package/dist/index.d.ts +25 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -1
- package/dist/index.js.map +1 -1
- package/dist/input-shape.d.ts +104 -0
- package/dist/input-shape.d.ts.map +1 -0
- package/dist/input-shape.js +132 -0
- package/dist/input-shape.js.map +1 -0
- package/dist/levers.d.ts +151 -0
- package/dist/levers.d.ts.map +1 -0
- package/dist/levers.js +160 -0
- package/dist/levers.js.map +1 -0
- package/dist/node.d.ts +1 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/output-shape.d.ts +96 -0
- package/dist/output-shape.d.ts.map +1 -0
- package/dist/output-shape.js +145 -0
- package/dist/output-shape.js.map +1 -0
- package/dist/pricing-overlay.d.ts +1 -1
- package/dist/pricing-overlay.d.ts.map +1 -1
- package/dist/pricing-overlay.js +46 -0
- package/dist/pricing-overlay.js.map +1 -1
- package/dist/repeats.d.ts +75 -0
- package/dist/repeats.d.ts.map +1 -0
- package/dist/repeats.js +82 -0
- package/dist/repeats.js.map +1 -0
- package/dist/reprice.d.ts +143 -0
- package/dist/reprice.d.ts.map +1 -0
- package/dist/reprice.js +82 -0
- package/dist/reprice.js.map +1 -0
- package/dist/session-cost.d.ts +70 -0
- package/dist/session-cost.d.ts.map +1 -0
- package/dist/session-cost.js +90 -0
- package/dist/session-cost.js.map +1 -0
- package/dist/session-ledger.d.ts +77 -0
- package/dist/session-ledger.d.ts.map +1 -0
- package/dist/session-ledger.js +99 -0
- package/dist/session-ledger.js.map +1 -0
- package/dist/ttl-fit.d.ts +103 -0
- package/dist/ttl-fit.d.ts.map +1 -0
- package/dist/ttl-fit.js +184 -0
- package/dist/ttl-fit.js.map +1 -0
- package/dist/usage.d.ts +434 -16
- package/dist/usage.d.ts.map +1 -1
- package/dist/usage.js +383 -23
- package/dist/usage.js.map +1 -1
- package/package.json +1 -1
- package/src/against.ts +48 -0
- package/src/config-schema.ts +106 -0
- package/src/conversation.ts +305 -0
- package/src/csv.ts +184 -0
- package/src/evaluate.ts +33 -3
- package/src/index.ts +51 -1
- package/src/input-shape.ts +259 -0
- package/src/levers.ts +331 -0
- package/src/node.ts +1 -1
- package/src/output-shape.ts +254 -0
- package/src/pricing-overlay.ts +52 -1
- package/src/repeats.ts +166 -0
- package/src/reprice.ts +227 -0
- package/src/session-cost.ts +170 -0
- package/src/session-ledger.ts +189 -0
- package/src/ttl-fit.ts +251 -0
- package/src/usage.ts +795 -7
package/dist/usage.js
CHANGED
|
@@ -1,16 +1,31 @@
|
|
|
1
1
|
import { effectivePricing, multipliersFor } from './pricing.js';
|
|
2
|
+
import { createConversationTracker } from './conversation.js';
|
|
3
|
+
import { createOutputShapeTracker } from './output-shape.js';
|
|
4
|
+
import { createInputShapeTracker } from './input-shape.js';
|
|
5
|
+
import { createRepeatsTracker } from './repeats.js';
|
|
6
|
+
import { createTtlFitTracker } from './ttl-fit.js';
|
|
7
|
+
import { createSessionLedgerTracker } from './session-ledger.js';
|
|
8
|
+
import { createSessionCostTracker } from './session-cost.js';
|
|
2
9
|
const EMPTY = () => ({
|
|
3
10
|
calls: 0,
|
|
4
11
|
inputTokens: 0,
|
|
5
12
|
cacheReadTokens: 0,
|
|
6
13
|
cacheWriteTokens: 0,
|
|
14
|
+
cacheWrite5mTokens: 0,
|
|
15
|
+
cacheWrite1hTokens: 0,
|
|
7
16
|
outputTokens: 0,
|
|
8
17
|
assumedWriteTtlCalls: 0,
|
|
18
|
+
maxCallInputTokens: 0,
|
|
9
19
|
inputUsd: 0,
|
|
10
20
|
cacheReadUsd: 0,
|
|
11
21
|
cacheWriteUsd: 0,
|
|
12
22
|
outputUsd: 0,
|
|
13
23
|
totalUsd: 0,
|
|
24
|
+
cachedTokensAtInputRateUsd: 0,
|
|
25
|
+
cacheWriteUsdIfAssumed1h: 0,
|
|
26
|
+
truncatedCalls: 0,
|
|
27
|
+
truncatedOutputUsd: 0,
|
|
28
|
+
stopReasonCalls: 0,
|
|
14
29
|
});
|
|
15
30
|
const OK = (value) => ({ kind: 'ok', value });
|
|
16
31
|
function readCount(...candidates) {
|
|
@@ -27,23 +42,28 @@ function readCount(...candidates) {
|
|
|
27
42
|
}
|
|
28
43
|
/** Zero for an absent count. Callers reject corrupt ones before reaching this. */
|
|
29
44
|
const valueOf = (count) => (count.kind === 'ok' ? count.value : 0);
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
*
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
function readMoment(...candidates) {
|
|
46
|
+
let sawCorrupt = false;
|
|
47
|
+
for (const value of candidates) {
|
|
48
|
+
if (value === undefined)
|
|
49
|
+
continue;
|
|
50
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
51
|
+
if (value >= 1e12)
|
|
52
|
+
return { kind: 'ok', ms: value };
|
|
53
|
+
if (value >= 1e8)
|
|
54
|
+
return { kind: 'ok', ms: value * 1000 };
|
|
55
|
+
sawCorrupt = true;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (typeof value === 'string') {
|
|
59
|
+
const parsed = Date.parse(value);
|
|
60
|
+
if (Number.isFinite(parsed))
|
|
61
|
+
return { kind: 'ok', ms: parsed };
|
|
62
|
+
}
|
|
63
|
+
sawCorrupt = true;
|
|
64
|
+
}
|
|
65
|
+
return sawCorrupt ? { kind: 'corrupt' } : { kind: 'absent' };
|
|
66
|
+
}
|
|
47
67
|
export function parseUsageLine(line) {
|
|
48
68
|
let raw;
|
|
49
69
|
try {
|
|
@@ -102,6 +122,15 @@ export function parseUsageLine(line) {
|
|
|
102
122
|
// Nothing to count at all.
|
|
103
123
|
if (Object.values(counts).every((c) => c.kind === 'absent'))
|
|
104
124
|
return null;
|
|
125
|
+
/**
|
|
126
|
+
* The clock, under the same rule as the counts: a timestamp that is present
|
|
127
|
+
* and unreadable rejects the line rather than becoming a silent absence.
|
|
128
|
+
* `created` is where OpenAI responses carry it (epoch seconds), so a log
|
|
129
|
+
* written by spreading the response already has one.
|
|
130
|
+
*/
|
|
131
|
+
const moment = readMoment(record.ts, record.timestamp, record.created_at, record.created);
|
|
132
|
+
if (moment.kind === 'corrupt')
|
|
133
|
+
return null;
|
|
105
134
|
const cached = valueOf(counts.openAiCached);
|
|
106
135
|
const flatWrite = valueOf(counts.cacheWrite);
|
|
107
136
|
const split5m = valueOf(counts.write5m);
|
|
@@ -120,22 +149,90 @@ export function parseUsageLine(line) {
|
|
|
120
149
|
cacheWrite1hTokens: hasSplit ? split1h : 0,
|
|
121
150
|
writeTtlKnown: hasSplit || flatWrite === 0,
|
|
122
151
|
outputTokens: valueOf(counts.output),
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
152
|
+
/**
|
|
153
|
+
* Trimmed and internally normalised: any whitespace run becomes one space.
|
|
154
|
+
* A label is a workload name, and it is also used as half of structured keys
|
|
155
|
+
* that split on `\n` — `byLabelAndModel`, the conversation tracker, the
|
|
156
|
+
* output-shape tracker. A label carrying a newline would corrupt that split
|
|
157
|
+
* and mis-file every figure under a truncated name; normalising at the one
|
|
158
|
+
* boundary where labels enter keeps every consumer honest at once.
|
|
159
|
+
*/
|
|
160
|
+
label: nameOf(record.label),
|
|
161
|
+
/**
|
|
162
|
+
* Read from either spelling, because both are what people already have:
|
|
163
|
+
* `session` in a hand-rolled log, `conversation_id` in most chat schemas.
|
|
164
|
+
* Refusing one of them would make the field's adoption a chore, and a field
|
|
165
|
+
* nobody sets measures nothing.
|
|
166
|
+
*/
|
|
167
|
+
session: nameOf(record.session) ?? nameOf(record.conversation_id),
|
|
168
|
+
ts: moment.kind === 'ok' ? moment.ms : null,
|
|
169
|
+
/**
|
|
170
|
+
* Anthropic spells it `stop_reason: "max_tokens"`, OpenAI
|
|
171
|
+
* `finish_reason: "length"`. Any other recorded reason is a completed
|
|
172
|
+
* answer; an absent field is `null`, which is "not measured" and not "did
|
|
173
|
+
* not happen" — the report treats those differently on purpose.
|
|
174
|
+
*/
|
|
175
|
+
truncated: (() => {
|
|
176
|
+
const reason = record.stop_reason ?? record.finish_reason;
|
|
177
|
+
if (typeof reason !== 'string')
|
|
178
|
+
return null;
|
|
179
|
+
return reason === 'max_tokens' || reason === 'length';
|
|
180
|
+
})(),
|
|
126
181
|
};
|
|
127
182
|
}
|
|
128
|
-
/**
|
|
129
|
-
|
|
183
|
+
/**
|
|
184
|
+
* A label or session identifier, from whatever a real log holds.
|
|
185
|
+
*
|
|
186
|
+
* **Numbers are identifiers too.** A conversation id is an auto-incremented
|
|
187
|
+
* integer in half the databases in existence, and the string-only version
|
|
188
|
+
* dropped `session: 12345` silently and then printed "No call in this log
|
|
189
|
+
* carried a session" — a false claim about a log that carried one on every
|
|
190
|
+
* line. A finite number is taken by its decimal form; booleans, objects and
|
|
191
|
+
* non-finite numbers stay out, because `session: true` names nothing.
|
|
192
|
+
*
|
|
193
|
+
* Strings are trimmed and internally normalised — any whitespace run becomes
|
|
194
|
+
* one space — because labels are half of structured keys that split on a
|
|
195
|
+
* newline, and a label carrying one would mis-file every figure it touches.
|
|
196
|
+
*/
|
|
197
|
+
function nameOf(value) {
|
|
198
|
+
if (typeof value === 'number' && Number.isFinite(value))
|
|
199
|
+
return String(value);
|
|
200
|
+
if (typeof value !== 'string')
|
|
201
|
+
return null;
|
|
202
|
+
const trimmed = value.trim().replace(/\s+/g, ' ');
|
|
203
|
+
return trimmed === '' ? null : trimmed;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* The bucket unlabelled calls land in.
|
|
207
|
+
*
|
|
208
|
+
* The empty string, because it is the one value a parsed label can never be —
|
|
209
|
+
* `parseUsageLine` trims and rejects empty. The first version used the literal
|
|
210
|
+
* string `'unlabelled'`, and a workload somebody had actually named `unlabelled`
|
|
211
|
+
* merged silently into the missing-label bucket: 200 labelled calls and 200
|
|
212
|
+
* unlabelled ones reported as one row of 400, and the "none of these calls
|
|
213
|
+
* carried a label" warning fired over a log where half of them had.
|
|
214
|
+
*
|
|
215
|
+
* Presentation stays in the CLI, which translates this sentinel through the
|
|
216
|
+
* message catalogue; data consumers can tell `''` from any real label.
|
|
217
|
+
*/
|
|
218
|
+
export const UNLABELLED = '';
|
|
130
219
|
/** Token counts only. Used for both halves, because both need them. */
|
|
131
220
|
function countInto(into, record) {
|
|
132
221
|
into.calls += 1;
|
|
133
222
|
into.inputTokens += record.inputTokens;
|
|
134
223
|
into.cacheReadTokens += record.cacheReadTokens;
|
|
135
224
|
into.cacheWriteTokens += record.cacheWrite5mTokens + record.cacheWrite1hTokens;
|
|
225
|
+
into.cacheWrite5mTokens += record.cacheWrite5mTokens;
|
|
226
|
+
into.cacheWrite1hTokens += record.cacheWrite1hTokens;
|
|
136
227
|
if (!record.writeTtlKnown)
|
|
137
228
|
into.assumedWriteTtlCalls += 1;
|
|
138
229
|
into.outputTokens += record.outputTokens;
|
|
230
|
+
into.maxCallInputTokens = Math.max(into.maxCallInputTokens, record.inputTokens + record.cacheReadTokens + record.cacheWrite5mTokens + record.cacheWrite1hTokens);
|
|
231
|
+
if (record.truncated !== null) {
|
|
232
|
+
into.stopReasonCalls += 1;
|
|
233
|
+
if (record.truncated)
|
|
234
|
+
into.truncatedCalls += 1;
|
|
235
|
+
}
|
|
139
236
|
}
|
|
140
237
|
function add(into, record, catalogue, on) {
|
|
141
238
|
/**
|
|
@@ -167,7 +264,29 @@ function add(into, record, catalogue, on) {
|
|
|
167
264
|
*/
|
|
168
265
|
into.cacheWriteUsd += per(record.cacheWrite5mTokens, inputPerMTok * rates.cacheWrite5m);
|
|
169
266
|
into.cacheWriteUsd += per(record.cacheWrite1hTokens, inputPerMTok * rates.cacheWrite1h);
|
|
267
|
+
/**
|
|
268
|
+
* The same writes with the assumption taken the other way.
|
|
269
|
+
*
|
|
270
|
+
* A record whose TTL the log did not state has all of its writes in the
|
|
271
|
+
* 5-minute bucket — `parseUsageLine` puts them there because one rate has to be
|
|
272
|
+
* chosen — so this prices exactly those at the 1-hour rate instead. Accumulated
|
|
273
|
+
* per call, and per model, because the ratio between the two rates is not a
|
|
274
|
+
* constant: 2.0/1.25 on Anthropic, 1.0/1.0 where a write costs what input
|
|
275
|
+
* costs. Scaling the total afterwards would invent a premium for providers that
|
|
276
|
+
* have none.
|
|
277
|
+
*/
|
|
278
|
+
const writeRateIfWrong = record.writeTtlKnown ? rates.cacheWrite5m : rates.cacheWrite1h;
|
|
279
|
+
into.cacheWriteUsdIfAssumed1h += per(record.cacheWrite5mTokens, inputPerMTok * writeRateIfWrong);
|
|
280
|
+
into.cacheWriteUsdIfAssumed1h += per(record.cacheWrite1hTokens, inputPerMTok * rates.cacheWrite1h);
|
|
170
281
|
into.outputUsd += per(record.outputTokens, outputPerMTok);
|
|
282
|
+
if (record.truncated === true) {
|
|
283
|
+
into.truncatedOutputUsd += per(record.outputTokens, outputPerMTok);
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* The same cache-touched tokens at the plain input rate, banked here because
|
|
287
|
+
* `inputPerMTok` is per model and is gone by the time anybody reads the total.
|
|
288
|
+
*/
|
|
289
|
+
into.cachedTokensAtInputRateUsd += per(record.cacheReadTokens + record.cacheWrite5mTokens + record.cacheWrite1hTokens, inputPerMTok);
|
|
171
290
|
into.totalUsd =
|
|
172
291
|
into.inputUsd + into.cacheReadUsd + into.cacheWriteUsd + into.outputUsd;
|
|
173
292
|
return true;
|
|
@@ -181,13 +300,46 @@ function add(into, record, catalogue, on) {
|
|
|
181
300
|
* lives, and it can chunk if it ever needs to.
|
|
182
301
|
*/
|
|
183
302
|
export function profileUsage(text, options) {
|
|
184
|
-
const { catalogue, on = new Date() } = options;
|
|
303
|
+
const { catalogue, on = new Date(), label: onlyLabel, sinceMs, untilMs } = options;
|
|
304
|
+
const windowed = sinceMs !== undefined || untilMs !== undefined;
|
|
305
|
+
let undatedExcluded = 0;
|
|
185
306
|
const total = EMPTY();
|
|
186
307
|
const unpriced = EMPTY();
|
|
187
308
|
const byLabel = new Map();
|
|
188
309
|
const byModel = new Map();
|
|
310
|
+
// Keyed on a pair, so the key carries a separator that cannot occur in either
|
|
311
|
+
// half. A model id is `[A-Za-z0-9._-]`, so a newline is safe in both.
|
|
312
|
+
const byPair = new Map();
|
|
189
313
|
const unpricedModels = new Set();
|
|
190
314
|
const skippedLines = [];
|
|
315
|
+
/**
|
|
316
|
+
* Fed in the pass this function already makes, rather than by keeping the records
|
|
317
|
+
* for a second one: a usage log is measured in megabytes, and what this holds is
|
|
318
|
+
* bounded by the number of conversations instead.
|
|
319
|
+
*/
|
|
320
|
+
const conversations = createConversationTracker({ catalogue, on });
|
|
321
|
+
const output = createOutputShapeTracker({ catalogue, on });
|
|
322
|
+
const input = createInputShapeTracker({ catalogue, on });
|
|
323
|
+
const repeats = createRepeatsTracker({ catalogue, on });
|
|
324
|
+
const ttlFit = createTtlFitTracker({ catalogue, on });
|
|
325
|
+
const ledger = createSessionLedgerTracker({ catalogue, on });
|
|
326
|
+
const sessionCosts = createSessionCostTracker({ catalogue, on });
|
|
327
|
+
let hasSessions = false;
|
|
328
|
+
const coverage = { label: 0, session: 0, ts: 0, stopReason: 0, cacheTtl: 0, cacheWrites: 0, parsed: 0 };
|
|
329
|
+
/**
|
|
330
|
+
* Raw lines already seen, for the duplicate check. Bounded by the number of
|
|
331
|
+
* *timestamped* lines — the price of catching a doubled bill, paid only on
|
|
332
|
+
* logs that carry a clock.
|
|
333
|
+
*/
|
|
334
|
+
const seenLines = new Set();
|
|
335
|
+
const duplicates = { count: 0, usd: 0 };
|
|
336
|
+
let spanFrom = Infinity;
|
|
337
|
+
let spanTo = -Infinity;
|
|
338
|
+
let spanCalls = 0;
|
|
339
|
+
/** Per UTC day: spend, calls, and spend per label. Bounded by days × labels. */
|
|
340
|
+
const days = new Map();
|
|
341
|
+
/** Per hour of the UTC day. Bounded by twenty-four entries, whatever the log. */
|
|
342
|
+
const hours = new Map();
|
|
191
343
|
const lines = text.split('\n');
|
|
192
344
|
for (let i = 0; i < lines.length; i += 1) {
|
|
193
345
|
const line = lines[i].trim();
|
|
@@ -198,6 +350,61 @@ export function profileUsage(text, options) {
|
|
|
198
350
|
skippedLines.push(i + 1);
|
|
199
351
|
continue;
|
|
200
352
|
}
|
|
353
|
+
// The drill-down: after the skip accounting, so a corrupt line is reported
|
|
354
|
+
// whatever it might have been labelled.
|
|
355
|
+
if (onlyLabel !== undefined && (record.label ?? UNLABELLED) !== onlyLabel)
|
|
356
|
+
continue;
|
|
357
|
+
/**
|
|
358
|
+
* The time window, after the label filter so `undatedExcluded` counts only
|
|
359
|
+
* the selected workload's clockless calls — a count polluted by every other
|
|
360
|
+
* label's records would overstate how much of *this* answer is missing.
|
|
361
|
+
* Records outside the window are simply not the question; records with no
|
|
362
|
+
* clock are the question left unanswerable, so they are counted.
|
|
363
|
+
*/
|
|
364
|
+
if (windowed) {
|
|
365
|
+
if (record.ts === null) {
|
|
366
|
+
undatedExcluded += 1;
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
if (sinceMs !== undefined && record.ts < sinceMs)
|
|
370
|
+
continue;
|
|
371
|
+
if (untilMs !== undefined && record.ts >= untilMs)
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Coverage is counted before pricing: whether a field is present is a
|
|
376
|
+
* property of the log, and a record on an unknown model still says
|
|
377
|
+
* whether somebody set `label`.
|
|
378
|
+
*/
|
|
379
|
+
coverage.parsed += 1;
|
|
380
|
+
if (record.label !== null)
|
|
381
|
+
coverage.label += 1;
|
|
382
|
+
if (record.session !== null)
|
|
383
|
+
coverage.session += 1;
|
|
384
|
+
if (record.ts !== null)
|
|
385
|
+
coverage.ts += 1;
|
|
386
|
+
if (record.truncated !== null)
|
|
387
|
+
coverage.stopReason += 1;
|
|
388
|
+
if (record.cacheWrite5mTokens + record.cacheWrite1hTokens > 0) {
|
|
389
|
+
coverage.cacheWrites += 1;
|
|
390
|
+
if (record.writeTtlKnown)
|
|
391
|
+
coverage.cacheTtl += 1;
|
|
392
|
+
}
|
|
393
|
+
if (record.session !== null)
|
|
394
|
+
hasSessions = true;
|
|
395
|
+
if (record.ts !== null) {
|
|
396
|
+
spanFrom = Math.min(spanFrom, record.ts);
|
|
397
|
+
spanTo = Math.max(spanTo, record.ts);
|
|
398
|
+
spanCalls += 1;
|
|
399
|
+
}
|
|
400
|
+
conversations.add(record);
|
|
401
|
+
output.add(record);
|
|
402
|
+
input.add(record);
|
|
403
|
+
repeats.add(record);
|
|
404
|
+
ttlFit.add(record);
|
|
405
|
+
ledger.add(record);
|
|
406
|
+
sessionCosts.add(record);
|
|
407
|
+
const usdBefore = total.totalUsd;
|
|
201
408
|
if (!add(total, record, catalogue, on)) {
|
|
202
409
|
unpricedModels.add(record.model);
|
|
203
410
|
countInto(unpriced, record);
|
|
@@ -208,6 +415,48 @@ export function profileUsage(text, options) {
|
|
|
208
415
|
countInto(byModel.get(record.model), record);
|
|
209
416
|
continue;
|
|
210
417
|
}
|
|
418
|
+
/**
|
|
419
|
+
* A line identical to one already read, with a clock to make the claim
|
|
420
|
+
* safe. Counted after pricing so the money is the exact delta this line
|
|
421
|
+
* added, which is what a doubled bill is overstated by.
|
|
422
|
+
*/
|
|
423
|
+
if (record.ts !== null) {
|
|
424
|
+
if (seenLines.has(line)) {
|
|
425
|
+
duplicates.count += 1;
|
|
426
|
+
duplicates.usd += total.totalUsd - usdBefore;
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
seenLines.add(line);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* The day's spend, as the exact delta this record just added to the total —
|
|
434
|
+
* the one place the per-record dollar exists without re-deriving the rate
|
|
435
|
+
* arithmetic a second time, where the two could drift apart.
|
|
436
|
+
*/
|
|
437
|
+
if (record.ts !== null) {
|
|
438
|
+
const day = new Date(record.ts).toISOString().slice(0, 10);
|
|
439
|
+
const usd = total.totalUsd - usdBefore;
|
|
440
|
+
let entry = days.get(day);
|
|
441
|
+
if (!entry) {
|
|
442
|
+
entry = { usd: 0, calls: 0, byLabel: new Map() };
|
|
443
|
+
days.set(day, entry);
|
|
444
|
+
}
|
|
445
|
+
entry.usd += usd;
|
|
446
|
+
entry.calls += 1;
|
|
447
|
+
const labelKey = record.label ?? UNLABELLED;
|
|
448
|
+
entry.byLabel.set(labelKey, (entry.byLabel.get(labelKey) ?? 0) + usd);
|
|
449
|
+
// The same exact per-record dollar, bucketed by hour of the UTC day.
|
|
450
|
+
const hour = new Date(record.ts).getUTCHours();
|
|
451
|
+
const hourEntry = hours.get(hour);
|
|
452
|
+
if (hourEntry) {
|
|
453
|
+
hourEntry.usd += usd;
|
|
454
|
+
hourEntry.calls += 1;
|
|
455
|
+
}
|
|
456
|
+
else {
|
|
457
|
+
hours.set(hour, { usd, calls: 1 });
|
|
458
|
+
}
|
|
459
|
+
}
|
|
211
460
|
const labelKey = record.label ?? UNLABELLED;
|
|
212
461
|
if (!byLabel.has(labelKey))
|
|
213
462
|
byLabel.set(labelKey, EMPTY());
|
|
@@ -215,6 +464,10 @@ export function profileUsage(text, options) {
|
|
|
215
464
|
if (!byModel.has(record.model))
|
|
216
465
|
byModel.set(record.model, EMPTY());
|
|
217
466
|
add(byModel.get(record.model), record, catalogue, on);
|
|
467
|
+
const pairKey = `${labelKey}\n${record.model}`;
|
|
468
|
+
if (!byPair.has(pairKey))
|
|
469
|
+
byPair.set(pairKey, EMPTY());
|
|
470
|
+
add(byPair.get(pairKey), record, catalogue, on);
|
|
218
471
|
}
|
|
219
472
|
const sorted = (map, key) => [...map.entries()]
|
|
220
473
|
.sort((a, b) => b[1].totalUsd - a[1].totalUsd || a[0].localeCompare(b[0]))
|
|
@@ -223,9 +476,45 @@ export function profileUsage(text, options) {
|
|
|
223
476
|
total,
|
|
224
477
|
byLabel: sorted(byLabel, 'label'),
|
|
225
478
|
byModel: sorted(byModel, 'model'),
|
|
479
|
+
byLabelAndModel: [...byPair.entries()]
|
|
480
|
+
.sort((a, b) => b[1].totalUsd - a[1].totalUsd || a[0].localeCompare(b[0]))
|
|
481
|
+
.map(([key, breakdown]) => {
|
|
482
|
+
const split = key.indexOf('\n');
|
|
483
|
+
return { label: key.slice(0, split), model: key.slice(split + 1), breakdown };
|
|
484
|
+
}),
|
|
226
485
|
unpricedModels: [...unpricedModels].sort(),
|
|
227
486
|
unpriced,
|
|
228
487
|
skippedLines,
|
|
488
|
+
conversations: conversations.finish(total.totalUsd),
|
|
489
|
+
hasSessions,
|
|
490
|
+
outputShapes: output.finish(total.totalUsd),
|
|
491
|
+
inputShapes: input.finish(total.totalUsd),
|
|
492
|
+
repeatedTurns: repeats.finish(),
|
|
493
|
+
span: spanCalls > 0 ? { fromMs: spanFrom, toMs: spanTo, calls: spanCalls } : null,
|
|
494
|
+
spendByDay: [...days.entries()]
|
|
495
|
+
.sort((a, b) => a[0].localeCompare(b[0]))
|
|
496
|
+
.map(([day, entry]) => {
|
|
497
|
+
let topLabel = null;
|
|
498
|
+
let topLabelUsd = 0;
|
|
499
|
+
for (const [label, usd] of entry.byLabel) {
|
|
500
|
+
if (usd > topLabelUsd) {
|
|
501
|
+
topLabel = label;
|
|
502
|
+
topLabelUsd = usd;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
return { day, usd: entry.usd, calls: entry.calls, topLabel, topLabelUsd };
|
|
506
|
+
}),
|
|
507
|
+
duplicateLines: duplicates,
|
|
508
|
+
fieldCoverage: coverage,
|
|
509
|
+
spendByHour: [...hours.entries()]
|
|
510
|
+
.sort((a, b) => a[0] - b[0])
|
|
511
|
+
.map(([hour, entry]) => ({ hour, usd: entry.usd, calls: entry.calls })),
|
|
512
|
+
cacheTtlFit: ttlFit.finish(),
|
|
513
|
+
timeWindow: windowed
|
|
514
|
+
? { sinceMs: sinceMs ?? null, untilMs: untilMs ?? null, undatedExcluded }
|
|
515
|
+
: null,
|
|
516
|
+
singleTurnCacheWrites: ledger.finish(),
|
|
517
|
+
sessionCosts: sessionCosts.finish(),
|
|
229
518
|
};
|
|
230
519
|
}
|
|
231
520
|
/**
|
|
@@ -271,4 +560,75 @@ export function cacheHitRate(breakdown) {
|
|
|
271
560
|
return null;
|
|
272
561
|
return breakdown.cacheReadTokens / attempts;
|
|
273
562
|
}
|
|
563
|
+
/**
|
|
564
|
+
* Floating-point noise, not a judgement threshold.
|
|
565
|
+
*
|
|
566
|
+
* Summing a million per-call doubles around a $100 bill accumulates roughly
|
|
567
|
+
* `n · eps · magnitude` ≈ $2e-8 of drift, and a verdict that flipped on that would
|
|
568
|
+
* be reporting arithmetic error as a finding. A millionth of a dollar is orders of
|
|
569
|
+
* magnitude below anything this tool prints, so nothing real is being rounded away
|
|
570
|
+
* — deliberately not a "too small to care about" cutoff, which would be a
|
|
571
|
+
* judgement and would belong somewhere a reader can see it.
|
|
572
|
+
*/
|
|
573
|
+
const CACHE_DELTA_NOISE_USD = 1e-6;
|
|
574
|
+
/**
|
|
575
|
+
* Did caching pay for itself?
|
|
576
|
+
*
|
|
577
|
+
* The question nothing else in this package can answer, and the one that decides
|
|
578
|
+
* whether the advice the rest of it gives was right. Trazum tells people to cache;
|
|
579
|
+
* on Anthropic a cache **write** costs 1.25x plain input at the 5-minute TTL and
|
|
580
|
+
* **2x** at the 1-hour one, so a prefix that changes faster than it is reused is
|
|
581
|
+
* billed at a premium and returns nothing. That workload would be cheaper with
|
|
582
|
+
* caching switched off, and no other report in this repository would ever say so.
|
|
583
|
+
*
|
|
584
|
+
* The counterfactual is exact, which is why this is allowed to exist here at all:
|
|
585
|
+
* caching changes the multiplier on a token, never the token. Had `cache_control`
|
|
586
|
+
* not been set, the identical prefix would have gone up as ordinary input at 1x.
|
|
587
|
+
* So `withoutCachingUsd` is not an estimate of a different call — it is the same
|
|
588
|
+
* call, arithmetic away.
|
|
589
|
+
*
|
|
590
|
+
* Worth running per label as well as over the whole log. A profitable cache on one
|
|
591
|
+
* workload and a bleeding one on another net out to a comfortable-looking total,
|
|
592
|
+
* and the aggregate is exactly where a loss hides.
|
|
593
|
+
*/
|
|
594
|
+
export function cacheEconomics(breakdown) {
|
|
595
|
+
const touchedTokens = breakdown.cacheReadTokens + breakdown.cacheWriteTokens;
|
|
596
|
+
const spentUsd = breakdown.cacheReadUsd + breakdown.cacheWriteUsd;
|
|
597
|
+
const withoutCachingUsd = breakdown.cachedTokensAtInputRateUsd;
|
|
598
|
+
const none = (verdict) => ({
|
|
599
|
+
spentUsd,
|
|
600
|
+
withoutCachingUsd,
|
|
601
|
+
deltaUsd: 0,
|
|
602
|
+
readsPerWrite: null,
|
|
603
|
+
verdict,
|
|
604
|
+
worstCaseDeltaUsd: 0,
|
|
605
|
+
worstCaseVerdict: verdict,
|
|
606
|
+
});
|
|
607
|
+
if (touchedTokens === 0)
|
|
608
|
+
return none('not-attempted');
|
|
609
|
+
/**
|
|
610
|
+
* Tokens went through the cache and no money is attached to either side, so
|
|
611
|
+
* there is nothing to compare. This is what an unpriced model looks like: the
|
|
612
|
+
* counts accumulate through `countInto` and the dollars never do. Without this
|
|
613
|
+
* guard the delta is `0 - 0` and the verdict comes out `no-difference` — a
|
|
614
|
+
* confident claim about a bill that was never computed.
|
|
615
|
+
*/
|
|
616
|
+
if (spentUsd === 0 && withoutCachingUsd === 0)
|
|
617
|
+
return none('unpriced');
|
|
618
|
+
const deltaUsd = spentUsd - withoutCachingUsd;
|
|
619
|
+
const worstCaseDeltaUsd = breakdown.cacheReadUsd + breakdown.cacheWriteUsdIfAssumed1h - withoutCachingUsd;
|
|
620
|
+
const readsPerWrite = breakdown.cacheWriteTokens === 0
|
|
621
|
+
? null
|
|
622
|
+
: breakdown.cacheReadTokens / breakdown.cacheWriteTokens;
|
|
623
|
+
const decide = (delta) => Math.abs(delta) < CACHE_DELTA_NOISE_USD ? 'no-difference' : delta > 0 ? 'lost-money' : 'paid-off';
|
|
624
|
+
return {
|
|
625
|
+
spentUsd,
|
|
626
|
+
withoutCachingUsd,
|
|
627
|
+
deltaUsd,
|
|
628
|
+
readsPerWrite,
|
|
629
|
+
verdict: decide(deltaUsd),
|
|
630
|
+
worstCaseDeltaUsd,
|
|
631
|
+
worstCaseVerdict: decide(worstCaseDeltaUsd),
|
|
632
|
+
};
|
|
633
|
+
}
|
|
274
634
|
//# sourceMappingURL=usage.js.map
|
package/dist/usage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../src/usage.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trazum/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.25.0",
|
|
4
4
|
"description": "Trazum core: priced advisories for LLM prompts (caching, model tier, batching, schemas), plus deterministic trimming, token counting and pricing.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "David Mu\u00f1oz Rey",
|
package/src/against.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The drivers of a change between two bills.
|
|
3
|
+
*
|
|
4
|
+
* One implementation, exported from core, because the sign convention here —
|
|
5
|
+
* **positive means the bill grew**, the diff convention — has already flipped
|
|
6
|
+
* once in this repository's history when restated by hand. The CLI, the MCP
|
|
7
|
+
* and the web all render these rows; three inline computations of the same
|
|
8
|
+
* union-and-subtract is three chances for one of them to disagree about what
|
|
9
|
+
* a vanished workload contributed.
|
|
10
|
+
*
|
|
11
|
+
* Derived over the **union** of keys, so an appeared or vanished workload is
|
|
12
|
+
* named rather than folded silently into the total: `was: null` is a key the
|
|
13
|
+
* previous log did not have, `now: null` one this log no longer has. Both are
|
|
14
|
+
* different statements from `$0.00`, and the renderings say which.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export interface AgainstDriver {
|
|
18
|
+
key: string;
|
|
19
|
+
/** What this key cost in the previous log, or null when it was not there. */
|
|
20
|
+
was: number | null;
|
|
21
|
+
/** What it costs now, or null when it is gone. */
|
|
22
|
+
now: number | null;
|
|
23
|
+
/** `(now ?? 0) - (was ?? 0)` — positive means the bill grew. */
|
|
24
|
+
delta: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Noise floor, not a judgement threshold: the same accumulated-double drift
|
|
29
|
+
* `cacheEconomics` refuses to report as a finding.
|
|
30
|
+
*/
|
|
31
|
+
const DRIVER_NOISE_USD = 1e-9;
|
|
32
|
+
|
|
33
|
+
export function driversBetween(
|
|
34
|
+
before: ReadonlyArray<{ key: string; usd: number }>,
|
|
35
|
+
after: ReadonlyArray<{ key: string; usd: number }>,
|
|
36
|
+
): AgainstDriver[] {
|
|
37
|
+
const wasBy = new Map(before.map((row) => [row.key, row.usd]));
|
|
38
|
+
const nowBy = new Map(after.map((row) => [row.key, row.usd]));
|
|
39
|
+
return [...new Set([...wasBy.keys(), ...nowBy.keys()])]
|
|
40
|
+
.map((key) => ({
|
|
41
|
+
key,
|
|
42
|
+
was: wasBy.has(key) ? wasBy.get(key)! : null,
|
|
43
|
+
now: nowBy.has(key) ? nowBy.get(key)! : null,
|
|
44
|
+
}))
|
|
45
|
+
.map((driver) => ({ ...driver, delta: (driver.now ?? 0) - (driver.was ?? 0) }))
|
|
46
|
+
.filter((driver) => Math.abs(driver.delta) > DRIVER_NOISE_USD)
|
|
47
|
+
.sort((a, b) => Math.abs(b.delta) - Math.abs(a.delta));
|
|
48
|
+
}
|