@broberg/ai-sdk 0.28.0 → 0.29.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.
@@ -1,21 +1,56 @@
1
+ // src/routing/tier-map.ts
2
+ var DEFAULT_TIER_MAP = {
3
+ fast: { provider: "mistral", model: "mistral-small-latest", transport: "http" },
4
+ smart: { provider: "mistral", model: "mistral-large-latest", transport: "http" },
5
+ powerful: { provider: "mistral", model: "mistral-large-latest", transport: "http" },
6
+ cheap: { provider: "mistral", model: "mistral-small-latest", transport: "http" },
7
+ // Vision: small-latest (vision-capable, cheap EU) is the default; override to
8
+ // mistral-large-latest for demanding image/spatial/composition work.
9
+ vision: { provider: "mistral", model: "mistral-small-latest", transport: "http" },
10
+ // Native video understanding — Gemini leads; flash-lite is the cheap default (F019).
11
+ // NOT Anthropic → out of the F030 phase-out (its own EU epic if/when needed).
12
+ video: { provider: "gemini", model: "gemini-2.5-flash-lite", transport: "http" },
13
+ // NOT Anthropic → out of F030 (EU-embedding migration is its own future epic).
14
+ embedding: { provider: "openai", model: "text-embedding-3-small", transport: "http" }
15
+ };
16
+ function resolveTier(tier, override, configMap) {
17
+ const base = configMap?.[tier] ?? DEFAULT_TIER_MAP[tier];
18
+ return { ...base, ...override };
19
+ }
20
+
1
21
  // src/availability/registry.ts
2
22
  var SUSPENDED_FABLE_MYTHOS = "suspended \u2014 US export-control directive (2026-06-12)";
3
23
  var DEFAULTS = [
4
24
  // ── Anthropic ────────────────────────────────────────────────────────────
5
- { id: "claude-haiku-4-5", aliases: ["haiku", "fast"], provider: "anthropic", available: true, status: "available", source: "default" },
6
- { id: "claude-sonnet-4-6", aliases: ["sonnet", "smart"], provider: "anthropic", available: true, status: "available", source: "default" },
7
- { id: "claude-opus-4-8", aliases: ["opus", "powerful"], provider: "anthropic", available: true, status: "available", source: "default" },
25
+ { id: "claude-haiku-4-5", aliases: ["haiku"], provider: "anthropic", available: true, status: "available", source: "default" },
26
+ { id: "claude-sonnet-4-6", aliases: ["sonnet"], provider: "anthropic", available: true, status: "available", source: "default" },
27
+ { id: "claude-opus-4-8", aliases: ["opus"], provider: "anthropic", available: true, status: "available", source: "default" },
8
28
  { id: "claude-fable-5", aliases: ["fable"], provider: "anthropic", available: true, status: "available", source: "default" },
9
29
  { id: "claude-mythos-5", aliases: ["mythos"], provider: "anthropic", available: false, status: "suspended", note: SUSPENDED_FABLE_MYTHOS, source: "default" },
10
30
  // ── Gemini ───────────────────────────────────────────────────────────────
11
31
  { id: "gemini-2.5-flash", aliases: ["gemini-flash"], provider: "gemini", available: true, status: "available", source: "default" },
12
- { id: "gemini-2.5-flash-lite", aliases: ["gemini-flash-lite", "video"], provider: "gemini", available: true, status: "available", source: "default" },
32
+ { id: "gemini-2.5-flash-lite", aliases: ["gemini-flash-lite"], provider: "gemini", available: true, status: "available", source: "default" },
13
33
  // ── OpenAI ───────────────────────────────────────────────────────────────
14
- { id: "text-embedding-3-small", aliases: ["embedding"], provider: "openai", available: true, status: "available", source: "default" },
34
+ { id: "text-embedding-3-small", aliases: [], provider: "openai", available: true, status: "available", source: "default" },
15
35
  // ── Mistral (EU / GDPR) ──────────────────────────────────────────────────
16
36
  { id: "mistral-large-latest", aliases: ["mistral-large"], provider: "mistral", available: true, status: "available", source: "default" },
17
37
  { id: "mistral-small-latest", aliases: ["mistral-small"], provider: "mistral", available: true, status: "available", source: "default" }
18
38
  ];
39
+ var TIER_ALIAS_CONFLICTS = [];
40
+ function applyTierAliases(entries) {
41
+ for (const [tier, spec] of Object.entries(DEFAULT_TIER_MAP)) {
42
+ const owner = entries.find((e) => e.id === spec.model && e.provider === spec.provider);
43
+ for (const e of entries) {
44
+ if (e !== owner && e.aliases.includes(tier)) {
45
+ TIER_ALIAS_CONFLICTS.push(`${tier} is hand-declared on ${e.id} (${e.provider}) but tier ${tier} calls ${spec.model} (${spec.provider})`);
46
+ e.aliases = e.aliases.filter((a) => a !== tier);
47
+ }
48
+ }
49
+ if (owner && !owner.aliases.includes(tier)) owner.aliases.push(tier);
50
+ }
51
+ return entries;
52
+ }
53
+ applyTierAliases(DEFAULTS);
19
54
  var OVERLAY = /* @__PURE__ */ new Map();
20
55
  var ALIAS_INDEX = /* @__PURE__ */ new Map();
