@salimassili/ai-costguard 2.0.1 → 2.1.1
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 +18 -4
- package/README.md +70 -23
- package/benchmarks/token-accuracy.mjs +102 -4
- 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/tokenizer.d.ts +19 -1
- package/dist/core/tokenizer.d.ts.map +1 -1
- package/dist/core/tokenizer.js +132 -75
- package/dist/core/tokenizer.js.map +1 -1
- package/dist/core/types.d.ts +11 -0
- package/dist/core/types.d.ts.map +1 -1
- 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 +17 -0
- package/dist/pricing/index.d.ts.map +1 -1
- package/dist/pricing/index.js +24 -5
- package/dist/pricing/index.js.map +1 -1
- package/docs/BENCHMARKS.md +16 -16
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 2.
|
|
3
|
+
## 2.1.1 - Unreleased
|
|
4
4
|
|
|
5
5
|
### Changed
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- Recalibrated the built-in zero-dependency token estimator with simple model-family and text-shape heuristics.
|
|
8
|
+
- Improved the fixed proxy token benchmark from `237.76%` average error to `9.68%` average error while keeping `registerTokenizer()` as the recommended exact-counting path.
|
|
9
|
+
|
|
10
|
+
## 2.1.0 - 2026-06-09
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Added `registerTokenizer()` for exact/provider-specific token counting without adding production dependencies.
|
|
15
|
+
- Added `getPricingMeta()` and `aifw pricing --check-stale --days <n>` for pricing freshness checks.
|
|
16
|
+
- Added structured `loopDetection` config with `similarityThreshold`, `minHistorySize`, and `windowSize`.
|
|
17
|
+
- Expanded the token accuracy benchmark to a 24-sample proxy corpus with per-sample output.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- Removed obsolete license-related surfaces. AI CostGuard does not contain license-key checks or local commercial-license enforcement.
|
|
8
22
|
- Added explicit built-in pricing freshness notice: `2026-06-07`.
|
|
9
|
-
-
|
|
10
|
-
-
|
|
23
|
+
- Updated README loop detection tuning, pricing freshness, token accuracy, and trust guidance.
|
|
24
|
+
- Documented that the built-in estimator materially overestimates the fixed proxy corpus and that production users can register exact tokenizers.
|
|
11
25
|
|
|
12
26
|
## 2.0.0 - 2026-06-08
|
|
13
27
|
|
package/README.md
CHANGED
|
@@ -149,12 +149,15 @@ Current runtime block codes:
|
|
|
149
149
|
guard(client, {
|
|
150
150
|
budget: 10,
|
|
151
151
|
maxSteps: 100,
|
|
152
|
-
behaviorAnalysis: true,
|
|
153
|
-
maxHistory: 32,
|
|
154
|
-
historyTtlMs: 5 * 60 * 1000,
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
152
|
+
behaviorAnalysis: true,
|
|
153
|
+
maxHistory: 32,
|
|
154
|
+
historyTtlMs: 5 * 60 * 1000,
|
|
155
|
+
loopDetection: {
|
|
156
|
+
similarityThreshold: 0.85,
|
|
157
|
+
minHistorySize: 2,
|
|
158
|
+
windowSize: 5,
|
|
159
|
+
},
|
|
160
|
+
retryThreshold: 2,
|
|
158
161
|
scope: {
|
|
159
162
|
projectId: 'production-api',
|
|
160
163
|
userId: 'optional-user',
|
|
@@ -177,23 +180,32 @@ guard(client, {
|
|
|
177
180
|
|
|
178
181
|
## Loop Detection Tuning
|
|
179
182
|
|
|
180
|
-
Default loop detection uses character trigram cosine similarity with
|
|
183
|
+
Default loop detection uses character trigram cosine similarity with:
|
|
184
|
+
|
|
185
|
+
- `loopDetection.similarityThreshold: 0.85`
|
|
186
|
+
- `loopDetection.minHistorySize: 2`
|
|
187
|
+
- `loopDetection.windowSize: 5`
|
|
181
188
|
|
|
182
189
|
- Higher threshold, such as `0.95`: fewer false positives, but near-duplicate loops can slip through.
|
|
183
190
|
- Lower threshold, such as `0.75`: catches looser repeats, but unrelated prompts can be blocked.
|
|
184
|
-
- Higher `
|
|
185
|
-
- Lower `
|
|
191
|
+
- Higher `minHistorySize`: waits for more repeated prompts before blocking.
|
|
192
|
+
- Lower `minHistorySize`: blocks faster, but is more aggressive.
|
|
193
|
+
- Smaller `windowSize`: compares fewer recent prompts, reducing old-history false positives.
|
|
194
|
+
- Larger `windowSize`: compares more history, improving catch rate but increasing false-positive risk in repetitive workflows.
|
|
186
195
|
|
|
187
196
|
```ts
|
|
188
197
|
const openai = guard(client, {
|
|
189
198
|
budget: 5,
|
|
190
|
-
|
|
191
|
-
|
|
199
|
+
loopDetection: {
|
|
200
|
+
similarityThreshold: 0.9,
|
|
201
|
+
minHistorySize: 3,
|
|
202
|
+
windowSize: 6,
|
|
203
|
+
},
|
|
192
204
|
scope: { sessionId: 'agent-run-123' },
|
|
193
205
|
});
|
|
194
206
|
```
|
|
195
207
|
|
|
196
|
-
Loop detection is heuristic. Expect false positives and false negatives, especially for short prompts, templated prompts, and prompts that share a lot of boilerplate.
|
|
208
|
+
Legacy `loopSimilarityThreshold` and `loopMinRepeats` config fields are still accepted, but `loopDetection` takes precedence. Loop detection is heuristic. Expect false positives and false negatives, especially for short prompts, templated prompts, and prompts that share a lot of boilerplate.
|
|
197
209
|
|
|
198
210
|
## Accounting Semantics
|
|
199
211
|
|
|
@@ -213,7 +225,7 @@ Known model pricing comes from built-in registry entries, runtime registrations,
|
|
|
213
225
|
Pricing last updated: `2026-06-07`. Provider pricing changes; AI CostGuard does not fetch real-time pricing. Override pricing manually when provider pages or your contract pricing differ from the built-ins.
|
|
214
226
|
|
|
215
227
|
```ts
|
|
216
|
-
import { registerPricing } from '@salimassili/ai-costguard';
|
|
228
|
+
import { getPricingMeta, registerPricing } from '@salimassili/ai-costguard';
|
|
217
229
|
|
|
218
230
|
registerPricing([
|
|
219
231
|
{
|
|
@@ -223,8 +235,18 @@ registerPricing([
|
|
|
223
235
|
lastUpdated: '2026-06-07',
|
|
224
236
|
source: 'internal',
|
|
225
237
|
},
|
|
226
|
-
]);
|
|
227
|
-
|
|
238
|
+
]);
|
|
239
|
+
|
|
240
|
+
console.log(getPricingMeta('gpt-4o-mini'));
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Check built-in pricing freshness from CI or a release script:
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
aifw pricing --check-stale --days 30
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
The command exits `0` when all registry entries are within the threshold and `1` when one or more entries are stale.
|
|
228
250
|
|
|
229
251
|
If you intentionally want fallback pricing for unknown models:
|
|
230
252
|
|
|
@@ -242,7 +264,31 @@ guard(client, {
|
|
|
242
264
|
});
|
|
243
265
|
```
|
|
244
266
|
|
|
245
|
-
Pricing changes frequently. Verify provider pricing before production use and override entries when needed.
|
|
267
|
+
Pricing changes frequently. Verify provider pricing before production use and override entries when needed.
|
|
268
|
+
|
|
269
|
+
## Token Counting Accuracy
|
|
270
|
+
|
|
271
|
+
AI CostGuard ships with a dependency-free token estimator so the root package stays small. It warns once per model/scope when approximate counting is used:
|
|
272
|
+
|
|
273
|
+
```text
|
|
274
|
+
[ai-costguard] Using approximate token counting for model: gpt-4o-mini. Register an exact tokenizer via registerTokenizer() for production use.
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
For production budgets that need tighter input-token estimates, register a provider tokenizer:
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
import { registerTokenizer } from '@salimassili/ai-costguard';
|
|
281
|
+
|
|
282
|
+
registerTokenizer('gpt-4o-mini', (text) => {
|
|
283
|
+
return myTokenizer.encode(text).length;
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
registerTokenizer(/^claude-/u, (text) => {
|
|
287
|
+
return myAnthropicTokenizer.count(text);
|
|
288
|
+
});
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
String patterns match model-name substrings case-insensitively. `RegExp` patterns are tested against the original model string. If a registered tokenizer throws or returns an invalid count, AI CostGuard falls back to the built-in approximation and keeps guarding the call.
|
|
246
292
|
|
|
247
293
|
## Events
|
|
248
294
|
|
|
@@ -392,9 +438,9 @@ npm run benchmark
|
|
|
392
438
|
|
|
393
439
|
The script reports runtime overhead, approximate heap delta, false-positive scenarios, loop detection behavior, and cost-estimation boundaries. Results are local measurements, not universal guarantees. See `docs/BENCHMARKS.md`.
|
|
394
440
|
|
|
395
|
-
Latest local benchmark in this repo on Node `v24.14.1` / Windows measured `0.
|
|
441
|
+
Latest local benchmark in this repo on Node `v24.14.1` / Windows measured `0.023937 ms` added per mocked guarded call over `5000` iterations. Re-run on your target runtime before using this number in performance-sensitive claims.
|
|
396
442
|
|
|
397
|
-
Token accuracy benchmark, fixed corpus
|
|
443
|
+
Token accuracy benchmark, fixed proxy corpus: average error `9.68%`, median error `11.43%`, max error `28.57%`, `24` samples. The dependency-free estimator is a rough guardrail, not provider-tokenizer parity. Register an exact tokenizer for production use when token accuracy matters.
|
|
398
444
|
|
|
399
445
|
## Why Not 50 Lines Of Code?
|
|
400
446
|
|
|
@@ -417,15 +463,16 @@ npm ci
|
|
|
417
463
|
npm run build
|
|
418
464
|
npm run typecheck
|
|
419
465
|
npm test
|
|
420
|
-
npm run smoke
|
|
421
|
-
npm run benchmark
|
|
422
|
-
npm
|
|
423
|
-
npm
|
|
466
|
+
npm run smoke
|
|
467
|
+
npm run benchmark
|
|
468
|
+
npm run benchmark:tokens
|
|
469
|
+
npm audit --omit=dev
|
|
470
|
+
npm pack --dry-run
|
|
424
471
|
```
|
|
425
472
|
|
|
426
473
|
## Limitations
|
|
427
474
|
|
|
428
|
-
- Token counting is approximate and dependency-free.
|
|
475
|
+
- Token counting is approximate and dependency-free unless you register an exact tokenizer.
|
|
429
476
|
- Token estimation is intentionally conservative and can overestimate materially; see the token accuracy benchmark.
|
|
430
477
|
- Pricing entries can become stale; override them for production.
|
|
431
478
|
- The free guard is process-local.
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { estimateTokensForModel } from '../dist/core/tokenizer.js';
|
|
2
2
|
|
|
3
3
|
const corpus = [
|
|
4
|
+
{ label: 'short english', text: 'Summarize this ticket.', referenceTokens: 5 },
|
|
5
|
+
{
|
|
6
|
+
label: 'long english',
|
|
7
|
+
text:
|
|
8
|
+
'A customer reports that their nightly invoice reconciliation agent loops after a database timeout. ' +
|
|
9
|
+
'Explain the likely failure mode and propose two safe remediation steps.',
|
|
10
|
+
referenceTokens: 31,
|
|
11
|
+
},
|
|
4
12
|
{ label: 'support summary', text: 'Summarize this support ticket in two bullets.', referenceTokens: 9 },
|
|
5
13
|
{
|
|
6
14
|
label: 'agent instruction',
|
|
@@ -17,6 +25,49 @@ const corpus = [
|
|
|
17
25
|
text: 'function normalizeUser(user) { return { id: user.id, email: user.email?.toLowerCase() }; }',
|
|
18
26
|
referenceTokens: 24,
|
|
19
27
|
},
|
|
28
|
+
{
|
|
29
|
+
label: 'python code',
|
|
30
|
+
text: 'def should_retry(error):\n return error.status in {429, 500, 503} and error.attempts < 3',
|
|
31
|
+
referenceTokens: 27,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
label: 'json config',
|
|
35
|
+
text: '{"model":"gpt-4o-mini","max_tokens":400,"tools":[{"name":"search","strict":true}]}',
|
|
36
|
+
referenceTokens: 25,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
label: 'markdown task',
|
|
40
|
+
text: '## Release checklist\n- Run tests\n- Verify npm pack\n- Publish patch\n- Tag the release',
|
|
41
|
+
referenceTokens: 22,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
label: 'arabic prompt',
|
|
45
|
+
text: 'لخص محادثة الدعم هذه وحدد السبب الجذري والخطوة التالية.',
|
|
46
|
+
referenceTokens: 18,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
label: 'french prompt',
|
|
50
|
+
text: 'Explique pourquoi le budget de l’agent a été dépassé et propose une limite plus sûre.',
|
|
51
|
+
referenceTokens: 20,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
label: 'repeated loop',
|
|
55
|
+
text: 'retry retry retry retry retry retry retry retry retry retry',
|
|
56
|
+
referenceTokens: 10,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
label: 'tool call like',
|
|
60
|
+
text:
|
|
61
|
+
'tool_call: {"name":"fetch_invoice","arguments":{"customerId":"cus_123","month":"2026-06"}} ' +
|
|
62
|
+
'result: {"status":"timeout"}',
|
|
63
|
+
referenceTokens: 34,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
label: 'agent loop like',
|
|
67
|
+
text:
|
|
68
|
+
'Step 12 failed. Try the same retrieval again with identical arguments, then repeat until the API returns data.',
|
|
69
|
+
referenceTokens: 22,
|
|
70
|
+
},
|
|
20
71
|
{
|
|
21
72
|
label: 'model comparison',
|
|
22
73
|
text: 'Compare Claude Haiku and GPT-4o mini for a budget-sensitive chatbot.',
|
|
@@ -37,15 +88,49 @@ const corpus = [
|
|
|
37
88
|
text: 'Create a TypeScript interface for a webhook payload with cost, model, and reason fields.',
|
|
38
89
|
referenceTokens: 17,
|
|
39
90
|
},
|
|
91
|
+
{
|
|
92
|
+
label: 'sql query',
|
|
93
|
+
text: 'SELECT tenant_id, SUM(cost_usd) FROM ai_events WHERE blocked = false GROUP BY tenant_id;',
|
|
94
|
+
referenceTokens: 23,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
label: 'error stack',
|
|
98
|
+
text: 'Error: Budget exceeded\n at GuardCore.check (src/core/GuardCore.ts:144:11)\n at agent.run (agent.ts:42:7)',
|
|
99
|
+
referenceTokens: 33,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
label: 'anthropic workflow',
|
|
103
|
+
model: 'claude-sonnet-4.6',
|
|
104
|
+
text:
|
|
105
|
+
'Claude should inspect the document, call the classifier once, and stop if confidence is below 0.7.',
|
|
106
|
+
referenceTokens: 21,
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
label: 'vercel chatbot',
|
|
110
|
+
text:
|
|
111
|
+
'streamText should answer the user only after the guard confirms the remaining session budget is sufficient.',
|
|
112
|
+
referenceTokens: 19,
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
label: 'ci budget check',
|
|
116
|
+
text: 'npx aifw check --budget 1 --model gpt-4o-mini --tokens 800 --max-steps 20',
|
|
117
|
+
referenceTokens: 29,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
label: 'mixed punctuation',
|
|
121
|
+
text: 'Guard this: $$$, retries=3, model=gpt-4o-mini, scope=session:abc, max_tokens=250.',
|
|
122
|
+
referenceTokens: 28,
|
|
123
|
+
},
|
|
40
124
|
];
|
|
41
125
|
|
|
42
126
|
const samples = corpus.map((sample) => {
|
|
43
|
-
const estimatedTokens =
|
|
127
|
+
const estimatedTokens = estimateTokensForModel(sample.model, sample.text).tokens;
|
|
44
128
|
const absoluteError = Math.abs(estimatedTokens - sample.referenceTokens);
|
|
45
129
|
const percentError = (absoluteError / sample.referenceTokens) * 100;
|
|
46
130
|
|
|
47
131
|
return {
|
|
48
132
|
label: sample.label,
|
|
133
|
+
model: sample.model ?? 'default-gpt-family',
|
|
49
134
|
estimatedTokens,
|
|
50
135
|
referenceTokens: sample.referenceTokens,
|
|
51
136
|
absoluteError,
|
|
@@ -57,14 +142,15 @@ const percentErrors = samples.map((sample) => sample.percentError).sort((a, b) =
|
|
|
57
142
|
const report = {
|
|
58
143
|
generatedAt: new Date().toISOString(),
|
|
59
144
|
reference: {
|
|
60
|
-
tokenizer: '
|
|
145
|
+
tokenizer: 'fixed proxy fixture counts',
|
|
61
146
|
note:
|
|
62
|
-
'Reference counts are
|
|
147
|
+
'Reference counts are dependency-free proxy fixtures, not live provider tokenizers. Use this to understand estimator bias and boundaries, not to claim exact provider parity.',
|
|
63
148
|
},
|
|
64
149
|
sampleCount: samples.length,
|
|
65
150
|
averageErrorPercent: round(average(percentErrors), 2),
|
|
66
151
|
medianErrorPercent: round(median(percentErrors), 2),
|
|
67
152
|
maxErrorPercent: Math.max(...percentErrors),
|
|
153
|
+
markdownTable: formatMarkdownTable(samples),
|
|
68
154
|
samples,
|
|
69
155
|
};
|
|
70
156
|
|
|
@@ -84,3 +170,15 @@ function round(value, digits) {
|
|
|
84
170
|
const factor = 10 ** digits;
|
|
85
171
|
return Math.round(value * factor) / factor;
|
|
86
172
|
}
|
|
173
|
+
|
|
174
|
+
function formatMarkdownTable(rows) {
|
|
175
|
+
const lines = ['| sample | estimate | proxy | error | error % |', '| --- | ---: | ---: | ---: | ---: |'];
|
|
176
|
+
|
|
177
|
+
for (const row of rows) {
|
|
178
|
+
lines.push(
|
|
179
|
+
`| ${row.label} | ${row.estimatedTokens} | ${row.referenceTokens} | ${row.absoluteError} | ${row.percentError}% |`
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return lines.join('\n');
|
|
184
|
+
}
|
package/dist/cli.d.ts
CHANGED
|
@@ -35,6 +35,13 @@ export interface CliDashboardOptions extends DashboardOptions {
|
|
|
35
35
|
once: boolean;
|
|
36
36
|
json: boolean;
|
|
37
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Parsed options for the pricing freshness command.
|
|
40
|
+
*/
|
|
41
|
+
export interface CliPricingOptions {
|
|
42
|
+
checkStale: boolean;
|
|
43
|
+
days: number;
|
|
44
|
+
}
|
|
38
45
|
/**
|
|
39
46
|
* Parses arguments for `aifw check`.
|
|
40
47
|
*/
|
|
@@ -43,6 +50,10 @@ export declare function parseCheckArgs(args: readonly string[]): CliCheckOptions
|
|
|
43
50
|
* Parses arguments for `aifw dashboard`.
|
|
44
51
|
*/
|
|
45
52
|
export declare function parseDashboardArgs(args: readonly string[]): CliDashboardOptions;
|
|
53
|
+
/**
|
|
54
|
+
* Parses arguments for `aifw pricing`.
|
|
55
|
+
*/
|
|
56
|
+
export declare function parsePricingArgs(args: readonly string[]): CliPricingOptions;
|
|
46
57
|
/**
|
|
47
58
|
* Runs the aifw CLI and returns a process exit code.
|
|
48
59
|
*/
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAGA,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AAExB;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,8BAA8B;IAC9B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,6BAA6B;IAC7B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,eAAe,CA0BvE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,mBAAmB,CAgC/E;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,GAAE,SAAS,MAAM,EAA0B,EAAE,EAAE,GAAE,KAAiB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAGA,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AAExB;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,8BAA8B;IAC9B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,6BAA6B;IAC7B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mDAAmD;IACnD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,gBAAgB;IAC3D,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,eAAe,CA0BvE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,mBAAmB,CAgC/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,CA+B3E;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,GAAE,SAAS,MAAM,EAA0B,EAAE,EAAE,GAAE,KAAiB,GAAG,MAAM,CA6GrG"}
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { getPricing } from './pricing/index.js';
|
|
2
|
+
import { getPricing, listPricing } from './pricing/index.js';
|
|
3
3
|
import { formatDashboardSummary, getDefaultEventLogPath, startDashboardServer, summarizeDashboard, } from './dashboard.js';
|
|
4
4
|
/**
|
|
5
5
|
* Parses arguments for `aifw check`.
|
|
@@ -60,6 +60,36 @@ export function parseDashboardArgs(args) {
|
|
|
60
60
|
json: flags.has('json'),
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Parses arguments for `aifw pricing`.
|
|
65
|
+
*/
|
|
66
|
+
export function parsePricingArgs(args) {
|
|
67
|
+
const options = new Map();
|
|
68
|
+
const flags = new Set();
|
|
69
|
+
for (let index = 0; index < args.length; index++) {
|
|
70
|
+
const arg = args[index];
|
|
71
|
+
if (!arg.startsWith('--'))
|
|
72
|
+
continue;
|
|
73
|
+
const key = arg.slice(2);
|
|
74
|
+
if (key === 'check-stale') {
|
|
75
|
+
flags.add(key);
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
const value = args[index + 1];
|
|
79
|
+
if (!value || value.startsWith('--')) {
|
|
80
|
+
throw new Error(`Missing value for --${key}`);
|
|
81
|
+
}
|
|
82
|
+
options.set(key, value);
|
|
83
|
+
index += 1;
|
|
84
|
+
}
|
|
85
|
+
if (!flags.has('check-stale')) {
|
|
86
|
+
throw new Error('aifw pricing currently supports --check-stale');
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
checkStale: true,
|
|
90
|
+
days: readOptionalNumber(options, 'days') ?? 30,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
63
93
|
/**
|
|
64
94
|
* Runs the aifw CLI and returns a process exit code.
|
|
65
95
|
*/
|
|
@@ -69,7 +99,7 @@ export function runCli(args = process.argv.slice(2), io = defaultIO) {
|
|
|
69
99
|
io.stdout(helpText());
|
|
70
100
|
return 0;
|
|
71
101
|
}
|
|
72
|
-
if (command !== 'check' && command !== 'dashboard') {
|
|
102
|
+
if (command !== 'check' && command !== 'dashboard' && command !== 'pricing') {
|
|
73
103
|
io.stderr(`Unknown command: ${command}\n\n${helpText()}`);
|
|
74
104
|
return 2;
|
|
75
105
|
}
|
|
@@ -91,6 +121,30 @@ export function runCli(args = process.argv.slice(2), io = defaultIO) {
|
|
|
91
121
|
});
|
|
92
122
|
return 0;
|
|
93
123
|
}
|
|
124
|
+
if (command === 'pricing') {
|
|
125
|
+
const options = parsePricingArgs(args.slice(1));
|
|
126
|
+
const entries = listPricing()
|
|
127
|
+
.map((entry) => {
|
|
128
|
+
const ageDays = getPricingAgeDays(entry.lastUpdated);
|
|
129
|
+
return {
|
|
130
|
+
model: entry.model,
|
|
131
|
+
lastUpdated: entry.lastUpdated,
|
|
132
|
+
source: entry.source,
|
|
133
|
+
ageDays,
|
|
134
|
+
stale: ageDays > options.days,
|
|
135
|
+
};
|
|
136
|
+
})
|
|
137
|
+
.sort((a, b) => a.model.localeCompare(b.model));
|
|
138
|
+
const staleCount = entries.filter((entry) => entry.stale).length;
|
|
139
|
+
io.stdout(JSON.stringify({
|
|
140
|
+
ok: staleCount === 0,
|
|
141
|
+
checkedAt: new Date().toISOString(),
|
|
142
|
+
thresholdDays: options.days,
|
|
143
|
+
staleCount,
|
|
144
|
+
entries,
|
|
145
|
+
}, null, 2) + '\n');
|
|
146
|
+
return staleCount === 0 ? 0 : 1;
|
|
147
|
+
}
|
|
94
148
|
const options = parseCheckArgs(args.slice(1));
|
|
95
149
|
const pricing = getPricing(options.model);
|
|
96
150
|
const hasCustomPricing = options.inputPricePer1k !== undefined || options.outputPricePer1k !== undefined;
|
|
@@ -156,6 +210,7 @@ function helpText() {
|
|
|
156
210
|
return [
|
|
157
211
|
'Usage:',
|
|
158
212
|
' aifw check --budget <usd> --model <model> --tokens <output-tokens> --max-steps <n>',
|
|
213
|
+
' aifw pricing --check-stale --days 30',
|
|
159
214
|
' aifw dashboard --events .ai-costguard/events.jsonl --budget <usd>',
|
|
160
215
|
' ai-costguard dashboard --once --json',
|
|
161
216
|
'',
|
|
@@ -167,6 +222,12 @@ function helpText() {
|
|
|
167
222
|
'',
|
|
168
223
|
].join('\n');
|
|
169
224
|
}
|
|
225
|
+
function getPricingAgeDays(lastUpdated) {
|
|
226
|
+
const lastUpdatedMs = Date.parse(`${lastUpdated}T00:00:00.000Z`);
|
|
227
|
+
if (!Number.isFinite(lastUpdatedMs))
|
|
228
|
+
return Number.POSITIVE_INFINITY;
|
|
229
|
+
return Math.max(0, Math.floor((Date.now() - lastUpdatedMs) / 86_400_000));
|
|
230
|
+
}
|
|
170
231
|
function readOptionalString(options, key) {
|
|
171
232
|
const value = options.get(key);
|
|
172
233
|
return value?.trim() ? value.trim() : undefined;
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/core/CostGuard.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export { guard, guardFunction, GuardError, middleware } from './GuardFree.js';
|
|
2
2
|
export type { GuardedClient, GuardEventControls } from './GuardFree.js';
|
|
3
|
-
export { BUILTIN_PRICING_LAST_UPDATED, 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 './tokenizer.js';
|
|
6
|
+
export type { TokenizerFn } from './tokenizer.js';
|
|
5
7
|
export type { GuardConfig, GuardErrorCode, GuardEvent, GuardEventHandler, GuardEventName, GuardScope, GuardState, GuardWebhookConfig, RequestContext, } from './types.js';
|
|
6
8
|
//# sourceMappingURL=CostGuard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CostGuard.d.ts","sourceRoot":"","sources":["../../src/core/CostGuard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC9E,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,4BAA4B,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"CostGuard.d.ts","sourceRoot":"","sources":["../../src/core/CostGuard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC9E,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,4BAA4B,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAC7H,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EACV,WAAW,EACX,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,cAAc,GACf,MAAM,YAAY,CAAC"}
|
package/dist/core/CostGuard.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { guard, guardFunction, GuardError, middleware } from './GuardFree.js';
|
|
2
|
-
export { BUILTIN_PRICING_LAST_UPDATED, 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 './tokenizer.js';
|
|
3
4
|
//# sourceMappingURL=CostGuard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CostGuard.js","sourceRoot":"","sources":["../../src/core/CostGuard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE9E,OAAO,EAAE,4BAA4B,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"CostGuard.js","sourceRoot":"","sources":["../../src/core/CostGuard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE9E,OAAO,EAAE,4BAA4B,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE7H,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/core/GuardCore.d.ts
CHANGED
|
@@ -50,6 +50,7 @@ export declare class GuardCore {
|
|
|
50
50
|
private readonly config;
|
|
51
51
|
private readonly state;
|
|
52
52
|
private readonly emitter;
|
|
53
|
+
private readonly approximateTokenWarnings;
|
|
53
54
|
/**
|
|
54
55
|
* Creates a process-local guard evaluator.
|
|
55
56
|
*/
|
|
@@ -94,6 +95,7 @@ export declare class GuardCore {
|
|
|
94
95
|
private getScopeState;
|
|
95
96
|
private pruneScope;
|
|
96
97
|
private extractScope;
|
|
98
|
+
private warnApproximateTokens;
|
|
97
99
|
}
|
|
98
100
|
/**
|
|
99
101
|
* Creates an empty process-local guard state.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GuardCore.d.ts","sourceRoot":"","sources":["../../src/core/GuardCore.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,cAAc,EAGd,UAAU,EACV,cAAc,EACf,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"GuardCore.d.ts","sourceRoot":"","sources":["../../src/core/GuardCore.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,iBAAiB,EACjB,cAAc,EAGd,UAAU,EACV,cAAc,EACf,MAAM,YAAY,CAAC;AAoBpB;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4BAA4B;IAC5B,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC;IAC5B,0CAA0C;IAC1C,OAAO,EAAE,cAAc,CAAC;IACxB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,IAAI,EAAE,cAAc,CAAC;IACrB,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,4CAA4C;IAC5C,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IAEtC;;OAEG;gBAED,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,cAAqC,EAC9C,IAAI,GAAE,cAAkC,EACxC,QAAQ,GAAE,OAAO,CAAC,kBAAkB,CAAM;IAe5C,MAAM,IAAI,kBAAkB;CAG7B;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAyBrB;IACF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAa;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAqB;IAE9D;;OAEG;gBACS,MAAM,GAAE,WAAgB,EAAE,WAAW,GAAE,UAA+B;IAsClF;;OAEG;IACH,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,IAAI;IAIrE;;OAEG;IACH,GAAG,CAAC,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAIhE;;OAEG;IACH,QAAQ,IAAI,UAAU;IAItB;;OAEG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAI9C;;OAEG;IACH,cAAc,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,cAAc;IAkCzE;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,cAAc,GAAG,gBAAgB;IAqChD;;OAEG;IACH,iBAAiB,CAAC,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,GAAG,IAAI;IAoBnE,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,eAAe;IAoBvB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,WAAW;IAanB,OAAO,CAAC,KAAK;IAkBb,OAAO,CAAC,IAAI;IAaZ,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,qBAAqB;CAU9B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAK7C"}
|