@broberg/ai-sdk 0.17.1 → 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.1";
1899
- declare const SDK_TAG: "@broberg/ai-sdk@0.17.1";
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({
@@ -2659,7 +2743,7 @@ function createAI(config = {}) {
2659
2743
  invoke: async (spec) => {
2660
2744
  const adapter = pickProvider(spec.provider);
2661
2745
  if (!adapter.tts) throw new Error(`createAI: provider "${spec.provider}" does not support tts`);
2662
- 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 });
2663
2747
  }
2664
2748
  });
2665
2749
  },
@@ -2809,8 +2893,8 @@ var stubProviders = {
2809
2893
  };
2810
2894
 
2811
2895
  // src/version.ts
2812
- var VERSION = "0.17.1";
2813
- var SDK_TAG = "@broberg/ai-sdk@0.17.1";
2896
+ var VERSION = "0.18.0";
2897
+ var SDK_TAG = "@broberg/ai-sdk@0.18.0";
2814
2898
 
2815
2899
  // src/availability/refresh.ts
2816
2900
  var NOT_REFRESHED = { refreshed: false, checked: 0, markedUnavailable: [] };
@@ -3083,7 +3167,76 @@ async function getCostSummary(dbPath) {
3083
3167
  }
3084
3168
  return { totalUsd: total?.total ?? 0, byProvider, byCapability };
3085
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
+ }
3086
3237
  export {
3238
+ AZURE_DANISH_VOICES,
3239
+ AZURE_DANISH_VOICE_LIST,
3087
3240
  BudgetExceededError,
3088
3241
  BudgetGuard,
3089
3242
  DEFAULT_TIER_MAP,
@@ -3091,11 +3244,13 @@ export {
3091
3244
  ModelUnavailableError,
3092
3245
  SDK_TAG,
3093
3246
  StreamHttpError,
3247
+ UpmetricsCostError,
3094
3248
  VERSION,
3095
3249
  aiConfigSchema,
3096
3250
  anthropicAdapter,
3097
3251
  anthropicApiAdapter,
3098
3252
  anthropicSubprocessAdapter,
3253
+ azureAdapter,
3099
3254
  bflAdapter,
3100
3255
  bflCredits,
3101
3256
  chatInputSchema,
@@ -3115,6 +3270,7 @@ export {
3115
3270
  getPrice,
3116
3271
  httpTransport,
3117
3272
  imageInputSchema,
3273
+ listAzureDanishVoices,
3118
3274
  listModels,
3119
3275
  makeContracts,
3120
3276
  makeOpenAICompatibleAdapter,
@@ -3130,6 +3286,7 @@ export {
3130
3286
  refreshAvailability,
3131
3287
  resetRefreshState,
3132
3288
  resetRegistry,
3289
+ resolveAzureVoice,
3133
3290
  resolveModel,
3134
3291
  resolveTier,
3135
3292
  resolveVoice,
@@ -3142,7 +3299,9 @@ export {
3142
3299
  toProviderTools,
3143
3300
  toolSchema,
3144
3301
  translateInputSchema,
3302
+ upmetricsCostClient,
3145
3303
  upmetricsSink,
3304
+ usdFromMicro,
3146
3305
  visionInputSchema
3147
3306
  };
3148
3307
  //# sourceMappingURL=index.js.map