@broberg/ai-sdk 0.17.0 → 0.18.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
@@ -298,6 +298,12 @@ interface PodcastResult {
298
298
  interface TtsRequest {
299
299
  text: string;
300
300
  voiceId: string;
301
+ /** BCP-47 locale (e.g. "da-DK"). Azure uses it for SSML xml:lang; ElevenLabs ignores it. */
302
+ lang?: string;
303
+ /** Provider output-format hint (e.g. an Azure X-Microsoft-OutputFormat); ElevenLabs ignores it. */
304
+ format?: string;
305
+ /** Speaking-rate multiplier (Azure): 1 = normal, 0.9 = 10% slower, 1.1 = faster. ElevenLabs ignores it. */
306
+ rate?: number;
301
307
  spec: TierSpec;
302
308
  }
303
309
  interface BatchRequestItem {
@@ -1585,6 +1591,9 @@ declare const ttsInputSchema: z.ZodObject<{
1585
1591
  labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1586
1592
  text: z.ZodString;
1587
1593
  voice: z.ZodString;
1594
+ lang: z.ZodOptional<z.ZodString>;
1595
+ format: z.ZodOptional<z.ZodString>;
1596
+ rate: z.ZodOptional<z.ZodNumber>;
1588
1597
  }, "strip", z.ZodTypeAny, {
1589
1598
  text: string;
1590
1599
  voice: string;
@@ -1601,6 +1610,9 @@ declare const ttsInputSchema: z.ZodObject<{
1601
1610
  transport: "http" | "subprocess";
1602
1611
  })[] | undefined;
1603
1612
  labels?: Record<string, string> | undefined;
1613
+ format?: string | undefined;
1614
+ lang?: string | undefined;
1615
+ rate?: number | undefined;
1604
1616
  }, {
1605
1617
  text: string;
1606
1618
  voice: string;
@@ -1617,6 +1629,9 @@ declare const ttsInputSchema: z.ZodObject<{
1617
1629
  transport: "http" | "subprocess";
1618
1630
  })[] | undefined;
1619
1631
  labels?: Record<string, string> | undefined;
1632
+ format?: string | undefined;
1633
+ lang?: string | undefined;
1634
+ rate?: number | undefined;
1620
1635
  }>;