21
56
  function seed() {
@@ -83,15 +118,16 @@ var ModelUnavailableError = class extends Error {
83
118
  function listModels(opts = {}) {
84
119
  return allEntries(opts.provider);
85
120
  }
86
- function isAvailable(requested) {
121
+ function isAvailable(requested, requireKnown = false) {
87
122
  const e = getEntry(requested);
88
- return e ? e.available : true;
123
+ if (!e) return !requireKnown;
124
+ return e.available;
89
125
  }
90
126
  function resolveModel(requested, opts = {}) {
91
127
  const id = canonicalId(requested) ?? requested;
92
128
  const entry = getEntry(requested);
93
129
  const provider = opts.provider ?? entry?.provider;
94
- if (isAvailable(requested)) {
130
+ if (isAvailable(requested, opts.requireKnown)) {
95
131
  return {
96
132
  ok: true,
97
133
  model: id,
@@ -103,7 +139,7 @@ function resolveModel(requested, opts = {}) {
103
139
  }
104
140
  const chain = opts.fallback === void 0 ? [] : Array.isArray(opts.fallback) ? opts.fallback : [opts.fallback];
105
141
  for (const fb of chain) {
106
- if (isAvailable(fb)) {
142
+ if (isAvailable(fb, opts.requireKnown)) {
107
143
  const fbId = canonicalId(fb) ?? fb;
108
144
  return {
109
145
  ok: false,
@@ -116,8 +152,10 @@ function resolveModel(requested, opts = {}) {
116
152
  };
117
153
  }
118
154
  }
155
+ const unknownAndGating = !entry && opts.requireKnown;
156
+ const reason = unknownAndGating ? `${id} is not a model this registry knows \u2014 requireKnown was set, so it is not assumed usable` : entry?.note ?? `${id} is unavailable`;
119
157
  if (opts.throwIfUnavailable) {
120
- throw new ModelUnavailableError(id, entry?.note, provider);
158
+ throw new ModelUnavailableError(id, reason, provider);
121
159
  }
122
160
  return {
123
161
  ok: false,
@@ -125,12 +163,14 @@ function resolveModel(requested, opts = {}) {
125
163
  requested: id,
126
164
  provider,
127
165
  fellBack: false,
128
- status: entry?.status ?? "suspended",
129
- reason: entry?.note ?? `${id} is unavailable`
166
+ status: entry?.status ?? "unknown",
167
+ reason
130
168
  };
131
169
  }
132
170
 
133
171
  export {
172
+ DEFAULT_TIER_MAP,
173
+ resolveTier,
134
174
  resetRegistry,
135
175
  providerIds,
136
176
  setAvailability,
@@ -138,4 +178,4 @@ export {
138
178
  listModels,
139
179
  resolveModel
140
180
  };
141
- //# sourceMappingURL=chunk-IT7HNKLY.js.map
181
+ //# sourceMappingURL=chunk-V2PD522L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/routing/tier-map.ts","../src/availability/registry.ts","../src/availability/types.ts","../src/availability/resolve.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.\n *\n * F030 — Anthropic API phase-out: `ANTHROPIC_API_KEY` was globally removed, so the\n * default cloud route may NOT hit Anthropic Console. `fast`/`smart`/`powerful`/\n * `vision` now default to **Mistral EU** (Paris-hosted, Schrems II-safe — so every\n * default text/vision call is GDPR-safe by default). Claude stays reachable as a\n * NON-default quality fallback for non-PII via `override:{provider:\"openrouter\",\n * model:\"anthropic/claude-…\"}`. DeepSeek (CN) is the opt-in non-PII secondary\n * (`provider:\"deepseek\"`), never a default. Magistral (reasoning) / mistral-large\n * for vision are per-call overrides, not defaults (don't pay the premium on all). */\nexport const DEFAULT_TIER_MAP: Record<Tier, TierSpec> = {\n fast: { provider: \"mistral\", model: \"mistral-small-latest\", transport: \"http\" },\n smart: { provider: \"mistral\", model: \"mistral-large-latest\", transport: \"http\" },\n powerful: { provider: \"mistral\", model: \"mistral-large-latest\", transport: \"http\" },\n cheap: { provider: \"mistral\", model: \"mistral-small-latest\", transport: \"http\" },\n // Vision: small-latest (vision-capable, cheap EU) is the default; override to\n // mistral-large-latest for demanding image/spatial/composition work.\n vision: { provider: \"mistral\", model: \"mistral-small-latest\", transport: \"http\" },\n // Native video understanding — Gemini leads; flash-lite is the cheap default (F019).\n // NOT Anthropic → out of the F030 phase-out (its own EU epic if/when needed).\n video: { provider: \"gemini\", model: \"gemini-2.5-flash-lite\", transport: \"http\" },\n // NOT Anthropic → out of F030 (EU-embedding migration is its own future epic).\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","// F022 — the model-availability registry: the ONE source both resolveModel()\n// (spawn / call path) and listModels() (UI picker) read. A curated default seed\n// (works offline — the durable floor) plus a mutable overlay that\n// refreshAvailability() updates from the live provider list.\n//\n// Scope note: this is a LIVENESS view (is this id alive right now?), not the\n// rich capability/price inventory (that is F017 src/catalogue). We only track\n// ids we want to assert status on; anything not here is fail-open (treated\n// available) so we never block a model we simply do not track.\nimport { DEFAULT_TIER_MAP } from \"../routing/tier-map.js\";\nimport type { AvailabilityStatus, AvailabilitySource, ModelStatus } from \"./types.js\";\n\n/** Internal registry row. `aliases[0]` surfaces as ModelStatus.alias. */\nexport interface RegistryEntry {\n id: string;\n aliases: string[];\n provider: string;\n available: boolean;\n status: AvailabilityStatus;\n note?: string;\n source: AvailabilitySource;\n}\n\nconst SUSPENDED_FABLE_MYTHOS = \"suspended — US export-control directive (2026-06-12)\";\n\n/** Curated defaults. Aliases here are MODEL-IDENTITY names only (short names for\n * the model itself). TIER aliases — fast/smart/powerful/cheap/vision/video/\n * embedding — are NOT written here: they are derived from DEFAULT_TIER_MAP below,\n * because hand-maintaining them in two places is exactly how they drifted.\n *\n * They HAD drifted, and it crossed the EU border: this list said `smart` was\n * claude-sonnet-4-6 (Anthropic, US) for the ~3 months after F030 pointed the\n * default tiers at Mistral EU, so resolveModel('smart') named a US model while\n * ai.chat({tier:'smart'}) called an EU one. Anyone using resolveModel to SHOW or\n * DECIDE where data goes — the obvious use — got the wrong answer. Measured by\n * fd-sundhed in 0.21.1, still true in 0.28.0, fixed here by deleting the second\n * list rather than correcting it. */\nconst DEFAULTS: RegistryEntry[] = [\n // ── Anthropic ────────────────────────────────────────────────────────────\n { id: \"claude-haiku-4-5\", aliases: [\"haiku\"], provider: \"anthropic\", available: true, status: \"available\", source: \"default\" },\n { id: \"claude-sonnet-4-6\", aliases: [\"sonnet\"], provider: \"anthropic\", available: true, status: \"available\", source: \"default\" },\n { id: \"claude-opus-4-8\", aliases: [\"opus\"], provider: \"anthropic\", available: true, status: \"available\", source: \"default\" },\n { id: \"claude-fable-5\", aliases: [\"fable\"], provider: \"anthropic\", available: true, status: \"available\", source: \"default\" },\n { id: \"claude-mythos-5\", aliases: [\"mythos\"], provider: \"anthropic\", available: false, status: \"suspended\", note: SUSPENDED_FABLE_MYTHOS, source: \"default\" },\n // ── Gemini ───────────────────────────────────────────────────────────────\n { id: \"gemini-2.5-flash\", aliases: [\"gemini-flash\"], provider: \"gemini\", available: true, status: \"available\", source: \"default\" },\n { id: \"gemini-2.5-flash-lite\", aliases: [\"gemini-flash-lite\"], provider: \"gemini\", available: true, status: \"available\", source: \"default\" },\n // ── OpenAI ───────────────────────────────────────────────────────────────\n { id: \"text-embedding-3-small\", aliases: [], provider: \"openai\", available: true, status: \"available\", source: \"default\" },\n // ── Mistral (EU / GDPR) ──────────────────────────────────────────────────\n { id: \"mistral-large-latest\", aliases: [\"mistral-large\"], provider: \"mistral\", available: true, status: \"available\", source: \"default\" },\n { id: \"mistral-small-latest\", aliases: [\"mistral-small\"], provider: \"mistral\", available: true, status: \"available\", source: \"default\" },\n];\n\n/** Attach every tier name as an alias of the model that tier ACTUALLY calls.\n * One source: DEFAULT_TIER_MAP decides, the registry follows. A tier whose model\n * is not in the registry is left unaliased on purpose — resolveModel then reports\n * status \"unknown\" (fail-open) instead of inventing a row, and the drift test\n * catches it. */\nexport const TIER_ALIAS_CONFLICTS: string[] = [];\n\nfunction applyTierAliases(entries: RegistryEntry[]): RegistryEntry[] {\n for (const [tier, spec] of Object.entries(DEFAULT_TIER_MAP)) {\n const owner = entries.find((e) => e.id === spec.model && e.provider === spec.provider);\n // A tier name hand-written on any OTHER row is the drift bug returning. It\n // would resolve correctly TODAY only because seed() lets the last write win\n // and the rows happen to be ordered favourably — reorder the array and the\n // tier silently points at the wrong provider again. Record it so a test can\n // fail on it, then strip it so runtime is right regardless.\n for (const e of entries) {\n if (e !== owner && e.aliases.includes(tier)) {\n TIER_ALIAS_CONFLICTS.push(`${tier} is hand-declared on ${e.id} (${e.provider}) but tier ${tier} calls ${spec.model} (${spec.provider})`);\n e.aliases = e.aliases.filter((a) => a !== tier);\n }\n }\n if (owner && !owner.aliases.includes(tier)) owner.aliases.push(tier);\n }\n return entries;\n}\napplyTierAliases(DEFAULTS);\n\n/** The live overlay, keyed by canonical id. Seeded from DEFAULTS (deep-copied so\n * resetting is clean). refreshAvailability() mutates this; resolve/listModels\n * read it synchronously. */\nlet OVERLAY = new Map<string, RegistryEntry>();\n/** alias → canonical id, rebuilt whenever the overlay is seeded. */\nlet ALIAS_INDEX = new Map<string, string>();\n\nfunction seed(): void {\n OVERLAY = new Map(DEFAULTS.map((e) => [e.id, { ...e, aliases: [...e.aliases] }]));\n ALIAS_INDEX = new Map();\n for (const e of DEFAULTS) for (const a of e.aliases) ALIAS_INDEX.set(a, e.id);\n}\nseed();\n\n/** Reset the overlay back to the curated defaults. For tests. */\nexport function resetRegistry(): void {\n seed();\n}\n\n/** Canonical id for a model id OR alias; null when we track neither. */\nexport function canonicalId(requested: string): string | null {\n if (OVERLAY.has(requested)) return requested;\n return ALIAS_INDEX.get(requested) ?? null;\n}\n\n/** The current entry for an id/alias, or undefined when untracked (fail-open). */\nexport function getEntry(requested: string): RegistryEntry | undefined {\n const id = canonicalId(requested);\n return id ? OVERLAY.get(id) : undefined;\n}\n\n/** All tracked entries (optionally provider-scoped), as a public ModelStatus[]. */\nexport function allEntries(provider?: string): ModelStatus[] {\n const rows: ModelStatus[] = [];\n for (const e of OVERLAY.values()) {\n if (provider && e.provider !== provider) continue;\n rows.push({\n id: e.id,\n alias: e.aliases[0],\n provider: e.provider,\n available: e.available,\n status: e.status,\n note: e.note,\n source: e.source,\n });\n }\n return rows;\n}\n\n/** Provider-scoped canonical ids (for refresh reconciliation). */\nexport function providerIds(provider: string): string[] {\n return [...OVERLAY.values()].filter((e) => e.provider === provider).map((e) => e.id);\n}\n\n/** Mark a tracked id available/suspended from a live refresh. No-op if untracked. */\nexport function setAvailability(id: string, available: boolean, note?: string): void {\n const e = OVERLAY.get(id);\n if (!e) return;\n e.available = available;\n e.status = available ? \"available\" : \"suspended\";\n e.source = \"refresh\";\n if (note !== undefined) e.note = note;\n else if (available) e.note = undefined;\n}\n","// F022 — Model Availability Harness. Public types for the availability layer:\n// the shared status read (ModelStatus), the resolve result, and the structured\n// error a caller can flag on. The registry is the one source both the spawn /\n// call path (resolveModel) and UI pickers (listModels) read.\n\nexport type AvailabilityStatus = \"available\" | \"suspended\" | \"unknown\";\n\n/** Where a model's current availability came from: the curated default seed,\n * or a live provider refresh (Anthropic GET /v1/models). */\nexport type AvailabilitySource = \"default\" | \"refresh\";\n\n/** One row of the shared status read — what a UI model-picker renders. */\nexport interface ModelStatus {\n /** Canonical provider model id, e.g. \"claude-fable-5\". */\n id: string;\n /** Short/tier alias, e.g. \"fable\" (the first registered alias). */\n alias?: string;\n /** \"anthropic\" | \"openai\" | \"gemini\" | \"mistral\" | … */\n provider: string;\n available: boolean;\n status: AvailabilityStatus;\n /** Friendly reason, e.g. \"suspended — US export-control directive (2026-06-12)\". */\n note?: string;\n source: AvailabilitySource;\n}\n\n/** Result of resolveModel — the spawn / call path consumes this synchronously. */\nexport interface ResolveResult {\n /** True when the requested model itself is available. */\n ok: boolean;\n /** The id to actually use: `requested` when ok, else the first available fallback. */\n model: string;\n /** What the caller asked for (id or alias, normalized to the canonical id). */\n requested: string;\n provider?: string;\n /** True when `model` differs from `requested` because we fell back. */\n fellBack: boolean;\n status: AvailabilityStatus;\n /** Why it degraded / why it is unavailable. */\n reason?: string;\n}\n\n/** Thrown by resolveModel when the requested model is unavailable, no usable\n * fallback exists, and the caller passed `throwIfUnavailable`. Callers flag on\n * `.code === \"model_unavailable\"`. */\nexport class ModelUnavailableError extends Error {\n readonly code = \"model_unavailable\";\n readonly requested: string;\n readonly provider?: string;\n readonly note?: string;\n constructor(requested: string, note?: string, provider?: string) {\n super(`model \"${requested}\" is unavailable${note ? ` (${note})` : \"\"}`);\n this.name = \"ModelUnavailableError\";\n this.requested = requested;\n this.note = note;\n this.provider = provider;\n }\n}\n","// F022 — the synchronous, zero-I/O resolve + status read. This is the spawn /\n// call hot path (buddy's launcher calls resolveModel per spawn, cardmem #4842):\n// it MUST never await and never touch the network. Freshness comes only from a\n// prior async refreshAvailability(); resolve just reads the in-memory registry.\nimport { allEntries, canonicalId, getEntry } from \"./registry.js\";\nimport { ModelUnavailableError } from \"./types.js\";\nimport type { ModelStatus, ResolveResult } from \"./types.js\";\n\nexport interface ResolveOptions {\n /** One id/alias or an ordered chain to try when `requested` is unavailable. */\n fallback?: string | string[];\n /** Scope hint (passed through to the result); does not gate lookup. */\n provider?: string;\n /** Throw ModelUnavailableError instead of returning ok:false when there is no\n * usable fallback. For callers that want to flag rather than degrade. */\n throwIfUnavailable?: boolean;\n /** Treat an id we do not track as UNUSABLE instead of fail-open.\n *\n * Default is fail-open: we never block a model we simply do not track. That is\n * right for liveness, and wrong for a caller who is GATING — cms measured the\n * consequence: resolveModel(\"cheap\") answered {ok:true, model:\"cheap\"}, so a\n * consumer following our own instruction to gate on `ok` passed the gate and\n * then sent the literal string \"cheap\" to a provider as a model id. A\n * success-shaped non-answer is worse than an error, because an error gets\n * handled and a shape does not.\n *\n * Set this when you need \"a model you actually know about\". Off by default so\n * no existing caller changes behaviour. */\n requireKnown?: boolean;\n}\n\n/** The shared status read — UI pickers grey out `available:false` rows. */\nexport function listModels(opts: { provider?: string } = {}): ModelStatus[] {\n return allEntries(opts.provider);\n}\n\n/** Is this id/alias currently usable? Untracked ids are fail-open (true) unless\n * the caller asked for requireKnown. */\nfunction isAvailable(requested: string, requireKnown = false): boolean {\n const e = getEntry(requested);\n if (!e) return !requireKnown; // fail-open on unknown, unless gating\n return e.available;\n}\n\n/**\n * Resolve a requested model (id or alias) to one that is actually usable.\n * Synchronous + offline by contract (cardmem #4842) — reads the registry only.\n *\n * - Available → pass through ({ ok:true, fellBack:false }).\n * - Unavailable + a fallback that IS available → swap ({ ok:false, fellBack:true }).\n * - Unavailable + no usable fallback → throw (throwIfUnavailable) or return ok:false.\n * - Unknown id → treated available (never block a model we do not track).\n */\nexport function resolveModel(requested: string, opts: ResolveOptions = {}): ResolveResult {\n const id = canonicalId(requested) ?? requested;\n const entry = getEntry(requested);\n const provider = opts.provider ?? entry?.provider;\n\n if (isAvailable(requested, opts.requireKnown)) {\n return {\n ok: true,\n model: id,\n requested: id,\n provider,\n fellBack: false,\n status: entry?.status ?? \"unknown\",\n };\n }\n\n // Requested is suspended — walk the fallback chain for the first available one.\n const chain = opts.fallback === undefined ? [] : Array.isArray(opts.fallback) ? opts.fallback : [opts.fallback];\n for (const fb of chain) {\n if (isAvailable(fb, opts.requireKnown)) {\n const fbId = canonicalId(fb) ?? fb;\n return {\n ok: false,\n model: fbId,\n requested: id,\n provider,\n fellBack: true,\n status: entry?.status ?? \"suspended\",\n reason: entry?.note ?? `${id} is unavailable`,\n };\n }\n }\n\n // No usable fallback.\n const unknownAndGating = !entry && opts.requireKnown;\n const reason = unknownAndGating\n ? `${id} is not a model this registry knows — requireKnown was set, so it is not assumed usable`\n : (entry?.note ?? `${id} is unavailable`);\n if (opts.throwIfUnavailable) {\n throw new ModelUnavailableError(id, reason, provider);\n }\n return {\n ok: false,\n model: id,\n requested: id,\n provider,\n fellBack: false,\n status: entry?.status ?? \"unknown\",\n reason,\n };\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.ts CHANGED
@@ -687,6 +687,7 @@ declare const chatInputSchema: z.ZodObject<{
687
687
  responseFormat: z.ZodOptional<z.ZodEnum<["json", "text"]>>;
688
688
  }, "strip", z.ZodTypeAny, {
689
689
  system?: string | undefined;
690
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
690
691
  prompt?: string | undefined;
691
692
  messages?: {
692
693
  role: "system" | "user" | "assistant" | "tool";
@@ -714,7 +715,6 @@ declare const chatInputSchema: z.ZodObject<{
714
715
  purpose?: string | undefined;
715
716
  maxTokens?: number | undefined;
716
717
  responseFormat?: "text" | "json" | undefined;
717
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
718
718
  override?: {
719
719
  provider?: string | undefined;
720
720
  model?: string | undefined;
@@ -728,6 +728,7 @@ declare const chatInputSchema: z.ZodObject<{
728
728
  labels?: Record<string, string> | undefined;
729
729
  }, {
730
730
  system?: string | undefined;
731
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
731
732
  prompt?: string | undefined;
732
733
  messages?: {
733
734
  role: "system" | "user" | "assistant" | "tool";
@@ -755,7 +756,6 @@ declare const chatInputSchema: z.ZodObject<{
755
756
  purpose?: string | undefined;
756
757
  maxTokens?: number | undefined;
757
758
  responseFormat?: "text" | "json" | undefined;
758
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
759
759
  override?: {
760
760
  provider?: string | undefined;
761
761
  model?: string | undefined;
@@ -808,9 +808,9 @@ declare const visionInputSchema: z.ZodObject<{
808
808
  image: string | Uint8Array<ArrayBuffer>;
809
809
  prompt: string;
810
810
  system?: string | undefined;
811
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
811
812
  mimeType?: string | undefined;
812
813
  purpose?: string | undefined;
813
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
814
814
  override?: {
815
815
  provider?: string | undefined;
816
816
  model?: string | undefined;
@@ -826,9 +826,9 @@ declare const visionInputSchema: z.ZodObject<{
826
826
  image: string | Uint8Array<ArrayBuffer>;
827
827
  prompt: string;
828
828
  system?: string | undefined;
829
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
829
830
  mimeType?: string | undefined;
830
831
  purpose?: string | undefined;
831
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
832
832
  override?: {
833
833
  provider?: string | undefined;
834
834
  model?: string | undefined;
@@ -880,9 +880,9 @@ declare const videoInputSchema: z.ZodObject<{
880
880
  video: string | Uint8Array<ArrayBuffer>;
881
881
  prompt: string;
882
882
  system?: string | undefined;
883
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
883
884
  mimeType?: string | undefined;
884
885
  purpose?: string | undefined;
885
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
886
886
  override?: {
887
887
  provider?: string | undefined;
888
888
  model?: string | undefined;
@@ -898,9 +898,9 @@ declare const videoInputSchema: z.ZodObject<{
898
898
  video: string | Uint8Array<ArrayBuffer>;
899
899
  prompt: string;
900
900
  system?: string | undefined;
901
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
901
902
  mimeType?: string | undefined;
902
903
  purpose?: string | undefined;
903
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
904
904
  override?: {
905
905
  provider?: string | undefined;
906
906
  model?: string | undefined;
@@ -949,8 +949,8 @@ declare const translateInputSchema: z.ZodObject<{
949
949
  }, "strip", z.ZodTypeAny, {
950
950
  text: string;
951
951
  to: string;
952
- purpose?: string | undefined;
953
952
  tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
953
+ purpose?: string | undefined;
954
954
  override?: {
955
955
  provider?: string | undefined;
956
956
  model?: string | undefined;
@@ -966,8 +966,8 @@ declare const translateInputSchema: z.ZodObject<{
966
966
  }, {
967
967
  text: string;
968
968
  to: string;
969
- purpose?: string | undefined;
970
969
  tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
970
+ purpose?: string | undefined;
971
971
  override?: {
972
972
  provider?: string | undefined;
973
973
  model?: string | undefined;
@@ -1045,6 +1045,7 @@ declare const imageInputSchema: z.ZodObject<{
1045
1045
  retryOnBlack: z.ZodOptional<z.ZodBoolean>;
1046
1046
  }, "strip", z.ZodTypeAny, {
1047
1047
  prompt: string;
1048
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1048
1049
  seed?: number | undefined;
1049
1050
  purpose?: string | undefined;
1050
1051
  loras?: {
@@ -1054,7 +1055,6 @@ declare const imageInputSchema: z.ZodObject<{
1054
1055
  lora?: string | undefined;
1055
1056
  width?: number | undefined;
1056
1057
  height?: number | undefined;
1057
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1058
1058
  override?: {
1059
1059
  provider?: string | undefined;
1060
1060
  model?: string | undefined;
@@ -1074,6 +1074,7 @@ declare const imageInputSchema: z.ZodObject<{
1074
1074
  retryOnBlack?: boolean | undefined;
1075
1075
  }, {
1076
1076
  prompt: string;
1077
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1077
1078
  seed?: number | undefined;
1078
1079
  purpose?: string | undefined;
1079
1080
  loras?: {
@@ -1083,7 +1084,6 @@ declare const imageInputSchema: z.ZodObject<{
1083
1084
  lora?: string | undefined;
1084
1085
  width?: number | undefined;
1085
1086
  height?: number | undefined;
1086
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1087
1087
  override?: {
1088
1088
  provider?: string | undefined;
1089
1089
  model?: string | undefined;
@@ -1142,10 +1142,10 @@ declare const animateInputSchema: z.ZodObject<{
1142
1142
  resolution: z.ZodOptional<z.ZodString>;
1143
1143
  }, "strip", z.ZodTypeAny, {
1144
1144
  image: string | Uint8Array<ArrayBuffer>;
1145
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1145
1146
  prompt?: string | undefined;
1146
1147
  resolution?: string | undefined;
1147
1148
  purpose?: string | undefined;
1148
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1149
1149
  override?: {
1150
1150
  provider?: string | undefined;
1151
1151
  model?: string | undefined;
@@ -1160,10 +1160,10 @@ declare const animateInputSchema: z.ZodObject<{
1160
1160
  durationSec?: number | undefined;
1161
1161
  }, {
1162
1162
  image: string | Uint8Array<ArrayBuffer>;
1163
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1163
1164
  prompt?: string | undefined;
1164
1165
  resolution?: string | undefined;
1165
1166
  purpose?: string | undefined;
1166
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1167
1167
  override?: {
1168
1168
  provider?: string | undefined;
1169
1169
  model?: string | undefined;
@@ -1216,9 +1216,9 @@ declare const trainStyleInputSchema: z.ZodObject<{
1216
1216
  createMasks: z.ZodOptional<z.ZodBoolean>;
1217
1217
  }, "strip", z.ZodTypeAny, {
1218
1218
  images: string | string[];
1219
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1219
1220
  purpose?: string | undefined;
1220
1221
  steps?: number | undefined;
1221
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1222
1222
  override?: {
1223
1223
  provider?: string | undefined;
1224
1224
  model?: string | undefined;
@@ -1235,9 +1235,9 @@ declare const trainStyleInputSchema: z.ZodObject<{
1235
1235
  createMasks?: boolean | undefined;
1236
1236
  }, {
1237
1237
  images: string | string[];
1238
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1238
1239
  purpose?: string | undefined;
1239
1240
  steps?: number | undefined;
1240
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1241
1241
  override?: {
1242
1242
  provider?: string | undefined;
1243
1243
  model?: string | undefined;
@@ -1286,8 +1286,8 @@ declare const embeddingInputSchema: z.ZodObject<{
1286
1286
  text: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
1287
1287
  }, "strip", z.ZodTypeAny, {
1288
1288
  text: string | string[];
1289
- purpose?: string | undefined;
1290
1289
  tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1290
+ purpose?: string | undefined;
1291
1291
  override?: {
1292
1292
  provider?: string | undefined;
1293
1293
  model?: string | undefined;
@@ -1301,8 +1301,8 @@ declare const embeddingInputSchema: z.ZodObject<{
1301
1301
  labels?: Record<string, string> | undefined;
1302
1302
  }, {
1303
1303
  text: string | string[];
1304
- purpose?: string | undefined;
1305
1304
  tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1305
+ purpose?: string | undefined;
1306
1306
  override?: {
1307
1307
  provider?: string | undefined;
1308
1308
  model?: string | undefined;
@@ -1359,9 +1359,9 @@ declare const transcribeInputSchema: z.ZodObject<{
1359
1359
  timestamps: z.ZodOptional<z.ZodUnion<[z.ZodEnum<["word", "segment"]>, z.ZodArray<z.ZodEnum<["word", "segment"]>, "many">]>>;
1360
1360
  }, "strip", z.ZodTypeAny, {
1361
1361
  audio: string | Uint8Array<ArrayBuffer>;
1362
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1362
1363
  language?: string | undefined;
1363
1364
  purpose?: string | undefined;
1364
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1365
1365
  override?: {
1366
1366
  provider?: string | undefined;
1367
1367
  model?: string | undefined;
@@ -1378,9 +1378,9 @@ declare const transcribeInputSchema: z.ZodObject<{
1378
1378
  timestamps?: "word" | "segment" | ("word" | "segment")[] | undefined;
1379
1379
  }, {
1380
1380
  audio: string | Uint8Array<ArrayBuffer>;
1381
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1381
1382
  language?: string | undefined;
1382
1383
  purpose?: string | undefined;
1383
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1384
1384
  override?: {
1385
1385
  provider?: string | undefined;
1386
1386
  model?: string | undefined;
@@ -1432,9 +1432,9 @@ declare const ocrInputSchema: z.ZodObject<{
1432
1432
  mimeType: z.ZodOptional<z.ZodString>;
1433
1433
  }, "strip", z.ZodTypeAny, {
1434
1434
  document: string | Uint8Array<ArrayBuffer>;
1435
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1435
1436
  mimeType?: string | undefined;
1436
1437
  purpose?: string | undefined;
1437
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1438
1438
  override?: {
1439
1439
  provider?: string | undefined;
1440
1440
  model?: string | undefined;
@@ -1448,9 +1448,9 @@ declare const ocrInputSchema: z.ZodObject<{
1448
1448
  labels?: Record<string, string> | undefined;
1449
1449
  }, {
1450
1450
  document: string | Uint8Array<ArrayBuffer>;
1451
+ tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1451
1452
  mimeType?: string | undefined;
1452
1453
  purpose?: string | undefined;
1453
- tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1454
1454
  override?: {
1455
1455
  provider?: string | undefined;
1456
1456
  model?: string | undefined;
@@ -1496,8 +1496,8 @@ declare const moderationInputSchema: z.ZodObject<{
1496
1496
  input: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
1497
1497
  }, "strip", z.ZodTypeAny, {
1498
1498
  input: string | string[];
1499
- purpose?: string | undefined;
1500
1499
  tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1500
+ purpose?: string | undefined;
1501
1501
  override?: {
1502
1502
  provider?: string | undefined;
1503
1503
  model?: string | undefined;
@@ -1511,8 +1511,8 @@ declare const moderationInputSchema: z.ZodObject<{
1511
1511
  labels?: Record<string, string> | undefined;
1512
1512
  }, {
1513
1513
  input: string | string[];
1514
- purpose?: string | undefined;
1515
1514
  tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1515
+ purpose?: string | undefined;
1516
1516
  override?: {
1517
1517
  provider?: string | undefined;
1518
1518
  model?: string | undefined;
@@ -1573,8 +1573,8 @@ declare const podcastInputSchema: z.ZodObject<{
1573
1573
  speaker: string;
1574
1574
  }[];
1575
1575
  voices: Record<string, string>;
1576
- purpose?: string | undefined;
1577
1576
  tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1577
+ purpose?: string | undefined;
1578
1578
  override?: {
1579
1579
  provider?: string | undefined;
1580
1580
  model?: string | undefined;
@@ -1593,8 +1593,8 @@ declare const podcastInputSchema: z.ZodObject<{
1593
1593
  speaker: string;
1594
1594
  }[];
1595
1595
  voices: Record<string, string>;
1596
- purpose?: string | undefined;
1597
1596
  tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1597
+ purpose?: string | undefined;
1598
1598
  override?: {
1599
1599
  provider?: string | undefined;
1600
1600
  model?: string | undefined;
@@ -1641,7 +1641,15 @@ declare const ttsInputSchema: z.ZodObject<{
1641
1641
  text: z.ZodString;
1642
1642
  voice: z.ZodString;
1643
1643
  /** F037: voice to use if `voice` is one we know the provider has retired. Without
1644
- * it a retired voice throws VoiceUnavailableError rather than reaching the API. */
1644
+ * it a retired voice throws VoiceUnavailableError rather than reaching the API.
1645
+ *
1646
+ * THINK BEFORE SETTING THIS. It is right for batch work where any acceptable voice
1647
+ * will do (a generated podcast, a bulk render). It is WRONG where the voice is an
1648
+ * identity a human recognises — a brand voice, a house narrator: falling back means
1649
+ * your product suddenly speaks with a stranger's voice and says nothing about why.
1650
+ * There, leave it unset and let the throw alarm you. Silence WITH a message beats
1651
+ * the wrong audio WITHOUT one. (torrent-search-api's call on their own house voice,
1652
+ * 2026-08-11 — they took the alarm over the fallback, deliberately.) */
1645
1653
  voiceFallback: z.ZodOptional<z.ZodString>;
1646
1654
  lang: z.ZodOptional<z.ZodString>;
1647
1655
  format: z.ZodOptional<z.ZodString>;
@@ -1649,8 +1657,8 @@ declare const ttsInputSchema: z.ZodObject<{
1649
1657
  }, "strip", z.ZodTypeAny, {
1650
1658
  text: string;
1651
1659
  voice: string;
1652
- purpose?: string | undefined;
1653
1660
  tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1661
+ purpose?: string | undefined;
1654
1662
  override?: {
1655
1663
  provider?: string | undefined;
1656
1664
  model?: string | undefined;
@@ -1669,8 +1677,8 @@ declare const ttsInputSchema: z.ZodObject<{
1669
1677
  }, {
1670
1678
  text: string;
1671
1679
  voice: string;
1672
- purpose?: string | undefined;
1673
1680
  tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
1681
+ purpose?: string | undefined;
1674
1682
  override?: {
1675
1683
  provider?: string | undefined;
1676
1684
  model?: string | undefined;
@@ -2053,8 +2061,8 @@ declare const falStubAdapter: ProviderAdapter;
2053
2061
  * wires the live adapters. */
2054
2062
  declare const stubProviders: Record<string, ProviderAdapter>;
2055
2063
 
2056
- declare const VERSION: "0.28.0";
2057
- declare const SDK_TAG: "@broberg/ai-sdk@0.28.0";
2064
+ declare const VERSION: "0.29.0";
2065
+ declare const SDK_TAG: "@broberg/ai-sdk@0.29.0";
2058
2066
 
2059
2067
  /** Built-in defaults. Every entry is overridable via AiConfig.defaults or a
2060
2068
  * per-call override.
package/dist/index.js CHANGED
@@ -1,35 +1,17 @@
1
1
  import {
2
+ DEFAULT_TIER_MAP,
2
3
  ModelUnavailableError,
3
4
  listModels,
4
5
  providerIds,
5
6
  resetRegistry,
6
7
  resolveModel,
8
+ resolveTier,
7
9
  setAvailability
8
- } from "./chunk-IT7HNKLY.js";
10
+ } from "./chunk-V2PD522L.js";
9
11
  import {
10
12
  getPrice
11
13
  } from "./chunk-LUPUAAHZ.js";
12
14
 
13
- // src/routing/tier-map.ts
14
- var DEFAULT_TIER_MAP = {
15
- fast: { provider: "mistral", model: "mistral-small-latest", transport: "http" },
16
- smart: { provider: "mistral", model: "mistral-large-latest", transport: "http" },
17
- powerful: { provider: "mistral", model: "mistral-large-latest", transport: "http" },
18
- cheap: { provider: "mistral", model: "mistral-small-latest", transport: "http" },
19
- // Vision: small-latest (vision-capable, cheap EU) is the default; override to
20
- // mistral-large-latest for demanding image/spatial/composition work.
21
- vision: { provider: "mistral", model: "mistral-small-latest", transport: "http" },
22
- // Native video understanding — Gemini leads; flash-lite is the cheap default (F019).
23
- // NOT Anthropic → out of the F030 phase-out (its own EU epic if/when needed).
24
- video: { provider: "gemini", model: "gemini-2.5-flash-lite", transport: "http" },
25
- // NOT Anthropic → out of F030 (EU-embedding migration is its own future epic).
26
- embedding: { provider: "openai", model: "text-embedding-3-small", transport: "http" }
27
- };
28
- function resolveTier(tier, override, configMap) {
29
- const base = configMap?.[tier] ?? DEFAULT_TIER_MAP[tier];
30
- return { ...base, ...override };
31
- }
32
-
33
15
  // src/transport/http.ts
34
16
  async function httpTransport(req) {
35
17
  if (!req.http) {
@@ -2761,7 +2743,15 @@ var ttsInputSchema = z.object({
2761
2743
  text: z.string(),
2762
2744
  voice: z.string(),
2763
2745
  /** F037: voice to use if `voice` is one we know the provider has retired. Without
2764
- * it a retired voice throws VoiceUnavailableError rather than reaching the API. */
2746
+ * it a retired voice throws VoiceUnavailableError rather than reaching the API.
2747
+ *
2748
+ * THINK BEFORE SETTING THIS. It is right for batch work where any acceptable voice
2749
+ * will do (a generated podcast, a bulk render). It is WRONG where the voice is an
2750
+ * identity a human recognises — a brand voice, a house narrator: falling back means
2751
+ * your product suddenly speaks with a stranger's voice and says nothing about why.
2752
+ * There, leave it unset and let the throw alarm you. Silence WITH a message beats
2753
+ * the wrong audio WITHOUT one. (torrent-search-api's call on their own house voice,
2754
+ * 2026-08-11 — they took the alarm over the fallback, deliberately.) */
2765
2755
  voiceFallback: z.string().optional(),
2766
2756
  lang: z.string().optional(),
2767
2757
  format: z.string().optional(),
@@ -2790,8 +2780,8 @@ var aiConfigSchema = z.object({
2790
2780
  });
2791
2781
 
2792
2782
  // src/version.ts
2793
- var VERSION = "0.28.0";
2794
- var SDK_TAG = "@broberg/ai-sdk@0.28.0";
2783
+ var VERSION = "0.29.0";
2784
+ var SDK_TAG = "@broberg/ai-sdk@0.29.0";
2795
2785
 
2796
2786
  // src/cost/sinks/upmetrics.ts
2797
2787
  function upmetricsSink(config) {