@salimassili/ai-costguard 2.0.0 → 2.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/CHANGELOG.md +62 -46
- package/LICENSE +21 -21
- package/README.md +421 -314
- package/benchmarks/run.mjs +229 -229
- package/benchmarks/token-accuracy.mjs +182 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +63 -2
- package/dist/cli.js.map +1 -1
- package/dist/core/CostGuard.d.ts +4 -2
- package/dist/core/CostGuard.d.ts.map +1 -1
- package/dist/core/CostGuard.js +2 -1
- package/dist/core/CostGuard.js.map +1 -1
- package/dist/core/GuardCore.d.ts +2 -0
- package/dist/core/GuardCore.d.ts.map +1 -1
- package/dist/core/GuardCore.js +37 -5
- package/dist/core/GuardCore.js.map +1 -1
- package/dist/core/GuardPro.d.ts +1 -13
- package/dist/core/GuardPro.d.ts.map +1 -1
- package/dist/core/GuardPro.js +7 -19
- package/dist/core/GuardPro.js.map +1 -1
- package/dist/core/tokenizer.d.ts +18 -0
- package/dist/core/tokenizer.d.ts.map +1 -1
- package/dist/core/tokenizer.js +45 -1
- package/dist/core/tokenizer.js.map +1 -1
- package/dist/core/types.d.ts +12 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/dashboard.js +49 -49
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/pricing/index.d.ts +24 -0
- package/dist/pricing/index.d.ts.map +1 -1
- package/dist/pricing/index.js +31 -5
- package/dist/pricing/index.js.map +1 -1
- package/dist/pro.d.ts +1 -1
- package/dist/pro.d.ts.map +1 -1
- package/dist/pro.js +1 -1
- package/dist/pro.js.map +1 -1
- package/docs/BENCHMARKS.md +54 -35
- package/docs/DASHBOARD.md +61 -61
- package/docs/INTEGRATIONS.md +153 -153
- package/examples/integrations/anthropic-workflow-budget.mjs +36 -36
- package/examples/integrations/ci-budget-check.mjs +32 -32
- package/examples/integrations/crewai-budget-gate.mjs +31 -31
- package/examples/integrations/langchain-retry-storm.mjs +32 -32
- package/examples/integrations/mastra-agent.mjs +41 -41
- package/examples/integrations/openai-agent-loop.mjs +44 -44
- package/examples/integrations/vercel-ai-chatbot.mjs +29 -29
- package/package.json +71 -69
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../src/core/tokenizer.ts"],"names":[],"mappings":"AAAA,MAAM,aAAa,GACjB,oFAAoF,CAAC;AAEvF,MAAM,SAAS,GAAG,IAAI,GAAG,CACvB;IACE,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;CACN,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CACtC,CAAC;
|
|
1
|
+
{"version":3,"file":"tokenizer.js","sourceRoot":"","sources":["../../src/core/tokenizer.ts"],"names":[],"mappings":"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"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -2,9 +2,7 @@ import type { ModelPricing } from '../pricing/index.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Stable machine-readable reasons for blocked requests.
|
|
4
4
|
*/
|
|
5
|
-
export type GuardErrorCode = 'UNKNOWN_MODEL' | 'BUDGET_EXCEEDED' | 'MAX_STEPS_EXCEEDED' | 'LOOP_DETECTED' | 'RETRY_STORM_DETECTED'
|
|
6
|
-
/** Reserved for compatibility; current GuardPro does not enforce local licenses. */
|
|
7
|
-
| 'INVALID_LICENSE';
|
|
5
|
+
export type GuardErrorCode = 'UNKNOWN_MODEL' | 'BUDGET_EXCEEDED' | 'MAX_STEPS_EXCEEDED' | 'LOOP_DETECTED' | 'RETRY_STORM_DETECTED';
|
|
8
6
|
/**
|
|
9
7
|
* Webhook destinations used by the guard when a request is blocked.
|
|
10
8
|
*/
|
|
@@ -47,6 +45,15 @@ export interface GuardConfig {
|
|
|
47
45
|
loopSimilarityThreshold?: number;
|
|
48
46
|
/** Number of prior similar prompts required before loop blocking. Defaults to 2. */
|
|
49
47
|
loopMinRepeats?: number;
|
|
48
|
+
/** Structured loop detection tuning. Takes precedence over legacy loopSimilarityThreshold/loopMinRepeats. */
|
|
49
|
+
loopDetection?: {
|
|
50
|
+
/** Similarity threshold from 0 to 1. Defaults to 0.85. */
|
|
51
|
+
similarityThreshold?: number;
|
|
52
|
+
/** Number of prior similar prompts required before loop blocking. Defaults to 2. */
|
|
53
|
+
minHistorySize?: number;
|
|
54
|
+
/** Number of recent prompts compared for loop detection. Defaults to 5. */
|
|
55
|
+
windowSize?: number;
|
|
56
|
+
};
|
|
50
57
|
/** Number of retry/failure prompts allowed before a retry storm is blocked. Defaults to 2. */
|
|
51
58
|
retryThreshold?: number;
|
|
52
59
|
/** Known AI SDK method paths to guard. Defaults to common OpenAI/Anthropic create methods. */
|
|
@@ -84,6 +91,8 @@ export interface RequestContext {
|
|
|
84
91
|
tokens: number;
|
|
85
92
|
/** Estimated input tokens. */
|
|
86
93
|
inputTokens?: number;
|
|
94
|
+
/** True when dependency-free approximate token counting was used. */
|
|
95
|
+
approximateTokens?: boolean;
|
|
87
96
|
/** Reserved or requested output tokens. */
|
|
88
97
|
outputTokens?: number;
|
|
89
98
|
/** Estimated USD cost for the request. */
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;GAEG;AACH,MAAM,MAAM,cAAc,GACtB,eAAe,GACf,iBAAiB,GACjB,oBAAoB,GACpB,eAAe,GACf,sBAAsB
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
package/dist/dashboard.js
CHANGED
|
@@ -111,57 +111,57 @@ export function startDashboardServer(options = {}) {
|
|
|
111
111
|
}
|
|
112
112
|
function renderDashboardHtml(summary) {
|
|
113
113
|
const recentRows = summary.recentEvents
|
|
114
|
-
.map((event) => `<tr>
|
|
115
|
-
<td>${escapeHtml(event.timestamp)}</td>
|
|
116
|
-
<td>${escapeHtml(event.type)}</td>
|
|
117
|
-
<td>${escapeHtml(event.code ?? '')}</td>
|
|
118
|
-
<td>${escapeHtml(event.model)}</td>
|
|
119
|
-
<td>${escapeHtml(event.scopeKey)}</td>
|
|
120
|
-
<td>$${event.estimatedCost.toFixed(6)}</td>
|
|
114
|
+
.map((event) => `<tr>
|
|
115
|
+
<td>${escapeHtml(event.timestamp)}</td>
|
|
116
|
+
<td>${escapeHtml(event.type)}</td>
|
|
117
|
+
<td>${escapeHtml(event.code ?? '')}</td>
|
|
118
|
+
<td>${escapeHtml(event.model)}</td>
|
|
119
|
+
<td>${escapeHtml(event.scopeKey)}</td>
|
|
120
|
+
<td>$${event.estimatedCost.toFixed(6)}</td>
|
|
121
121
|
</tr>`)
|
|
122
122
|
.join('');
|
|
123
|
-
return `<!doctype html>
|
|
124
|
-
<html lang="en">
|
|
125
|
-
<head>
|
|
126
|
-
<meta charset="utf-8">
|
|
127
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
128
|
-
<title>AI CostGuard Local Dashboard</title>
|
|
129
|
-
<style>
|
|
130
|
-
body { margin: 0; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #101418; color: #eef2f4; }
|
|
131
|
-
main { max-width: 1120px; margin: 0 auto; padding: 32px 20px; }
|
|
132
|
-
h1 { margin: 0 0 8px; font-size: 32px; }
|
|
133
|
-
p { color: #a8b3bd; }
|
|
134
|
-
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; margin: 24px 0; }
|
|
135
|
-
.metric { border: 1px solid #2d363e; border-radius: 8px; padding: 16px; background: #161c22; }
|
|
136
|
-
.label { color: #8d99a5; font-size: 13px; }
|
|
137
|
-
.value { margin-top: 8px; font-size: 24px; font-weight: 700; }
|
|
138
|
-
table { width: 100%; border-collapse: collapse; margin-top: 20px; background: #161c22; }
|
|
139
|
-
th, td { border-bottom: 1px solid #2d363e; padding: 10px; text-align: left; font-size: 14px; }
|
|
140
|
-
th { color: #a8b3bd; }
|
|
141
|
-
code { color: #90cdf4; }
|
|
142
|
-
</style>
|
|
143
|
-
</head>
|
|
144
|
-
<body>
|
|
145
|
-
<main>
|
|
146
|
-
<h1>AI CostGuard Local Dashboard</h1>
|
|
147
|
-
<p>Local-only view generated from <code>${escapeHtml(summary.eventLogPath)}</code>. Refresh the page for updates.</p>
|
|
148
|
-
<section class="grid">
|
|
149
|
-
${metric('Budget used', summary.budgetUsedPercent === undefined ? `$${summary.estimatedSpendUsd.toFixed(6)}` : `${summary.budgetUsedPercent.toFixed(2)}%`)}
|
|
150
|
-
${metric('Requests allowed', String(summary.requestsAllowed))}
|
|
151
|
-
${metric('Requests blocked', String(summary.requestsBlocked))}
|
|
152
|
-
${metric('Estimated spend', `$${summary.estimatedSpendUsd.toFixed(6)}`)}
|
|
153
|
-
${metric('Estimated savings', `$${summary.estimatedSavingsUsd.toFixed(6)}`)}
|
|
154
|
-
${metric('Loop detections', String(summary.loopDetections))}
|
|
155
|
-
${metric('Retry detections', String(summary.retryDetections))}
|
|
156
|
-
${metric('Actual spend', `$${summary.actualSpendUsd.toFixed(6)}`)}
|
|
157
|
-
</section>
|
|
158
|
-
<h2>Recent Guard Events</h2>
|
|
159
|
-
<table>
|
|
160
|
-
<thead><tr><th>Time</th><th>Type</th><th>Code</th><th>Model</th><th>Scope</th><th>Estimated Cost</th></tr></thead>
|
|
161
|
-
<tbody>${recentRows || '<tr><td colspan="6">No events yet.</td></tr>'}</tbody>
|
|
162
|
-
</table>
|
|
163
|
-
</main>
|
|
164
|
-
</body>
|
|
123
|
+
return `<!doctype html>
|
|
124
|
+
<html lang="en">
|
|
125
|
+
<head>
|
|
126
|
+
<meta charset="utf-8">
|
|
127
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
128
|
+
<title>AI CostGuard Local Dashboard</title>
|
|
129
|
+
<style>
|
|
130
|
+
body { margin: 0; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #101418; color: #eef2f4; }
|
|
131
|
+
main { max-width: 1120px; margin: 0 auto; padding: 32px 20px; }
|
|
132
|
+
h1 { margin: 0 0 8px; font-size: 32px; }
|
|
133
|
+
p { color: #a8b3bd; }
|
|
134
|
+
.grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; margin: 24px 0; }
|
|
135
|
+
.metric { border: 1px solid #2d363e; border-radius: 8px; padding: 16px; background: #161c22; }
|
|
136
|
+
.label { color: #8d99a5; font-size: 13px; }
|
|
137
|
+
.value { margin-top: 8px; font-size: 24px; font-weight: 700; }
|
|
138
|
+
table { width: 100%; border-collapse: collapse; margin-top: 20px; background: #161c22; }
|
|
139
|
+
th, td { border-bottom: 1px solid #2d363e; padding: 10px; text-align: left; font-size: 14px; }
|
|
140
|
+
th { color: #a8b3bd; }
|
|
141
|
+
code { color: #90cdf4; }
|
|
142
|
+
</style>
|
|
143
|
+
</head>
|
|
144
|
+
<body>
|
|
145
|
+
<main>
|
|
146
|
+
<h1>AI CostGuard Local Dashboard</h1>
|
|
147
|
+
<p>Local-only view generated from <code>${escapeHtml(summary.eventLogPath)}</code>. Refresh the page for updates.</p>
|
|
148
|
+
<section class="grid">
|
|
149
|
+
${metric('Budget used', summary.budgetUsedPercent === undefined ? `$${summary.estimatedSpendUsd.toFixed(6)}` : `${summary.budgetUsedPercent.toFixed(2)}%`)}
|
|
150
|
+
${metric('Requests allowed', String(summary.requestsAllowed))}
|
|
151
|
+
${metric('Requests blocked', String(summary.requestsBlocked))}
|
|
152
|
+
${metric('Estimated spend', `$${summary.estimatedSpendUsd.toFixed(6)}`)}
|
|
153
|
+
${metric('Estimated savings', `$${summary.estimatedSavingsUsd.toFixed(6)}`)}
|
|
154
|
+
${metric('Loop detections', String(summary.loopDetections))}
|
|
155
|
+
${metric('Retry detections', String(summary.retryDetections))}
|
|
156
|
+
${metric('Actual spend', `$${summary.actualSpendUsd.toFixed(6)}`)}
|
|
157
|
+
</section>
|
|
158
|
+
<h2>Recent Guard Events</h2>
|
|
159
|
+
<table>
|
|
160
|
+
<thead><tr><th>Time</th><th>Type</th><th>Code</th><th>Model</th><th>Scope</th><th>Estimated Cost</th></tr></thead>
|
|
161
|
+
<tbody>${recentRows || '<tr><td colspan="6">No events yet.</td></tr>'}</tbody>
|
|
162
|
+
</table>
|
|
163
|
+
</main>
|
|
164
|
+
</body>
|
|
165
165
|
</html>`;
|
|
166
166
|
}
|
|
167
167
|
function metric(label, value) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { guard, guardFunction, GuardError, middleware } from './core/GuardFree.js';
|
|
2
2
|
export type { GuardedClient, GuardEventControls } from './core/GuardFree.js';
|
|
3
|
-
export { getPricing, registerPricing, listPricing } from './pricing/index.js';
|
|
4
|
-
export type { ModelPricing } from './pricing/index.js';
|
|
3
|
+
export { BUILTIN_PRICING_LAST_UPDATED, getPricing, getPricingMeta, registerPricing, listPricing } from './pricing/index.js';
|
|
4
|
+
export type { ModelPricing, PricingMeta } from './pricing/index.js';
|
|
5
|
+
export { registerTokenizer } from './core/tokenizer.js';
|
|
6
|
+
export type { TokenizerFn } from './core/tokenizer.js';
|
|
5
7
|
export type { GuardConfig, GuardErrorCode, GuardEvent, GuardEventHandler, GuardEventName, GuardScope, GuardState, GuardWebhookConfig, RequestContext, } from './core/types.js';
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACnF,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACnF,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,4BAA4B,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC5H,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,YAAY,EACV,WAAW,EACX,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,cAAc,GACf,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { guard, guardFunction, GuardError, middleware } from './core/GuardFree.js';
|
|
2
|
-
export { getPricing, registerPricing, listPricing } from './pricing/index.js';
|
|
2
|
+
export { BUILTIN_PRICING_LAST_UPDATED, getPricing, getPricingMeta, registerPricing, listPricing } from './pricing/index.js';
|
|
3
|
+
export { registerTokenizer } from './core/tokenizer.js';
|
|
3
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEnF,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEnF,OAAO,EAAE,4BAA4B,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAE5H,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/pricing/index.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Last manual verification date for the built-in pricing registry.
|
|
3
|
+
*
|
|
4
|
+
* Provider pricing changes; use pricingOverrides/registerPricing for current
|
|
5
|
+
* production pricing when provider pages differ from these built-ins.
|
|
6
|
+
*/
|
|
7
|
+
export declare const BUILTIN_PRICING_LAST_UPDATED = "2026-06-07";
|
|
1
8
|
/**
|
|
2
9
|
* Pricing entry expressed in USD per 1,000 tokens.
|
|
3
10
|
*/
|
|
@@ -13,6 +20,19 @@ export interface ModelPricing {
|
|
|
13
20
|
/** Human-readable source for the pricing entry. */
|
|
14
21
|
source: string;
|
|
15
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Freshness metadata for the pricing entry resolved for a model.
|
|
25
|
+
*/
|
|
26
|
+
export interface PricingMeta {
|
|
27
|
+
/** Pricing entry selected for the requested model. */
|
|
28
|
+
pricing: ModelPricing;
|
|
29
|
+
/** Last manual verification date for the built-in registry. */
|
|
30
|
+
registryLastUpdated: string;
|
|
31
|
+
/** Age of the selected pricing entry in whole days. */
|
|
32
|
+
ageDays: number;
|
|
33
|
+
/** True when the selected pricing entry is older than the stale-pricing threshold. */
|
|
34
|
+
stale: boolean;
|
|
35
|
+
}
|
|
16
36
|
/**
|
|
17
37
|
* Returns pricing for a model from overrides, runtime entries, or built-in entries.
|
|
18
38
|
*/
|
|
@@ -21,6 +41,10 @@ export declare function getPricing(model: string, overrides?: readonly ModelPric
|
|
|
21
41
|
* Registers or replaces runtime pricing entries by model name.
|
|
22
42
|
*/
|
|
23
43
|
export declare function registerPricing(entries: readonly ModelPricing[]): void;
|
|
44
|
+
/**
|
|
45
|
+
* Returns freshness metadata for the pricing entry resolved for a model.
|
|
46
|
+
*/
|
|
47
|
+
export declare function getPricingMeta(model: string, overrides?: readonly ModelPricing[]): PricingMeta | undefined;
|
|
24
48
|
/**
|
|
25
49
|
* Lists built-in and runtime pricing entries, deduplicated by normalized model name.
|
|
26
50
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pricing/index.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;CAChB;AA0GD;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,SAAS,YAAY,EAAO,GAAG,YAAY,GAAG,SAAS,CAuB3G;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI,CAMtE;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,YAAY,EAAE,CAe5C"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/pricing/index.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,eAAe,CAAC;AAGzD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,yCAAyC;IACzC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,sDAAsD;IACtD,OAAO,EAAE,YAAY,CAAC;IACtB,+DAA+D;IAC/D,mBAAmB,EAAE,MAAM,CAAC;IAC5B,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,KAAK,EAAE,OAAO,CAAC;CAChB;AA0GD;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,SAAS,YAAY,EAAO,GAAG,YAAY,GAAG,SAAS,CAuB3G;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,IAAI,CAMtE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,SAAS,YAAY,EAAO,GAAG,WAAW,GAAG,SAAS,CAU9G;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,YAAY,EAAE,CAe5C"}
|
package/dist/pricing/index.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
const STALE_PRICING_DAYS = 30;
|
|
2
|
+
/**
|
|
3
|
+
* Last manual verification date for the built-in pricing registry.
|
|
4
|
+
*
|
|
5
|
+
* Provider pricing changes; use pricingOverrides/registerPricing for current
|
|
6
|
+
* production pricing when provider pages differ from these built-ins.
|
|
7
|
+
*/
|
|
8
|
+
export const BUILTIN_PRICING_LAST_UPDATED = '2026-06-07';
|
|
2
9
|
const BUILTIN_PRICING = [
|
|
3
10
|
{
|
|
4
11
|
model: 'gpt-5.5',
|
|
@@ -135,6 +142,20 @@ export function registerPricing(entries) {
|
|
|
135
142
|
runtimePricing.set(normalizeModel(entry.model), entry);
|
|
136
143
|
}
|
|
137
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Returns freshness metadata for the pricing entry resolved for a model.
|
|
147
|
+
*/
|
|
148
|
+
export function getPricingMeta(model, overrides = []) {
|
|
149
|
+
const pricing = getPricing(model, overrides);
|
|
150
|
+
if (!pricing)
|
|
151
|
+
return undefined;
|
|
152
|
+
return {
|
|
153
|
+
pricing,
|
|
154
|
+
registryLastUpdated: BUILTIN_PRICING_LAST_UPDATED,
|
|
155
|
+
ageDays: getPricingAgeDays(pricing),
|
|
156
|
+
stale: isPricingStale(pricing, STALE_PRICING_DAYS),
|
|
157
|
+
};
|
|
158
|
+
}
|
|
138
159
|
/**
|
|
139
160
|
* Lists built-in and runtime pricing entries, deduplicated by normalized model name.
|
|
140
161
|
*/
|
|
@@ -169,15 +190,20 @@ function warnIfAnyStale(entries) {
|
|
|
169
190
|
}
|
|
170
191
|
}
|
|
171
192
|
function warnIfStale(entry) {
|
|
172
|
-
const lastUpdatedMs = Date.parse(`${entry.lastUpdated}T00:00:00.000Z`);
|
|
173
|
-
if (!Number.isFinite(lastUpdatedMs))
|
|
174
|
-
return;
|
|
175
|
-
const ageDays = (Date.now() - lastUpdatedMs) / 86_400_000;
|
|
176
193
|
const warningKey = `${normalizeModel(entry.model)}:${entry.lastUpdated}`;
|
|
177
|
-
if (
|
|
194
|
+
if (isPricingStale(entry, STALE_PRICING_DAYS) && !staleWarnings.has(warningKey)) {
|
|
178
195
|
staleWarnings.add(warningKey);
|
|
179
196
|
console.warn(`[AI CostGuard] Pricing for "${entry.model}" is older than ${STALE_PRICING_DAYS} days. ` +
|
|
180
197
|
`Last checked ${entry.lastUpdated}; verify ${entry.source}.`);
|
|
181
198
|
}
|
|
182
199
|
}
|
|
200
|
+
function getPricingAgeDays(entry) {
|
|
201
|
+
const lastUpdatedMs = Date.parse(`${entry.lastUpdated}T00:00:00.000Z`);
|
|
202
|
+
if (!Number.isFinite(lastUpdatedMs))
|
|
203
|
+
return Number.POSITIVE_INFINITY;
|
|
204
|
+
return Math.max(0, Math.floor((Date.now() - lastUpdatedMs) / 86_400_000));
|
|
205
|
+
}
|
|
206
|
+
function isPricingStale(entry, staleAfterDays) {
|
|
207
|
+
return getPricingAgeDays(entry) > staleAfterDays;
|
|
208
|
+
}
|
|
183
209
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pricing/index.ts"],"names":[],"mappings":"AAAA,MAAM,kBAAkB,GAAG,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/pricing/index.ts"],"names":[],"mappings":"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"}
|
package/dist/pro.d.ts
CHANGED
package/dist/pro.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pro.d.ts","sourceRoot":"","sources":["../src/pro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"pro.d.ts","sourceRoot":"","sources":["../src/pro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC3D,YAAY,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/pro.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { GuardPro, getProGuard
|
|
1
|
+
export { GuardPro, getProGuard } from './core/GuardPro.js';
|
|
2
2
|
//# sourceMappingURL=pro.js.map
|
package/dist/pro.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pro.js","sourceRoot":"","sources":["../src/pro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"pro.js","sourceRoot":"","sources":["../src/pro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
|
package/docs/BENCHMARKS.md
CHANGED
|
@@ -1,51 +1,70 @@
|
|
|
1
|
-
# Benchmarks
|
|
2
|
-
|
|
3
|
-
Benchmarks are local measurements, not universal guarantees. Hardware, Node version, model request shape, history size, and enabled behavior checks all matter.
|
|
1
|
+
# Benchmarks
|
|
2
|
+
|
|
3
|
+
Benchmarks are local measurements, not universal guarantees. Hardware, Node version, model request shape, history size, and enabled behavior checks all matter.
|
|
4
|
+
|
|
5
|
+
Run:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run build
|
|
9
|
+
npm run benchmark
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
For shorter sanity runs:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
node benchmarks/run.mjs --iterations 500
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The benchmark script measures:
|
|
19
|
+
|
|
20
|
+
- Runtime overhead per guarded function call
|
|
21
|
+
- Approximate heap delta after guarded calls
|
|
22
|
+
- Benign false-positive scenario for repeated "again" prompts
|
|
23
|
+
- Loop detection block step for repeated prompts
|
|
24
|
+
- Cost-estimation sample boundaries
|
|
4
25
|
|
|
5
|
-
|
|
26
|
+
Token accuracy benchmark:
|
|
6
27
|
|
|
7
28
|
```bash
|
|
8
29
|
npm run build
|
|
9
|
-
npm run benchmark
|
|
30
|
+
npm run benchmark:tokens
|
|
10
31
|
```
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
The benchmark script measures:
|
|
19
|
-
|
|
20
|
-
- Runtime overhead per guarded function call
|
|
21
|
-
- Approximate heap delta after guarded calls
|
|
22
|
-
- Benign false-positive scenario for repeated "again" prompts
|
|
23
|
-
- Loop detection block step for repeated prompts
|
|
24
|
-
- Cost-estimation sample boundaries
|
|
25
|
-
|
|
26
|
-
## Current Local Result
|
|
27
|
-
|
|
28
|
-
Current local run:
|
|
29
|
-
|
|
30
|
-
- Date: `2026-06-08T13:03:42.459Z`
|
|
32
|
+
|
|
33
|
+
## Current Local Result
|
|
34
|
+
|
|
35
|
+
Current local run:
|
|
36
|
+
|
|
37
|
+
- Date: `2026-06-08T19:54:52.399Z`
|
|
31
38
|
- Node: `v24.14.1`
|
|
32
39
|
- Platform: `win32`
|
|
33
40
|
- Iterations: `5000`
|
|
34
|
-
- Direct mocked async call: `0.
|
|
35
|
-
- Guarded mocked async call: `0.
|
|
36
|
-
- Added overhead: `0.
|
|
41
|
+
- Direct mocked async call: `0.000409 ms/call`
|
|
42
|
+
- Guarded mocked async call: `0.024346 ms/call`
|
|
43
|
+
- Added overhead: `0.023937 ms/call`
|
|
37
44
|
- Benign repeated "again" prompts blocked: `0`
|
|
38
45
|
- Repeated loop prompt blocked at step: `3`
|
|
39
46
|
- GC exposed for memory run: `false`
|
|
40
|
-
|
|
47
|
+
|
|
41
48
|
Do not quote benchmark numbers without the Node version, platform, iteration count, and date.
|
|
42
49
|
|
|
43
50
|
Generated benchmark output is intentionally not published in the npm package. Re-run the benchmark on your target runtime before using numbers in public claims.
|
|
44
51
|
|
|
45
|
-
##
|
|
52
|
+
## Token Accuracy Result
|
|
53
|
+
|
|
54
|
+
Current fixed-corpus token accuracy run:
|
|
55
|
+
|
|
56
|
+
- Reference: dependency-free fixed proxy fixture counts, not a live provider tokenizer
|
|
57
|
+
- Samples: `24`
|
|
58
|
+
- Average error: `237.76%`
|
|
59
|
+
- Median error: `240.06%`
|
|
60
|
+
- Max error: `390%`
|
|
46
61
|
|
|
47
|
-
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
- `
|
|
62
|
+
This shows the current dependency-free estimator is conservative and materially overestimates this proxy corpus. Treat AI CostGuard estimates as pre-call guardrails, not exact provider tokenizer counts. For production budgets that need tighter input-token estimates, register an exact tokenizer with `registerTokenizer()`.
|
|
63
|
+
|
|
64
|
+
## Interpreting Results
|
|
65
|
+
|
|
66
|
+
- `runtimeOverhead.addedPerCallMs` is the local overhead added by the guard wrapper in the benchmark request shape.
|
|
67
|
+
- `memoryOverhead.heapDeltaBytes` is noisy unless Node runs with `--expose-gc`.
|
|
68
|
+
- `falsePositiveScenarios.blocked` should remain `0` for the included benign repeated "again" prompts.
|
|
69
|
+
- `loopDetectionBehavior.blockedAtStep` should show when a repeated loop is stopped.
|
|
70
|
+
- `costEstimationBoundaries` reports this package's dependency-free estimator, not exact provider tokenizer output.
|
package/docs/DASHBOARD.md
CHANGED
|
@@ -1,61 +1,61 @@
|
|
|
1
|
-
# Local Dashboard
|
|
2
|
-
|
|
3
|
-
AI CostGuard includes a local-only dashboard command. It does not create an account, send telemetry, or run a cloud backend.
|
|
4
|
-
|
|
5
|
-
The dashboard reads a JSONL event log written by guarded clients:
|
|
6
|
-
|
|
7
|
-
```ts
|
|
8
|
-
import { guard } from '@salimassili/ai-costguard';
|
|
9
|
-
|
|
10
|
-
const openai = guard(client, {
|
|
11
|
-
budget: 5,
|
|
12
|
-
eventLogPath: '.ai-costguard/events.jsonl',
|
|
13
|
-
eventLogPrompt: 'none',
|
|
14
|
-
});
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
Start the dashboard:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
ai-costguard dashboard --events .ai-costguard/events.jsonl --budget 5
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
For scoped packages or one-off runs:
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
npx @salimassili/ai-costguard dashboard --events .ai-costguard/events.jsonl --budget 5
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
If the package is installed locally, this also works:
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
npx ai-costguard dashboard --events .ai-costguard/events.jsonl --budget 5
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## What It Shows
|
|
36
|
-
|
|
37
|
-
- Budget used
|
|
38
|
-
- Requests allowed
|
|
39
|
-
- Requests blocked
|
|
40
|
-
- Estimated spend
|
|
41
|
-
- Estimated savings
|
|
42
|
-
- Attempted spend
|
|
43
|
-
- Actual spend when provider usage is available
|
|
44
|
-
- Loop detections
|
|
45
|
-
- Retry detections
|
|
46
|
-
- Recent guard events
|
|
47
|
-
|
|
48
|
-
## Non-Interactive Summary
|
|
49
|
-
|
|
50
|
-
Use `--once` for CI, smoke tests, or terminal summaries:
|
|
51
|
-
|
|
52
|
-
```bash
|
|
53
|
-
ai-costguard dashboard --events .ai-costguard/events.jsonl --budget 5 --once
|
|
54
|
-
ai-costguard dashboard --events .ai-costguard/events.jsonl --budget 5 --once --json
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## Privacy Notes
|
|
58
|
-
|
|
59
|
-
`eventLogPrompt` defaults to `none`, so prompt text is not written to disk. Set `eventLogPrompt: 'preview'` only for local debugging where prompt previews are acceptable.
|
|
60
|
-
|
|
61
|
-
The dashboard is a local development view, not a billing ledger. Use provider billing exports for financial reconciliation.
|
|
1
|
+
# Local Dashboard
|
|
2
|
+
|
|
3
|
+
AI CostGuard includes a local-only dashboard command. It does not create an account, send telemetry, or run a cloud backend.
|
|
4
|
+
|
|
5
|
+
The dashboard reads a JSONL event log written by guarded clients:
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { guard } from '@salimassili/ai-costguard';
|
|
9
|
+
|
|
10
|
+
const openai = guard(client, {
|
|
11
|
+
budget: 5,
|
|
12
|
+
eventLogPath: '.ai-costguard/events.jsonl',
|
|
13
|
+
eventLogPrompt: 'none',
|
|
14
|
+
});
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Start the dashboard:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
ai-costguard dashboard --events .ai-costguard/events.jsonl --budget 5
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For scoped packages or one-off runs:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx @salimassili/ai-costguard dashboard --events .ai-costguard/events.jsonl --budget 5
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
If the package is installed locally, this also works:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx ai-costguard dashboard --events .ai-costguard/events.jsonl --budget 5
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## What It Shows
|
|
36
|
+
|
|
37
|
+
- Budget used
|
|
38
|
+
- Requests allowed
|
|
39
|
+
- Requests blocked
|
|
40
|
+
- Estimated spend
|
|
41
|
+
- Estimated savings
|
|
42
|
+
- Attempted spend
|
|
43
|
+
- Actual spend when provider usage is available
|
|
44
|
+
- Loop detections
|
|
45
|
+
- Retry detections
|
|
46
|
+
- Recent guard events
|
|
47
|
+
|
|
48
|
+
## Non-Interactive Summary
|
|
49
|
+
|
|
50
|
+
Use `--once` for CI, smoke tests, or terminal summaries:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
ai-costguard dashboard --events .ai-costguard/events.jsonl --budget 5 --once
|
|
54
|
+
ai-costguard dashboard --events .ai-costguard/events.jsonl --budget 5 --once --json
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Privacy Notes
|
|
58
|
+
|
|
59
|
+
`eventLogPrompt` defaults to `none`, so prompt text is not written to disk. Set `eventLogPrompt: 'preview'` only for local debugging where prompt previews are acceptable.
|
|
60
|
+
|
|
61
|
+
The dashboard is a local development view, not a billing ledger. Use provider billing exports for financial reconciliation.
|