@broberg/ai-sdk 0.27.0 → 0.28.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 CHANGED
@@ -1640,6 +1640,9 @@ declare const ttsInputSchema: z.ZodObject<{
1640
1640
  labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1641
1641
  text: z.ZodString;
1642
1642
  voice: z.ZodString;
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. */
1645
+ voiceFallback: z.ZodOptional<z.ZodString>;
1643
1646
  lang: z.ZodOptional<z.ZodString>;
1644
1647
  format: z.ZodOptional<z.ZodString>;
1645
1648
  rate: z.ZodOptional<z.ZodNumber>;
@@ -1660,6 +1663,7 @@ declare const ttsInputSchema: z.ZodObject<{
1660
1663
  })[] | undefined;
1661
1664
  labels?: Record<string, string> | undefined;
1662
1665
  format?: string | undefined;
1666
+ voiceFallback?: string | undefined;
1663
1667
  lang?: string | undefined;
1664
1668
  rate?: number | undefined;
1665
1669
  }, {
@@ -1679,6 +1683,7 @@ declare const ttsInputSchema: z.ZodObject<{
1679
1683
  })[] | undefined;
1680
1684
  labels?: Record<string, string> | undefined;
1681
1685
  format?: string | undefined;
1686
+ voiceFallback?: string | undefined;
1682
1687
  lang?: string | undefined;
1683
1688
  rate?: number | undefined;
1684
1689
  }>;
@@ -2048,8 +2053,8 @@ declare const falStubAdapter: ProviderAdapter;
2048
2053
  * wires the live adapters. */
2049
2054
  declare const stubProviders: Record<string, ProviderAdapter>;
2050
2055
 
2051
- declare const VERSION: "0.27.0";
2052
- declare const SDK_TAG: "@broberg/ai-sdk@0.27.0";
2056
+ declare const VERSION: "0.28.0";
2057
+ declare const SDK_TAG: "@broberg/ai-sdk@0.28.0";
2053
2058
 
2054
2059
  /** Built-in defaults. Every entry is overridable via AiConfig.defaults or a
2055
2060
  * per-call override.
@@ -2102,6 +2107,88 @@ declare function refreshAvailability(opts?: RefreshOptions): Promise<RefreshResu
2102
2107
  /** Reset the overlay back to the curated defaults. For tests. */
2103
2108
  declare function resetRegistry(): void;
2104
2109
 
