@broberg/ai-sdk 0.47.0 → 0.47.1

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
@@ -2271,6 +2271,24 @@ declare function createAI(config?: AiConfig): AiClient;
2271
2271
  /** Pull the first JSON value out of a model reply (tolerates ```json fences + prose). */
2272
2272
  declare function parseJsonLoose(text: string): unknown;
2273
2273
  type ChatVision = Pick<AiClient, "chat" | "vision">;
2274
+ /** F052.2 — resolve the model's answer to one of the CALLER's labels, or to null.
2275
+ *
2276
+ * Reported by helpdesk from a live customer ticket (BR-2WYHD, 15 September 2026). They
2277
+ * pass labels carrying their own description — `"virker-ikke — noget er i stykker…"` —
2278
+ * and the model answered `"virker-ikke"`, the canonical short form. That IS in their
2279
+ * taxonomy. Exact equality threw a correct answer away, and it failed in the green
2280
+ * direction: `label: null` reads as "the model could not decide", a legitimate outcome
2281
+ * nobody investigates. The gradient runs TOWARD the bug — the better a consumer fills in
2282
+ * the description, the longer the label, the likelier the model answers with the head.
2283
+ *
2284
+ * NO SEPARATOR PARAMETER, deliberately. helpdesk proposed splitting on a separator and
2285
+ * flagged themselves that hardcoding an em-dash just moves the cliff. A PREFIX needs no
2286
+ * separator at all: "virker-ikke" is a prefix of the decorated label, whatever joins them.
2287
+ *
2288
+ * AND AMBIGUITY MUST STAY null. If the answer prefixes TWO labels ("betaling" against
2289
+ * "betaling — kort" and "betaling — faktura"), picking one would turn a discarded correct
2290
+ * answer into a confident wrong one — a downgrade wearing a fix's clothes. */
2291
+ declare function matchLabel(answer: unknown, labels: string[]): string | null;
2274
2292
  declare function makeContracts(client: ChatVision): Contracts;
2275
2293
 
2276
2294
  /** Convert SDK tools to a provider's request format. */
@@ -2534,8 +2552,8 @@ declare const falStubAdapter: ProviderAdapter;
2534
2552
  * wires the live adapters. */
2535
2553
  declare const stubProviders: Record<string, ProviderAdapter>;
2536
2554
 
2537
- declare const VERSION: "0.47.0";
2538
- declare const SDK_TAG: "@broberg/ai-sdk@0.47.0";
2555
+ declare const VERSION: "0.47.1";
2556
+ declare const SDK_TAG: "@broberg/ai-sdk@0.47.1";
2539
2557
 
2540
2558
  /** Built-in defaults. Every entry is overridable via AiConfig.defaults or a
2541
2559
  * per-call override.
@@ -3009,4 +3027,4 @@ interface StreamTransportRequest extends TransportRequest {
3009
3027
  */
3010
3028
  declare function streamTransport(req: StreamTransportRequest): AsyncIterable<string>;
3011
3029
 
