@broberg/ai-sdk 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 +81 -0
- package/dist/index.d.ts +1146 -0
- package/dist/index.js +1416 -0
- package/dist/index.js.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# @broberg/ai-sdk
|
|
2
|
+
|
|
3
|
+
One AI/LLM SDK — one facade, all providers, all capabilities, with **first-class
|
|
4
|
+
cost control on every call**.
|
|
5
|
+
|
|
6
|
+
A provider-agnostic facade: your code calls `ai.chat()`, `ai.vision()`,
|
|
7
|
+
`ai.image()` — never a provider SDK directly. Swap providers by changing a tier,
|
|
8
|
+
not your call-sites. Every call returns a `Usage` (tokens, cost, latency,
|
|
9
|
+
transport) and can fan that out to any cost sink.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun add @broberg/ai-sdk # or: npm i @broberg/ai-sdk
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick start
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { createAI } from "@broberg/ai-sdk";
|
|
19
|
+
|
|
20
|
+
const ai = createAI(); // real adapters, keys from env (ANTHROPIC_API_KEY, …)
|
|
21
|
+
|
|
22
|
+
const { text, usage } = await ai.chat({ prompt: "Say hi in Danish" });
|
|
23
|
+
console.log(text, usage.costUsd);
|
|
24
|
+
|
|
25
|
+
const v = await ai.vision({ image: "https://…/photo.png", prompt: "Describe" });
|
|
26
|
+
const img = await ai.image({ prompt: "a sunlit beach in Blokhus" });
|
|
27
|
+
const da = await ai.translate({ text: "hello", to: "Danish" });
|
|
28
|
+
const emb = await ai.embedding({ text: ["a", "b"] });
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Capabilities
|
|
32
|
+
|
|
33
|
+
`chat` · `vision` · `translate` · `image` (fal.ai) · `embedding` · `transcribe`
|
|
34
|
+
(Whisper), plus **prompt contracts** with structured output:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { z } from "zod";
|
|
38
|
+
const { data } = await ai.contracts.extract({
|
|
39
|
+
text: "Sanne is 40 and lives in Blokhus",
|
|
40
|
+
schema: z.object({ name: z.string(), age: z.number(), city: z.string() }),
|
|
41
|
+
});
|
|
42
|
+
// also: ai.contracts.{ mockup, design, classify, rerank }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Providers & tiers
|
|
46
|
+
|
|
47
|
+
Adapters: **Anthropic** (HTTP + `claude -p` subprocess), **OpenAI**, **Google
|
|
48
|
+
Gemini**, **DeepInfra**, **OpenRouter** (incl. MiniMax), **fal.ai** (images).
|
|
49
|
+
|
|
50
|
+
Calls route through named **tiers** — `fast · smart · powerful · cheap · vision ·
|
|
51
|
+
embedding` — each resolving to a `(provider, model, transport)` triple,
|
|
52
|
+
overridable per call:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
await ai.chat({ prompt: "…", tier: "powerful" });
|
|
56
|
+
await ai.chat({ prompt: "…", override: { provider: "openrouter", model: "minimax/minimax-m2.7" } });
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`cheap` routes through the local `claude -p` CLI (Max plan → `costUsd: 0`,
|
|
60
|
+
flagged `subprocess: true`).
|
|
61
|
+
|
|
62
|
+
## Cost, budget & sinks
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { createAI, upmetricsSink, sqliteSink, multiSink } from "@broberg/ai-sdk";
|
|
66
|
+
|
|
67
|
+
const ai = createAI({
|
|
68
|
+
budget: { perCallUsd: 0.05, rollingUsd: 5 }, // pre-flight guard (throws BudgetExceededError)
|
|
69
|
+
costSink: multiSink([
|
|
70
|
+
upmetricsSink({ baseUrl: "https://upmetrics.org", apiKey: process.env.UPMETRICS_API_KEY!, agentName: "my-app" }),
|
|
71
|
+
sqliteSink({ dbPath: "./ai-cost.db" }),
|
|
72
|
+
]),
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Sinks: `upmetricsSink` (canonical), `discordSink`, `sqliteSink`, `multiSink`,
|
|
77
|
+
`noopSink`. A failing sink never crashes a call.
|
|
78
|
+
|
|
79
|
+
## License
|
|
80
|
+
|
|
81
|
+
FSL-1.1-Apache-2.0
|