@broberg/ai-sdk 0.3.1 → 0.4.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/dist/index.d.ts +26 -2
- package/dist/index.js +25 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -66,6 +66,9 @@ interface Usage {
|
|
|
66
66
|
latencyMs: number;
|
|
67
67
|
capability: Capability;
|
|
68
68
|
purpose?: string;
|
|
69
|
+
/** Consumer-defined attribution dimensions (e.g. {tenantId}) for per-tenant
|
|
70
|
+
* cost breakdown — the sink forwards these (F011). */
|
|
71
|
+
labels?: Record<string, string>;
|
|
69
72
|
ts: string;
|
|
70
73
|
subprocess?: true;
|
|
71
74
|
}
|
|
@@ -100,6 +103,9 @@ interface CallOptions {
|
|
|
100
103
|
* cms/trail/sanne/xrt81 all hand-roll this — make it first-class). */
|
|
101
104
|
fallback?: (Tier | TierSpec)[];
|
|
102
105
|
purpose?: string;
|
|
106
|
+
/** Consumer-defined attribution dimensions (e.g. {tenantId}) carried onto
|
|
107
|
+
* Usage and forwarded by the cost sink for per-tenant cost breakdown (F011). */
|
|
108
|
+
labels?: Record<string, string>;
|
|
103
109
|
}
|
|
104
110
|
interface ChatRequest {
|
|
105
111
|
messages: Message[];
|
|
@@ -383,6 +389,7 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
383
389
|
transport: "http" | "subprocess";
|
|
384
390
|
}>]>, "many">>;
|
|
385
391
|
purpose: z.ZodOptional<z.ZodString>;
|
|
392
|
+
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
386
393
|
prompt: z.ZodOptional<z.ZodString>;
|
|
387
394
|
messages: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
388
395
|
role: z.ZodEnum<["system", "user", "assistant", "tool"]>;
|
|
@@ -513,6 +520,7 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
513
520
|
transport: "http" | "subprocess";
|
|
514
521
|
})[] | undefined;
|
|
515
522
|
purpose?: string | undefined;
|
|
523
|
+
labels?: Record<string, string> | undefined;
|
|
516
524
|
}, {
|
|
517
525
|
system?: string | undefined;
|
|
518
526
|
prompt?: string | undefined;
|
|
@@ -553,6 +561,7 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
553
561
|
transport: "http" | "subprocess";
|
|
554
562
|
})[] | undefined;
|
|
555
563
|
purpose?: string | undefined;
|
|
564
|
+
labels?: Record<string, string> | undefined;
|
|
556
565
|
}>;
|
|
557
566
|
declare const visionInputSchema: z.ZodObject<{
|
|
558
567
|
tier: z.ZodOptional<z.ZodEnum<["fast", "smart", "powerful", "cheap", "vision", "embedding"]>>;
|
|
@@ -583,6 +592,7 @@ declare const visionInputSchema: z.ZodObject<{
|
|
|
583
592
|
transport: "http" | "subprocess";
|
|
584
593
|
}>]>, "many">>;
|
|
585
594
|
purpose: z.ZodOptional<z.ZodString>;
|
|
595
|
+
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
586
596
|
image: z.ZodUnion<[z.ZodString, z.ZodType<Uint8Array<ArrayBuffer>, z.ZodTypeDef, Uint8Array<ArrayBuffer>>]>;
|
|
587
597
|
prompt: z.ZodString;
|
|
588
598
|
mimeType: z.ZodOptional<z.ZodString>;
|
|
@@ -602,6 +612,7 @@ declare const visionInputSchema: z.ZodObject<{
|
|
|
602
612
|
transport: "http" | "subprocess";
|
|
603
613
|
})[] | undefined;
|
|
604
614
|
purpose?: string | undefined;
|
|
615
|
+
labels?: Record<string, string> | undefined;
|
|
605
616
|
}, {
|
|
606
617
|
image: string | Uint8Array<ArrayBuffer>;
|
|
607
618
|
prompt: string;
|
|
@@ -618,6 +629,7 @@ declare const visionInputSchema: z.ZodObject<{
|
|
|
618
629
|
transport: "http" | "subprocess";
|
|
619
630
|
})[] | undefined;
|
|
620
631
|
purpose?: string | undefined;
|
|
632
|
+
labels?: Record<string, string> | undefined;
|
|
621
633
|
}>;
|
|
622
634
|
declare const translateInputSchema: z.ZodObject<{
|
|
623
635
|
tier: z.ZodOptional<z.ZodEnum<["fast", "smart", "powerful", "cheap", "vision", "embedding"]>>;
|
|
@@ -648,6 +660,7 @@ declare const translateInputSchema: z.ZodObject<{
|
|
|
648
660
|
transport: "http" | "subprocess";
|
|
649
661
|
}>]>, "many">>;
|
|
650
662
|
purpose: z.ZodOptional<z.ZodString>;
|
|
663
|
+
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
651
664
|
text: z.ZodString;
|
|
652
665
|
to: z.ZodString;
|
|
653
666
|
from: z.ZodOptional<z.ZodString>;
|
|
@@ -666,6 +679,7 @@ declare const translateInputSchema: z.ZodObject<{
|
|
|
666
679
|
transport: "http" | "subprocess";
|
|
667
680
|
})[] | undefined;
|
|
668
681
|
purpose?: string | undefined;
|
|
682
|
+
labels?: Record<string, string> | undefined;
|
|
669
683
|
from?: string | undefined;
|
|
670
684
|
}, {
|
|
671
685
|
text: string;
|
|
@@ -682,6 +696,7 @@ declare const translateInputSchema: z.ZodObject<{
|
|
|
682
696
|
transport: "http" | "subprocess";
|
|
683
697
|
})[] | undefined;
|
|
684
698
|
purpose?: string | undefined;
|
|
699
|
+
labels?: Record<string, string> | undefined;
|
|
685
700
|
from?: string | undefined;
|
|
686
701
|
}>;
|
|
687
702
|
declare const imageInputSchema: z.ZodObject<{
|
|
@@ -713,6 +728,7 @@ declare const imageInputSchema: z.ZodObject<{
|
|
|
713
728
|
transport: "http" | "subprocess";
|
|
714
729
|
}>]>, "many">>;
|
|
715
730
|
purpose: z.ZodOptional<z.ZodString>;
|
|
731
|
+
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
716
732
|
prompt: z.ZodString;
|
|
717
733
|
width: z.ZodOptional<z.ZodNumber>;
|
|
718
734
|
height: z.ZodOptional<z.ZodNumber>;
|
|
@@ -730,6 +746,7 @@ declare const imageInputSchema: z.ZodObject<{
|
|
|
730
746
|
transport: "http" | "subprocess";
|
|
731
747
|
})[] | undefined;
|
|
732
748
|
purpose?: string | undefined;
|
|
749
|
+
labels?: Record<string, string> | undefined;
|
|
733
750
|
width?: number | undefined;
|
|
734
751
|
height?: number | undefined;
|
|
735
752
|
}, {
|
|
@@ -746,6 +763,7 @@ declare const imageInputSchema: z.ZodObject<{
|
|
|
746
763
|
transport: "http" | "subprocess";
|
|
747
764
|
})[] | undefined;
|
|
748
765
|
purpose?: string | undefined;
|
|
766
|
+
labels?: Record<string, string> | undefined;
|
|
749
767
|
width?: number | undefined;
|
|
750
768
|
height?: number | undefined;
|
|
751
769
|
}>;
|
|
@@ -778,6 +796,7 @@ declare const embeddingInputSchema: z.ZodObject<{
|
|
|
778
796
|
transport: "http" | "subprocess";
|
|
779
797
|
}>]>, "many">>;
|
|
780
798
|
purpose: z.ZodOptional<z.ZodString>;
|
|
799
|
+
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
781
800
|
text: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
782
801
|
}, "strip", z.ZodTypeAny, {
|
|
783
802
|
text: string | string[];
|
|
@@ -793,6 +812,7 @@ declare const embeddingInputSchema: z.ZodObject<{
|
|
|
793
812
|
transport: "http" | "subprocess";
|
|
794
813
|
})[] | undefined;
|
|
795
814
|
purpose?: string | undefined;
|
|
815
|
+
labels?: Record<string, string> | undefined;
|
|
796
816
|
}, {
|
|
797
817
|
text: string | string[];
|
|
798
818
|
tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "embedding" | undefined;
|
|
@@ -807,6 +827,7 @@ declare const embeddingInputSchema: z.ZodObject<{
|
|
|
807
827
|
transport: "http" | "subprocess";
|
|
808
828
|
})[] | undefined;
|
|
809
829
|
purpose?: string | undefined;
|
|
830
|
+
labels?: Record<string, string> | undefined;
|
|
810
831
|
}>;
|
|
811
832
|
declare const transcribeInputSchema: z.ZodObject<{
|
|
812
833
|
tier: z.ZodOptional<z.ZodEnum<["fast", "smart", "powerful", "cheap", "vision", "embedding"]>>;
|
|
@@ -837,6 +858,7 @@ declare const transcribeInputSchema: z.ZodObject<{
|
|
|
837
858
|
transport: "http" | "subprocess";
|
|
838
859
|
}>]>, "many">>;
|
|
839
860
|
purpose: z.ZodOptional<z.ZodString>;
|
|
861
|
+
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
840
862
|
/** Audio URL or raw bytes. */
|
|
841
863
|
audio: z.ZodUnion<[z.ZodString, z.ZodType<Uint8Array<ArrayBuffer>, z.ZodTypeDef, Uint8Array<ArrayBuffer>>]>;
|
|
842
864
|
language: z.ZodOptional<z.ZodString>;
|
|
@@ -857,6 +879,7 @@ declare const transcribeInputSchema: z.ZodObject<{
|
|
|
857
879
|
transport: "http" | "subprocess";
|
|
858
880
|
})[] | undefined;
|
|
859
881
|
purpose?: string | undefined;
|
|
882
|
+
labels?: Record<string, string> | undefined;
|
|
860
883
|
durationSec?: number | undefined;
|
|
861
884
|
}, {
|
|
862
885
|
audio: string | Uint8Array<ArrayBuffer>;
|
|
@@ -873,6 +896,7 @@ declare const transcribeInputSchema: z.ZodObject<{
|
|
|
873
896
|
transport: "http" | "subprocess";
|
|
874
897
|
})[] | undefined;
|
|
875
898
|
purpose?: string | undefined;
|
|
899
|
+
labels?: Record<string, string> | undefined;
|
|
876
900
|
durationSec?: number | undefined;
|
|
877
901
|
}>;
|
|
878
902
|
declare const aiConfigSchema: z.ZodObject<{
|
|
@@ -1038,8 +1062,8 @@ declare const falStubAdapter: ProviderAdapter;
|
|
|
1038
1062
|
* wires the live adapters. */
|
|
1039
1063
|
declare const stubProviders: Record<string, ProviderAdapter>;
|
|
1040
1064
|
|
|
1041
|
-
declare const VERSION: "0.
|
|
1042
|
-
declare const SDK_TAG: "@broberg/ai-sdk@0.
|
|
1065
|
+
declare const VERSION: "0.4.1";
|
|
1066
|
+
declare const SDK_TAG: "@broberg/ai-sdk@0.4.1";
|
|
1043
1067
|
|
|
1044
1068
|
/** Built-in defaults. Every entry is overridable via AiConfig.defaults or a
|
|
1045
1069
|
* per-call override. Model IDs are current at scaffold time; callers pin their
|
package/dist/index.js
CHANGED
|
@@ -249,7 +249,11 @@ var PRICING = {
|
|
|
249
249
|
"google:gemini-2.5-flash": { inputPer1M: 0.3, outputPer1M: 2.5, version: V }
|
|
250
250
|
};
|
|
251
251
|
function getPrice(provider, model) {
|
|
252
|
-
|
|
252
|
+
const exact = PRICING[`${provider}:${model}`];
|
|
253
|
+
if (exact) return exact;
|
|
254
|
+
const base = model.replace(/-\d{8}$/, "");
|
|
255
|
+
if (base !== model) return PRICING[`${provider}:${base}`];
|
|
256
|
+
return void 0;
|
|
253
257
|
}
|
|
254
258
|
|
|
255
259
|
// src/cost/usage.ts
|
|
@@ -1262,7 +1266,10 @@ var callOptions = {
|
|
|
1262
1266
|
tier: tierSchema.optional(),
|
|
1263
1267
|
override: tierSpecSchema.partial().optional(),
|
|
1264
1268
|
fallback: z.array(z.union([tierSchema, tierSpecSchema])).optional(),
|
|
1265
|
-
purpose: z.string().optional()
|
|
1269
|
+
purpose: z.string().optional(),
|
|
1270
|
+
/** Consumer-defined attribution dimensions (e.g. {tenantId}) ridden into the
|
|
1271
|
+
* cost sink for per-tenant/per-customer cost breakdown (F011). */
|
|
1272
|
+
labels: z.record(z.string(), z.string()).optional()
|
|
1266
1273
|
};
|
|
1267
1274
|
var chatInputSchema = z.object({
|
|
1268
1275
|
prompt: z.string().optional(),
|
|
@@ -1345,10 +1352,11 @@ function createAI(config = {}) {
|
|
|
1345
1352
|
}
|
|
1346
1353
|
return adapter;
|
|
1347
1354
|
}
|
|
1348
|
-
function enrich(usage, capability, tier, purpose, latencyMs) {
|
|
1355
|
+
function enrich(usage, capability, tier, purpose, latencyMs, labels) {
|
|
1349
1356
|
usage.capability = capability;
|
|
1350
1357
|
if (tier) usage.tier = tier;
|
|
1351
1358
|
if (purpose) usage.purpose = purpose;
|
|
1359
|
+
if (labels && Object.keys(labels).length > 0) usage.labels = labels;
|
|
1352
1360
|
usage.latencyMs = Math.round(latencyMs);
|
|
1353
1361
|
if (!usage.ts) usage.ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
1354
1362
|
return usage;
|
|
@@ -1381,7 +1389,7 @@ function createAI(config = {}) {
|
|
|
1381
1389
|
try {
|
|
1382
1390
|
const t0 = performance.now();
|
|
1383
1391
|
const res = await opts.invoke(spec);
|
|
1384
|
-
enrich(res.usage, opts.capability, i === 0 ? opts.tier : void 0, opts.purpose, performance.now() - t0);
|
|
1392
|
+
enrich(res.usage, opts.capability, i === 0 ? opts.tier : void 0, opts.purpose, performance.now() - t0, opts.labels);
|
|
1385
1393
|
await settle(res.usage);
|
|
1386
1394
|
await report(res.usage);
|
|
1387
1395
|
return res;
|
|
@@ -1441,7 +1449,7 @@ function createAI(config = {}) {
|
|
|
1441
1449
|
})) {
|
|
1442
1450
|
if (ev.type === "text" || ev.type === "tool_call") emitted = true;
|
|
1443
1451
|
if (ev.type === "usage") {
|
|
1444
|
-
enrich(ev.usage, "chat", i === 0 ? tier : void 0, input.purpose, performance.now() - t0);
|
|
1452
|
+
enrich(ev.usage, "chat", i === 0 ? tier : void 0, input.purpose, performance.now() - t0, input.labels);
|
|
1445
1453
|
await settle(ev.usage);
|
|
1446
1454
|
await report(ev.usage);
|
|
1447
1455
|
}
|
|
@@ -1473,6 +1481,7 @@ function createAI(config = {}) {
|
|
|
1473
1481
|
capability: "chat",
|
|
1474
1482
|
tier,
|
|
1475
1483
|
purpose: input.purpose,
|
|
1484
|
+
labels: input.labels,
|
|
1476
1485
|
estIn,
|
|
1477
1486
|
estOut: input.maxTokens ?? 512,
|
|
1478
1487
|
invoke: async (spec) => {
|
|
@@ -1493,6 +1502,7 @@ function createAI(config = {}) {
|
|
|
1493
1502
|
capability: "vision",
|
|
1494
1503
|
tier,
|
|
1495
1504
|
purpose: input.purpose,
|
|
1505
|
+
labels: input.labels,
|
|
1496
1506
|
estIn: estTokens(input.prompt) + 1e3,
|
|
1497
1507
|
// prompt + ~1k image payload
|
|
1498
1508
|
estOut: 512,
|
|
@@ -1514,6 +1524,7 @@ function createAI(config = {}) {
|
|
|
1514
1524
|
capability: "translate",
|
|
1515
1525
|
tier,
|
|
1516
1526
|
purpose: input.purpose,
|
|
1527
|
+
labels: input.labels,
|
|
1517
1528
|
estIn,
|
|
1518
1529
|
estOut: estIn,
|
|
1519
1530
|
invoke: async (spec) => {
|
|
@@ -1531,6 +1542,7 @@ function createAI(config = {}) {
|
|
|
1531
1542
|
fallback: input.fallback,
|
|
1532
1543
|
capability: "image",
|
|
1533
1544
|
purpose: input.purpose,
|
|
1545
|
+
labels: input.labels,
|
|
1534
1546
|
estIn: 0,
|
|
1535
1547
|
// image cost is not token-based
|
|
1536
1548
|
estOut: 0,
|
|
@@ -1551,6 +1563,7 @@ function createAI(config = {}) {
|
|
|
1551
1563
|
capability: "embedding",
|
|
1552
1564
|
tier,
|
|
1553
1565
|
purpose: input.purpose,
|
|
1566
|
+
labels: input.labels,
|
|
1554
1567
|
estIn: text.reduce((n, t) => n + estTokens(t), 0),
|
|
1555
1568
|
estOut: 0,
|
|
1556
1569
|
invoke: async (spec) => {
|
|
@@ -1568,6 +1581,7 @@ function createAI(config = {}) {
|
|
|
1568
1581
|
fallback: input.fallback,
|
|
1569
1582
|
capability: "transcribe",
|
|
1570
1583
|
purpose: input.purpose,
|
|
1584
|
+
labels: input.labels,
|
|
1571
1585
|
estIn: 0,
|
|
1572
1586
|
estOut: 0,
|
|
1573
1587
|
invoke: async (spec) => {
|
|
@@ -1665,8 +1679,8 @@ var stubProviders = {
|
|
|
1665
1679
|
};
|
|
1666
1680
|
|
|
1667
1681
|
// src/version.ts
|
|
1668
|
-
var VERSION = "0.
|
|
1669
|
-
var SDK_TAG = "@broberg/ai-sdk@0.
|
|
1682
|
+
var VERSION = "0.4.1";
|
|
1683
|
+
var SDK_TAG = "@broberg/ai-sdk@0.4.1";
|
|
1670
1684
|
|
|
1671
1685
|
// src/cost/budget-store.ts
|
|
1672
1686
|
function sqliteBudgetStore(config) {
|
|
@@ -1740,6 +1754,10 @@ function upmetricsSink(config) {
|
|
|
1740
1754
|
started_at: startedAt,
|
|
1741
1755
|
ended_at: endedAt,
|
|
1742
1756
|
tags: {
|
|
1757
|
+
// Consumer attribution labels (e.g. tenantId) ride in tags so no new
|
|
1758
|
+
// top-level field risks the strict-shape ingest schema (F011). The
|
|
1759
|
+
// SDK-owned keys win — a label can never clobber capability/transport/sdk.
|
|
1760
|
+
...usage.labels,
|
|
1743
1761
|
capability: usage.capability,
|
|
1744
1762
|
transport: usage.transport,
|
|
1745
1763
|
sdk: SDK_TAG
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/routing/tier-map.ts","../src/transport/http.ts","../src/transport/subprocess.ts","../src/transport/stream.ts","../src/providers/tools.ts","../src/cost/pricing.ts","../src/cost/usage.ts","../src/providers/anthropic.ts","../src/providers/openai-compatible.ts","../src/providers/openai.ts","../src/providers/gemini.ts","../src/providers/deepinfra.ts","../src/providers/openrouter.ts","../src/providers/fal.ts","../src/providers/registry.ts","../src/cost/budget.ts","../src/capabilities/vision.ts","../src/capabilities/translate.ts","../src/capabilities/embedding.ts","../src/capabilities/transcribe.ts","../src/capabilities/contracts/index.ts","../src/schema/inputs.ts","../src/client.ts","../src/providers/stub.ts","../src/version.ts","../src/cost/budget-store.ts","../src/cost/sinks/noop.ts","../src/cost/sinks/multi.ts","../src/cost/sinks/upmetrics.ts","../src/cost/sinks/discord.ts","../src/cost/sinks/sqlite.ts"],"sourcesContent":["// Tier routing: a named Tier resolves to a concrete (provider, model, transport).\n// Precedence is per-call override > client config map > built-in defaults.\nimport type { Tier, TierSpec } from \"../types.js\";\n\n/** Built-in defaults. Every entry is overridable via AiConfig.defaults or a\n * per-call override. Model IDs are current at scaffold time; callers pin their\n * own via config. `cheap` routes through the local `claude -p` subprocess\n * (Max plan → costUsd 0); everything else is HTTP. */\nexport const DEFAULT_TIER_MAP: Record<Tier, TierSpec> = {\n fast: { provider: \"anthropic\", model: \"claude-haiku-4-5\", transport: \"http\" },\n smart: { provider: \"anthropic\", model: \"claude-sonnet-4-6\", transport: \"http\" },\n powerful: { provider: \"anthropic\", model: \"claude-opus-4-8\", transport: \"http\" },\n cheap: { provider: \"anthropic\", model: \"claude-haiku-4-5\", transport: \"subprocess\" },\n vision: { provider: \"anthropic\", model: \"claude-sonnet-4-6\", transport: \"http\" },\n embedding: { provider: \"openai\", model: \"text-embedding-3-small\", transport: \"http\" },\n};\n\n/**\n * Resolve a Tier to a concrete TierSpec.\n *\n * Merge order (later wins): DEFAULT_TIER_MAP < configMap < override.\n * - `configMap` is the client-level AiConfig.defaults (per-tier full specs).\n * - `override` is a per-call Partial<TierSpec> — only the fields it sets win.\n */\nexport function resolveTier(\n tier: Tier,\n override?: Partial<TierSpec>,\n configMap?: Partial<Record<Tier, TierSpec>>,\n): TierSpec {\n const base = configMap?.[tier] ?? DEFAULT_TIER_MAP[tier];\n return { ...base, ...override };\n}\n","// HTTP transport: a thin fetch wrapper. Provider-agnostic — the adapter supplies\n// the fully-built url/headers/body and parses the returned json itself.\nimport type { TransportRequest, HttpResponse } from \"./types.js\";\n\nexport async function httpTransport(req: TransportRequest): Promise<HttpResponse> {\n if (!req.http) {\n throw new Error(\"httpTransport: req.http is required for http transport\");\n }\n const { url, method = \"POST\", headers, body } = req.http;\n const res = await fetch(url, {\n method,\n headers,\n body:\n body === undefined\n ? undefined\n : typeof body === \"string\"\n ? body\n : JSON.stringify(body),\n });\n const json: unknown = await res.json().catch(() => undefined);\n return { ok: res.ok, status: res.status, json };\n}\n","// Subprocess transport: runs the local `claude -p` CLI (Anthropic Max plan).\n// No API key, no metered charge — costUsd is always 0, flagged subprocess:true so\n// dashboards can split free (Max) from paid (API). Token counts still come back\n// from the CLI's JSON so usage is tracked even when cost is zero.\nimport type { TransportRequest, SubprocessResponse } from \"./types.js\";\n\n/** The subset of `claude -p --output-format json` output we read. The CLI emits\n * more fields; we only need the result text + token usage. */\ninterface ClaudeCliJson {\n result?: string;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n}\n\n/** Pure parser for the `claude -p --output-format json` stdout. Exported so it\n * can be unit-tested without spawning the binary. costUsd is pinned to 0. */\nexport function parseClaudeCliJson(raw: string): SubprocessResponse {\n let parsed: ClaudeCliJson;\n try {\n parsed = JSON.parse(raw) as ClaudeCliJson;\n } catch {\n throw new Error(\n `subprocessTransport: could not parse claude -p JSON output: ${raw.slice(0, 200)}`,\n );\n }\n const u = parsed.usage ?? {};\n return {\n text: parsed.result ?? \"\",\n inputTokens: u.input_tokens ?? 0,\n outputTokens: u.output_tokens ?? 0,\n cacheReadTokens: u.cache_read_input_tokens ?? 0,\n cacheCreationTokens: u.cache_creation_input_tokens ?? 0,\n costUsd: 0,\n subprocess: true,\n };\n}\n\nexport async function subprocessTransport(\n req: TransportRequest,\n): Promise<SubprocessResponse> {\n if (!req.subprocess) {\n throw new Error(\"subprocessTransport: req.subprocess is required for subprocess transport\");\n }\n const { prompt, systemPrompt } = req.subprocess;\n\n const cmd = [\"claude\", \"-p\", \"--output-format\", \"json\", \"--model\", req.spec.model];\n if (systemPrompt) cmd.push(\"--system-prompt\", systemPrompt);\n\n // Prompt goes in on stdin as a Blob (no argv length limit, no manual FileSink).\n const proc = (() => {\n try {\n return Bun.spawn(cmd, {\n stdin: new Blob([prompt]),\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n } catch (err) {\n throw new Error(\n `subprocessTransport: failed to spawn 'claude' — is the CLI installed and on PATH? (${String(err)})`,\n );\n }\n })();\n\n const [stdout, stderr, exitCode] = await Promise.all([\n new Response(proc.stdout).text(),\n new Response(proc.stderr).text(),\n proc.exited,\n ]);\n\n if (exitCode !== 0) {\n throw new Error(\n `subprocessTransport: claude -p exited ${exitCode}: ${stderr.slice(0, 300) || stdout.slice(0, 300)}`,\n );\n }\n\n return parseClaudeCliJson(stdout);\n}\n","// SSE streaming transport (F8.1). Like httpTransport but yields the parsed\n// `data:` payloads from the response body instead of awaiting .json() — pure\n// fetch + a ReadableStream reader, so it is Node 18+ and Bun safe. The adapter\n// supplies the `stream:true` body and parses each yielded JSON string itself.\nimport type { TransportRequest } from \"./types.js\";\n\n/** HTTP error from a streaming connect — carries `status` so the client's\n * pre-stream fallback can tell an eligible 429/5xx from a hard 4xx. */\nexport class StreamHttpError extends Error {\n readonly status: number;\n constructor(message: string, status: number) {\n super(message);\n this.name = \"StreamHttpError\";\n this.status = status;\n }\n}\n\nexport interface StreamTransportRequest extends TransportRequest {\n /** Injectable fetch for tests. */\n fetch?: typeof fetch;\n}\n\n/**\n * Open an SSE stream and yield each event's `data:` payload as a raw string\n * (the JSON after `data: `), skipping the `[DONE]` terminator and non-data\n * lines. Throws StreamHttpError before the first yield on a non-2xx connect.\n */\nexport async function* streamTransport(req: StreamTransportRequest): AsyncIterable<string> {\n if (!req.http) throw new Error(\"streamTransport: req.http is required for http transport\");\n const { url, method = \"POST\", headers, body } = req.http;\n const fetchImpl = req.fetch ?? fetch;\n const res = await fetchImpl(url, {\n method,\n headers,\n body:\n body === undefined\n ? undefined\n : typeof body === \"string\"\n ? body\n : JSON.stringify(body),\n });\n if (!res.ok || !res.body) {\n const text = await res.text().catch(() => \"\");\n throw new StreamHttpError(`stream ${res.status}: ${text.slice(0, 300)}`, res.status);\n }\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n // OpenAI/Anthropic emit one `data: {json}\\n\\n` per event — parse per line.\n let nl: number;\n while ((nl = buffer.indexOf(\"\\n\")) >= 0) {\n const line = buffer.slice(0, nl).replace(/\\r$/, \"\");\n buffer = buffer.slice(nl + 1);\n if (!line.startsWith(\"data:\")) continue; // skip comments / event: / id:\n const data = line.slice(5).trim();\n if (data === \"[DONE]\") return;\n if (data) yield data;\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n","// Cross-provider tool/function-calling normalization. The SDK speaks one Tool /\n// ToolCall shape; each provider has its own. toProviderTools builds the request\n// tools array; fromProviderToolCall parses one tool-call out of a response.\n// OpenAI, DeepInfra and OpenRouter share the OpenAI-compatible format.\nimport type { Tool, ToolCall } from \"../types.js\";\n\ntype ToolProvider = \"openai\" | \"deepinfra\" | \"openrouter\" | \"gemini\" | \"anthropic\";\n\nfunction family(provider: string): ToolProvider {\n if (provider === \"gemini\" || provider === \"google\") return \"gemini\";\n if (provider === \"anthropic\") return \"anthropic\";\n // openai, deepinfra, openrouter — all OpenAI-compatible\n return \"openai\";\n}\n\n/** Convert SDK tools to a provider's request format. */\nexport function toProviderTools(tools: Tool[], provider: string): unknown {\n switch (family(provider)) {\n case \"openai\":\n return tools.map((t) => ({\n type: \"function\",\n function: { name: t.name, description: t.description, parameters: t.parameters },\n }));\n case \"gemini\":\n return [\n {\n functionDeclarations: tools.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n },\n ];\n case \"anthropic\":\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.parameters,\n }));\n default:\n throw new Error(`toProviderTools: unsupported provider family for \"${provider}\"`);\n }\n}\n\n/** Parse a single provider-shaped tool call back into the SDK ToolCall shape. */\nexport function fromProviderToolCall(raw: unknown, provider: string): ToolCall {\n const r = raw as Record<string, unknown>;\n switch (family(provider)) {\n case \"openai\": {\n // { id, type:\"function\", function:{ name, arguments:\"<json>\" } }\n const fn = (r.function ?? {}) as { name?: string; arguments?: string };\n return {\n id: typeof r.id === \"string\" ? r.id : \"\",\n name: fn.name ?? \"\",\n arguments: parseArgs(fn.arguments),\n };\n }\n case \"gemini\": {\n // { functionCall:{ name, args } } or { name, args }\n const fc = (r.functionCall ?? r) as { name?: string; args?: unknown };\n return {\n id: \"\", // Gemini function calls have no id\n name: fc.name ?? \"\",\n arguments: (fc.args as Record<string, unknown>) ?? {},\n };\n }\n case \"anthropic\": {\n // { type:\"tool_use\", id, name, input }\n return {\n id: typeof r.id === \"string\" ? r.id : \"\",\n name: typeof r.name === \"string\" ? r.name : \"\",\n arguments: (r.input as Record<string, unknown>) ?? {},\n };\n }\n default:\n throw new Error(`fromProviderToolCall: unsupported provider family for \"${provider}\"`);\n }\n}\n\nfunction parseArgs(raw: unknown): Record<string, unknown> {\n if (raw === undefined || raw === null) return {};\n if (typeof raw === \"object\") return raw as Record<string, unknown>;\n if (typeof raw === \"string\") {\n try {\n return JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return {};\n }\n }\n return {};\n}\n","// Versioned per-(provider, model) pricing. F3.6 populates the table + adds tests\n// + MiniMax coverage. F3.1 ships the type + lookup with an empty table, so\n// computeCost returns 0 for every model until F3.6 lands (calls still complete).\nexport interface PricingEntry {\n /** USD per 1M input tokens. */\n inputPer1M: number;\n /** USD per 1M output tokens. */\n outputPer1M: number;\n /** USD per 1M cache-read tokens (falls back to input rate if unset). */\n cacheReadPer1M?: number;\n /** USD per 1M cache-write/creation tokens (falls back to input rate if unset). */\n cacheWritePer1M?: number;\n /** Pricing snapshot version (date or tag) so stale entries are detectable. */\n version: string;\n}\n\n// USD per 1M tokens. Anthropic cache multipliers follow the standard model:\n// cache-read ≈ 0.1× input, cache-write ≈ 1.25× input. Verified against the\n// pricing tables in cms (packages/cms-ai/src/providers) + trail (model-lab).\n// MiniMax M2.7 is an estimate pending confirmation against OpenRouter's live\n// price page — flagged in its version string.\nconst V = \"2026-06-02\";\n\n/** Keyed `${provider}:${model}`. */\nconst PRICING: Record<string, PricingEntry> = {\n // Anthropic (direct API). DEFAULT_TIER_MAP: fast/cheap=haiku, smart/vision=sonnet, powerful=opus.\n \"anthropic:claude-haiku-4-5\": {\n inputPer1M: 0.8,\n outputPer1M: 4.0,\n cacheReadPer1M: 0.08,\n cacheWritePer1M: 1.0,\n version: V,\n },\n \"anthropic:claude-sonnet-4-6\": {\n inputPer1M: 3.0,\n outputPer1M: 15.0,\n cacheReadPer1M: 0.3,\n cacheWritePer1M: 3.75,\n version: V,\n },\n \"anthropic:claude-opus-4-8\": {\n inputPer1M: 15.0,\n outputPer1M: 75.0,\n cacheReadPer1M: 1.5,\n cacheWritePer1M: 18.75,\n version: V,\n },\n\n // OpenAI. embedding default tier = text-embedding-3-small (no output tokens).\n \"openai:text-embedding-3-small\": { inputPer1M: 0.02, outputPer1M: 0, version: V },\n \"openai:text-embedding-3-large\": { inputPer1M: 0.13, outputPer1M: 0, version: V },\n \"openai:gpt-4o\": { inputPer1M: 2.5, outputPer1M: 10.0, version: V },\n \"openai:gpt-4o-mini\": { inputPer1M: 0.15, outputPer1M: 0.6, version: V },\n // Whisper is priced per minute, not per token — not representable here; transcribe\n // (F5.6) computes its own cost. Listed as 0 so token-based compute never charges it.\n \"openai:whisper-1\": { inputPer1M: 0, outputPer1M: 0, version: V },\n\n // OpenRouter (meta-router — model slugs include the upstream vendor).\n \"openrouter:anthropic/claude-sonnet-4-6\": { inputPer1M: 3.0, outputPer1M: 15.0, version: V },\n \"openrouter:anthropic/claude-haiku-4-5\": { inputPer1M: 0.8, outputPer1M: 4.0, version: V },\n \"openrouter:google/gemini-2.5-flash\": { inputPer1M: 0.3, outputPer1M: 2.5, version: V },\n \"openrouter:minimax/minimax-m2.7\": {\n inputPer1M: 0.3,\n outputPer1M: 1.2,\n version: `${V}-estimate`,\n },\n\n // Google Gemini (direct). Image-gen model used by cms.\n \"google:gemini-2.5-flash\": { inputPer1M: 0.3, outputPer1M: 2.5, version: V },\n};\n\nexport function getPrice(provider: string, model: string): PricingEntry | undefined {\n return PRICING[`${provider}:${model}`];\n}\n","// Usage construction + cost computation. Real adapters (F4) build their Usage via\n// freshUsage() and fill costUsd from computeCost(). The pricing table lives in\n// ./pricing.ts (F3.6); until a model is priced, computeCost returns 0 so calls\n// still complete (cost just shows $0 rather than throwing).\nimport { getPrice } from \"./pricing.js\";\nimport type { Usage, Transport, Capability } from \"../types.js\";\n\n/**\n * Cost in USD for a call. cache-read/creation tokens are priced separately when\n * the pricing entry defines rates for them; otherwise they fall back to the\n * input rate (read) / are ignored (creation). Unknown model → 0.\n */\nexport function computeCost(\n provider: string,\n model: string,\n inputTokens: number,\n outputTokens: number,\n cacheReadTokens = 0,\n cacheCreationTokens = 0,\n): number {\n const price = getPrice(provider, model);\n if (!price) return 0;\n const perToken = (per1M: number) => per1M / 1_000_000;\n const inRate = perToken(price.inputPer1M);\n const outRate = perToken(price.outputPer1M);\n const cacheReadRate =\n price.cacheReadPer1M !== undefined ? perToken(price.cacheReadPer1M) : inRate;\n const cacheWriteRate =\n price.cacheWritePer1M !== undefined ? perToken(price.cacheWritePer1M) : inRate;\n return (\n inputTokens * inRate +\n outputTokens * outRate +\n cacheReadTokens * cacheReadRate +\n cacheCreationTokens * cacheWriteRate\n );\n}\n\n/** Build a Usage with cost computed from the pricing table. Adapters call this\n * after a successful provider call; latencyMs/ts/capability are stamped by the\n * client (call-context owner), so they default to 0/\"\"/the passed capability. */\nexport function freshUsage(args: {\n provider: string;\n model: string;\n transport: Transport;\n capability: Capability;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheCreationTokens?: number;\n subprocess?: boolean;\n}): Usage {\n const cacheReadTokens = args.cacheReadTokens ?? 0;\n const cacheCreationTokens = args.cacheCreationTokens ?? 0;\n // Subprocess (Max plan) is never a metered charge to us — cost is always 0.\n const costUsd = args.subprocess\n ? 0\n : computeCost(\n args.provider,\n args.model,\n args.inputTokens,\n args.outputTokens,\n cacheReadTokens,\n cacheCreationTokens,\n );\n const usage: Usage = {\n provider: args.provider,\n model: args.model,\n transport: args.transport,\n inputTokens: args.inputTokens,\n outputTokens: args.outputTokens,\n cacheReadTokens,\n cacheCreationTokens,\n costUsd,\n latencyMs: 0,\n capability: args.capability,\n ts: \"\",\n };\n if (args.subprocess) usage.subprocess = true;\n return usage;\n}\n","// Anthropic adapter (F4.6) — the real one (F2.5 shipped only a stub). Two\n// transports: http (api.anthropic.com/v1/messages) and subprocess (claude -p,\n// Max plan, costUsd 0). Critical for the xrt81 vision pilot. Tools normalized\n// via F4.5. No @anthropic-ai/sdk package — plain fetch through httpTransport.\nimport { httpTransport } from \"../transport/http.js\";\nimport { subprocessTransport } from \"../transport/subprocess.js\";\nimport { streamTransport } from \"../transport/stream.js\";\nimport { toProviderTools, fromProviderToolCall } from \"./tools.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ChatStreamEvent,\n Message,\n ContentPart,\n ToolCall,\n} from \"../types.js\";\n\ninterface AnthropicBlock {\n type: string;\n text?: string;\n id?: string;\n name?: string;\n input?: Record<string, unknown>;\n}\ninterface AnthropicResponse {\n content?: AnthropicBlock[];\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n error?: unknown;\n}\n\nfunction contentBlocks(content: string | ContentPart[]): unknown {\n if (typeof content === \"string\") return content;\n return content.map((p) => {\n if (p.type === \"text\") return { type: \"text\", text: p.text };\n if (typeof p.image === \"string\" && /^https?:\\/\\//.test(p.image)) {\n return { type: \"image\", source: { type: \"url\", url: p.image } };\n }\n const data =\n typeof p.image === \"string\"\n ? p.image.replace(/^data:[^;]+;base64,/, \"\")\n : Buffer.from(p.image).toString(\"base64\");\n return {\n type: \"image\",\n source: { type: \"base64\", media_type: p.mimeType ?? \"image/png\", data },\n };\n });\n}\n\n/** Flatten messages to a single prompt for the subprocess (claude -p) path. */\nfunction flattenForSubprocess(messages: Message[]): { prompt: string; system?: string } {\n const sys: string[] = [];\n const turns: string[] = [];\n for (const m of messages) {\n const text =\n typeof m.content === \"string\"\n ? m.content\n : m.content.map((p) => (p.type === \"text\" ? p.text : \"[image]\")).join(\" \");\n if (m.role === \"system\") sys.push(text);\n else turns.push(`${m.role}: ${text}`);\n }\n return { prompt: turns.join(\"\\n\\n\"), system: sys.length ? sys.join(\"\\n\") : undefined };\n}\n\nexport function anthropicAdapter(\n config: { apiKey?: string; baseUrl?: string; anthropicVersion?: string; fetch?: typeof fetch } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://api.anthropic.com\";\n const version = config.anthropicVersion ?? \"2023-06-01\";\n\n /** Build the /v1/messages body (shared by the http + stream paths). */\n function buildBody(req: ChatRequest): Record<string, unknown> {\n const system: string[] = [];\n const messages: { role: string; content: unknown }[] = [];\n for (const m of req.messages as Message[]) {\n if (m.role === \"system\") {\n system.push(typeof m.content === \"string\" ? m.content : \"\");\n continue;\n }\n // tool-result turn → a user message carrying a tool_result block (F8.7).\n if (m.role === \"tool\") {\n messages.push({\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n tool_use_id: m.toolCallId ?? \"\",\n content: typeof m.content === \"string\" ? m.content : \"\",\n },\n ],\n });\n continue;\n }\n // assistant turn that called tools → text blocks + tool_use blocks (F8.7).\n if (m.role === \"assistant\" && m.toolCalls && m.toolCalls.length > 0) {\n const blocks: unknown[] = [];\n if (typeof m.content === \"string\") {\n if (m.content.length > 0) blocks.push({ type: \"text\", text: m.content });\n } else {\n blocks.push(...(contentBlocks(m.content) as unknown[]));\n }\n for (const tc of m.toolCalls) {\n blocks.push({ type: \"tool_use\", id: tc.id, name: tc.name, input: tc.arguments });\n }\n messages.push({ role: \"assistant\", content: blocks });\n continue;\n }\n messages.push({ role: m.role === \"assistant\" ? \"assistant\" : \"user\", content: contentBlocks(m.content) });\n }\n const body: Record<string, unknown> = {\n model: req.spec.model,\n max_tokens: req.maxTokens ?? 1024, // Anthropic requires max_tokens\n messages,\n };\n if (system.length > 0) body.system = system.join(\"\\n\");\n if (req.tools) body.tools = toProviderTools(req.tools, \"anthropic\");\n if (req.temperature !== undefined) body.temperature = req.temperature;\n return body;\n }\n\n function apiKeyOrThrow(): string {\n const apiKey = config.apiKey ?? process.env.ANTHROPIC_API_KEY;\n if (!apiKey) throw new Error(\"anthropic adapter: API key not set (env ANTHROPIC_API_KEY)\");\n return apiKey;\n }\n\n async function chatHttp(req: ChatRequest): Promise<ChatResult> {\n const apiKey = apiKeyOrThrow();\n const body = buildBody(req);\n\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${baseUrl}/v1/messages`,\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": version,\n },\n body,\n },\n });\n if (!res.ok) throw new Error(`anthropic ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n\n const data = res.json as AnthropicResponse;\n const blocks = data.content ?? [];\n const text = blocks\n .filter((b) => b.type === \"text\" && typeof b.text === \"string\")\n .map((b) => b.text)\n .join(\"\");\n const toolCalls: ToolCall[] = blocks\n .filter((b) => b.type === \"tool_use\")\n .map((b) => fromProviderToolCall(b, \"anthropic\"));\n\n const usage = freshUsage({\n provider: \"anthropic\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: data.usage?.input_tokens ?? 0,\n outputTokens: data.usage?.output_tokens ?? 0,\n cacheReadTokens: data.usage?.cache_read_input_tokens ?? 0,\n cacheCreationTokens: data.usage?.cache_creation_input_tokens ?? 0,\n });\n const result: ChatResult = { text, usage };\n if (toolCalls.length > 0) result.toolCalls = toolCalls;\n return result;\n }\n\n async function chatSubprocess(req: ChatRequest): Promise<ChatResult> {\n const { prompt, system } = flattenForSubprocess(req.messages as Message[]);\n const r = await subprocessTransport({ spec: req.spec, subprocess: { prompt, systemPrompt: system } });\n const usage = freshUsage({\n provider: \"anthropic\",\n model: req.spec.model,\n transport: \"subprocess\",\n capability: \"chat\",\n inputTokens: r.inputTokens,\n outputTokens: r.outputTokens,\n cacheReadTokens: r.cacheReadTokens,\n cacheCreationTokens: r.cacheCreationTokens,\n subprocess: true,\n });\n return { text: r.text, usage };\n }\n\n async function chat(req: ChatRequest): Promise<ChatResult> {\n return req.spec.transport === \"subprocess\" ? chatSubprocess(req) : chatHttp(req);\n }\n\n // Streaming chat (F8.4) over the native /v1/messages SSE. Maps\n // content_block_delta(text_delta) → text events, accumulates tool_use blocks\n // (id/name from content_block_start, input from input_json_delta) → complete\n // tool_call events, and reads usage from message_start + message_delta. Only\n // the http transport streams — `claude -p` subprocess is one-shot.\n async function* chatStream(req: ChatRequest): AsyncIterable<ChatStreamEvent> {\n if (req.spec.transport === \"subprocess\") {\n throw new Error(\"anthropic adapter: streaming is not supported over the subprocess transport\");\n }\n const apiKey = apiKeyOrThrow();\n const body = { ...buildBody(req), stream: true };\n const stream = streamTransport({\n spec: req.spec,\n fetch: config.fetch,\n http: {\n url: `${baseUrl}/v1/messages`,\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": version,\n },\n body,\n },\n });\n\n let inputTokens = 0;\n let outputTokens = 0;\n let cacheReadTokens = 0;\n let cacheCreationTokens = 0;\n let stopReason: string | null = null;\n // index → accumulated tool_use block (input_json_delta fragments concatenated).\n const toolBlocks = new Map<number, { id: string; name: string; json: string }>();\n\n for await (const data of stream) {\n let ev: AnthropicStreamEvent;\n try {\n ev = JSON.parse(data) as AnthropicStreamEvent;\n } catch {\n continue;\n }\n switch (ev.type) {\n case \"message_start\": {\n const u = ev.message?.usage;\n inputTokens = u?.input_tokens ?? 0;\n cacheReadTokens = u?.cache_read_input_tokens ?? 0;\n cacheCreationTokens = u?.cache_creation_input_tokens ?? 0;\n break;\n }\n case \"content_block_start\": {\n if (ev.content_block?.type === \"tool_use\" && ev.index !== undefined) {\n toolBlocks.set(ev.index, {\n id: ev.content_block.id ?? \"\",\n name: ev.content_block.name ?? \"\",\n json: \"\",\n });\n }\n break;\n }\n case \"content_block_delta\": {\n const d = ev.delta;\n if (d?.type === \"text_delta\" && d.text) {\n yield { type: \"text\", delta: d.text };\n } else if (d?.type === \"input_json_delta\" && d.partial_json && ev.index !== undefined) {\n const b = toolBlocks.get(ev.index);\n if (b) b.json += d.partial_json;\n }\n break;\n }\n case \"message_delta\": {\n if (ev.delta?.stop_reason) stopReason = ev.delta.stop_reason;\n if (ev.usage?.output_tokens !== undefined) outputTokens = ev.usage.output_tokens;\n break;\n }\n default:\n break; // content_block_stop / message_stop / ping\n }\n }\n\n for (const [, b] of [...toolBlocks.entries()].sort((a, c) => a[0] - c[0])) {\n let args: Record<string, unknown> = {};\n try {\n args = b.json ? (JSON.parse(b.json) as Record<string, unknown>) : {};\n } catch {\n args = {};\n }\n yield { type: \"tool_call\", id: b.id, name: b.name, args };\n }\n const usage = freshUsage({\n provider: \"anthropic\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens,\n outputTokens,\n cacheReadTokens,\n cacheCreationTokens,\n });\n yield { type: \"usage\", costUsd: usage.costUsd, model: usage.model, usage };\n yield { type: \"finish\", reason: mapAnthropicStop(stopReason) };\n }\n\n return { name: \"anthropic\", chat, chatStream, vision: chat };\n}\n\n/** Anthropic Messages SSE event (only the fields we read). */\ninterface AnthropicStreamEvent {\n type: string;\n index?: number;\n message?: {\n usage?: {\n input_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n };\n content_block?: { type?: string; id?: string; name?: string };\n delta?: { type?: string; text?: string; partial_json?: string; stop_reason?: string };\n usage?: { output_tokens?: number };\n}\n\n/** Map Anthropic stop_reason → the SDK's ChatStreamEvent finish reason. */\nfunction mapAnthropicStop(reason: string | null): \"end_turn\" | \"tool_calls\" | \"length\" | \"stop\" {\n switch (reason) {\n case \"tool_use\":\n return \"tool_calls\";\n case \"max_tokens\":\n return \"length\";\n case \"stop_sequence\":\n return \"stop\";\n default:\n return \"end_turn\";\n }\n}\n","// Shared core for OpenAI-compatible chat APIs. OpenAI (F4.1), DeepInfra (F4.3)\n// and OpenRouter (F4.4) all speak this wire format — only base URL, key and a\n// couple of headers differ. The adapter uses httpTransport (F2.4) for the wire\n// I/O and the F4.5 tool contract for tool round-tripping.\nimport { httpTransport } from \"../transport/http.js\";\nimport { streamTransport } from \"../transport/stream.js\";\nimport { toProviderTools, fromProviderToolCall } from \"./tools.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ChatStreamEvent,\n Message,\n ToolCall,\n} from \"../types.js\";\n\nexport interface OpenAICompatibleConfig {\n /** Provider name recorded on Usage (e.g. \"openai\", \"deepinfra\", \"openrouter\"). */\n name: string;\n /** Chat completions base, e.g. \"https://api.openai.com/v1\". */\n baseUrl: string;\n /** Resolved at call time if omitted (env var per provider). */\n apiKey?: string;\n /** Extra headers (e.g. OpenRouter's HTTP-Referer / X-Title). */\n extraHeaders?: Record<string, string>;\n /** Injectable fetch for the streaming path (tests). */\n fetch?: typeof fetch;\n /** OpenRouter ground-truth cost (F010): send `usage:{include:true}` and use the\n * response's `usage.cost` (USD) as costUsd, falling back to the pricing table.\n * Only OpenRouter returns this field — openai/deepinfra leave it false. */\n costFromResponseField?: boolean;\n}\n\ninterface OAToolCall {\n id?: string;\n function?: { name?: string; arguments?: string };\n}\ninterface OAResponse {\n choices?: { message?: { content?: string | null; tool_calls?: OAToolCall[] } }[];\n usage?: { prompt_tokens?: number; completion_tokens?: number; cost?: number };\n error?: unknown;\n}\n\n/** SDK message → OpenAI message (string content, or multimodal parts for vision).\n * Threads the normalized tool form to the wire: a `tool`-role message's\n * `toolCallId` → `tool_call_id`, and an assistant message's `toolCalls` →\n * `tool_calls:[{id,type:'function',function:{name,arguments}}]` (F8.3) so a\n * multi-turn tool conversation round-trips. Exported for serialization tests. */\nexport function toOpenAIMessage(m: Message): Record<string, unknown> {\n if (typeof m.content === \"string\") {\n const base: Record<string, unknown> = { role: m.role, content: m.content };\n if (m.toolCallId) base.tool_call_id = m.toolCallId;\n if (m.toolCalls && m.toolCalls.length > 0) {\n base.tool_calls = m.toolCalls.map((tc) => ({\n id: tc.id,\n type: \"function\",\n function: { name: tc.name, arguments: JSON.stringify(tc.arguments) },\n }));\n }\n return base;\n }\n const content = m.content.map((p) => {\n if (p.type === \"text\") return { type: \"text\", text: p.text };\n const url =\n typeof p.image === \"string\"\n ? p.image\n : `data:${p.mimeType ?? \"image/png\"};base64,${Buffer.from(p.image).toString(\"base64\")}`;\n return { type: \"image_url\", image_url: { url } };\n });\n return { role: m.role, content };\n}\n\nexport function makeOpenAICompatibleAdapter(config: OpenAICompatibleConfig): ProviderAdapter {\n async function chat(req: ChatRequest): Promise<ChatResult> {\n const apiKey = config.apiKey ?? process.env[`${config.name.toUpperCase()}_API_KEY`];\n if (!apiKey) {\n throw new Error(`${config.name} adapter: API key not set (env ${config.name.toUpperCase()}_API_KEY)`);\n }\n const body: Record<string, unknown> = {\n model: req.spec.model,\n messages: req.messages.map(toOpenAIMessage),\n };\n if (req.tools) body.tools = toProviderTools(req.tools, \"openai\");\n if (req.maxTokens !== undefined) body.max_tokens = req.maxTokens;\n if (req.temperature !== undefined) body.temperature = req.temperature;\n if (req.responseFormat === \"json\") body.response_format = { type: \"json_object\" };\n if (config.costFromResponseField) body.usage = { include: true };\n\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${config.baseUrl}/chat/completions`,\n headers: {\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n ...config.extraHeaders,\n },\n body,\n },\n });\n if (!res.ok) {\n throw new Error(`${config.name} ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n }\n const data = res.json as OAResponse;\n const msg = data.choices?.[0]?.message;\n const text = msg?.content ?? \"\";\n const toolCalls: ToolCall[] | undefined = msg?.tool_calls?.map((tc) =>\n fromProviderToolCall(tc, \"openai\"),\n );\n const usage = freshUsage({\n provider: config.name,\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: data.usage?.prompt_tokens ?? 0,\n outputTokens: data.usage?.completion_tokens ?? 0,\n });\n if (config.costFromResponseField && typeof data.usage?.cost === \"number\") {\n usage.costUsd = data.usage.cost; // OpenRouter ground-truth beats the estimate\n }\n const result: ChatResult = { text, usage };\n if (toolCalls && toolCalls.length > 0) result.toolCalls = toolCalls;\n return result;\n }\n\n // Streaming chat (F8.2). Parses the OpenAI chat.completions SSE: content\n // deltas → text events, tool_calls deltas accumulated (index-keyed, arguments\n // string concatenated) → complete tool_call events at end, the include_usage\n // chunk → a usage event, finish_reason → the terminal finish (emitted last so\n // tool_calls + usage precede it).\n async function* chatStream(req: ChatRequest): AsyncIterable<ChatStreamEvent> {\n const apiKey = config.apiKey ?? process.env[`${config.name.toUpperCase()}_API_KEY`];\n if (!apiKey) {\n throw new Error(`${config.name} adapter: API key not set (env ${config.name.toUpperCase()}_API_KEY)`);\n }\n const body: Record<string, unknown> = {\n model: req.spec.model,\n messages: req.messages.map(toOpenAIMessage),\n stream: true,\n stream_options: { include_usage: true },\n };\n if (req.tools) body.tools = toProviderTools(req.tools, \"openai\");\n if (req.maxTokens !== undefined) body.max_tokens = req.maxTokens;\n if (req.temperature !== undefined) body.temperature = req.temperature;\n if (req.responseFormat === \"json\") body.response_format = { type: \"json_object\" };\n if (config.costFromResponseField) body.usage = { include: true };\n\n const stream = streamTransport({\n spec: req.spec,\n fetch: config.fetch,\n http: {\n url: `${config.baseUrl}/chat/completions`,\n headers: {\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n ...config.extraHeaders,\n },\n body,\n },\n });\n\n // index → accumulated tool call (id/name set once, arguments concatenated).\n const toolAcc = new Map<number, { id: string; name: string; args: string }>();\n let finishReason: string | null = null;\n\n for await (const data of stream) {\n let chunk: OAStreamChunk;\n try {\n chunk = JSON.parse(data) as OAStreamChunk;\n } catch {\n continue; // ignore unparseable keep-alive noise\n }\n const choice = chunk.choices?.[0];\n if (choice) {\n const delta = choice.delta ?? {};\n if (typeof delta.content === \"string\" && delta.content.length > 0) {\n yield { type: \"text\", delta: delta.content };\n }\n for (const tc of delta.tool_calls ?? []) {\n const idx = tc.index ?? 0;\n const cur = toolAcc.get(idx) ?? { id: \"\", name: \"\", args: \"\" };\n if (tc.id) cur.id = tc.id;\n if (tc.function?.name) cur.name = tc.function.name;\n if (tc.function?.arguments) cur.args += tc.function.arguments;\n toolAcc.set(idx, cur);\n }\n if (choice.finish_reason) finishReason = choice.finish_reason;\n }\n if (chunk.usage) {\n const usage = freshUsage({\n provider: config.name,\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: chunk.usage.prompt_tokens ?? 0,\n outputTokens: chunk.usage.completion_tokens ?? 0,\n });\n if (config.costFromResponseField && typeof chunk.usage.cost === \"number\") {\n usage.costUsd = chunk.usage.cost; // OpenRouter ground-truth\n }\n yield { type: \"usage\", costUsd: usage.costUsd, model: usage.model, usage };\n }\n }\n\n // Flush accumulated tool calls (complete), then the terminal finish.\n for (const [, t] of [...toolAcc.entries()].sort((a, b) => a[0] - b[0])) {\n let args: Record<string, unknown> = {};\n try {\n args = t.args ? (JSON.parse(t.args) as Record<string, unknown>) : {};\n } catch {\n args = {};\n }\n yield { type: \"tool_call\", id: t.id, name: t.name, args };\n }\n yield { type: \"finish\", reason: mapFinishReason(finishReason) };\n }\n\n return {\n name: config.name,\n chat,\n chatStream,\n // gpt-4o-class models are multimodal — vision shares the chat path.\n vision: chat,\n };\n}\n\n/** OpenAI streaming chunk shape (only the fields we read). */\ninterface OAStreamChunk {\n choices?: {\n delta?: {\n content?: string | null;\n tool_calls?: { index?: number; id?: string; function?: { name?: string; arguments?: string } }[];\n };\n finish_reason?: string | null;\n }[];\n usage?: { prompt_tokens?: number; completion_tokens?: number; cost?: number };\n}\n\n/** Map OpenAI finish_reason → the SDK's ChatStreamEvent finish reason. */\nfunction mapFinishReason(reason: string | null): \"end_turn\" | \"tool_calls\" | \"length\" | \"stop\" {\n switch (reason) {\n case \"tool_calls\":\n return \"tool_calls\";\n case \"length\":\n return \"length\";\n case \"stop\":\n return \"stop\";\n default:\n return \"end_turn\";\n }\n}\n","// OpenAI adapter (F4.1 chat/vision + F5.4 embedding). Chat/vision come from the\n// shared OpenAI-compatible core; embedding uses the /embeddings endpoint. No\n// openai npm package — plain fetch through httpTransport.\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport { httpTransport } from \"../transport/http.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n EmbeddingRequest,\n EmbeddingResult,\n TranscribeRequest,\n TranscribeResult,\n} from \"../types.js\";\n\n/** Whisper-family per-minute USD prices (audio is not token-priced). */\nconst WHISPER_PRICE_PER_MIN: Record<string, number> = {\n \"whisper-1\": 0.006,\n};\n\nexport function openaiAdapter(\n config: { apiKey?: string; baseUrl?: string; fetch?: typeof fetch } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://api.openai.com/v1\";\n const base = makeOpenAICompatibleAdapter({ name: \"openai\", baseUrl, apiKey: config.apiKey });\n\n async function embedding(req: EmbeddingRequest): Promise<EmbeddingResult> {\n const apiKey = config.apiKey ?? process.env.OPENAI_API_KEY;\n if (!apiKey) throw new Error(\"openai adapter: API key not set (env OPENAI_API_KEY)\");\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${baseUrl}/embeddings`,\n headers: { \"content-type\": \"application/json\", Authorization: `Bearer ${apiKey}` },\n body: { model: req.spec.model, input: req.input },\n },\n });\n if (!res.ok) {\n throw new Error(`openai ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n }\n const data = res.json as {\n data?: { embedding: number[] }[];\n usage?: { prompt_tokens?: number };\n };\n const vectors = (data.data ?? []).map((d) => d.embedding);\n const usage = freshUsage({\n provider: \"openai\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"embedding\",\n inputTokens: data.usage?.prompt_tokens ?? 0,\n outputTokens: 0,\n });\n return { vectors, usage };\n }\n\n async function transcribe(req: TranscribeRequest): Promise<TranscribeResult> {\n const apiKey = config.apiKey ?? process.env.OPENAI_API_KEY;\n if (!apiKey) throw new Error(\"openai adapter: API key not set (env OPENAI_API_KEY)\");\n // Whisper is multipart/form-data — bypass httpTransport (JSON-only). Don't set\n // content-type; fetch adds the multipart boundary.\n const form = new FormData();\n form.append(\"file\", new Blob([req.audio]), \"audio\");\n form.append(\"model\", req.spec.model);\n if (req.language) form.append(\"language\", req.language);\n const fetchImpl = config.fetch ?? fetch;\n const res = await fetchImpl(`${baseUrl}/audio/transcriptions`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${apiKey}` },\n body: form,\n });\n if (!res.ok) {\n throw new Error(`openai ${res.status}: ${(await res.text().catch(() => \"\")).slice(0, 200)}`);\n }\n const data = (await res.json()) as { text?: string };\n const usage = freshUsage({\n provider: \"openai\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"transcribe\",\n inputTokens: 0,\n outputTokens: 0, // Whisper is per-minute, not token-priced.\n });\n // Per-minute cost when the caller supplies the audio duration (API returns none).\n if (req.durationSec !== undefined) {\n const perMinute = WHISPER_PRICE_PER_MIN[req.spec.model] ?? 0;\n usage.costUsd = (req.durationSec / 60) * perMinute;\n }\n return { text: data.text ?? \"\", usage };\n }\n\n return { ...base, embedding, transcribe };\n}\n","// Google Gemini adapter (F4.2). generateContent REST API; API key in the query\n// param (?key=), not a header. System turns map to systemInstruction; assistant\n// maps to role \"model\". Token counts come from usageMetadata. Tools normalized\n// via F4.5. No @google/generative-ai package — plain fetch through httpTransport.\nimport { httpTransport } from \"../transport/http.js\";\nimport { streamTransport } from \"../transport/stream.js\";\nimport { toProviderTools, fromProviderToolCall } from \"./tools.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ChatStreamEvent,\n Message,\n ContentPart,\n ToolCall,\n} from \"../types.js\";\n\ninterface GeminiPart {\n text?: string;\n functionCall?: { name: string; args: Record<string, unknown> };\n inlineData?: { mimeType: string; data: string };\n}\ninterface GeminiResponse {\n candidates?: { content?: { parts?: GeminiPart[] } }[];\n usageMetadata?: { promptTokenCount?: number; candidatesTokenCount?: number };\n error?: unknown;\n}\n\nfunction partsFrom(content: string | ContentPart[]): GeminiPart[] {\n if (typeof content === \"string\") return [{ text: content }];\n return content.map((p): GeminiPart => {\n if (p.type === \"text\") return { text: p.text };\n const data =\n typeof p.image === \"string\"\n ? p.image.replace(/^data:[^;]+;base64,/, \"\")\n : Buffer.from(p.image).toString(\"base64\");\n return { inlineData: { mimeType: p.mimeType ?? \"image/png\", data } };\n });\n}\n\nexport function geminiAdapter(\n config: { apiKey?: string; baseUrl?: string; fetch?: typeof fetch } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://generativelanguage.googleapis.com/v1beta\";\n\n function resolveKey(): string {\n const apiKey = config.apiKey ?? process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;\n if (!apiKey) throw new Error(\"gemini adapter: API key not set (env GOOGLE_API_KEY)\");\n return apiKey;\n }\n\n /** Build the generateContent body (shared by the http + stream paths). */\n function buildBody(req: ChatRequest): Record<string, unknown> {\n const systemParts: GeminiPart[] = [];\n const contents: { role: string; parts: GeminiPart[] }[] = [];\n for (const m of req.messages as Message[]) {\n if (m.role === \"system\") {\n systemParts.push(...partsFrom(m.content));\n } else {\n contents.push({\n role: m.role === \"assistant\" ? \"model\" : \"user\",\n parts: partsFrom(m.content),\n });\n }\n }\n const body: Record<string, unknown> = { contents };\n if (systemParts.length > 0) body.systemInstruction = { parts: systemParts };\n if (req.tools) body.tools = toProviderTools(req.tools, \"gemini\");\n const genConfig: Record<string, unknown> = {};\n if (req.maxTokens !== undefined) genConfig.maxOutputTokens = req.maxTokens;\n if (req.temperature !== undefined) genConfig.temperature = req.temperature;\n if (Object.keys(genConfig).length > 0) body.generationConfig = genConfig;\n return body;\n }\n\n async function chat(req: ChatRequest): Promise<ChatResult> {\n const apiKey = resolveKey();\n const body = buildBody(req);\n\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${baseUrl}/models/${req.spec.model}:generateContent?key=${encodeURIComponent(apiKey)}`,\n headers: { \"content-type\": \"application/json\" },\n body,\n },\n });\n if (!res.ok) {\n throw new Error(`gemini ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n }\n const data = res.json as GeminiResponse;\n const parts = data.candidates?.[0]?.content?.parts ?? [];\n const text = parts\n .filter((p) => typeof p.text === \"string\")\n .map((p) => p.text)\n .join(\"\");\n const toolCalls: ToolCall[] = parts\n .filter((p) => p.functionCall)\n .map((p) => fromProviderToolCall({ functionCall: p.functionCall }, \"gemini\"));\n\n const usage = freshUsage({\n provider: \"gemini\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: data.usageMetadata?.promptTokenCount ?? 0,\n outputTokens: data.usageMetadata?.candidatesTokenCount ?? 0,\n });\n const result: ChatResult = { text, usage };\n if (toolCalls.length > 0) result.toolCalls = toolCalls;\n return result;\n }\n\n // Streaming chat (F8.6) over streamGenerateContent?alt=sse. Each SSE chunk is\n // a partial GenerateContentResponse: parts[].text → text events, parts[].\n // functionCall → complete tool_call events (gemini sends each call whole), and\n // the final usageMetadata → a usage event. finishReason maps the terminal.\n async function* chatStream(req: ChatRequest): AsyncIterable<ChatStreamEvent> {\n const apiKey = resolveKey();\n const body = buildBody(req);\n const stream = streamTransport({\n spec: req.spec,\n fetch: config.fetch,\n http: {\n url: `${baseUrl}/models/${req.spec.model}:streamGenerateContent?alt=sse&key=${encodeURIComponent(apiKey)}`,\n headers: { \"content-type\": \"application/json\" },\n body,\n },\n });\n\n const toolCalls: ToolCall[] = [];\n let inputTokens = 0;\n let outputTokens = 0;\n let finishReason: string | null = null;\n\n for await (const data of stream) {\n let chunk: GeminiResponse & { candidates?: { finishReason?: string }[] };\n try {\n chunk = JSON.parse(data) as typeof chunk;\n } catch {\n continue;\n }\n const candidate = chunk.candidates?.[0];\n for (const p of candidate?.content?.parts ?? []) {\n if (typeof p.text === \"string\" && p.text.length > 0) {\n yield { type: \"text\", delta: p.text };\n } else if (p.functionCall) {\n toolCalls.push(fromProviderToolCall({ functionCall: p.functionCall }, \"gemini\"));\n }\n }\n if (candidate?.finishReason) finishReason = candidate.finishReason;\n if (chunk.usageMetadata) {\n inputTokens = chunk.usageMetadata.promptTokenCount ?? inputTokens;\n outputTokens = chunk.usageMetadata.candidatesTokenCount ?? outputTokens;\n }\n }\n\n for (const tc of toolCalls) {\n yield { type: \"tool_call\", id: tc.id, name: tc.name, args: tc.arguments };\n }\n const usage = freshUsage({\n provider: \"gemini\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens,\n outputTokens,\n });\n yield { type: \"usage\", costUsd: usage.costUsd, model: usage.model, usage };\n yield {\n type: \"finish\",\n reason: toolCalls.length > 0 ? \"tool_calls\" : mapGeminiFinish(finishReason),\n };\n }\n\n return { name: \"gemini\", chat, chatStream, vision: chat };\n}\n\n/** Map Gemini finishReason → the SDK's ChatStreamEvent finish reason. */\nfunction mapGeminiFinish(reason: string | null): \"end_turn\" | \"tool_calls\" | \"length\" | \"stop\" {\n switch (reason) {\n case \"MAX_TOKENS\":\n return \"length\";\n case \"STOP\":\n return \"end_turn\";\n default:\n return reason ? \"stop\" : \"end_turn\";\n }\n}\n","// DeepInfra adapter (F4.3). DeepInfra exposes an OpenAI-compatible endpoint, so\n// this is the shared core pointed at DeepInfra's base URL + key. No extra deps.\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport type { ProviderAdapter } from \"../types.js\";\n\nexport function deepinfraAdapter(\n config: { apiKey?: string; baseUrl?: string } = {},\n): ProviderAdapter {\n return makeOpenAICompatibleAdapter({\n name: \"deepinfra\",\n baseUrl: config.baseUrl ?? \"https://api.deepinfra.com/v1/openai\",\n apiKey: config.apiKey,\n });\n}\n","// OpenRouter adapter (F4.4). Meta-router with an OpenAI-compatible API — reuses\n// the shared core + OpenRouter's attribution headers. Any upstream model is\n// reachable by its slug, e.g. \"minimax/minimax-m2.7\", \"google/gemini-2.5-flash\".\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport type { ProviderAdapter } from \"../types.js\";\n\nexport function openrouterAdapter(\n config: { apiKey?: string; baseUrl?: string; referer?: string; title?: string } = {},\n): ProviderAdapter {\n return makeOpenAICompatibleAdapter({\n name: \"openrouter\",\n baseUrl: config.baseUrl ?? \"https://openrouter.ai/api/v1\",\n apiKey: config.apiKey,\n extraHeaders: {\n \"HTTP-Referer\": config.referer ?? \"https://broberg.ai\",\n \"X-Title\": config.title ?? \"@broberg/ai-sdk\",\n },\n // OpenRouter returns ground-truth usage.cost (USD) when usage:{include:true}\n // is set — use it over the local pricing-table estimate (F010).\n costFromResponseField: true,\n });\n}\n","// fal.ai image adapter (F5.3). Two modes, both observed in the F1 inventory:\n// - sync : POST https://fal.run/{model}, image URL straight back (sanneandersen)\n// - queue : POST https://queue.fal.run/{model} → poll status → fetch result\n// Auth header `Authorization: Key <FAL_KEY>`. No @fal-ai/client — plain fetch.\nimport { freshUsage } from \"../cost/usage.js\";\nimport type { ProviderAdapter, ImageRequest, ImageResult } from \"../types.js\";\n\ninterface FalImagesResponse {\n images?: { url?: string }[];\n error?: unknown;\n}\ninterface FalQueueSubmit {\n request_id?: string;\n status_url?: string;\n response_url?: string;\n}\ninterface FalQueueStatus {\n status?: \"IN_QUEUE\" | \"IN_PROGRESS\" | \"COMPLETED\" | \"FAILED\";\n}\n\nexport interface FalAdapterConfig {\n apiKey?: string;\n /** \"sync\" (default — fal.run, fast models) or \"queue\" (queue.fal.run, polled). */\n mode?: \"sync\" | \"queue\";\n syncBaseUrl?: string;\n queueBaseUrl?: string;\n pollIntervalMs?: number;\n timeoutMs?: number;\n fetch?: typeof fetch;\n /** Override the per-image USD price (else a built-in estimate per model, 0 if unknown). */\n pricePerImage?: number;\n}\n\n// Per-image USD ESTIMATES (fal prices by megapixel/model and changes often —\n// verify before relying on these; override via config.pricePerImage). fal does\n// not return a price, so this is the SDK's best-effort cost for `usage.costUsd`.\nconst FAL_IMAGE_PRICE_ESTIMATE: Record<string, number> = {\n \"fal-ai/flux/schnell\": 0.003,\n \"fal-ai/flux/dev\": 0.025,\n \"fal-ai/flux-pro\": 0.05,\n \"fal-ai/flux-pro/v1.1\": 0.04,\n};\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport function falAdapter(config: FalAdapterConfig = {}): ProviderAdapter {\n const doFetch = config.fetch ?? fetch;\n const syncBase = config.syncBaseUrl ?? \"https://fal.run\";\n const queueBase = config.queueBaseUrl ?? \"https://queue.fal.run\";\n const pollIntervalMs = config.pollIntervalMs ?? 2000;\n const timeoutMs = config.timeoutMs ?? 60000;\n\n async function image(req: ImageRequest): Promise<ImageResult> {\n const apiKey = config.apiKey ?? process.env.FAL_KEY;\n if (!apiKey) throw new Error(\"fal adapter: FAL_KEY not set\");\n const headers = { \"content-type\": \"application/json\", Authorization: `Key ${apiKey}` };\n\n const body: Record<string, unknown> = { prompt: req.prompt };\n if (req.width !== undefined && req.height !== undefined) {\n body.image_size = { width: req.width, height: req.height };\n }\n\n const mode = config.mode ?? \"sync\";\n const url = await (mode === \"sync\"\n ? runSync(req.spec.model, headers, body)\n : runQueue(req.spec.model, headers, body));\n\n // fal returns no price; estimate per-image (one image per call) so usage.costUsd\n // isn't silently 0. Override via config.pricePerImage.\n const usage = freshUsage({\n provider: \"fal\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"image\",\n inputTokens: 0,\n outputTokens: 0,\n });\n usage.costUsd = config.pricePerImage ?? FAL_IMAGE_PRICE_ESTIMATE[req.spec.model] ?? 0;\n return { url, usage };\n }\n\n async function runSync(\n model: string,\n headers: Record<string, string>,\n body: unknown,\n ): Promise<string> {\n const res = await doFetch(`${syncBase}/${model}`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n throw new Error(`fal ${res.status}: ${(await res.text().catch(() => \"\")).slice(0, 200)}`);\n }\n const data = (await res.json()) as FalImagesResponse;\n const out = data.images?.[0]?.url;\n if (!out) throw new Error(`fal: no image url in response`);\n return out;\n }\n\n async function runQueue(\n model: string,\n headers: Record<string, string>,\n body: unknown,\n ): Promise<string> {\n const submitRes = await doFetch(`${queueBase}/${model}`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!submitRes.ok) {\n throw new Error(`fal queue submit ${submitRes.status}`);\n }\n const submit = (await submitRes.json()) as FalQueueSubmit;\n const statusUrl = submit.status_url;\n const responseUrl = submit.response_url;\n if (!statusUrl || !responseUrl) throw new Error(\"fal queue: missing status/response url\");\n\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n const statusRes = await doFetch(statusUrl, { headers });\n const status = (await statusRes.json()) as FalQueueStatus;\n if (status.status === \"COMPLETED\") break;\n if (status.status === \"FAILED\") throw new Error(\"fal queue: generation FAILED\");\n if (Date.now() >= deadline) throw new Error(`fal queue: timed out after ${timeoutMs}ms`);\n await sleep(pollIntervalMs);\n }\n\n const resultRes = await doFetch(responseUrl, { headers });\n const result = (await resultRes.json()) as FalImagesResponse;\n const out = result.images?.[0]?.url;\n if (!out) throw new Error(\"fal queue: no image url in result\");\n return out;\n }\n\n return { name: \"fal\", image };\n}\n","// Default provider registry — the live adapters wired when AiConfig.providers is\n// absent. A bare createAI() makes real calls (keys from env). fal stays a stub\n// until F5.3 ships the real fal.ai image adapter.\nimport { anthropicAdapter } from \"./anthropic.js\";\nimport { openaiAdapter } from \"./openai.js\";\nimport { geminiAdapter } from \"./gemini.js\";\nimport { deepinfraAdapter } from \"./deepinfra.js\";\nimport { openrouterAdapter } from \"./openrouter.js\";\nimport { falAdapter } from \"./fal.js\";\nimport type { ProviderAdapter } from \"../types.js\";\n\nexport const defaultProviders: Record<string, ProviderAdapter> = {\n anthropic: anthropicAdapter(),\n openai: openaiAdapter(),\n gemini: geminiAdapter(),\n deepinfra: deepinfraAdapter(),\n openrouter: openrouterAdapter(),\n fal: falAdapter(),\n};\n","// Pre-flight budget guard. check() runs BEFORE the transport fires, so a call\n// that would breach a ceiling never reaches the provider. record() folds the\n// actual cost into the running total after a successful call.\nimport type { BudgetConfig, BudgetStore } from \"../types.js\";\n\n/** Default rolling-total store: in-memory, per BudgetGuard instance. */\nclass InMemoryBudgetStore implements BudgetStore {\n private spentUsd = 0;\n getSpent(): number {\n return this.spentUsd;\n }\n addSpent(usd: number): void {\n this.spentUsd += usd;\n }\n}\n\nexport class BudgetExceededError extends Error {\n readonly kind: \"per-call\" | \"rolling\";\n readonly limit: number;\n readonly spent: number;\n readonly requested: number;\n\n constructor(\n kind: \"per-call\" | \"rolling\",\n limit: number,\n spent: number,\n requested: number,\n ) {\n super(\n `Budget exceeded (${kind}): this call's estimated $${requested.toFixed(6)} ` +\n (kind === \"rolling\"\n ? `+ $${spent.toFixed(6)} already spent exceeds the $${limit.toFixed(6)} rolling ceiling`\n : `exceeds the $${limit.toFixed(6)} per-call ceiling`),\n );\n this.name = \"BudgetExceededError\";\n this.kind = kind;\n this.limit = limit;\n this.spent = spent;\n this.requested = requested;\n }\n}\n\nexport class BudgetGuard {\n private readonly store: BudgetStore;\n\n constructor(private readonly config: BudgetConfig) {\n this.store = config.store ?? new InMemoryBudgetStore();\n }\n\n /** Throws BudgetExceededError if `requested` would breach the per-call ceiling\n * or push the rolling total past its ceiling. Call before firing the request.\n * Async because a persistent store may be I/O-backed. */\n async check(requested: number): Promise<void> {\n const { perCallUsd, rollingUsd } = this.config;\n if (perCallUsd !== undefined && requested > perCallUsd) {\n throw new BudgetExceededError(\"per-call\", perCallUsd, await this.store.getSpent(), requested);\n }\n if (rollingUsd !== undefined) {\n const spent = await this.store.getSpent();\n if (spent + requested > rollingUsd) {\n throw new BudgetExceededError(\"rolling\", rollingUsd, spent, requested);\n }\n }\n }\n\n /** Add an actual cost to the running total (after a successful call). */\n async record(actual: number): Promise<void> {\n await this.store.addSpent(actual);\n }\n\n async totalSpent(): Promise<number> {\n return this.store.getSpent();\n }\n}\n","// Vision capability helper. The client owns orchestration (tier/budget/sink);\n// this module owns the vision-specific message shaping so it's unit-testable and\n// the capabilities/ layout stays meaningful. Default tier: \"vision\".\nimport type { VisionInput } from \"../schema/inputs.js\";\nimport type { Message, Tier } from \"../types.js\";\n\nexport const VISION_DEFAULT_TIER: Tier = \"vision\";\n\n/** Build the single-user multimodal message (text + image) for a vision call. */\nexport function buildVisionMessages(input: VisionInput): Message[] {\n return [\n {\n role: \"user\",\n content: [\n { type: \"text\", text: input.prompt },\n { type: \"image\", image: input.image, mimeType: input.mimeType },\n ],\n },\n ];\n}\n","// Translate capability helper. A thin prompt-contract on top of chat — the\n// client orchestrates (tier/budget/sink); this builds the messages. Default\n// tier: \"fast\". Returns the translation only, no preamble.\nimport type { TranslateInput } from \"../schema/inputs.js\";\nimport type { Message, Tier } from \"../types.js\";\n\nexport const TRANSLATE_DEFAULT_TIER: Tier = \"fast\";\n\nconst TRANSLATE_SYSTEM =\n \"You are a translation engine. Translate the user's text only. \" +\n \"Return the translation and nothing else — no preamble, no quotes.\";\n\nexport function buildTranslateMessages(input: TranslateInput): Message[] {\n const fromClause = input.from ? ` from ${input.from}` : \"\";\n return [\n { role: \"system\", content: TRANSLATE_SYSTEM },\n { role: \"user\", content: `Translate${fromClause} to ${input.to}:\\n\\n${input.text}` },\n ];\n}\n","// Embedding capability marker. The client orchestrates; this names the default\n// tier (OpenAI text-embedding-3-small via the embedding tier).\nimport type { Tier } from \"../types.js\";\n\nexport const EMBEDDING_DEFAULT_TIER: Tier = \"embedding\";\n","// Transcribe capability. No tier in the tier map (provider-specific, like image)\n// — defaults to OpenAI Whisper, overridable per call. Synergy: cctalk Danish\n// dictation. costUsd is 0 for v1 (Whisper is priced per minute, not per token).\nimport type { TierSpec } from \"../types.js\";\n\nexport const DEFAULT_TRANSCRIBE_SPEC: TierSpec = {\n provider: \"openai\",\n model: \"whisper-1\",\n transport: \"http\",\n};\n\n/** Fetch a URL to raw bytes; pass through bytes unchanged. */\nexport async function resolveAudio(\n audio: string | Uint8Array,\n fetchImpl: typeof fetch = fetch,\n): Promise<Uint8Array> {\n if (typeof audio !== \"string\") return audio;\n if (!/^https?:\\/\\//.test(audio)) {\n throw new Error(\"transcribe: string audio must be an http(s) URL (or pass raw bytes)\");\n }\n const res = await fetchImpl(audio);\n if (!res.ok) throw new Error(`transcribe: failed to fetch audio (${res.status})`);\n return new Uint8Array(await res.arrayBuffer());\n}\n","// Prompt-contract capabilities (F5.5). Each is a fixed system prompt over\n// chat/vision; extract adds Zod output validation with one retry. Exposed as\n// ai.contracts.* — built from the client so budget/cost tracking apply.\nimport type { AiClient, VisionInput } from \"../../schema/inputs.js\";\nimport type {\n Contracts,\n MockupInput,\n MockupResult,\n DesignInput,\n DesignResult,\n ExtractInput,\n ExtractResult,\n ClassifyInput,\n ClassifyResult,\n RerankInput,\n RerankResult,\n} from \"./types.js\";\n\n/** Pull the first JSON value out of a model reply (tolerates ```json fences + prose). */\nexport function parseJsonLoose(text: string): unknown {\n const fenced = text.replace(/```(?:json)?/gi, \"\").trim();\n const start = fenced.search(/[[{]/);\n if (start === -1) throw new Error(\"no JSON found in model output\");\n const slice = fenced.slice(start);\n // Walk back from the end to the matching closing bracket.\n const lastObj = slice.lastIndexOf(\"}\");\n const lastArr = slice.lastIndexOf(\"]\");\n const end = Math.max(lastObj, lastArr);\n return JSON.parse(slice.slice(0, end + 1));\n}\n\ntype ChatVision = Pick<AiClient, \"chat\" | \"vision\">;\n\nexport function makeContracts(client: ChatVision): Contracts {\n return {\n async mockup(input: MockupInput): Promise<MockupResult> {\n const constraints = input.constraints ? `\\n\\nConstraints:\\n${input.constraints}` : \"\";\n const res = await client.chat({\n system:\n \"You are a UI mockup generator. Output a single self-contained HTML document \" +\n \"using Tailwind CSS utility classes. Return ONLY the HTML — no markdown, no prose.\",\n prompt: `Build a UI mockup for:\\n${input.description}${constraints}`,\n tier: input.tier ?? \"smart\",\n purpose: input.purpose ?? \"contract:mockup\",\n });\n return { html: res.text, usage: res.usage };\n },\n\n async design(input: DesignInput): Promise<DesignResult> {\n const res = await client.vision({\n image: input.screenshot as VisionInput[\"image\"],\n prompt:\n \"You are a design-iteration engine. Given this screenshot, apply the instructions \" +\n `and return a single self-contained HTML document (Tailwind), ONLY the HTML.\\n\\n` +\n `Instructions:\\n${input.instructions}`,\n tier: input.tier ?? \"powerful\",\n purpose: input.purpose ?? \"contract:design\",\n });\n return { html: res.text, usage: res.usage };\n },\n\n async extract<T>(input: ExtractInput<T>): Promise<ExtractResult<T>> {\n const base =\n \"You are a structured-data extractor. Extract the requested data from the text and \" +\n \"return ONLY valid JSON — no markdown, no prose.\" +\n (input.instructions ? `\\n\\n${input.instructions}` : \"\");\n const run = async (reinforce: boolean) => {\n const res = await client.chat({\n system: reinforce ? `${base}\\n\\nYour previous output was not valid JSON. Return ONLY parseable JSON.` : base,\n prompt: input.text,\n tier: input.tier ?? \"smart\",\n purpose: input.purpose ?? \"contract:extract\",\n });\n return res;\n };\n let res = await run(false);\n try {\n return { data: input.schema.parse(parseJsonLoose(res.text)), usage: res.usage };\n } catch {\n // one retry with reinforcement\n res = await run(true);\n return { data: input.schema.parse(parseJsonLoose(res.text)), usage: res.usage };\n }\n },\n\n async classify(input: ClassifyInput): Promise<ClassifyResult> {\n const res = await client.chat({\n system:\n \"You are a zero-shot classifier. Choose exactly one label from the provided list. \" +\n 'Return ONLY JSON: {\"label\": \"<one of the labels>\", \"confidence\": <0..1>}.',\n prompt: `Labels: ${JSON.stringify(input.labels)}\\n\\nText:\\n${input.text}`,\n tier: input.tier ?? \"cheap\",\n purpose: input.purpose ?? \"contract:classify\",\n });\n const parsed = parseJsonLoose(res.text) as { label?: string; confidence?: number };\n const label = input.labels.includes(parsed.label ?? \"\") ? parsed.label! : (input.labels[0] ?? \"\");\n const confidence = typeof parsed.confidence === \"number\" ? parsed.confidence : 0;\n return { label, confidence, usage: res.usage };\n },\n\n async rerank(input: RerankInput): Promise<RerankResult> {\n const res = await client.chat({\n system:\n \"You are a relevance reranker. Score each item 0..1 for relevance to the query and \" +\n 'return ONLY JSON: [{\"item\": \"<verbatim item>\", \"score\": <0..1>}], ordered by score desc.',\n prompt: `Query: ${input.query}\\n\\nItems:\\n${JSON.stringify(input.items)}`,\n tier: input.tier ?? \"fast\",\n purpose: input.purpose ?? \"contract:rerank\",\n });\n const raw = parseJsonLoose(res.text) as { item?: string; score?: number }[];\n const ranked = (Array.isArray(raw) ? raw : [])\n .map((r) => ({ item: String(r.item ?? \"\"), score: typeof r.score === \"number\" ? r.score : 0 }))\n .sort((a, b) => b.score - a.score);\n return { ranked, usage: res.usage };\n },\n };\n}\n","// Zod is the single source of truth for the public input shapes. The TypeScript\n// types are derived via z.infer — no hand-written interface duplicates them.\n// The client .parse()s every input at the boundary, so invalid input throws a\n// ZodError before any provider work happens.\nimport { z } from \"zod\";\nimport type {\n ProviderAdapter,\n CostSink,\n TranslateResult,\n ChatResult,\n ChatStreamEvent,\n ImageResult,\n EmbeddingResult,\n TranscribeResult,\n} from \"../types.js\";\nimport type { Contracts } from \"../capabilities/contracts/types.js\";\n\n// ── Reusable sub-schemas ───────────────────────────────────────────────────\n\nexport const transportSchema = z.enum([\"http\", \"subprocess\"]);\n\nexport const tierSchema = z.enum([\n \"fast\",\n \"smart\",\n \"powerful\",\n \"cheap\",\n \"vision\",\n \"embedding\",\n]);\n\nexport const tierSpecSchema = z.object({\n provider: z.string(),\n model: z.string(),\n transport: transportSchema,\n});\n\nexport const toolSchema = z.object({\n name: z.string(),\n description: z.string(),\n parameters: z.record(z.unknown()),\n});\n\nexport const toolCallSchema = z.object({\n id: z.string(),\n name: z.string(),\n arguments: z.record(z.unknown()),\n});\n\nexport const contentPartSchema = z.union([\n z.object({ type: z.literal(\"text\"), text: z.string() }),\n z.object({\n type: z.literal(\"image\"),\n image: z.union([z.string(), z.instanceof(Uint8Array)]),\n mimeType: z.string().optional(),\n }),\n]);\n\nexport const messageSchema = z.object({\n role: z.enum([\"system\", \"user\", \"assistant\", \"tool\"]),\n content: z.union([z.string(), z.array(contentPartSchema)]),\n toolCalls: z.array(toolCallSchema).optional(),\n toolCallId: z.string().optional(),\n});\n\n/** Per-call options shared by every capability input. */\nconst callOptions = {\n tier: tierSchema.optional(),\n override: tierSpecSchema.partial().optional(),\n fallback: z.array(z.union([tierSchema, tierSpecSchema])).optional(),\n purpose: z.string().optional(),\n} as const;\n\n// ── The 5 capability inputs ────────────────────────────────────────────────\n\nexport const chatInputSchema = z.object({\n prompt: z.string().optional(),\n messages: z.array(messageSchema).optional(),\n system: z.string().optional(),\n tools: z.array(toolSchema).optional(),\n maxTokens: z.number().int().positive().optional(),\n temperature: z.number().min(0).max(2).optional(),\n /** \"json\" requests JSON-object output (OpenAI-compatible response_format). */\n responseFormat: z.enum([\"json\", \"text\"]).optional(),\n ...callOptions,\n});\n\nexport const visionInputSchema = z.object({\n image: z.union([z.string(), z.instanceof(Uint8Array)]),\n prompt: z.string(),\n mimeType: z.string().optional(),\n ...callOptions,\n});\n\nexport const translateInputSchema = z.object({\n text: z.string(),\n to: z.string(),\n from: z.string().optional(),\n ...callOptions,\n});\n\nexport const imageInputSchema = z.object({\n prompt: z.string(),\n width: z.number().int().positive().optional(),\n height: z.number().int().positive().optional(),\n ...callOptions,\n});\n\nexport const embeddingInputSchema = z.object({\n text: z.union([z.string(), z.array(z.string())]),\n ...callOptions,\n});\n\nexport const transcribeInputSchema = z.object({\n /** Audio URL or raw bytes. */\n audio: z.union([z.string(), z.instanceof(Uint8Array)]),\n language: z.string().optional(),\n /** Audio length in seconds — enables Whisper per-minute cost. */\n durationSec: z.number().positive().optional(),\n ...callOptions,\n});\n\n// ── Client config ──────────────────────────────────────────────────────────\n\nexport const budgetSchema = z.object({\n perCallUsd: z.number().positive().optional(),\n rollingUsd: z.number().positive().optional(),\n});\n\nexport const aiConfigSchema = z.object({\n defaults: z.record(tierSchema, tierSpecSchema).optional(),\n // Functions can't be deeply validated — z.custom asserts the TS type and\n // passes the value through untouched.\n providers: z.record(z.string(), z.custom<ProviderAdapter>()).optional(),\n costSink: z.custom<CostSink>().optional(),\n budget: budgetSchema.optional(),\n});\n\n// ── Derived types (z.infer is the single source) ───────────────────────────\n\nexport type ChatInput = z.infer<typeof chatInputSchema>;\nexport type VisionInput = z.infer<typeof visionInputSchema>;\nexport type TranslateInput = z.infer<typeof translateInputSchema>;\nexport type ImageInput = z.infer<typeof imageInputSchema>;\nexport type EmbeddingInput = z.infer<typeof embeddingInputSchema>;\nexport type TranscribeInput = z.infer<typeof transcribeInputSchema>;\nexport type AiConfig = z.infer<typeof aiConfigSchema>;\n\n/** The public facade. Defined here because it depends on the derived inputs. */\nexport interface AiClient {\n chat(input: ChatInput): Promise<ChatResult>;\n /** Streaming chat (F8) — same input as chat; yields ChatStreamEvents. The\n * caller owns the tool-loop (per-turn engine, not an agent runtime). */\n chatStream(input: ChatInput): AsyncIterable<ChatStreamEvent>;\n vision(input: VisionInput): Promise<ChatResult>;\n translate(input: TranslateInput): Promise<TranslateResult>;\n image(input: ImageInput): Promise<ImageResult>;\n embedding(input: EmbeddingInput): Promise<EmbeddingResult>;\n transcribe(input: TranscribeInput): Promise<TranscribeResult>;\n /** Prompt-contract capabilities (F5.5) layered on chat/vision. */\n contracts: Contracts;\n}\n","// createAI() — the facade factory. Resolves routing, picks a provider adapter,\n// delegates the call, stamps call-context metadata onto Usage, and reports to the\n// cost sink. Provider specifics live in adapters; cost compute/budget land in F3.\nimport { resolveTier } from \"./routing/tier-map.js\";\nimport { defaultProviders } from \"./providers/registry.js\";\nimport { computeCost } from \"./cost/usage.js\";\nimport { BudgetGuard } from \"./cost/budget.js\";\nimport { buildVisionMessages, VISION_DEFAULT_TIER } from \"./capabilities/vision.js\";\nimport { buildTranslateMessages, TRANSLATE_DEFAULT_TIER } from \"./capabilities/translate.js\";\nimport { EMBEDDING_DEFAULT_TIER } from \"./capabilities/embedding.js\";\nimport { DEFAULT_TRANSCRIBE_SPEC, resolveAudio } from \"./capabilities/transcribe.js\";\nimport { makeContracts } from \"./capabilities/contracts/index.js\";\nimport {\n aiConfigSchema,\n chatInputSchema,\n visionInputSchema,\n translateInputSchema,\n imageInputSchema,\n embeddingInputSchema,\n transcribeInputSchema,\n} from \"./schema/inputs.js\";\nimport type {\n AiConfig,\n AiClient,\n ChatInput,\n VisionInput,\n TranslateInput,\n ImageInput,\n EmbeddingInput,\n TranscribeInput,\n} from \"./schema/inputs.js\";\nimport type {\n ChatResult,\n ChatStreamEvent,\n ImageResult,\n EmbeddingResult,\n TranscribeResult,\n TranslateResult,\n ProviderAdapter,\n Message,\n Capability,\n Tier,\n TierSpec,\n Usage,\n} from \"./types.js\";\n\n/** Built-in image route (no image tier in the tier map — fal owns its routing). */\nconst DEFAULT_IMAGE_SPEC: TierSpec = {\n provider: \"fal\",\n model: \"fal-ai/flux/schnell\",\n transport: \"http\",\n};\n\nexport function createAI(config: AiConfig = {}): AiClient {\n // Validate config at the boundary (throws ZodError on bad shape).\n const cfg = aiConfigSchema.parse(config);\n const providers = cfg.providers ?? defaultProviders;\n const budget = cfg.budget ? new BudgetGuard(cfg.budget) : undefined;\n\n const estTokens = (s: string): number => Math.ceil(s.length / 4);\n\n /** Pre-flight budget check. Estimates this call's cost and throws\n * BudgetExceededError before the transport fires. No-op without a budget. */\n async function preflight(spec: TierSpec, estInTokens: number, estOutTokens: number): Promise<void> {\n if (!budget) return;\n await budget.check(computeCost(spec.provider, spec.model, estInTokens, estOutTokens));\n }\n\n /** Fold the actual cost into the rolling total after a successful call. */\n async function settle(usage: Usage): Promise<void> {\n if (budget) await budget.record(usage.costUsd);\n }\n\n function pickProvider(name: string): ProviderAdapter {\n const adapter = providers[name];\n if (!adapter) {\n throw new Error(\n `createAI: no provider adapter registered for \"${name}\". Registered: ${Object.keys(providers).join(\", \") || \"(none)\"}`,\n );\n }\n return adapter;\n }\n\n /** Stamp call-context metadata the client owns onto the adapter's Usage:\n * capability, tier, purpose, the wall-clock latency, and the timestamp. */\n function enrich(\n usage: Usage,\n capability: Capability,\n tier: Tier | undefined,\n purpose: string | undefined,\n latencyMs: number,\n ): Usage {\n usage.capability = capability;\n if (tier) usage.tier = tier;\n if (purpose) usage.purpose = purpose;\n usage.latencyMs = Math.round(latencyMs);\n if (!usage.ts) usage.ts = new Date().toISOString();\n return usage;\n }\n\n async function report(usage: Usage): Promise<void> {\n if (!cfg.costSink) return;\n try {\n await cfg.costSink.record(usage);\n } catch {\n // A broken sink must never crash a real AI call (F3.3 invariant).\n }\n }\n\n function toMessages(input: ChatInput): Message[] {\n if (input.messages && input.messages.length > 0) return input.messages;\n const msgs: Message[] = [];\n if (input.system) msgs.push({ role: \"system\", content: input.system });\n msgs.push({ role: \"user\", content: input.prompt ?? \"\" });\n return msgs;\n }\n\n /** Run a capability with an optional fallback chain. Tries the primary route,\n * then each fallback (Tier or TierSpec) in order if the call errors. A budget\n * breach propagates immediately (not a fallback trigger). On the first\n * success: stamp Usage, settle the budget, report to the sink, return. */\n async function runCapability<R extends { usage: Usage }>(opts: {\n primary: TierSpec;\n fallback?: (Tier | TierSpec)[];\n capability: Capability;\n tier?: Tier;\n purpose?: string;\n estIn: number;\n estOut: number;\n invoke: (spec: TierSpec) => Promise<R>;\n }): Promise<R> {\n const routes: TierSpec[] = [\n opts.primary,\n ...(opts.fallback ?? []).map((f) =>\n typeof f === \"string\" ? resolveTier(f, undefined, cfg.defaults) : f,\n ),\n ];\n let lastErr: unknown;\n for (let i = 0; i < routes.length; i++) {\n const spec = routes[i]!;\n await preflight(spec, opts.estIn, opts.estOut); // BudgetExceededError propagates\n try {\n const t0 = performance.now();\n const res = await opts.invoke(spec);\n enrich(res.usage, opts.capability, i === 0 ? opts.tier : undefined, opts.purpose, performance.now() - t0);\n await settle(res.usage);\n await report(res.usage);\n return res;\n } catch (e) {\n lastErr = e; // try the next fallback route\n }\n }\n throw lastErr;\n }\n\n /** Whether a pre-first-token streaming error should fall back to the next\n * route. Eligible: network/timeout/parse (no status) + 429 + 5xx. Hard 4xx\n * bubbles up (no silent re-route) — sa contract #2565. */\n function eligibleForFallback(e: unknown): boolean {\n const status = (e as { status?: number } | null)?.status;\n if (status === undefined) return true;\n return status === 429 || status >= 500;\n }\n\n function errorEvent(e: unknown): ChatStreamEvent {\n const ev: ChatStreamEvent = {\n type: \"error\",\n message: e instanceof Error ? e.message : String(e),\n };\n const status = (e as { status?: number } | null)?.status;\n if (status !== undefined) ev.status = status;\n return ev;\n }\n\n /** Streaming chat with pre-stream fallback (F8.1). Yields ChatStreamEvents as\n * the turn unfolds. Fallback re-routes only BEFORE the first text/tool_call\n * event (deltas can't be un-emitted); once streaming has begun, an error is\n * surfaced as an error event and the stream ends. Budget breaches propagate. */\n async function* chatStreamImpl(input: ChatInput): AsyncIterable<ChatStreamEvent> {\n input = chatInputSchema.parse(input);\n const tier = input.tier ?? \"smart\";\n const messages = toMessages(input);\n const estIn = messages.reduce(\n (n, m) => n + estTokens(typeof m.content === \"string\" ? m.content : JSON.stringify(m.content)),\n 0,\n );\n const estOut = input.maxTokens ?? 512;\n const routes: TierSpec[] = [\n resolveTier(tier, input.override, cfg.defaults),\n ...(input.fallback ?? []).map((f) =>\n typeof f === \"string\" ? resolveTier(f, undefined, cfg.defaults) : f,\n ),\n ];\n\n let lastErr: unknown;\n for (let i = 0; i < routes.length; i++) {\n const spec = routes[i]!;\n await preflight(spec, estIn, estOut); // BudgetExceededError propagates\n const adapter = pickProvider(spec.provider);\n if (!adapter.chatStream) {\n throw new Error(`createAI: provider \"${spec.provider}\" does not support streaming`);\n }\n const t0 = performance.now();\n let emitted = false;\n try {\n for await (const ev of adapter.chatStream({\n messages,\n spec,\n tools: input.tools,\n maxTokens: input.maxTokens,\n temperature: input.temperature,\n responseFormat: input.responseFormat,\n })) {\n if (ev.type === \"text\" || ev.type === \"tool_call\") emitted = true;\n if (ev.type === \"usage\") {\n enrich(ev.usage, \"chat\", i === 0 ? tier : undefined, input.purpose, performance.now() - t0);\n await settle(ev.usage);\n await report(ev.usage);\n }\n yield ev;\n }\n return; // stream completed cleanly\n } catch (e) {\n lastErr = e;\n if (emitted || !eligibleForFallback(e)) {\n yield errorEvent(e); // mid-stream or hard error → surface + stop\n return;\n }\n // pre-first-token eligible error → try the next route\n }\n }\n yield errorEvent(lastErr);\n }\n\n const client: AiClient = {\n async chat(input: ChatInput): Promise<ChatResult> {\n input = chatInputSchema.parse(input);\n const tier = input.tier ?? \"smart\";\n const messages = toMessages(input);\n const estIn = messages.reduce(\n (n, m) => n + estTokens(typeof m.content === \"string\" ? m.content : JSON.stringify(m.content)),\n 0,\n );\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"chat\",\n tier,\n purpose: input.purpose,\n estIn,\n estOut: input.maxTokens ?? 512,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.chat) throw new Error(`createAI: provider \"${spec.provider}\" does not support chat`);\n return adapter.chat({ messages, spec, tools: input.tools, maxTokens: input.maxTokens, temperature: input.temperature, responseFormat: input.responseFormat });\n },\n });\n },\n\n chatStream: chatStreamImpl,\n\n async vision(input: VisionInput): Promise<ChatResult> {\n input = visionInputSchema.parse(input);\n const tier = input.tier ?? VISION_DEFAULT_TIER;\n const messages: Message[] = buildVisionMessages(input);\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"vision\",\n tier,\n purpose: input.purpose,\n estIn: estTokens(input.prompt) + 1000, // prompt + ~1k image payload\n estOut: 512,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.vision) throw new Error(`createAI: provider \"${spec.provider}\" does not support vision`);\n return adapter.vision({ messages, spec });\n },\n });\n },\n\n async translate(input: TranslateInput): Promise<TranslateResult> {\n input = translateInputSchema.parse(input);\n const tier = input.tier ?? TRANSLATE_DEFAULT_TIER;\n const messages: Message[] = buildTranslateMessages(input);\n const estIn = estTokens(input.text) + 40;\n const res = await runCapability<ChatResult>({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"translate\",\n tier,\n purpose: input.purpose,\n estIn,\n estOut: estIn,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.chat) throw new Error(`createAI: provider \"${spec.provider}\" does not support chat (translate routes through chat)`);\n return adapter.chat({ messages, spec });\n },\n });\n return { text: res.text, usage: res.usage };\n },\n\n async image(input: ImageInput): Promise<ImageResult> {\n input = imageInputSchema.parse(input);\n return runCapability({\n primary: { ...DEFAULT_IMAGE_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"image\",\n purpose: input.purpose,\n estIn: 0, // image cost is not token-based\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.image) throw new Error(`createAI: provider \"${spec.provider}\" does not support image`);\n return adapter.image({ prompt: input.prompt, spec, width: input.width, height: input.height });\n },\n });\n },\n\n async embedding(input: EmbeddingInput): Promise<EmbeddingResult> {\n input = embeddingInputSchema.parse(input);\n const tier = input.tier ?? EMBEDDING_DEFAULT_TIER;\n const text = Array.isArray(input.text) ? input.text : [input.text];\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"embedding\",\n tier,\n purpose: input.purpose,\n estIn: text.reduce((n, t) => n + estTokens(t), 0),\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.embedding) throw new Error(`createAI: provider \"${spec.provider}\" does not support embedding`);\n return adapter.embedding({ input: text, spec });\n },\n });\n },\n\n async transcribe(input: TranscribeInput): Promise<TranscribeResult> {\n input = transcribeInputSchema.parse(input);\n const audio = await resolveAudio(input.audio);\n return runCapability({\n primary: { ...DEFAULT_TRANSCRIBE_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"transcribe\",\n purpose: input.purpose,\n estIn: 0,\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.transcribe) throw new Error(`createAI: provider \"${spec.provider}\" does not support transcribe`);\n return adapter.transcribe({ audio, language: input.language, durationSec: input.durationSec, spec });\n },\n });\n },\n\n // Replaced below with the real prompt-contracts (needs the client itself).\n contracts: undefined as unknown as AiClient[\"contracts\"],\n };\n\n client.contracts = makeContracts(client);\n return client;\n}\n","// Stub provider adapters (F2.5). They satisfy ProviderAdapter so the client wires\n// up and resolves without real network calls. Real implementations land in F4\n// (anthropic/openai/gemini/openrouter/deepinfra) and F5.3 (fal image). The stub\n// usage carries zero tokens/cost — F3.1 fills real numbers in the live adapters.\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ImageRequest,\n ImageResult,\n EmbeddingRequest,\n EmbeddingResult,\n Usage,\n Capability,\n} from \"../types.js\";\n\nfunction stubUsage(\n provider: string,\n model: string,\n transport: \"http\" | \"subprocess\",\n capability: Capability,\n): Usage {\n return {\n provider,\n model,\n transport,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheCreationTokens: 0,\n costUsd: 0,\n latencyMs: 0,\n capability,\n // ts is supplied by the caller-side at real call time; stub uses a fixed marker\n // ('' avoids Date.now() — keeps the stub pure/deterministic for tests).\n ts: \"\",\n };\n}\n\nfunction lastUserText(req: ChatRequest): string {\n for (let i = req.messages.length - 1; i >= 0; i--) {\n const m = req.messages[i];\n if (m && m.role === \"user\") {\n return typeof m.content === \"string\"\n ? m.content\n : m.content.map((p) => (p.type === \"text\" ? p.text : \"[image]\")).join(\" \");\n }\n }\n return \"\";\n}\n\n/** Anthropic adapter stub (HTTP path). */\nexport const anthropicApiAdapter: ProviderAdapter = {\n name: \"anthropic\",\n async chat(req: ChatRequest): Promise<ChatResult> {\n return {\n text: `[stub:anthropic-api] ${lastUserText(req)}`,\n usage: stubUsage(\"anthropic\", req.spec.model, \"http\", \"chat\"),\n };\n },\n async vision(req: ChatRequest): Promise<ChatResult> {\n return {\n text: `[stub:anthropic-api:vision] ${lastUserText(req)}`,\n usage: stubUsage(\"anthropic\", req.spec.model, \"http\", \"vision\"),\n };\n },\n};\n\n/** Anthropic adapter stub (subprocess / `claude -p` path). */\nexport const anthropicSubprocessAdapter: ProviderAdapter = {\n name: \"anthropic\",\n async chat(req: ChatRequest): Promise<ChatResult> {\n const usage = stubUsage(\"anthropic\", req.spec.model, \"subprocess\", \"chat\");\n usage.subprocess = true;\n return { text: `[stub:anthropic-subprocess] ${lastUserText(req)}`, usage };\n },\n};\n\n/** OpenAI adapter stub — covers the embedding default tier + a chat fallback. */\nexport const openaiStubAdapter: ProviderAdapter = {\n name: \"openai\",\n async chat(req: ChatRequest): Promise<ChatResult> {\n return {\n text: `[stub:openai] ${lastUserText(req)}`,\n usage: stubUsage(\"openai\", req.spec.model, \"http\", \"chat\"),\n };\n },\n async embedding(req: EmbeddingRequest): Promise<EmbeddingResult> {\n return {\n vectors: req.input.map(() => [0, 0, 0]),\n usage: stubUsage(\"openai\", req.spec.model, \"http\", \"embedding\"),\n };\n },\n};\n\n/** fal.ai adapter stub — image generation (real one in fal.ts, F5.3). */\nexport const falStubAdapter: ProviderAdapter = {\n name: \"fal\",\n async image(req: ImageRequest): Promise<ImageResult> {\n return {\n url: `https://stub.fal/${encodeURIComponent(req.prompt).slice(0, 32)}.png`,\n usage: stubUsage(\"fal\", req.spec.model, \"http\", \"image\"),\n };\n },\n};\n\n/** Stub provider registry — deterministic, no network. Used by tests via\n * createAI({ providers: stubProviders }). The real default registry (registry.ts)\n * wires the live adapters. */\nexport const stubProviders: Record<string, ProviderAdapter> = {\n anthropic: anthropicApiAdapter,\n openai: openaiStubAdapter,\n fal: falStubAdapter,\n};\n","// AUTO-GENERATED by scripts/gen-version.mjs — do not edit, do not commit.\nexport const VERSION = \"0.3.1\" as const;\nexport const SDK_TAG = \"@broberg/ai-sdk@0.3.1\" as const;\n","// Persistent BudgetStore backed by bun:sqlite (F7.1). The rolling total survives\n// process restarts and is shared by every process pointing at the same file, so\n// a budget ceiling is a real production guard — not a per-process counter that\n// resets on deploy. bun:sqlite is imported lazily (Node-safe import, like sqliteSink).\nimport type { BudgetStore } from \"../types.js\";\n\nexport interface SqliteBudgetStoreConfig {\n /** SQLite file path, e.g. \"./ai-budget.db\". */\n dbPath: string;\n /** Window/bucket key — use e.g. a day-stamp for a daily budget. Default \"default\". */\n key?: string;\n}\n\nexport function sqliteBudgetStore(config: SqliteBudgetStoreConfig): BudgetStore {\n const key = config.key ?? \"default\";\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let ready: Promise<any> | null = null;\n const open = async () => {\n const { Database } = await import(\"bun:sqlite\");\n const db = new Database(config.dbPath);\n db.run(\n `CREATE TABLE IF NOT EXISTS budget_spend (key TEXT PRIMARY KEY, spent_usd REAL NOT NULL DEFAULT 0)`,\n );\n return db;\n };\n\n return {\n async getSpent(): Promise<number> {\n const db = await (ready ??= open());\n const row = db\n .query(`SELECT spent_usd FROM budget_spend WHERE key = $key`)\n .get({ $key: key }) as { spent_usd: number } | null;\n return row?.spent_usd ?? 0;\n },\n async addSpent(usd: number): Promise<void> {\n const db = await (ready ??= open());\n db.run(\n `INSERT INTO budget_spend (key, spent_usd) VALUES ($key, $usd)\n ON CONFLICT(key) DO UPDATE SET spent_usd = spent_usd + $usd`,\n { $key: key, $usd: usd },\n );\n },\n };\n}\n","import type { CostSink } from \"../../types.js\";\n\n/** A sink that does nothing. The default when no costSink is configured. */\nexport const noopSink: CostSink = {\n record() {\n // intentionally empty\n },\n};\n","import type { CostSink, Usage } from \"../../types.js\";\n\n/** Fan a Usage out to several sinks. Uses allSettled so one failing sink never\n * prevents the others from recording (and never propagates to the caller). */\nexport function multiSink(sinks: CostSink[]): CostSink {\n return {\n async record(usage: Usage): Promise<void> {\n // async wrapper turns a synchronous throw in s.record into a rejected\n // promise, so allSettled isolates it (a sync throw would otherwise escape\n // the .map before allSettled ran).\n await Promise.allSettled(sinks.map(async (s) => s.record(usage)));\n },\n };\n}\n","// upmetricsSink — the canonical cost sink. Forwards each Usage to the upmetrics\n// agent-run ingest (POST /api/agent, mode:\"record\"). Field mapping follows\n// upmetrics/docs/AGENT-SCHEMA.md \"For cost-sink authors\" exactly:\n// - agent_kind / agent_name are injected (not in Usage; required by ingest)\n// - camelCase Usage → snake_case wire fields\n// - capability + transport ride in tags (no top-level column)\n// - toolCalls[].errorCount → tool_calls[].error_count (deep rename)\n// - latencyMs → duration_ms; ts → started_at; ended_at = ts + latency\n// Errors never propagate (CostSink invariant). Do NOT use @upmetrics/agent\n// wrapAnthropic here — the SDK already owns the provider call.\nimport { SDK_TAG } from \"../../version.js\";\nimport type { CostSink, Usage } from \"../../types.js\";\n\nexport interface UpmetricsSinkConfig {\n /** Ingest base URL, e.g. https://upmetrics.org */\n baseUrl: string;\n /** Per-project api_key → sent as the X-Upmetrics-Key header. */\n apiKey: string;\n /** Consumer name dashboards group by (e.g. \"cms\", \"trail\", \"xrt81\") — NOT the\n * capability. */\n agentName: string;\n /** Defaults to \"chatbot\" (\"embedding\" auto-selected for embedding calls). */\n agentKind?: string;\n /** When true, guarantees no prompt/response content is ever sent (the sink\n * sends none regardless — Usage carries no excerpts — so this is belt-and-\n * suspenders for GDPR-health projects). */\n complianceMode?: boolean;\n /** Injectable fetch for testing; defaults to global fetch. */\n fetch?: typeof fetch;\n /** Optional error hook (errors are otherwise swallowed silently). */\n onError?: (err: unknown) => void;\n}\n\nexport function upmetricsSink(config: UpmetricsSinkConfig): CostSink {\n const doFetch = config.fetch ?? fetch;\n const url = `${config.baseUrl.replace(/\\/$/, \"\")}/api/agent`;\n\n return {\n async record(usage: Usage): Promise<void> {\n try {\n const startedAt = usage.ts || new Date().toISOString();\n const endedAt = new Date(\n new Date(startedAt).getTime() + (usage.latencyMs || 0),\n ).toISOString();\n\n const agentKind =\n config.agentKind ?? (usage.capability === \"embedding\" ? \"embedding\" : \"chatbot\");\n\n const body: Record<string, unknown> = {\n mode: \"record\",\n agent_kind: agentKind,\n agent_name: config.agentName,\n provider: usage.provider,\n model: usage.model,\n status: \"success\",\n input_tokens: usage.inputTokens,\n output_tokens: usage.outputTokens,\n cache_read_tokens: usage.cacheReadTokens,\n cache_creation_tokens: usage.cacheCreationTokens,\n cost_usd: usage.costUsd,\n duration_ms: usage.latencyMs,\n started_at: startedAt,\n ended_at: endedAt,\n tags: {\n capability: usage.capability,\n transport: usage.transport,\n sdk: SDK_TAG,\n },\n };\n if (usage.tier !== undefined) body.tier = usage.tier;\n if (usage.purpose !== undefined) body.purpose = usage.purpose;\n if (usage.toolCalls) {\n body.tool_calls = usage.toolCalls.map((t) => ({\n name: t.name,\n count: t.count,\n error_count: t.errorCount ?? 0,\n }));\n }\n // complianceMode is a no-op today (we never send excerpts) but documents intent.\n void config.complianceMode;\n\n const res = await doFetch(url, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"X-Upmetrics-Key\": config.apiKey,\n },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n config.onError?.(\n new Error(`upmetricsSink: ingest returned ${res.status}: ${text.slice(0, 200)}`),\n );\n }\n } catch (err) {\n // Never let a sink failure crash a real AI call.\n config.onError?.(err);\n }\n },\n };\n}\n","// discordSink — posts a per-call cost embed to a Discord webhook. Secondary sink\n// (upmetricsSink is canonical); handy for repos not wired to Upmetrics or for an\n// at-a-glance spend feed. Plain fetch, no Discord SDK. Errors never propagate.\nimport type { CostSink, Usage } from \"../../types.js\";\n\nexport interface DiscordSinkConfig {\n webhookUrl: string;\n /** Skip posting paid calls below this USD threshold (anti-spam). Subprocess\n * (Max-plan free) calls always post so the \"free\" feed stays visible.\n * Default 0 → post everything. */\n minUsd?: number;\n fetch?: typeof fetch;\n onError?: (err: unknown) => void;\n}\n\nexport function discordSink(config: DiscordSinkConfig): CostSink {\n const doFetch = config.fetch ?? fetch;\n const minUsd = config.minUsd ?? 0;\n\n return {\n async record(usage: Usage): Promise<void> {\n try {\n // Skip cheap PAID calls; always show subprocess (free) calls.\n if (!usage.subprocess && usage.costUsd < minUsd) return;\n\n const costLabel = usage.subprocess\n ? \"Max plan (free)\"\n : `$${usage.costUsd.toFixed(6)}`;\n\n const embed = {\n title: `AI call — ${usage.capability}`,\n fields: [\n { name: \"Provider\", value: usage.provider, inline: true },\n { name: \"Model\", value: usage.model, inline: true },\n { name: \"Transport\", value: usage.transport, inline: true },\n { name: \"Cost\", value: costLabel, inline: true },\n {\n name: \"Tokens\",\n value: `${usage.inputTokens} in / ${usage.outputTokens} out`,\n inline: true,\n },\n { name: \"Latency\", value: `${usage.latencyMs} ms`, inline: true },\n ],\n timestamp: usage.ts || new Date().toISOString(),\n };\n\n const res = await doFetch(config.webhookUrl, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ embeds: [embed] }),\n });\n if (!res.ok) {\n config.onError?.(new Error(`discordSink: webhook returned ${res.status}`));\n }\n } catch (err) {\n config.onError?.(err);\n }\n },\n };\n}\n","// sqliteSink — persists every Usage to a local bun:sqlite DB. Secondary/offline\n// sink (upmetricsSink is canonical). No npm dependency — bun:sqlite is built in.\n//\n// IMPORTANT: bun:sqlite is imported LAZILY (dynamic import on first use), not at\n// module top level. A static `import \"bun:sqlite\"` would leak into the package\n// entry and crash every Node consumer (`ERR_UNSUPPORTED_ESM_URL_SCHEME`). With\n// the lazy import, importing @broberg/ai-sdk works everywhere; bun:sqlite only\n// loads when sqliteSink/getCostSummary actually run (Bun only).\nimport type { CostSink, Usage } from \"../../types.js\";\n\nexport interface SqliteSinkConfig {\n /** Path to the SQLite file, e.g. \"./ai-cost.db\" (or \":memory:\"). */\n dbPath: string;\n}\n\nconst CREATE_TABLE = `\nCREATE TABLE IF NOT EXISTS ai_usage (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n ts TEXT NOT NULL,\n provider TEXT NOT NULL,\n model TEXT NOT NULL,\n tier TEXT,\n transport TEXT NOT NULL,\n capability TEXT NOT NULL,\n purpose TEXT,\n input_tokens INTEGER NOT NULL,\n output_tokens INTEGER NOT NULL,\n cache_read_tokens INTEGER NOT NULL,\n cache_creation_tokens INTEGER NOT NULL,\n cost_usd REAL NOT NULL,\n latency_ms INTEGER NOT NULL,\n subprocess INTEGER NOT NULL DEFAULT 0\n)`;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nasync function openDb(dbPath: string, readonly = false): Promise<any> {\n const { Database } = await import(\"bun:sqlite\");\n return new Database(dbPath, readonly ? { readonly: true } : undefined);\n}\n\nexport function sqliteSink(config: SqliteSinkConfig): CostSink {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let ready: Promise<any> | null = null;\n const init = async () => {\n const db = await openDb(config.dbPath);\n db.run(CREATE_TABLE);\n const insert = db.prepare(\n `INSERT INTO ai_usage\n (ts, provider, model, tier, transport, capability, purpose,\n input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens,\n cost_usd, latency_ms, subprocess)\n VALUES ($ts, $provider, $model, $tier, $transport, $capability, $purpose,\n $input, $output, $cacheRead, $cacheCreation, $cost, $latency, $subprocess)`,\n );\n return insert;\n };\n\n return {\n async record(usage: Usage): Promise<void> {\n const insert = await (ready ??= init());\n insert.run({\n $ts: usage.ts || new Date().toISOString(),\n $provider: usage.provider,\n $model: usage.model,\n $tier: usage.tier ?? null,\n $transport: usage.transport,\n $capability: usage.capability,\n $purpose: usage.purpose ?? null,\n $input: usage.inputTokens,\n $output: usage.outputTokens,\n $cacheRead: usage.cacheReadTokens,\n $cacheCreation: usage.cacheCreationTokens,\n $cost: usage.costUsd,\n $latency: usage.latencyMs,\n $subprocess: usage.subprocess ? 1 : 0,\n });\n },\n };\n}\n\nexport interface CostSummary {\n totalUsd: number;\n byProvider: Record<string, number>;\n byCapability: Record<string, number>;\n}\n\n/** Aggregate the recorded spend from a sqliteSink DB. Creates the table if the\n * DB has never been written to, so an empty DB summarises cleanly to 0. */\nexport async function getCostSummary(dbPath: string): Promise<CostSummary> {\n const db = await openDb(dbPath);\n db.run(CREATE_TABLE);\n const total = db\n .query(`SELECT SUM(cost_usd) AS total FROM ai_usage`)\n .get() as { total: number | null };\n const byProvider: Record<string, number> = {};\n for (const row of db\n .query(`SELECT provider, SUM(cost_usd) AS sum FROM ai_usage GROUP BY provider`)\n .all() as { provider: string; sum: number }[]) {\n byProvider[row.provider] = row.sum;\n }\n const byCapability: Record<string, number> = {};\n for (const row of db\n .query(`SELECT capability, SUM(cost_usd) AS sum FROM ai_usage GROUP BY capability`)\n .all() as { capability: string; sum: number }[]) {\n byCapability[row.capability] = row.sum;\n }\n return { totalUsd: total?.total ?? 0, byProvider, byCapability };\n}\n"],"mappings":"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","names":["res"]}
|
|
1
|
+
{"version":3,"sources":["../src/routing/tier-map.ts","../src/transport/http.ts","../src/transport/subprocess.ts","../src/transport/stream.ts","../src/providers/tools.ts","../src/cost/pricing.ts","../src/cost/usage.ts","../src/providers/anthropic.ts","../src/providers/openai-compatible.ts","../src/providers/openai.ts","../src/providers/gemini.ts","../src/providers/deepinfra.ts","../src/providers/openrouter.ts","../src/providers/fal.ts","../src/providers/registry.ts","../src/cost/budget.ts","../src/capabilities/vision.ts","../src/capabilities/translate.ts","../src/capabilities/embedding.ts","../src/capabilities/transcribe.ts","../src/capabilities/contracts/index.ts","../src/schema/inputs.ts","../src/client.ts","../src/providers/stub.ts","../src/version.ts","../src/cost/budget-store.ts","../src/cost/sinks/noop.ts","../src/cost/sinks/multi.ts","../src/cost/sinks/upmetrics.ts","../src/cost/sinks/discord.ts","../src/cost/sinks/sqlite.ts"],"sourcesContent":["// Tier routing: a named Tier resolves to a concrete (provider, model, transport).\n// Precedence is per-call override > client config map > built-in defaults.\nimport type { Tier, TierSpec } from \"../types.js\";\n\n/** Built-in defaults. Every entry is overridable via AiConfig.defaults or a\n * per-call override. Model IDs are current at scaffold time; callers pin their\n * own via config. `cheap` routes through the local `claude -p` subprocess\n * (Max plan → costUsd 0); everything else is HTTP. */\nexport const DEFAULT_TIER_MAP: Record<Tier, TierSpec> = {\n fast: { provider: \"anthropic\", model: \"claude-haiku-4-5\", transport: \"http\" },\n smart: { provider: \"anthropic\", model: \"claude-sonnet-4-6\", transport: \"http\" },\n powerful: { provider: \"anthropic\", model: \"claude-opus-4-8\", transport: \"http\" },\n cheap: { provider: \"anthropic\", model: \"claude-haiku-4-5\", transport: \"subprocess\" },\n vision: { provider: \"anthropic\", model: \"claude-sonnet-4-6\", transport: \"http\" },\n embedding: { provider: \"openai\", model: \"text-embedding-3-small\", transport: \"http\" },\n};\n\n/**\n * Resolve a Tier to a concrete TierSpec.\n *\n * Merge order (later wins): DEFAULT_TIER_MAP < configMap < override.\n * - `configMap` is the client-level AiConfig.defaults (per-tier full specs).\n * - `override` is a per-call Partial<TierSpec> — only the fields it sets win.\n */\nexport function resolveTier(\n tier: Tier,\n override?: Partial<TierSpec>,\n configMap?: Partial<Record<Tier, TierSpec>>,\n): TierSpec {\n const base = configMap?.[tier] ?? DEFAULT_TIER_MAP[tier];\n return { ...base, ...override };\n}\n","// HTTP transport: a thin fetch wrapper. Provider-agnostic — the adapter supplies\n// the fully-built url/headers/body and parses the returned json itself.\nimport type { TransportRequest, HttpResponse } from \"./types.js\";\n\nexport async function httpTransport(req: TransportRequest): Promise<HttpResponse> {\n if (!req.http) {\n throw new Error(\"httpTransport: req.http is required for http transport\");\n }\n const { url, method = \"POST\", headers, body } = req.http;\n const res = await fetch(url, {\n method,\n headers,\n body:\n body === undefined\n ? undefined\n : typeof body === \"string\"\n ? body\n : JSON.stringify(body),\n });\n const json: unknown = await res.json().catch(() => undefined);\n return { ok: res.ok, status: res.status, json };\n}\n","// Subprocess transport: runs the local `claude -p` CLI (Anthropic Max plan).\n// No API key, no metered charge — costUsd is always 0, flagged subprocess:true so\n// dashboards can split free (Max) from paid (API). Token counts still come back\n// from the CLI's JSON so usage is tracked even when cost is zero.\nimport type { TransportRequest, SubprocessResponse } from \"./types.js\";\n\n/** The subset of `claude -p --output-format json` output we read. The CLI emits\n * more fields; we only need the result text + token usage. */\ninterface ClaudeCliJson {\n result?: string;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n };\n}\n\n/** Pure parser for the `claude -p --output-format json` stdout. Exported so it\n * can be unit-tested without spawning the binary. costUsd is pinned to 0. */\nexport function parseClaudeCliJson(raw: string): SubprocessResponse {\n let parsed: ClaudeCliJson;\n try {\n parsed = JSON.parse(raw) as ClaudeCliJson;\n } catch {\n throw new Error(\n `subprocessTransport: could not parse claude -p JSON output: ${raw.slice(0, 200)}`,\n );\n }\n const u = parsed.usage ?? {};\n return {\n text: parsed.result ?? \"\",\n inputTokens: u.input_tokens ?? 0,\n outputTokens: u.output_tokens ?? 0,\n cacheReadTokens: u.cache_read_input_tokens ?? 0,\n cacheCreationTokens: u.cache_creation_input_tokens ?? 0,\n costUsd: 0,\n subprocess: true,\n };\n}\n\nexport async function subprocessTransport(\n req: TransportRequest,\n): Promise<SubprocessResponse> {\n if (!req.subprocess) {\n throw new Error(\"subprocessTransport: req.subprocess is required for subprocess transport\");\n }\n const { prompt, systemPrompt } = req.subprocess;\n\n const cmd = [\"claude\", \"-p\", \"--output-format\", \"json\", \"--model\", req.spec.model];\n if (systemPrompt) cmd.push(\"--system-prompt\", systemPrompt);\n\n // Prompt goes in on stdin as a Blob (no argv length limit, no manual FileSink).\n const proc = (() => {\n try {\n return Bun.spawn(cmd, {\n stdin: new Blob([prompt]),\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n } catch (err) {\n throw new Error(\n `subprocessTransport: failed to spawn 'claude' — is the CLI installed and on PATH? (${String(err)})`,\n );\n }\n })();\n\n const [stdout, stderr, exitCode] = await Promise.all([\n new Response(proc.stdout).text(),\n new Response(proc.stderr).text(),\n proc.exited,\n ]);\n\n if (exitCode !== 0) {\n throw new Error(\n `subprocessTransport: claude -p exited ${exitCode}: ${stderr.slice(0, 300) || stdout.slice(0, 300)}`,\n );\n }\n\n return parseClaudeCliJson(stdout);\n}\n","// SSE streaming transport (F8.1). Like httpTransport but yields the parsed\n// `data:` payloads from the response body instead of awaiting .json() — pure\n// fetch + a ReadableStream reader, so it is Node 18+ and Bun safe. The adapter\n// supplies the `stream:true` body and parses each yielded JSON string itself.\nimport type { TransportRequest } from \"./types.js\";\n\n/** HTTP error from a streaming connect — carries `status` so the client's\n * pre-stream fallback can tell an eligible 429/5xx from a hard 4xx. */\nexport class StreamHttpError extends Error {\n readonly status: number;\n constructor(message: string, status: number) {\n super(message);\n this.name = \"StreamHttpError\";\n this.status = status;\n }\n}\n\nexport interface StreamTransportRequest extends TransportRequest {\n /** Injectable fetch for tests. */\n fetch?: typeof fetch;\n}\n\n/**\n * Open an SSE stream and yield each event's `data:` payload as a raw string\n * (the JSON after `data: `), skipping the `[DONE]` terminator and non-data\n * lines. Throws StreamHttpError before the first yield on a non-2xx connect.\n */\nexport async function* streamTransport(req: StreamTransportRequest): AsyncIterable<string> {\n if (!req.http) throw new Error(\"streamTransport: req.http is required for http transport\");\n const { url, method = \"POST\", headers, body } = req.http;\n const fetchImpl = req.fetch ?? fetch;\n const res = await fetchImpl(url, {\n method,\n headers,\n body:\n body === undefined\n ? undefined\n : typeof body === \"string\"\n ? body\n : JSON.stringify(body),\n });\n if (!res.ok || !res.body) {\n const text = await res.text().catch(() => \"\");\n throw new StreamHttpError(`stream ${res.status}: ${text.slice(0, 300)}`, res.status);\n }\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n try {\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n // OpenAI/Anthropic emit one `data: {json}\\n\\n` per event — parse per line.\n let nl: number;\n while ((nl = buffer.indexOf(\"\\n\")) >= 0) {\n const line = buffer.slice(0, nl).replace(/\\r$/, \"\");\n buffer = buffer.slice(nl + 1);\n if (!line.startsWith(\"data:\")) continue; // skip comments / event: / id:\n const data = line.slice(5).trim();\n if (data === \"[DONE]\") return;\n if (data) yield data;\n }\n }\n } finally {\n reader.releaseLock();\n }\n}\n","// Cross-provider tool/function-calling normalization. The SDK speaks one Tool /\n// ToolCall shape; each provider has its own. toProviderTools builds the request\n// tools array; fromProviderToolCall parses one tool-call out of a response.\n// OpenAI, DeepInfra and OpenRouter share the OpenAI-compatible format.\nimport type { Tool, ToolCall } from \"../types.js\";\n\ntype ToolProvider = \"openai\" | \"deepinfra\" | \"openrouter\" | \"gemini\" | \"anthropic\";\n\nfunction family(provider: string): ToolProvider {\n if (provider === \"gemini\" || provider === \"google\") return \"gemini\";\n if (provider === \"anthropic\") return \"anthropic\";\n // openai, deepinfra, openrouter — all OpenAI-compatible\n return \"openai\";\n}\n\n/** Convert SDK tools to a provider's request format. */\nexport function toProviderTools(tools: Tool[], provider: string): unknown {\n switch (family(provider)) {\n case \"openai\":\n return tools.map((t) => ({\n type: \"function\",\n function: { name: t.name, description: t.description, parameters: t.parameters },\n }));\n case \"gemini\":\n return [\n {\n functionDeclarations: tools.map((t) => ({\n name: t.name,\n description: t.description,\n parameters: t.parameters,\n })),\n },\n ];\n case \"anthropic\":\n return tools.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: t.parameters,\n }));\n default:\n throw new Error(`toProviderTools: unsupported provider family for \"${provider}\"`);\n }\n}\n\n/** Parse a single provider-shaped tool call back into the SDK ToolCall shape. */\nexport function fromProviderToolCall(raw: unknown, provider: string): ToolCall {\n const r = raw as Record<string, unknown>;\n switch (family(provider)) {\n case \"openai\": {\n // { id, type:\"function\", function:{ name, arguments:\"<json>\" } }\n const fn = (r.function ?? {}) as { name?: string; arguments?: string };\n return {\n id: typeof r.id === \"string\" ? r.id : \"\",\n name: fn.name ?? \"\",\n arguments: parseArgs(fn.arguments),\n };\n }\n case \"gemini\": {\n // { functionCall:{ name, args } } or { name, args }\n const fc = (r.functionCall ?? r) as { name?: string; args?: unknown };\n return {\n id: \"\", // Gemini function calls have no id\n name: fc.name ?? \"\",\n arguments: (fc.args as Record<string, unknown>) ?? {},\n };\n }\n case \"anthropic\": {\n // { type:\"tool_use\", id, name, input }\n return {\n id: typeof r.id === \"string\" ? r.id : \"\",\n name: typeof r.name === \"string\" ? r.name : \"\",\n arguments: (r.input as Record<string, unknown>) ?? {},\n };\n }\n default:\n throw new Error(`fromProviderToolCall: unsupported provider family for \"${provider}\"`);\n }\n}\n\nfunction parseArgs(raw: unknown): Record<string, unknown> {\n if (raw === undefined || raw === null) return {};\n if (typeof raw === \"object\") return raw as Record<string, unknown>;\n if (typeof raw === \"string\") {\n try {\n return JSON.parse(raw) as Record<string, unknown>;\n } catch {\n return {};\n }\n }\n return {};\n}\n","// Versioned per-(provider, model) pricing. F3.6 populates the table + adds tests\n// + MiniMax coverage. F3.1 ships the type + lookup with an empty table, so\n// computeCost returns 0 for every model until F3.6 lands (calls still complete).\nexport interface PricingEntry {\n /** USD per 1M input tokens. */\n inputPer1M: number;\n /** USD per 1M output tokens. */\n outputPer1M: number;\n /** USD per 1M cache-read tokens (falls back to input rate if unset). */\n cacheReadPer1M?: number;\n /** USD per 1M cache-write/creation tokens (falls back to input rate if unset). */\n cacheWritePer1M?: number;\n /** Pricing snapshot version (date or tag) so stale entries are detectable. */\n version: string;\n}\n\n// USD per 1M tokens. Anthropic cache multipliers follow the standard model:\n// cache-read ≈ 0.1× input, cache-write ≈ 1.25× input. Verified against the\n// pricing tables in cms (packages/cms-ai/src/providers) + trail (model-lab).\n// MiniMax M2.7 is an estimate pending confirmation against OpenRouter's live\n// price page — flagged in its version string.\nconst V = \"2026-06-02\";\n\n/** Keyed `${provider}:${model}`. */\nconst PRICING: Record<string, PricingEntry> = {\n // Anthropic (direct API). DEFAULT_TIER_MAP: fast/cheap=haiku, smart/vision=sonnet, powerful=opus.\n \"anthropic:claude-haiku-4-5\": {\n inputPer1M: 0.8,\n outputPer1M: 4.0,\n cacheReadPer1M: 0.08,\n cacheWritePer1M: 1.0,\n version: V,\n },\n \"anthropic:claude-sonnet-4-6\": {\n inputPer1M: 3.0,\n outputPer1M: 15.0,\n cacheReadPer1M: 0.3,\n cacheWritePer1M: 3.75,\n version: V,\n },\n \"anthropic:claude-opus-4-8\": {\n inputPer1M: 15.0,\n outputPer1M: 75.0,\n cacheReadPer1M: 1.5,\n cacheWritePer1M: 18.75,\n version: V,\n },\n\n // OpenAI. embedding default tier = text-embedding-3-small (no output tokens).\n \"openai:text-embedding-3-small\": { inputPer1M: 0.02, outputPer1M: 0, version: V },\n \"openai:text-embedding-3-large\": { inputPer1M: 0.13, outputPer1M: 0, version: V },\n \"openai:gpt-4o\": { inputPer1M: 2.5, outputPer1M: 10.0, version: V },\n \"openai:gpt-4o-mini\": { inputPer1M: 0.15, outputPer1M: 0.6, version: V },\n // Whisper is priced per minute, not per token — not representable here; transcribe\n // (F5.6) computes its own cost. Listed as 0 so token-based compute never charges it.\n \"openai:whisper-1\": { inputPer1M: 0, outputPer1M: 0, version: V },\n\n // OpenRouter (meta-router — model slugs include the upstream vendor).\n \"openrouter:anthropic/claude-sonnet-4-6\": { inputPer1M: 3.0, outputPer1M: 15.0, version: V },\n \"openrouter:anthropic/claude-haiku-4-5\": { inputPer1M: 0.8, outputPer1M: 4.0, version: V },\n \"openrouter:google/gemini-2.5-flash\": { inputPer1M: 0.3, outputPer1M: 2.5, version: V },\n \"openrouter:minimax/minimax-m2.7\": {\n inputPer1M: 0.3,\n outputPer1M: 1.2,\n version: `${V}-estimate`,\n },\n\n // Google Gemini (direct). Image-gen model used by cms.\n \"google:gemini-2.5-flash\": { inputPer1M: 0.3, outputPer1M: 2.5, version: V },\n};\n\nexport function getPrice(provider: string, model: string): PricingEntry | undefined {\n const exact = PRICING[`${provider}:${model}`];\n if (exact) return exact;\n // Providers ship dated model snapshots, e.g. \"claude-haiku-4-5-20251001\".\n // Strip a trailing -YYYYMMDD and retry the base lookup so a dated variant\n // prices the same as its base model instead of falling through to 0 — a real\n // paid call must never be logged as $0 (F012). Covers openrouter slugs too.\n const base = model.replace(/-\\d{8}$/, \"\");\n if (base !== model) return PRICING[`${provider}:${base}`];\n return undefined;\n}\n","// Usage construction + cost computation. Real adapters (F4) build their Usage via\n// freshUsage() and fill costUsd from computeCost(). The pricing table lives in\n// ./pricing.ts (F3.6); until a model is priced, computeCost returns 0 so calls\n// still complete (cost just shows $0 rather than throwing).\nimport { getPrice } from \"./pricing.js\";\nimport type { Usage, Transport, Capability } from \"../types.js\";\n\n/**\n * Cost in USD for a call. cache-read/creation tokens are priced separately when\n * the pricing entry defines rates for them; otherwise they fall back to the\n * input rate (read) / are ignored (creation). Unknown model → 0.\n */\nexport function computeCost(\n provider: string,\n model: string,\n inputTokens: number,\n outputTokens: number,\n cacheReadTokens = 0,\n cacheCreationTokens = 0,\n): number {\n const price = getPrice(provider, model);\n if (!price) return 0;\n const perToken = (per1M: number) => per1M / 1_000_000;\n const inRate = perToken(price.inputPer1M);\n const outRate = perToken(price.outputPer1M);\n const cacheReadRate =\n price.cacheReadPer1M !== undefined ? perToken(price.cacheReadPer1M) : inRate;\n const cacheWriteRate =\n price.cacheWritePer1M !== undefined ? perToken(price.cacheWritePer1M) : inRate;\n return (\n inputTokens * inRate +\n outputTokens * outRate +\n cacheReadTokens * cacheReadRate +\n cacheCreationTokens * cacheWriteRate\n );\n}\n\n/** Build a Usage with cost computed from the pricing table. Adapters call this\n * after a successful provider call; latencyMs/ts/capability are stamped by the\n * client (call-context owner), so they default to 0/\"\"/the passed capability. */\nexport function freshUsage(args: {\n provider: string;\n model: string;\n transport: Transport;\n capability: Capability;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens?: number;\n cacheCreationTokens?: number;\n subprocess?: boolean;\n}): Usage {\n const cacheReadTokens = args.cacheReadTokens ?? 0;\n const cacheCreationTokens = args.cacheCreationTokens ?? 0;\n // Subprocess (Max plan) is never a metered charge to us — cost is always 0.\n const costUsd = args.subprocess\n ? 0\n : computeCost(\n args.provider,\n args.model,\n args.inputTokens,\n args.outputTokens,\n cacheReadTokens,\n cacheCreationTokens,\n );\n const usage: Usage = {\n provider: args.provider,\n model: args.model,\n transport: args.transport,\n inputTokens: args.inputTokens,\n outputTokens: args.outputTokens,\n cacheReadTokens,\n cacheCreationTokens,\n costUsd,\n latencyMs: 0,\n capability: args.capability,\n ts: \"\",\n };\n if (args.subprocess) usage.subprocess = true;\n return usage;\n}\n","// Anthropic adapter (F4.6) — the real one (F2.5 shipped only a stub). Two\n// transports: http (api.anthropic.com/v1/messages) and subprocess (claude -p,\n// Max plan, costUsd 0). Critical for the xrt81 vision pilot. Tools normalized\n// via F4.5. No @anthropic-ai/sdk package — plain fetch through httpTransport.\nimport { httpTransport } from \"../transport/http.js\";\nimport { subprocessTransport } from \"../transport/subprocess.js\";\nimport { streamTransport } from \"../transport/stream.js\";\nimport { toProviderTools, fromProviderToolCall } from \"./tools.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ChatStreamEvent,\n Message,\n ContentPart,\n ToolCall,\n} from \"../types.js\";\n\ninterface AnthropicBlock {\n type: string;\n text?: string;\n id?: string;\n name?: string;\n input?: Record<string, unknown>;\n}\ninterface AnthropicResponse {\n content?: AnthropicBlock[];\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n error?: unknown;\n}\n\nfunction contentBlocks(content: string | ContentPart[]): unknown {\n if (typeof content === \"string\") return content;\n return content.map((p) => {\n if (p.type === \"text\") return { type: \"text\", text: p.text };\n if (typeof p.image === \"string\" && /^https?:\\/\\//.test(p.image)) {\n return { type: \"image\", source: { type: \"url\", url: p.image } };\n }\n const data =\n typeof p.image === \"string\"\n ? p.image.replace(/^data:[^;]+;base64,/, \"\")\n : Buffer.from(p.image).toString(\"base64\");\n return {\n type: \"image\",\n source: { type: \"base64\", media_type: p.mimeType ?? \"image/png\", data },\n };\n });\n}\n\n/** Flatten messages to a single prompt for the subprocess (claude -p) path. */\nfunction flattenForSubprocess(messages: Message[]): { prompt: string; system?: string } {\n const sys: string[] = [];\n const turns: string[] = [];\n for (const m of messages) {\n const text =\n typeof m.content === \"string\"\n ? m.content\n : m.content.map((p) => (p.type === \"text\" ? p.text : \"[image]\")).join(\" \");\n if (m.role === \"system\") sys.push(text);\n else turns.push(`${m.role}: ${text}`);\n }\n return { prompt: turns.join(\"\\n\\n\"), system: sys.length ? sys.join(\"\\n\") : undefined };\n}\n\nexport function anthropicAdapter(\n config: { apiKey?: string; baseUrl?: string; anthropicVersion?: string; fetch?: typeof fetch } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://api.anthropic.com\";\n const version = config.anthropicVersion ?? \"2023-06-01\";\n\n /** Build the /v1/messages body (shared by the http + stream paths). */\n function buildBody(req: ChatRequest): Record<string, unknown> {\n const system: string[] = [];\n const messages: { role: string; content: unknown }[] = [];\n for (const m of req.messages as Message[]) {\n if (m.role === \"system\") {\n system.push(typeof m.content === \"string\" ? m.content : \"\");\n continue;\n }\n // tool-result turn → a user message carrying a tool_result block (F8.7).\n if (m.role === \"tool\") {\n messages.push({\n role: \"user\",\n content: [\n {\n type: \"tool_result\",\n tool_use_id: m.toolCallId ?? \"\",\n content: typeof m.content === \"string\" ? m.content : \"\",\n },\n ],\n });\n continue;\n }\n // assistant turn that called tools → text blocks + tool_use blocks (F8.7).\n if (m.role === \"assistant\" && m.toolCalls && m.toolCalls.length > 0) {\n const blocks: unknown[] = [];\n if (typeof m.content === \"string\") {\n if (m.content.length > 0) blocks.push({ type: \"text\", text: m.content });\n } else {\n blocks.push(...(contentBlocks(m.content) as unknown[]));\n }\n for (const tc of m.toolCalls) {\n blocks.push({ type: \"tool_use\", id: tc.id, name: tc.name, input: tc.arguments });\n }\n messages.push({ role: \"assistant\", content: blocks });\n continue;\n }\n messages.push({ role: m.role === \"assistant\" ? \"assistant\" : \"user\", content: contentBlocks(m.content) });\n }\n const body: Record<string, unknown> = {\n model: req.spec.model,\n max_tokens: req.maxTokens ?? 1024, // Anthropic requires max_tokens\n messages,\n };\n if (system.length > 0) body.system = system.join(\"\\n\");\n if (req.tools) body.tools = toProviderTools(req.tools, \"anthropic\");\n if (req.temperature !== undefined) body.temperature = req.temperature;\n return body;\n }\n\n function apiKeyOrThrow(): string {\n const apiKey = config.apiKey ?? process.env.ANTHROPIC_API_KEY;\n if (!apiKey) throw new Error(\"anthropic adapter: API key not set (env ANTHROPIC_API_KEY)\");\n return apiKey;\n }\n\n async function chatHttp(req: ChatRequest): Promise<ChatResult> {\n const apiKey = apiKeyOrThrow();\n const body = buildBody(req);\n\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${baseUrl}/v1/messages`,\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": version,\n },\n body,\n },\n });\n if (!res.ok) throw new Error(`anthropic ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n\n const data = res.json as AnthropicResponse;\n const blocks = data.content ?? [];\n const text = blocks\n .filter((b) => b.type === \"text\" && typeof b.text === \"string\")\n .map((b) => b.text)\n .join(\"\");\n const toolCalls: ToolCall[] = blocks\n .filter((b) => b.type === \"tool_use\")\n .map((b) => fromProviderToolCall(b, \"anthropic\"));\n\n const usage = freshUsage({\n provider: \"anthropic\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: data.usage?.input_tokens ?? 0,\n outputTokens: data.usage?.output_tokens ?? 0,\n cacheReadTokens: data.usage?.cache_read_input_tokens ?? 0,\n cacheCreationTokens: data.usage?.cache_creation_input_tokens ?? 0,\n });\n const result: ChatResult = { text, usage };\n if (toolCalls.length > 0) result.toolCalls = toolCalls;\n return result;\n }\n\n async function chatSubprocess(req: ChatRequest): Promise<ChatResult> {\n const { prompt, system } = flattenForSubprocess(req.messages as Message[]);\n const r = await subprocessTransport({ spec: req.spec, subprocess: { prompt, systemPrompt: system } });\n const usage = freshUsage({\n provider: \"anthropic\",\n model: req.spec.model,\n transport: \"subprocess\",\n capability: \"chat\",\n inputTokens: r.inputTokens,\n outputTokens: r.outputTokens,\n cacheReadTokens: r.cacheReadTokens,\n cacheCreationTokens: r.cacheCreationTokens,\n subprocess: true,\n });\n return { text: r.text, usage };\n }\n\n async function chat(req: ChatRequest): Promise<ChatResult> {\n return req.spec.transport === \"subprocess\" ? chatSubprocess(req) : chatHttp(req);\n }\n\n // Streaming chat (F8.4) over the native /v1/messages SSE. Maps\n // content_block_delta(text_delta) → text events, accumulates tool_use blocks\n // (id/name from content_block_start, input from input_json_delta) → complete\n // tool_call events, and reads usage from message_start + message_delta. Only\n // the http transport streams — `claude -p` subprocess is one-shot.\n async function* chatStream(req: ChatRequest): AsyncIterable<ChatStreamEvent> {\n if (req.spec.transport === \"subprocess\") {\n throw new Error(\"anthropic adapter: streaming is not supported over the subprocess transport\");\n }\n const apiKey = apiKeyOrThrow();\n const body = { ...buildBody(req), stream: true };\n const stream = streamTransport({\n spec: req.spec,\n fetch: config.fetch,\n http: {\n url: `${baseUrl}/v1/messages`,\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": apiKey,\n \"anthropic-version\": version,\n },\n body,\n },\n });\n\n let inputTokens = 0;\n let outputTokens = 0;\n let cacheReadTokens = 0;\n let cacheCreationTokens = 0;\n let stopReason: string | null = null;\n // index → accumulated tool_use block (input_json_delta fragments concatenated).\n const toolBlocks = new Map<number, { id: string; name: string; json: string }>();\n\n for await (const data of stream) {\n let ev: AnthropicStreamEvent;\n try {\n ev = JSON.parse(data) as AnthropicStreamEvent;\n } catch {\n continue;\n }\n switch (ev.type) {\n case \"message_start\": {\n const u = ev.message?.usage;\n inputTokens = u?.input_tokens ?? 0;\n cacheReadTokens = u?.cache_read_input_tokens ?? 0;\n cacheCreationTokens = u?.cache_creation_input_tokens ?? 0;\n break;\n }\n case \"content_block_start\": {\n if (ev.content_block?.type === \"tool_use\" && ev.index !== undefined) {\n toolBlocks.set(ev.index, {\n id: ev.content_block.id ?? \"\",\n name: ev.content_block.name ?? \"\",\n json: \"\",\n });\n }\n break;\n }\n case \"content_block_delta\": {\n const d = ev.delta;\n if (d?.type === \"text_delta\" && d.text) {\n yield { type: \"text\", delta: d.text };\n } else if (d?.type === \"input_json_delta\" && d.partial_json && ev.index !== undefined) {\n const b = toolBlocks.get(ev.index);\n if (b) b.json += d.partial_json;\n }\n break;\n }\n case \"message_delta\": {\n if (ev.delta?.stop_reason) stopReason = ev.delta.stop_reason;\n if (ev.usage?.output_tokens !== undefined) outputTokens = ev.usage.output_tokens;\n break;\n }\n default:\n break; // content_block_stop / message_stop / ping\n }\n }\n\n for (const [, b] of [...toolBlocks.entries()].sort((a, c) => a[0] - c[0])) {\n let args: Record<string, unknown> = {};\n try {\n args = b.json ? (JSON.parse(b.json) as Record<string, unknown>) : {};\n } catch {\n args = {};\n }\n yield { type: \"tool_call\", id: b.id, name: b.name, args };\n }\n const usage = freshUsage({\n provider: \"anthropic\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens,\n outputTokens,\n cacheReadTokens,\n cacheCreationTokens,\n });\n yield { type: \"usage\", costUsd: usage.costUsd, model: usage.model, usage };\n yield { type: \"finish\", reason: mapAnthropicStop(stopReason) };\n }\n\n return { name: \"anthropic\", chat, chatStream, vision: chat };\n}\n\n/** Anthropic Messages SSE event (only the fields we read). */\ninterface AnthropicStreamEvent {\n type: string;\n index?: number;\n message?: {\n usage?: {\n input_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n };\n };\n content_block?: { type?: string; id?: string; name?: string };\n delta?: { type?: string; text?: string; partial_json?: string; stop_reason?: string };\n usage?: { output_tokens?: number };\n}\n\n/** Map Anthropic stop_reason → the SDK's ChatStreamEvent finish reason. */\nfunction mapAnthropicStop(reason: string | null): \"end_turn\" | \"tool_calls\" | \"length\" | \"stop\" {\n switch (reason) {\n case \"tool_use\":\n return \"tool_calls\";\n case \"max_tokens\":\n return \"length\";\n case \"stop_sequence\":\n return \"stop\";\n default:\n return \"end_turn\";\n }\n}\n","// Shared core for OpenAI-compatible chat APIs. OpenAI (F4.1), DeepInfra (F4.3)\n// and OpenRouter (F4.4) all speak this wire format — only base URL, key and a\n// couple of headers differ. The adapter uses httpTransport (F2.4) for the wire\n// I/O and the F4.5 tool contract for tool round-tripping.\nimport { httpTransport } from \"../transport/http.js\";\nimport { streamTransport } from \"../transport/stream.js\";\nimport { toProviderTools, fromProviderToolCall } from \"./tools.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ChatStreamEvent,\n Message,\n ToolCall,\n} from \"../types.js\";\n\nexport interface OpenAICompatibleConfig {\n /** Provider name recorded on Usage (e.g. \"openai\", \"deepinfra\", \"openrouter\"). */\n name: string;\n /** Chat completions base, e.g. \"https://api.openai.com/v1\". */\n baseUrl: string;\n /** Resolved at call time if omitted (env var per provider). */\n apiKey?: string;\n /** Extra headers (e.g. OpenRouter's HTTP-Referer / X-Title). */\n extraHeaders?: Record<string, string>;\n /** Injectable fetch for the streaming path (tests). */\n fetch?: typeof fetch;\n /** OpenRouter ground-truth cost (F010): send `usage:{include:true}` and use the\n * response's `usage.cost` (USD) as costUsd, falling back to the pricing table.\n * Only OpenRouter returns this field — openai/deepinfra leave it false. */\n costFromResponseField?: boolean;\n}\n\ninterface OAToolCall {\n id?: string;\n function?: { name?: string; arguments?: string };\n}\ninterface OAResponse {\n choices?: { message?: { content?: string | null; tool_calls?: OAToolCall[] } }[];\n usage?: { prompt_tokens?: number; completion_tokens?: number; cost?: number };\n error?: unknown;\n}\n\n/** SDK message → OpenAI message (string content, or multimodal parts for vision).\n * Threads the normalized tool form to the wire: a `tool`-role message's\n * `toolCallId` → `tool_call_id`, and an assistant message's `toolCalls` →\n * `tool_calls:[{id,type:'function',function:{name,arguments}}]` (F8.3) so a\n * multi-turn tool conversation round-trips. Exported for serialization tests. */\nexport function toOpenAIMessage(m: Message): Record<string, unknown> {\n if (typeof m.content === \"string\") {\n const base: Record<string, unknown> = { role: m.role, content: m.content };\n if (m.toolCallId) base.tool_call_id = m.toolCallId;\n if (m.toolCalls && m.toolCalls.length > 0) {\n base.tool_calls = m.toolCalls.map((tc) => ({\n id: tc.id,\n type: \"function\",\n function: { name: tc.name, arguments: JSON.stringify(tc.arguments) },\n }));\n }\n return base;\n }\n const content = m.content.map((p) => {\n if (p.type === \"text\") return { type: \"text\", text: p.text };\n const url =\n typeof p.image === \"string\"\n ? p.image\n : `data:${p.mimeType ?? \"image/png\"};base64,${Buffer.from(p.image).toString(\"base64\")}`;\n return { type: \"image_url\", image_url: { url } };\n });\n return { role: m.role, content };\n}\n\nexport function makeOpenAICompatibleAdapter(config: OpenAICompatibleConfig): ProviderAdapter {\n async function chat(req: ChatRequest): Promise<ChatResult> {\n const apiKey = config.apiKey ?? process.env[`${config.name.toUpperCase()}_API_KEY`];\n if (!apiKey) {\n throw new Error(`${config.name} adapter: API key not set (env ${config.name.toUpperCase()}_API_KEY)`);\n }\n const body: Record<string, unknown> = {\n model: req.spec.model,\n messages: req.messages.map(toOpenAIMessage),\n };\n if (req.tools) body.tools = toProviderTools(req.tools, \"openai\");\n if (req.maxTokens !== undefined) body.max_tokens = req.maxTokens;\n if (req.temperature !== undefined) body.temperature = req.temperature;\n if (req.responseFormat === \"json\") body.response_format = { type: \"json_object\" };\n if (config.costFromResponseField) body.usage = { include: true };\n\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${config.baseUrl}/chat/completions`,\n headers: {\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n ...config.extraHeaders,\n },\n body,\n },\n });\n if (!res.ok) {\n throw new Error(`${config.name} ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n }\n const data = res.json as OAResponse;\n const msg = data.choices?.[0]?.message;\n const text = msg?.content ?? \"\";\n const toolCalls: ToolCall[] | undefined = msg?.tool_calls?.map((tc) =>\n fromProviderToolCall(tc, \"openai\"),\n );\n const usage = freshUsage({\n provider: config.name,\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: data.usage?.prompt_tokens ?? 0,\n outputTokens: data.usage?.completion_tokens ?? 0,\n });\n if (config.costFromResponseField && typeof data.usage?.cost === \"number\") {\n usage.costUsd = data.usage.cost; // OpenRouter ground-truth beats the estimate\n }\n const result: ChatResult = { text, usage };\n if (toolCalls && toolCalls.length > 0) result.toolCalls = toolCalls;\n return result;\n }\n\n // Streaming chat (F8.2). Parses the OpenAI chat.completions SSE: content\n // deltas → text events, tool_calls deltas accumulated (index-keyed, arguments\n // string concatenated) → complete tool_call events at end, the include_usage\n // chunk → a usage event, finish_reason → the terminal finish (emitted last so\n // tool_calls + usage precede it).\n async function* chatStream(req: ChatRequest): AsyncIterable<ChatStreamEvent> {\n const apiKey = config.apiKey ?? process.env[`${config.name.toUpperCase()}_API_KEY`];\n if (!apiKey) {\n throw new Error(`${config.name} adapter: API key not set (env ${config.name.toUpperCase()}_API_KEY)`);\n }\n const body: Record<string, unknown> = {\n model: req.spec.model,\n messages: req.messages.map(toOpenAIMessage),\n stream: true,\n stream_options: { include_usage: true },\n };\n if (req.tools) body.tools = toProviderTools(req.tools, \"openai\");\n if (req.maxTokens !== undefined) body.max_tokens = req.maxTokens;\n if (req.temperature !== undefined) body.temperature = req.temperature;\n if (req.responseFormat === \"json\") body.response_format = { type: \"json_object\" };\n if (config.costFromResponseField) body.usage = { include: true };\n\n const stream = streamTransport({\n spec: req.spec,\n fetch: config.fetch,\n http: {\n url: `${config.baseUrl}/chat/completions`,\n headers: {\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n ...config.extraHeaders,\n },\n body,\n },\n });\n\n // index → accumulated tool call (id/name set once, arguments concatenated).\n const toolAcc = new Map<number, { id: string; name: string; args: string }>();\n let finishReason: string | null = null;\n\n for await (const data of stream) {\n let chunk: OAStreamChunk;\n try {\n chunk = JSON.parse(data) as OAStreamChunk;\n } catch {\n continue; // ignore unparseable keep-alive noise\n }\n const choice = chunk.choices?.[0];\n if (choice) {\n const delta = choice.delta ?? {};\n if (typeof delta.content === \"string\" && delta.content.length > 0) {\n yield { type: \"text\", delta: delta.content };\n }\n for (const tc of delta.tool_calls ?? []) {\n const idx = tc.index ?? 0;\n const cur = toolAcc.get(idx) ?? { id: \"\", name: \"\", args: \"\" };\n if (tc.id) cur.id = tc.id;\n if (tc.function?.name) cur.name = tc.function.name;\n if (tc.function?.arguments) cur.args += tc.function.arguments;\n toolAcc.set(idx, cur);\n }\n if (choice.finish_reason) finishReason = choice.finish_reason;\n }\n if (chunk.usage) {\n const usage = freshUsage({\n provider: config.name,\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: chunk.usage.prompt_tokens ?? 0,\n outputTokens: chunk.usage.completion_tokens ?? 0,\n });\n if (config.costFromResponseField && typeof chunk.usage.cost === \"number\") {\n usage.costUsd = chunk.usage.cost; // OpenRouter ground-truth\n }\n yield { type: \"usage\", costUsd: usage.costUsd, model: usage.model, usage };\n }\n }\n\n // Flush accumulated tool calls (complete), then the terminal finish.\n for (const [, t] of [...toolAcc.entries()].sort((a, b) => a[0] - b[0])) {\n let args: Record<string, unknown> = {};\n try {\n args = t.args ? (JSON.parse(t.args) as Record<string, unknown>) : {};\n } catch {\n args = {};\n }\n yield { type: \"tool_call\", id: t.id, name: t.name, args };\n }\n yield { type: \"finish\", reason: mapFinishReason(finishReason) };\n }\n\n return {\n name: config.name,\n chat,\n chatStream,\n // gpt-4o-class models are multimodal — vision shares the chat path.\n vision: chat,\n };\n}\n\n/** OpenAI streaming chunk shape (only the fields we read). */\ninterface OAStreamChunk {\n choices?: {\n delta?: {\n content?: string | null;\n tool_calls?: { index?: number; id?: string; function?: { name?: string; arguments?: string } }[];\n };\n finish_reason?: string | null;\n }[];\n usage?: { prompt_tokens?: number; completion_tokens?: number; cost?: number };\n}\n\n/** Map OpenAI finish_reason → the SDK's ChatStreamEvent finish reason. */\nfunction mapFinishReason(reason: string | null): \"end_turn\" | \"tool_calls\" | \"length\" | \"stop\" {\n switch (reason) {\n case \"tool_calls\":\n return \"tool_calls\";\n case \"length\":\n return \"length\";\n case \"stop\":\n return \"stop\";\n default:\n return \"end_turn\";\n }\n}\n","// OpenAI adapter (F4.1 chat/vision + F5.4 embedding). Chat/vision come from the\n// shared OpenAI-compatible core; embedding uses the /embeddings endpoint. No\n// openai npm package — plain fetch through httpTransport.\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport { httpTransport } from \"../transport/http.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n EmbeddingRequest,\n EmbeddingResult,\n TranscribeRequest,\n TranscribeResult,\n} from \"../types.js\";\n\n/** Whisper-family per-minute USD prices (audio is not token-priced). */\nconst WHISPER_PRICE_PER_MIN: Record<string, number> = {\n \"whisper-1\": 0.006,\n};\n\nexport function openaiAdapter(\n config: { apiKey?: string; baseUrl?: string; fetch?: typeof fetch } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://api.openai.com/v1\";\n const base = makeOpenAICompatibleAdapter({ name: \"openai\", baseUrl, apiKey: config.apiKey });\n\n async function embedding(req: EmbeddingRequest): Promise<EmbeddingResult> {\n const apiKey = config.apiKey ?? process.env.OPENAI_API_KEY;\n if (!apiKey) throw new Error(\"openai adapter: API key not set (env OPENAI_API_KEY)\");\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${baseUrl}/embeddings`,\n headers: { \"content-type\": \"application/json\", Authorization: `Bearer ${apiKey}` },\n body: { model: req.spec.model, input: req.input },\n },\n });\n if (!res.ok) {\n throw new Error(`openai ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n }\n const data = res.json as {\n data?: { embedding: number[] }[];\n usage?: { prompt_tokens?: number };\n };\n const vectors = (data.data ?? []).map((d) => d.embedding);\n const usage = freshUsage({\n provider: \"openai\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"embedding\",\n inputTokens: data.usage?.prompt_tokens ?? 0,\n outputTokens: 0,\n });\n return { vectors, usage };\n }\n\n async function transcribe(req: TranscribeRequest): Promise<TranscribeResult> {\n const apiKey = config.apiKey ?? process.env.OPENAI_API_KEY;\n if (!apiKey) throw new Error(\"openai adapter: API key not set (env OPENAI_API_KEY)\");\n // Whisper is multipart/form-data — bypass httpTransport (JSON-only). Don't set\n // content-type; fetch adds the multipart boundary.\n const form = new FormData();\n form.append(\"file\", new Blob([req.audio]), \"audio\");\n form.append(\"model\", req.spec.model);\n if (req.language) form.append(\"language\", req.language);\n const fetchImpl = config.fetch ?? fetch;\n const res = await fetchImpl(`${baseUrl}/audio/transcriptions`, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${apiKey}` },\n body: form,\n });\n if (!res.ok) {\n throw new Error(`openai ${res.status}: ${(await res.text().catch(() => \"\")).slice(0, 200)}`);\n }\n const data = (await res.json()) as { text?: string };\n const usage = freshUsage({\n provider: \"openai\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"transcribe\",\n inputTokens: 0,\n outputTokens: 0, // Whisper is per-minute, not token-priced.\n });\n // Per-minute cost when the caller supplies the audio duration (API returns none).\n if (req.durationSec !== undefined) {\n const perMinute = WHISPER_PRICE_PER_MIN[req.spec.model] ?? 0;\n usage.costUsd = (req.durationSec / 60) * perMinute;\n }\n return { text: data.text ?? \"\", usage };\n }\n\n return { ...base, embedding, transcribe };\n}\n","// Google Gemini adapter (F4.2). generateContent REST API; API key in the query\n// param (?key=), not a header. System turns map to systemInstruction; assistant\n// maps to role \"model\". Token counts come from usageMetadata. Tools normalized\n// via F4.5. No @google/generative-ai package — plain fetch through httpTransport.\nimport { httpTransport } from \"../transport/http.js\";\nimport { streamTransport } from \"../transport/stream.js\";\nimport { toProviderTools, fromProviderToolCall } from \"./tools.js\";\nimport { freshUsage } from \"../cost/usage.js\";\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ChatStreamEvent,\n Message,\n ContentPart,\n ToolCall,\n} from \"../types.js\";\n\ninterface GeminiPart {\n text?: string;\n functionCall?: { name: string; args: Record<string, unknown> };\n inlineData?: { mimeType: string; data: string };\n}\ninterface GeminiResponse {\n candidates?: { content?: { parts?: GeminiPart[] } }[];\n usageMetadata?: { promptTokenCount?: number; candidatesTokenCount?: number };\n error?: unknown;\n}\n\nfunction partsFrom(content: string | ContentPart[]): GeminiPart[] {\n if (typeof content === \"string\") return [{ text: content }];\n return content.map((p): GeminiPart => {\n if (p.type === \"text\") return { text: p.text };\n const data =\n typeof p.image === \"string\"\n ? p.image.replace(/^data:[^;]+;base64,/, \"\")\n : Buffer.from(p.image).toString(\"base64\");\n return { inlineData: { mimeType: p.mimeType ?? \"image/png\", data } };\n });\n}\n\nexport function geminiAdapter(\n config: { apiKey?: string; baseUrl?: string; fetch?: typeof fetch } = {},\n): ProviderAdapter {\n const baseUrl = config.baseUrl ?? \"https://generativelanguage.googleapis.com/v1beta\";\n\n function resolveKey(): string {\n const apiKey = config.apiKey ?? process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;\n if (!apiKey) throw new Error(\"gemini adapter: API key not set (env GOOGLE_API_KEY)\");\n return apiKey;\n }\n\n /** Build the generateContent body (shared by the http + stream paths). */\n function buildBody(req: ChatRequest): Record<string, unknown> {\n const systemParts: GeminiPart[] = [];\n const contents: { role: string; parts: GeminiPart[] }[] = [];\n for (const m of req.messages as Message[]) {\n if (m.role === \"system\") {\n systemParts.push(...partsFrom(m.content));\n } else {\n contents.push({\n role: m.role === \"assistant\" ? \"model\" : \"user\",\n parts: partsFrom(m.content),\n });\n }\n }\n const body: Record<string, unknown> = { contents };\n if (systemParts.length > 0) body.systemInstruction = { parts: systemParts };\n if (req.tools) body.tools = toProviderTools(req.tools, \"gemini\");\n const genConfig: Record<string, unknown> = {};\n if (req.maxTokens !== undefined) genConfig.maxOutputTokens = req.maxTokens;\n if (req.temperature !== undefined) genConfig.temperature = req.temperature;\n if (Object.keys(genConfig).length > 0) body.generationConfig = genConfig;\n return body;\n }\n\n async function chat(req: ChatRequest): Promise<ChatResult> {\n const apiKey = resolveKey();\n const body = buildBody(req);\n\n const res = await httpTransport({\n spec: req.spec,\n http: {\n url: `${baseUrl}/models/${req.spec.model}:generateContent?key=${encodeURIComponent(apiKey)}`,\n headers: { \"content-type\": \"application/json\" },\n body,\n },\n });\n if (!res.ok) {\n throw new Error(`gemini ${res.status}: ${JSON.stringify(res.json).slice(0, 300)}`);\n }\n const data = res.json as GeminiResponse;\n const parts = data.candidates?.[0]?.content?.parts ?? [];\n const text = parts\n .filter((p) => typeof p.text === \"string\")\n .map((p) => p.text)\n .join(\"\");\n const toolCalls: ToolCall[] = parts\n .filter((p) => p.functionCall)\n .map((p) => fromProviderToolCall({ functionCall: p.functionCall }, \"gemini\"));\n\n const usage = freshUsage({\n provider: \"gemini\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens: data.usageMetadata?.promptTokenCount ?? 0,\n outputTokens: data.usageMetadata?.candidatesTokenCount ?? 0,\n });\n const result: ChatResult = { text, usage };\n if (toolCalls.length > 0) result.toolCalls = toolCalls;\n return result;\n }\n\n // Streaming chat (F8.6) over streamGenerateContent?alt=sse. Each SSE chunk is\n // a partial GenerateContentResponse: parts[].text → text events, parts[].\n // functionCall → complete tool_call events (gemini sends each call whole), and\n // the final usageMetadata → a usage event. finishReason maps the terminal.\n async function* chatStream(req: ChatRequest): AsyncIterable<ChatStreamEvent> {\n const apiKey = resolveKey();\n const body = buildBody(req);\n const stream = streamTransport({\n spec: req.spec,\n fetch: config.fetch,\n http: {\n url: `${baseUrl}/models/${req.spec.model}:streamGenerateContent?alt=sse&key=${encodeURIComponent(apiKey)}`,\n headers: { \"content-type\": \"application/json\" },\n body,\n },\n });\n\n const toolCalls: ToolCall[] = [];\n let inputTokens = 0;\n let outputTokens = 0;\n let finishReason: string | null = null;\n\n for await (const data of stream) {\n let chunk: GeminiResponse & { candidates?: { finishReason?: string }[] };\n try {\n chunk = JSON.parse(data) as typeof chunk;\n } catch {\n continue;\n }\n const candidate = chunk.candidates?.[0];\n for (const p of candidate?.content?.parts ?? []) {\n if (typeof p.text === \"string\" && p.text.length > 0) {\n yield { type: \"text\", delta: p.text };\n } else if (p.functionCall) {\n toolCalls.push(fromProviderToolCall({ functionCall: p.functionCall }, \"gemini\"));\n }\n }\n if (candidate?.finishReason) finishReason = candidate.finishReason;\n if (chunk.usageMetadata) {\n inputTokens = chunk.usageMetadata.promptTokenCount ?? inputTokens;\n outputTokens = chunk.usageMetadata.candidatesTokenCount ?? outputTokens;\n }\n }\n\n for (const tc of toolCalls) {\n yield { type: \"tool_call\", id: tc.id, name: tc.name, args: tc.arguments };\n }\n const usage = freshUsage({\n provider: \"gemini\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"chat\",\n inputTokens,\n outputTokens,\n });\n yield { type: \"usage\", costUsd: usage.costUsd, model: usage.model, usage };\n yield {\n type: \"finish\",\n reason: toolCalls.length > 0 ? \"tool_calls\" : mapGeminiFinish(finishReason),\n };\n }\n\n return { name: \"gemini\", chat, chatStream, vision: chat };\n}\n\n/** Map Gemini finishReason → the SDK's ChatStreamEvent finish reason. */\nfunction mapGeminiFinish(reason: string | null): \"end_turn\" | \"tool_calls\" | \"length\" | \"stop\" {\n switch (reason) {\n case \"MAX_TOKENS\":\n return \"length\";\n case \"STOP\":\n return \"end_turn\";\n default:\n return reason ? \"stop\" : \"end_turn\";\n }\n}\n","// DeepInfra adapter (F4.3). DeepInfra exposes an OpenAI-compatible endpoint, so\n// this is the shared core pointed at DeepInfra's base URL + key. No extra deps.\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport type { ProviderAdapter } from \"../types.js\";\n\nexport function deepinfraAdapter(\n config: { apiKey?: string; baseUrl?: string } = {},\n): ProviderAdapter {\n return makeOpenAICompatibleAdapter({\n name: \"deepinfra\",\n baseUrl: config.baseUrl ?? \"https://api.deepinfra.com/v1/openai\",\n apiKey: config.apiKey,\n });\n}\n","// OpenRouter adapter (F4.4). Meta-router with an OpenAI-compatible API — reuses\n// the shared core + OpenRouter's attribution headers. Any upstream model is\n// reachable by its slug, e.g. \"minimax/minimax-m2.7\", \"google/gemini-2.5-flash\".\nimport { makeOpenAICompatibleAdapter } from \"./openai-compatible.js\";\nimport type { ProviderAdapter } from \"../types.js\";\n\nexport function openrouterAdapter(\n config: { apiKey?: string; baseUrl?: string; referer?: string; title?: string } = {},\n): ProviderAdapter {\n return makeOpenAICompatibleAdapter({\n name: \"openrouter\",\n baseUrl: config.baseUrl ?? \"https://openrouter.ai/api/v1\",\n apiKey: config.apiKey,\n extraHeaders: {\n \"HTTP-Referer\": config.referer ?? \"https://broberg.ai\",\n \"X-Title\": config.title ?? \"@broberg/ai-sdk\",\n },\n // OpenRouter returns ground-truth usage.cost (USD) when usage:{include:true}\n // is set — use it over the local pricing-table estimate (F010).\n costFromResponseField: true,\n });\n}\n","// fal.ai image adapter (F5.3). Two modes, both observed in the F1 inventory:\n// - sync : POST https://fal.run/{model}, image URL straight back (sanneandersen)\n// - queue : POST https://queue.fal.run/{model} → poll status → fetch result\n// Auth header `Authorization: Key <FAL_KEY>`. No @fal-ai/client — plain fetch.\nimport { freshUsage } from \"../cost/usage.js\";\nimport type { ProviderAdapter, ImageRequest, ImageResult } from \"../types.js\";\n\ninterface FalImagesResponse {\n images?: { url?: string }[];\n error?: unknown;\n}\ninterface FalQueueSubmit {\n request_id?: string;\n status_url?: string;\n response_url?: string;\n}\ninterface FalQueueStatus {\n status?: \"IN_QUEUE\" | \"IN_PROGRESS\" | \"COMPLETED\" | \"FAILED\";\n}\n\nexport interface FalAdapterConfig {\n apiKey?: string;\n /** \"sync\" (default — fal.run, fast models) or \"queue\" (queue.fal.run, polled). */\n mode?: \"sync\" | \"queue\";\n syncBaseUrl?: string;\n queueBaseUrl?: string;\n pollIntervalMs?: number;\n timeoutMs?: number;\n fetch?: typeof fetch;\n /** Override the per-image USD price (else a built-in estimate per model, 0 if unknown). */\n pricePerImage?: number;\n}\n\n// Per-image USD ESTIMATES (fal prices by megapixel/model and changes often —\n// verify before relying on these; override via config.pricePerImage). fal does\n// not return a price, so this is the SDK's best-effort cost for `usage.costUsd`.\nconst FAL_IMAGE_PRICE_ESTIMATE: Record<string, number> = {\n \"fal-ai/flux/schnell\": 0.003,\n \"fal-ai/flux/dev\": 0.025,\n \"fal-ai/flux-pro\": 0.05,\n \"fal-ai/flux-pro/v1.1\": 0.04,\n};\n\nconst sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\nexport function falAdapter(config: FalAdapterConfig = {}): ProviderAdapter {\n const doFetch = config.fetch ?? fetch;\n const syncBase = config.syncBaseUrl ?? \"https://fal.run\";\n const queueBase = config.queueBaseUrl ?? \"https://queue.fal.run\";\n const pollIntervalMs = config.pollIntervalMs ?? 2000;\n const timeoutMs = config.timeoutMs ?? 60000;\n\n async function image(req: ImageRequest): Promise<ImageResult> {\n const apiKey = config.apiKey ?? process.env.FAL_KEY;\n if (!apiKey) throw new Error(\"fal adapter: FAL_KEY not set\");\n const headers = { \"content-type\": \"application/json\", Authorization: `Key ${apiKey}` };\n\n const body: Record<string, unknown> = { prompt: req.prompt };\n if (req.width !== undefined && req.height !== undefined) {\n body.image_size = { width: req.width, height: req.height };\n }\n\n const mode = config.mode ?? \"sync\";\n const url = await (mode === \"sync\"\n ? runSync(req.spec.model, headers, body)\n : runQueue(req.spec.model, headers, body));\n\n // fal returns no price; estimate per-image (one image per call) so usage.costUsd\n // isn't silently 0. Override via config.pricePerImage.\n const usage = freshUsage({\n provider: \"fal\",\n model: req.spec.model,\n transport: \"http\",\n capability: \"image\",\n inputTokens: 0,\n outputTokens: 0,\n });\n usage.costUsd = config.pricePerImage ?? FAL_IMAGE_PRICE_ESTIMATE[req.spec.model] ?? 0;\n return { url, usage };\n }\n\n async function runSync(\n model: string,\n headers: Record<string, string>,\n body: unknown,\n ): Promise<string> {\n const res = await doFetch(`${syncBase}/${model}`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n throw new Error(`fal ${res.status}: ${(await res.text().catch(() => \"\")).slice(0, 200)}`);\n }\n const data = (await res.json()) as FalImagesResponse;\n const out = data.images?.[0]?.url;\n if (!out) throw new Error(`fal: no image url in response`);\n return out;\n }\n\n async function runQueue(\n model: string,\n headers: Record<string, string>,\n body: unknown,\n ): Promise<string> {\n const submitRes = await doFetch(`${queueBase}/${model}`, {\n method: \"POST\",\n headers,\n body: JSON.stringify(body),\n });\n if (!submitRes.ok) {\n throw new Error(`fal queue submit ${submitRes.status}`);\n }\n const submit = (await submitRes.json()) as FalQueueSubmit;\n const statusUrl = submit.status_url;\n const responseUrl = submit.response_url;\n if (!statusUrl || !responseUrl) throw new Error(\"fal queue: missing status/response url\");\n\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n const statusRes = await doFetch(statusUrl, { headers });\n const status = (await statusRes.json()) as FalQueueStatus;\n if (status.status === \"COMPLETED\") break;\n if (status.status === \"FAILED\") throw new Error(\"fal queue: generation FAILED\");\n if (Date.now() >= deadline) throw new Error(`fal queue: timed out after ${timeoutMs}ms`);\n await sleep(pollIntervalMs);\n }\n\n const resultRes = await doFetch(responseUrl, { headers });\n const result = (await resultRes.json()) as FalImagesResponse;\n const out = result.images?.[0]?.url;\n if (!out) throw new Error(\"fal queue: no image url in result\");\n return out;\n }\n\n return { name: \"fal\", image };\n}\n","// Default provider registry — the live adapters wired when AiConfig.providers is\n// absent. A bare createAI() makes real calls (keys from env). fal stays a stub\n// until F5.3 ships the real fal.ai image adapter.\nimport { anthropicAdapter } from \"./anthropic.js\";\nimport { openaiAdapter } from \"./openai.js\";\nimport { geminiAdapter } from \"./gemini.js\";\nimport { deepinfraAdapter } from \"./deepinfra.js\";\nimport { openrouterAdapter } from \"./openrouter.js\";\nimport { falAdapter } from \"./fal.js\";\nimport type { ProviderAdapter } from \"../types.js\";\n\nexport const defaultProviders: Record<string, ProviderAdapter> = {\n anthropic: anthropicAdapter(),\n openai: openaiAdapter(),\n gemini: geminiAdapter(),\n deepinfra: deepinfraAdapter(),\n openrouter: openrouterAdapter(),\n fal: falAdapter(),\n};\n","// Pre-flight budget guard. check() runs BEFORE the transport fires, so a call\n// that would breach a ceiling never reaches the provider. record() folds the\n// actual cost into the running total after a successful call.\nimport type { BudgetConfig, BudgetStore } from \"../types.js\";\n\n/** Default rolling-total store: in-memory, per BudgetGuard instance. */\nclass InMemoryBudgetStore implements BudgetStore {\n private spentUsd = 0;\n getSpent(): number {\n return this.spentUsd;\n }\n addSpent(usd: number): void {\n this.spentUsd += usd;\n }\n}\n\nexport class BudgetExceededError extends Error {\n readonly kind: \"per-call\" | \"rolling\";\n readonly limit: number;\n readonly spent: number;\n readonly requested: number;\n\n constructor(\n kind: \"per-call\" | \"rolling\",\n limit: number,\n spent: number,\n requested: number,\n ) {\n super(\n `Budget exceeded (${kind}): this call's estimated $${requested.toFixed(6)} ` +\n (kind === \"rolling\"\n ? `+ $${spent.toFixed(6)} already spent exceeds the $${limit.toFixed(6)} rolling ceiling`\n : `exceeds the $${limit.toFixed(6)} per-call ceiling`),\n );\n this.name = \"BudgetExceededError\";\n this.kind = kind;\n this.limit = limit;\n this.spent = spent;\n this.requested = requested;\n }\n}\n\nexport class BudgetGuard {\n private readonly store: BudgetStore;\n\n constructor(private readonly config: BudgetConfig) {\n this.store = config.store ?? new InMemoryBudgetStore();\n }\n\n /** Throws BudgetExceededError if `requested` would breach the per-call ceiling\n * or push the rolling total past its ceiling. Call before firing the request.\n * Async because a persistent store may be I/O-backed. */\n async check(requested: number): Promise<void> {\n const { perCallUsd, rollingUsd } = this.config;\n if (perCallUsd !== undefined && requested > perCallUsd) {\n throw new BudgetExceededError(\"per-call\", perCallUsd, await this.store.getSpent(), requested);\n }\n if (rollingUsd !== undefined) {\n const spent = await this.store.getSpent();\n if (spent + requested > rollingUsd) {\n throw new BudgetExceededError(\"rolling\", rollingUsd, spent, requested);\n }\n }\n }\n\n /** Add an actual cost to the running total (after a successful call). */\n async record(actual: number): Promise<void> {\n await this.store.addSpent(actual);\n }\n\n async totalSpent(): Promise<number> {\n return this.store.getSpent();\n }\n}\n","// Vision capability helper. The client owns orchestration (tier/budget/sink);\n// this module owns the vision-specific message shaping so it's unit-testable and\n// the capabilities/ layout stays meaningful. Default tier: \"vision\".\nimport type { VisionInput } from \"../schema/inputs.js\";\nimport type { Message, Tier } from \"../types.js\";\n\nexport const VISION_DEFAULT_TIER: Tier = \"vision\";\n\n/** Build the single-user multimodal message (text + image) for a vision call. */\nexport function buildVisionMessages(input: VisionInput): Message[] {\n return [\n {\n role: \"user\",\n content: [\n { type: \"text\", text: input.prompt },\n { type: \"image\", image: input.image, mimeType: input.mimeType },\n ],\n },\n ];\n}\n","// Translate capability helper. A thin prompt-contract on top of chat — the\n// client orchestrates (tier/budget/sink); this builds the messages. Default\n// tier: \"fast\". Returns the translation only, no preamble.\nimport type { TranslateInput } from \"../schema/inputs.js\";\nimport type { Message, Tier } from \"../types.js\";\n\nexport const TRANSLATE_DEFAULT_TIER: Tier = \"fast\";\n\nconst TRANSLATE_SYSTEM =\n \"You are a translation engine. Translate the user's text only. \" +\n \"Return the translation and nothing else — no preamble, no quotes.\";\n\nexport function buildTranslateMessages(input: TranslateInput): Message[] {\n const fromClause = input.from ? ` from ${input.from}` : \"\";\n return [\n { role: \"system\", content: TRANSLATE_SYSTEM },\n { role: \"user\", content: `Translate${fromClause} to ${input.to}:\\n\\n${input.text}` },\n ];\n}\n","// Embedding capability marker. The client orchestrates; this names the default\n// tier (OpenAI text-embedding-3-small via the embedding tier).\nimport type { Tier } from \"../types.js\";\n\nexport const EMBEDDING_DEFAULT_TIER: Tier = \"embedding\";\n","// Transcribe capability. No tier in the tier map (provider-specific, like image)\n// — defaults to OpenAI Whisper, overridable per call. Synergy: cctalk Danish\n// dictation. costUsd is 0 for v1 (Whisper is priced per minute, not per token).\nimport type { TierSpec } from \"../types.js\";\n\nexport const DEFAULT_TRANSCRIBE_SPEC: TierSpec = {\n provider: \"openai\",\n model: \"whisper-1\",\n transport: \"http\",\n};\n\n/** Fetch a URL to raw bytes; pass through bytes unchanged. */\nexport async function resolveAudio(\n audio: string | Uint8Array,\n fetchImpl: typeof fetch = fetch,\n): Promise<Uint8Array> {\n if (typeof audio !== \"string\") return audio;\n if (!/^https?:\\/\\//.test(audio)) {\n throw new Error(\"transcribe: string audio must be an http(s) URL (or pass raw bytes)\");\n }\n const res = await fetchImpl(audio);\n if (!res.ok) throw new Error(`transcribe: failed to fetch audio (${res.status})`);\n return new Uint8Array(await res.arrayBuffer());\n}\n","// Prompt-contract capabilities (F5.5). Each is a fixed system prompt over\n// chat/vision; extract adds Zod output validation with one retry. Exposed as\n// ai.contracts.* — built from the client so budget/cost tracking apply.\nimport type { AiClient, VisionInput } from \"../../schema/inputs.js\";\nimport type {\n Contracts,\n MockupInput,\n MockupResult,\n DesignInput,\n DesignResult,\n ExtractInput,\n ExtractResult,\n ClassifyInput,\n ClassifyResult,\n RerankInput,\n RerankResult,\n} from \"./types.js\";\n\n/** Pull the first JSON value out of a model reply (tolerates ```json fences + prose). */\nexport function parseJsonLoose(text: string): unknown {\n const fenced = text.replace(/```(?:json)?/gi, \"\").trim();\n const start = fenced.search(/[[{]/);\n if (start === -1) throw new Error(\"no JSON found in model output\");\n const slice = fenced.slice(start);\n // Walk back from the end to the matching closing bracket.\n const lastObj = slice.lastIndexOf(\"}\");\n const lastArr = slice.lastIndexOf(\"]\");\n const end = Math.max(lastObj, lastArr);\n return JSON.parse(slice.slice(0, end + 1));\n}\n\ntype ChatVision = Pick<AiClient, \"chat\" | \"vision\">;\n\nexport function makeContracts(client: ChatVision): Contracts {\n return {\n async mockup(input: MockupInput): Promise<MockupResult> {\n const constraints = input.constraints ? `\\n\\nConstraints:\\n${input.constraints}` : \"\";\n const res = await client.chat({\n system:\n \"You are a UI mockup generator. Output a single self-contained HTML document \" +\n \"using Tailwind CSS utility classes. Return ONLY the HTML — no markdown, no prose.\",\n prompt: `Build a UI mockup for:\\n${input.description}${constraints}`,\n tier: input.tier ?? \"smart\",\n purpose: input.purpose ?? \"contract:mockup\",\n });\n return { html: res.text, usage: res.usage };\n },\n\n async design(input: DesignInput): Promise<DesignResult> {\n const res = await client.vision({\n image: input.screenshot as VisionInput[\"image\"],\n prompt:\n \"You are a design-iteration engine. Given this screenshot, apply the instructions \" +\n `and return a single self-contained HTML document (Tailwind), ONLY the HTML.\\n\\n` +\n `Instructions:\\n${input.instructions}`,\n tier: input.tier ?? \"powerful\",\n purpose: input.purpose ?? \"contract:design\",\n });\n return { html: res.text, usage: res.usage };\n },\n\n async extract<T>(input: ExtractInput<T>): Promise<ExtractResult<T>> {\n const base =\n \"You are a structured-data extractor. Extract the requested data from the text and \" +\n \"return ONLY valid JSON — no markdown, no prose.\" +\n (input.instructions ? `\\n\\n${input.instructions}` : \"\");\n const run = async (reinforce: boolean) => {\n const res = await client.chat({\n system: reinforce ? `${base}\\n\\nYour previous output was not valid JSON. Return ONLY parseable JSON.` : base,\n prompt: input.text,\n tier: input.tier ?? \"smart\",\n purpose: input.purpose ?? \"contract:extract\",\n });\n return res;\n };\n let res = await run(false);\n try {\n return { data: input.schema.parse(parseJsonLoose(res.text)), usage: res.usage };\n } catch {\n // one retry with reinforcement\n res = await run(true);\n return { data: input.schema.parse(parseJsonLoose(res.text)), usage: res.usage };\n }\n },\n\n async classify(input: ClassifyInput): Promise<ClassifyResult> {\n const res = await client.chat({\n system:\n \"You are a zero-shot classifier. Choose exactly one label from the provided list. \" +\n 'Return ONLY JSON: {\"label\": \"<one of the labels>\", \"confidence\": <0..1>}.',\n prompt: `Labels: ${JSON.stringify(input.labels)}\\n\\nText:\\n${input.text}`,\n tier: input.tier ?? \"cheap\",\n purpose: input.purpose ?? \"contract:classify\",\n });\n const parsed = parseJsonLoose(res.text) as { label?: string; confidence?: number };\n const label = input.labels.includes(parsed.label ?? \"\") ? parsed.label! : (input.labels[0] ?? \"\");\n const confidence = typeof parsed.confidence === \"number\" ? parsed.confidence : 0;\n return { label, confidence, usage: res.usage };\n },\n\n async rerank(input: RerankInput): Promise<RerankResult> {\n const res = await client.chat({\n system:\n \"You are a relevance reranker. Score each item 0..1 for relevance to the query and \" +\n 'return ONLY JSON: [{\"item\": \"<verbatim item>\", \"score\": <0..1>}], ordered by score desc.',\n prompt: `Query: ${input.query}\\n\\nItems:\\n${JSON.stringify(input.items)}`,\n tier: input.tier ?? \"fast\",\n purpose: input.purpose ?? \"contract:rerank\",\n });\n const raw = parseJsonLoose(res.text) as { item?: string; score?: number }[];\n const ranked = (Array.isArray(raw) ? raw : [])\n .map((r) => ({ item: String(r.item ?? \"\"), score: typeof r.score === \"number\" ? r.score : 0 }))\n .sort((a, b) => b.score - a.score);\n return { ranked, usage: res.usage };\n },\n };\n}\n","// Zod is the single source of truth for the public input shapes. The TypeScript\n// types are derived via z.infer — no hand-written interface duplicates them.\n// The client .parse()s every input at the boundary, so invalid input throws a\n// ZodError before any provider work happens.\nimport { z } from \"zod\";\nimport type {\n ProviderAdapter,\n CostSink,\n TranslateResult,\n ChatResult,\n ChatStreamEvent,\n ImageResult,\n EmbeddingResult,\n TranscribeResult,\n} from \"../types.js\";\nimport type { Contracts } from \"../capabilities/contracts/types.js\";\n\n// ── Reusable sub-schemas ───────────────────────────────────────────────────\n\nexport const transportSchema = z.enum([\"http\", \"subprocess\"]);\n\nexport const tierSchema = z.enum([\n \"fast\",\n \"smart\",\n \"powerful\",\n \"cheap\",\n \"vision\",\n \"embedding\",\n]);\n\nexport const tierSpecSchema = z.object({\n provider: z.string(),\n model: z.string(),\n transport: transportSchema,\n});\n\nexport const toolSchema = z.object({\n name: z.string(),\n description: z.string(),\n parameters: z.record(z.unknown()),\n});\n\nexport const toolCallSchema = z.object({\n id: z.string(),\n name: z.string(),\n arguments: z.record(z.unknown()),\n});\n\nexport const contentPartSchema = z.union([\n z.object({ type: z.literal(\"text\"), text: z.string() }),\n z.object({\n type: z.literal(\"image\"),\n image: z.union([z.string(), z.instanceof(Uint8Array)]),\n mimeType: z.string().optional(),\n }),\n]);\n\nexport const messageSchema = z.object({\n role: z.enum([\"system\", \"user\", \"assistant\", \"tool\"]),\n content: z.union([z.string(), z.array(contentPartSchema)]),\n toolCalls: z.array(toolCallSchema).optional(),\n toolCallId: z.string().optional(),\n});\n\n/** Per-call options shared by every capability input. */\nconst callOptions = {\n tier: tierSchema.optional(),\n override: tierSpecSchema.partial().optional(),\n fallback: z.array(z.union([tierSchema, tierSpecSchema])).optional(),\n purpose: z.string().optional(),\n /** Consumer-defined attribution dimensions (e.g. {tenantId}) ridden into the\n * cost sink for per-tenant/per-customer cost breakdown (F011). */\n labels: z.record(z.string(), z.string()).optional(),\n} as const;\n\n// ── The 5 capability inputs ────────────────────────────────────────────────\n\nexport const chatInputSchema = z.object({\n prompt: z.string().optional(),\n messages: z.array(messageSchema).optional(),\n system: z.string().optional(),\n tools: z.array(toolSchema).optional(),\n maxTokens: z.number().int().positive().optional(),\n temperature: z.number().min(0).max(2).optional(),\n /** \"json\" requests JSON-object output (OpenAI-compatible response_format). */\n responseFormat: z.enum([\"json\", \"text\"]).optional(),\n ...callOptions,\n});\n\nexport const visionInputSchema = z.object({\n image: z.union([z.string(), z.instanceof(Uint8Array)]),\n prompt: z.string(),\n mimeType: z.string().optional(),\n ...callOptions,\n});\n\nexport const translateInputSchema = z.object({\n text: z.string(),\n to: z.string(),\n from: z.string().optional(),\n ...callOptions,\n});\n\nexport const imageInputSchema = z.object({\n prompt: z.string(),\n width: z.number().int().positive().optional(),\n height: z.number().int().positive().optional(),\n ...callOptions,\n});\n\nexport const embeddingInputSchema = z.object({\n text: z.union([z.string(), z.array(z.string())]),\n ...callOptions,\n});\n\nexport const transcribeInputSchema = z.object({\n /** Audio URL or raw bytes. */\n audio: z.union([z.string(), z.instanceof(Uint8Array)]),\n language: z.string().optional(),\n /** Audio length in seconds — enables Whisper per-minute cost. */\n durationSec: z.number().positive().optional(),\n ...callOptions,\n});\n\n// ── Client config ──────────────────────────────────────────────────────────\n\nexport const budgetSchema = z.object({\n perCallUsd: z.number().positive().optional(),\n rollingUsd: z.number().positive().optional(),\n});\n\nexport const aiConfigSchema = z.object({\n defaults: z.record(tierSchema, tierSpecSchema).optional(),\n // Functions can't be deeply validated — z.custom asserts the TS type and\n // passes the value through untouched.\n providers: z.record(z.string(), z.custom<ProviderAdapter>()).optional(),\n costSink: z.custom<CostSink>().optional(),\n budget: budgetSchema.optional(),\n});\n\n// ── Derived types (z.infer is the single source) ───────────────────────────\n\nexport type ChatInput = z.infer<typeof chatInputSchema>;\nexport type VisionInput = z.infer<typeof visionInputSchema>;\nexport type TranslateInput = z.infer<typeof translateInputSchema>;\nexport type ImageInput = z.infer<typeof imageInputSchema>;\nexport type EmbeddingInput = z.infer<typeof embeddingInputSchema>;\nexport type TranscribeInput = z.infer<typeof transcribeInputSchema>;\nexport type AiConfig = z.infer<typeof aiConfigSchema>;\n\n/** The public facade. Defined here because it depends on the derived inputs. */\nexport interface AiClient {\n chat(input: ChatInput): Promise<ChatResult>;\n /** Streaming chat (F8) — same input as chat; yields ChatStreamEvents. The\n * caller owns the tool-loop (per-turn engine, not an agent runtime). */\n chatStream(input: ChatInput): AsyncIterable<ChatStreamEvent>;\n vision(input: VisionInput): Promise<ChatResult>;\n translate(input: TranslateInput): Promise<TranslateResult>;\n image(input: ImageInput): Promise<ImageResult>;\n embedding(input: EmbeddingInput): Promise<EmbeddingResult>;\n transcribe(input: TranscribeInput): Promise<TranscribeResult>;\n /** Prompt-contract capabilities (F5.5) layered on chat/vision. */\n contracts: Contracts;\n}\n","// createAI() — the facade factory. Resolves routing, picks a provider adapter,\n// delegates the call, stamps call-context metadata onto Usage, and reports to the\n// cost sink. Provider specifics live in adapters; cost compute/budget land in F3.\nimport { resolveTier } from \"./routing/tier-map.js\";\nimport { defaultProviders } from \"./providers/registry.js\";\nimport { computeCost } from \"./cost/usage.js\";\nimport { BudgetGuard } from \"./cost/budget.js\";\nimport { buildVisionMessages, VISION_DEFAULT_TIER } from \"./capabilities/vision.js\";\nimport { buildTranslateMessages, TRANSLATE_DEFAULT_TIER } from \"./capabilities/translate.js\";\nimport { EMBEDDING_DEFAULT_TIER } from \"./capabilities/embedding.js\";\nimport { DEFAULT_TRANSCRIBE_SPEC, resolveAudio } from \"./capabilities/transcribe.js\";\nimport { makeContracts } from \"./capabilities/contracts/index.js\";\nimport {\n aiConfigSchema,\n chatInputSchema,\n visionInputSchema,\n translateInputSchema,\n imageInputSchema,\n embeddingInputSchema,\n transcribeInputSchema,\n} from \"./schema/inputs.js\";\nimport type {\n AiConfig,\n AiClient,\n ChatInput,\n VisionInput,\n TranslateInput,\n ImageInput,\n EmbeddingInput,\n TranscribeInput,\n} from \"./schema/inputs.js\";\nimport type {\n ChatResult,\n ChatStreamEvent,\n ImageResult,\n EmbeddingResult,\n TranscribeResult,\n TranslateResult,\n ProviderAdapter,\n Message,\n Capability,\n Tier,\n TierSpec,\n Usage,\n} from \"./types.js\";\n\n/** Built-in image route (no image tier in the tier map — fal owns its routing). */\nconst DEFAULT_IMAGE_SPEC: TierSpec = {\n provider: \"fal\",\n model: \"fal-ai/flux/schnell\",\n transport: \"http\",\n};\n\nexport function createAI(config: AiConfig = {}): AiClient {\n // Validate config at the boundary (throws ZodError on bad shape).\n const cfg = aiConfigSchema.parse(config);\n const providers = cfg.providers ?? defaultProviders;\n const budget = cfg.budget ? new BudgetGuard(cfg.budget) : undefined;\n\n const estTokens = (s: string): number => Math.ceil(s.length / 4);\n\n /** Pre-flight budget check. Estimates this call's cost and throws\n * BudgetExceededError before the transport fires. No-op without a budget. */\n async function preflight(spec: TierSpec, estInTokens: number, estOutTokens: number): Promise<void> {\n if (!budget) return;\n await budget.check(computeCost(spec.provider, spec.model, estInTokens, estOutTokens));\n }\n\n /** Fold the actual cost into the rolling total after a successful call. */\n async function settle(usage: Usage): Promise<void> {\n if (budget) await budget.record(usage.costUsd);\n }\n\n function pickProvider(name: string): ProviderAdapter {\n const adapter = providers[name];\n if (!adapter) {\n throw new Error(\n `createAI: no provider adapter registered for \"${name}\". Registered: ${Object.keys(providers).join(\", \") || \"(none)\"}`,\n );\n }\n return adapter;\n }\n\n /** Stamp call-context metadata the client owns onto the adapter's Usage:\n * capability, tier, purpose, the wall-clock latency, and the timestamp. */\n function enrich(\n usage: Usage,\n capability: Capability,\n tier: Tier | undefined,\n purpose: string | undefined,\n latencyMs: number,\n labels: Record<string, string> | undefined,\n ): Usage {\n usage.capability = capability;\n if (tier) usage.tier = tier;\n if (purpose) usage.purpose = purpose;\n if (labels && Object.keys(labels).length > 0) usage.labels = labels;\n usage.latencyMs = Math.round(latencyMs);\n if (!usage.ts) usage.ts = new Date().toISOString();\n return usage;\n }\n\n async function report(usage: Usage): Promise<void> {\n if (!cfg.costSink) return;\n try {\n await cfg.costSink.record(usage);\n } catch {\n // A broken sink must never crash a real AI call (F3.3 invariant).\n }\n }\n\n function toMessages(input: ChatInput): Message[] {\n if (input.messages && input.messages.length > 0) return input.messages;\n const msgs: Message[] = [];\n if (input.system) msgs.push({ role: \"system\", content: input.system });\n msgs.push({ role: \"user\", content: input.prompt ?? \"\" });\n return msgs;\n }\n\n /** Run a capability with an optional fallback chain. Tries the primary route,\n * then each fallback (Tier or TierSpec) in order if the call errors. A budget\n * breach propagates immediately (not a fallback trigger). On the first\n * success: stamp Usage, settle the budget, report to the sink, return. */\n async function runCapability<R extends { usage: Usage }>(opts: {\n primary: TierSpec;\n fallback?: (Tier | TierSpec)[];\n capability: Capability;\n tier?: Tier;\n purpose?: string;\n labels?: Record<string, string>;\n estIn: number;\n estOut: number;\n invoke: (spec: TierSpec) => Promise<R>;\n }): Promise<R> {\n const routes: TierSpec[] = [\n opts.primary,\n ...(opts.fallback ?? []).map((f) =>\n typeof f === \"string\" ? resolveTier(f, undefined, cfg.defaults) : f,\n ),\n ];\n let lastErr: unknown;\n for (let i = 0; i < routes.length; i++) {\n const spec = routes[i]!;\n await preflight(spec, opts.estIn, opts.estOut); // BudgetExceededError propagates\n try {\n const t0 = performance.now();\n const res = await opts.invoke(spec);\n enrich(res.usage, opts.capability, i === 0 ? opts.tier : undefined, opts.purpose, performance.now() - t0, opts.labels);\n await settle(res.usage);\n await report(res.usage);\n return res;\n } catch (e) {\n lastErr = e; // try the next fallback route\n }\n }\n throw lastErr;\n }\n\n /** Whether a pre-first-token streaming error should fall back to the next\n * route. Eligible: network/timeout/parse (no status) + 429 + 5xx. Hard 4xx\n * bubbles up (no silent re-route) — sa contract #2565. */\n function eligibleForFallback(e: unknown): boolean {\n const status = (e as { status?: number } | null)?.status;\n if (status === undefined) return true;\n return status === 429 || status >= 500;\n }\n\n function errorEvent(e: unknown): ChatStreamEvent {\n const ev: ChatStreamEvent = {\n type: \"error\",\n message: e instanceof Error ? e.message : String(e),\n };\n const status = (e as { status?: number } | null)?.status;\n if (status !== undefined) ev.status = status;\n return ev;\n }\n\n /** Streaming chat with pre-stream fallback (F8.1). Yields ChatStreamEvents as\n * the turn unfolds. Fallback re-routes only BEFORE the first text/tool_call\n * event (deltas can't be un-emitted); once streaming has begun, an error is\n * surfaced as an error event and the stream ends. Budget breaches propagate. */\n async function* chatStreamImpl(input: ChatInput): AsyncIterable<ChatStreamEvent> {\n input = chatInputSchema.parse(input);\n const tier = input.tier ?? \"smart\";\n const messages = toMessages(input);\n const estIn = messages.reduce(\n (n, m) => n + estTokens(typeof m.content === \"string\" ? m.content : JSON.stringify(m.content)),\n 0,\n );\n const estOut = input.maxTokens ?? 512;\n const routes: TierSpec[] = [\n resolveTier(tier, input.override, cfg.defaults),\n ...(input.fallback ?? []).map((f) =>\n typeof f === \"string\" ? resolveTier(f, undefined, cfg.defaults) : f,\n ),\n ];\n\n let lastErr: unknown;\n for (let i = 0; i < routes.length; i++) {\n const spec = routes[i]!;\n await preflight(spec, estIn, estOut); // BudgetExceededError propagates\n const adapter = pickProvider(spec.provider);\n if (!adapter.chatStream) {\n throw new Error(`createAI: provider \"${spec.provider}\" does not support streaming`);\n }\n const t0 = performance.now();\n let emitted = false;\n try {\n for await (const ev of adapter.chatStream({\n messages,\n spec,\n tools: input.tools,\n maxTokens: input.maxTokens,\n temperature: input.temperature,\n responseFormat: input.responseFormat,\n })) {\n if (ev.type === \"text\" || ev.type === \"tool_call\") emitted = true;\n if (ev.type === \"usage\") {\n enrich(ev.usage, \"chat\", i === 0 ? tier : undefined, input.purpose, performance.now() - t0, input.labels);\n await settle(ev.usage);\n await report(ev.usage);\n }\n yield ev;\n }\n return; // stream completed cleanly\n } catch (e) {\n lastErr = e;\n if (emitted || !eligibleForFallback(e)) {\n yield errorEvent(e); // mid-stream or hard error → surface + stop\n return;\n }\n // pre-first-token eligible error → try the next route\n }\n }\n yield errorEvent(lastErr);\n }\n\n const client: AiClient = {\n async chat(input: ChatInput): Promise<ChatResult> {\n input = chatInputSchema.parse(input);\n const tier = input.tier ?? \"smart\";\n const messages = toMessages(input);\n const estIn = messages.reduce(\n (n, m) => n + estTokens(typeof m.content === \"string\" ? m.content : JSON.stringify(m.content)),\n 0,\n );\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"chat\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn,\n estOut: input.maxTokens ?? 512,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.chat) throw new Error(`createAI: provider \"${spec.provider}\" does not support chat`);\n return adapter.chat({ messages, spec, tools: input.tools, maxTokens: input.maxTokens, temperature: input.temperature, responseFormat: input.responseFormat });\n },\n });\n },\n\n chatStream: chatStreamImpl,\n\n async vision(input: VisionInput): Promise<ChatResult> {\n input = visionInputSchema.parse(input);\n const tier = input.tier ?? VISION_DEFAULT_TIER;\n const messages: Message[] = buildVisionMessages(input);\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"vision\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn: estTokens(input.prompt) + 1000, // prompt + ~1k image payload\n estOut: 512,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.vision) throw new Error(`createAI: provider \"${spec.provider}\" does not support vision`);\n return adapter.vision({ messages, spec });\n },\n });\n },\n\n async translate(input: TranslateInput): Promise<TranslateResult> {\n input = translateInputSchema.parse(input);\n const tier = input.tier ?? TRANSLATE_DEFAULT_TIER;\n const messages: Message[] = buildTranslateMessages(input);\n const estIn = estTokens(input.text) + 40;\n const res = await runCapability<ChatResult>({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"translate\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn,\n estOut: estIn,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.chat) throw new Error(`createAI: provider \"${spec.provider}\" does not support chat (translate routes through chat)`);\n return adapter.chat({ messages, spec });\n },\n });\n return { text: res.text, usage: res.usage };\n },\n\n async image(input: ImageInput): Promise<ImageResult> {\n input = imageInputSchema.parse(input);\n return runCapability({\n primary: { ...DEFAULT_IMAGE_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"image\",\n purpose: input.purpose,\n labels: input.labels,\n estIn: 0, // image cost is not token-based\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.image) throw new Error(`createAI: provider \"${spec.provider}\" does not support image`);\n return adapter.image({ prompt: input.prompt, spec, width: input.width, height: input.height });\n },\n });\n },\n\n async embedding(input: EmbeddingInput): Promise<EmbeddingResult> {\n input = embeddingInputSchema.parse(input);\n const tier = input.tier ?? EMBEDDING_DEFAULT_TIER;\n const text = Array.isArray(input.text) ? input.text : [input.text];\n return runCapability({\n primary: resolveTier(tier, input.override, cfg.defaults),\n fallback: input.fallback,\n capability: \"embedding\",\n tier,\n purpose: input.purpose,\n labels: input.labels,\n estIn: text.reduce((n, t) => n + estTokens(t), 0),\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.embedding) throw new Error(`createAI: provider \"${spec.provider}\" does not support embedding`);\n return adapter.embedding({ input: text, spec });\n },\n });\n },\n\n async transcribe(input: TranscribeInput): Promise<TranscribeResult> {\n input = transcribeInputSchema.parse(input);\n const audio = await resolveAudio(input.audio);\n return runCapability({\n primary: { ...DEFAULT_TRANSCRIBE_SPEC, ...input.override },\n fallback: input.fallback,\n capability: \"transcribe\",\n purpose: input.purpose,\n labels: input.labels,\n estIn: 0,\n estOut: 0,\n invoke: async (spec) => {\n const adapter = pickProvider(spec.provider);\n if (!adapter.transcribe) throw new Error(`createAI: provider \"${spec.provider}\" does not support transcribe`);\n return adapter.transcribe({ audio, language: input.language, durationSec: input.durationSec, spec });\n },\n });\n },\n\n // Replaced below with the real prompt-contracts (needs the client itself).\n contracts: undefined as unknown as AiClient[\"contracts\"],\n };\n\n client.contracts = makeContracts(client);\n return client;\n}\n","// Stub provider adapters (F2.5). They satisfy ProviderAdapter so the client wires\n// up and resolves without real network calls. Real implementations land in F4\n// (anthropic/openai/gemini/openrouter/deepinfra) and F5.3 (fal image). The stub\n// usage carries zero tokens/cost — F3.1 fills real numbers in the live adapters.\nimport type {\n ProviderAdapter,\n ChatRequest,\n ChatResult,\n ImageRequest,\n ImageResult,\n EmbeddingRequest,\n EmbeddingResult,\n Usage,\n Capability,\n} from \"../types.js\";\n\nfunction stubUsage(\n provider: string,\n model: string,\n transport: \"http\" | \"subprocess\",\n capability: Capability,\n): Usage {\n return {\n provider,\n model,\n transport,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n cacheCreationTokens: 0,\n costUsd: 0,\n latencyMs: 0,\n capability,\n // ts is supplied by the caller-side at real call time; stub uses a fixed marker\n // ('' avoids Date.now() — keeps the stub pure/deterministic for tests).\n ts: \"\",\n };\n}\n\nfunction lastUserText(req: ChatRequest): string {\n for (let i = req.messages.length - 1; i >= 0; i--) {\n const m = req.messages[i];\n if (m && m.role === \"user\") {\n return typeof m.content === \"string\"\n ? m.content\n : m.content.map((p) => (p.type === \"text\" ? p.text : \"[image]\")).join(\" \");\n }\n }\n return \"\";\n}\n\n/** Anthropic adapter stub (HTTP path). */\nexport const anthropicApiAdapter: ProviderAdapter = {\n name: \"anthropic\",\n async chat(req: ChatRequest): Promise<ChatResult> {\n return {\n text: `[stub:anthropic-api] ${lastUserText(req)}`,\n usage: stubUsage(\"anthropic\", req.spec.model, \"http\", \"chat\"),\n };\n },\n async vision(req: ChatRequest): Promise<ChatResult> {\n return {\n text: `[stub:anthropic-api:vision] ${lastUserText(req)}`,\n usage: stubUsage(\"anthropic\", req.spec.model, \"http\", \"vision\"),\n };\n },\n};\n\n/** Anthropic adapter stub (subprocess / `claude -p` path). */\nexport const anthropicSubprocessAdapter: ProviderAdapter = {\n name: \"anthropic\",\n async chat(req: ChatRequest): Promise<ChatResult> {\n const usage = stubUsage(\"anthropic\", req.spec.model, \"subprocess\", \"chat\");\n usage.subprocess = true;\n return { text: `[stub:anthropic-subprocess] ${lastUserText(req)}`, usage };\n },\n};\n\n/** OpenAI adapter stub — covers the embedding default tier + a chat fallback. */\nexport const openaiStubAdapter: ProviderAdapter = {\n name: \"openai\",\n async chat(req: ChatRequest): Promise<ChatResult> {\n return {\n text: `[stub:openai] ${lastUserText(req)}`,\n usage: stubUsage(\"openai\", req.spec.model, \"http\", \"chat\"),\n };\n },\n async embedding(req: EmbeddingRequest): Promise<EmbeddingResult> {\n return {\n vectors: req.input.map(() => [0, 0, 0]),\n usage: stubUsage(\"openai\", req.spec.model, \"http\", \"embedding\"),\n };\n },\n};\n\n/** fal.ai adapter stub — image generation (real one in fal.ts, F5.3). */\nexport const falStubAdapter: ProviderAdapter = {\n name: \"fal\",\n async image(req: ImageRequest): Promise<ImageResult> {\n return {\n url: `https://stub.fal/${encodeURIComponent(req.prompt).slice(0, 32)}.png`,\n usage: stubUsage(\"fal\", req.spec.model, \"http\", \"image\"),\n };\n },\n};\n\n/** Stub provider registry — deterministic, no network. Used by tests via\n * createAI({ providers: stubProviders }). The real default registry (registry.ts)\n * wires the live adapters. */\nexport const stubProviders: Record<string, ProviderAdapter> = {\n anthropic: anthropicApiAdapter,\n openai: openaiStubAdapter,\n fal: falStubAdapter,\n};\n","// AUTO-GENERATED by scripts/gen-version.mjs — do not edit, do not commit.\nexport const VERSION = \"0.4.1\" as const;\nexport const SDK_TAG = \"@broberg/ai-sdk@0.4.1\" as const;\n","// Persistent BudgetStore backed by bun:sqlite (F7.1). The rolling total survives\n// process restarts and is shared by every process pointing at the same file, so\n// a budget ceiling is a real production guard — not a per-process counter that\n// resets on deploy. bun:sqlite is imported lazily (Node-safe import, like sqliteSink).\nimport type { BudgetStore } from \"../types.js\";\n\nexport interface SqliteBudgetStoreConfig {\n /** SQLite file path, e.g. \"./ai-budget.db\". */\n dbPath: string;\n /** Window/bucket key — use e.g. a day-stamp for a daily budget. Default \"default\". */\n key?: string;\n}\n\nexport function sqliteBudgetStore(config: SqliteBudgetStoreConfig): BudgetStore {\n const key = config.key ?? \"default\";\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let ready: Promise<any> | null = null;\n const open = async () => {\n const { Database } = await import(\"bun:sqlite\");\n const db = new Database(config.dbPath);\n db.run(\n `CREATE TABLE IF NOT EXISTS budget_spend (key TEXT PRIMARY KEY, spent_usd REAL NOT NULL DEFAULT 0)`,\n );\n return db;\n };\n\n return {\n async getSpent(): Promise<number> {\n const db = await (ready ??= open());\n const row = db\n .query(`SELECT spent_usd FROM budget_spend WHERE key = $key`)\n .get({ $key: key }) as { spent_usd: number } | null;\n return row?.spent_usd ?? 0;\n },\n async addSpent(usd: number): Promise<void> {\n const db = await (ready ??= open());\n db.run(\n `INSERT INTO budget_spend (key, spent_usd) VALUES ($key, $usd)\n ON CONFLICT(key) DO UPDATE SET spent_usd = spent_usd + $usd`,\n { $key: key, $usd: usd },\n );\n },\n };\n}\n","import type { CostSink } from \"../../types.js\";\n\n/** A sink that does nothing. The default when no costSink is configured. */\nexport const noopSink: CostSink = {\n record() {\n // intentionally empty\n },\n};\n","import type { CostSink, Usage } from \"../../types.js\";\n\n/** Fan a Usage out to several sinks. Uses allSettled so one failing sink never\n * prevents the others from recording (and never propagates to the caller). */\nexport function multiSink(sinks: CostSink[]): CostSink {\n return {\n async record(usage: Usage): Promise<void> {\n // async wrapper turns a synchronous throw in s.record into a rejected\n // promise, so allSettled isolates it (a sync throw would otherwise escape\n // the .map before allSettled ran).\n await Promise.allSettled(sinks.map(async (s) => s.record(usage)));\n },\n };\n}\n","// upmetricsSink — the canonical cost sink. Forwards each Usage to the upmetrics\n// agent-run ingest (POST /api/agent, mode:\"record\"). Field mapping follows\n// upmetrics/docs/AGENT-SCHEMA.md \"For cost-sink authors\" exactly:\n// - agent_kind / agent_name are injected (not in Usage; required by ingest)\n// - camelCase Usage → snake_case wire fields\n// - capability + transport ride in tags (no top-level column)\n// - toolCalls[].errorCount → tool_calls[].error_count (deep rename)\n// - latencyMs → duration_ms; ts → started_at; ended_at = ts + latency\n// Errors never propagate (CostSink invariant). Do NOT use @upmetrics/agent\n// wrapAnthropic here — the SDK already owns the provider call.\nimport { SDK_TAG } from \"../../version.js\";\nimport type { CostSink, Usage } from \"../../types.js\";\n\nexport interface UpmetricsSinkConfig {\n /** Ingest base URL, e.g. https://upmetrics.org */\n baseUrl: string;\n /** Per-project api_key → sent as the X-Upmetrics-Key header. */\n apiKey: string;\n /** Consumer name dashboards group by (e.g. \"cms\", \"trail\", \"xrt81\") — NOT the\n * capability. */\n agentName: string;\n /** Defaults to \"chatbot\" (\"embedding\" auto-selected for embedding calls). */\n agentKind?: string;\n /** When true, guarantees no prompt/response content is ever sent (the sink\n * sends none regardless — Usage carries no excerpts — so this is belt-and-\n * suspenders for GDPR-health projects). */\n complianceMode?: boolean;\n /** Injectable fetch for testing; defaults to global fetch. */\n fetch?: typeof fetch;\n /** Optional error hook (errors are otherwise swallowed silently). */\n onError?: (err: unknown) => void;\n}\n\nexport function upmetricsSink(config: UpmetricsSinkConfig): CostSink {\n const doFetch = config.fetch ?? fetch;\n const url = `${config.baseUrl.replace(/\\/$/, \"\")}/api/agent`;\n\n return {\n async record(usage: Usage): Promise<void> {\n try {\n const startedAt = usage.ts || new Date().toISOString();\n const endedAt = new Date(\n new Date(startedAt).getTime() + (usage.latencyMs || 0),\n ).toISOString();\n\n const agentKind =\n config.agentKind ?? (usage.capability === \"embedding\" ? \"embedding\" : \"chatbot\");\n\n const body: Record<string, unknown> = {\n mode: \"record\",\n agent_kind: agentKind,\n agent_name: config.agentName,\n provider: usage.provider,\n model: usage.model,\n status: \"success\",\n input_tokens: usage.inputTokens,\n output_tokens: usage.outputTokens,\n cache_read_tokens: usage.cacheReadTokens,\n cache_creation_tokens: usage.cacheCreationTokens,\n cost_usd: usage.costUsd,\n duration_ms: usage.latencyMs,\n started_at: startedAt,\n ended_at: endedAt,\n tags: {\n // Consumer attribution labels (e.g. tenantId) ride in tags so no new\n // top-level field risks the strict-shape ingest schema (F011). The\n // SDK-owned keys win — a label can never clobber capability/transport/sdk.\n ...usage.labels,\n capability: usage.capability,\n transport: usage.transport,\n sdk: SDK_TAG,\n },\n };\n if (usage.tier !== undefined) body.tier = usage.tier;\n if (usage.purpose !== undefined) body.purpose = usage.purpose;\n if (usage.toolCalls) {\n body.tool_calls = usage.toolCalls.map((t) => ({\n name: t.name,\n count: t.count,\n error_count: t.errorCount ?? 0,\n }));\n }\n // complianceMode is a no-op today (we never send excerpts) but documents intent.\n void config.complianceMode;\n\n const res = await doFetch(url, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n \"X-Upmetrics-Key\": config.apiKey,\n },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n config.onError?.(\n new Error(`upmetricsSink: ingest returned ${res.status}: ${text.slice(0, 200)}`),\n );\n }\n } catch (err) {\n // Never let a sink failure crash a real AI call.\n config.onError?.(err);\n }\n },\n };\n}\n","// discordSink — posts a per-call cost embed to a Discord webhook. Secondary sink\n// (upmetricsSink is canonical); handy for repos not wired to Upmetrics or for an\n// at-a-glance spend feed. Plain fetch, no Discord SDK. Errors never propagate.\nimport type { CostSink, Usage } from \"../../types.js\";\n\nexport interface DiscordSinkConfig {\n webhookUrl: string;\n /** Skip posting paid calls below this USD threshold (anti-spam). Subprocess\n * (Max-plan free) calls always post so the \"free\" feed stays visible.\n * Default 0 → post everything. */\n minUsd?: number;\n fetch?: typeof fetch;\n onError?: (err: unknown) => void;\n}\n\nexport function discordSink(config: DiscordSinkConfig): CostSink {\n const doFetch = config.fetch ?? fetch;\n const minUsd = config.minUsd ?? 0;\n\n return {\n async record(usage: Usage): Promise<void> {\n try {\n // Skip cheap PAID calls; always show subprocess (free) calls.\n if (!usage.subprocess && usage.costUsd < minUsd) return;\n\n const costLabel = usage.subprocess\n ? \"Max plan (free)\"\n : `$${usage.costUsd.toFixed(6)}`;\n\n const embed = {\n title: `AI call — ${usage.capability}`,\n fields: [\n { name: \"Provider\", value: usage.provider, inline: true },\n { name: \"Model\", value: usage.model, inline: true },\n { name: \"Transport\", value: usage.transport, inline: true },\n { name: \"Cost\", value: costLabel, inline: true },\n {\n name: \"Tokens\",\n value: `${usage.inputTokens} in / ${usage.outputTokens} out`,\n inline: true,\n },\n { name: \"Latency\", value: `${usage.latencyMs} ms`, inline: true },\n ],\n timestamp: usage.ts || new Date().toISOString(),\n };\n\n const res = await doFetch(config.webhookUrl, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ embeds: [embed] }),\n });\n if (!res.ok) {\n config.onError?.(new Error(`discordSink: webhook returned ${res.status}`));\n }\n } catch (err) {\n config.onError?.(err);\n }\n },\n };\n}\n","// sqliteSink — persists every Usage to a local bun:sqlite DB. Secondary/offline\n// sink (upmetricsSink is canonical). No npm dependency — bun:sqlite is built in.\n//\n// IMPORTANT: bun:sqlite is imported LAZILY (dynamic import on first use), not at\n// module top level. A static `import \"bun:sqlite\"` would leak into the package\n// entry and crash every Node consumer (`ERR_UNSUPPORTED_ESM_URL_SCHEME`). With\n// the lazy import, importing @broberg/ai-sdk works everywhere; bun:sqlite only\n// loads when sqliteSink/getCostSummary actually run (Bun only).\nimport type { CostSink, Usage } from \"../../types.js\";\n\nexport interface SqliteSinkConfig {\n /** Path to the SQLite file, e.g. \"./ai-cost.db\" (or \":memory:\"). */\n dbPath: string;\n}\n\nconst CREATE_TABLE = `\nCREATE TABLE IF NOT EXISTS ai_usage (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n ts TEXT NOT NULL,\n provider TEXT NOT NULL,\n model TEXT NOT NULL,\n tier TEXT,\n transport TEXT NOT NULL,\n capability TEXT NOT NULL,\n purpose TEXT,\n input_tokens INTEGER NOT NULL,\n output_tokens INTEGER NOT NULL,\n cache_read_tokens INTEGER NOT NULL,\n cache_creation_tokens INTEGER NOT NULL,\n cost_usd REAL NOT NULL,\n latency_ms INTEGER NOT NULL,\n subprocess INTEGER NOT NULL DEFAULT 0\n)`;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nasync function openDb(dbPath: string, readonly = false): Promise<any> {\n const { Database } = await import(\"bun:sqlite\");\n return new Database(dbPath, readonly ? { readonly: true } : undefined);\n}\n\nexport function sqliteSink(config: SqliteSinkConfig): CostSink {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let ready: Promise<any> | null = null;\n const init = async () => {\n const db = await openDb(config.dbPath);\n db.run(CREATE_TABLE);\n const insert = db.prepare(\n `INSERT INTO ai_usage\n (ts, provider, model, tier, transport, capability, purpose,\n input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens,\n cost_usd, latency_ms, subprocess)\n VALUES ($ts, $provider, $model, $tier, $transport, $capability, $purpose,\n $input, $output, $cacheRead, $cacheCreation, $cost, $latency, $subprocess)`,\n );\n return insert;\n };\n\n return {\n async record(usage: Usage): Promise<void> {\n const insert = await (ready ??= init());\n insert.run({\n $ts: usage.ts || new Date().toISOString(),\n $provider: usage.provider,\n $model: usage.model,\n $tier: usage.tier ?? null,\n $transport: usage.transport,\n $capability: usage.capability,\n $purpose: usage.purpose ?? null,\n $input: usage.inputTokens,\n $output: usage.outputTokens,\n $cacheRead: usage.cacheReadTokens,\n $cacheCreation: usage.cacheCreationTokens,\n $cost: usage.costUsd,\n $latency: usage.latencyMs,\n $subprocess: usage.subprocess ? 1 : 0,\n });\n },\n };\n}\n\nexport interface CostSummary {\n totalUsd: number;\n byProvider: Record<string, number>;\n byCapability: Record<string, number>;\n}\n\n/** Aggregate the recorded spend from a sqliteSink DB. Creates the table if the\n * DB has never been written to, so an empty DB summarises cleanly to 0. */\nexport async function getCostSummary(dbPath: string): Promise<CostSummary> {\n const db = await openDb(dbPath);\n db.run(CREATE_TABLE);\n const total = db\n .query(`SELECT SUM(cost_usd) AS total FROM ai_usage`)\n .get() as { total: number | null };\n const byProvider: Record<string, number> = {};\n for (const row of db\n .query(`SELECT provider, SUM(cost_usd) AS sum FROM ai_usage GROUP BY provider`)\n .all() as { provider: string; sum: number }[]) {\n byProvider[row.provider] = row.sum;\n }\n const byCapability: Record<string, number> = {};\n for (const row of db\n .query(`SELECT capability, SUM(cost_usd) AS sum FROM ai_usage GROUP BY capability`)\n .all() as { capability: string; sum: number }[]) {\n byCapability[row.capability] = row.sum;\n }\n return { totalUsd: total?.total ?? 0, byProvider, byCapability };\n}\n"],"mappings":"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","names":["res"]}
|
package/package.json
CHANGED