2110
+ type VoiceStatus = "available" | "retired" | "unknown";
2111
+ type VoiceProvider = "elevenlabs" | "azure";
2112
+ /** One row of the shared voice read — what a UI voice-picker renders. */
2113
+ interface VoiceInfo {
2114
+ /** Full provider voice id, e.g. "da-DK-ChristelNeural" / "4RklGmuxoAskAbGXplXN". */
2115
+ id: string;
2116
+ /** Curated friendly name a caller passes as `voice`, e.g. "christel". */
2117
+ name: string;
2118
+ provider: VoiceProvider;
2119
+ /** BCP-47 locale of the voice itself, e.g. "da-DK". NB: an Azure multilingual
2120
+ * voice speaking Danish reports its own locale ("de-DE" for Seraphina) — that
2121
+ * is what the adapter actually sends as xml:lang. */
2122
+ locale: string;
2123
+ /** Only where the provider publishes it — absent is "we do not know", never a
2124
+ * guess from the first name. */
2125
+ gender?: "female" | "male";
2126
+ available: boolean;
2127
+ status: VoiceStatus;
2128
+ /** Why it is unavailable, or any caveat worth showing in a picker. */
2129
+ note?: string;
2130
+ /** ISO date this row's status was last confirmed AGAINST THE PROVIDER. Exposed
2131
+ * on purpose (the F034.1 lesson): a registry that cannot be seen to go stale
2132
+ * is worse than one that can, because nobody knows when to re-check it. */
2133
+ checkedAt: string;
2134
+ }
2135
+ /** Result of checkVoice — deliberately the same shape as ResolveResult (F022) so
2136
+ * a consumer learns one idiom for models and voices. */
2137
+ interface VoiceResolveResult {
2138
+ /** True when the requested voice itself is usable. */
2139
+ ok: boolean;
2140
+ /** The id to actually send: the requested voice's id when ok, else the
2141
+ * fallback's. When there is no usable fallback this is the dead id and `ok`
2142
+ * is false — mirroring resolveModel, the caller must read `ok`. */
2143
+ voiceId: string;
2144
+ /** What the caller asked for, verbatim. */
2145
+ requested: string;
2146
+ provider?: VoiceProvider;
2147
+ /** True when `voiceId` differs from what was requested because we fell back. */
2148
+ fellBack: boolean;
2149
+ status: VoiceStatus;
2150
+ /** Why it degraded / why it is unavailable. */
2151
+ reason?: string;
2152
+ }
2153
+ /** Thrown when the requested voice is retired and no usable fallback exists.
2154
+ * Callers flag on `.code === "voice_unavailable"`. */
2155
+ declare class VoiceUnavailableError extends Error {
2156
+ readonly code = "voice_unavailable";
2157
+ readonly requested: string;
2158
+ readonly provider?: VoiceProvider;
2159
+ readonly note?: string;
2160
+ constructor(requested: string, note?: string, provider?: VoiceProvider);
2161
+ }
2162
+
2163
+ interface CheckVoiceOptions {
2164
+ /** One name/id or an ordered chain to try when `requested` is retired. */
2165
+ fallback?: string | string[];
2166
+ /** Throw VoiceUnavailableError instead of returning ok:false when nothing in the
2167
+ * chain is usable. For callers that want to fail loudly rather than degrade. */
2168
+ throwIfUnavailable?: boolean;
2169
+ }
2170
+ /**
2171
+ * The shared voice read — a UI picker greys out `available:false` rows and can show
2172
+ * `checkedAt` so a stale registry is visible rather than silently trusted.
2173
+ *
2174
+ * NB: distinct from `elevenlabsAdapter().listVoices()`, which is an async call to
2175
+ * ElevenLabs' live API. This one is synchronous, cross-provider, and reads only the
2176
+ * curated registry.
2177
+ */
2178
+ declare function listVoices(opts?: {
2179
+ provider?: VoiceProvider;
2180
+ }): VoiceInfo[];
2181
+ /**
2182
+ * Resolve a requested voice (curated name or raw provider id) to one that is
2183
+ * actually usable. Synchronous + offline by contract.
2184
+ *
2185
+ * - Available → pass through ({ ok:true, fellBack:false }).
2186
+ * - Retired + a usable fallback → swap ({ ok:false, fellBack:true }).
2187
+ * - Retired + no usable fallback → throw (throwIfUnavailable) or return ok:false.
2188
+ * - Untracked id → treated usable ({ status:"unknown" }), passed through verbatim.
2189
+ */
2190
+ declare function checkVoice(requested: string, opts?: CheckVoiceOptions): VoiceResolveResult;
2191
+
2105
2192
  /**
2106
2193
  * Cost in USD for a call. cache-read/creation tokens are priced separately when
2107
2194
  * the pricing entry defines rates for them; otherwise they fall back to the
@@ -2376,4 +2463,4 @@ interface StreamTransportRequest extends TransportRequest {
2376
2463
  */
2377
2464
  declare function streamTransport(req: StreamTransportRequest): AsyncIterable<string>;
2378
2465
 
