@claudexor/budget 1.0.0 → 2.0.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/README.md +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/ledger.d.ts +43 -42
- package/dist/ledger.d.ts.map +1 -1
- package/dist/ledger.js +234 -140
- package/dist/ledger.js.map +1 -1
- package/dist/metrics.d.ts +15 -1
- package/dist/metrics.d.ts.map +1 -1
- package/dist/metrics.js +27 -5
- package/dist/metrics.js.map +1 -1
- package/dist/observe.d.ts.map +1 -1
- package/dist/observe.js +20 -10
- package/dist/observe.js.map +1 -1
- package/dist/router.d.ts +15 -12
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +51 -43
- package/dist/router.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @claudexor/budget
|
|
2
2
|
|
|
3
|
-
Internal package of [Claudexor](https://github.com/razzant/claudexor) — Budget governor: pre-call lease reservation, loop detection, 3-tier circuit breaker,
|
|
3
|
+
Internal package of [Claudexor](https://github.com/razzant/claudexor) — Budget governor: pre-call lease reservation, loop detection, 3-tier circuit breaker, routing goals, observed quota.
|
|
4
4
|
|
|
5
5
|
Published as part of the Claudexor toolchain; it follows the monorepo's
|
|
6
6
|
lockstep version and has no separate semver contract. Use the `claudexor`
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "./ledger.js";
|
|
2
2
|
export * from "./router.js";
|
|
3
3
|
export * from "./observe.js";
|
|
4
|
-
export { loadHarnessMetrics, recordHarnessMetric, metricsPath, type HarnessMetric, type HarnessMetrics } from "./metrics.js";
|
|
4
|
+
export { loadHarnessMetrics, recordHarnessMetric, metricsPath, type HarnessMetric, type HarnessMetrics, } from "./metrics.js";
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,EACX,KAAK,aAAa,EAClB,KAAK,cAAc,GACpB,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export * from "./ledger.js";
|
|
2
2
|
export * from "./router.js";
|
|
3
3
|
export * from "./observe.js";
|
|
4
|
-
export { loadHarnessMetrics, recordHarnessMetric, metricsPath } from "./metrics.js";
|
|
4
|
+
export { loadHarnessMetrics, recordHarnessMetric, metricsPath, } from "./metrics.js";
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,WAAW,GAGZ,MAAM,cAAc,CAAC"}
|
package/dist/ledger.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
import type { BudgetLease, BudgetObservation, Intent } from "@claudexor/schema";
|
|
1
|
+
import type { BillingKnowledge, BudgetLease, BudgetObservation, CostEvidence, CostKnowledge, CredentialRoute, Intent, PaidBudget, QuotaSnapshot } from "@claudexor/schema";
|
|
2
2
|
export type CircuitTier = "ok" | "soft" | "downgrade" | "hard";
|
|
3
|
-
export
|
|
4
|
-
maxUsd?: number | null;
|
|
5
|
-
}
|
|
3
|
+
export type BudgetTerminal = "exhausted" | "exhausted_overshoot" | "cost_unverifiable" | null;
|
|
6
4
|
export interface CircuitThresholds {
|
|
7
5
|
soft: number;
|
|
8
6
|
downgrade: number;
|
|
@@ -14,69 +12,72 @@ export interface ReserveInput {
|
|
|
14
12
|
intent: Intent;
|
|
15
13
|
harnessId: string;
|
|
16
14
|
modelHint?: string | null;
|
|
17
|
-
maxUsd?: number | null;
|
|
18
15
|
reason?: string[];
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
16
|
+
cost?: CostEvidence;
|
|
17
|
+
}
|
|
18
|
+
export interface BudgetSettlement {
|
|
19
|
+
knowledge: CostKnowledge;
|
|
20
|
+
source: string;
|
|
21
|
+
provenance: string[];
|
|
22
|
+
cashUsd?: number;
|
|
23
|
+
valuationUsd?: number;
|
|
25
24
|
}
|
|
26
25
|
export interface ReserveResult {
|
|
27
26
|
granted: boolean;
|
|
28
27
|
tier: CircuitTier;
|
|
29
28
|
lease?: BudgetLease;
|
|
30
29
|
reason?: string;
|
|
31
|
-
|
|
32
|
-
* breaker already tripped; `estimate_headroom` = the DD-27 wave guard —
|
|
33
|
-
* this slot's estimate does not fit, but already-granted work continues. */
|
|
34
|
-
denied?: "hard_cap" | "estimate_headroom";
|
|
30
|
+
denied?: "hard_cap" | "estimate_headroom" | "finite_zero" | "unknown_paid_in_flight";
|
|
35
31
|
}
|
|
36
32
|
/** Stable fingerprint of a prompt for loop detection. */
|
|
37
33
|
export declare function promptFingerprint(prompt: string): string;
|
|
38
|
-
/**
|
|
39
|
-
* Dollar-based budget ledger with pre-call reservation, prompt-fingerprint loop
|
|
40
|
-
* detection, and a 3-tier circuit breaker (soft-warn -> downgrade -> hard-kill).
|
|
41
|
-
* Sub-ledgers (children) roll their spend up to the parent.
|
|
42
|
-
*/
|
|
34
|
+
/** One root incremental-cash ledger. Nested work receives this same instance. */
|
|
43
35
|
export declare class BudgetLedger {
|
|
44
|
-
private readonly
|
|
36
|
+
private readonly budget;
|
|
45
37
|
private readonly thresholds;
|
|
46
|
-
private readonly parent?;
|
|
47
38
|
private readonly leases;
|
|
48
|
-
/** Outstanding USD holds for reserved-but-unsettled leases (amount-bearing). */
|
|
49
39
|
private readonly holds;
|
|
40
|
+
private readonly unknownPaidInFlight;
|
|
50
41
|
private readonly observations;
|
|
42
|
+
private readonly quotaSnapshots;
|
|
51
43
|
private readonly promptCounts;
|
|
52
44
|
private spendUsd;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
private valuationUsd;
|
|
46
|
+
private overshot;
|
|
47
|
+
private unverifiable;
|
|
48
|
+
constructor(budget?: PaidBudget, thresholds?: CircuitThresholds);
|
|
56
49
|
private outstandingHolds;
|
|
50
|
+
private cap;
|
|
57
51
|
tier(): CircuitTier;
|
|
58
|
-
|
|
59
|
-
private remainingHeadroomUsd;
|
|
52
|
+
remainingUsd(): number | null;
|
|
60
53
|
reserve(input: ReserveInput): ReserveResult;
|
|
61
|
-
/**
|
|
62
|
-
* Raise a lease's hold to the cost streamed so far (never lowers it). Call from
|
|
63
|
-
* the usage-event stream so `tier()` reflects in-flight spend mid-attempt.
|
|
64
|
-
*/
|
|
65
54
|
updateHold(leaseId: string, streamedUsd: number): void;
|
|
66
|
-
|
|
67
|
-
private adjustRollupHold;
|
|
68
|
-
private clearHold;
|
|
69
|
-
settle(leaseId: string, actualUsd: number): void;
|
|
55
|
+
settle(leaseId: string, settlement: BudgetSettlement): void;
|
|
70
56
|
cancel(leaseId: string): void;
|
|
71
|
-
private addRollupSpend;
|
|
72
57
|
spend(): number;
|
|
73
|
-
|
|
58
|
+
valuation(): number;
|
|
59
|
+
terminal(): BudgetTerminal;
|
|
60
|
+
observe(observation: BudgetObservation): void;
|
|
61
|
+
/** Seed durable quota projection without collapsing credential identities. */
|
|
62
|
+
observeQuotaSnapshot(snapshot: QuotaSnapshot): void;
|
|
74
63
|
observationsFor(harnessId: string): BudgetObservation[];
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
64
|
+
cooldownActive(harnessId: string, credentialRoute?: CredentialRoute, now?: number): boolean;
|
|
65
|
+
/** Binding pacing slack across applicable windows; null means honestly unknown. */
|
|
66
|
+
bindingPaceSlack(harnessId: string, credentialRoute?: CredentialRoute, now?: number): number | null;
|
|
67
|
+
private snapshotsFor;
|
|
79
68
|
recordPrompt(fingerprint: string): number;
|
|
80
69
|
isLoop(fingerprint: string, threshold?: number): boolean;
|
|
81
70
|
}
|
|
71
|
+
export declare function routeCostEvidence(input: {
|
|
72
|
+
billing?: BillingKnowledge;
|
|
73
|
+
knowledge?: CostKnowledge;
|
|
74
|
+
source: string;
|
|
75
|
+
provenance: string[];
|
|
76
|
+
estimatedUsd?: number | null;
|
|
77
|
+
}): CostEvidence;
|
|
78
|
+
export declare function attemptCostEvidence(harnessId: string, attemptId: string, estimatedUsd?: number, billing?: BillingKnowledge): CostEvidence;
|
|
79
|
+
export declare function usageCostSettlement(cashUsd: number, estimated: boolean, source: string, provenance: string[]): BudgetSettlement;
|
|
80
|
+
export declare function attemptUsageCostSettlement(cashUsd: number, estimated: boolean, attemptId: string, harnessId: string, authMode?: "local_session" | "api_key" | null): BudgetSettlement;
|
|
81
|
+
export declare function unknownCostSettlement(source: string, cashUsd?: number): BudgetSettlement;
|
|
82
|
+
export declare function isBudgetTerminal(status: string | null): status is Exclude<BudgetTerminal, null>;
|
|
82
83
|
//# sourceMappingURL=ledger.d.ts.map
|
package/dist/ledger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"ledger.d.ts","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"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"}
|
package/dist/ledger.js
CHANGED
|
@@ -1,91 +1,97 @@
|
|
|
1
|
-
import { BudgetLease as BudgetLeaseSchema } from "@claudexor/schema";
|
|
1
|
+
import { BudgetLease as BudgetLeaseSchema, CostEvidence as CostEvidenceSchema, } from "@claudexor/schema";
|
|
2
2
|
import { newId, nowIso, sha256 } from "@claudexor/util";
|
|
3
|
+
const UNKNOWN_COST = {
|
|
4
|
+
knowledge: "unknown",
|
|
5
|
+
billing: "unknown",
|
|
6
|
+
source: "route_preflight",
|
|
7
|
+
provenance: ["route:billing-unknown"],
|
|
8
|
+
estimatedUsd: null,
|
|
9
|
+
};
|
|
3
10
|
/** Stable fingerprint of a prompt for loop detection. */
|
|
4
11
|
export function promptFingerprint(prompt) {
|
|
5
12
|
return sha256(prompt.trim().replace(/\s+/g, " ").toLowerCase());
|
|
6
13
|
}
|
|
7
|
-
/**
|
|
8
|
-
* Dollar-based budget ledger with pre-call reservation, prompt-fingerprint loop
|
|
9
|
-
* detection, and a 3-tier circuit breaker (soft-warn -> downgrade -> hard-kill).
|
|
10
|
-
* Sub-ledgers (children) roll their spend up to the parent.
|
|
11
|
-
*/
|
|
14
|
+
/** One root incremental-cash ledger. Nested work receives this same instance. */
|
|
12
15
|
export class BudgetLedger {
|
|
13
|
-
|
|
16
|
+
budget;
|
|
14
17
|
thresholds;
|
|
15
|
-
parent;
|
|
16
18
|
leases = new Map();
|
|
17
|
-
/** Outstanding USD holds for reserved-but-unsettled leases (amount-bearing). */
|
|
18
19
|
holds = new Map();
|
|
20
|
+
unknownPaidInFlight = new Set();
|
|
19
21
|
observations = [];
|
|
22
|
+
quotaSnapshots = new Map();
|
|
20
23
|
promptCounts = new Map();
|
|
21
24
|
spendUsd = 0;
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
valuationUsd = 0;
|
|
26
|
+
overshot = false;
|
|
27
|
+
unverifiable = false;
|
|
28
|
+
constructor(budget = { kind: "unlimited" }, thresholds = { soft: 0.75, downgrade: 0.9, hard: 1 }) {
|
|
29
|
+
this.budget = budget;
|
|
24
30
|
this.thresholds = thresholds;
|
|
25
|
-
this.parent = parent;
|
|
26
|
-
}
|
|
27
|
-
/** Create a child sub-ledger whose spend rolls up to this one. */
|
|
28
|
-
child(limits = {}) {
|
|
29
|
-
return new BudgetLedger(limits, this.thresholds, this);
|
|
30
31
|
}
|
|
31
32
|
outstandingHolds() {
|
|
32
33
|
let sum = 0;
|
|
33
|
-
for (const
|
|
34
|
-
sum +=
|
|
34
|
+
for (const value of this.holds.values())
|
|
35
|
+
sum += value;
|
|
35
36
|
return sum;
|
|
36
37
|
}
|
|
38
|
+
cap() {
|
|
39
|
+
return this.budget.kind === "finite" ? this.budget.maxUsd : null;
|
|
40
|
+
}
|
|
37
41
|
tier() {
|
|
38
|
-
const cap = this.
|
|
39
|
-
|
|
40
|
-
if (cap === null || cap <= 0)
|
|
41
|
-
return "ok";
|
|
42
|
-
// Settled spend + outstanding in-flight holds: a parallel wave of
|
|
43
|
-
// streaming candidates counts against the cap BEFORE settlement.
|
|
44
|
-
const ratio = (this.spendUsd + this.outstandingHolds()) / cap;
|
|
45
|
-
if (ratio >= this.thresholds.hard)
|
|
46
|
-
return "hard";
|
|
47
|
-
if (ratio >= this.thresholds.downgrade)
|
|
48
|
-
return "downgrade";
|
|
49
|
-
if (ratio >= this.thresholds.soft)
|
|
50
|
-
return "soft";
|
|
42
|
+
const cap = this.cap();
|
|
43
|
+
if (cap === null)
|
|
51
44
|
return "ok";
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (
|
|
62
|
-
return
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
45
|
+
if (this.overshot)
|
|
46
|
+
return "hard";
|
|
47
|
+
if (cap === 0)
|
|
48
|
+
return this.spendUsd > 0 || this.outstandingHolds() > 0 ? "hard" : "ok";
|
|
49
|
+
const ratio = (this.spendUsd + this.outstandingHolds()) / cap;
|
|
50
|
+
if (ratio >= this.thresholds.hard)
|
|
51
|
+
return "hard";
|
|
52
|
+
if (ratio >= this.thresholds.downgrade)
|
|
53
|
+
return "downgrade";
|
|
54
|
+
if (ratio >= this.thresholds.soft)
|
|
55
|
+
return "soft";
|
|
56
|
+
return "ok";
|
|
57
|
+
}
|
|
58
|
+
remainingUsd() {
|
|
59
|
+
const cap = this.cap();
|
|
60
|
+
return cap === null ? null : Math.max(0, cap - this.spendUsd - this.outstandingHolds());
|
|
66
61
|
}
|
|
67
62
|
reserve(input) {
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
const cost = CostEvidenceSchema.parse(input.cost ?? UNKNOWN_COST);
|
|
64
|
+
const zeroCash = cost.billing === "proven_zero" || cost.billing === "subscription_entitlement";
|
|
65
|
+
const cap = this.cap();
|
|
66
|
+
if (cap === 0 && !zeroCash) {
|
|
67
|
+
return {
|
|
68
|
+
granted: false,
|
|
69
|
+
tier: "hard",
|
|
70
|
+
denied: "finite_zero",
|
|
71
|
+
reason: "finite(0) admits only proven-zero or subscription-entitlement work",
|
|
72
|
+
};
|
|
71
73
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
74
|
+
if (this.tier() === "hard" && !zeroCash) {
|
|
75
|
+
return { granted: false, tier: "hard", denied: "hard_cap", reason: "budget exhausted" };
|
|
76
|
+
}
|
|
77
|
+
const unknownPaid = !zeroCash && cost.knowledge === "unknown";
|
|
78
|
+
if (cap !== null && cap > 0 && unknownPaid && this.unknownPaidInFlight.size > 0) {
|
|
79
|
+
return {
|
|
80
|
+
granted: false,
|
|
81
|
+
tier: this.tier(),
|
|
82
|
+
denied: "unknown_paid_in_flight",
|
|
83
|
+
reason: "one unknown-cost paid unit is already in flight",
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const estimate = zeroCash ? 0 : (cost.estimatedUsd ?? 0);
|
|
87
|
+
const headroom = this.remainingUsd();
|
|
88
|
+
if (estimate > 0 && headroom !== null && estimate >= headroom) {
|
|
89
|
+
return {
|
|
90
|
+
granted: false,
|
|
91
|
+
tier: this.tier(),
|
|
92
|
+
denied: "estimate_headroom",
|
|
93
|
+
reason: `insufficient headroom for estimated cost (${estimate.toFixed(2)} USD >= ${headroom.toFixed(2)} USD remaining)`,
|
|
94
|
+
};
|
|
89
95
|
}
|
|
90
96
|
const lease = BudgetLeaseSchema.parse({
|
|
91
97
|
lease_id: newId("lease"),
|
|
@@ -94,119 +100,207 @@ export class BudgetLedger {
|
|
|
94
100
|
intent: input.intent,
|
|
95
101
|
harness_id: input.harnessId,
|
|
96
102
|
model_hint: input.modelHint ?? null,
|
|
97
|
-
|
|
103
|
+
cost,
|
|
98
104
|
reason: input.reason ?? [],
|
|
99
105
|
created_at: nowIso(),
|
|
100
106
|
state: "reserved",
|
|
101
107
|
});
|
|
102
108
|
this.leases.set(lease.lease_id, lease);
|
|
103
|
-
if (
|
|
104
|
-
this.
|
|
105
|
-
|
|
106
|
-
|
|
109
|
+
if (estimate > 0)
|
|
110
|
+
this.holds.set(lease.lease_id, estimate);
|
|
111
|
+
if (unknownPaid && cap !== null)
|
|
112
|
+
this.unknownPaidInFlight.add(lease.lease_id);
|
|
113
|
+
return { granted: true, tier: this.tier(), lease };
|
|
107
114
|
}
|
|
108
|
-
/**
|
|
109
|
-
* Raise a lease's hold to the cost streamed so far (never lowers it). Call from
|
|
110
|
-
* the usage-event stream so `tier()` reflects in-flight spend mid-attempt.
|
|
111
|
-
*/
|
|
112
115
|
updateHold(leaseId, streamedUsd) {
|
|
113
|
-
|
|
116
|
+
const lease = this.leases.get(leaseId);
|
|
117
|
+
if (!lease || lease.state !== "reserved")
|
|
118
|
+
return;
|
|
119
|
+
if (lease.cost.billing === "proven_zero" || lease.cost.billing === "subscription_entitlement")
|
|
114
120
|
return;
|
|
115
121
|
const current = this.holds.get(leaseId) ?? 0;
|
|
116
122
|
if (streamedUsd > current)
|
|
117
|
-
this.
|
|
118
|
-
}
|
|
119
|
-
setHold(leaseId, usd) {
|
|
120
|
-
const prev = this.holds.get(leaseId) ?? 0;
|
|
121
|
-
this.holds.set(leaseId, usd);
|
|
122
|
-
this.parent?.adjustRollupHold(leaseId, usd - prev);
|
|
123
|
-
}
|
|
124
|
-
adjustRollupHold(leaseId, deltaUsd) {
|
|
125
|
-
const key = `child:${leaseId}`;
|
|
126
|
-
const prev = this.holds.get(key) ?? 0;
|
|
127
|
-
const next = Math.max(0, prev + deltaUsd);
|
|
128
|
-
if (next === 0)
|
|
129
|
-
this.holds.delete(key);
|
|
130
|
-
else
|
|
131
|
-
this.holds.set(key, next);
|
|
132
|
-
this.parent?.adjustRollupHold(leaseId, deltaUsd);
|
|
133
|
-
}
|
|
134
|
-
clearHold(leaseId) {
|
|
135
|
-
const held = this.holds.get(leaseId) ?? 0;
|
|
136
|
-
this.holds.delete(leaseId);
|
|
137
|
-
if (held > 0)
|
|
138
|
-
this.parent?.adjustRollupHold(leaseId, -held);
|
|
123
|
+
this.holds.set(leaseId, streamedUsd);
|
|
139
124
|
}
|
|
140
|
-
settle(leaseId,
|
|
125
|
+
settle(leaseId, settlement) {
|
|
141
126
|
const lease = this.leases.get(leaseId);
|
|
142
|
-
// Fail loudly: settling a lease this ledger never granted would attribute
|
|
143
|
-
// spend to nothing (a bookkeeping bug, not a runtime race).
|
|
144
127
|
if (!lease)
|
|
145
128
|
throw new Error(`cannot settle unknown lease: ${leaseId}`);
|
|
146
|
-
// Idempotent for the spend add: a duplicate settle (success path followed
|
|
147
|
-
// by a late error handler) must never double-count real spend. DECIDED
|
|
148
|
-
// TRADEOFF: this no-op can also mask a genuine double-settle bug — spend
|
|
149
|
-
// correctness wins because the duplicate-settle race is a real runtime
|
|
150
|
-
// path (terminal handler + error handler), while a masked bug still
|
|
151
|
-
// surfaces in the rollup totals a test would assert on.
|
|
152
129
|
if (lease.state !== "reserved")
|
|
153
130
|
return;
|
|
154
131
|
lease.state = "settled";
|
|
155
|
-
this.
|
|
156
|
-
this.
|
|
157
|
-
|
|
132
|
+
this.holds.delete(leaseId);
|
|
133
|
+
this.unknownPaidInFlight.delete(leaseId);
|
|
134
|
+
const zeroCash = lease.cost.billing === "proven_zero" || lease.cost.billing === "subscription_entitlement";
|
|
135
|
+
const cashUsd = zeroCash ? 0 : Math.max(0, settlement.cashUsd ?? 0);
|
|
136
|
+
this.spendUsd += cashUsd;
|
|
137
|
+
this.valuationUsd += Math.max(0, settlement.valuationUsd ?? (zeroCash ? (settlement.cashUsd ?? 0) : 0));
|
|
138
|
+
if (this.budget.kind === "finite") {
|
|
139
|
+
if (!zeroCash && settlement.knowledge === "unknown")
|
|
140
|
+
this.unverifiable = true;
|
|
141
|
+
if (this.spendUsd > this.budget.maxUsd)
|
|
142
|
+
this.overshot = true;
|
|
143
|
+
}
|
|
158
144
|
}
|
|
159
145
|
cancel(leaseId) {
|
|
160
146
|
const lease = this.leases.get(leaseId);
|
|
161
|
-
if (lease)
|
|
147
|
+
if (lease?.state === "reserved")
|
|
162
148
|
lease.state = "cancelled";
|
|
163
|
-
this.
|
|
164
|
-
|
|
165
|
-
addRollupSpend(usd) {
|
|
166
|
-
this.spendUsd += usd;
|
|
167
|
-
this.parent?.addRollupSpend(usd);
|
|
149
|
+
this.holds.delete(leaseId);
|
|
150
|
+
this.unknownPaidInFlight.delete(leaseId);
|
|
168
151
|
}
|
|
169
152
|
spend() {
|
|
170
153
|
return this.spendUsd;
|
|
171
154
|
}
|
|
172
|
-
|
|
173
|
-
this.
|
|
155
|
+
valuation() {
|
|
156
|
+
return this.valuationUsd;
|
|
157
|
+
}
|
|
158
|
+
terminal() {
|
|
159
|
+
if (this.overshot)
|
|
160
|
+
return "exhausted_overshoot";
|
|
161
|
+
if (this.unverifiable)
|
|
162
|
+
return "cost_unverifiable";
|
|
163
|
+
return this.tier() === "hard" ? "exhausted" : null;
|
|
164
|
+
}
|
|
165
|
+
observe(observation) {
|
|
166
|
+
this.observations.push(observation);
|
|
167
|
+
}
|
|
168
|
+
/** Seed durable quota projection without collapsing credential identities. */
|
|
169
|
+
observeQuotaSnapshot(snapshot) {
|
|
170
|
+
const subject = snapshot.subject;
|
|
171
|
+
const key = [
|
|
172
|
+
subject.harness,
|
|
173
|
+
subject.credential_route,
|
|
174
|
+
subject.subject_id ?? "",
|
|
175
|
+
snapshot.source,
|
|
176
|
+
].join("\0");
|
|
177
|
+
this.quotaSnapshots.set(key, snapshot);
|
|
174
178
|
}
|
|
175
179
|
observationsFor(harnessId) {
|
|
176
|
-
return this.observations.filter((
|
|
180
|
+
return this.observations.filter((observation) => observation.harness_id === harnessId);
|
|
177
181
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if (!o.cooldown_until)
|
|
182
|
+
cooldownActive(harnessId, credentialRoute, now = Date.now()) {
|
|
183
|
+
const liveObservation = this.observationsFor(harnessId).some((observation) => {
|
|
184
|
+
if (!observation.cooldown_until)
|
|
182
185
|
return false;
|
|
183
|
-
const
|
|
184
|
-
return Number.isFinite(
|
|
186
|
+
const time = Date.parse(observation.cooldown_until);
|
|
187
|
+
return Number.isFinite(time) && time > now;
|
|
185
188
|
});
|
|
189
|
+
if (liveObservation)
|
|
190
|
+
return true;
|
|
191
|
+
if (!credentialRoute)
|
|
192
|
+
return false;
|
|
193
|
+
return this.snapshotsFor(harnessId, credentialRoute).some((snapshot) => snapshot.constraints.some((constraint) => {
|
|
194
|
+
const cooldown = constraint.cooldown_until
|
|
195
|
+
? Date.parse(constraint.cooldown_until)
|
|
196
|
+
: Number.NaN;
|
|
197
|
+
const reset = constraint.resets_at ? Date.parse(constraint.resets_at) : Number.NaN;
|
|
198
|
+
return ((Number.isFinite(cooldown) && cooldown > now) ||
|
|
199
|
+
(constraint.used_ratio !== null &&
|
|
200
|
+
constraint.used_ratio >= 1 &&
|
|
201
|
+
Number.isFinite(reset) &&
|
|
202
|
+
reset > now));
|
|
203
|
+
}));
|
|
186
204
|
}
|
|
187
|
-
/**
|
|
188
|
-
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
205
|
+
/** Binding pacing slack across applicable windows; null means honestly unknown. */
|
|
206
|
+
bindingPaceSlack(harnessId, credentialRoute, now = Date.now()) {
|
|
207
|
+
const latest = new Map();
|
|
208
|
+
for (const observation of this.observationsFor(harnessId)) {
|
|
209
|
+
if (observation.kind !== "quota_constraint" || !observation.constraint_id)
|
|
210
|
+
continue;
|
|
211
|
+
latest.set(observation.constraint_id, observation);
|
|
212
|
+
}
|
|
213
|
+
const slacks = [];
|
|
214
|
+
for (const observation of latest.values()) {
|
|
215
|
+
if (typeof observation.used_ratio !== "number" ||
|
|
216
|
+
typeof observation.window_seconds !== "number" ||
|
|
217
|
+
!observation.resets_at)
|
|
218
|
+
continue;
|
|
219
|
+
const resetMs = Date.parse(observation.resets_at);
|
|
220
|
+
if (!Number.isFinite(resetMs) || resetMs <= now)
|
|
221
|
+
continue;
|
|
222
|
+
const remaining = Math.min(1, Math.max(0, (resetMs - now) / 1000 / observation.window_seconds));
|
|
223
|
+
const elapsedFraction = 1 - remaining;
|
|
224
|
+
slacks.push(elapsedFraction - observation.used_ratio);
|
|
225
|
+
}
|
|
226
|
+
if (credentialRoute) {
|
|
227
|
+
for (const snapshot of this.snapshotsFor(harnessId, credentialRoute)) {
|
|
228
|
+
for (const constraint of snapshot.constraints) {
|
|
229
|
+
if (typeof constraint.used_ratio !== "number" ||
|
|
230
|
+
typeof constraint.window_seconds !== "number" ||
|
|
231
|
+
!constraint.resets_at)
|
|
232
|
+
continue;
|
|
233
|
+
const resetMs = Date.parse(constraint.resets_at);
|
|
234
|
+
if (!Number.isFinite(resetMs) || resetMs <= now)
|
|
235
|
+
continue;
|
|
236
|
+
const remaining = Math.min(1, Math.max(0, (resetMs - now) / 1000 / constraint.window_seconds));
|
|
237
|
+
slacks.push(1 - remaining - constraint.used_ratio);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return slacks.length > 0 ? Math.min(...slacks) : null;
|
|
242
|
+
}
|
|
243
|
+
snapshotsFor(harnessId, credentialRoute) {
|
|
244
|
+
return [...this.quotaSnapshots.values()].filter((snapshot) => snapshot.freshness === "fresh" &&
|
|
245
|
+
snapshot.subject.harness === harnessId &&
|
|
246
|
+
snapshot.subject.credential_route === credentialRoute);
|
|
196
247
|
}
|
|
197
248
|
recordPrompt(fingerprint) {
|
|
198
|
-
const
|
|
199
|
-
this.promptCounts.set(fingerprint,
|
|
200
|
-
return
|
|
249
|
+
const count = (this.promptCounts.get(fingerprint) ?? 0) + 1;
|
|
250
|
+
this.promptCounts.set(fingerprint, count);
|
|
251
|
+
return count;
|
|
201
252
|
}
|
|
202
253
|
isLoop(fingerprint, threshold = 3) {
|
|
203
254
|
return (this.promptCounts.get(fingerprint) ?? 0) >= threshold;
|
|
204
255
|
}
|
|
205
256
|
}
|
|
206
|
-
function
|
|
207
|
-
return {
|
|
257
|
+
export function routeCostEvidence(input) {
|
|
258
|
+
return CostEvidenceSchema.parse({
|
|
259
|
+
billing: input.billing ?? "unknown",
|
|
260
|
+
knowledge: input.knowledge ?? "unknown",
|
|
261
|
+
source: input.source,
|
|
262
|
+
provenance: input.provenance,
|
|
263
|
+
estimatedUsd: input.estimatedUsd ?? null,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
export function attemptCostEvidence(harnessId, attemptId, estimatedUsd, billing = "unknown") {
|
|
267
|
+
return routeCostEvidence({
|
|
268
|
+
source: "route-preflight",
|
|
269
|
+
provenance: [`harness:${harnessId}`, `attempt:${attemptId}`, `billing:${billing}`],
|
|
270
|
+
billing,
|
|
271
|
+
knowledge: estimatedUsd === undefined ? "unknown" : "estimated",
|
|
272
|
+
estimatedUsd: estimatedUsd ?? null,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
export function usageCostSettlement(cashUsd, estimated, source, provenance) {
|
|
276
|
+
return cashUsd > 0
|
|
277
|
+
? { knowledge: estimated ? "estimated" : "exact", source, provenance, cashUsd }
|
|
278
|
+
: { knowledge: "unknown", source: `${source}-missing`, provenance };
|
|
279
|
+
}
|
|
280
|
+
export function attemptUsageCostSettlement(cashUsd, estimated, attemptId, harnessId, authMode) {
|
|
281
|
+
if (authMode === "local_session" && estimated) {
|
|
282
|
+
return {
|
|
283
|
+
knowledge: "unknown",
|
|
284
|
+
source: "harness-token-valuation",
|
|
285
|
+
provenance: [`attempt:${attemptId}`, `harness:${harnessId}`, "route:vendor_native"],
|
|
286
|
+
valuationUsd: cashUsd,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
return usageCostSettlement(cashUsd, estimated, "harness-usage", [
|
|
290
|
+
`attempt:${attemptId}`,
|
|
291
|
+
`harness:${harnessId}`,
|
|
292
|
+
...(authMode ? [`route:${authMode}`] : []),
|
|
293
|
+
]);
|
|
294
|
+
}
|
|
295
|
+
export function unknownCostSettlement(source, cashUsd) {
|
|
296
|
+
return {
|
|
297
|
+
knowledge: "unknown",
|
|
298
|
+
source,
|
|
299
|
+
provenance: [`orchestrator:${source}`],
|
|
300
|
+
...(cashUsd === undefined ? {} : { cashUsd }),
|
|
301
|
+
};
|
|
208
302
|
}
|
|
209
|
-
function
|
|
210
|
-
return
|
|
303
|
+
export function isBudgetTerminal(status) {
|
|
304
|
+
return (status === "exhausted" || status === "exhausted_overshoot" || status === "cost_unverifiable");
|
|
211
305
|
}
|
|
212
306
|
//# sourceMappingURL=ledger.js.map
|
package/dist/ledger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ledger.js","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,IAAI,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAyCxD,yDAAyD;AACzD,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;AAClE,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,YAAY;IASJ;IACA;IACA;IAVF,MAAM,GAAG,IAAI,GAAG,EAAuB,CAAC;IACzD,gFAAgF;IAC/D,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IAClC,YAAY,GAAwB,EAAE,CAAC;IACvC,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAC;IAClD,QAAQ,GAAG,CAAC,CAAC;IAErB,YACmB,SAAuB,EAAE,EACzB,aAAgC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,EACzE,MAAqB;QAFrB,WAAM,GAAN,MAAM,CAAmB;QACzB,eAAU,GAAV,UAAU,CAA+D;QACzE,WAAM,GAAN,MAAM,CAAe;IACrC,CAAC;IAEJ,kEAAkE;IAClE,KAAK,CAAC,SAAuB,EAAE;QAC7B,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACzD,CAAC;IAEO,gBAAgB;QACtB,IAAI,GAAG,GAAG,CAAC,CAAC;QACZ,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;YAAE,GAAG,IAAI,CAAC,CAAC;QAC9C,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI;QACF,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC;QACvC,MAAM,SAAS,GAAG,CAAC,GAAgB,EAAE;YACnC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC1C,kEAAkE;YAClE,iEAAiE;YACjE,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC,GAAG,GAAG,CAAC;YAC9D,IAAI,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI;gBAAE,OAAO,MAAM,CAAC;YACjD,IAAI,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS;gBAAE,OAAO,WAAW,CAAC;YAC3D,IAAI,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI;gBAAE,OAAO,MAAM,CAAC;YACjD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,EAAE,CAAC;QACL,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;QAC/C,OAAO,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAC3C,CAAC;IAED,uFAAuF;IAC/E,oBAAoB;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC;QACvC,MAAM,KAAK,GAAG,GAAG,KAAK,IAAI,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACvH,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,oBAAoB,EAAE,IAAI,IAAI,CAAC;QAC3D,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;QAClC,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,KAAK,CAAC;QAClC,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC;IAED,OAAO,CAAC,KAAmB;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,qCAAqC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;QACrG,CAAC;QACD,uEAAuE;QACvE,qEAAqE;QACrE,0EAA0E;QAC1E,uEAAuE;QACvE,wEAAwE;QACxE,wEAAwE;QACxE,8CAA8C;QAC9C,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;YACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC7C,IAAI,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,WAAW,IAAI,QAAQ,EAAE,CAAC;gBACvD,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,IAAI;oBACJ,MAAM,EAAE,6CAA6C,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB;oBAC7I,MAAM,EAAE,mBAAmB;iBAC5B,CAAC;YACJ,CAAC;QACH,CAAC;QACD,MAAM,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC;YACpC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC;YACxB,OAAO,EAAE,KAAK,CAAC,MAAM;YACrB,UAAU,EAAE,KAAK,CAAC,SAAS;YAC3B,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,KAAK,CAAC,SAAS;YAC3B,UAAU,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;YACnC,OAAO,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI;YAC7B,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,EAAE;YAC1B,UAAU,EAAE,MAAM,EAAE;YACpB,KAAK,EAAE,UAAU;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACvC,IAAI,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;YACnE,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;QAClD,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACxC,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,OAAe,EAAE,WAAmB;QAC7C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,WAAW,GAAG,OAAO;YAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAChE,CAAC;IAEO,OAAO,CAAC,OAAe,EAAE,GAAW;QAC1C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC;IACrD,CAAC;IAEO,gBAAgB,CAAC,OAAe,EAAE,QAAgB;QACxD,MAAM,GAAG,GAAG,SAAS,OAAO,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,QAAQ,CAAC,CAAC;QAC1C,IAAI,IAAI,KAAK,CAAC;YAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;;YAClC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACnD,CAAC;IAEO,SAAS,CAAC,OAAe;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3B,IAAI,IAAI,GAAG,CAAC;YAAE,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM,CAAC,OAAe,EAAE,SAAiB;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,0EAA0E;QAC1E,4DAA4D;QAC5D,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,OAAO,EAAE,CAAC,CAAC;QACvE,0EAA0E;QAC1E,uEAAuE;QACvE,yEAAyE;QACzE,uEAAuE;QACvE,oEAAoE;QACpE,wDAAwD;QACxD,IAAI,KAAK,CAAC,KAAK,KAAK,UAAU;YAAE,OAAO;QACvC,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACxB,IAAI,CAAC,QAAQ,IAAI,SAAS,CAAC;QAC3B,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,OAAe;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,KAAK;YAAE,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC;QACrC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAEO,cAAc,CAAC,GAAW;QAChC,IAAI,CAAC,QAAQ,IAAI,GAAG,CAAC;QACrB,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,OAAO,CAAC,CAAoB;QAC1B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5B,CAAC;IAED,eAAe,CAAC,SAAiB;QAC/B,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC;IACrE,CAAC;IAED,kFAAkF;IAClF,cAAc,CAAC,SAAiB,EAAE,MAAc,IAAI,CAAC,GAAG,EAAE;QACxD,OAAO,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YAChD,IAAI,CAAC,CAAC,CAAC,cAAc;gBAAE,OAAO,KAAK,CAAC;YACpC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC;YACvC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;QACvC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,yEAAyE;IACzE,QAAQ,CAAC,SAAiB;QACxB,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC;aACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;aAC1B,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;QACrD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO,GAAG,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,YAAY,CAAC,WAAmB;QAC9B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACxD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACtC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,CAAC,WAAmB,EAAE,SAAS,GAAG,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,SAAS,CAAC;IAChE,CAAC;CACF;AAED,SAAS,QAAQ,CAAC,CAAc;IAC9B,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,UAAU,CAAC,CAAc,EAAE,CAAc;IAChD,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,CAAC"}
|
|
1
|
+
{"version":3,"file":"ledger.js","sourceRoot":"","sources":["../src/ledger.ts"],"names":[],"mappings":"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"}
|
package/dist/metrics.d.ts
CHANGED
|
@@ -2,13 +2,27 @@ export interface HarnessMetric {
|
|
|
2
2
|
avg_cost_usd: number | null;
|
|
3
3
|
avg_duration_ms: number | null;
|
|
4
4
|
samples: number;
|
|
5
|
+
/**
|
|
6
|
+
* Auth route the harness's LAST settled attempt actually ran under
|
|
7
|
+
* (adapter-disclosed route evidence, not a manifest capability guess).
|
|
8
|
+
* Economy routing may consume settled cost as evidence; no quality prior is
|
|
9
|
+
* inferred. Null until any attempt disclosed a route.
|
|
10
|
+
*/
|
|
11
|
+
last_auth_mode: "local_session" | "api_key" | null;
|
|
5
12
|
}
|
|
6
13
|
export type HarnessMetrics = Record<string, HarnessMetric>;
|
|
7
14
|
export declare function metricsPath(configDir: string): string;
|
|
8
15
|
export declare function loadHarnessMetrics(configDir: string): HarnessMetrics;
|
|
9
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Record one settled attempt (EMA update; atomic tmp+rename write).
|
|
18
|
+
* `authMode` is route evidence and updates independently of the performance
|
|
19
|
+
* sample: an auth-only record (no cost/duration) refreshes `last_auth_mode`
|
|
20
|
+
* WITHOUT counting a sample, so errored attempts can still disclose the route
|
|
21
|
+
* they burned without earning a flattering latency average.
|
|
22
|
+
*/
|
|
10
23
|
export declare function recordHarnessMetric(configDir: string, harnessId: string, sample: {
|
|
11
24
|
costUsd?: number | null;
|
|
12
25
|
durationMs?: number | null;
|
|
26
|
+
authMode?: "local_session" | "api_key" | null;
|
|
13
27
|
}): void;
|
|
14
28
|
//# sourceMappingURL=metrics.d.ts.map
|
package/dist/metrics.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,cAAc,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;CACpD;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAM3D,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAiCpE;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE;IACN,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAAC;CAC/C,GACA,IAAI,CAmCN"}
|
package/dist/metrics.js
CHANGED
|
@@ -24,8 +24,15 @@ export function loadHarnessMetrics(configDir) {
|
|
|
24
24
|
const m = v;
|
|
25
25
|
out[id] = {
|
|
26
26
|
avg_cost_usd: typeof m.avg_cost_usd === "number" && m.avg_cost_usd >= 0 ? m.avg_cost_usd : null,
|
|
27
|
-
avg_duration_ms: typeof m.avg_duration_ms === "number" && m.avg_duration_ms >= 0
|
|
28
|
-
|
|
27
|
+
avg_duration_ms: typeof m.avg_duration_ms === "number" && m.avg_duration_ms >= 0
|
|
28
|
+
? m.avg_duration_ms
|
|
29
|
+
: null,
|
|
30
|
+
samples: typeof m.samples === "number" && m.samples > 0
|
|
31
|
+
? Math.min(m.samples, MAX_SAMPLES_COUNTED)
|
|
32
|
+
: 0,
|
|
33
|
+
last_auth_mode: m.last_auth_mode === "local_session" || m.last_auth_mode === "api_key"
|
|
34
|
+
? m.last_auth_mode
|
|
35
|
+
: null,
|
|
29
36
|
};
|
|
30
37
|
}
|
|
31
38
|
return out;
|
|
@@ -34,10 +41,21 @@ export function loadHarnessMetrics(configDir) {
|
|
|
34
41
|
return {};
|
|
35
42
|
}
|
|
36
43
|
}
|
|
37
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Record one settled attempt (EMA update; atomic tmp+rename write).
|
|
46
|
+
* `authMode` is route evidence and updates independently of the performance
|
|
47
|
+
* sample: an auth-only record (no cost/duration) refreshes `last_auth_mode`
|
|
48
|
+
* WITHOUT counting a sample, so errored attempts can still disclose the route
|
|
49
|
+
* they burned without earning a flattering latency average.
|
|
50
|
+
*/
|
|
38
51
|
export function recordHarnessMetric(configDir, harnessId, sample) {
|
|
39
52
|
const all = loadHarnessMetrics(configDir);
|
|
40
|
-
const prev = all[harnessId] ?? {
|
|
53
|
+
const prev = all[harnessId] ?? {
|
|
54
|
+
avg_cost_usd: null,
|
|
55
|
+
avg_duration_ms: null,
|
|
56
|
+
samples: 0,
|
|
57
|
+
last_auth_mode: null,
|
|
58
|
+
};
|
|
41
59
|
const ema = (old, next) => {
|
|
42
60
|
if (typeof next !== "number" || !Number.isFinite(next) || next < 0)
|
|
43
61
|
return old;
|
|
@@ -45,10 +63,14 @@ export function recordHarnessMetric(configDir, harnessId, sample) {
|
|
|
45
63
|
return next;
|
|
46
64
|
return old * (1 - EMA_ALPHA) + next * EMA_ALPHA;
|
|
47
65
|
};
|
|
66
|
+
const isPerfSample = typeof sample.costUsd === "number" || typeof sample.durationMs === "number";
|
|
48
67
|
all[harnessId] = {
|
|
49
68
|
avg_cost_usd: ema(prev.avg_cost_usd, sample.costUsd),
|
|
50
69
|
avg_duration_ms: ema(prev.avg_duration_ms, sample.durationMs),
|
|
51
|
-
samples: Math.min(prev.samples + 1, MAX_SAMPLES_COUNTED),
|
|
70
|
+
samples: isPerfSample ? Math.min(prev.samples + 1, MAX_SAMPLES_COUNTED) : prev.samples,
|
|
71
|
+
last_auth_mode: sample.authMode === "local_session" || sample.authMode === "api_key"
|
|
72
|
+
? sample.authMode
|
|
73
|
+
: prev.last_auth_mode,
|
|
52
74
|
};
|
|
53
75
|
const path = metricsPath(configDir);
|
|
54
76
|
try {
|
package/dist/metrics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"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"}
|
package/dist/observe.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKzE;;;;;;GAMG;AACH;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,GAAG,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"observe.d.ts","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAKzE;;;;;;GAMG;AACH;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,YAAY,GAAG,iBAAiB,EAAE,CAgC9F"}
|
package/dist/observe.js
CHANGED
|
@@ -19,20 +19,29 @@ export function observationsFromEvent(harnessId, ev) {
|
|
|
19
19
|
// Token-derived costs (e.g. codex) are honest estimates -> "observed"; only
|
|
20
20
|
// natively-reported costs (e.g. claude) are "exact".
|
|
21
21
|
const quality = ev.usage.estimated ? "observed" : "exact";
|
|
22
|
-
out.push({ harness_id: harnessId, ts: nowIso(), quality, kind: "spend", usd: ev.usage.cost_usd });
|
|
23
|
-
}
|
|
24
|
-
if (ev.quota) {
|
|
25
|
-
// The CLI's own machine-readable window record (codex rollout
|
|
26
|
-
// token_count.rate_limits) -> "native" quality used_percent observation.
|
|
27
22
|
out.push({
|
|
28
23
|
harness_id: harnessId,
|
|
29
24
|
ts: nowIso(),
|
|
30
|
-
quality
|
|
31
|
-
kind: "
|
|
32
|
-
|
|
33
|
-
resets_at: ev.quota.resets_at ?? null,
|
|
25
|
+
quality,
|
|
26
|
+
kind: "spend",
|
|
27
|
+
usd: ev.usage.cost_usd,
|
|
34
28
|
});
|
|
35
29
|
}
|
|
30
|
+
if (ev.quota) {
|
|
31
|
+
for (const constraint of ev.quota.constraints) {
|
|
32
|
+
out.push({
|
|
33
|
+
harness_id: harnessId,
|
|
34
|
+
ts: nowIso(),
|
|
35
|
+
quality: "native",
|
|
36
|
+
kind: "quota_constraint",
|
|
37
|
+
constraint_id: constraint.id,
|
|
38
|
+
used_ratio: constraint.used_ratio,
|
|
39
|
+
window_seconds: constraint.window_seconds,
|
|
40
|
+
resets_at: constraint.resets_at,
|
|
41
|
+
cooldown_until: constraint.cooldown_until,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
36
45
|
const single = singleObservationFromEvent(harnessId, ev);
|
|
37
46
|
if (single)
|
|
38
47
|
out.push(single);
|
|
@@ -42,7 +51,8 @@ function singleObservationFromEvent(harnessId, ev) {
|
|
|
42
51
|
if (ev.rate_limit) {
|
|
43
52
|
const resets = ev.rate_limit.resets_at ?? null;
|
|
44
53
|
const delay = ev.rate_limit.retry_delay_ms ?? null;
|
|
45
|
-
const cooldownUntil = resets ??
|
|
54
|
+
const cooldownUntil = resets ??
|
|
55
|
+
new Date(Date.now() + (typeof delay === "number" && delay > 0 ? delay : DEFAULT_COOLDOWN_MS)).toISOString();
|
|
46
56
|
return {
|
|
47
57
|
harness_id: harnessId,
|
|
48
58
|
ts: nowIso(),
|
package/dist/observe.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observe.js","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAE1C;;;;;;GAMG;AACH;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAiB,EAAE,EAAgB;IACvE,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,QAAQ,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC3F,4EAA4E;QAC5E,qDAAqD;QACrD,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;QAC1D,GAAG,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"observe.js","sourceRoot":"","sources":["../src/observe.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAE1C;;;;;;GAMG;AACH;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAiB,EAAE,EAAgB;IACvE,MAAM,GAAG,GAAwB,EAAE,CAAC;IACpC,IAAI,EAAE,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,QAAQ,IAAI,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QAC3F,4EAA4E;QAC5E,qDAAqD;QACrD,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC;QAC1D,GAAG,CAAC,IAAI,CAAC;YACP,UAAU,EAAE,SAAS;YACrB,EAAE,EAAE,MAAM,EAAE;YACZ,OAAO;YACP,IAAI,EAAE,OAAO;YACb,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ;SACvB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,EAAE,CAAC,KAAK,EAAE,CAAC;QACb,KAAK,MAAM,UAAU,IAAI,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YAC9C,GAAG,CAAC,IAAI,CAAC;gBACP,UAAU,EAAE,SAAS;gBACrB,EAAE,EAAE,MAAM,EAAE;gBACZ,OAAO,EAAE,QAAQ;gBACjB,IAAI,EAAE,kBAAkB;gBACxB,aAAa,EAAE,UAAU,CAAC,EAAE;gBAC5B,UAAU,EAAE,UAAU,CAAC,UAAU;gBACjC,cAAc,EAAE,UAAU,CAAC,cAAc;gBACzC,SAAS,EAAE,UAAU,CAAC,SAAS;gBAC/B,cAAc,EAAE,UAAU,CAAC,cAAc;aAC1C,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,MAAM,MAAM,GAAG,0BAA0B,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACzD,IAAI,MAAM;QAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7B,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,0BAA0B,CAAC,SAAiB,EAAE,EAAgB;IACrE,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,IAAI,IAAI,CAAC;QAC/C,MAAM,KAAK,GAAG,EAAE,CAAC,UAAU,CAAC,cAAc,IAAI,IAAI,CAAC;QACnD,MAAM,aAAa,GACjB,MAAM;YACN,IAAI,IAAI,CACN,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,CACpF,CAAC,WAAW,EAAE,CAAC;QAClB,OAAO;YACL,UAAU,EAAE,SAAS;YACrB,EAAE,EAAE,MAAM,EAAE;YACZ,OAAO,EAAE,UAAU;YACnB,IAAI,EAAE,cAAc;YACpB,SAAS,EAAE,MAAM;YACjB,cAAc,EAAE,aAAa;YAC7B,MAAM,EAAE,EAAE,CAAC,KAAK,IAAI,SAAS;SAC9B,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/router.d.ts
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BillingKnowledge, CredentialRoute, EffortHint, Intent, PaidFallback, QualityTierSet, RoutingGoal } from "@claudexor/schema";
|
|
2
2
|
import type { BudgetLedger } from "./ledger.js";
|
|
3
3
|
export interface RouterCandidate {
|
|
4
4
|
harnessId: string;
|
|
5
|
-
providerFamily: ProviderFamily;
|
|
6
5
|
available: boolean;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
model?: string;
|
|
7
|
+
effort?: EffortHint;
|
|
8
|
+
billingKnowledge?: BillingKnowledge;
|
|
9
|
+
incrementalCostUsd?: number | null;
|
|
10
|
+
credentialRoute?: CredentialRoute;
|
|
12
11
|
}
|
|
13
12
|
export interface RouteContext {
|
|
14
|
-
|
|
13
|
+
goal: RoutingGoal;
|
|
14
|
+
paidFallback: PaidFallback;
|
|
15
|
+
intent: Intent;
|
|
16
|
+
qualityTiers: QualityTierSet;
|
|
15
17
|
ledger: BudgetLedger;
|
|
16
|
-
/** Provider families already used (penalized, to encourage cross-family diversity). */
|
|
17
|
-
diversityAgainst?: ProviderFamily[];
|
|
18
18
|
}
|
|
19
|
-
export declare
|
|
20
|
-
|
|
19
|
+
export declare class RoutingPreflightError extends Error {
|
|
20
|
+
readonly code = "routing_preflight_refused";
|
|
21
|
+
}
|
|
22
|
+
/** Order candidates transparently; lower tuple values win. Unknown quota remains eligible. */
|
|
23
|
+
export declare function rankHarnesses(candidates: RouterCandidate[], ctx: RouteContext): RouterCandidate[];
|
|
21
24
|
export declare function selectHarness(candidates: RouterCandidate[], ctx: RouteContext): RouterCandidate | null;
|
|
22
25
|
//# sourceMappingURL=router.d.ts.map
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,MAAM,EACN,YAAY,EACZ,cAAc,EACd,WAAW,EACZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,WAAW,CAAC;IAClB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,cAAc,CAAC;IAC7B,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,IAAI,+BAA+B;CAC7C;AAiCD,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,GAAG,EAAE,YAAY,GAAG,eAAe,EAAE,CA2BjG;AAED,wBAAgB,aAAa,CAC3B,UAAU,EAAE,eAAe,EAAE,EAC7B,GAAG,EAAE,YAAY,GAChB,eAAe,GAAG,IAAI,CAExB"}
|
package/dist/router.js
CHANGED
|
@@ -1,48 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
case "cheapest":
|
|
4
|
-
return { quality: 0.5, cost: 2.0, latency: 1.0, preferSubscription: 1, preferApi: 1 };
|
|
5
|
-
case "strongest":
|
|
6
|
-
return { quality: 2.0, cost: 0.2, latency: 0.5, preferSubscription: 1, preferApi: 1 };
|
|
7
|
-
case "burn":
|
|
8
|
-
return { quality: 2.0, cost: 0.0, latency: 0.2, preferSubscription: 1, preferApi: 1 };
|
|
9
|
-
case "subscription-first":
|
|
10
|
-
return { quality: 1.0, cost: 0.5, latency: 0.5, preferSubscription: 1.6, preferApi: 0.6 };
|
|
11
|
-
case "api-overflow":
|
|
12
|
-
return { quality: 1.0, cost: 0.8, latency: 0.5, preferSubscription: 0.6, preferApi: 1.6 };
|
|
13
|
-
default:
|
|
14
|
-
return { quality: 1.0, cost: 0.7, latency: 0.5, preferSubscription: 1.1, preferApi: 1.0 };
|
|
15
|
-
}
|
|
1
|
+
export class RoutingPreflightError extends Error {
|
|
2
|
+
code = "routing_preflight_refused";
|
|
16
3
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const diversity = ctx.diversityAgainst?.includes(c.providerFamily) ? 0.5 : 1;
|
|
24
|
-
const authPref = c.authMode === "local_session" ? w.preferSubscription : c.authMode === "api_key" ? w.preferApi : 1;
|
|
25
|
-
const conserve = (ctx.portfolio === "conserve-claude" && c.providerFamily === "anthropic") ||
|
|
26
|
-
(ctx.portfolio === "conserve-codex" && c.providerFamily === "openai")
|
|
27
|
-
? 0.4
|
|
28
|
-
: 1;
|
|
29
|
-
const cost = Math.max(0.0001, c.costPerCall ?? 0.01);
|
|
30
|
-
const latency = Math.max(0.1, (c.latencyMs ?? 1000) / 1000);
|
|
31
|
-
const costFactor = cost ** w.cost;
|
|
32
|
-
const latencyFactor = latency ** w.latency;
|
|
33
|
-
return (quality * headroom * diversity * authPref * conserve) / (costFactor * latencyFactor);
|
|
4
|
+
function tierIndex(candidate, ctx) {
|
|
5
|
+
const tiers = ctx.qualityTiers[ctx.intent] ?? [];
|
|
6
|
+
const index = tiers.findIndex((tier) => tier.some((route) => route.harness === candidate.harnessId &&
|
|
7
|
+
route.model === candidate.model &&
|
|
8
|
+
route.effort === candidate.effort));
|
|
9
|
+
return index < 0 ? null : index;
|
|
34
10
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
11
|
+
function isIncrementalPaid(candidate) {
|
|
12
|
+
return !["proven_zero", "subscription_entitlement"].includes(candidate.billingKnowledge ?? "unknown");
|
|
13
|
+
}
|
|
14
|
+
function eligible(candidates, ctx) {
|
|
15
|
+
const ready = candidates.filter((candidate) => candidate.available &&
|
|
16
|
+
!ctx.ledger.cooldownActive(candidate.harnessId, candidate.credentialRoute));
|
|
17
|
+
const free = ready.filter((candidate) => !isIncrementalPaid(candidate));
|
|
18
|
+
if (ctx.paidFallback === "never")
|
|
19
|
+
return free;
|
|
20
|
+
if (ctx.paidFallback === "when_unavailable" && free.length > 0)
|
|
21
|
+
return free;
|
|
22
|
+
return ready;
|
|
23
|
+
}
|
|
24
|
+
/** Order candidates transparently; lower tuple values win. Unknown quota remains eligible. */
|
|
25
|
+
export function rankHarnesses(candidates, ctx) {
|
|
26
|
+
const routes = eligible(candidates, ctx);
|
|
27
|
+
if (ctx.goal === "quality" && routes.every((candidate) => tierIndex(candidate, ctx) === null)) {
|
|
28
|
+
throw new RoutingPreflightError(`quality routing requires a comparable user-declared tier for intent '${ctx.intent}'`);
|
|
45
29
|
}
|
|
46
|
-
return
|
|
30
|
+
return routes.toSorted((a, b) => {
|
|
31
|
+
const aTier = tierIndex(a, ctx) ?? Number.MAX_SAFE_INTEGER;
|
|
32
|
+
const bTier = tierIndex(b, ctx) ?? Number.MAX_SAFE_INTEGER;
|
|
33
|
+
if (ctx.goal === "quality")
|
|
34
|
+
return aTier - bTier;
|
|
35
|
+
if (ctx.goal === "economy") {
|
|
36
|
+
const aPaid = isIncrementalPaid(a) ? 1 : 0;
|
|
37
|
+
const bPaid = isIncrementalPaid(b) ? 1 : 0;
|
|
38
|
+
const paidOrder = aPaid - bPaid;
|
|
39
|
+
if (paidOrder !== 0)
|
|
40
|
+
return paidOrder;
|
|
41
|
+
const aCost = a.incrementalCostUsd ?? Number.POSITIVE_INFINITY;
|
|
42
|
+
const bCost = b.incrementalCostUsd ?? Number.POSITIVE_INFINITY;
|
|
43
|
+
return aCost - bCost || aTier - bTier;
|
|
44
|
+
}
|
|
45
|
+
const aSlack = ctx.ledger.bindingPaceSlack(a.harnessId, a.credentialRoute);
|
|
46
|
+
const bSlack = ctx.ledger.bindingPaceSlack(b.harnessId, b.credentialRoute);
|
|
47
|
+
if (aSlack !== null || bSlack !== null) {
|
|
48
|
+
return (bSlack ?? Number.NEGATIVE_INFINITY) - (aSlack ?? Number.NEGATIVE_INFINITY);
|
|
49
|
+
}
|
|
50
|
+
return aTier - bTier;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
export function selectHarness(candidates, ctx) {
|
|
54
|
+
return rankHarnesses(candidates, ctx)[0] ?? null;
|
|
47
55
|
}
|
|
48
56
|
//# sourceMappingURL=router.js.map
|
package/dist/router.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AA6BA,
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claudexor/budget",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"description": "Budget governor: pre-call
|
|
5
|
+
"description": "Budget governor: pre-call leases, circuit breaker, evidence-based routing goals, and multi-window quota pacing.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
"dist"
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@claudexor/
|
|
20
|
-
"@claudexor/
|
|
19
|
+
"@claudexor/util": "2.0.0",
|
|
20
|
+
"@claudexor/schema": "2.0.0"
|
|
21
21
|
},
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|