@salimassili/ai-costguard 1.2.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/LICENSE +21 -0
  3. package/README.md +281 -103
  4. package/benchmarks/run.mjs +229 -0
  5. package/dist/cli.d.ts +50 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +178 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/core/CostGuard.d.ts +3 -4
  10. package/dist/core/CostGuard.d.ts.map +1 -1
  11. package/dist/core/CostGuard.js +1 -2
  12. package/dist/core/CostGuard.js.map +1 -1
  13. package/dist/core/GuardCore.d.ts +93 -13
  14. package/dist/core/GuardCore.d.ts.map +1 -1
  15. package/dist/core/GuardCore.js +372 -158
  16. package/dist/core/GuardCore.js.map +1 -1
  17. package/dist/core/GuardFree.d.ts +42 -18
  18. package/dist/core/GuardFree.d.ts.map +1 -1
  19. package/dist/core/GuardFree.js +95 -140
  20. package/dist/core/GuardFree.js.map +1 -1
  21. package/dist/core/GuardPro.d.ts +85 -5
  22. package/dist/core/GuardPro.d.ts.map +1 -1
  23. package/dist/core/GuardPro.js +216 -121
  24. package/dist/core/GuardPro.js.map +1 -1
  25. package/dist/core/event-log.d.ts +37 -0
  26. package/dist/core/event-log.d.ts.map +1 -0
  27. package/dist/core/event-log.js +49 -0
  28. package/dist/core/event-log.js.map +1 -0
  29. package/dist/core/events.d.ts +20 -0
  30. package/dist/core/events.d.ts.map +1 -0
  31. package/dist/core/events.js +46 -0
  32. package/dist/core/events.js.map +1 -0
  33. package/dist/core/similarity.d.ts +13 -0
  34. package/dist/core/similarity.d.ts.map +1 -0
  35. package/dist/core/similarity.js +51 -0
  36. package/dist/core/similarity.js.map +1 -0
  37. package/dist/core/tokenizer.d.ts +18 -0
  38. package/dist/core/tokenizer.d.ts.map +1 -0
  39. package/dist/core/tokenizer.js +137 -0
  40. package/dist/core/tokenizer.js.map +1 -0
  41. package/dist/core/types.d.ts +153 -5
  42. package/dist/core/types.d.ts.map +1 -1
  43. package/dist/core/types.js +0 -3
  44. package/dist/core/types.js.map +1 -1
  45. package/dist/core/webhooks.d.ts +15 -0
  46. package/dist/core/webhooks.d.ts.map +1 -0
  47. package/dist/core/webhooks.js +58 -0
  48. package/dist/core/webhooks.js.map +1 -0
  49. package/dist/dashboard.d.ts +73 -0
  50. package/dist/dashboard.d.ts.map +1 -0
  51. package/dist/dashboard.js +201 -0
  52. package/dist/dashboard.js.map +1 -0
  53. package/dist/index.d.ts +3 -4
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +1 -2
  56. package/dist/index.js.map +1 -1
  57. package/dist/pricing/index.d.ts +19 -2
  58. package/dist/pricing/index.d.ts.map +1 -1
  59. package/dist/pricing/index.js +93 -13
  60. package/dist/pricing/index.js.map +1 -1
  61. package/dist/pro.d.ts +3 -0
  62. package/dist/pro.d.ts.map +1 -0
  63. package/dist/pro.js +2 -0
  64. package/dist/pro.js.map +1 -0
  65. package/docs/BENCHMARKS.md +51 -0
  66. package/docs/DASHBOARD.md +61 -0
  67. package/docs/INTEGRATIONS.md +153 -0
  68. package/examples/integrations/anthropic-workflow-budget.mjs +36 -0
  69. package/examples/integrations/ci-budget-check.mjs +32 -0
  70. package/examples/integrations/crewai-budget-gate.mjs +31 -0
  71. package/examples/integrations/langchain-retry-storm.mjs +32 -0
  72. package/examples/integrations/mastra-agent.mjs +41 -0
  73. package/examples/integrations/openai-agent-loop.mjs +44 -0
  74. package/examples/integrations/vercel-ai-chatbot.mjs +29 -0
  75. package/package.json +35 -7