1621
1636
  declare const aiConfigSchema: z.ZodObject<{
1622
1637
  defaults: z.ZodOptional<z.ZodRecord<z.ZodEnum<["fast", "smart", "powerful", "cheap", "vision", "video", "embedding"]>, z.ZodObject<{
@@ -1815,6 +1830,41 @@ declare function elevenlabsAdapter(config?: {
1815
1830
  listVoices(): Promise<ElevenLabsVoice[]>;
1816
1831
  };
1817
1832
 
1833
+ /** A curated Danish-speaking Azure voice, exposed so a consuming app can render a
1834
+ * picker. `native` = a true da-DK voice (most natural); otherwise a multilingual
1835
+ * voice that also speaks Danish (Azure has only 2 native da-DK voices). */
1836
+ interface AzureVoiceInfo {
1837
+ /** Friendly name a caller passes as `voice` (e.g. "christel"). */
1838
+ name: string;
1839
+ /** Full Azure voice name (e.g. "da-DK-ChristelNeural"). */
1840
+ voiceId: string;
1841
+ gender: "female" | "male";
1842
+ /** Display label for a UI picker. */
1843
+ display: string;
1844
+ /** True for the 2 native da-DK voices; false for multilingual voices speaking Danish. */
1845
+ native: boolean;
1846
+ /** Per-voice default speaking rate, applied when a call passes no explicit `rate`
1847
+ * (e.g. Christel reads a touch fast, so her natural default is 0.85). Omitted = 1 (normal). */
1848
+ defaultRate?: number;
1849
+ }
1850
+ /** Curated da-DK roster (F026) — 2 native + 4 multilingual, 3 of each gender.
1851
+ * Verified against Azure's voices/list (only Christel + Jeppe are native da-DK). */
1852
+ declare const AZURE_DANISH_VOICE_LIST: AzureVoiceInfo[];
1853
+ /** Friendly name → full Azure voice name. Distinct from ELEVENLABS_DANISH_VOICES so
1854
+ * the client's resolveVoice passes these through unchanged to this adapter. */
1855
+ declare const AZURE_DANISH_VOICES: Record<string, string>;
1856
+ /** The curated Danish voice roster, for a consuming app to present in a picker. */
1857
+ declare function listAzureDanishVoices(): AzureVoiceInfo[];
1858
+ /** Resolve a curated friendly name to its full Azure voice; pass a full voice name
1859
+ * (e.g. "da-DK-ChristelNeural") through unchanged. */
1860
+ declare function resolveAzureVoice(nameOrVoice: string): string;
1861
+ declare function azureAdapter(config?: {
1862
+ apiKey?: string;
1863
+ region?: string;
1864
+ fetch?: typeof fetch;
1865
+ pricePer1kChars?: number;
1866
+ }): ProviderAdapter;
1867
+
1818
1868
  interface FalAdapterConfig {
1819
1869
  apiKey?: string;
1820
1870
  /** "sync" (default — fal.run, fast models) or "queue" (queue.fal.run, polled). */
@@ -1895,8 +1945,8 @@ declare const falStubAdapter: ProviderAdapter;
1895
1945
  * wires the live adapters. */
1896
1946
  declare const stubProviders: Record<string, ProviderAdapter>;
1897
1947
 
1898
- declare const VERSION: "0.17.0";
1899
- declare const SDK_TAG: "@broberg/ai-sdk@0.17.0";
1948
+ declare const VERSION: "0.18.0";
1949
+ declare const SDK_TAG: "@broberg/ai-sdk@0.18.0";
1900
1950
 
1901
1951
  /** Built-in defaults. Every entry is overridable via AiConfig.defaults or a
1902
1952
  * per-call override. Model IDs are current at scaffold time; callers pin their
@@ -2047,6 +2097,103 @@ interface CostSummary {
2047
2097
  * DB has never been written to, so an empty DB summarises cleanly to 0. */
2048
2098
  declare function getCostSummary(dbPath: string): Promise<CostSummary>;
2049
2099
 
2100
+ /** Thrown when the cost read-API rejects (e.g. 401 invalid_api_key) or is unreachable. */
2101
+ declare class UpmetricsCostError extends Error {
2102
+ readonly status?: number;
2103
+ readonly code?: string;
2104
+ constructor(message: string, opts?: {
2105
+ status?: number;
2106
+ code?: string;
2107
+ });
2108
+ }
2109
+ interface UpmetricsCostClientConfig {
2110
+ /** Read-API base URL, e.g. https://upmetrics.org */
2111
+ baseUrl: string;
2112
+ /** Per-project api_key (uk_…) — sent as X-Upmetrics-Key; resolves to your own project only. */
2113
+ apiKey: string;
2114
+ /** Injectable fetch for testing; defaults to global fetch. */
2115
+ fetch?: typeof fetch;
2116
+ }
2117
+ /** Shared filter surface for summary + timeseries (mirrors COST-API.md query params). */
2118
+ interface CostQuery {
2119
+ /** Relative window; ignored when from/to are given. */
2120
+ window?: "day" | "week" | "month";
2121
+ /** Explicit window start (ISO-8601 or epoch-ms) — overrides `window`. */
2122
+ from?: string | number;
2123
+ /** Explicit window end (ISO-8601 or epoch-ms) — overrides `window`. */
2124
+ to?: string | number;
2125
+ provider?: string;
2126
+ model?: string;
2127
+ tier?: string;
2128
+ /** Filter to one consumer (the sink's agent_name). */
2129
+ agentName?: string;
2130
+ transport?: "http" | "subprocess";
2131
+ /** Tag filters → `tag.<key>=<value>` (e.g. { tenantId: "sanne" }). */
2132
+ tags?: Record<string, string>;
2133
+ }
2134
+ interface CostSummaryQuery extends CostQuery {
2135
+ /** Break the total down per distinct value of this tag key (the per-tenant view). */
2136
+ groupBy?: string;
2137
+ }
2138
+ interface CostTimeseriesQuery extends CostQuery {
2139
+ /** Bucket granularity (default "day"). */
2140
+ bucket?: "day" | "hour";
2141
+ }
2142
+ /** One breakdown row, ordered by cost desc. `tier`/`capability` fall back to "(none)". */
2143
+ interface UpmetricsCostRow {
2144
+ key: string;
2145
+ micro_usd: number;
2146
+ input_tokens: number;
2147
+ output_tokens: number;
2148
+ run_count: number;
2149
+ }
2150
+ interface UpmetricsCostSummary {
2151
+ generated_at: string;
2152
+ window: {
2153
+ from: string;
2154
+ to: string;
2155
+ };
2156
+ total_micro_usd: number;
2157
+ input_tokens: number;
2158
+ output_tokens: number;
2159
+ cache_read_tokens: number;
2160
+ cache_creation_tokens: number;
2161
+ run_count: number;
2162
+ metered: {
2163
+ metered_micro_usd: number;
2164
+ free_run_count: number;
2165
+ };
2166
+ by_provider: UpmetricsCostRow[];
2167
+ by_model: UpmetricsCostRow[];
2168
+ by_tier: UpmetricsCostRow[];
2169
+ by_capability: UpmetricsCostRow[];
2170
+ /** Present only when `groupBy` was requested. */
2171
+ group_by?: string;
2172
+ by_group?: UpmetricsCostRow[];
2173
+ }
2174
+ interface UpmetricsCostTimeseries {
2175
+ generated_at: string;
2176
+ bucket: "day" | "hour";
2177
+ window: {
2178
+ from: string;
2179
+ to: string;
2180
+ };
2181
+ /** Only non-zero buckets are returned — pad missing buckets yourself. */
2182
+ points: Array<{
2183
+ ts: string;
2184
+ micro_usd: number;
2185
+ input_tokens: number;
2186
+ output_tokens: number;
2187
+ run_count: number;
2188
+ }>;
2189
+ }
2190
+ /** Convert integer micro-USD to a USD float for display. `$1 = 1_000_000`. */
2191
+ declare const usdFromMicro: (microUsd: number) => number;
2192
+ declare function upmetricsCostClient(config: UpmetricsCostClientConfig): {
2193
+ summary(query?: CostSummaryQuery): Promise<UpmetricsCostSummary>;
2194
+ timeseries(query?: CostTimeseriesQuery): Promise<UpmetricsCostTimeseries>;
2195
+ };
2196
+
2050
2197
  interface PricingEntry {
2051
2198
  /** USD per 1M input tokens. */
2052
2199
  inputPer1M: number;
@@ -2122,4 +2269,4 @@ interface StreamTransportRequest extends TransportRequest {
2122
2269
  */
2123
2270
  declare function streamTransport(req: StreamTransportRequest): AsyncIterable<string>;
2124
2271
 
2125
- export { type AiClient, type AiConfig, 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 CostSink, type CostSummary, 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 UpmetricsSinkConfig, type Usage, VERSION, type VideoInput, type VisionInput, aiConfigSchema, anthropicAdapter, anthropicApiAdapter, anthropicSubprocessAdapter, bflAdapter, bflCredits, chatInputSchema, computeCost, createAI, deepinfraAdapter, defaultProviders, discordSink, elevenlabsAdapter, embeddingInputSchema, falAdapter, falStubAdapter, freshUsage, fromProviderToolCall, geminiAdapter, getCostSummary, getPrice, httpTransport, imageInputSchema, makeContracts, makeOpenAICompatibleAdapter, messageSchema, mistralAdapter, multiSink, noopSink, openaiAdapter, openaiStubAdapter, openrouterAdapter, parseClaudeCliJson, parseJsonLoose, refreshAvailability, resetRefreshState, resetRegistry, resolveTier, resolveVoice, sqliteBudgetStore, sqliteSink, streamTransport, stubProviders, subprocessTransport, tierSpecSchema, toProviderTools, toolSchema, translateInputSchema, upmetricsSink, visionInputSchema };
2272
+ 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, defaultProviders, discordSink, elevenlabsAdapter, embeddingInputSchema, falAdapter, falStubAdapter, freshUsage, fromProviderToolCall, geminiAdapter, getCostSummary, getPrice, httpTransport, imageInputSchema, listAzureDanishVoices, makeContracts, makeOpenAICompatibleAdapter, messageSchema, mistralAdapter, multiSink, noopSink, openaiAdapter, openaiStubAdapter, openrouterAdapter, parseClaudeCliJson, parseJsonLoose, refreshAvailability, resetRefreshState, resetRegistry, resolveAzureVoice, resolveTier, resolveVoice, sqliteBudgetStore, sqliteSink, streamTransport, stubProviders, subprocessTransport, tierSpecSchema, toProviderTools, toolSchema, translateInputSchema, upmetricsCostClient, upmetricsSink, usdFromMicro, visionInputSchema };
package/dist/index.js CHANGED
@@ -1395,6 +1395,86 @@ function elevenlabsAdapter(config = {}) {
1395
1395
  return { name: "elevenlabs", dialogue, tts, listVoices };
1396
1396
  }
1397
1397
 
1398
+ // src/providers/azure.ts
1399
+ var AZURE_TTS_PRICE_PER_1K_CHARS = 0.016;
1400
+ var DEFAULT_REGION = "westeurope";
1401
+ var DEFAULT_FORMAT = "audio-24khz-48kbitrate-mono-mp3";
1402
+ var AZURE_DANISH_VOICE_LIST = [
1403
+ { name: "christel", voiceId: "da-DK-ChristelNeural", gender: "female", display: "Christel", native: true, defaultRate: 0.85 },
1404
+ { name: "seraphina", voiceId: "de-DE-SeraphinaMultilingualNeural", gender: "female", display: "Seraphina", native: false },
1405
+ { name: "ava", voiceId: "en-US-AvaMultilingualNeural", gender: "female", display: "Ava", native: false },
1406
+ { name: "jeppe", voiceId: "da-DK-JeppeNeural", gender: "male", display: "Jeppe", native: true },
1407
+ { name: "florian", voiceId: "de-DE-FlorianMultilingualNeural", gender: "male", display: "Florian", native: false },
1408
+ { name: "andrew", voiceId: "en-US-AndrewMultilingualNeural", gender: "male", display: "Andrew", native: false }
1409
+ ];
1410
+ var AZURE_DANISH_VOICES = Object.fromEntries(
1411
+ AZURE_DANISH_VOICE_LIST.map((v) => [v.name, v.voiceId])
1412
+ );
1413
+ function listAzureDanishVoices() {
1414
+ return AZURE_DANISH_VOICE_LIST;
1415
+ }
1416
+ function resolveAzureVoice(nameOrVoice) {
1417
+ return AZURE_DANISH_VOICES[nameOrVoice] ?? nameOrVoice;
1418
+ }
1419
+ function xmlEscape(s) {
1420
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
1421
+ }
1422
+ function localeOf(voice) {
1423
+ const parts = voice.split("-");
1424
+ return parts.length >= 2 ? `${parts[0]}-${parts[1]}` : "en-US";
1425
+ }
1426
+ function azureAdapter(config = {}) {
1427
+ const fetchImpl = config.fetch ?? fetch;
1428
+ function key() {
1429
+ const k = config.apiKey ?? process.env.AZURE_SPEECH_KEY;
1430
+ if (!k) throw new Error("azure adapter: API key not set (env AZURE_SPEECH_KEY)");
1431
+ return k;
1432
+ }
1433
+ function region() {
1434
+ return config.region ?? process.env.AZURE_SPEECH_REGION ?? DEFAULT_REGION;
1435
+ }
1436
+ function priceFor(chars, model) {
1437
+ const usage = freshUsage({
1438
+ provider: "azure",
1439
+ model,
1440
+ transport: "http",
1441
+ capability: "tts",
1442
+ inputTokens: 0,
1443
+ outputTokens: 0
1444
+ });
1445
+ usage.costUsd = chars / 1e3 * (config.pricePer1kChars ?? AZURE_TTS_PRICE_PER_1K_CHARS);
1446
+ return usage;
1447
+ }
1448
+ async function tts(req) {
1449
+ const voice = resolveAzureVoice(req.voiceId);
1450
+ const lang = req.lang ?? localeOf(voice);
1451
+ const format = req.format ?? DEFAULT_FORMAT;
1452
+ const escaped = xmlEscape(req.text);
1453
+ const effRate = req.rate ?? AZURE_DANISH_VOICE_LIST.find((v) => v.voiceId === voice)?.defaultRate;
1454
+ const inner = effRate != null && effRate !== 1 ? `<prosody rate='${effRate}'>${escaped}</prosody>` : escaped;
1455
+ const ssml = `<speak version='1.0' xml:lang='${lang}'><voice name='${voice}'>${inner}</voice></speak>`;
1456
+ const res = await fetchImpl(
1457
+ `https://${region()}.tts.speech.microsoft.com/cognitiveservices/v1`,
1458
+ {
1459
+ method: "POST",
1460
+ headers: {
1461
+ "Ocp-Apim-Subscription-Key": key(),
1462
+ "Content-Type": "application/ssml+xml",
1463
+ "X-Microsoft-OutputFormat": format
1464
+ },
1465
+ body: ssml
1466
+ }
1467
+ );
1468
+ if (!res.ok) {
1469
+ const body = await res.text().catch(() => "");
1470
+ throw new Error(`azure tts ${res.status}: ${body.slice(0, 300)}`);
1471
+ }
1472
+ const audio = new Uint8Array(await res.arrayBuffer());
1473
+ return { audio, mimeType: "audio/mpeg", usage: priceFor(req.text.length, req.spec.model) };
1474
+ }
1475
+ return { name: "azure", tts };
1476
+ }
1477
+
1398
1478
  // src/providers/fal.ts
1399
1479
  import { deflateRawSync, crc32 } from "zlib";
1400
1480
  var FAL_IMAGE_PRICE_ESTIMATE = {
@@ -1822,6 +1902,7 @@ var defaultProviders = {
1822
1902
  openrouter: openrouterAdapter(),
1823
1903
  mistral: mistralAdapter(),
1824
1904
  elevenlabs: elevenlabsAdapter(),
1905
+ azure: azureAdapter(),
1825
1906
  fal: falAdapter(),
1826
1907
  bfl: bflAdapter()
1827
1908
  };
@@ -2206,6 +2287,9 @@ var podcastInputSchema = z.object({
2206
2287
  var ttsInputSchema = z.object({
2207
2288
  text: z.string(),
2208
2289
  voice: z.string(),
2290
+ lang: z.string().optional(),
2291
+ format: z.string().optional(),
2292
+ rate: z.number().positive().optional(),
2209
2293
  ...callOptions
2210
2294
  });
2211
2295
  var budgetSchema = z.object({
@@ -2247,6 +2331,7 @@ var DEFAULT_ANIMATE_SPEC = {
2247
2331
  model: "veo-3.1-generate-preview",
2248
2332
  transport: "http"
2249
2333
  };
2334
+ var ANIMATE_AUDIO_DIRECTIVE = "No spoken dialogue, no talking, no voiceover. Include natural ambient background sounds that match the environment.";
2250
2335
  var DEFAULT_BFL_FINETUNE_SPEC = {
2251
2336
  provider: "bfl",
2252
2337
  model: "flux-pro-1.1-ultra-finetuned",
@@ -2535,6 +2620,7 @@ function createAI(config = {}) {
2535
2620
  },
2536
2621
  async animate(input) {
2537
2622
  input = animateInputSchema.parse(input);
2623
+ const prompt = input.prompt?.trim() ? `${input.prompt.trim()} ${ANIMATE_AUDIO_DIRECTIVE}` : ANIMATE_AUDIO_DIRECTIVE;
2538
2624
  return runCapability({
2539
2625
  primary: { ...DEFAULT_ANIMATE_SPEC, ...input.override },
2540
2626
  fallback: input.fallback,
@@ -2549,7 +2635,7 @@ function createAI(config = {}) {
2549
2635
  if (!adapter.animate) throw new Error(`createAI: provider "${spec.provider}" does not support animate`);
2550
2636
  return adapter.animate({
2551
2637
  image: input.image,
2552
- prompt: input.prompt,
2638
+ prompt,
2553
2639
  durationSec: input.durationSec,
2554
2640
  resolution: input.resolution,
2555
2641
  spec
@@ -2657,7 +2743,7 @@ function createAI(config = {}) {
2657
2743
  invoke: async (spec) => {
2658
2744
  const adapter = pickProvider(spec.provider);
2659
2745
  if (!adapter.tts) throw new Error(`createAI: provider "${spec.provider}" does not support tts`);
2660
- return adapter.tts({ text: input.text, voiceId: resolveVoice(input.voice), spec });
2746
+ return adapter.tts({ text: input.text, voiceId: resolveVoice(input.voice), lang: input.lang, format: input.format, rate: input.rate, spec });
2661
2747
  }
2662
2748
  });
2663
2749
  },
@@ -2807,8 +2893,8 @@ var stubProviders = {
2807
2893
  };
2808
2894
 
2809
2895
  // src/version.ts
2810
- var VERSION = "0.17.0";
2811
- var SDK_TAG = "@broberg/ai-sdk@0.17.0";
2896
+ var VERSION = "0.18.0";
2897
+ var SDK_TAG = "@broberg/ai-sdk@0.18.0";
2812
2898
 
2813
2899
  // src/availability/refresh.ts
2814
2900
  var NOT_REFRESHED = { refreshed: false, checked: 0, markedUnavailable: [] };
@@ -3081,7 +3167,76 @@ async function getCostSummary(dbPath) {
3081
3167
  }
3082
3168
  return { totalUsd: total?.total ?? 0, byProvider, byCapability };
3083
3169
  }
3170
+
3171
+ // src/cost/upmetrics-read.ts
3172
+ var UpmetricsCostError = class extends Error {
3173
+ status;
3174
+ code;
3175
+ constructor(message, opts) {
3176
+ super(message);
3177
+ this.name = "UpmetricsCostError";
3178
+ this.status = opts?.status;
3179
+ this.code = opts?.code;
3180
+ }
3181
+ };
3182
+ var usdFromMicro = (microUsd) => microUsd / 1e6;
3183
+ function buildQuery(q) {
3184
+ const p = new URLSearchParams();
3185
+ if (q.bucket) p.set("bucket", q.bucket);
3186
+ if (q.from !== void 0) p.set("from", String(q.from));
3187
+ if (q.to !== void 0) p.set("to", String(q.to));
3188
+ if (q.window && q.from === void 0 && q.to === void 0) p.set("window", q.window);
3189
+ if (q.provider) p.set("provider", q.provider);
3190
+ if (q.model) p.set("model", q.model);
3191
+ if (q.tier) p.set("tier", q.tier);
3192
+ if (q.agentName) p.set("agent_name", q.agentName);
3193
+ if (q.transport) p.set("transport", q.transport);
3194
+ if (q.groupBy) p.set("groupBy", q.groupBy);
3195
+ for (const [k, v] of Object.entries(q.tags ?? {})) p.set(`tag.${k}`, v);
3196
+ const s = p.toString();
3197
+ return s ? `?${s}` : "";
3198
+ }
3199
+ function upmetricsCostClient(config) {
3200
+ const doFetch = config.fetch ?? fetch;
3201
+ const base = config.baseUrl.replace(/\/$/, "");
3202
+ async function get(path, query) {
3203
+ let res;
3204
+ try {
3205
+ res = await doFetch(`${base}${path}${query}`, {
3206
+ method: "GET",
3207
+ headers: { "X-Upmetrics-Key": config.apiKey }
3208
+ });
3209
+ } catch (err) {
3210
+ throw new UpmetricsCostError(
3211
+ `upmetricsCostClient: ${path} unreachable: ${err?.message ?? String(err)}`
3212
+ );
3213
+ }
3214
+ if (!res.ok) {
3215
+ let code;
3216
+ const text = await res.text().catch(() => "");
3217
+ try {
3218
+ code = JSON.parse(text).error;
3219
+ } catch {
3220
+ }
3221
+ throw new UpmetricsCostError(
3222
+ `upmetricsCostClient: ${path} returned ${res.status}${code ? ` (${code})` : ""}`,
3223
+ { status: res.status, code }
3224
+ );
3225
+ }
3226
+ return await res.json();
3227
+ }
3228
+ return {
3229
+ summary(query = {}) {
3230
+ return get("/api/cost/summary", buildQuery(query));
3231
+ },
3232
+ timeseries(query = {}) {
3233
+ return get("/api/cost/timeseries", buildQuery(query));
3234
+ }
3235
+ };
3236
+ }
3084
3237
  export {
3238
+ AZURE_DANISH_VOICES,
3239
+ AZURE_DANISH_VOICE_LIST,
3085
3240
  BudgetExceededError,
3086
3241
  BudgetGuard,
3087
3242
  DEFAULT_TIER_MAP,
@@ -3089,11 +3244,13 @@ export {
3089
3244
  ModelUnavailableError,
3090
3245
  SDK_TAG,
3091
3246
  StreamHttpError,
3247
+ UpmetricsCostError,
3092
3248
  VERSION,
3093
3249
  aiConfigSchema,
3094
3250
  anthropicAdapter,
3095
3251
  anthropicApiAdapter,
3096
3252
  anthropicSubprocessAdapter,
3253
+ azureAdapter,
3097
3254
  bflAdapter,
3098
3255
  bflCredits,
3099
3256
  chatInputSchema,
@@ -3113,6 +3270,7 @@ export {
3113
3270
  getPrice,
3114
3271
  httpTransport,
3115
3272
  imageInputSchema,
3273
+ listAzureDanishVoices,
3116
3274
  listModels,
3117
3275
  makeContracts,
3118
3276
  makeOpenAICompatibleAdapter,
@@ -3128,6 +3286,7 @@ export {
3128
3286
  refreshAvailability,
3129
3287
  resetRefreshState,
3130
3288
  resetRegistry,
3289
+ resolveAzureVoice,
3131
3290
  resolveModel,
3132
3291
  resolveTier,
3133
3292
  resolveVoice,
@@ -3140,7 +3299,9 @@ export {
3140
3299
  toProviderTools,
3141
3300
  toolSchema,
3142
3301
  translateInputSchema,
3302
+ upmetricsCostClient,
3143
3303
  upmetricsSink,
3304
+ usdFromMicro,
3144
3305
  visionInputSchema
3145
3306
  };
3146
3307
  //# sourceMappingURL=index.js.map