2379
- export { AZURE_DANISH_VOICES, AZURE_DANISH_VOICE_LIST, type AiClient, type AiConfig, type AzureVoiceInfo, type BatchJob, type BatchRequestItem, type BatchResultItem, type BflAdapterConfig, type BflCredits, type BudgetConfig, BudgetExceededError, BudgetGuard, type BudgetStore, type CallOptions, type Capability, type ChatInput, type ChatRequest, type ChatResult, type ChatStreamEvent, type ClassifyInput, type ClassifyResult, type ContentPart, type Contracts, type CostQuery, type CostSink, type CostSummary, type CostSummaryQuery, type CostTimeseriesQuery, DEFAULT_TIER_MAP, type DesignInput, type DesignResult, type DialogueRequest, type DialogueTurn, type DiscordSinkConfig, ELEVENLABS_DANISH_VOICES, type EmbeddingInput, type EmbeddingRequest, type EmbeddingResult, type ExtractInput, type ExtractResult, type FalAdapterConfig, type HttpResponse, type ImageInput, type ImageRequest, type ImageResult, type LoraWeight, type Message, type MockupInput, type MockupResult, type ModerationInput, type ModerationItem, type ModerationRequest, type ModerationResult, type OcrInput, type OcrPage, type OcrRequest, type OcrResult, type OpenAICompatibleConfig, type PodcastInput, type PodcastResult, type PricingEntry, type ProviderAdapter, type RefreshOptions, type RefreshResult, type RerankInput, type RerankResult, type Role, SDK_TAG, type SqliteBudgetStoreConfig, type SqliteSinkConfig, StreamHttpError, type SubprocessResponse, type Tier, type TierSpec, type Tool, type ToolCall, type TrainStyleInput, type TrainStyleRequest, type TrainStyleResult, type TranscribeInput, type TranscribeRequest, type TranscribeResult, type TranslateInput, type TranslateResult, type Transport, type TransportRequest, type TransportResponse, type TtsInput, type TtsRequest, type UpmetricsCostClientConfig, UpmetricsCostError, type UpmetricsCostRow, type UpmetricsCostSummary, type UpmetricsCostTimeseries, type UpmetricsSinkConfig, type Usage, VERSION, type VideoInput, type VisionInput, aiConfigSchema, anthropicAdapter, anthropicApiAdapter, anthropicSubprocessAdapter, azureAdapter, bflAdapter, bflCredits, chatInputSchema, computeCost, createAI, deepinfraAdapter, deeplAdapter, deepseekAdapter, defaultProviders, discordSink, elevenlabsAdapter, embeddingInputSchema, falAdapter, falStubAdapter, freshUsage, fromProviderToolCall, geminiAdapter, getCostSummary, getPrice, httpTransport, imageInputSchema, listAzureDanishVoices, makeContracts, makeOpenAICompatibleAdapter, messageSchema, mistralAdapter, mistralStubAdapter, multiSink, noopSink, openaiAdapter, openaiStubAdapter, openrouterAdapter, parseClaudeCliJson, parseJsonLoose, refreshAvailability, requestyAdapter, resetRefreshState, resetRegistry, resolveAzureVoice, resolveTier, resolveVoice, sqliteBudgetStore, sqliteSink, streamTransport, stubProviders, subprocessTransport, tierSpecSchema, toProviderTools, toolSchema, translateInputSchema, upmetricsCostClient, upmetricsSink, usdFromMicro, vertexAdapter, visionInputSchema };
2466
+ export { AZURE_DANISH_VOICES, AZURE_DANISH_VOICE_LIST, type AiClient, type AiConfig, type AzureVoiceInfo, type BatchJob, type BatchRequestItem, type BatchResultItem, type BflAdapterConfig, type BflCredits, type BudgetConfig, BudgetExceededError, BudgetGuard, type BudgetStore, type CallOptions, type Capability, type ChatInput, type ChatRequest, type ChatResult, type ChatStreamEvent, type CheckVoiceOptions, type ClassifyInput, type ClassifyResult, type ContentPart, type Contracts, type CostQuery, type CostSink, type CostSummary, type CostSummaryQuery, type CostTimeseriesQuery, DEFAULT_TIER_MAP, type DesignInput, type DesignResult, type DialogueRequest, type DialogueTurn, type DiscordSinkConfig, ELEVENLABS_DANISH_VOICES, type EmbeddingInput, type EmbeddingRequest, type EmbeddingResult, type ExtractInput, type ExtractResult, type FalAdapterConfig, type HttpResponse, type ImageInput, type ImageRequest, type ImageResult, type LoraWeight, type Message, type MockupInput, type MockupResult, type ModerationInput, type ModerationItem, type ModerationRequest, type ModerationResult, type OcrInput, type OcrPage, type OcrRequest, type OcrResult, type OpenAICompatibleConfig, type PodcastInput, type PodcastResult, type PricingEntry, type ProviderAdapter, type RefreshOptions, type RefreshResult, type RerankInput, type RerankResult, type Role, SDK_TAG, type SqliteBudgetStoreConfig, type SqliteSinkConfig, StreamHttpError, type SubprocessResponse, type Tier, type TierSpec, type Tool, type ToolCall, type TrainStyleInput, type TrainStyleRequest, type TrainStyleResult, type TranscribeInput, type TranscribeRequest, type TranscribeResult, type TranslateInput, type TranslateResult, type Transport, type TransportRequest, type TransportResponse, type TtsInput, type TtsRequest, type UpmetricsCostClientConfig, UpmetricsCostError, type UpmetricsCostRow, type UpmetricsCostSummary, type UpmetricsCostTimeseries, type UpmetricsSinkConfig, type Usage, VERSION, type VideoInput, type VisionInput, type VoiceInfo, type VoiceProvider, type VoiceResolveResult, type VoiceStatus, VoiceUnavailableError, aiConfigSchema, anthropicAdapter, anthropicApiAdapter, anthropicSubprocessAdapter, azureAdapter, bflAdapter, bflCredits, chatInputSchema, checkVoice, computeCost, createAI, deepinfraAdapter, deeplAdapter, deepseekAdapter, defaultProviders, discordSink, elevenlabsAdapter, embeddingInputSchema, falAdapter, falStubAdapter, freshUsage, fromProviderToolCall, geminiAdapter, getCostSummary, getPrice, httpTransport, imageInputSchema, listAzureDanishVoices, listVoices, makeContracts, makeOpenAICompatibleAdapter, messageSchema, mistralAdapter, mistralStubAdapter, multiSink, noopSink, openaiAdapter, openaiStubAdapter, openrouterAdapter, parseClaudeCliJson, parseJsonLoose, refreshAvailability, requestyAdapter, resetRefreshState, resetRegistry, resolveAzureVoice, resolveTier, resolveVoice, sqliteBudgetStore, sqliteSink, streamTransport, stubProviders, subprocessTransport, tierSpecSchema, toProviderTools, toolSchema, translateInputSchema, upmetricsCostClient, upmetricsSink, usdFromMicro, vertexAdapter, visionInputSchema };
package/dist/index.js CHANGED
@@ -1390,13 +1390,13 @@ function elevenlabsAdapter(config = {}) {
1390
1390
  const audio = new Uint8Array(await res.arrayBuffer());
1391
1391
  return { audio, mimeType: "audio/mpeg", usage: priceFor(req.text.length, model) };
1392
1392
  }