@@ -1,27 +1,51 @@
1
+ import { GuardError } from './GuardCore.js';
2
+ import type { GuardConfig, GuardEventHandler, GuardEventName, GuardState, RequestContext } from './types.js';
1
3
  /**
2
- * GuardFree.ts - LOCAL ILLUSION OF SAFETY (FREE VERSION)
3
- *
4
- * Each process thinks it is safe.
5
- * Single-process protection only.
6
- *
7
- * INSTALL: const ai = guard(openai)
4
+ * Event controls added to a guarded client proxy.
8
5
  */
9
- import { GuardConfig, RequestContext, GuardState } from './types.js';
6
+ export interface GuardEventControls {
7
+ /** Subscribes to block, allow, or cost events. */
8
+ on(eventName: GuardEventName, handler: GuardEventHandler): () => void;
9
+ /** Removes an event handler. */
10
+ off(eventName: GuardEventName, handler: GuardEventHandler): void;
11
+ /** Returns the mutable process-local guard state. */
12
+ getGuardState(): GuardState;
13
+ }
10
14
  /**
11
- * Local Safety Illusion - FREE VERSION
12
- *
13
- * Each process thinks it is safe.
14
- * Single-process protection only.
15
+ * Client type returned by guard().
16
+ */
17
+ export type GuardedClient<TClient extends object> = TClient & GuardEventControls;
18
+ /**
19
+ * Wraps an OpenAI-like client with process-local cost, loop, and retry protection.
20
+ */
21
+ export declare function guard<TClient extends object>(client: TClient, config?: GuardConfig, sharedState?: GuardState): GuardedClient<TClient>;
22
+ /**
23
+ * Wraps a standalone AI function with the same guard behavior as guard().
15
24
  *
16
- * WARNING: Process-local only. Not production safe.
25
+ * The first function argument should be an OpenAI-like request object containing
26
+ * model, messages/prompt/input, and max_tokens/maxOutputTokens when possible.
27
+ */
28
+ export declare function guardFunction<TArgs extends readonly unknown[], TResult>(fn: (...args: TArgs) => TResult, config?: GuardConfig): ((...args: TArgs) => TResult) & GuardEventControls;
29
+ /**
30
+ * Express-compatible middleware that attaches req.localSafety.check() and req.guard.check().
17
31
  */
18
- export declare function guard(client: any, config: GuardConfig, sharedState?: GuardState): any;
32
+ export declare function middleware(config?: GuardConfig): (req: MiddlewareRequest, res: unknown, next: () => void) => void;
19
33
  /**
20
- * Express middleware - Local safety for web apps
34
+ * Error thrown when a request is blocked before provider execution.
21
35
  */
