@salimassili/ai-costguard 2.1.2 → 2.1.4
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.
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { guard, GuardError, registerTokenizer } from '@salimassili/ai-costguard';
|
|
2
|
+
|
|
3
|
+
const slackWebhook = process.env.COSTGUARD_SLACK_WEBHOOK;
|
|
4
|
+
let providerCalls = 0;
|
|
5
|
+
|
|
6
|
+
// Keeps this demo output quiet and deterministic. Production apps can keep the
|
|
7
|
+
// default estimator or register a provider-specific tokenizer.
|
|
8
|
+
registerTokenizer('gpt-4o-mini', (text) => Math.ceil(text.length / 4));
|
|
9
|
+
|
|
10
|
+
const mockedOpenAI = {
|
|
11
|
+
chat: {
|
|
12
|
+
completions: {
|
|
13
|
+
create: async () => {
|
|
14
|
+
providerCalls += 1;
|
|
15
|
+
return {
|
|
16
|
+
id: 'mocked-provider-response',
|
|
17
|
+
choices: [{ message: { content: 'This should never execute in the demo.' } }],
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const openai = guard(mockedOpenAI, {
|
|
25
|
+
budget: 0.0001,
|
|
26
|
+
scope: { projectId: 'sales-demo', sessionId: 'slack-webhook-block-demo' },
|
|
27
|
+
webhooks: {
|
|
28
|
+
slack: slackWebhook,
|
|
29
|
+
retries: 0,
|
|
30
|
+
timeoutMs: 1000,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
console.log('AI CostGuard Slack webhook block demo');
|
|
35
|
+
console.log('Scenario: an agent tries to start an expensive model call with almost no budget left.');
|
|
36
|
+
console.log(`Slack alert: ${slackWebhook ? 'enabled from COSTGUARD_SLACK_WEBHOOK' : 'off by default'}`);
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
await openai.chat.completions.create({
|
|
40
|
+
model: 'gpt-4o-mini',
|
|
41
|
+
messages: [
|
|
42
|
+
{
|
|
43
|
+
role: 'user',
|
|
44
|
+
content:
|
|
45
|
+
'Run a large analysis job, summarize every retry, and reserve enough output for a long report.',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
max_tokens: 800,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
throw new Error('Expected AI CostGuard to block before the mocked provider ran.');
|
|
52
|
+
} catch (error) {
|
|
53
|
+
if (!(error instanceof GuardError)) {
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
console.log('Result: BLOCKED before provider execution');
|
|
58
|
+
console.log(`Reason: ${error.code}`);
|
|
59
|
+
console.log(`Estimated avoided spend: $${error.context.estimatedCost.toFixed(6)}`);
|
|
60
|
+
console.log(`Provider calls executed: ${providerCalls}`);
|
|
61
|
+
console.log('Webhook URL printed: no');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (providerCalls !== 0) {
|
|
65
|
+
throw new Error(`Provider executed ${providerCalls} time(s); expected 0.`);
|
|
66
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salimassili/ai-costguard",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.4",
|
|
4
4
|
"description": "Local-first runtime safety layer for AI agents that blocks runaway costs, loops, retries, and budget overruns before API calls execute.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|