1393
- async function listVoices() {
1393
+ async function listVoices2() {
1394
1394
  const res = await fetchImpl(`${baseUrl}/voices`, { headers: { "xi-api-key": key() } });
1395
1395
  if (!res.ok) throw new Error(`elevenlabs voices ${res.status}`);
1396
1396
  const data = await res.json();
1397
1397
  return (data.voices ?? []).map((v) => ({ voiceId: v.voice_id, name: v.name, language: v.labels?.language }));
1398
1398
  }
1399
- return { name: "elevenlabs", dialogue, tts, listVoices };
1399
+ return { name: "elevenlabs", dialogue, tts, listVoices: listVoices2 };
1400
1400
  }
1401
1401
 
1402
1402
  // src/providers/azure.ts
@@ -2449,6 +2449,143 @@ ${JSON.stringify(input.items)}`,
2449
2449
  };
2450
2450
  }
2451
2451
 
2452
+ // src/voices/registry.ts
2453
+ var CHECKED_AT = {
2454
+ // All 5 curated ids confirmed by SYNTHESIS — POST /v1/text-to-speech/{id} returned
2455
+ // 200 with distinct audio per voice (5 distinct sha256), and a fabricated id
2456
+ // returned 404, so a 200 means something.
2457
+ //
2458
+ // NB: GET /v1/voices/{id} is NOT a liveness test and must not be used as one. It
2459
+ // answers "is this voice saved in our account", and returns voice_not_found for a
2460
+ // public/shared voice that synthesizes perfectly well. Using it cost us a false
2461
+ // retirement (see the note on `mads` below) — the only honest liveness check for
2462
+ // ElevenLabs is a real synthesis call, which is exactly why v1 does no live check.
2463
+ elevenlabs: "2026-08-11",
2464
+ // F026 (6ca38c4) verified the 6 curated names against Azure's voices/list. Not
2465
+ // re-probed since: this machine has no Azure Speech key, and inventing a fresher
2466
+ // date than the last real check is exactly the lie checkedAt exists to prevent.
2467
+ azure: "2026-06-23"
2468
+ };
2469
+ var RETIRED_DEFAULT = {};
2470
+ var RETIRED = RETIRED_DEFAULT;
2471
+ var ELEVENLABS_GENDER = {
2472
+ soren: "male",
2473
+ jesper: "male",
2474
+ noam: "male",
2475
+ camilla: "female"
2476
+ };
2477
+ var NOTES = {
2478
+ mads: "usable, but not saved to the ElevenLabs account, so the voices endpoint publishes no metadata for it (verified by synthesis 2026-08-11)"
2479
+ };
2480
+ function build() {
2481
+ const rows = [];
2482
+ for (const [name, id] of Object.entries(ELEVENLABS_DANISH_VOICES)) {
2483
+ const retired = RETIRED[name];
2484
+ rows.push({
2485
+ id,
2486
+ name,
2487
+ provider: "elevenlabs",
2488
+ // The curated ElevenLabs roster IS the Danish one (see the constant's name
2489
+ // + F020); the multilingual model speaks it as da-DK.
2490
+ locale: "da-DK",
2491
+ gender: ELEVENLABS_GENDER[name],
2492
+ available: retired === void 0,
2493
+ status: retired === void 0 ? "available" : "retired",
2494
+ note: retired ?? NOTES[name],
2495
+ checkedAt: CHECKED_AT.elevenlabs
2496
+ });
2497
+ }
2498
+ for (const v of AZURE_DANISH_VOICE_LIST) {
2499
+ const retired = RETIRED[v.name];
2500
+ rows.push({
2501
+ id: v.voiceId,
2502
+ name: v.name,
2503
+ provider: "azure",
2504
+ locale: localeOf(v.voiceId),
2505
+ gender: v.gender,
2506
+ available: retired === void 0,
2507
+ status: retired === void 0 ? "available" : "retired",
2508
+ note: retired ?? NOTES[v.name],
2509
+ checkedAt: CHECKED_AT.azure
2510
+ });
2511
+ }
2512
+ return rows;
2513
+ }
2514
+ var ROWS = build();
2515
+ function allVoices(provider) {
2516
+ return provider ? ROWS.filter((v) => v.provider === provider) : [...ROWS];
2517
+ }
2518
+ function getVoice(nameOrId) {
2519
+ return ROWS.find((v) => v.name === nameOrId || v.id === nameOrId);
2520
+ }
2521
+
2522
+ // src/voices/types.ts
2523
+ var VoiceUnavailableError = class extends Error {
2524
+ code = "voice_unavailable";
2525
+ requested;
2526
+ provider;
2527
+ note;
2528
+ constructor(requested, note, provider) {
2529
+ super(`voice "${requested}" is unavailable${note ? ` (${note})` : ""}`);
2530
+ this.name = "VoiceUnavailableError";
2531
+ this.requested = requested;
2532
+ this.note = note;
2533
+ this.provider = provider;
2534
+ }
2535
+ };
2536
+
2537
+ // src/voices/resolve.ts
2538
+ function listVoices(opts = {}) {
2539
+ return allVoices(opts.provider);
2540
+ }
2541
+ function usable(nameOrId) {
2542
+ const v = getVoice(nameOrId);
2543
+ return v ? v.available : true;
2544
+ }
2545
+ function idFor(nameOrId) {
2546
+ return getVoice(nameOrId)?.id ?? nameOrId;
2547
+ }
2548
+ function checkVoice(requested, opts = {}) {
2549
+ const entry = getVoice(requested);
2550
+ const provider = entry?.provider;
2551
+ if (usable(requested)) {
2552
+ return {
2553
+ ok: true,
2554
+ voiceId: idFor(requested),
2555
+ requested,
2556
+ provider,
2557
+ fellBack: false,
2558
+ status: entry?.status ?? "unknown"
2559
+ };
2560
+ }
2561
+ const chain = opts.fallback === void 0 ? [] : Array.isArray(opts.fallback) ? opts.fallback : [opts.fallback];
2562
+ for (const fb of chain) {
2563
+ if (usable(fb)) {
2564
+ return {
2565
+ ok: false,
2566
+ voiceId: idFor(fb),
2567
+ requested,
2568
+ provider: getVoice(fb)?.provider ?? provider,
2569
+ fellBack: true,
2570
+ status: entry?.status ?? "retired",
2571
+ reason: entry?.note ?? `${requested} is unavailable`
2572
+ };
2573
+ }
2574
+ }
2575
+ if (opts.throwIfUnavailable) {
2576
+ throw new VoiceUnavailableError(requested, entry?.note, provider);
2577
+ }
2578
+ return {
2579
+ ok: false,
2580
+ voiceId: idFor(requested),
2581
+ requested,
2582
+ provider,
2583
+ fellBack: false,
2584
+ status: entry?.status ?? "retired",
2585
+ reason: entry?.note ?? `${requested} is unavailable`
2586
+ };
2587
+ }
2588
+
2452
2589
  // src/schema/inputs.ts
2453
2590
  import { z } from "zod";
2454
2591
  var transportSchema = z.enum(["http", "subprocess"]);
@@ -2623,6 +2760,9 @@ var podcastInputSchema = z.object({
2623
2760
  var ttsInputSchema = z.object({
2624
2761
  text: z.string(),
2625
2762
  voice: z.string(),
2763
+ /** 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. */
2765
+ voiceFallback: z.string().optional(),
2626
2766
  lang: z.string().optional(),
2627
2767
  format: z.string().optional(),
2628
2768
  rate: z.number().positive().optional(),
@@ -2650,8 +2790,8 @@ var aiConfigSchema = z.object({
2650
2790
  });
2651
2791
 
2652
2792
  // src/version.ts
2653
- var VERSION = "0.27.0";
2654
- var SDK_TAG = "@broberg/ai-sdk@0.27.0";
2793
+ var VERSION = "0.28.0";
2794
+ var SDK_TAG = "@broberg/ai-sdk@0.28.0";
2655
2795
 
2656
2796
  // src/cost/sinks/upmetrics.ts
2657
2797
  function upmetricsSink(config) {
@@ -3133,7 +3273,9 @@ function createAI(config = {}) {
3133
3273
  const inputs = input.script.map((turn) => {
3134
3274
  const mapped = input.voices[turn.speaker];
3135
3275
  if (!mapped) throw new Error(`ai.podcast: no voice mapped for speaker "${turn.speaker}"`);
3136
- return { text: turn.text, voiceId: resolveVoice(mapped) };
3276
+ const res = checkVoice(mapped);
3277
+ if (!res.ok) throw new VoiceUnavailableError(mapped, `${res.reason} \u2014 speaker "${turn.speaker}"`, res.provider);
3278
+ return { text: turn.text, voiceId: res.voiceId };
3137
3279
  });
3138
3280
  const chars = input.script.reduce((n, t) => n + t.text.length, 0);
3139
3281
  return runCapability({
@@ -3154,6 +3296,7 @@ function createAI(config = {}) {
3154
3296
  },
3155
3297
  async tts(input) {
3156
3298
  input = ttsInputSchema.parse(input);
3299
+ const { voiceId } = checkVoice(input.voice, { fallback: input.voiceFallback, throwIfUnavailable: true });
3157
3300
  return runCapability({
3158
3301
  primary: { ...DEFAULT_TTS_SPEC, ...input.override },
3159
3302
  fallback: input.fallback,
@@ -3166,7 +3309,7 @@ function createAI(config = {}) {
3166
3309
  invoke: async (spec) => {
3167
3310
  const adapter = pickProvider(spec.provider);
3168
3311
  if (!adapter.tts) throw new Error(`createAI: provider "${spec.provider}" does not support tts`);
3169
- return adapter.tts({ text: input.text, voiceId: resolveVoice(input.voice), lang: input.lang, format: input.format, rate: input.rate, spec });
3312
+ return adapter.tts({ text: input.text, voiceId, lang: input.lang, format: input.format, rate: input.rate, spec });
3170
3313
  }
3171
3314
  });
3172
3315
  },
@@ -3614,6 +3757,7 @@ export {
3614
3757
  StreamHttpError,
3615
3758
  UpmetricsCostError,
3616
3759
  VERSION,
3760
+ VoiceUnavailableError,
3617
3761
  aiConfigSchema,
3618
3762
  anthropicAdapter,
3619
3763
  anthropicApiAdapter,
@@ -3622,6 +3766,7 @@ export {
3622
3766
  bflAdapter,
3623
3767
  bflCredits,
3624
3768
  chatInputSchema,
3769
+ checkVoice,
3625
3770
  computeCost,
3626
3771
  createAI,
3627
3772
  deepinfraAdapter,
@@ -3642,6 +3787,7 @@ export {
3642
3787
  imageInputSchema,
3643
3788
  listAzureDanishVoices,
3644
3789
  listModels,
3790
+ listVoices,
3645
3791
  makeContracts,
3646
3792
  makeOpenAICompatibleAdapter,
3647
3793
  messageSchema,