@agentguard-run/spend 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-log.js","sourceRoot":"","sources":["../src/decision-log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * AgentGuard(TM) Spend — Public API
3
+ *
4
+ * Patent notice: Protected by U.S. patent-pending technology
5
+ * (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
6
+ * and an additional application filed May 2026).
7
+ */
8
+ export type { SpendAction, SpendWindow, Provider, EnforcementMode, CapabilityTier, SpendCap, SpendScope, SpendPolicy, CallContext, SpendDecision, SignedDecisionLogEntry, SpendStore, DecisionLogStore, } from './types';
9
+ export { getModelCost, setCostOverride, clearCostOverrides, computeCallCents, inferProvider, type ModelCost, } from './cost-table';
10
+ export { evaluatePolicy, buildScopeKey } from './policy';
11
+ export { canonicalJson, sha256Hex, computeEntryHash, computeSignerFingerprint, signDecision, verifyEntry, verifyChain, GENESIS_PREVIOUS_HASH, InMemoryDecisionLogStore, } from './decision-log';
12
+ export { InMemorySpendStore } from './store-memory';
13
+ export { SpendGuard, withSpendGuard, AgentGuardBlockedError, type SpendGuardConfig, type OpenAIBindingOptions, } from './spend-guard';
14
+ export declare const AGENTGUARD_SPEND_VERSION = "0.1.0-alpha.1";
15
+ /** Patent marking. 35 U.S.C. § 287 constructive notice. */
16
+ export declare const PATENT_NOTICE: string;
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EACV,WAAW,EACX,WAAW,EACX,QAAQ,EACR,eAAe,EACf,cAAc,EACd,QAAQ,EACR,UAAU,EACV,WAAW,EACX,WAAW,EACX,aAAa,EACb,sBAAsB,EACtB,UAAU,EACV,gBAAgB,GACjB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,YAAY,EACZ,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,KAAK,SAAS,GACf,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzD,OAAO,EACL,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,wBAAwB,EACxB,YAAY,EACZ,WAAW,EACX,WAAW,EACX,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGpD,OAAO,EACL,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,GAC1B,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AAExD,2DAA2D;AAC3D,eAAO,MAAM,aAAa,QAIK,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ /**
3
+ * AgentGuard(TM) Spend — Public API
4
+ *
5
+ * Patent notice: Protected by U.S. patent-pending technology
6
+ * (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
7
+ * and an additional application filed May 2026).
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.PATENT_NOTICE = exports.AGENTGUARD_SPEND_VERSION = exports.AgentGuardBlockedError = exports.withSpendGuard = exports.SpendGuard = exports.InMemorySpendStore = exports.InMemoryDecisionLogStore = exports.GENESIS_PREVIOUS_HASH = exports.verifyChain = exports.verifyEntry = exports.signDecision = exports.computeSignerFingerprint = exports.computeEntryHash = exports.sha256Hex = exports.canonicalJson = exports.buildScopeKey = exports.evaluatePolicy = exports.inferProvider = exports.computeCallCents = exports.clearCostOverrides = exports.setCostOverride = exports.getModelCost = void 0;
11
+ // Cost table
12
+ var cost_table_1 = require("./cost-table");
13
+ Object.defineProperty(exports, "getModelCost", { enumerable: true, get: function () { return cost_table_1.getModelCost; } });
14
+ Object.defineProperty(exports, "setCostOverride", { enumerable: true, get: function () { return cost_table_1.setCostOverride; } });
15
+ Object.defineProperty(exports, "clearCostOverrides", { enumerable: true, get: function () { return cost_table_1.clearCostOverrides; } });
16
+ Object.defineProperty(exports, "computeCallCents", { enumerable: true, get: function () { return cost_table_1.computeCallCents; } });
17
+ Object.defineProperty(exports, "inferProvider", { enumerable: true, get: function () { return cost_table_1.inferProvider; } });
18
+ // Policy engine
19
+ var policy_1 = require("./policy");
20
+ Object.defineProperty(exports, "evaluatePolicy", { enumerable: true, get: function () { return policy_1.evaluatePolicy; } });
21
+ Object.defineProperty(exports, "buildScopeKey", { enumerable: true, get: function () { return policy_1.buildScopeKey; } });
22
+ // Decision log
23
+ var decision_log_1 = require("./decision-log");
24
+ Object.defineProperty(exports, "canonicalJson", { enumerable: true, get: function () { return decision_log_1.canonicalJson; } });
25
+ Object.defineProperty(exports, "sha256Hex", { enumerable: true, get: function () { return decision_log_1.sha256Hex; } });
26
+ Object.defineProperty(exports, "computeEntryHash", { enumerable: true, get: function () { return decision_log_1.computeEntryHash; } });
27
+ Object.defineProperty(exports, "computeSignerFingerprint", { enumerable: true, get: function () { return decision_log_1.computeSignerFingerprint; } });
28
+ Object.defineProperty(exports, "signDecision", { enumerable: true, get: function () { return decision_log_1.signDecision; } });
29
+ Object.defineProperty(exports, "verifyEntry", { enumerable: true, get: function () { return decision_log_1.verifyEntry; } });
30
+ Object.defineProperty(exports, "verifyChain", { enumerable: true, get: function () { return decision_log_1.verifyChain; } });
31
+ Object.defineProperty(exports, "GENESIS_PREVIOUS_HASH", { enumerable: true, get: function () { return decision_log_1.GENESIS_PREVIOUS_HASH; } });
32
+ Object.defineProperty(exports, "InMemoryDecisionLogStore", { enumerable: true, get: function () { return decision_log_1.InMemoryDecisionLogStore; } });
33
+ // In-memory spend store
34
+ var store_memory_1 = require("./store-memory");
35
+ Object.defineProperty(exports, "InMemorySpendStore", { enumerable: true, get: function () { return store_memory_1.InMemorySpendStore; } });
36
+ // Core wrapper
37
+ var spend_guard_1 = require("./spend-guard");
38
+ Object.defineProperty(exports, "SpendGuard", { enumerable: true, get: function () { return spend_guard_1.SpendGuard; } });
39
+ Object.defineProperty(exports, "withSpendGuard", { enumerable: true, get: function () { return spend_guard_1.withSpendGuard; } });
40
+ Object.defineProperty(exports, "AgentGuardBlockedError", { enumerable: true, get: function () { return spend_guard_1.AgentGuardBlockedError; } });
41
+ exports.AGENTGUARD_SPEND_VERSION = '0.1.0-alpha.1';
42
+ /** Patent marking. 35 U.S.C. § 287 constructive notice. */
43
+ exports.PATENT_NOTICE = 'Protected by U.S. patent-pending technology ' +
44
+ '(App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626; ' +
45
+ 'and an additional application filed May 2026). ' +
46
+ 'Additional patents pending.';
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAmBH,aAAa;AACb,2CAOsB;AANpB,0GAAA,YAAY,OAAA;AACZ,6GAAA,eAAe,OAAA;AACf,gHAAA,kBAAkB,OAAA;AAClB,8GAAA,gBAAgB,OAAA;AAChB,2GAAA,aAAa,OAAA;AAIf,gBAAgB;AAChB,mCAAyD;AAAhD,wGAAA,cAAc,OAAA;AAAE,uGAAA,aAAa,OAAA;AAEtC,eAAe;AACf,+CAUwB;AATtB,6GAAA,aAAa,OAAA;AACb,yGAAA,SAAS,OAAA;AACT,gHAAA,gBAAgB,OAAA;AAChB,wHAAA,wBAAwB,OAAA;AACxB,4GAAA,YAAY,OAAA;AACZ,2GAAA,WAAW,OAAA;AACX,2GAAA,WAAW,OAAA;AACX,qHAAA,qBAAqB,OAAA;AACrB,wHAAA,wBAAwB,OAAA;AAG1B,wBAAwB;AACxB,+CAAoD;AAA3C,kHAAA,kBAAkB,OAAA;AAE3B,eAAe;AACf,6CAMuB;AALrB,yGAAA,UAAU,OAAA;AACV,6GAAA,cAAc,OAAA;AACd,qHAAA,sBAAsB,OAAA;AAKX,QAAA,wBAAwB,GAAG,eAAe,CAAC;AAExD,2DAA2D;AAC9C,QAAA,aAAa,GACxB,8CAA8C;IAC9C,6DAA6D;IAC7D,iDAAiD;IACjD,6BAA6B,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * AgentGuard(TM) Spend — Policy evaluation engine
3
+ *
4
+ * Evaluates a SpendPolicy against a CallContext and returns a SpendDecision.
5
+ * Pure function over inputs and the spend store; no network calls, no provider
6
+ * SDK dependencies, no data plane involvement.
7
+ *
8
+ * Patent notice: Protected by U.S. patent-pending technology
9
+ * (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
10
+ * and an additional application filed May 2026).
11
+ */
12
+ import type { SpendPolicy, CallContext, SpendDecision, SpendStore, SpendScope, SpendAction } from './types';
13
+ /**
14
+ * Build a deterministic scope key from a SpendScope. The key identifies a
15
+ * single (tenant, user, team, agent, provider) combination for storing window
16
+ * spend totals.
17
+ */
18
+ export declare function buildScopeKey(scope: SpendScope): string;
19
+ /**
20
+ * Returns true if the cap's scope shape is satisfied by the call's scope.
21
+ *
22
+ * A cap matches if every non-empty field in the cap's policy scope is present
23
+ * AND equal in the call's scope. Empty fields in the policy scope are
24
+ * wildcards (match anything).
25
+ */
26
+ declare function policyMatchesCall(policyScope: SpendScope, callScope: SpendScope): boolean;
27
+ declare function mostRestrictive(a: SpendAction, b: SpendAction): SpendAction;
28
+ /**
29
+ * Evaluate the policy against the call. Returns a SpendDecision describing the
30
+ * action to take, the cap that triggered it (if any), and the projected vs
31
+ * actual spend in the relevant window.
32
+ *
33
+ * Side effect: on 'allow' and 'downgrade', this function INCREMENTS the window
34
+ * spend. On 'block' and 'shadow' the increment is NOT applied (a blocked call
35
+ * does not cost anything; a shadow call is observed but not yet wired through).
36
+ * Callers that need to count shadow calls toward spend should increment
37
+ * explicitly after the provider call returns.
38
+ */
39
+ export declare function evaluatePolicy(policy: SpendPolicy, call: CallContext, store: SpendStore): Promise<SpendDecision>;
40
+ declare function capabilityMeetsRequirement(claimed: NonNullable<SpendPolicy['requiredCapability']>, required: NonNullable<SpendPolicy['requiredCapability']>): boolean;
41
+ export declare const _testing: {
42
+ mostRestrictive: typeof mostRestrictive;
43
+ policyMatchesCall: typeof policyMatchesCall;
44
+ capabilityMeetsRequirement: typeof capabilityMeetsRequirement;
45
+ };
46
+ export {};
47
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,aAAa,EACb,UAAU,EAEV,UAAU,EAEV,WAAW,EACZ,MAAM,SAAS,CAAC;AAGjB;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAUvD;AAED;;;;;;GAMG;AACH,iBAAS,iBAAiB,CAAC,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAQlF;AAaD,iBAAS,eAAe,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,GAAG,WAAW,CAEpE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,aAAa,CAAC,CA2KxB;AASD,iBAAS,0BAA0B,CACjC,OAAO,EAAE,WAAW,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC,EACvD,QAAQ,EAAE,WAAW,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC,GACvD,OAAO,CAET;AAGD,eAAO,MAAM,QAAQ;;;;CAAqE,CAAC"}
package/dist/policy.js ADDED
@@ -0,0 +1,239 @@
1
+ "use strict";
2
+ /**
3
+ * AgentGuard(TM) Spend — Policy evaluation engine
4
+ *
5
+ * Evaluates a SpendPolicy against a CallContext and returns a SpendDecision.
6
+ * Pure function over inputs and the spend store; no network calls, no provider
7
+ * SDK dependencies, no data plane involvement.
8
+ *
9
+ * Patent notice: Protected by U.S. patent-pending technology
10
+ * (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
11
+ * and an additional application filed May 2026).
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports._testing = void 0;
15
+ exports.buildScopeKey = buildScopeKey;
16
+ exports.evaluatePolicy = evaluatePolicy;
17
+ const crypto_1 = require("crypto");
18
+ const cost_table_1 = require("./cost-table");
19
+ /**
20
+ * Build a deterministic scope key from a SpendScope. The key identifies a
21
+ * single (tenant, user, team, agent, provider) combination for storing window
22
+ * spend totals.
23
+ */
24
+ function buildScopeKey(scope) {
25
+ const parts = [
26
+ `tenant=${scope.tenantId}`,
27
+ scope.userId ? `user=${scope.userId}` : '',
28
+ scope.teamId ? `team=${scope.teamId}` : '',
29
+ scope.agentId ? `agent=${scope.agentId}` : '',
30
+ scope.taskId ? `task=${scope.taskId}` : '',
31
+ scope.provider ? `prov=${scope.provider}` : '',
32
+ ].filter(Boolean);
33
+ return parts.join('|');
34
+ }
35
+ /**
36
+ * Returns true if the cap's scope shape is satisfied by the call's scope.
37
+ *
38
+ * A cap matches if every non-empty field in the cap's policy scope is present
39
+ * AND equal in the call's scope. Empty fields in the policy scope are
40
+ * wildcards (match anything).
41
+ */
42
+ function policyMatchesCall(policyScope, callScope) {
43
+ if (policyScope.tenantId !== callScope.tenantId)
44
+ return false;
45
+ if (policyScope.userId && policyScope.userId !== callScope.userId)
46
+ return false;
47
+ if (policyScope.teamId && policyScope.teamId !== callScope.teamId)
48
+ return false;
49
+ if (policyScope.agentId && policyScope.agentId !== callScope.agentId)
50
+ return false;
51
+ if (policyScope.taskId && policyScope.taskId !== callScope.taskId)
52
+ return false;
53
+ if (policyScope.provider && policyScope.provider !== callScope.provider)
54
+ return false;
55
+ return true;
56
+ }
57
+ /**
58
+ * Restrictiveness order: block > downgrade > shadow > allow. Used to combine
59
+ * actions when multiple caps trigger simultaneously.
60
+ */
61
+ const ACTION_RANK = {
62
+ block: 3,
63
+ downgrade: 2,
64
+ shadow: 1,
65
+ allow: 0,
66
+ };
67
+ function mostRestrictive(a, b) {
68
+ return ACTION_RANK[a] >= ACTION_RANK[b] ? a : b;
69
+ }
70
+ /**
71
+ * Evaluate the policy against the call. Returns a SpendDecision describing the
72
+ * action to take, the cap that triggered it (if any), and the projected vs
73
+ * actual spend in the relevant window.
74
+ *
75
+ * Side effect: on 'allow' and 'downgrade', this function INCREMENTS the window
76
+ * spend. On 'block' and 'shadow' the increment is NOT applied (a blocked call
77
+ * does not cost anything; a shadow call is observed but not yet wired through).
78
+ * Callers that need to count shadow calls toward spend should increment
79
+ * explicitly after the provider call returns.
80
+ */
81
+ async function evaluatePolicy(policy, call, store) {
82
+ const decisionId = (0, crypto_1.randomUUID)();
83
+ const timestamp = new Date().toISOString();
84
+ const reasons = [];
85
+ // 1. Confirm policy applies to this call.
86
+ if (!policyMatchesCall(policy.scope, call.scope)) {
87
+ reasons.push(`Policy ${policy.id} scope does not match call scope`);
88
+ return {
89
+ decisionId,
90
+ timestamp,
91
+ action: 'allow',
92
+ triggeredCap: null,
93
+ triggeredScopeKey: null,
94
+ projectedCents: 0,
95
+ windowSpendBefore: 0,
96
+ windowSpendAfter: 0,
97
+ provider: call.provider ?? (0, cost_table_1.inferProvider)(call.model),
98
+ modelRequested: call.model,
99
+ modelResolved: call.model,
100
+ policyId: policy.id,
101
+ policyVersion: policy.version,
102
+ reasons,
103
+ };
104
+ }
105
+ // 2. Capability gate (Patent D §7.3 reduction). If the policy requires a
106
+ // capability tier and the caller's claim is below it, block immediately.
107
+ if (policy.requiredCapability) {
108
+ const claimed = call.capabilityClaim;
109
+ if (!claimed || !capabilityMeetsRequirement(claimed, policy.requiredCapability)) {
110
+ reasons.push(`Capability '${claimed ?? 'none'}' below required '${policy.requiredCapability}'`);
111
+ return {
112
+ decisionId,
113
+ timestamp,
114
+ action: 'block',
115
+ triggeredCap: null,
116
+ triggeredScopeKey: null,
117
+ projectedCents: 0,
118
+ windowSpendBefore: 0,
119
+ windowSpendAfter: 0,
120
+ provider: call.provider ?? (0, cost_table_1.inferProvider)(call.model),
121
+ modelRequested: call.model,
122
+ modelResolved: call.model,
123
+ policyId: policy.id,
124
+ policyVersion: policy.version,
125
+ reasons,
126
+ };
127
+ }
128
+ }
129
+ // 3. Compute projected cost.
130
+ const projectedCents = (0, cost_table_1.computeCallCents)(call.model, call.inputTokens, call.outputTokens);
131
+ if (projectedCents === null) {
132
+ reasons.push(`Unknown model '${call.model}', no cost data — defaulting to allow`);
133
+ return {
134
+ decisionId,
135
+ timestamp,
136
+ action: policy.mode === 'enforce' ? 'block' : 'allow',
137
+ triggeredCap: null,
138
+ triggeredScopeKey: null,
139
+ projectedCents: 0,
140
+ windowSpendBefore: 0,
141
+ windowSpendAfter: 0,
142
+ provider: call.provider ?? (0, cost_table_1.inferProvider)(call.model),
143
+ modelRequested: call.model,
144
+ modelResolved: call.model,
145
+ policyId: policy.id,
146
+ policyVersion: policy.version,
147
+ reasons,
148
+ };
149
+ }
150
+ // 4. Evaluate caps in order. First triggered cap wins; if multiple caps would
151
+ // fire on this call, the most restrictive action is selected.
152
+ let chosenAction = 'allow';
153
+ let triggeredCap = null;
154
+ let triggeredScopeKey = null;
155
+ let windowSpendBefore = 0;
156
+ let windowSpendAfter = 0;
157
+ let modelResolved = call.model;
158
+ const scopeKey = buildScopeKey(call.scope);
159
+ for (const cap of policy.caps) {
160
+ const currentSpend = await store.getWindowSpend(scopeKey, cap.window);
161
+ const projectedTotal = currentSpend + projectedCents;
162
+ if (projectedTotal > cap.amountCents) {
163
+ const candidateAction = cap.action;
164
+ if (ACTION_RANK[candidateAction] > ACTION_RANK[chosenAction]) {
165
+ chosenAction = candidateAction;
166
+ triggeredCap = cap;
167
+ triggeredScopeKey = scopeKey;
168
+ windowSpendBefore = currentSpend;
169
+ windowSpendAfter = projectedTotal;
170
+ if (candidateAction === 'downgrade' && cap.downgradeTo) {
171
+ modelResolved = cap.downgradeTo;
172
+ }
173
+ reasons.push(`Cap '${cap.window}=${cap.amountCents}c' exceeded ` +
174
+ `(spent=${currentSpend}c, +call=${projectedCents}c, total=${projectedTotal}c) ` +
175
+ `→ ${candidateAction}` +
176
+ (cap.reason ? ` (${cap.reason})` : ''));
177
+ }
178
+ }
179
+ }
180
+ if (chosenAction === 'allow') {
181
+ reasons.push(`All caps within budget (call=${projectedCents}c, model=${call.model}, scope=${scopeKey})`);
182
+ windowSpendBefore = 0;
183
+ windowSpendAfter = projectedCents;
184
+ }
185
+ // 5. Apply enforcement mode. In SHADOW mode, downgrade with the same cap to
186
+ // 'shadow' (log only, do not block or rewrite). CANARY mode applies the
187
+ // enforcement for a 5% sticky slice of agents (handled by caller via
188
+ // wrapper.ts). ENFORCE mode applies the chosen action as-is.
189
+ const effectiveAction = policy.mode === 'shadow' && (chosenAction === 'block' || chosenAction === 'downgrade')
190
+ ? 'shadow'
191
+ : chosenAction;
192
+ // 6. If action is allow or downgrade, increment the window spend for caps
193
+ // that did NOT trigger (so future calls see the running total).
194
+ // On block/shadow we do not increment because the call did not (or will
195
+ // not) actually execute against the provider.
196
+ // On downgrade, the customer pays for the RESOLVED model, not the original.
197
+ // Recompute the actual cost so the budget is charged correctly.
198
+ let chargedCents = projectedCents;
199
+ if (effectiveAction === 'downgrade' && modelResolved !== call.model) {
200
+ const downgradedCost = (0, cost_table_1.computeCallCents)(modelResolved, call.inputTokens, call.outputTokens);
201
+ if (downgradedCost !== null)
202
+ chargedCents = downgradedCost;
203
+ }
204
+ if (effectiveAction === 'allow' || effectiveAction === 'downgrade') {
205
+ // Track spend against the same windows the policy cares about.
206
+ const windowsToTrack = new Set(policy.caps.map((c) => c.window));
207
+ for (const w of windowsToTrack) {
208
+ await store.incrementWindowSpend(scopeKey, w, chargedCents);
209
+ }
210
+ }
211
+ return {
212
+ decisionId,
213
+ timestamp,
214
+ action: effectiveAction,
215
+ triggeredCap,
216
+ triggeredScopeKey,
217
+ projectedCents,
218
+ windowSpendBefore,
219
+ windowSpendAfter,
220
+ provider: call.provider ?? (0, cost_table_1.inferProvider)(call.model),
221
+ modelRequested: call.model,
222
+ modelResolved,
223
+ policyId: policy.id,
224
+ policyVersion: policy.version,
225
+ reasons,
226
+ };
227
+ }
228
+ const CAPABILITY_ORDER = {
229
+ read_only: 0,
230
+ data_write: 1,
231
+ payment_initiate: 2,
232
+ payment_execute: 3,
233
+ };
234
+ function capabilityMeetsRequirement(claimed, required) {
235
+ return CAPABILITY_ORDER[claimed] >= CAPABILITY_ORDER[required];
236
+ }
237
+ // Re-export combining helper for tests and external callers.
238
+ exports._testing = { mostRestrictive, policyMatchesCall, capabilityMeetsRequirement };
239
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * AgentGuard(TM) Spend — Core SDK entry point
3
+ *
4
+ * `withSpendGuard()` wraps a provider SDK client (OpenAI, Anthropic, Bedrock)
5
+ * and enforces a SpendPolicy locally before each call is sent to the provider.
6
+ *
7
+ * Design rule: ZERO DATA PLANE INVOLVEMENT.
8
+ * - Prompts never leave the customer process.
9
+ * - Provider API keys never leave the customer process.
10
+ * - The signing key never leaves the customer process.
11
+ * - All decisions and the entire signed log live in the customer's storage.
12
+ *
13
+ * Patent notice: Protected by U.S. patent-pending technology
14
+ * (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626;
15
+ * and an additional application filed May 2026).
16
+ */
17
+ import type { SpendPolicy, CallContext, SpendDecision, SpendStore, DecisionLogStore, SignedDecisionLogEntry, CapabilityTier, SpendScope } from './types';
18
+ /**
19
+ * Configuration for an AgentGuard Spend instance.
20
+ */
21
+ export interface SpendGuardConfig {
22
+ /** The policy to evaluate every call against */
23
+ policy: SpendPolicy;
24
+ /** Spend state store (default: in-memory) */
25
+ spendStore?: SpendStore;
26
+ /** Decision log store (default: in-memory) */
27
+ logStore?: DecisionLogStore;
28
+ /** Ed25519 signing keys; if omitted, decisions are NOT signed (alpha-only). */
29
+ signingKeys?: {
30
+ /** 32-byte Ed25519 secret seed */
31
+ privateKey: Uint8Array;
32
+ /** 32-byte Ed25519 public key */
33
+ publicKey: Uint8Array;
34
+ };
35
+ /** Optional hook fired on every decision (useful for OTel / SIEM export) */
36
+ onDecision?: (decision: SpendDecision, signed: SignedDecisionLogEntry | null) => void | Promise<void>;
37
+ /** Optional token-count estimator. Defaults to `chars / 4` heuristic. */
38
+ tokenEstimator?: (text: string) => number;
39
+ }
40
+ export declare class SpendGuard {
41
+ private config;
42
+ private spendStore;
43
+ private logStore;
44
+ private nextSequence;
45
+ private previousHash;
46
+ constructor(config: SpendGuardConfig);
47
+ /**
48
+ * Hydrate the chain pointer from the log store. Call this once at startup
49
+ * if the log store is persistent and may already contain entries from a
50
+ * previous run.
51
+ */
52
+ hydrate(): Promise<void>;
53
+ /**
54
+ * Evaluate the policy for a call and append to the decision log.
55
+ * Returns the decision plus the signed log entry (or null if unsigned).
56
+ */
57
+ decide(call: CallContext): Promise<{
58
+ decision: SpendDecision;
59
+ signed: SignedDecisionLogEntry | null;
60
+ }>;
61
+ /** Default token estimator: 1 token ≈ 4 characters of English. */
62
+ private defaultTokenEstimator;
63
+ /** Estimate tokens for a string using the configured estimator. */
64
+ estimateTokens(text: string): number;
65
+ /** Expose the spend store for tests and dashboards. */
66
+ getSpendStore(): SpendStore;
67
+ /** Expose the log store for tests and dashboards. */
68
+ getLogStore(): DecisionLogStore;
69
+ }
70
+ /**
71
+ * Drop-in wrapper for an OpenAI v5+ client.
72
+ *
73
+ * Usage:
74
+ * import OpenAI from 'openai';
75
+ * import { withSpendGuard } from '@merchantguard/agentguard-spend';
76
+ *
77
+ * const openai = new OpenAI();
78
+ * const policy: SpendPolicy = { ... };
79
+ * const guarded = withSpendGuard(openai, { policy, scope: { tenantId, userId } });
80
+ *
81
+ * const completion = await guarded.chat.completions.create({
82
+ * model: 'gpt-5',
83
+ * messages: [{ role: 'user', content: 'hi' }],
84
+ * });
85
+ *
86
+ * Internals:
87
+ * - On every chat.completions.create call we estimate input tokens, decide
88
+ * under the policy, then either pass through, downgrade the model, or
89
+ * short-circuit with a structured `AgentGuardBlockedError`.
90
+ * - After the call returns, we record the actual output tokens for true-up.
91
+ */
92
+ export interface OpenAIBindingOptions {
93
+ policy: SpendPolicy;
94
+ scope: SpendScope;
95
+ capabilityClaim?: CapabilityTier;
96
+ config?: Omit<SpendGuardConfig, 'policy'>;
97
+ }
98
+ export declare class AgentGuardBlockedError extends Error {
99
+ decision: SpendDecision;
100
+ constructor(decision: SpendDecision);
101
+ }
102
+ /**
103
+ * Wrap an OpenAI client. Returns a proxy whose chat.completions.create
104
+ * enforces the spend policy. Other endpoints pass through untouched in this
105
+ * alpha; subsequent releases will cover responses, embeddings, and images.
106
+ */
107
+ export declare function withSpendGuard(client: any, opts: OpenAIBindingOptions): any;
108
+ //# sourceMappingURL=spend-guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spend-guard.d.ts","sourceRoot":"","sources":["../src/spend-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,sBAAsB,EAEtB,cAAc,EACd,UAAU,EACX,MAAM,SAAS,CAAC;AAUjB;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gDAAgD;IAChD,MAAM,EAAE,WAAW,CAAC;IACpB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,+EAA+E;IAC/E,WAAW,CAAC,EAAE;QACZ,kCAAkC;QAClC,UAAU,EAAE,UAAU,CAAC;QACvB,iCAAiC;QACjC,SAAS,EAAE,UAAU,CAAC;KACvB,CAAC;IACF,4EAA4E;IAC5E,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtG,yEAAyE;IACzE,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CAC3C;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,QAAQ,CAAmB;IACnC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,YAAY,CAAyB;gBAEjC,MAAM,EAAE,gBAAgB;IAMpC;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;OAGG;IACG,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC;QACvC,QAAQ,EAAE,aAAa,CAAC;QACxB,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;KACvC,CAAC;IAwBF,kEAAkE;IAClE,OAAO,CAAC,qBAAqB;IAI7B,mEAAmE;IACnE,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAKpC,uDAAuD;IACvD,aAAa,IAAI,UAAU;IAI3B,qDAAqD;IACrD,WAAW,IAAI,gBAAgB;CAGhC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,EAAE,UAAU,CAAC;IAClB,eAAe,CAAC,EAAE,cAAc,CAAC;IACjC,MAAM,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;CAC3C;AAED,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,QAAQ,EAAE,aAAa,CAAC;gBACZ,QAAQ,EAAE,aAAa;CAQpC;AAED;;;;GAIG;AAEH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,GAAG,EACX,IAAI,EAAE,oBAAoB,GAEzB,GAAG,CA8CL"}