@broberg/ai-sdk 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +41 -10
- package/dist/index.js +27 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -121,8 +121,20 @@ interface ChatRequest {
|
|
|
121
121
|
* conversation" (a conversation id, a session id). Requests sharing a prefix AND
|
|
122
122
|
* this key reuse the cached prefix at 10% of the input rate. Not auto-generated:
|
|
123
123
|
* only the caller knows what "the same conversation" means, and an SDK-invented
|
|
124
|
-
* key would either collide across tenants or never hit.
|
|
124
|
+
* key would either collide across tenants or never hit.
|
|
125
|
+
*
|
|
126
|
+
* BIND IT TO THE TENANT, not only to the conversation. This key IS a shared-prefix
|
|
127
|
+
* identity: two callers passing the same key can be served each other's cached
|
|
128
|
+
* prefix. So two tenants with identical transcripts must still get DIFFERENT keys
|
|
129
|
+
* — derive it from (tenant, conversation), never from the conversation alone.
|
|
130
|
+
* (components' requirement while building @broberg/chat, 2026-08-27, where two
|
|
131
|
+
* knowledge bases are written for readers with different permissions.) */
|
|
125
132
|
promptCacheKey?: string;
|
|
133
|
+
/** F039.2 — prompt caching is ON by default where the provider supports it.
|
|
134
|
+
* Set false to opt out (e.g. a one-shot call whose prefix will never repeat).
|
|
135
|
+
* Off has no cost benefit and no penalty; a cache MISS was measured to cost
|
|
136
|
+
* exactly the same as a call with no key at all. */
|
|
137
|
+
promptCache?: boolean;
|
|
126
138
|
temperature?: number;
|
|
127
139
|
/** "json" → request JSON-object output where the provider supports it (F009). */
|
|
128
140
|
responseFormat?: "json" | "text";
|
|
@@ -539,7 +551,6 @@ declare const messageSchema: z.ZodObject<{
|
|
|
539
551
|
}>, "many">>;
|
|
540
552
|
toolCallId: z.ZodOptional<z.ZodString>;
|
|
541
553
|
}, "strip", z.ZodTypeAny, {
|
|
542
|
-
role: "system" | "user" | "assistant" | "tool";
|
|
543
554
|
content: string | ({
|
|
544
555
|
text: string;
|
|
545
556
|
type: "text";
|
|
@@ -548,6 +559,7 @@ declare const messageSchema: z.ZodObject<{
|
|
|
548
559
|
type: "image";
|
|
549
560
|
mimeType?: string | undefined;
|
|
550
561
|
})[];
|
|
562
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
551
563
|
toolCalls?: {
|
|
552
564
|
id: string;
|
|
553
565
|
name: string;
|
|
@@ -555,7 +567,6 @@ declare const messageSchema: z.ZodObject<{
|
|
|
555
567
|
}[] | undefined;
|
|
556
568
|
toolCallId?: string | undefined;
|
|
557
569
|
}, {
|
|
558
|
-
role: "system" | "user" | "assistant" | "tool";
|
|
559
570
|
content: string | ({
|
|
560
571
|
text: string;
|
|
561
572
|
type: "text";
|
|
@@ -564,6 +575,7 @@ declare const messageSchema: z.ZodObject<{
|
|
|
564
575
|
type: "image";
|
|
565
576
|
mimeType?: string | undefined;
|
|
566
577
|
})[];
|
|
578
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
567
579
|
toolCalls?: {
|
|
568
580
|
id: string;
|
|
569
581
|
name: string;
|
|
@@ -602,8 +614,13 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
602
614
|
purpose: z.ZodOptional<z.ZodString>;
|
|
603
615
|
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
604
616
|
/** F039 — reuse a cached prompt prefix on Mistral at 10% of the input rate.
|
|
605
|
-
* A stable id for "the same conversation" (conversation id, session id).
|
|
617
|
+
* A stable id for "the same conversation" (conversation id, session id).
|
|
618
|
+
* Derive it from (tenant, conversation): the key is a shared-prefix identity,
|
|
619
|
+
* so two tenants with identical transcripts must get different keys. */
|
|
606
620
|
promptCacheKey: z.ZodOptional<z.ZodString>;
|
|
621
|
+
/** F039.2 — prompt caching is ON by default on providers that support it.
|
|
622
|
+
* false opts out; an explicit promptCacheKey always wins. */
|
|
623
|
+
promptCache: z.ZodOptional<z.ZodBoolean>;
|
|
607
624
|
prompt: z.ZodOptional<z.ZodString>;
|
|
608
625
|
messages: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
609
626
|
role: z.ZodEnum<["system", "user", "assistant", "tool"]>;
|
|
@@ -644,7 +661,6 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
644
661
|
}>, "many">>;
|
|
645
662
|
toolCallId: z.ZodOptional<z.ZodString>;
|
|
646
663
|
}, "strip", z.ZodTypeAny, {
|
|
647
|
-
role: "system" | "user" | "assistant" | "tool";
|
|
648
664
|
content: string | ({
|
|
649
665
|
text: string;
|
|
650
666
|
type: "text";
|
|
@@ -653,6 +669,7 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
653
669
|
type: "image";
|
|
654
670
|
mimeType?: string | undefined;
|
|
655
671
|
})[];
|
|
672
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
656
673
|
toolCalls?: {
|
|
657
674
|
id: string;
|
|
658
675
|
name: string;
|
|
@@ -660,7 +677,6 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
660
677
|
}[] | undefined;
|
|
661
678
|
toolCallId?: string | undefined;
|
|
662
679
|
}, {
|
|
663
|
-
role: "system" | "user" | "assistant" | "tool";
|
|
664
680
|
content: string | ({
|
|
665
681
|
text: string;
|
|
666
682
|
type: "text";
|
|
@@ -669,6 +685,7 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
669
685
|
type: "image";
|
|
670
686
|
mimeType?: string | undefined;
|
|
671
687
|
})[];
|
|
688
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
672
689
|
toolCalls?: {
|
|
673
690
|
id: string;
|
|
674
691
|
name: string;
|
|
@@ -699,7 +716,6 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
699
716
|
tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
|
|
700
717
|
prompt?: string | undefined;
|
|
701
718
|
messages?: {
|
|
702
|
-
role: "system" | "user" | "assistant" | "tool";
|
|
703
719
|
content: string | ({
|
|
704
720
|
text: string;
|
|
705
721
|
type: "text";
|
|
@@ -708,6 +724,7 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
708
724
|
type: "image";
|
|
709
725
|
mimeType?: string | undefined;
|
|
710
726
|
})[];
|
|
727
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
711
728
|
toolCalls?: {
|
|
712
729
|
id: string;
|
|
713
730
|
name: string;
|
|
@@ -723,6 +740,7 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
723
740
|
temperature?: number | undefined;
|
|
724
741
|
purpose?: string | undefined;
|
|
725
742
|
promptCacheKey?: string | undefined;
|
|
743
|
+
promptCache?: boolean | undefined;
|
|
726
744
|
maxTokens?: number | undefined;
|
|
727
745
|
responseFormat?: "text" | "json" | undefined;
|
|
728
746
|
override?: {
|
|
@@ -741,7 +759,6 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
741
759
|
tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
|
|
742
760
|
prompt?: string | undefined;
|
|
743
761
|
messages?: {
|
|
744
|
-
role: "system" | "user" | "assistant" | "tool";
|
|
745
762
|
content: string | ({
|
|
746
763
|
text: string;
|
|
747
764
|
type: "text";
|
|
@@ -750,6 +767,7 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
750
767
|
type: "image";
|
|
751
768
|
mimeType?: string | undefined;
|
|
752
769
|
})[];
|
|
770
|
+
role: "system" | "user" | "assistant" | "tool";
|
|
753
771
|
toolCalls?: {
|
|
754
772
|
id: string;
|
|
755
773
|
name: string;
|
|
@@ -765,6 +783,7 @@ declare const chatInputSchema: z.ZodObject<{
|
|
|
765
783
|
temperature?: number | undefined;
|
|
766
784
|
purpose?: string | undefined;
|
|
767
785
|
promptCacheKey?: string | undefined;
|
|
786
|
+
promptCache?: boolean | undefined;
|
|
768
787
|
maxTokens?: number | undefined;
|
|
769
788
|
responseFormat?: "text" | "json" | undefined;
|
|
770
789
|
override?: {
|
|
@@ -1707,6 +1726,9 @@ declare const ttsInputSchema: z.ZodObject<{
|
|
|
1707
1726
|
rate?: number | undefined;
|
|
1708
1727
|
}>;
|
|
1709
1728
|
declare const aiConfigSchema: z.ZodObject<{
|
|
1729
|
+
/** F039.2 — client-wide opt-out from prompt caching (default: on where the
|
|
1730
|
+
* provider supports it). A per-call `promptCache` wins over this. */
|
|
1731
|
+
promptCache: z.ZodOptional<z.ZodBoolean>;
|
|
1710
1732
|
defaults: z.ZodOptional<z.ZodRecord<z.ZodEnum<["fast", "smart", "powerful", "cheap", "vision", "video", "embedding"]>, z.ZodObject<{
|
|
1711
1733
|
provider: z.ZodString;
|
|
1712
1734
|
model: z.ZodString;
|
|
@@ -1746,6 +1768,7 @@ declare const aiConfigSchema: z.ZodObject<{
|
|
|
1746
1768
|
autoResolve?: boolean | undefined;
|
|
1747
1769
|
}>>;
|
|
1748
1770
|
}, "strip", z.ZodTypeAny, {
|
|
1771
|
+
promptCache?: boolean | undefined;
|
|
1749
1772
|
defaults?: Partial<Record<"fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding", {
|
|
1750
1773
|
provider: string;
|
|
1751
1774
|
model: string;
|
|
@@ -1762,6 +1785,7 @@ declare const aiConfigSchema: z.ZodObject<{
|
|
|
1762
1785
|
autoResolve?: boolean | undefined;
|
|
1763
1786
|
} | undefined;
|
|
1764
1787
|
}, {
|
|
1788
|
+
promptCache?: boolean | undefined;
|
|
1765
1789
|
defaults?: Partial<Record<"fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding", {
|
|
1766
1790
|
provider: string;
|
|
1767
1791
|
model: string;
|
|
@@ -2051,6 +2075,13 @@ interface OpenAICompatibleConfig {
|
|
|
2051
2075
|
* response's `usage.cost` (USD) as costUsd, falling back to the pricing table.
|
|
2052
2076
|
* Only OpenRouter returns this field — openai/deepinfra leave it false. */
|
|
2053
2077
|
costFromResponseField?: boolean;
|
|
2078
|
+
/** F039.2 — this provider accepts `prompt_cache_key` and caches a shared prefix
|
|
2079
|
+
* on it. Mistral only, deliberately: an unknown field is ignored by some
|
|
2080
|
+
* OpenAI-compatible servers and rejected with a 400 by others, so sending it
|
|
2081
|
+
* everywhere would trade a saving for an outage. Providers that cache
|
|
2082
|
+
* AUTOMATICALLY (openai, deepseek, gemini) need no key — they only need their
|
|
2083
|
+
* cached counts read back, which happens for every provider below. */
|
|
2084
|
+
supportsPromptCacheKey?: boolean;
|
|
2054
2085
|
}
|
|
2055
2086
|
declare function makeOpenAICompatibleAdapter(config: OpenAICompatibleConfig): ProviderAdapter;
|
|
2056
2087
|
|
|
@@ -2072,8 +2103,8 @@ declare const falStubAdapter: ProviderAdapter;
|
|
|
2072
2103
|
* wires the live adapters. */
|
|
2073
2104
|
declare const stubProviders: Record<string, ProviderAdapter>;
|
|
2074
2105
|
|
|
2075
|
-
declare const VERSION: "0.
|
|
2076
|
-
declare const SDK_TAG: "@broberg/ai-sdk@0.
|
|
2106
|
+
declare const VERSION: "0.31.0";
|
|
2107
|
+
declare const SDK_TAG: "@broberg/ai-sdk@0.31.0";
|
|
2077
2108
|
|
|
2078
2109
|
/** Built-in defaults. Every entry is overridable via AiConfig.defaults or a
|
|
2079
2110
|
* per-call override.
|
package/dist/index.js
CHANGED
|
@@ -485,6 +485,16 @@ function mapAnthropicStop(reason) {
|
|
|
485
485
|
}
|
|
486
486
|
|
|
487
487
|
// src/providers/openai-compatible.ts
|
|
488
|
+
function autoCacheKey(messages) {
|
|
489
|
+
const system = messages.find((m) => m.role === "system");
|
|
490
|
+
if (!system || typeof system.content !== "string" || system.content.length < 200) return void 0;
|
|
491
|
+
let h = 2166136261;
|
|
492
|
+
for (let i = 0; i < system.content.length; i++) {
|
|
493
|
+
h ^= system.content.charCodeAt(i);
|
|
494
|
+
h = Math.imul(h, 16777619) >>> 0;
|
|
495
|
+
}
|
|
496
|
+
return `ai-sdk-auto-${h.toString(16)}-${system.content.length}`;
|
|
497
|
+
}
|
|
488
498
|
function toOpenAIMessage(m) {
|
|
489
499
|
if (typeof m.content === "string") {
|
|
490
500
|
const base = { role: m.role, content: m.content };
|
|
@@ -523,7 +533,10 @@ function makeOpenAICompatibleAdapter(config) {
|
|
|
523
533
|
if (req.maxTokens !== void 0) body.max_tokens = req.maxTokens;
|
|
524
534
|
if (req.temperature !== void 0) body.temperature = req.temperature;
|
|
525
535
|
if (req.responseFormat === "json") body.response_format = { type: "json_object" };
|
|
526
|
-
if (req.
|
|
536
|
+
if (config.supportsPromptCacheKey && req.promptCache !== false) {
|
|
537
|
+
const k = req.promptCacheKey ?? autoCacheKey(req.messages);
|
|
538
|
+
if (k !== void 0) body.prompt_cache_key = k;
|
|
539
|
+
}
|
|
527
540
|
if (config.costFromResponseField) body.usage = { include: true };
|
|
528
541
|
const res = await httpTransport({
|
|
529
542
|
spec: req.spec,
|
|
@@ -1150,7 +1163,7 @@ var VOXTRAL_PRICE_PER_MIN = {
|
|
|
1150
1163
|
};
|
|
1151
1164
|
function mistralAdapter(config = {}) {
|
|
1152
1165
|
const baseUrl = config.baseUrl ?? "https://api.mistral.ai/v1";
|
|
1153
|
-
const base = makeOpenAICompatibleAdapter({ name: "mistral", baseUrl, apiKey: config.apiKey });
|
|
1166
|
+
const base = makeOpenAICompatibleAdapter({ name: "mistral", baseUrl, apiKey: config.apiKey, supportsPromptCacheKey: true });
|
|
1154
1167
|
function key() {
|
|
1155
1168
|
const k = config.apiKey ?? process.env.MISTRAL_API_KEY;
|
|
1156
1169
|
if (!k) throw new Error("mistral adapter: API key not set (env MISTRAL_API_KEY)");
|
|
@@ -2627,8 +2640,13 @@ var callOptions = {
|
|
|
2627
2640
|
};
|
|
2628
2641
|
var chatInputSchema = z.object({
|
|
2629
2642
|
/** F039 — reuse a cached prompt prefix on Mistral at 10% of the input rate.
|
|
2630
|
-
* A stable id for "the same conversation" (conversation id, session id).
|
|
2643
|
+
* A stable id for "the same conversation" (conversation id, session id).
|
|
2644
|
+
* Derive it from (tenant, conversation): the key is a shared-prefix identity,
|
|
2645
|
+
* so two tenants with identical transcripts must get different keys. */
|
|
2631
2646
|
promptCacheKey: z.string().optional(),
|
|
2647
|
+
/** F039.2 — prompt caching is ON by default on providers that support it.
|
|
2648
|
+
* false opts out; an explicit promptCacheKey always wins. */
|
|
2649
|
+
promptCache: z.boolean().optional(),
|
|
2632
2650
|
prompt: z.string().optional(),
|
|
2633
2651
|
messages: z.array(messageSchema).optional(),
|
|
2634
2652
|
system: z.string().optional(),
|
|
@@ -2777,6 +2795,9 @@ var availabilitySchema = z.object({
|
|
|
2777
2795
|
fallback: z.union([z.string(), z.array(z.string())]).optional()
|
|
2778
2796
|
});
|
|
2779
2797
|
var aiConfigSchema = z.object({
|
|
2798
|
+
/** F039.2 — client-wide opt-out from prompt caching (default: on where the
|
|
2799
|
+
* provider supports it). A per-call `promptCache` wins over this. */
|
|
2800
|
+
promptCache: z.boolean().optional(),
|
|
2780
2801
|
defaults: z.record(tierSchema, tierSpecSchema).optional(),
|
|
2781
2802
|
// Functions can't be deeply validated — z.custom asserts the TS type and
|
|
2782
2803
|
// passes the value through untouched.
|
|
@@ -2790,8 +2811,8 @@ var aiConfigSchema = z.object({
|
|
|
2790
2811
|
});
|
|
2791
2812
|
|
|
2792
2813
|
// src/version.ts
|
|
2793
|
-
var VERSION = "0.
|
|
2794
|
-
var SDK_TAG = "@broberg/ai-sdk@0.
|
|
2814
|
+
var VERSION = "0.31.0";
|
|
2815
|
+
var SDK_TAG = "@broberg/ai-sdk@0.31.0";
|
|
2795
2816
|
|
|
2796
2817
|
// src/cost/sinks/upmetrics.ts
|
|
2797
2818
|
function upmetricsSink(config) {
|
|
@@ -3075,7 +3096,7 @@ function createAI(config = {}) {
|
|
|
3075
3096
|
invoke: async (spec) => {
|
|
3076
3097
|
const adapter = pickProvider(spec.provider);
|
|
3077
3098
|
if (!adapter.chat) throw new Error(`createAI: provider "${spec.provider}" does not support chat`);
|
|
3078
|
-
return adapter.chat({ messages, spec, tools: input.tools, maxTokens: input.maxTokens, temperature: input.temperature, responseFormat: input.responseFormat, promptCacheKey: input.promptCacheKey });
|
|
3099
|
+
return adapter.chat({ messages, spec, tools: input.tools, maxTokens: input.maxTokens, temperature: input.temperature, responseFormat: input.responseFormat, promptCacheKey: input.promptCacheKey, promptCache: input.promptCache ?? cfg.promptCache });
|
|
3079
3100
|
}
|
|
3080
3101
|
});
|
|
3081
3102
|
},
|