@trazum/core 1.30.0 → 1.32.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/gate-explain.d.ts +80 -0
- package/dist/gate-explain.d.ts.map +1 -0
- package/dist/gate-explain.js +73 -0
- package/dist/gate-explain.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/reprice.d.ts +39 -0
- package/dist/reprice.d.ts.map +1 -1
- package/dist/reprice.js +43 -0
- package/dist/reprice.js.map +1 -1
- package/package.json +1 -1
- package/src/gate-explain.ts +107 -0
- package/src/index.ts +2 -0
- package/src/reprice.ts +91 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Why a gate failed, and what would move it — from figures the report already
|
|
3
|
+
* computed.
|
|
4
|
+
*
|
|
5
|
+
* A gate today prints a verdict and an exit code. The person reading it is in
|
|
6
|
+
* CI, which is the one place nobody opens the full report: the build is red,
|
|
7
|
+
* the message says the bill is over budget, and finding out *which workload*
|
|
8
|
+
* and *what to do* means running the tool again locally with different flags.
|
|
9
|
+
* Most people do not, so the gate is a tripwire rather than a fix.
|
|
10
|
+
*
|
|
11
|
+
* **This module invents nothing.** The overage is subtraction, the largest
|
|
12
|
+
* contributor is the biggest slice already in the report, and the cheapest
|
|
13
|
+
* lever is `billLevers`' own arithmetic. What is added is the joining of the
|
|
14
|
+
* three, so the failure carries its own next step.
|
|
15
|
+
*
|
|
16
|
+
* What it deliberately does not do is recommend. `coversIt` states whether the
|
|
17
|
+
* lever's saving is at least the overage — a comparison of two numbers already
|
|
18
|
+
* on the page — and nothing here claims the cheaper model can do the work or
|
|
19
|
+
* that the calls can wait for a batch window. Those are the reader's to judge,
|
|
20
|
+
* and the copy on every surface says so.
|
|
21
|
+
*/
|
|
22
|
+
import type { BillLevers, SliceLevers } from './levers.js';
|
|
23
|
+
import type { UsageProfileReport } from './usage.js';
|
|
24
|
+
export interface GateExplanation {
|
|
25
|
+
/** What the bill was over by. Always positive — this only describes failures. */
|
|
26
|
+
overageUsd: number;
|
|
27
|
+
/**
|
|
28
|
+
* The slice carrying the most spend, or null when the report has no slices
|
|
29
|
+
* to point at. Null rather than a zeroed row: "nothing to name" and "a
|
|
30
|
+
* workload that cost nothing" are different statements.
|
|
31
|
+
*/
|
|
32
|
+
largest: {
|
|
33
|
+
label: string;
|
|
34
|
+
model: string;
|
|
35
|
+
usd: number;
|
|
36
|
+
share: number;
|
|
37
|
+
} | null;
|
|
38
|
+
/**
|
|
39
|
+
* The single cheapest lever available anywhere in the bill, by what it
|
|
40
|
+
* would save. Null when the catalogue offers none — no routing candidate
|
|
41
|
+
* and no batch price is a real answer, not an empty recommendation.
|
|
42
|
+
*/
|
|
43
|
+
lever: SliceLevers | null;
|
|
44
|
+
/**
|
|
45
|
+
* Whether that lever alone would cover the overage. Two numbers compared,
|
|
46
|
+
* stated rather than implied: a lever worth half the overage is still worth
|
|
47
|
+
* pulling, and a reader must not be left to infer it closed the gap.
|
|
48
|
+
*/
|
|
49
|
+
coversIt: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The explanation for a failed spend gate.
|
|
53
|
+
*
|
|
54
|
+
* `overUsd` is what the gate judged minus its limit — passed in rather than
|
|
55
|
+
* recomputed, because each gate judges a different figure (the whole bill, one
|
|
56
|
+
* day, one conversation) and this module must not guess which.
|
|
57
|
+
*/
|
|
58
|
+
export declare function explainGateFailure(report: UsageProfileReport, levers: BillLevers, overUsd: number): GateExplanation;
|
|
59
|
+
/**
|
|
60
|
+
* How much room a passing gate had left, as a fraction of the limit.
|
|
61
|
+
*
|
|
62
|
+
* A pass 2% under budget and a pass 60% under are different states of the
|
|
63
|
+
* world, and only one of them is quiet news. Returned as a fraction so every
|
|
64
|
+
* surface applies the same threshold to it rather than inventing one.
|
|
65
|
+
*
|
|
66
|
+
* `null` when the limit is zero — a budget of nothing has no margin to be a
|
|
67
|
+
* fraction of, and dividing would produce an Infinity that reads like an
|
|
68
|
+
* answer.
|
|
69
|
+
*/
|
|
70
|
+
export declare function gateMargin(judgedUsd: number, limitUsd: number): number | null;
|
|
71
|
+
/**
|
|
72
|
+
* The threshold under which a pass is worth saying out loud, stated here and
|
|
73
|
+
* repeated in every rendering's copy.
|
|
74
|
+
*
|
|
75
|
+
* A tenth of the budget is close enough that the next ordinary week crosses
|
|
76
|
+
* it. Wider than that and the pass is genuinely quiet news, which is what a
|
|
77
|
+
* gate passing should usually be.
|
|
78
|
+
*/
|
|
79
|
+
export declare const GATE_MARGIN_TIGHT = 0.1;
|
|
80
|
+
//# sourceMappingURL=gate-explain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-explain.d.ts","sourceRoot":"","sources":["../src/gate-explain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC7E;;;;OAIG;IACH,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,kBAAkB,EAC1B,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,MAAM,GACd,eAAe,CAqBjB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG7E;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,MAAM,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Why a gate failed, and what would move it — from figures the report already
|
|
3
|
+
* computed.
|
|
4
|
+
*
|
|
5
|
+
* A gate today prints a verdict and an exit code. The person reading it is in
|
|
6
|
+
* CI, which is the one place nobody opens the full report: the build is red,
|
|
7
|
+
* the message says the bill is over budget, and finding out *which workload*
|
|
8
|
+
* and *what to do* means running the tool again locally with different flags.
|
|
9
|
+
* Most people do not, so the gate is a tripwire rather than a fix.
|
|
10
|
+
*
|
|
11
|
+
* **This module invents nothing.** The overage is subtraction, the largest
|
|
12
|
+
* contributor is the biggest slice already in the report, and the cheapest
|
|
13
|
+
* lever is `billLevers`' own arithmetic. What is added is the joining of the
|
|
14
|
+
* three, so the failure carries its own next step.
|
|
15
|
+
*
|
|
16
|
+
* What it deliberately does not do is recommend. `coversIt` states whether the
|
|
17
|
+
* lever's saving is at least the overage — a comparison of two numbers already
|
|
18
|
+
* on the page — and nothing here claims the cheaper model can do the work or
|
|
19
|
+
* that the calls can wait for a batch window. Those are the reader's to judge,
|
|
20
|
+
* and the copy on every surface says so.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* The explanation for a failed spend gate.
|
|
24
|
+
*
|
|
25
|
+
* `overUsd` is what the gate judged minus its limit — passed in rather than
|
|
26
|
+
* recomputed, because each gate judges a different figure (the whole bill, one
|
|
27
|
+
* day, one conversation) and this module must not guess which.
|
|
28
|
+
*/
|
|
29
|
+
export function explainGateFailure(report, levers, overUsd) {
|
|
30
|
+
const biggest = report.byLabelAndModel[0] ?? null;
|
|
31
|
+
const lever = levers.slices.length > 0 ? levers.slices[0] : null;
|
|
32
|
+
return {
|
|
33
|
+
overageUsd: overUsd,
|
|
34
|
+
largest: biggest === null
|
|
35
|
+
? null
|
|
36
|
+
: {
|
|
37
|
+
label: biggest.label,
|
|
38
|
+
model: biggest.model,
|
|
39
|
+
usd: biggest.breakdown.totalUsd,
|
|
40
|
+
share: report.total.totalUsd > 0
|
|
41
|
+
? biggest.breakdown.totalUsd / report.total.totalUsd
|
|
42
|
+
: 0,
|
|
43
|
+
},
|
|
44
|
+
lever,
|
|
45
|
+
coversIt: lever !== null && lever.combinedUsd >= overUsd,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* How much room a passing gate had left, as a fraction of the limit.
|
|
50
|
+
*
|
|
51
|
+
* A pass 2% under budget and a pass 60% under are different states of the
|
|
52
|
+
* world, and only one of them is quiet news. Returned as a fraction so every
|
|
53
|
+
* surface applies the same threshold to it rather than inventing one.
|
|
54
|
+
*
|
|
55
|
+
* `null` when the limit is zero — a budget of nothing has no margin to be a
|
|
56
|
+
* fraction of, and dividing would produce an Infinity that reads like an
|
|
57
|
+
* answer.
|
|
58
|
+
*/
|
|
59
|
+
export function gateMargin(judgedUsd, limitUsd) {
|
|
60
|
+
if (limitUsd <= 0)
|
|
61
|
+
return null;
|
|
62
|
+
return (limitUsd - judgedUsd) / limitUsd;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The threshold under which a pass is worth saying out loud, stated here and
|
|
66
|
+
* repeated in every rendering's copy.
|
|
67
|
+
*
|
|
68
|
+
* A tenth of the budget is close enough that the next ordinary week crosses
|
|
69
|
+
* it. Wider than that and the pass is genuinely quiet news, which is what a
|
|
70
|
+
* gate passing should usually be.
|
|
71
|
+
*/
|
|
72
|
+
export const GATE_MARGIN_TIGHT = 0.1;
|
|
73
|
+
//# sourceMappingURL=gate-explain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-explain.js","sourceRoot":"","sources":["../src/gate-explain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AA4BH;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,MAA0B,EAC1B,MAAkB,EAClB,OAAe;IAEf,MAAM,OAAO,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAClD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAElE,OAAO;QACL,UAAU,EAAE,OAAO;QACnB,OAAO,EACL,OAAO,KAAK,IAAI;YACd,CAAC,CAAC,IAAI;YACN,CAAC,CAAC;gBACE,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,QAAQ;gBAC/B,KAAK,EACH,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC;oBACvB,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ;oBACpD,CAAC,CAAC,CAAC;aACR;QACP,KAAK;QACL,QAAQ,EAAE,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,WAAW,IAAI,OAAO;KACzD,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE,QAAgB;IAC5D,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/B,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,GAAG,QAAQ,CAAC;AAC3C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export type { ProfileCsvOptions, ProfileCsvShape } from './csv.js';
|
|
|
10
10
|
export { driversBetween } from './against.js';
|
|
11
11
|
export type { AgainstDriver } from './against.js';
|
|
12
12
|
export { coverageDrift, COVERAGE_FIELDS, COVERAGE_DRIFT_MIN } from './coverage-drift.js';
|
|
13
|
+
export { explainGateFailure, gateMargin, GATE_MARGIN_TIGHT } from './gate-explain.js';
|
|
14
|
+
export type { GateExplanation } from './gate-explain.js';
|
|
13
15
|
export type { CoverageDrift, CoverageField } from './coverage-drift.js';
|
|
14
16
|
export { createInputShapeTracker, inputShapes } from './input-shape.js';
|
|
15
17
|
export type { InputShape, InputShapeOptions, InputShapeTracker } from './input-shape.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ export { TTL_1H_MS, TTL_5M_MS, cacheTtlFit, createTtlFitTracker } from './ttl-fi
|
|
|
15
15
|
export { PROFILE_CSV_COLUMNS, PROFILE_CSV_DAY_COLUMNS, PROFILE_CSV_HOUR_COLUMNS, PROFILE_CSV_MODEL_DAY_COLUMNS, profileToCsv, } from './csv.js';
|
|
16
16
|
export { driversBetween } from './against.js';
|
|
17
17
|
export { coverageDrift, COVERAGE_FIELDS, COVERAGE_DRIFT_MIN } from './coverage-drift.js';
|
|
18
|
+
export { explainGateFailure, gateMargin, GATE_MARGIN_TIGHT } from './gate-explain.js';
|
|
18
19
|
// The same tokens at another model's rates — arithmetic, not advice, and it
|
|
19
20
|
// refuses to price a call the target could not have accepted. See reprice.ts.
|
|
20
21
|
// The shape of a call's input — the half of the bill a total could only name.
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC/F,OAAO,EACL,UAAU,EACV,cAAc,EACd,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,QAAQ,GACT,MAAM,YAAY,CAAC;AAWpB,OAAO,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAClF,gFAAgF;AAChF,4EAA4E;AAC5E,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEtF,2EAA2E;AAC3E,+EAA+E;AAC/E,8EAA8E;AAC9E,0EAA0E;AAC1E,yCAAyC;AACzC,4EAA4E;AAC5E,qDAAqD;AACrD,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,EACxB,6BAA6B,EAC7B,YAAY,GACb,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/reprice.d.ts
CHANGED
|
@@ -71,6 +71,26 @@ export interface RepricedSlice {
|
|
|
71
71
|
deltaUsd: number;
|
|
72
72
|
/** The slice's largest single call, cache reads and writes included. */
|
|
73
73
|
maxCallInputTokens: number;
|
|
74
|
+
/**
|
|
75
|
+
* Present when the slice's cache traffic could not exist on the target.
|
|
76
|
+
*
|
|
77
|
+
* A cache entry only forms above the model's minimum prompt size, and when
|
|
78
|
+
* even this slice's largest call sits under the target's minimum, none of
|
|
79
|
+
* its calls could create one — so `targetUsd`, which grants the cache
|
|
80
|
+
* traffic the target's discounted rates, is priced on entries the target
|
|
81
|
+
* would refuse to create. That error flatters the move, which is exactly
|
|
82
|
+
* the direction this repository refuses. `noCacheUsd` is the same tokens
|
|
83
|
+
* with every cache token at the full input rate: the figure the target
|
|
84
|
+
* would actually bill if the entries cannot form. The truth sits at
|
|
85
|
+
* `noCacheUsd` (no entries) — not between the two by interpolation.
|
|
86
|
+
*
|
|
87
|
+
* Null when the slice has no cache traffic, or when its calls clear the
|
|
88
|
+
* target's minimum — where the standard figure stands unqualified.
|
|
89
|
+
*/
|
|
90
|
+
cacheBeyondTarget: {
|
|
91
|
+
minTokens: number;
|
|
92
|
+
noCacheUsd: number;
|
|
93
|
+
} | null;
|
|
74
94
|
}
|
|
75
95
|
/** A slice holding a call the target model could not have accepted. */
|
|
76
96
|
export interface OverContextSlice {
|
|
@@ -120,6 +140,25 @@ export interface RepriceReport {
|
|
|
120
140
|
*/
|
|
121
141
|
unpricedModels: string[];
|
|
122
142
|
unpricedCalls: number;
|
|
143
|
+
/**
|
|
144
|
+
* The moved bill with the target's Batch API on top, over the same movable
|
|
145
|
+
* slices — or null when the target sells no batch discount, which is a
|
|
146
|
+
* different statement from a $0 saving.
|
|
147
|
+
*
|
|
148
|
+
* The other half of "priced whole": routing and batching combine by
|
|
149
|
+
* discounting the *target's* rates, not by adding two savings — the same
|
|
150
|
+
* never-summed rule the levers learned when $12.60 plus $10.50 exceeded
|
|
151
|
+
* the $21.00 slice they came from. The discount covers input and output,
|
|
152
|
+
* cache traffic priced unchanged, matching the levers' convention exactly
|
|
153
|
+
* so the two surfaces cannot disagree about what batching is worth.
|
|
154
|
+
*
|
|
155
|
+
* Whether these calls can wait for a batch window is not knowable from a
|
|
156
|
+
* log, and nothing here claims it — the field is arithmetic, the decision
|
|
157
|
+
* is the reader's.
|
|
158
|
+
*/
|
|
159
|
+
batchOnTarget: {
|
|
160
|
+
targetUsd: number;
|
|
161
|
+
} | null;
|
|
123
162
|
/** Always true. A field, not a comment, so a rendering can print it. */
|
|
124
163
|
sameTokensAssumed: true;
|
|
125
164
|
}
|
package/dist/reprice.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reprice.d.ts","sourceRoot":"","sources":["../src/reprice.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,6EAA6E;AAC7E,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,kBAAkB,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"reprice.d.ts","sourceRoot":"","sources":["../src/reprice.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,6EAA6E;AAC7E,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;;;;;OAeG;IACH,iBAAiB,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACrE;AAED,uEAAuE;AACvE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,oDAAoD;QACpD,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;IACF;;;OAGG;IACH,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,4EAA4E;IAC5E,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD;;;OAGG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;;OAKG;IACH,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;;;;;OAeG;IACH,aAAa,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5C,wEAAwE;IACxE,iBAAiB,EAAE,IAAI,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,IAAI,CACb,cAAc,EACd,aAAa,GAAG,iBAAiB,GAAG,oBAAoB,GAAG,oBAAoB,GAAG,cAAc,CACjG,EACD,KAAK,EAAE,YAAY,EACnB,EAAE,GAAE,IAAiB,GACpB,MAAM,CAWR;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,kBAAkB,EAC1B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,gBAAgB,EAC3B,EAAE,GAAE,IAAiB,GACpB,aAAa,GAAG,IAAI,CAmHtB"}
|
package/dist/reprice.js
CHANGED
|
@@ -51,6 +51,32 @@ export function repriceProfile(report, targetId, catalogue, on = new Date()) {
|
|
|
51
51
|
}
|
|
52
52
|
const targetUsd = priceTokensOn(breakdown, target, on);
|
|
53
53
|
assumedWriteTtlCalls += breakdown.assumedWriteTtlCalls;
|
|
54
|
+
/**
|
|
55
|
+
* Cache traffic the target could not grant. The comparison is against the
|
|
56
|
+
* slice's *largest* call: if even that one sits under the target's cache
|
|
57
|
+
* minimum, no call in the slice could create an entry, and that is a fact
|
|
58
|
+
* rather than a guess. A slice whose largest call clears the minimum may
|
|
59
|
+
* still hold smaller calls that do not — undecidable per call from an
|
|
60
|
+
* aggregate, so nothing is claimed there.
|
|
61
|
+
*/
|
|
62
|
+
const cacheTokens = breakdown.cacheReadTokens + breakdown.cacheWrite5mTokens + breakdown.cacheWrite1hTokens;
|
|
63
|
+
// A null minimum is an *unknown* one — overlay-added models leave it null
|
|
64
|
+
// rather than invent a number — and nothing can be claimed against a
|
|
65
|
+
// threshold nobody stated. Unqualified is the only honest rendering there.
|
|
66
|
+
const cacheBeyondTarget = cacheTokens > 0 &&
|
|
67
|
+
target.cacheMinTokens !== null &&
|
|
68
|
+
breakdown.maxCallInputTokens < target.cacheMinTokens
|
|
69
|
+
? {
|
|
70
|
+
minTokens: target.cacheMinTokens,
|
|
71
|
+
noCacheUsd: priceTokensOn({
|
|
72
|
+
inputTokens: breakdown.inputTokens + cacheTokens,
|
|
73
|
+
cacheReadTokens: 0,
|
|
74
|
+
cacheWrite5mTokens: 0,
|
|
75
|
+
cacheWrite1hTokens: 0,
|
|
76
|
+
outputTokens: breakdown.outputTokens,
|
|
77
|
+
}, target, on),
|
|
78
|
+
}
|
|
79
|
+
: null;
|
|
54
80
|
slices.push({
|
|
55
81
|
label: slice.label,
|
|
56
82
|
model: slice.model,
|
|
@@ -59,12 +85,28 @@ export function repriceProfile(report, targetId, catalogue, on = new Date()) {
|
|
|
59
85
|
targetUsd,
|
|
60
86
|
deltaUsd: targetUsd - breakdown.totalUsd,
|
|
61
87
|
maxCallInputTokens: breakdown.maxCallInputTokens,
|
|
88
|
+
cacheBeyondTarget,
|
|
62
89
|
});
|
|
63
90
|
}
|
|
64
91
|
slices.sort((a, b) => a.deltaUsd - b.deltaUsd || b.currentUsd - a.currentUsd);
|
|
65
92
|
overContext.sort((a, b) => b.currentUsd - a.currentUsd);
|
|
66
93
|
const currentUsd = slices.reduce((sum, s) => sum + s.currentUsd, 0);
|
|
67
94
|
const targetUsd = slices.reduce((sum, s) => sum + s.targetUsd, 0);
|
|
95
|
+
/**
|
|
96
|
+
* The same movable tokens, batched on the target. Computed from the token
|
|
97
|
+
* aggregates rather than by discounting `targetUsd`, because the discount
|
|
98
|
+
* covers input and output while cache traffic rides through unchanged.
|
|
99
|
+
*/
|
|
100
|
+
const batchRate = multipliersFor(target).batch;
|
|
101
|
+
let batchOnTarget = null;
|
|
102
|
+
if (batchRate !== null && batchRate < 1 && slices.length > 0) {
|
|
103
|
+
const { inputPerMTok, outputPerMTok } = effectivePricing(target, on);
|
|
104
|
+
const movable = report.byLabelAndModel.filter((slice) => slice.model !== target.id && slice.breakdown.maxCallInputTokens <= target.contextWindow);
|
|
105
|
+
const inOutUsd = movable.reduce((sum, slice) => sum +
|
|
106
|
+
(slice.breakdown.inputTokens / 1_000_000) * inputPerMTok +
|
|
107
|
+
(slice.breakdown.outputTokens / 1_000_000) * outputPerMTok, 0);
|
|
108
|
+
batchOnTarget = { targetUsd: targetUsd - inOutUsd * (1 - batchRate) };
|
|
109
|
+
}
|
|
68
110
|
return {
|
|
69
111
|
target: { id: target.id, displayName: target.displayName, contextWindow: target.contextWindow },
|
|
70
112
|
slices,
|
|
@@ -76,6 +118,7 @@ export function repriceProfile(report, targetId, catalogue, on = new Date()) {
|
|
|
76
118
|
assumedWriteTtlCalls,
|
|
77
119
|
unpricedModels: report.unpricedModels,
|
|
78
120
|
unpricedCalls: report.unpriced.calls,
|
|
121
|
+
batchOnTarget,
|
|
79
122
|
sameTokensAssumed: true,
|
|
80
123
|
};
|
|
81
124
|
}
|
package/dist/reprice.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reprice.js","sourceRoot":"","sources":["../src/reprice.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"reprice.js","sourceRoot":"","sources":["../src/reprice.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.32.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",
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Why a gate failed, and what would move it — from figures the report already
|
|
3
|
+
* computed.
|
|
4
|
+
*
|
|
5
|
+
* A gate today prints a verdict and an exit code. The person reading it is in
|
|
6
|
+
* CI, which is the one place nobody opens the full report: the build is red,
|
|
7
|
+
* the message says the bill is over budget, and finding out *which workload*
|
|
8
|
+
* and *what to do* means running the tool again locally with different flags.
|
|
9
|
+
* Most people do not, so the gate is a tripwire rather than a fix.
|
|
10
|
+
*
|
|
11
|
+
* **This module invents nothing.** The overage is subtraction, the largest
|
|
12
|
+
* contributor is the biggest slice already in the report, and the cheapest
|
|
13
|
+
* lever is `billLevers`' own arithmetic. What is added is the joining of the
|
|
14
|
+
* three, so the failure carries its own next step.
|
|
15
|
+
*
|
|
16
|
+
* What it deliberately does not do is recommend. `coversIt` states whether the
|
|
17
|
+
* lever's saving is at least the overage — a comparison of two numbers already
|
|
18
|
+
* on the page — and nothing here claims the cheaper model can do the work or
|
|
19
|
+
* that the calls can wait for a batch window. Those are the reader's to judge,
|
|
20
|
+
* and the copy on every surface says so.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import type { BillLevers, SliceLevers } from './levers.js';
|
|
24
|
+
import type { UsageProfileReport } from './usage.js';
|
|
25
|
+
|
|
26
|
+
export interface GateExplanation {
|
|
27
|
+
/** What the bill was over by. Always positive — this only describes failures. */
|
|
28
|
+
overageUsd: number;
|
|
29
|
+
/**
|
|
30
|
+
* The slice carrying the most spend, or null when the report has no slices
|
|
31
|
+
* to point at. Null rather than a zeroed row: "nothing to name" and "a
|
|
32
|
+
* workload that cost nothing" are different statements.
|
|
33
|
+
*/
|
|
34
|
+
largest: { label: string; model: string; usd: number; share: number } | null;
|
|
35
|
+
/**
|
|
36
|
+
* The single cheapest lever available anywhere in the bill, by what it
|
|
37
|
+
* would save. Null when the catalogue offers none — no routing candidate
|
|
38
|
+
* and no batch price is a real answer, not an empty recommendation.
|
|
39
|
+
*/
|
|
40
|
+
lever: SliceLevers | null;
|
|
41
|
+
/**
|
|
42
|
+
* Whether that lever alone would cover the overage. Two numbers compared,
|
|
43
|
+
* stated rather than implied: a lever worth half the overage is still worth
|
|
44
|
+
* pulling, and a reader must not be left to infer it closed the gap.
|
|
45
|
+
*/
|
|
46
|
+
coversIt: boolean;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* The explanation for a failed spend gate.
|
|
51
|
+
*
|
|
52
|
+
* `overUsd` is what the gate judged minus its limit — passed in rather than
|
|
53
|
+
* recomputed, because each gate judges a different figure (the whole bill, one
|
|
54
|
+
* day, one conversation) and this module must not guess which.
|
|
55
|
+
*/
|
|
56
|
+
export function explainGateFailure(
|
|
57
|
+
report: UsageProfileReport,
|
|
58
|
+
levers: BillLevers,
|
|
59
|
+
overUsd: number,
|
|
60
|
+
): GateExplanation {
|
|
61
|
+
const biggest = report.byLabelAndModel[0] ?? null;
|
|
62
|
+
const lever = levers.slices.length > 0 ? levers.slices[0]! : null;
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
overageUsd: overUsd,
|
|
66
|
+
largest:
|
|
67
|
+
biggest === null
|
|
68
|
+
? null
|
|
69
|
+
: {
|
|
70
|
+
label: biggest.label,
|
|
71
|
+
model: biggest.model,
|
|
72
|
+
usd: biggest.breakdown.totalUsd,
|
|
73
|
+
share:
|
|
74
|
+
report.total.totalUsd > 0
|
|
75
|
+
? biggest.breakdown.totalUsd / report.total.totalUsd
|
|
76
|
+
: 0,
|
|
77
|
+
},
|
|
78
|
+
lever,
|
|
79
|
+
coversIt: lever !== null && lever.combinedUsd >= overUsd,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* How much room a passing gate had left, as a fraction of the limit.
|
|
85
|
+
*
|
|
86
|
+
* A pass 2% under budget and a pass 60% under are different states of the
|
|
87
|
+
* world, and only one of them is quiet news. Returned as a fraction so every
|
|
88
|
+
* surface applies the same threshold to it rather than inventing one.
|
|
89
|
+
*
|
|
90
|
+
* `null` when the limit is zero — a budget of nothing has no margin to be a
|
|
91
|
+
* fraction of, and dividing would produce an Infinity that reads like an
|
|
92
|
+
* answer.
|
|
93
|
+
*/
|
|
94
|
+
export function gateMargin(judgedUsd: number, limitUsd: number): number | null {
|
|
95
|
+
if (limitUsd <= 0) return null;
|
|
96
|
+
return (limitUsd - judgedUsd) / limitUsd;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* The threshold under which a pass is worth saying out loud, stated here and
|
|
101
|
+
* repeated in every rendering's copy.
|
|
102
|
+
*
|
|
103
|
+
* A tenth of the budget is close enough that the next ordinary week crosses
|
|
104
|
+
* it. Wider than that and the pass is genuinely quiet news, which is what a
|
|
105
|
+
* gate passing should usually be.
|
|
106
|
+
*/
|
|
107
|
+
export const GATE_MARGIN_TIGHT = 0.1;
|
package/src/index.ts
CHANGED
|
@@ -41,6 +41,8 @@ export type { ProfileCsvOptions, ProfileCsvShape } from './csv.js';
|
|
|
41
41
|
export { driversBetween } from './against.js';
|
|
42
42
|
export type { AgainstDriver } from './against.js';
|
|
43
43
|
export { coverageDrift, COVERAGE_FIELDS, COVERAGE_DRIFT_MIN } from './coverage-drift.js';
|
|
44
|
+
export { explainGateFailure, gateMargin, GATE_MARGIN_TIGHT } from './gate-explain.js';
|
|
45
|
+
export type { GateExplanation } from './gate-explain.js';
|
|
44
46
|
export type { CoverageDrift, CoverageField } from './coverage-drift.js';
|
|
45
47
|
// The same tokens at another model's rates — arithmetic, not advice, and it
|
|
46
48
|
// refuses to price a call the target could not have accepted. See reprice.ts.
|
package/src/reprice.ts
CHANGED
|
@@ -74,6 +74,23 @@ export interface RepricedSlice {
|
|
|
74
74
|
deltaUsd: number;
|
|
75
75
|
/** The slice's largest single call, cache reads and writes included. */
|
|
76
76
|
maxCallInputTokens: number;
|
|
77
|
+
/**
|
|
78
|
+
* Present when the slice's cache traffic could not exist on the target.
|
|
79
|
+
*
|
|
80
|
+
* A cache entry only forms above the model's minimum prompt size, and when
|
|
81
|
+
* even this slice's largest call sits under the target's minimum, none of
|
|
82
|
+
* its calls could create one — so `targetUsd`, which grants the cache
|
|
83
|
+
* traffic the target's discounted rates, is priced on entries the target
|
|
84
|
+
* would refuse to create. That error flatters the move, which is exactly
|
|
85
|
+
* the direction this repository refuses. `noCacheUsd` is the same tokens
|
|
86
|
+
* with every cache token at the full input rate: the figure the target
|
|
87
|
+
* would actually bill if the entries cannot form. The truth sits at
|
|
88
|
+
* `noCacheUsd` (no entries) — not between the two by interpolation.
|
|
89
|
+
*
|
|
90
|
+
* Null when the slice has no cache traffic, or when its calls clear the
|
|
91
|
+
* target's minimum — where the standard figure stands unqualified.
|
|
92
|
+
*/
|
|
93
|
+
cacheBeyondTarget: { minTokens: number; noCacheUsd: number } | null;
|
|
77
94
|
}
|
|
78
95
|
|
|
79
96
|
/** A slice holding a call the target model could not have accepted. */
|
|
@@ -122,6 +139,23 @@ export interface RepriceReport {
|
|
|
122
139
|
*/
|
|
123
140
|
unpricedModels: string[];
|
|
124
141
|
unpricedCalls: number;
|
|
142
|
+
/**
|
|
143
|
+
* The moved bill with the target's Batch API on top, over the same movable
|
|
144
|
+
* slices — or null when the target sells no batch discount, which is a
|
|
145
|
+
* different statement from a $0 saving.
|
|
146
|
+
*
|
|
147
|
+
* The other half of "priced whole": routing and batching combine by
|
|
148
|
+
* discounting the *target's* rates, not by adding two savings — the same
|
|
149
|
+
* never-summed rule the levers learned when $12.60 plus $10.50 exceeded
|
|
150
|
+
* the $21.00 slice they came from. The discount covers input and output,
|
|
151
|
+
* cache traffic priced unchanged, matching the levers' convention exactly
|
|
152
|
+
* so the two surfaces cannot disagree about what batching is worth.
|
|
153
|
+
*
|
|
154
|
+
* Whether these calls can wait for a batch window is not knowable from a
|
|
155
|
+
* log, and nothing here claims it — the field is arithmetic, the decision
|
|
156
|
+
* is the reader's.
|
|
157
|
+
*/
|
|
158
|
+
batchOnTarget: { targetUsd: number } | null;
|
|
125
159
|
/** Always true. A field, not a comment, so a rendering can print it. */
|
|
126
160
|
sameTokensAssumed: true;
|
|
127
161
|
}
|
|
@@ -194,6 +228,38 @@ export function repriceProfile(
|
|
|
194
228
|
}
|
|
195
229
|
const targetUsd = priceTokensOn(breakdown, target, on);
|
|
196
230
|
assumedWriteTtlCalls += breakdown.assumedWriteTtlCalls;
|
|
231
|
+
/**
|
|
232
|
+
* Cache traffic the target could not grant. The comparison is against the
|
|
233
|
+
* slice's *largest* call: if even that one sits under the target's cache
|
|
234
|
+
* minimum, no call in the slice could create an entry, and that is a fact
|
|
235
|
+
* rather than a guess. A slice whose largest call clears the minimum may
|
|
236
|
+
* still hold smaller calls that do not — undecidable per call from an
|
|
237
|
+
* aggregate, so nothing is claimed there.
|
|
238
|
+
*/
|
|
239
|
+
const cacheTokens =
|
|
240
|
+
breakdown.cacheReadTokens + breakdown.cacheWrite5mTokens + breakdown.cacheWrite1hTokens;
|
|
241
|
+
// A null minimum is an *unknown* one — overlay-added models leave it null
|
|
242
|
+
// rather than invent a number — and nothing can be claimed against a
|
|
243
|
+
// threshold nobody stated. Unqualified is the only honest rendering there.
|
|
244
|
+
const cacheBeyondTarget =
|
|
245
|
+
cacheTokens > 0 &&
|
|
246
|
+
target.cacheMinTokens !== null &&
|
|
247
|
+
breakdown.maxCallInputTokens < target.cacheMinTokens
|
|
248
|
+
? {
|
|
249
|
+
minTokens: target.cacheMinTokens,
|
|
250
|
+
noCacheUsd: priceTokensOn(
|
|
251
|
+
{
|
|
252
|
+
inputTokens: breakdown.inputTokens + cacheTokens,
|
|
253
|
+
cacheReadTokens: 0,
|
|
254
|
+
cacheWrite5mTokens: 0,
|
|
255
|
+
cacheWrite1hTokens: 0,
|
|
256
|
+
outputTokens: breakdown.outputTokens,
|
|
257
|
+
},
|
|
258
|
+
target,
|
|
259
|
+
on,
|
|
260
|
+
),
|
|
261
|
+
}
|
|
262
|
+
: null;
|
|
197
263
|
slices.push({
|
|
198
264
|
label: slice.label,
|
|
199
265
|
model: slice.model,
|
|
@@ -202,6 +268,7 @@ export function repriceProfile(
|
|
|
202
268
|
targetUsd,
|
|
203
269
|
deltaUsd: targetUsd - breakdown.totalUsd,
|
|
204
270
|
maxCallInputTokens: breakdown.maxCallInputTokens,
|
|
271
|
+
cacheBeyondTarget,
|
|
205
272
|
});
|
|
206
273
|
}
|
|
207
274
|
|
|
@@ -211,6 +278,29 @@ export function repriceProfile(
|
|
|
211
278
|
const currentUsd = slices.reduce((sum, s) => sum + s.currentUsd, 0);
|
|
212
279
|
const targetUsd = slices.reduce((sum, s) => sum + s.targetUsd, 0);
|
|
213
280
|
|
|
281
|
+
/**
|
|
282
|
+
* The same movable tokens, batched on the target. Computed from the token
|
|
283
|
+
* aggregates rather than by discounting `targetUsd`, because the discount
|
|
284
|
+
* covers input and output while cache traffic rides through unchanged.
|
|
285
|
+
*/
|
|
286
|
+
const batchRate = multipliersFor(target).batch;
|
|
287
|
+
let batchOnTarget: { targetUsd: number } | null = null;
|
|
288
|
+
if (batchRate !== null && batchRate < 1 && slices.length > 0) {
|
|
289
|
+
const { inputPerMTok, outputPerMTok } = effectivePricing(target, on);
|
|
290
|
+
const movable = report.byLabelAndModel.filter(
|
|
291
|
+
(slice) =>
|
|
292
|
+
slice.model !== target.id && slice.breakdown.maxCallInputTokens <= target.contextWindow,
|
|
293
|
+
);
|
|
294
|
+
const inOutUsd = movable.reduce(
|
|
295
|
+
(sum, slice) =>
|
|
296
|
+
sum +
|
|
297
|
+
(slice.breakdown.inputTokens / 1_000_000) * inputPerMTok +
|
|
298
|
+
(slice.breakdown.outputTokens / 1_000_000) * outputPerMTok,
|
|
299
|
+
0,
|
|
300
|
+
);
|
|
301
|
+
batchOnTarget = { targetUsd: targetUsd - inOutUsd * (1 - batchRate) };
|
|
302
|
+
}
|
|
303
|
+
|
|
214
304
|
return {
|
|
215
305
|
target: { id: target.id, displayName: target.displayName, contextWindow: target.contextWindow },
|
|
216
306
|
slices,
|
|
@@ -222,6 +312,7 @@ export function repriceProfile(
|
|
|
222
312
|
assumedWriteTtlCalls,
|
|
223
313
|
unpricedModels: report.unpricedModels,
|
|
224
314
|
unpricedCalls: report.unpriced.calls,
|
|
315
|
+
batchOnTarget,
|
|
225
316
|
sameTokensAssumed: true,
|
|
226
317
|
};
|
|
227
318
|
}
|