@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.
- package/LICENSE +63 -0
- package/PATENTS.md +16 -0
- package/README.md +80 -0
- package/dist/cost-table.d.ts +53 -0
- package/dist/cost-table.d.ts.map +1 -0
- package/dist/cost-table.js +108 -0
- package/dist/cost-table.js.map +1 -0
- package/dist/decision-log.d.ts +98 -0
- package/dist/decision-log.d.ts.map +1 -0
- package/dist/decision-log.js +233 -0
- package/dist/decision-log.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/policy.d.ts +47 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +239 -0
- package/dist/policy.js.map +1 -0
- package/dist/spend-guard.d.ts +108 -0
- package/dist/spend-guard.d.ts.map +1 -0
- package/dist/spend-guard.js +154 -0
- package/dist/spend-guard.js.map +1 -0
- package/dist/store-memory.d.ts +28 -0
- package/dist/store-memory.d.ts.map +1 -0
- package/dist/store-memory.js +70 -0
- package/dist/store-memory.js.map +1 -0
- package/dist/types.d.ts +186 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decision-log.js","sourceRoot":"","sources":["../src/decision-log.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|
package/dist/policy.d.ts
ADDED
|
@@ -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"}
|