ai-shield-core 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/dist/audit/logger.d.ts +40 -0
- package/dist/audit/logger.d.ts.map +1 -0
- package/dist/audit/logger.js +100 -0
- package/dist/audit/logger.js.map +1 -0
- package/dist/audit/types.d.ts +12 -0
- package/dist/audit/types.d.ts.map +1 -0
- package/dist/audit/types.js +3 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/cache/lru.d.ts +27 -0
- package/dist/cache/lru.d.ts.map +1 -0
- package/dist/cache/lru.js +74 -0
- package/dist/cache/lru.js.map +1 -0
- package/dist/cost/anomaly.d.ts +10 -0
- package/dist/cost/anomaly.d.ts.map +1 -0
- package/dist/cost/anomaly.js +42 -0
- package/dist/cost/anomaly.js.map +1 -0
- package/dist/cost/pricing.d.ts +7 -0
- package/dist/cost/pricing.d.ts.map +1 -0
- package/dist/cost/pricing.js +51 -0
- package/dist/cost/pricing.js.map +1 -0
- package/dist/cost/tracker.d.ts +24 -0
- package/dist/cost/tracker.d.ts.map +1 -0
- package/dist/cost/tracker.js +136 -0
- package/dist/cost/tracker.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/policy/engine.d.ts +36 -0
- package/dist/policy/engine.d.ts.map +1 -0
- package/dist/policy/engine.js +127 -0
- package/dist/policy/engine.js.map +1 -0
- package/dist/policy/tools.d.ts +25 -0
- package/dist/policy/tools.d.ts.map +1 -0
- package/dist/policy/tools.js +158 -0
- package/dist/policy/tools.js.map +1 -0
- package/dist/scanner/canary.d.ts +9 -0
- package/dist/scanner/canary.d.ts.map +1 -0
- package/dist/scanner/canary.js +19 -0
- package/dist/scanner/canary.js.map +1 -0
- package/dist/scanner/chain.d.ts +17 -0
- package/dist/scanner/chain.d.ts.map +1 -0
- package/dist/scanner/chain.js +69 -0
- package/dist/scanner/chain.js.map +1 -0
- package/dist/scanner/heuristic.d.ts +28 -0
- package/dist/scanner/heuristic.d.ts.map +1 -0
- package/dist/scanner/heuristic.js +375 -0
- package/dist/scanner/heuristic.js.map +1 -0
- package/dist/scanner/pii.d.ts +17 -0
- package/dist/scanner/pii.d.ts.map +1 -0
- package/dist/scanner/pii.js +255 -0
- package/dist/scanner/pii.js.map +1 -0
- package/dist/shield.d.ts +31 -0
- package/dist/shield.d.ts.map +1 -0
- package/dist/shield.js +184 -0
- package/dist/shield.js.map +1 -0
- package/dist/types.d.ts +182 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +27 -0
- package/src/audit/logger.ts +135 -0
- package/src/audit/schema.sql +51 -0
- package/src/audit/types.ts +16 -0
- package/src/cache/lru.ts +93 -0
- package/src/cost/anomaly.ts +57 -0
- package/src/cost/pricing.ts +58 -0
- package/src/cost/tracker.ts +182 -0
- package/src/index.ts +91 -0
- package/src/policy/engine.ts +163 -0
- package/src/policy/tools.ts +189 -0
- package/src/scanner/canary.ts +30 -0
- package/src/scanner/chain.ts +88 -0
- package/src/scanner/heuristic.ts +427 -0
- package/src/scanner/pii.ts +313 -0
- package/src/shield.ts +228 -0
- package/src/types.ts +242 -0
- package/tsconfig.json +8 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { AuditRecord, ScanResult, ScanContext } from "../types.js";
|
|
2
|
+
import type { AuditStore } from "./types.js";
|
|
3
|
+
export interface AuditLoggerConfig {
|
|
4
|
+
store: AuditStore;
|
|
5
|
+
batchSize?: number;
|
|
6
|
+
flushIntervalMs?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class AuditLogger {
|
|
9
|
+
private store;
|
|
10
|
+
private buffer;
|
|
11
|
+
private batchSize;
|
|
12
|
+
private flushTimer;
|
|
13
|
+
constructor(config: AuditLoggerConfig);
|
|
14
|
+
/** Log a scan result */
|
|
15
|
+
log(input: string, result: ScanResult, context?: ScanContext, extra?: {
|
|
16
|
+
model?: string;
|
|
17
|
+
outputTokenCount?: number;
|
|
18
|
+
toolsCalled?: string[];
|
|
19
|
+
costUsd?: number;
|
|
20
|
+
}): Promise<void>;
|
|
21
|
+
/** Flush buffered records to store */
|
|
22
|
+
flush(): Promise<void>;
|
|
23
|
+
/** Close the logger (flush + stop timer) */
|
|
24
|
+
close(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export declare class ConsoleAuditStore implements AuditStore {
|
|
27
|
+
write(record: AuditRecord): Promise<void>;
|
|
28
|
+
writeBatch(records: AuditRecord[]): Promise<void>;
|
|
29
|
+
flush(): Promise<void>;
|
|
30
|
+
close(): Promise<void>;
|
|
31
|
+
private print;
|
|
32
|
+
}
|
|
33
|
+
export declare class MemoryAuditStore implements AuditStore {
|
|
34
|
+
records: AuditRecord[];
|
|
35
|
+
write(record: AuditRecord): Promise<void>;
|
|
36
|
+
writeBatch(records: AuditRecord[]): Promise<void>;
|
|
37
|
+
flush(): Promise<void>;
|
|
38
|
+
close(): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/audit/logger.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAO7C,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAA+C;gBAErD,MAAM,EAAE,iBAAiB;IAUrC,wBAAwB;IAClB,GAAG,CACP,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,WAAgB,EACzB,KAAK,GAAE;QACL,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB,OAAO,CAAC,EAAE,MAAM,CAAC;KACb,GACL,OAAO,CAAC,IAAI,CAAC;IA+BhB,sCAAsC;IAChC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAO5B,4CAA4C;IACtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B;AAID,qBAAa,iBAAkB,YAAW,UAAU;IAC5C,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAE5B,OAAO,CAAC,KAAK;CAUd;AAID,qBAAa,gBAAiB,YAAW,UAAU;IACjD,OAAO,EAAE,WAAW,EAAE,CAAM;IAEtB,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAIjD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAC7B"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MemoryAuditStore = exports.ConsoleAuditStore = exports.AuditLogger = void 0;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
const node_crypto_2 = require("node:crypto");
|
|
6
|
+
class AuditLogger {
|
|
7
|
+
store;
|
|
8
|
+
buffer = [];
|
|
9
|
+
batchSize;
|
|
10
|
+
flushTimer = null;
|
|
11
|
+
constructor(config) {
|
|
12
|
+
this.store = config.store;
|
|
13
|
+
this.batchSize = config.batchSize ?? 100;
|
|
14
|
+
const flushMs = config.flushIntervalMs ?? 1000;
|
|
15
|
+
this.flushTimer = setInterval(() => {
|
|
16
|
+
void this.flush();
|
|
17
|
+
}, flushMs);
|
|
18
|
+
}
|
|
19
|
+
/** Log a scan result */
|
|
20
|
+
async log(input, result, context = {}, extra = {}) {
|
|
21
|
+
const record = {
|
|
22
|
+
id: (0, node_crypto_1.randomUUID)(),
|
|
23
|
+
timestamp: new Date(),
|
|
24
|
+
sessionId: context.sessionId,
|
|
25
|
+
agentId: context.agentId,
|
|
26
|
+
userIdHash: context.userId
|
|
27
|
+
? (0, node_crypto_2.createHash)("sha256").update(context.userId).digest("hex").substring(0, 16)
|
|
28
|
+
: undefined,
|
|
29
|
+
requestType: context.tools?.length ? "tool_call" : "chat",
|
|
30
|
+
inputHash: (0, node_crypto_2.createHash)("sha256").update(input).digest("hex"),
|
|
31
|
+
inputTokenCount: Math.ceil(input.length / 4), // rough estimate
|
|
32
|
+
model: extra.model,
|
|
33
|
+
securityDecision: result.decision,
|
|
34
|
+
securityReason: result.violations.length > 0
|
|
35
|
+
? result.violations.map((v) => v.message).join("; ")
|
|
36
|
+
: undefined,
|
|
37
|
+
violations: result.violations,
|
|
38
|
+
scanDurationMs: result.meta.scanDurationMs,
|
|
39
|
+
outputTokenCount: extra.outputTokenCount,
|
|
40
|
+
toolsCalled: extra.toolsCalled,
|
|
41
|
+
costUsd: extra.costUsd,
|
|
42
|
+
};
|
|
43
|
+
this.buffer.push(record);
|
|
44
|
+
if (this.buffer.length >= this.batchSize) {
|
|
45
|
+
await this.flush();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Flush buffered records to store */
|
|
49
|
+
async flush() {
|
|
50
|
+
if (this.buffer.length === 0)
|
|
51
|
+
return;
|
|
52
|
+
const batch = this.buffer.splice(0);
|
|
53
|
+
await this.store.writeBatch(batch);
|
|
54
|
+
}
|
|
55
|
+
/** Close the logger (flush + stop timer) */
|
|
56
|
+
async close() {
|
|
57
|
+
if (this.flushTimer) {
|
|
58
|
+
clearInterval(this.flushTimer);
|
|
59
|
+
this.flushTimer = null;
|
|
60
|
+
}
|
|
61
|
+
await this.flush();
|
|
62
|
+
await this.store.close();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.AuditLogger = AuditLogger;
|
|
66
|
+
// --- Console Store (for development) ---
|
|
67
|
+
class ConsoleAuditStore {
|
|
68
|
+
async write(record) {
|
|
69
|
+
this.print(record);
|
|
70
|
+
}
|
|
71
|
+
async writeBatch(records) {
|
|
72
|
+
for (const record of records)
|
|
73
|
+
this.print(record);
|
|
74
|
+
}
|
|
75
|
+
async flush() { }
|
|
76
|
+
async close() { }
|
|
77
|
+
print(record) {
|
|
78
|
+
const icon = record.securityDecision === "block" ? "BLOCK" : record.securityDecision === "warn" ? "WARN " : "ALLOW";
|
|
79
|
+
const violations = record.violations.length > 0
|
|
80
|
+
? ` [${record.violations.map((v) => v.message).join(", ")}]`
|
|
81
|
+
: "";
|
|
82
|
+
// Using stderr to not interfere with application output
|
|
83
|
+
process.stderr.write(`[AI-Shield] ${icon} | ${record.scanDurationMs.toFixed(1)}ms | agent=${record.agentId ?? "-"} | ${record.inputHash.substring(0, 8)}...${violations}\n`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
exports.ConsoleAuditStore = ConsoleAuditStore;
|
|
87
|
+
// --- Memory Store (for testing) ---
|
|
88
|
+
class MemoryAuditStore {
|
|
89
|
+
records = [];
|
|
90
|
+
async write(record) {
|
|
91
|
+
this.records.push(record);
|
|
92
|
+
}
|
|
93
|
+
async writeBatch(records) {
|
|
94
|
+
this.records.push(...records);
|
|
95
|
+
}
|
|
96
|
+
async flush() { }
|
|
97
|
+
async close() { }
|
|
98
|
+
}
|
|
99
|
+
exports.MemoryAuditStore = MemoryAuditStore;
|
|
100
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/audit/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AuditRecord } from "../types.js";
|
|
2
|
+
export interface AuditStore {
|
|
3
|
+
/** Write a single record */
|
|
4
|
+
write(record: AuditRecord): Promise<void>;
|
|
5
|
+
/** Write a batch of records */
|
|
6
|
+
writeBatch(records: AuditRecord[]): Promise<void>;
|
|
7
|
+
/** Flush any buffered records */
|
|
8
|
+
flush(): Promise<void>;
|
|
9
|
+
/** Close the store */
|
|
10
|
+
close(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/audit/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAM/C,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,+BAA+B;IAC/B,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,iCAAiC;IACjC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,sBAAsB;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/audit/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface LRUCacheConfig {
|
|
2
|
+
/** Maximum number of cached entries (default: 1000) */
|
|
3
|
+
maxSize?: number;
|
|
4
|
+
/** Time-to-live in milliseconds (default: 300_000 = 5 minutes) */
|
|
5
|
+
ttlMs?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class ScanLRUCache<V = unknown> {
|
|
8
|
+
private cache;
|
|
9
|
+
private readonly maxSize;
|
|
10
|
+
private readonly ttlMs;
|
|
11
|
+
constructor(config?: LRUCacheConfig);
|
|
12
|
+
/** Get a cached value. Returns undefined on miss or expiry. Promotes to MRU on hit. */
|
|
13
|
+
get(key: string): V | undefined;
|
|
14
|
+
/** Store a value. Evicts LRU entry if at capacity. */
|
|
15
|
+
set(key: string, value: V): void;
|
|
16
|
+
/** Check if key exists and is not expired */
|
|
17
|
+
has(key: string): boolean;
|
|
18
|
+
/** Delete a specific key */
|
|
19
|
+
delete(key: string): boolean;
|
|
20
|
+
/** Clear all entries */
|
|
21
|
+
clear(): void;
|
|
22
|
+
/** Current number of entries (may include expired) */
|
|
23
|
+
get size(): number;
|
|
24
|
+
/** Remove all expired entries. Returns count of removed entries. */
|
|
25
|
+
prune(): number;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=lru.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lru.d.ts","sourceRoot":"","sources":["../../src/cache/lru.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAOD,qBAAa,YAAY,CAAC,CAAC,GAAG,OAAO;IACnC,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,MAAM,GAAE,cAAmB;IAKvC,uFAAuF;IACvF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAe/B,sDAAsD;IACtD,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAgBhC,6CAA6C;IAC7C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,4BAA4B;IAC5B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAI5B,wBAAwB;IACxB,KAAK,IAAI,IAAI;IAIb,sDAAsD;IACtD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,oEAAoE;IACpE,KAAK,IAAI,MAAM;CAWhB"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// LRU Cache — O(1) scan result caching with TTL
|
|
4
|
+
// Uses Map insertion-order for LRU eviction
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.ScanLRUCache = void 0;
|
|
8
|
+
class ScanLRUCache {
|
|
9
|
+
cache = new Map();
|
|
10
|
+
maxSize;
|
|
11
|
+
ttlMs;
|
|
12
|
+
constructor(config = {}) {
|
|
13
|
+
this.maxSize = config.maxSize ?? 1000;
|
|
14
|
+
this.ttlMs = config.ttlMs ?? 300_000;
|
|
15
|
+
}
|
|
16
|
+
/** Get a cached value. Returns undefined on miss or expiry. Promotes to MRU on hit. */
|
|
17
|
+
get(key) {
|
|
18
|
+
const entry = this.cache.get(key);
|
|
19
|
+
if (!entry)
|
|
20
|
+
return undefined;
|
|
21
|
+
if (Date.now() > entry.expiresAt) {
|
|
22
|
+
this.cache.delete(key);
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
// Promote to most-recently-used (Map maintains insertion order)
|
|
26
|
+
this.cache.delete(key);
|
|
27
|
+
this.cache.set(key, entry);
|
|
28
|
+
return entry.value;
|
|
29
|
+
}
|
|
30
|
+
/** Store a value. Evicts LRU entry if at capacity. */
|
|
31
|
+
set(key, value) {
|
|
32
|
+
// Remove existing to update position
|
|
33
|
+
this.cache.delete(key);
|
|
34
|
+
// Evict oldest (first in Map) if at capacity
|
|
35
|
+
if (this.cache.size >= this.maxSize) {
|
|
36
|
+
const oldestKey = this.cache.keys().next().value;
|
|
37
|
+
this.cache.delete(oldestKey);
|
|
38
|
+
}
|
|
39
|
+
this.cache.set(key, {
|
|
40
|
+
value,
|
|
41
|
+
expiresAt: Date.now() + this.ttlMs,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/** Check if key exists and is not expired */
|
|
45
|
+
has(key) {
|
|
46
|
+
return this.get(key) !== undefined;
|
|
47
|
+
}
|
|
48
|
+
/** Delete a specific key */
|
|
49
|
+
delete(key) {
|
|
50
|
+
return this.cache.delete(key);
|
|
51
|
+
}
|
|
52
|
+
/** Clear all entries */
|
|
53
|
+
clear() {
|
|
54
|
+
this.cache.clear();
|
|
55
|
+
}
|
|
56
|
+
/** Current number of entries (may include expired) */
|
|
57
|
+
get size() {
|
|
58
|
+
return this.cache.size;
|
|
59
|
+
}
|
|
60
|
+
/** Remove all expired entries. Returns count of removed entries. */
|
|
61
|
+
prune() {
|
|
62
|
+
const now = Date.now();
|
|
63
|
+
let removed = 0;
|
|
64
|
+
for (const [key, entry] of this.cache) {
|
|
65
|
+
if (now > entry.expiresAt) {
|
|
66
|
+
this.cache.delete(key);
|
|
67
|
+
removed++;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return removed;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
exports.ScanLRUCache = ScanLRUCache;
|
|
74
|
+
//# sourceMappingURL=lru.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lru.js","sourceRoot":"","sources":["../../src/cache/lru.ts"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,gDAAgD;AAChD,4CAA4C;AAC5C,+DAA+D;;;AAc/D,MAAa,YAAY;IACf,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChC,OAAO,CAAS;IAChB,KAAK,CAAS;IAE/B,YAAY,SAAyB,EAAE;QACrC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC;QACtC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC;IACvC,CAAC;IAED,uFAAuF;IACvF,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAE7B,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,gEAAgE;QAChE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC3B,OAAO,KAAK,CAAC,KAAK,CAAC;IACrB,CAAC;IAED,sDAAsD;IACtD,GAAG,CAAC,GAAW,EAAE,KAAQ;QACvB,qCAAqC;QACrC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEvB,6CAA6C;QAC7C,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACpC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAe,CAAC;YAC3D,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YAClB,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK;SACnC,CAAC,CAAC;IACL,CAAC;IAED,6CAA6C;IAC7C,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;IACrC,CAAC;IAED,4BAA4B;IAC5B,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,wBAAwB;IACxB,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,sDAAsD;IACtD,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;IAED,oEAAoE;IACpE,KAAK;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACtC,IAAI,GAAG,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACvB,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AA3ED,oCA2EC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface AnomalyResult {
|
|
2
|
+
isAnomaly: boolean;
|
|
3
|
+
zScore: number;
|
|
4
|
+
currentValue: number;
|
|
5
|
+
mean: number;
|
|
6
|
+
stdDev: number;
|
|
7
|
+
}
|
|
8
|
+
/** Detect anomalies using z-score (>2.5 standard deviations = anomaly) */
|
|
9
|
+
export declare function detectAnomaly(currentValue: number, historicalValues: number[], threshold?: number): AnomalyResult;
|
|
10
|
+
//# sourceMappingURL=anomaly.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anomaly.d.ts","sourceRoot":"","sources":["../../src/cost/anomaly.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAC3B,YAAY,EAAE,MAAM,EACpB,gBAAgB,EAAE,MAAM,EAAE,EAC1B,SAAS,GAAE,MAAY,GACtB,aAAa,CAsCf"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================
|
|
3
|
+
// Cost Anomaly Detection — Z-Score based
|
|
4
|
+
// Flags unusual spending patterns
|
|
5
|
+
// ============================================================
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.detectAnomaly = detectAnomaly;
|
|
8
|
+
/** Detect anomalies using z-score (>2.5 standard deviations = anomaly) */
|
|
9
|
+
function detectAnomaly(currentValue, historicalValues, threshold = 2.5) {
|
|
10
|
+
if (historicalValues.length < 3) {
|
|
11
|
+
// Not enough data to determine anomaly
|
|
12
|
+
return {
|
|
13
|
+
isAnomaly: false,
|
|
14
|
+
zScore: 0,
|
|
15
|
+
currentValue,
|
|
16
|
+
mean: currentValue,
|
|
17
|
+
stdDev: 0,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const mean = historicalValues.reduce((a, b) => a + b, 0) / historicalValues.length;
|
|
21
|
+
const variance = historicalValues.reduce((sum, val) => sum + (val - mean) ** 2, 0) /
|
|
22
|
+
historicalValues.length;
|
|
23
|
+
const stdDev = Math.sqrt(variance);
|
|
24
|
+
if (stdDev === 0) {
|
|
25
|
+
return {
|
|
26
|
+
isAnomaly: currentValue !== mean,
|
|
27
|
+
zScore: currentValue === mean ? 0 : Infinity,
|
|
28
|
+
currentValue,
|
|
29
|
+
mean,
|
|
30
|
+
stdDev: 0,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const zScore = (currentValue - mean) / stdDev;
|
|
34
|
+
return {
|
|
35
|
+
isAnomaly: zScore > threshold,
|
|
36
|
+
zScore,
|
|
37
|
+
currentValue,
|
|
38
|
+
mean,
|
|
39
|
+
stdDev,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=anomaly.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anomaly.js","sourceRoot":"","sources":["../../src/cost/anomaly.ts"],"names":[],"mappings":";AAAA,+DAA+D;AAC/D,yCAAyC;AACzC,kCAAkC;AAClC,+DAA+D;;AAW/D,sCA0CC;AA3CD,0EAA0E;AAC1E,SAAgB,aAAa,CAC3B,YAAoB,EACpB,gBAA0B,EAC1B,YAAoB,GAAG;IAEvB,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChC,uCAAuC;QACvC,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,MAAM,EAAE,CAAC;YACT,YAAY;YACZ,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,CAAC;SACV,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GACR,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,gBAAgB,CAAC,MAAM,CAAC;IACxE,MAAM,QAAQ,GACZ,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACjE,gBAAgB,CAAC,MAAM,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEnC,IAAI,MAAM,KAAK,CAAC,EAAE,CAAC;QACjB,OAAO;YACL,SAAS,EAAE,YAAY,KAAK,IAAI;YAChC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ;YAC5C,YAAY;YACZ,IAAI;YACJ,MAAM,EAAE,CAAC;SACV,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC;IAE9C,OAAO;QACL,SAAS,EAAE,MAAM,GAAG,SAAS;QAC7B,MAAM;QACN,YAAY;QACZ,IAAI;QACJ,MAAM;KACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ModelPricing } from "../types.js";
|
|
2
|
+
export declare const MODEL_PRICING: Record<string, ModelPricing>;
|
|
3
|
+
/** Get pricing for a model, fallback to gpt-4o-mini rates */
|
|
4
|
+
export declare function getModelPricing(model: string): ModelPricing;
|
|
5
|
+
/** Estimate cost for a given number of tokens */
|
|
6
|
+
export declare function estimateCost(model: string, inputTokens: number, outputTokens: number): number;
|
|
7
|
+
//# sourceMappingURL=pricing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../src/cost/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAOhD,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAsBtD,CAAC;AAEF,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAY3D;AAED,iDAAiD;AACjD,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,MAAM,CAMR"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MODEL_PRICING = void 0;
|
|
4
|
+
exports.getModelPricing = getModelPricing;
|
|
5
|
+
exports.estimateCost = estimateCost;
|
|
6
|
+
// ============================================================
|
|
7
|
+
// Model Pricing Table — Updated Feb 2026
|
|
8
|
+
// Prices in USD per 1M tokens
|
|
9
|
+
// ============================================================
|
|
10
|
+
exports.MODEL_PRICING = {
|
|
11
|
+
// OpenAI
|
|
12
|
+
"gpt-5.2": { inputPer1M: 2.50, outputPer1M: 10.0 },
|
|
13
|
+
"gpt-5.1": { inputPer1M: 2.50, outputPer1M: 10.0 },
|
|
14
|
+
"gpt-5": { inputPer1M: 2.50, outputPer1M: 10.0 },
|
|
15
|
+
"gpt-4.1": { inputPer1M: 2.00, outputPer1M: 8.00 },
|
|
16
|
+
"gpt-4o": { inputPer1M: 2.50, outputPer1M: 10.0 },
|
|
17
|
+
"gpt-4o-mini": { inputPer1M: 0.15, outputPer1M: 0.60 },
|
|
18
|
+
"o3": { inputPer1M: 10.0, outputPer1M: 40.0 },
|
|
19
|
+
"o3-mini": { inputPer1M: 1.10, outputPer1M: 4.40 },
|
|
20
|
+
"o4-mini": { inputPer1M: 1.10, outputPer1M: 4.40 },
|
|
21
|
+
// Anthropic
|
|
22
|
+
"claude-opus-4-6": { inputPer1M: 15.0, outputPer1M: 75.0 },
|
|
23
|
+
"claude-sonnet-4-6": { inputPer1M: 3.0, outputPer1M: 15.0 },
|
|
24
|
+
"claude-haiku-4-5": { inputPer1M: 0.80, outputPer1M: 4.0 },
|
|
25
|
+
// Aliases
|
|
26
|
+
"gpt-5.2-turbo": { inputPer1M: 2.50, outputPer1M: 10.0 },
|
|
27
|
+
opus: { inputPer1M: 15.0, outputPer1M: 75.0 },
|
|
28
|
+
sonnet: { inputPer1M: 3.0, outputPer1M: 15.0 },
|
|
29
|
+
haiku: { inputPer1M: 0.80, outputPer1M: 4.0 },
|
|
30
|
+
};
|
|
31
|
+
/** Get pricing for a model, fallback to gpt-4o-mini rates */
|
|
32
|
+
function getModelPricing(model) {
|
|
33
|
+
// Try exact match
|
|
34
|
+
const exact = exports.MODEL_PRICING[model];
|
|
35
|
+
if (exact)
|
|
36
|
+
return exact;
|
|
37
|
+
// Try prefix match (e.g., "gpt-4o-2024-08-06" → "gpt-4o")
|
|
38
|
+
for (const [key, pricing] of Object.entries(exports.MODEL_PRICING)) {
|
|
39
|
+
if (model.startsWith(key))
|
|
40
|
+
return pricing;
|
|
41
|
+
}
|
|
42
|
+
// Fallback
|
|
43
|
+
return { inputPer1M: 0.15, outputPer1M: 0.60 };
|
|
44
|
+
}
|
|
45
|
+
/** Estimate cost for a given number of tokens */
|
|
46
|
+
function estimateCost(model, inputTokens, outputTokens) {
|
|
47
|
+
const pricing = getModelPricing(model);
|
|
48
|
+
return ((inputTokens / 1_000_000) * pricing.inputPer1M +
|
|
49
|
+
(outputTokens / 1_000_000) * pricing.outputPer1M);
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=pricing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../src/cost/pricing.ts"],"names":[],"mappings":";;;AAgCA,0CAYC;AAGD,oCAUC;AAvDD,+DAA+D;AAC/D,yCAAyC;AACzC,8BAA8B;AAC9B,+DAA+D;AAElD,QAAA,aAAa,GAAiC;IACzD,SAAS;IACT,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IAClD,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IAClD,OAAO,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IAChD,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IAClD,QAAQ,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IACjD,aAAa,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IACtD,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IAC7C,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IAClD,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IAElD,YAAY;IACZ,iBAAiB,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IAC1D,mBAAmB,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE;IAC3D,kBAAkB,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;IAE1D,UAAU;IACV,eAAe,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IACxD,IAAI,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;IAC7C,MAAM,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE;IAC9C,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;CAC9C,CAAC;AAEF,6DAA6D;AAC7D,SAAgB,eAAe,CAAC,KAAa;IAC3C,kBAAkB;IAClB,MAAM,KAAK,GAAG,qBAAa,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IAExB,0DAA0D;IAC1D,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,qBAAa,CAAC,EAAE,CAAC;QAC3D,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,OAAO,CAAC;IAC5C,CAAC;IAED,WAAW;IACX,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AACjD,CAAC;AAED,iDAAiD;AACjD,SAAgB,YAAY,CAC1B,KAAa,EACb,WAAmB,EACnB,YAAoB;IAEpB,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACvC,OAAO,CACL,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,UAAU;QAC9C,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,WAAW,CACjD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { BudgetConfig, BudgetCheckResult, CostRecord } from "../types.js";
|
|
2
|
+
/** Minimal Redis interface (compatible with ioredis) */
|
|
3
|
+
export interface RedisLike {
|
|
4
|
+
get(key: string): Promise<string | null>;
|
|
5
|
+
incrbyfloat(key: string, increment: number): Promise<string>;
|
|
6
|
+
expire(key: string, seconds: number): Promise<number>;
|
|
7
|
+
}
|
|
8
|
+
export declare class CostTracker {
|
|
9
|
+
private store;
|
|
10
|
+
private budgets;
|
|
11
|
+
private records;
|
|
12
|
+
constructor(budgets?: Record<string, BudgetConfig>, redis?: RedisLike);
|
|
13
|
+
/** Check if a request is within budget BEFORE sending to LLM */
|
|
14
|
+
checkBudget(entityId: string, model: string, estimatedInputTokens: number, estimatedOutputTokens?: number): Promise<BudgetCheckResult>;
|
|
15
|
+
/** Record actual cost AFTER receiving response */
|
|
16
|
+
recordCost(entityId: string, model: string, inputTokens: number, outputTokens: number): Promise<CostRecord>;
|
|
17
|
+
/** Get current spend for an entity */
|
|
18
|
+
getCurrentSpend(entityId: string): Promise<number>;
|
|
19
|
+
/** Get all recorded costs (for export/audit) */
|
|
20
|
+
getRecords(): CostRecord[];
|
|
21
|
+
private budgetKey;
|
|
22
|
+
private periodSeconds;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/cost/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,iBAAiB,EAEjB,UAAU,EACX,MAAM,aAAa,CAAC;AASrB,wDAAwD;AACxD,MAAM,WAAW,SAAS;IACxB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACzC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACvD;AAgCD,qBAAa,WAAW;IACtB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,OAAO,CAAoB;gBAGjC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAM,EAC1C,KAAK,CAAC,EAAE,SAAS;IAMnB,gEAAgE;IAC1D,WAAW,CACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,oBAAoB,EAAE,MAAM,EAC5B,qBAAqB,GAAE,MAAY,GAClC,OAAO,CAAC,iBAAiB,CAAC;IAgC7B,kDAAkD;IAC5C,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,CAAC;IA+BtB,sCAAsC;IAChC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAOxD,gDAAgD;IAChD,UAAU,IAAI,UAAU,EAAE;IAI1B,OAAO,CAAC,SAAS;IAmBjB,OAAO,CAAC,aAAa;CAUtB"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CostTracker = void 0;
|
|
4
|
+
const pricing_js_1 = require("./pricing.js");
|
|
5
|
+
/** In-memory fallback store */
|
|
6
|
+
class MemoryStore {
|
|
7
|
+
data = new Map();
|
|
8
|
+
async get(key) {
|
|
9
|
+
const entry = this.data.get(key);
|
|
10
|
+
if (!entry)
|
|
11
|
+
return null;
|
|
12
|
+
if (entry.expiresAt && Date.now() > entry.expiresAt) {
|
|
13
|
+
this.data.delete(key);
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
return entry.value;
|
|
17
|
+
}
|
|
18
|
+
async incrbyfloat(key, increment) {
|
|
19
|
+
const current = parseFloat((await this.get(key)) ?? "0");
|
|
20
|
+
const newValue = (current + increment).toString();
|
|
21
|
+
const entry = this.data.get(key);
|
|
22
|
+
this.data.set(key, { value: newValue, expiresAt: entry?.expiresAt });
|
|
23
|
+
return newValue;
|
|
24
|
+
}
|
|
25
|
+
async expire(key, seconds) {
|
|
26
|
+
const entry = this.data.get(key);
|
|
27
|
+
if (!entry)
|
|
28
|
+
return 0;
|
|
29
|
+
entry.expiresAt = Date.now() + seconds * 1000;
|
|
30
|
+
return 1;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
class CostTracker {
|
|
34
|
+
store;
|
|
35
|
+
budgets;
|
|
36
|
+
records = [];
|
|
37
|
+
constructor(budgets = {}, redis) {
|
|
38
|
+
this.store = redis ?? new MemoryStore();
|
|
39
|
+
this.budgets = new Map(Object.entries(budgets));
|
|
40
|
+
}
|
|
41
|
+
/** Check if a request is within budget BEFORE sending to LLM */
|
|
42
|
+
async checkBudget(entityId, model, estimatedInputTokens, estimatedOutputTokens = 500) {
|
|
43
|
+
const budget = this.budgets.get(entityId);
|
|
44
|
+
if (!budget) {
|
|
45
|
+
return { allowed: true, currentSpend: 0, remainingBudget: Infinity };
|
|
46
|
+
}
|
|
47
|
+
const estimated = (0, pricing_js_1.estimateCost)(model, estimatedInputTokens, estimatedOutputTokens);
|
|
48
|
+
const key = this.budgetKey(entityId, budget.period);
|
|
49
|
+
const currentSpend = parseFloat((await this.store.get(key)) ?? "0");
|
|
50
|
+
if (currentSpend + estimated > budget.hardLimit) {
|
|
51
|
+
return {
|
|
52
|
+
allowed: false,
|
|
53
|
+
currentSpend,
|
|
54
|
+
remainingBudget: Math.max(0, budget.hardLimit - currentSpend),
|
|
55
|
+
warning: `Hard budget limit reached: $${currentSpend.toFixed(2)} / $${budget.hardLimit}`,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const warning = currentSpend + estimated > budget.softLimit
|
|
59
|
+
? `Approaching budget: $${currentSpend.toFixed(2)} / $${budget.hardLimit} (${Math.round((currentSpend / budget.hardLimit) * 100)}%)`
|
|
60
|
+
: undefined;
|
|
61
|
+
return {
|
|
62
|
+
allowed: true,
|
|
63
|
+
currentSpend,
|
|
64
|
+
remainingBudget: budget.hardLimit - currentSpend,
|
|
65
|
+
warning,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** Record actual cost AFTER receiving response */
|
|
69
|
+
async recordCost(entityId, model, inputTokens, outputTokens) {
|
|
70
|
+
const cost = (0, pricing_js_1.estimateCost)(model, inputTokens, outputTokens);
|
|
71
|
+
const record = {
|
|
72
|
+
entityId,
|
|
73
|
+
model,
|
|
74
|
+
inputTokens,
|
|
75
|
+
outputTokens,
|
|
76
|
+
cost,
|
|
77
|
+
timestamp: new Date(),
|
|
78
|
+
};
|
|
79
|
+
// Update budget counter
|
|
80
|
+
const budget = this.budgets.get(entityId);
|
|
81
|
+
if (budget) {
|
|
82
|
+
const key = this.budgetKey(entityId, budget.period);
|
|
83
|
+
await this.store.incrbyfloat(key, cost);
|
|
84
|
+
await this.store.expire(key, this.periodSeconds(budget.period) * 2);
|
|
85
|
+
}
|
|
86
|
+
// Also update any matching broader budgets (global, etc.)
|
|
87
|
+
const globalBudget = this.budgets.get("global");
|
|
88
|
+
if (globalBudget && entityId !== "global") {
|
|
89
|
+
const globalKey = this.budgetKey("global", globalBudget.period);
|
|
90
|
+
await this.store.incrbyfloat(globalKey, cost);
|
|
91
|
+
await this.store.expire(globalKey, this.periodSeconds(globalBudget.period) * 2);
|
|
92
|
+
}
|
|
93
|
+
this.records.push(record);
|
|
94
|
+
return record;
|
|
95
|
+
}
|
|
96
|
+
/** Get current spend for an entity */
|
|
97
|
+
async getCurrentSpend(entityId) {
|
|
98
|
+
const budget = this.budgets.get(entityId);
|
|
99
|
+
if (!budget)
|
|
100
|
+
return 0;
|
|
101
|
+
const key = this.budgetKey(entityId, budget.period);
|
|
102
|
+
return parseFloat((await this.store.get(key)) ?? "0");
|
|
103
|
+
}
|
|
104
|
+
/** Get all recorded costs (for export/audit) */
|
|
105
|
+
getRecords() {
|
|
106
|
+
return [...this.records];
|
|
107
|
+
}
|
|
108
|
+
budgetKey(entityId, period) {
|
|
109
|
+
const now = new Date();
|
|
110
|
+
let periodKey;
|
|
111
|
+
switch (period) {
|
|
112
|
+
case "hourly":
|
|
113
|
+
periodKey = `${now.getUTCFullYear()}-${now.getUTCMonth()}-${now.getUTCDate()}-${now.getUTCHours()}`;
|
|
114
|
+
break;
|
|
115
|
+
case "daily":
|
|
116
|
+
periodKey = `${now.getUTCFullYear()}-${now.getUTCMonth()}-${now.getUTCDate()}`;
|
|
117
|
+
break;
|
|
118
|
+
case "monthly":
|
|
119
|
+
periodKey = `${now.getUTCFullYear()}-${now.getUTCMonth()}`;
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
return `ai-shield:cost:${entityId}:${periodKey}`;
|
|
123
|
+
}
|
|
124
|
+
periodSeconds(period) {
|
|
125
|
+
switch (period) {
|
|
126
|
+
case "hourly":
|
|
127
|
+
return 3600;
|
|
128
|
+
case "daily":
|
|
129
|
+
return 86400;
|
|
130
|
+
case "monthly":
|
|
131
|
+
return 86400 * 31;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.CostTracker = CostTracker;
|
|
136
|
+
//# sourceMappingURL=tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../src/cost/tracker.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export { AIShield } from "./shield.js";
|
|
2
|
+
export { HeuristicScanner, type HeuristicConfig } from "./scanner/heuristic.js";
|
|
3
|
+
export { PIIScanner } from "./scanner/pii.js";
|
|
4
|
+
export { ScannerChain, type ChainConfig } from "./scanner/chain.js";
|
|
5
|
+
export { injectCanary, checkCanaryLeak } from "./scanner/canary.js";
|
|
6
|
+
export { PolicyEngine, type PolicyPreset } from "./policy/engine.js";
|
|
7
|
+
export { ToolPolicyScanner } from "./policy/tools.js";
|
|
8
|
+
export { CostTracker, type RedisLike } from "./cost/tracker.js";
|
|
9
|
+
export { detectAnomaly, type AnomalyResult } from "./cost/anomaly.js";
|
|
10
|
+
export { getModelPricing, estimateCost, MODEL_PRICING } from "./cost/pricing.js";
|
|
11
|
+
export { AuditLogger, ConsoleAuditStore, MemoryAuditStore } from "./audit/logger.js";
|
|
12
|
+
export type { AuditStore } from "./audit/types.js";
|
|
13
|
+
export { ScanLRUCache, type LRUCacheConfig } from "./cache/lru.js";
|
|
14
|
+
export type { ScanDecision, ScanResult, ScannerResult, Scanner, ScanContext, Violation, ViolationType, PIIType, PIIAction, PIIEntity, PIIConfig, ToolCall, ToolPermissions, ToolPolicy, ToolManifestPin, BudgetPeriod, BudgetConfig, CostEstimate, CostRecord, BudgetCheckResult, ModelPricing, AuditRecord, AuditConfig, ShieldConfig, InjectionConfig, CostConfig, CacheConfig, ToolConfig, PresetName, } from "./types.js";
|
|
15
|
+
import type { ShieldConfig, ScanResult, ScanContext } from "./types.js";
|
|
16
|
+
/** Quick scan — one line, maximum protection */
|
|
17
|
+
export declare function shield(input: string, configOrContext?: ShieldConfig | ScanContext): Promise<ScanResult>;
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAE,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGpE,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGjF,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrF,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGnE,YAAY,EAEV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,OAAO,EACP,WAAW,EACX,SAAS,EACT,aAAa,EAEb,OAAO,EACP,SAAS,EACT,SAAS,EACT,SAAS,EAET,QAAQ,EACR,eAAe,EACf,UAAU,EACV,eAAe,EAEf,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,iBAAiB,EACjB,YAAY,EAEZ,WAAW,EACX,WAAW,EAEX,YAAY,EACZ,eAAe,EACf,UAAU,EACV,WAAW,EACX,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC;AAKpB,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAExE,gDAAgD;AAChD,wBAAsB,MAAM,CAC1B,KAAK,EAAE,MAAM,EACb,eAAe,CAAC,EAAE,YAAY,GAAG,WAAW,GAC3C,OAAO,CAAC,UAAU,CAAC,CAarB"}
|