@trazum/core 1.64.0 → 1.66.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/config-schema.d.ts +32 -1
- package/dist/config-schema.d.ts.map +1 -1
- package/dist/config-schema.js +55 -3
- package/dist/config-schema.js.map +1 -1
- package/dist/conform.d.ts +8 -1
- package/dist/conform.d.ts.map +1 -1
- package/dist/conform.js +82 -0
- package/dist/conform.js.map +1 -1
- package/dist/gateway.d.ts +32 -1
- package/dist/gateway.d.ts.map +1 -1
- package/dist/gateway.js +64 -3
- package/dist/gateway.js.map +1 -1
- package/dist/guard.d.ts +20 -0
- package/dist/guard.d.ts.map +1 -1
- package/dist/guard.js +41 -3
- package/dist/guard.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/judgement.d.ts +159 -0
- package/dist/judgement.d.ts.map +1 -0
- package/dist/judgement.js +188 -0
- package/dist/judgement.js.map +1 -0
- package/dist/position.d.ts +74 -0
- package/dist/position.d.ts.map +1 -0
- package/dist/position.js +93 -0
- package/dist/position.js.map +1 -0
- package/dist/schemas.d.ts +13 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +144 -0
- package/dist/schemas.js.map +1 -0
- package/dist/session-cost.d.ts +2 -0
- package/dist/session-cost.d.ts.map +1 -1
- package/dist/session-cost.js +1 -1
- package/dist/session-cost.js.map +1 -1
- package/package.json +1 -1
- package/src/config-schema.ts +89 -3
- package/src/conform.ts +79 -0
- package/src/gateway.ts +108 -4
- package/src/guard.ts +73 -3
- package/src/index.ts +18 -2
- package/src/judgement.ts +346 -0
- package/src/position.ts +126 -0
- package/src/schemas.ts +150 -0
- package/src/session-cost.ts +1 -1
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One policy, judged once — the function every door calls.
|
|
3
|
+
*
|
|
4
|
+
* The `limits` block states the policy: per-day, per-session and per-label
|
|
5
|
+
* USD ceilings. This module answers whether a proposed call fits it, and the
|
|
6
|
+
* design constraint is the 1.62 arc's lesson: **two doors to the same value
|
|
7
|
+
* agreeing by coincidence is a defect waiting for its input.** So the doors
|
|
8
|
+
* — the gateway's 402, `serve`'s cost answer, `spend_guard` over MCP — do
|
|
9
|
+
* not each read a slice of config and do their own arithmetic. They hand
|
|
10
|
+
* this function the policy, the measured position and the call, and forward
|
|
11
|
+
* its answer.
|
|
12
|
+
*
|
|
13
|
+
* Nothing here re-derives the single-ceiling semantics either. Each ceiling
|
|
14
|
+
* is judged by `answerCost`, the function that has answered "does this call
|
|
15
|
+
* fit this budget" for every door since 1.44 — including its refusals: a
|
|
16
|
+
* negative token count is rejected before it can become money, an unpriced
|
|
17
|
+
* model is a cannot-tell rather than a guess, and a verdict always names
|
|
18
|
+
* whether it rests on a measurement alone or needed the estimate. A policy
|
|
19
|
+
* judgement is those answers, one per applicable ceiling, under one verdict.
|
|
20
|
+
*
|
|
21
|
+
* Two refusals are this module's own, and both close the same loophole: a
|
|
22
|
+
* policy with per-label ceilings judging a call that names no label, or a
|
|
23
|
+
* per-session ceiling judging a call that names no session, is `cannot-tell`
|
|
24
|
+
* — not "no ceiling applies". A call that omits its label does not slip past
|
|
25
|
+
* the label's ceiling; it becomes unjudgeable, and the answer says why.
|
|
26
|
+
*/
|
|
27
|
+
import { answerCost } from './answer.js';
|
|
28
|
+
import { formatUsd } from './savings.js';
|
|
29
|
+
const judgementOf = (scope, label, limitUsd, answer) => ({
|
|
30
|
+
scope,
|
|
31
|
+
label,
|
|
32
|
+
limitUsd,
|
|
33
|
+
verdict: answer.verdict,
|
|
34
|
+
restsOn: answer.restsOn,
|
|
35
|
+
// The single-ceiling reasons map one-to-one; the two call-shape refusals
|
|
36
|
+
// (`no-label-on-call`, `no-session-on-call`) never reach answerCost.
|
|
37
|
+
reason: answer.reason === null ? null : answer.reason === 'model-unpriced' ? 'model-unpriced' : 'nothing-measured',
|
|
38
|
+
measuredUsd: answer.budget?.consumedUsd ?? null,
|
|
39
|
+
window: answer.budget?.window ?? null,
|
|
40
|
+
afterCallUsd: answer.afterCall?.usd ?? null,
|
|
41
|
+
waived: null,
|
|
42
|
+
});
|
|
43
|
+
const unjudgeable = (scope, label, limitUsd, reason) => ({
|
|
44
|
+
scope,
|
|
45
|
+
label,
|
|
46
|
+
limitUsd,
|
|
47
|
+
verdict: 'cannot-tell',
|
|
48
|
+
restsOn: null,
|
|
49
|
+
reason,
|
|
50
|
+
measuredUsd: null,
|
|
51
|
+
window: null,
|
|
52
|
+
afterCallUsd: null,
|
|
53
|
+
waived: null,
|
|
54
|
+
});
|
|
55
|
+
/** The waiver gate that names one judgement's ceiling. */
|
|
56
|
+
const gateOf = (judgement) => judgement.scope === 'day'
|
|
57
|
+
? 'limits.dayUsd'
|
|
58
|
+
: judgement.scope === 'session'
|
|
59
|
+
? 'limits.sessionUsd'
|
|
60
|
+
: `limits.byLabel:${judgement.label ?? ''}`;
|
|
61
|
+
/**
|
|
62
|
+
* The unexpired waiver for one judgement, if the config carries one.
|
|
63
|
+
*
|
|
64
|
+
* Judged in UTC at run time, the same rule `check` applies: the day the
|
|
65
|
+
* waiver expires, the ceiling refuses again — nobody has to remember.
|
|
66
|
+
*/
|
|
67
|
+
const waiverFor = (judgement, waivers, on) => {
|
|
68
|
+
const today = on.toISOString().slice(0, 10);
|
|
69
|
+
const match = waivers.find((entry) => entry.gate === gateOf(judgement) && entry.until >= today);
|
|
70
|
+
return match === undefined ? null : { reason: match.reason, until: match.until };
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Judges a proposed call against the whole `limits` policy.
|
|
74
|
+
*
|
|
75
|
+
* Pure and synchronous for the same reason `answerCost` is: this runs inside
|
|
76
|
+
* a request that has not been sent yet, and a function that reads a file
|
|
77
|
+
* cannot promise single-digit milliseconds. The caller measures; this judges.
|
|
78
|
+
*/
|
|
79
|
+
export function judgeLimits(policy, position, call, options) {
|
|
80
|
+
const judgements = [];
|
|
81
|
+
const judge = (consumedUsd, limitUsd, window) => answerCost({
|
|
82
|
+
model: call.model,
|
|
83
|
+
inputTokens: call.inputTokens,
|
|
84
|
+
outputTokens: call.outputTokens,
|
|
85
|
+
basis: call.basis,
|
|
86
|
+
limitUsd,
|
|
87
|
+
consumedUsd: consumedUsd ?? undefined,
|
|
88
|
+
window,
|
|
89
|
+
}, options);
|
|
90
|
+
if (policy?.dayUsd !== undefined) {
|
|
91
|
+
judgements.push(judgementOf('day', null, policy.dayUsd, judge(position.dayUsd, policy.dayUsd, position.dayWindow ?? null)));
|
|
92
|
+
}
|
|
93
|
+
if (policy?.sessionUsd !== undefined) {
|
|
94
|
+
judgements.push(call.session === undefined
|
|
95
|
+
? unjudgeable('session', null, policy.sessionUsd, 'no-session-on-call')
|
|
96
|
+
: judgementOf('session', null, policy.sessionUsd, judge(position.sessionUsd, policy.sessionUsd, position.sessionWindow ?? null)));
|
|
97
|
+
}
|
|
98
|
+
if (policy?.byLabel !== undefined && Object.keys(policy.byLabel).length > 0) {
|
|
99
|
+
if (call.label === undefined) {
|
|
100
|
+
/*
|
|
101
|
+
The loophole this closes: per-label ceilings with an unlabelled call.
|
|
102
|
+
Skipping the scope would mean the ceiling only binds calls polite
|
|
103
|
+
enough to name themselves — the same defect as the negative token
|
|
104
|
+
count, worn as an omission. One judgement, no label, cannot-tell.
|
|
105
|
+
The ceiling reported is the smallest, because that is the one the
|
|
106
|
+
call might be dodging.
|
|
107
|
+
*/
|
|
108
|
+
const smallest = Math.min(...Object.values(policy.byLabel));
|
|
109
|
+
judgements.push(unjudgeable('label', null, smallest, 'no-label-on-call'));
|
|
110
|
+
}
|
|
111
|
+
else if (policy.byLabel[call.label] !== undefined) {
|
|
112
|
+
const limitUsd = policy.byLabel[call.label];
|
|
113
|
+
judgements.push(judgementOf('label', call.label, limitUsd, judge(position.labelUsd, limitUsd, position.labelWindow ?? null)));
|
|
114
|
+
}
|
|
115
|
+
// A labelled call whose label has no ceiling is judged by the other
|
|
116
|
+
// scopes alone: the policy said nothing about this label, and inventing
|
|
117
|
+
// a ceiling for it would be enforcing config nobody wrote.
|
|
118
|
+
}
|
|
119
|
+
if (judgements.length === 0) {
|
|
120
|
+
return { schemaVersion: 1, verdict: 'cannot-tell', reason: 'no-policy', judgements: [] };
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Waivers, applied after every ceiling is judged: the measurement stays —
|
|
124
|
+
* a waived judgement still says `over` — but the silence is attached, on
|
|
125
|
+
* the record, and the verdict below treats a waived `over` as not-refusing.
|
|
126
|
+
*/
|
|
127
|
+
const { on = new Date(), waivers = [] } = options;
|
|
128
|
+
if (waivers.length > 0) {
|
|
129
|
+
for (const judgement of judgements) {
|
|
130
|
+
if (judgement.verdict === 'over')
|
|
131
|
+
judgement.waived = waiverFor(judgement, waivers, on);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const verdict = judgements.some((entry) => entry.verdict === 'over' && entry.waived === null)
|
|
135
|
+
? 'over'
|
|
136
|
+
: judgements.some((entry) => entry.verdict === 'cannot-tell')
|
|
137
|
+
? 'cannot-tell'
|
|
138
|
+
: 'within';
|
|
139
|
+
return { schemaVersion: 1, verdict, reason: null, judgements };
|
|
140
|
+
}
|
|
141
|
+
/** The scope, as a refusal names it. Labels print; session identifiers never do. */
|
|
142
|
+
export function limitScopeName(judgement) {
|
|
143
|
+
return judgement.scope === 'day'
|
|
144
|
+
? "the day's ceiling"
|
|
145
|
+
: judgement.scope === 'session'
|
|
146
|
+
? "this session's ceiling"
|
|
147
|
+
: judgement.label === null
|
|
148
|
+
? 'the per-label ceiling'
|
|
149
|
+
: `the "${judgement.label}" label's ceiling`;
|
|
150
|
+
}
|
|
151
|
+
/** The period a measured figure covers, when the judgement carries one. */
|
|
152
|
+
function periodOf(judgement) {
|
|
153
|
+
if (judgement.window === null)
|
|
154
|
+
return '';
|
|
155
|
+
const from = new Date(judgement.window.fromMs).toISOString();
|
|
156
|
+
const to = new Date(judgement.window.toMs).toISOString();
|
|
157
|
+
return ` between ${from} and ${to}`;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The refusal, legible — chapter four's rule, written once.
|
|
161
|
+
*
|
|
162
|
+
* Every over-limit sentence names the limit, the measured position and the
|
|
163
|
+
* period, so an agent can log it and a person can audit it without
|
|
164
|
+
* re-running anything. Every door uses this builder rather than composing
|
|
165
|
+
* its own, for the same reason every door uses the same judge.
|
|
166
|
+
*/
|
|
167
|
+
export function limitSentence(judgement) {
|
|
168
|
+
const limit = formatUsd(judgement.limitUsd);
|
|
169
|
+
const measured = judgement.measuredUsd === null ? 'nothing measured' : `${formatUsd(judgement.measuredUsd)} measured`;
|
|
170
|
+
return judgement.restsOn === 'measured'
|
|
171
|
+
? `${capital(limitScopeName(judgement))} of ${limit} is already spent: ${measured}${periodOf(judgement)}.`
|
|
172
|
+
: `This call would take ${limitScopeName(judgement)} of ${limit} past its limit: ${measured}${periodOf(judgement)}, plus this call's estimate.`;
|
|
173
|
+
}
|
|
174
|
+
/** Why the policy could not be judged, in one auditable sentence. */
|
|
175
|
+
export function unjudgedSentence(judged) {
|
|
176
|
+
const first = judged.judgements.find((entry) => entry.verdict === 'cannot-tell');
|
|
177
|
+
const which = first === undefined ? 'a ceiling' : limitScopeName(first);
|
|
178
|
+
const why = first?.reason === 'no-label-on-call'
|
|
179
|
+
? 'the call names no label'
|
|
180
|
+
: first?.reason === 'no-session-on-call'
|
|
181
|
+
? 'the call names no session'
|
|
182
|
+
: first?.reason === 'model-unpriced'
|
|
183
|
+
? 'the model is not in the price catalogue'
|
|
184
|
+
: 'its spend has not been measured';
|
|
185
|
+
return `${capital(which)} in the limits policy cannot be judged: ${why}.`;
|
|
186
|
+
}
|
|
187
|
+
const capital = (text) => `${text[0].toUpperCase()}${text.slice(1)}`;
|
|
188
|
+
//# sourceMappingURL=judgement.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"judgement.js","sourceRoot":"","sources":["../src/judgement.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The measured side of the limits policy: what a usage log says each scope
|
|
3
|
+
* has already spent.
|
|
4
|
+
*
|
|
5
|
+
* `judgeLimits` judges; this measures. The split is the product's oldest
|
|
6
|
+
* rule — the judging function must be pure and instant, so whatever reads
|
|
7
|
+
* and prices records happens once, here, and the doors keep the result.
|
|
8
|
+
*
|
|
9
|
+
* **Absence is `null`, never zero.** A log with no clock cannot say what
|
|
10
|
+
* today has cost; a log that records no sessions cannot say what a session
|
|
11
|
+
* has spent. Both come back `null`, and `judgeLimits` turns a `null` into
|
|
12
|
+
* `cannot-tell` rather than an approval. The one deliberate asymmetry: a log
|
|
13
|
+
* that *does* record sessions and has never seen this one answers `0` — the
|
|
14
|
+
* history of a conversation that has not started is complete and empty,
|
|
15
|
+
* which is a measurement, not an absence.
|
|
16
|
+
*
|
|
17
|
+
* **Session keys never leave this module.** The index groups by them — that
|
|
18
|
+
* is the whole job — but the map lives in door memory, `positionAt` returns
|
|
19
|
+
* only dollar figures, and nothing here is serialised. The guarantee the
|
|
20
|
+
* usage module states (a session key is somebody's conversation and is never
|
|
21
|
+
* printed) holds through this door too.
|
|
22
|
+
*/
|
|
23
|
+
import type { UsageRecord } from './usage.js';
|
|
24
|
+
import type { PricingCatalogue } from './pricing.js';
|
|
25
|
+
import type { MeasuredPosition } from './judgement.js';
|
|
26
|
+
/**
|
|
27
|
+
* Everything a door needs to answer `positionAt` in constant time, built
|
|
28
|
+
* once from the log it was pointed at.
|
|
29
|
+
*/
|
|
30
|
+
export interface MeasuredIndex {
|
|
31
|
+
/** Spend inside the current UTC day. Null when no record carries a clock. */
|
|
32
|
+
dayUsd: number | null;
|
|
33
|
+
/** The UTC day the figure covers. Null exactly when `dayUsd` is. */
|
|
34
|
+
dayWindow: {
|
|
35
|
+
fromMs: number;
|
|
36
|
+
toMs: number;
|
|
37
|
+
} | null;
|
|
38
|
+
/** Whether any record carried a label / a session at all. */
|
|
39
|
+
labelsSeen: boolean;
|
|
40
|
+
sessionsSeen: boolean;
|
|
41
|
+
/** Priced spend per label. Keys are labels, which do print. */
|
|
42
|
+
labels: ReadonlyMap<string, number>;
|
|
43
|
+
/** Priced spend per session. Keys are session identifiers — never printed. */
|
|
44
|
+
sessions: ReadonlyMap<string, number>;
|
|
45
|
+
/** Whether the log held any records at all. */
|
|
46
|
+
any: boolean;
|
|
47
|
+
/** Records whose model the catalogue cannot price — money nobody can see. */
|
|
48
|
+
unpriced: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Prices and groups a parsed usage log, once.
|
|
52
|
+
*
|
|
53
|
+
* An unpriced record contributes nothing to any figure and is **counted**
|
|
54
|
+
* instead of dropped silently: a door that reports "measured $3" over a log
|
|
55
|
+
* with a thousand unpriced records is wrong by an amount nobody can see, in
|
|
56
|
+
* the flattering direction, and `unpriced` is how the door says so.
|
|
57
|
+
*/
|
|
58
|
+
export declare function indexUsage(records: readonly UsageRecord[], options: {
|
|
59
|
+
catalogue: PricingCatalogue;
|
|
60
|
+
on?: Date;
|
|
61
|
+
}): MeasuredIndex;
|
|
62
|
+
/**
|
|
63
|
+
* The measured position for one proposed call, from an index built once.
|
|
64
|
+
*
|
|
65
|
+
* A scope the log cannot see is `null`; a scope it can see and has nothing
|
|
66
|
+
* recorded for is `0`. The difference is the difference between "unknown"
|
|
67
|
+
* and "a conversation that has not started yet", and collapsing them is how
|
|
68
|
+
* a dead log approves a live spend.
|
|
69
|
+
*/
|
|
70
|
+
export declare function positionAt(index: MeasuredIndex, call: {
|
|
71
|
+
label?: string;
|
|
72
|
+
session?: string;
|
|
73
|
+
}): MeasuredPosition;
|
|
74
|
+
//# sourceMappingURL=position.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIvD;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,oEAAoE;IACpE,SAAS,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACnD,6DAA6D;IAC7D,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,+DAA+D;IAC/D,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,8EAA8E;IAC9E,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,+CAA+C;IAC/C,GAAG,EAAE,OAAO,CAAC;IACb,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,OAAO,EAAE;IAAE,SAAS,EAAE,gBAAgB,CAAC;IAAC,EAAE,CAAC,EAAE,IAAI,CAAA;CAAE,GAClD,aAAa,CAsCf;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GACzC,gBAAgB,CAWlB"}
|
package/dist/position.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The measured side of the limits policy: what a usage log says each scope
|
|
3
|
+
* has already spent.
|
|
4
|
+
*
|
|
5
|
+
* `judgeLimits` judges; this measures. The split is the product's oldest
|
|
6
|
+
* rule — the judging function must be pure and instant, so whatever reads
|
|
7
|
+
* and prices records happens once, here, and the doors keep the result.
|
|
8
|
+
*
|
|
9
|
+
* **Absence is `null`, never zero.** A log with no clock cannot say what
|
|
10
|
+
* today has cost; a log that records no sessions cannot say what a session
|
|
11
|
+
* has spent. Both come back `null`, and `judgeLimits` turns a `null` into
|
|
12
|
+
* `cannot-tell` rather than an approval. The one deliberate asymmetry: a log
|
|
13
|
+
* that *does* record sessions and has never seen this one answers `0` — the
|
|
14
|
+
* history of a conversation that has not started is complete and empty,
|
|
15
|
+
* which is a measurement, not an absence.
|
|
16
|
+
*
|
|
17
|
+
* **Session keys never leave this module.** The index groups by them — that
|
|
18
|
+
* is the whole job — but the map lives in door memory, `positionAt` returns
|
|
19
|
+
* only dollar figures, and nothing here is serialised. The guarantee the
|
|
20
|
+
* usage module states (a session key is somebody's conversation and is never
|
|
21
|
+
* printed) holds through this door too.
|
|
22
|
+
*/
|
|
23
|
+
import { costOf } from './session-cost.js';
|
|
24
|
+
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
25
|
+
/**
|
|
26
|
+
* Prices and groups a parsed usage log, once.
|
|
27
|
+
*
|
|
28
|
+
* An unpriced record contributes nothing to any figure and is **counted**
|
|
29
|
+
* instead of dropped silently: a door that reports "measured $3" over a log
|
|
30
|
+
* with a thousand unpriced records is wrong by an amount nobody can see, in
|
|
31
|
+
* the flattering direction, and `unpriced` is how the door says so.
|
|
32
|
+
*/
|
|
33
|
+
export function indexUsage(records, options) {
|
|
34
|
+
const { catalogue, on = new Date() } = options;
|
|
35
|
+
const dayFromMs = Math.floor(on.getTime() / DAY_MS) * DAY_MS;
|
|
36
|
+
const dayToMs = dayFromMs + DAY_MS;
|
|
37
|
+
const labels = new Map();
|
|
38
|
+
const sessions = new Map();
|
|
39
|
+
let labelsSeen = false;
|
|
40
|
+
let sessionsSeen = false;
|
|
41
|
+
let clocksSeen = false;
|
|
42
|
+
let dayUsd = 0;
|
|
43
|
+
let unpriced = 0;
|
|
44
|
+
for (const record of records) {
|
|
45
|
+
if (record.label !== null)
|
|
46
|
+
labelsSeen = true;
|
|
47
|
+
if (record.session !== null)
|
|
48
|
+
sessionsSeen = true;
|
|
49
|
+
if (record.ts !== null)
|
|
50
|
+
clocksSeen = true;
|
|
51
|
+
const usd = costOf(record, catalogue, on);
|
|
52
|
+
if (usd === null) {
|
|
53
|
+
unpriced += 1;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (record.label !== null)
|
|
57
|
+
labels.set(record.label, (labels.get(record.label) ?? 0) + usd);
|
|
58
|
+
if (record.session !== null)
|
|
59
|
+
sessions.set(record.session, (sessions.get(record.session) ?? 0) + usd);
|
|
60
|
+
if (record.ts !== null && record.ts >= dayFromMs && record.ts < dayToMs)
|
|
61
|
+
dayUsd += usd;
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
dayUsd: clocksSeen ? dayUsd : null,
|
|
65
|
+
dayWindow: clocksSeen ? { fromMs: dayFromMs, toMs: dayToMs } : null,
|
|
66
|
+
labelsSeen,
|
|
67
|
+
sessionsSeen,
|
|
68
|
+
labels,
|
|
69
|
+
sessions,
|
|
70
|
+
any: records.length > 0,
|
|
71
|
+
unpriced,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The measured position for one proposed call, from an index built once.
|
|
76
|
+
*
|
|
77
|
+
* A scope the log cannot see is `null`; a scope it can see and has nothing
|
|
78
|
+
* recorded for is `0`. The difference is the difference between "unknown"
|
|
79
|
+
* and "a conversation that has not started yet", and collapsing them is how
|
|
80
|
+
* a dead log approves a live spend.
|
|
81
|
+
*/
|
|
82
|
+
export function positionAt(index, call) {
|
|
83
|
+
if (!index.any) {
|
|
84
|
+
return { dayUsd: null, sessionUsd: null, labelUsd: null };
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
dayUsd: index.dayUsd,
|
|
88
|
+
dayWindow: index.dayWindow,
|
|
89
|
+
sessionUsd: call.session !== undefined && index.sessionsSeen ? (index.sessions.get(call.session) ?? 0) : null,
|
|
90
|
+
labelUsd: call.label !== undefined && index.labelsSeen ? (index.labels.get(call.label) ?? 0) : null,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=position.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"position.js","sourceRoot":"","sources":["../src/position.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ContractName } from './conform.js';
|
|
2
|
+
/**
|
|
3
|
+
* One schema per contract, keyed by the exact names `--contract` accepts.
|
|
4
|
+
*
|
|
5
|
+
* The usage log is the one non-document contract: its schema describes **one
|
|
6
|
+
* record** — one line of the log — because a `.jsonl` file is not itself a
|
|
7
|
+
* JSON value and no JSON Schema can describe a file of lines. Validators run
|
|
8
|
+
* per line, which is how the log is read everywhere else too.
|
|
9
|
+
*/
|
|
10
|
+
export declare const CONTRACT_SCHEMAS: Record<ContractName, Record<string, unknown>>;
|
|
11
|
+
/** The schema for one named contract — the object `trazum schema` prints. */
|
|
12
|
+
export declare function contractSchema(name: ContractName): Record<string, unknown>;
|
|
13
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AA6CjD;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA2F1E,CAAC;AAEF,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAE1E"}
|
package/dist/schemas.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A JSON Schema for every contract, so a document can be checked with **no
|
|
3
|
+
* Trazum at all** — any off-the-shelf draft 2020-12 validator will do.
|
|
4
|
+
*
|
|
5
|
+
* Authored, not generated: `conform`'s rules live as functions and a schema
|
|
6
|
+
* generated from closures would be a guess wearing a standard. What keeps the
|
|
7
|
+
* two doors honest instead is the guard in the suite: every fixture `conform`
|
|
8
|
+
* accepts must validate against its schema, and every fixture `conform`
|
|
9
|
+
* rejects for a structural reason must fail it — a schema that drifts from
|
|
10
|
+
* `conform` is the two-doors defect wearing a file format.
|
|
11
|
+
*
|
|
12
|
+
* The schemas state **required fields and their types, and stop there** —
|
|
13
|
+
* the same line `conform` holds. `additionalProperties` is never `false`:
|
|
14
|
+
* these documents gain fields without a version bump, and a schema that
|
|
15
|
+
* rejected tomorrow's field would be a schema nobody upgrades. Field prose
|
|
16
|
+
* lives in `docs/json-output.md`; the schema carries structure.
|
|
17
|
+
*/
|
|
18
|
+
const DRAFT = 'https://json-schema.org/draft/2020-12/schema';
|
|
19
|
+
/** Shorthand: an object schema over required properties. */
|
|
20
|
+
function doc(name, properties) {
|
|
21
|
+
return {
|
|
22
|
+
$schema: DRAFT,
|
|
23
|
+
$id: `https://github.com/Davmunrey/Trazum/schema/${name}/v1.json`,
|
|
24
|
+
title: `trazum ${name} document, schemaVersion 1`,
|
|
25
|
+
type: 'object',
|
|
26
|
+
required: ['schemaVersion', ...Object.keys(properties)],
|
|
27
|
+
properties: {
|
|
28
|
+
schemaVersion: { const: 1 },
|
|
29
|
+
...properties,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const array = { type: 'array' };
|
|
34
|
+
const object = { type: 'object' };
|
|
35
|
+
const number = { type: 'number' };
|
|
36
|
+
const string = { type: 'string' };
|
|
37
|
+
const boolean = { type: 'boolean' };
|
|
38
|
+
const objectOrNull = { type: ['object', 'null'] };
|
|
39
|
+
const stringOrNull = { type: ['string', 'null'] };
|
|
40
|
+
/**
|
|
41
|
+
* One schema per contract, keyed by the exact names `--contract` accepts.
|
|
42
|
+
*
|
|
43
|
+
* The usage log is the one non-document contract: its schema describes **one
|
|
44
|
+
* record** — one line of the log — because a `.jsonl` file is not itself a
|
|
45
|
+
* JSON value and no JSON Schema can describe a file of lines. Validators run
|
|
46
|
+
* per line, which is how the log is read everywhere else too.
|
|
47
|
+
*/
|
|
48
|
+
export const CONTRACT_SCHEMAS = {
|
|
49
|
+
'usage-log': {
|
|
50
|
+
$schema: DRAFT,
|
|
51
|
+
$id: 'https://github.com/Davmunrey/Trazum/schema/usage-log/v1.json',
|
|
52
|
+
title: 'trazum usage-log record — one line of the log',
|
|
53
|
+
type: 'object',
|
|
54
|
+
required: ['model'],
|
|
55
|
+
properties: {
|
|
56
|
+
model: string,
|
|
57
|
+
usage: object,
|
|
58
|
+
timestamp: string,
|
|
59
|
+
label: string,
|
|
60
|
+
session: string,
|
|
61
|
+
outcome: string,
|
|
62
|
+
stop_reason: string,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
profile: doc('profile', {
|
|
66
|
+
total: object,
|
|
67
|
+
byLabel: array,
|
|
68
|
+
byModel: array,
|
|
69
|
+
byLabelAndModel: array,
|
|
70
|
+
unpricedModels: array,
|
|
71
|
+
skippedLines: array,
|
|
72
|
+
span: objectOrNull,
|
|
73
|
+
}),
|
|
74
|
+
fleet: doc('fleet', { bySource: array, rollup: object }),
|
|
75
|
+
plan: doc('plan', {
|
|
76
|
+
actions: array,
|
|
77
|
+
projectedSavingUsd: number,
|
|
78
|
+
measuredStakeUsd: number,
|
|
79
|
+
totalUsd: number,
|
|
80
|
+
}),
|
|
81
|
+
verification: doc('verification', {
|
|
82
|
+
actions: array,
|
|
83
|
+
arrived: number,
|
|
84
|
+
notArrived: number,
|
|
85
|
+
cannotTell: number,
|
|
86
|
+
}),
|
|
87
|
+
history: doc('history', { periods: array, runs: array }),
|
|
88
|
+
connected: doc('connected', { provider: string, total: object, unavailable: array }),
|
|
89
|
+
'cost-answer': doc('cost-answer', {
|
|
90
|
+
verdict: string,
|
|
91
|
+
call: objectOrNull,
|
|
92
|
+
budget: objectOrNull,
|
|
93
|
+
}),
|
|
94
|
+
'spend-guard': doc('spend-guard', {
|
|
95
|
+
verdict: string,
|
|
96
|
+
cost: object,
|
|
97
|
+
alternatives: array,
|
|
98
|
+
because: string,
|
|
99
|
+
}),
|
|
100
|
+
'outcome-report': doc('outcome-report', {
|
|
101
|
+
slices: array,
|
|
102
|
+
undeclared: array,
|
|
103
|
+
coverage: object,
|
|
104
|
+
successShareOfRecordedUsd: { type: ['number', 'null'] },
|
|
105
|
+
noRate: stringOrNull,
|
|
106
|
+
}),
|
|
107
|
+
'annual-record': doc('annual-record', {
|
|
108
|
+
months: array,
|
|
109
|
+
missingMonths: array,
|
|
110
|
+
promises: object,
|
|
111
|
+
outcomes: objectOrNull,
|
|
112
|
+
cannotSay: array,
|
|
113
|
+
}),
|
|
114
|
+
'roll-up': doc('roll-up', {
|
|
115
|
+
contributors: array,
|
|
116
|
+
rejected: array,
|
|
117
|
+
total: object,
|
|
118
|
+
notMerged: array,
|
|
119
|
+
cannotSay: array,
|
|
120
|
+
}),
|
|
121
|
+
'first-run': doc('first-run', { config: object, justified: array, declined: array }),
|
|
122
|
+
pulse: doc('pulse', { beats: array, nowMs: number, stale: boolean }),
|
|
123
|
+
'rule-yield': doc('rule-yield', {
|
|
124
|
+
rules: array,
|
|
125
|
+
tokensBefore: number,
|
|
126
|
+
tokensSaved: number,
|
|
127
|
+
floor: number,
|
|
128
|
+
}),
|
|
129
|
+
'gateway-refusal': doc('gateway-refusal', { error: object, reason: string, alternatives: array }),
|
|
130
|
+
bench: doc('bench', { workloads: array, node: string, cpus: number }),
|
|
131
|
+
'prompt-draft': doc('prompt-draft', {
|
|
132
|
+
prompt: stringOrNull,
|
|
133
|
+
sections: array,
|
|
134
|
+
answered: array,
|
|
135
|
+
declined: array,
|
|
136
|
+
missing: array,
|
|
137
|
+
measured: objectOrNull,
|
|
138
|
+
}),
|
|
139
|
+
};
|
|
140
|
+
/** The schema for one named contract — the object `trazum schema` prints. */
|
|
141
|
+
export function contractSchema(name) {
|
|
142
|
+
return CONTRACT_SCHEMAS[name];
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"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"}
|
package/dist/session-cost.d.ts
CHANGED
|
@@ -64,6 +64,8 @@ export interface SessionCostTracker {
|
|
|
64
64
|
add(record: UsageRecord): void;
|
|
65
65
|
finish(): SessionCostShape[];
|
|
66
66
|
}
|
|
67
|
+
/** Every billed dollar of one call, at its own model's rates. */
|
|
68
|
+
export declare function costOf(record: UsageRecord, catalogue: PricingCatalogue, on: Date): number | null;
|
|
67
69
|
export declare function createSessionCostTracker(options: SessionCostOptions): SessionCostTracker;
|
|
68
70
|
/** The same measurement over a list, for a caller holding one already. */
|
|
69
71
|
export declare function sessionCostShapes(records: readonly UsageRecord[], options: SessionCostOptions): SessionCostShape[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-cost.d.ts","sourceRoot":"","sources":["../src/session-cost.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,EAAE,CAAC,EAAE,IAAI,CAAC;IACV;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC/B,MAAM,IAAI,gBAAgB,EAAE,CAAC;CAC9B;
|
|
1
|
+
{"version":3,"file":"session-cost.d.ts","sourceRoot":"","sources":["../src/session-cost.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,EAAE,CAAC,EAAE,IAAI,CAAC;IACV;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC/B,MAAM,IAAI,gBAAgB,EAAE,CAAC;CAC9B;AAED,iEAAiE;AACjE,wBAAgB,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,gBAAgB,EAAE,EAAE,EAAE,IAAI,GAAG,MAAM,GAAG,IAAI,CAahG;AAgBD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,kBAAkB,GAAG,kBAAkB,CAwDxF;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,OAAO,EAAE,kBAAkB,GAC1B,gBAAgB,EAAE,CAIpB"}
|
package/dist/session-cost.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { effectivePricing, multipliersFor } from './pricing.js';
|
|
2
2
|
import { UNLABELLED } from './usage.js';
|
|
3
3
|
/** Every billed dollar of one call, at its own model's rates. */
|
|
4
|
-
function costOf(record, catalogue, on) {
|
|
4
|
+
export function costOf(record, catalogue, on) {
|
|
5
5
|
const model = catalogue.byId.get(record.model);
|
|
6
6
|
if (!model)
|
|
7
7
|
return null;
|
package/dist/session-cost.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-cost.js","sourceRoot":"","sources":["../src/session-cost.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAwExC,iEAAiE;AACjE,
|
|
1
|
+
{"version":3,"file":"session-cost.js","sourceRoot":"","sources":["../src/session-cost.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.66.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",
|