floe-guard 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/README.md +63 -0
- package/dist/index.cjs +982 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +177 -0
- package/dist/index.d.ts +177 -0
- package/dist/index.js +954 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
- package/src/cost_map.json +734 -0
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# floe-guard (Vercel AI SDK)
|
|
2
|
+
|
|
3
|
+
**A local budget guardrail for AI agents** — the TypeScript counterpart to the
|
|
4
|
+
[Python `floe-guard`](../README.md). It hard-stops your agent *before its next LLM
|
|
5
|
+
call* when it would cross a USD spend ceiling. No account, no signup, no network.
|
|
6
|
+
Runs in your process.
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm i floe-guard ai@4 @ai-sdk/openai
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { wrapLanguageModel } from "ai";
|
|
14
|
+
import { openai } from "@ai-sdk/openai";
|
|
15
|
+
import { BudgetGuard, budgetGuardMiddleware } from "floe-guard";
|
|
16
|
+
|
|
17
|
+
const guard = new BudgetGuard(5.0); // your ceiling, in USD
|
|
18
|
+
|
|
19
|
+
const model = wrapLanguageModel({
|
|
20
|
+
model: openai("gpt-4o"),
|
|
21
|
+
middleware: budgetGuardMiddleware(guard),
|
|
22
|
+
});
|
|
23
|
+
// generateText / streamText with `model` now stop at $5 — the call that would
|
|
24
|
+
// cross the ceiling throws `BudgetExceeded` BEFORE it runs.
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The middleware sits in the call path: it `check()`s before `doGenerate` /
|
|
28
|
+
`doStream` (throwing `BudgetExceeded` to halt the run) and `record()`s priced
|
|
29
|
+
token usage after — for streaming it reads usage from the `finish` part.
|
|
30
|
+
|
|
31
|
+
## Pricing
|
|
32
|
+
|
|
33
|
+
Tokens are priced **offline** from a bundled
|
|
34
|
+
[LiteLLM cost map](src/cost_map.json). A model that isn't in the map (and has no
|
|
35
|
+
manual price) **fails closed**: `record` throws `UnpriceableModelError` rather
|
|
36
|
+
than silently treating spend as free — *you can't cap spend you can't measure.*
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
const guard = new BudgetGuard(5.0, {
|
|
40
|
+
priceOverrides: {
|
|
41
|
+
"my-self-hosted-model": { inputCostPerToken: 1e-6, outputCostPerToken: 2e-6 },
|
|
42
|
+
},
|
|
43
|
+
// or failClosed: false to warn-and-skip for models you accept un-metered.
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Verified against
|
|
48
|
+
|
|
49
|
+
`ai@4` (`LanguageModelV1Middleware` via `wrapLanguageModel` /
|
|
50
|
+
`experimental_wrapLanguageModel`). Declared as a peer dependency.
|
|
51
|
+
|
|
52
|
+
## Development
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install
|
|
56
|
+
npm run build
|
|
57
|
+
npm test
|
|
58
|
+
npm run typecheck
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## License
|
|
62
|
+
|
|
63
|
+
MIT — see [../LICENSE](../LICENSE).
|