22
- export declare function middleware(config: GuardConfig): (req: any, res: any, next: any) => void;
23
- export declare class GuardError extends Error {
24
- context: RequestContext;
25
- constructor(message: string, context?: RequestContext);
36
+ export { GuardError };
37
+ /**
38
+ * Pricing lookup re-export kept for compatibility with older imports.
39
+ */
40
+ export { getPricing } from '../pricing/index.js';
41
+ interface MiddlewareRequest {
42
+ localSafety?: MiddlewareControls;
43
+ guard?: MiddlewareControls;
44
+ }
45
+ interface MiddlewareControls {
46
+ state: GuardState;
47
+ check(context: RequestContext): void;
48
+ on(eventName: GuardEventName, handler: GuardEventHandler): () => void;
49
+ off(eventName: GuardEventName, handler: GuardEventHandler): void;
26
50
  }
27
51
  //# sourceMappingURL=GuardFree.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GuardFree.d.ts","sourceRoot":"","sources":["../../src/core/GuardFree.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;;GAOG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,UAAU,OAmE/E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,IAGpC,KAAK,GAAG,EAAE,KAAK,GAAG,EAAE,MAAM,GAAG,UAwBtC;AA+DD,qBAAa,UAAW,SAAQ,KAAK;IACnC,OAAO,EAAE,cAAc,CAAC;gBACZ,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc;CAKtD"}
1
+ {"version":3,"file":"GuardFree.d.ts","sourceRoot":"","sources":["../../src/core/GuardFree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAoB,MAAM,gBAAgB,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,cAAc,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7G;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,kDAAkD;IAClD,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,IAAI,CAAC;IACtE,gCAAgC;IAChC,GAAG,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACjE,qDAAqD;IACrD,aAAa,IAAI,UAAU,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,OAAO,SAAS,MAAM,IAAI,OAAO,GAAG,kBAAkB,CAAC;AAEjF;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,SAAS,MAAM,EAC1C,MAAM,EAAE,OAAO,EACf,MAAM,GAAE,WAAgB,EACxB,WAAW,GAAE,UAA+B,GAC3C,aAAa,CAAC,OAAO,CAAC,CAqDxB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,SAAS,SAAS,OAAO,EAAE,EAAE,OAAO,EACrE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,EAC/B,MAAM,GAAE,WAAgB,GACvB,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,kBAAkB,CAepD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,GAAE,WAAgB,GAAG,CAAC,GAAG,EAAE,iBAAiB,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,KAAK,IAAI,CAiBrH;AAED;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,CAAC;AAEtB;;GAEG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,UAAU,iBAAiB;IACzB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,KAAK,CAAC,EAAE,kBAAkB,CAAC;CAC5B;AAED,UAAU,kBAAkB;IAC1B,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IACrC,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,IAAI,CAAC;IACtE,GAAG,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAC;CAClE"}
@@ -1,159 +1,114 @@
1
+ import { GuardCore, GuardError, createGuardState } from './GuardCore.js';
1
2
  /**
2
- * GuardFree.ts - LOCAL ILLUSION OF SAFETY (FREE VERSION)
3
- *
4
- * Each process thinks it is safe.
5
- * Single-process protection only.
6
- *
7
- * INSTALL: const ai = guard(openai)
3
+ * Wraps an OpenAI-like client with process-local cost, loop, and retry protection.
8
4
  */
9
- import { getPricing as lookupPricing } from '../pricing/index.js';
5
+ export function guard(client, config = {}, sharedState = createGuardState()) {
6
+ const core = new GuardCore(config, sharedState);
7
+ const proxies = new WeakMap();
8
+ const wrap = (target, path = []) => {
9
+ const cached = proxies.get(target);
10
+ if (cached)
11
+ return cached;
12
+ const proxy = new Proxy(target, {
13
+ get(currentTarget, prop, receiver) {
14
+ if (prop === 'on')
15
+ return core.on.bind(core);
16
+ if (prop === 'off')
17
+ return core.off.bind(core);
18
+ if (prop === 'getGuardState')
19
+ return core.getState.bind(core);
20
+ const value = Reflect.get(currentTarget, prop, receiver);
21
+ const nextPath = typeof prop === 'string' ? [...path, prop] : path;
22
+ if (typeof value === 'function') {
23
+ return (...args) => {
24
+ const methodPath = nextPath.join('.');
25
+ if (!core.shouldGuardMethod(methodPath)) {
26
+ return Reflect.apply(value, currentTarget, args);
27
+ }
28
+ const context = core.extractContext(args, methodPath);
29
+ core.check(context);
30
+ const result = Reflect.apply(value, currentTarget, stripGuardMetadata(args));
31
+ if (isPromiseLike(result)) {
32
+ return result.then((resolved) => {
33
+ core.recordActualUsage(context, resolved);
34
+ return resolved;
35
+ });
36
+ }
37
+ core.recordActualUsage(context, result);
38
+ return result;
39
+ };
40
+ }
41
+ if (isObject(value)) {
42
+ return wrap(value, nextPath);
43
+ }
44
+ return value;
45
+ },
46
+ });
47
+ proxies.set(target, proxy);
48
+ return proxy;
49
+ };
50
+ return wrap(client);
51
+ }
10
52
  /**
11
- * Local Safety Illusion - FREE VERSION
53
+ * Wraps a standalone AI function with the same guard behavior as guard().
12
54
  *
13
- * Each process thinks it is safe.
14
- * Single-process protection only.
15
- *
16
- * WARNING: Process-local only. Not production safe.
55
+ * The first function argument should be an OpenAI-like request object containing
56
+ * model, messages/prompt/input, and max_tokens/maxOutputTokens when possible.
17
57
  */
18
- export function guard(client, config, sharedState) {
19
- const defaults = {
20
- budget: 10
21
- };
22
- const guardConfig = { ...defaults, ...config };
23
- // Process-local state only - each process thinks it's safe
24
- const state = sharedState || {
25
- requestCount: 0,
26
- totalCost: 0,
27
- lastRequestTime: 0,
28
- blockedCount: 0,
29
- };
30
- return new Proxy(client, {
31
- get(target, prop) {
32
- const value = target[prop];
33
- if (typeof value === 'function') {
34
- return (...args) => {
35
- const ctx = extractContext(args, prop);
36
- // Local budget check - each process thinks it's safe
37
- if (state.totalCost + ctx.estimatedCost > guardConfig.budget) {
38
- const saved = guardConfig.budget - state.totalCost;
39
- state.blockedCount++;
40
- console.error(`🚨 LOCAL SAFETY: Budget exceeded → saved $${saved.toFixed(2)}`);
41
- throw new GuardError(`Budget exceeded`, ctx);
42
- }
43
- // Local loop detection - basic hash only
44
- if (detectLocalLoop(ctx.prompt, state)) {
45
- const saved = ctx.estimatedCost * 20;
46
- state.blockedCount++;
47
- console.error(`🚨 LOCAL SAFETY: Loop detected → saved $${saved.toFixed(2)}`);
48
- throw new GuardError(`Loop detected`, ctx);
49
- }
50
- // Local retry detection - basic keyword only
51
- if (detectLocalRetry(ctx.prompt, state)) {
52
- const saved = ctx.estimatedCost * 10;
53
- state.blockedCount++;
54
- console.error(`🚨 LOCAL SAFETY: Retry detected → saved $${saved.toFixed(2)}`);
55
- throw new GuardError(`Retry detected`, ctx);
56
- }
57
- // Update local state only
58
- state.requestCount++;
59
- state.totalCost += ctx.estimatedCost;
60
- state.lastRequestTime = Date.now();
61
- return value.apply(target, args);
62
- };
63
- }
64
- // Handle nested objects (local only)
65
- if (value && typeof value === 'object') {
66
- return guard(value, guardConfig, state);
67
- }
68
- return value;
69
- },
58
+ export function guardFunction(fn, config = {}) {
59
+ const methodName = config.guardedMethods?.[0] ?? 'run';
60
+ const container = { [methodName]: fn };
61
+ const guarded = guard(container, {
62
+ ...config,
63
+ guardedMethods: [methodName],
70
64
  });
65
+ const guardedFn = ((...args) => guarded[methodName](...args));
66
+ guardedFn.on = guarded.on;
67
+ guardedFn.off = guarded.off;
68
+ guardedFn.getGuardState = guarded.getGuardState;
69
+ return guardedFn;
71
70
  }
72
71
  /**
73
- * Express middleware - Local safety for web apps
72
+ * Express-compatible middleware that attaches req.localSafety.check() and req.guard.check().
74
73
  */
75
- export function middleware(config) {
76
- const guardConfig = { ...config, budget: config.budget || 10 };
77
- return (req, res, next) => {
78
- req.localSafety = {
79
- state: {
80
- requestCount: 0,
81
- totalCost: 0,
82
- lastRequestTime: 0,
83
- blockedCount: 0,
74
+ export function middleware(config = {}) {
75
+ const core = new GuardCore(config);
76
+ return (req, _res, next) => {
77
+ const controls = {
78
+ state: core.getState(),
79
+ check: (context) => {
80
+ core.check(context);
84
81
  },
85
- check: (ctx) => {
86
- if (req.localSafety.state.totalCost + ctx.estimatedCost > guardConfig.budget) {
87
- throw new GuardError('Budget exceeded', ctx);
88
- }
89
- if (detectLocalLoop(ctx.prompt, req.localSafety.state)) {
90
- throw new GuardError('Loop detected', ctx);
91
- }
92
- if (detectLocalRetry(ctx.prompt, req.localSafety.state)) {
93
- throw new GuardError('Retry detected', ctx);
94
- }
95
- req.localSafety.state.requestCount++;
96
- req.localSafety.state.totalCost += ctx.estimatedCost;
97
- }
82
+ on: core.on.bind(core),
83
+ off: core.off.bind(core),
98
84
  };
85
+ req.localSafety = controls;
86
+ req.guard = controls;
99
87
  next();
100
88
  };
101
89
  }
102
- // Local loop detection - basic hash only (each process thinks it's safe)
103
- function detectLocalLoop(prompt, state) {
104
- const promptHash = prompt.slice(0, 100);
105
- const recentHashes = state.recentHashes || [];
106
- const count = recentHashes.filter((h) => h === promptHash).length;
107
- recentHashes.push(promptHash);
108
- if (recentHashes.length > 5)
109
- recentHashes.shift(); // Very limited memory
110
- state.recentHashes = recentHashes;
111
- return count >= 3; // Basic detection only
90
+ /**
91
+ * Error thrown when a request is blocked before provider execution.
92
+ */
93
+ export { GuardError };
94
+ /**
95
+ * Pricing lookup re-export kept for compatibility with older imports.
96
+ */
97
+ export { getPricing } from '../pricing/index.js';
98
+ function isObject(value) {
99
+ return typeof value === 'object' && value !== null;
112
100
  }
113
- // Local retry detection - basic keyword only (each process thinks it's safe)
114
- function detectLocalRetry(prompt, state) {
115
- const retryKeywords = ['retry', 'again', 'repeat', 'error', 'fail', 'timeout'];
116
- const hasRetryKeyword = retryKeywords.some(keyword => prompt.toLowerCase().includes(keyword));
117
- if (!hasRetryKeyword)
118
- return false;
119
- const recentRetries = state.recentRetries || [];
120
- const recentRetryCount = recentRetries.filter((r) => r).length;
121
- recentRetries.push(true);
122
- if (recentRetries.length > 3)
123
- recentRetries.shift(); // Very limited memory
124
- state.recentRetries = recentRetries;
125
- return recentRetryCount >= 2; // Basic detection only
101
+ function isPromiseLike(value) {
102
+ return isObject(value) && typeof value.then === 'function';
126
103
  }
127
- // Extract request context (local only)
128
- function extractContext(args, prop) {
129
- const params = args[0] || {};
130
- const model = params.model || 'unknown';
131
- const messages = params.messages || [];
132
- const prompt = messages.map((m) => m.content).join(' ').slice(0, 200);
133
- const inputText = JSON.stringify(messages);
134
- const estimatedInputTokens = Math.ceil(inputText.length / 4);
135
- const maxOutputTokens = params.max_tokens || 1000;
136
- const tokens = estimatedInputTokens + maxOutputTokens;
137
- const pricing = lookupPricing(model);
138
- const inputPer1kTokens = pricing?.inputPer1kTokens ?? 0.01;
139
- const outputPer1kTokens = pricing?.outputPer1kTokens ?? 0.03;
140
- const estimatedCost = (estimatedInputTokens / 1000) * inputPer1kTokens +
141
- (maxOutputTokens / 1000) * outputPer1kTokens;
142
- return {
143
- model,
144
- tokens,
145
- estimatedCost,
146
- timestamp: Date.now(),
147
- prompt,
148
- };
104
+ function stripGuardMetadata(args) {
105
+ const [first, ...rest] = args;
106
+ if (!isPlainRecord(first))
107
+ return args;
108
+ const { projectId: _projectId, project_id: _project_id, userId: _userId, user_id: _user_id, sessionId: _sessionId, session_id: _session_id, ...providerParams } = first;
109
+ return [providerParams, ...rest];
149
110
  }
150
- // Custom error (local only)
151
- export class GuardError extends Error {
152
- context;
153
- constructor(message, context) {
154
- super(message);
155
- this.name = 'GuardError';
156
- this.context = context;
157
- }
111
+ function isPlainRecord(value) {
112
+ return Object.prototype.toString.call(value) === '[object Object]';
158
113
  }
159
114
  //# sourceMappingURL=GuardFree.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GuardFree.js","sourceRoot":"","sources":["../../src/core/GuardFree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GuardFree.js","sourceRoot":"","sources":["../../src/core/GuardFree.ts"],"names":[],"mappings":"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"}
@@ -1,27 +1,107 @@
1
+ import type { GuardWebhookConfig } from './types.js';
2
+ /**
3
+ * Minimal Redis client surface used by GuardPro. Supplying redisClient is useful for tests.
4
+ */
5
+ export interface GuardProRedisClient {
6
+ /** Optional connection status exposed by ioredis-compatible clients. */
7
+ status?: string;
8
+ /** Registers a connection event handler. */
9
+ on?(eventName: 'ready' | 'error' | 'close', handler: () => void): unknown;
10
+ /** Opens the Redis connection when the client is lazy. */
11
+ connect?(): Promise<unknown>;
12
+ /** Evaluates the atomic spend increment Lua script. */
13
+ eval(script: string, keys: number, key: string, amount: string, ttlSeconds: string): Promise<unknown>;
14
+ /** Reads the current spend value. */
15
+ get(key: string): Promise<string | null>;
16
+ /** Deletes a spend key. */
17
+ del(key: string): Promise<unknown>;
18
+ /** Closes the connection. */
19
+ quit?(): Promise<unknown>;
20
+ }
21
+ /**
22
+ * Configuration for Redis-backed budget enforcement.
23
+ */
1
24
  export interface GuardProConfig {
25
+ /** Redis connection URL. Instances sharing this URL reuse one pooled connection. */
2
26
  redisUrl: string;
27
+ /** Budget in USD for each project/session window. */
3
28
  budget: number;
29
+ /** Session TTL in seconds. Defaults to 86400. */
4
30
  windowSeconds?: number;
31
+ /** Slack webhook URL for budget block notifications. */
5
32
  slackWebhook?: string;
33
+ /** Discord webhook URL for budget block notifications. */
34
+ discordWebhook?: string;
35
+ /** Combined webhook configuration. */
36
+ webhooks?: GuardWebhookConfig;
37
+ /** Deprecated compatibility field. GuardPro does not enforce licenses locally. */
6
38
  licenseKey?: string;
39
+ /** Optional Redis-compatible client. When omitted, GuardPro pools ioredis clients by URL. */
40
+ redisClient?: GuardProRedisClient;
7
41
  }
42
+ /**
43
+ * Redis-backed budget guard with local fallback when Redis is unavailable.
44
+ */
8
45
  export declare class GuardPro {
9
- private readonly redis;
46
+ private static readonly pools;
47
+ private readonly redisUrl;
48
+ private readonly redisClient?;
49
+ private readonly poolEntry?;
10
50
  private readonly budget;
11
51
  private readonly windowSeconds;
12
- private readonly slackWebhook?;
13
- private connected;
52
+ private readonly webhooks?;
53
+ private readonly localSpend;
54
+ private directRedisFailed;
55
+ private directRedisReady;
56
+ /**
57
+ * Creates a GuardPro instance and reuses a pooled Redis connection for the same URL.
58
+ */
14
59
  constructor(config: GuardProConfig);
60
+ /**
61
+ * Atomically charges estimated spend for a project and throws GuardError when budget is exceeded.
62
+ */
15
63
  checkAndCharge(projectId: string, estimatedCost: number): Promise<void>;
64
+ /**
65
+ * Returns current spend for a project from Redis when available, otherwise from local fallback state.
66
+ */
16
67
  getSpend(projectId: string): Promise<number>;
68
+ /**
69
+ * Resets spend for a project in Redis when available and always clears local fallback state.
70
+ */
17
71
  resetSpend(projectId: string): Promise<void>;
72
+ /**
73
+ * Returns true when the pooled or supplied Redis client is currently connected.
74
+ */
18
75
  isConnected(): boolean;
76
+ /**
77
+ * Releases this instance's pooled Redis reference and closes the connection when unused.
78
+ */
19
79
  shutdown(): Promise<void>;
20
- private incrementSpend;
21
- private sendBudgetAlert;
80
+ private static getPoolEntry;
81
+ private attachConnectionEvents;
82
+ private getUsableRedis;
83
+ private connect;
84
+ private incrementRedisOrFallback;
85
+ private incrementRedis;
86
+ private incrementLocal;
87
+ private getLocal;
88
+ private markDisconnected;
89
+ private safeQuit;
22
90
  private getSpendKey;
23
91
  private createContext;
24
92
  }
93
+ /**
94
+ * Deprecated compatibility helper.
95
+ *
96
+ * This is a format sanity check only. It is not license enforcement and should
97
+ * not be used for commercial access control.
98
+ */
25
99
  export declare function validateLicense(key: string): boolean;
100
+ /**
101
+ * Creates GuardPro.
102
+ *
103
+ * The return type remains nullable for backwards compatibility with older
104
+ * callers, but local license rejection has intentionally been removed.
105
+ */
26
106
  export declare function getProGuard(config: GuardProConfig): GuardPro | null;
27
107
  //# sourceMappingURL=GuardPro.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"GuardPro.d.ts","sourceRoot":"","sources":["../../src/core/GuardPro.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAQ;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IACvC,OAAO,CAAC,SAAS,CAAkB;gBAEvB,MAAM,EAAE,cAAc;IAqD5B,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCvE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAU5C,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASlD,WAAW,IAAI,OAAO;IAIhB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAUjB,cAAc;YAqBd,eAAe;IAgB7B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,aAAa;CAStB;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAIpD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,GAAG,IAAI,CAGnE"}
1
+ {"version":3,"file":"GuardPro.d.ts","sourceRoot":"","sources":["../../src/core/GuardPro.ts"],"names":[],"mappings":"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"}