3012
- export { AZURE_DANISH_VOICES, AZURE_DANISH_VOICE_LIST, type AiClient, type AiConfig, type AlignedWordTimings, type AzureVoiceInfo, type AzureWordBoundary, type BatchJob, type BatchRequestItem, type BatchResultItem, type BflAdapterConfig, type BflCredits, type BudgetConfig, BudgetExceededError, BudgetGuard, type BudgetStore, CONFIG_DERIVED_HOSTS, 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_BASE_URLS, 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 FixedHostProvider, type HttpResponse, type ImageInput, type ImageRequest, type ImageResult, LOCALLY_PINNED_HOSTS, 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 Region, type RerankInput, type RerankResult, type Role, type RouteForecast, 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, type WordTiming, aiConfigSchema, alignWordTimings, anthropicAdapter, anthropicApiAdapter, anthropicSubprocessAdapter, azureAdapter, bflAdapter, bflCredits, chatInputSchema, checkVoice, classifyRegionName, computeCost, createAI, deepinfraAdapter, deeplAdapter, deepseekAdapter, defaultBaseUrl, 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, regionOfHost, regionOfProvider, requestyAdapter, resetRefreshState, resetRegistry, resolveAzureVoice, resolveTier, resolveVoice, sqliteBudgetStore, sqliteSink, streamTransport, stubProviders, subprocessTransport, tierSpecSchema, toProviderTools, toolSchema, translateInputSchema, upmetricsCostClient, upmetricsSink, usdFromMicro, vertexAdapter, visionInputSchema, wouldProviderRouteTo, wouldRouteTo };
3030
+ export { AZURE_DANISH_VOICES, AZURE_DANISH_VOICE_LIST, type AiClient, type AiConfig, type AlignedWordTimings, type AzureVoiceInfo, type AzureWordBoundary, type BatchJob, type BatchRequestItem, type BatchResultItem, type BflAdapterConfig, type BflCredits, type BudgetConfig, BudgetExceededError, BudgetGuard, type BudgetStore, CONFIG_DERIVED_HOSTS, 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_BASE_URLS, 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 FixedHostProvider, type HttpResponse, type ImageInput, type ImageRequest, type ImageResult, LOCALLY_PINNED_HOSTS, 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 Region, type RerankInput, type RerankResult, type Role, type RouteForecast, 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, type WordTiming, aiConfigSchema, alignWordTimings, anthropicAdapter, anthropicApiAdapter, anthropicSubprocessAdapter, azureAdapter, bflAdapter, bflCredits, chatInputSchema, checkVoice, classifyRegionName, computeCost, createAI, deepinfraAdapter, deeplAdapter, deepseekAdapter, defaultBaseUrl, defaultProviders, discordSink, elevenlabsAdapter, embeddingInputSchema, falAdapter, falStubAdapter, freshUsage, fromProviderToolCall, geminiAdapter, getCostSummary, getPrice, httpTransport, imageInputSchema, listAzureDanishVoices, listVoices, makeContracts, makeOpenAICompatibleAdapter, matchLabel, messageSchema, mistralAdapter, mistralStubAdapter, multiSink, noopSink, openaiAdapter, openaiStubAdapter, openrouterAdapter, parseClaudeCliJson, parseJsonLoose, refreshAvailability, regionOfHost, regionOfProvider, requestyAdapter, resetRefreshState, resetRegistry, resolveAzureVoice, resolveTier, resolveVoice, sqliteBudgetStore, sqliteSink, streamTransport, stubProviders, subprocessTransport, tierSpecSchema, toProviderTools, toolSchema, translateInputSchema, upmetricsCostClient, upmetricsSink, usdFromMicro, vertexAdapter, visionInputSchema, wouldProviderRouteTo, wouldRouteTo };
package/dist/index.js CHANGED
@@ -2876,6 +2876,23 @@ function parseJsonLoose(text) {
2876
2876
  const end = Math.max(lastObj, lastArr);
2877
2877
  return JSON.parse(slice.slice(0, end + 1));
2878
2878
  }
2879
+ function matchLabel(answer, labels) {
2880
+ if (typeof answer !== "string") return null;
2881
+ if (labels.includes(answer)) return answer;
2882
+ const norm = (s) => s.trim().replace(/^["'`]|["'`]$/g, "").trim().toLowerCase();
2883
+ const a = norm(answer);
2884
+ if (a.length === 0) return null;
2885
+ const exactish = labels.filter((l) => norm(l) === a);
2886
+ if (exactish.length === 1) return exactish[0];
2887
+ if (exactish.length > 1) return null;
2888
+ const prefixed = labels.filter((l) => {
2889
+ const n = norm(l);
2890
+ if (!n.startsWith(a)) return false;
2891
+ const next = n.charAt(a.length);
2892
+ return next === "" || /\s/.test(next);
2893
+ });
2894
+ return prefixed.length === 1 ? prefixed[0] : null;
2895
+ }
2879
2896
  function makeContracts(client) {
2880
2897
  return {
2881
2898
  async mockup(input) {
@@ -2938,10 +2955,10 @@ ${input.text}`,
2938
2955
  purpose: input.purpose ?? "contract:classify"
2939
2956
  });
2940
2957
  const parsed = parseJsonLoose(res.text);
2941
- const matched = typeof parsed.label === "string" && input.labels.includes(parsed.label);
2958
+ const matched = matchLabel(parsed.label, input.labels);
2942
2959
  return {
2943
- label: matched ? parsed.label : null,
2944
- ...matched ? {} : { rawLabel: typeof parsed.label === "string" ? parsed.label : res.text.slice(0, 200) },
2960
+ label: matched,
2961
+ ...matched !== null ? {} : { rawLabel: typeof parsed.label === "string" ? parsed.label : res.text.slice(0, 200) },
2945
2962
  // 0 is a real confidence; "no confidence reported" is not 0.
2946
2963
  confidence: typeof parsed.confidence === "number" ? parsed.confidence : null,
2947
2964
  usage: res.usage
@@ -3362,8 +3379,8 @@ var aiConfigSchema = z.object({
3362
3379
  });
3363
3380
 
3364
3381
  // src/version.ts
3365
- var VERSION = "0.47.0";
3366
- var SDK_TAG = "@broberg/ai-sdk@0.47.0";
3382
+ var VERSION = "0.47.1";
3383
+ var SDK_TAG = "@broberg/ai-sdk@0.47.1";
3367
3384
 
3368
3385
  // src/cost/sinks/upmetrics.ts
3369
3386
  function upmetricsSink(config) {
@@ -4448,6 +4465,7 @@ export {
4448
4465
  listVoices,
4449
4466
  makeContracts,
4450
4467
  makeOpenAICompatibleAdapter,
4468
+ matchLabel,
4451
4469
  messageSchema,
4452
4470
  mistralAdapter,
4453
4471
  mistralStubAdapter,