@broberg/ai-sdk 0.1.2 → 0.3.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
@@ -74,12 +74,21 @@ interface Usage {
74
74
  interface CostSink {
75
75
  record(usage: Usage): void | Promise<void>;
76
76
  }
77
+ /** Backing store for a BudgetGuard's rolling total. Default is in-memory
78
+ * (per createAI instance). A persistent store (e.g. sqliteBudgetStore) makes
79
+ * the rolling budget survive restarts + shared across processes (F7.1). */
80
+ interface BudgetStore {
81
+ getSpent(): number | Promise<number>;
82
+ addSpent(usd: number): void | Promise<void>;
83
+ }
77
84
  /** Pre-flight budget ceilings, enforced before a call fires (F3.2). */
78
85
  interface BudgetConfig {
79
86
  /** Reject a single call whose estimated cost exceeds this many USD. */
80
87
  perCallUsd?: number;
81
- /** Reject once cumulative spend on this client instance exceeds this many USD. */
88
+ /** Reject once cumulative spend exceeds this many USD. */
82
89
  rollingUsd?: number;
90
+ /** Where the rolling total lives. Omit for in-memory (per instance). */
91
+ store?: BudgetStore;
83
92
  }
84
93
  /** Per-call options shared by every capability: which tier, optional routing
85
94
  * override, optional fallback chain, and a free-text purpose for cost reports. */
@@ -98,12 +107,39 @@ interface ChatRequest {
98
107
  tools?: Tool[];
99
108
  maxTokens?: number;
100
109
  temperature?: number;
110
+ /** "json" → request JSON-object output where the provider supports it (F009). */
111
+ responseFormat?: "json" | "text";
101
112
  }
102
113
  interface ChatResult {
103
114
  text: string;
104
115
  toolCalls?: ToolCall[];
105
116
  usage: Usage;
106
117
  }
118
+ /** A single event from `ai.chatStream` / `adapter.chatStream` (F8). A streamed
119
+ * turn yields `text`/`tool_call` events as they arrive, one `usage` event when
120
+ * the provider reports totals, and a terminal `finish` (or `error`). Tool calls
121
+ * are emitted COMPLETE — accumulated across wire fragments, never partial. */
122
+ type ChatStreamEvent = {
123
+ type: "text";
124
+ delta: string;
125
+ } | {
126
+ type: "tool_call";
127
+ id: string;
128
+ name: string;
129
+ args: Record<string, unknown>;
130
+ } | {
131
+ type: "usage";
132
+ costUsd: number;
133
+ model: string;
134
+ usage: Usage;
135
+ } | {
136
+ type: "finish";
137
+ reason: "end_turn" | "tool_calls" | "length" | "stop";
138
+ } | {
139
+ type: "error";
140
+ message: string;
141
+ status?: number;
142
+ };
107
143
  interface ImageRequest {
108
144
  prompt: string;
109
145
  spec: TierSpec;
@@ -126,6 +162,8 @@ interface TranscribeRequest {
126
162
  /** Raw audio bytes (the client resolves a URL to bytes before calling). */
127
163
  audio: Uint8Array;
128
164
  language?: string;
165
+ /** Audio length in seconds — enables per-minute cost (Whisper). Omit → cost 0. */
166
+ durationSec?: number;
129
167
  spec: TierSpec;
130
168
  }
131
169
  interface TranscribeResult {
@@ -141,6 +179,9 @@ interface ProviderAdapter {
141
179
  * (e.g. fal does image only). The client guards each call and throws a clear
142
180
  * "provider X does not support Y" when a capability is absent. */
143
181
  chat?(req: ChatRequest): Promise<ChatResult>;
182
+ /** Streaming chat (F8). Optional — absence is a typed "no streaming support".
183
+ * Same request shape as chat; yields ChatStreamEvents as the turn unfolds. */
184
+ chatStream?(req: ChatRequest): AsyncIterable<ChatStreamEvent>;
144
185
  vision?(req: ChatRequest): Promise<ChatResult>;
145
186
  image?(req: ImageRequest): Promise<ImageResult>;
146
187
  embedding?(req: EmbeddingRequest): Promise<EmbeddingResult>;
@@ -430,6 +471,8 @@ declare const chatInputSchema: z.ZodObject<{
430
471
  }>, "many">>;
431
472
  maxTokens: z.ZodOptional<z.ZodNumber>;
432
473
  temperature: z.ZodOptional<z.ZodNumber>;
474
+ /** "json" requests JSON-object output (OpenAI-compatible response_format). */
475
+ responseFormat: z.ZodOptional<z.ZodEnum<["json", "text"]>>;
433
476
  }, "strip", z.ZodTypeAny, {
434
477
  system?: string | undefined;
435
478
  prompt?: string | undefined;
@@ -457,6 +500,7 @@ declare const chatInputSchema: z.ZodObject<{
457
500
  }[] | undefined;
458
501
  temperature?: number | undefined;
459
502
  maxTokens?: number | undefined;
503
+ responseFormat?: "text" | "json" | undefined;
460
504
  tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "embedding" | undefined;
461
505
  override?: {
462
506
  provider?: string | undefined;
@@ -496,6 +540,7 @@ declare const chatInputSchema: z.ZodObject<{
496
540
  }[] | undefined;
497
541
  temperature?: number | undefined;
498
542
  maxTokens?: number | undefined;
543
+ responseFormat?: "text" | "json" | undefined;
499
544
  tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "embedding" | undefined;
500
545
  override?: {
501
546
  provider?: string | undefined;
@@ -795,6 +840,8 @@ declare const transcribeInputSchema: z.ZodObject<{
795
840
  /** Audio URL or raw bytes. */
796
841
  audio: z.ZodUnion<[z.ZodString, z.ZodType<Uint8Array<ArrayBuffer>, z.ZodTypeDef, Uint8Array<ArrayBuffer>>]>;
797
842
  language: z.ZodOptional<z.ZodString>;
843
+ /** Audio length in seconds — enables Whisper per-minute cost. */
844
+ durationSec: z.ZodOptional<z.ZodNumber>;
798
845
  }, "strip", z.ZodTypeAny, {
799
846
  audio: string | Uint8Array<ArrayBuffer>;
800
847
  language?: string | undefined;
@@ -810,6 +857,7 @@ declare const transcribeInputSchema: z.ZodObject<{
810
857
  transport: "http" | "subprocess";
811
858
  })[] | undefined;
812
859
  purpose?: string | undefined;
860
+ durationSec?: number | undefined;
813
861
  }, {
814
862
  audio: string | Uint8Array<ArrayBuffer>;
815
863
  language?: string | undefined;
@@ -825,6 +873,7 @@ declare const transcribeInputSchema: z.ZodObject<{
825
873
  transport: "http" | "subprocess";
826
874
  })[] | undefined;
827
875
  purpose?: string | undefined;
876
+ durationSec?: number | undefined;
828
877
  }>;
829
878
  declare const aiConfigSchema: z.ZodObject<{
830
879
  defaults: z.ZodOptional<z.ZodRecord<z.ZodEnum<["fast", "smart", "powerful", "cheap", "vision", "embedding"]>, z.ZodObject<{
@@ -887,6 +936,9 @@ type AiConfig = z.infer<typeof aiConfigSchema>;
887
936
  /** The public facade. Defined here because it depends on the derived inputs. */
888
937
  interface AiClient {
889
938
  chat(input: ChatInput): Promise<ChatResult>;
939
+ /** Streaming chat (F8) — same input as chat; yields ChatStreamEvents. The
940
+ * caller owns the tool-loop (per-turn engine, not an agent runtime). */
941
+ chatStream(input: ChatInput): AsyncIterable<ChatStreamEvent>;
890
942
  vision(input: VisionInput): Promise<ChatResult>;
891
943
  translate(input: TranslateInput): Promise<TranslateResult>;
892
944
  image(input: ImageInput): Promise<ImageResult>;
@@ -912,6 +964,7 @@ declare function anthropicAdapter(config?: {
912
964
  apiKey?: string;
913
965
  baseUrl?: string;
914
966
  anthropicVersion?: string;
967
+ fetch?: typeof fetch;
915
968
  }): ProviderAdapter;
916
969
 
917
970
  declare function openaiAdapter(config?: {
@@ -923,6 +976,7 @@ declare function openaiAdapter(config?: {
923
976
  declare function geminiAdapter(config?: {
924
977
  apiKey?: string;
925
978
  baseUrl?: string;
979
+ fetch?: typeof fetch;
926
980
  }): ProviderAdapter;
927
981
 
928
982
  declare function deepinfraAdapter(config?: {
@@ -960,6 +1014,12 @@ interface OpenAICompatibleConfig {
960
1014
  apiKey?: string;
961
1015
  /** Extra headers (e.g. OpenRouter's HTTP-Referer / X-Title). */
962
1016
  extraHeaders?: Record<string, string>;
1017
+ /** Injectable fetch for the streaming path (tests). */
1018
+ fetch?: typeof fetch;
1019
+ /** OpenRouter ground-truth cost (F010): send `usage:{include:true}` and use the
1020
+ * response's `usage.cost` (USD) as costUsd, falling back to the pricing table.
1021
+ * Only OpenRouter returns this field — openai/deepinfra leave it false. */
1022
+ costFromResponseField?: boolean;
963
1023
  }
964
1024
  declare function makeOpenAICompatibleAdapter(config: OpenAICompatibleConfig): ProviderAdapter;
965
1025
 
@@ -978,8 +1038,8 @@ declare const falStubAdapter: ProviderAdapter;
978
1038
  * wires the live adapters. */
979
1039
  declare const stubProviders: Record<string, ProviderAdapter>;
980
1040
 
981
- declare const VERSION: "0.1.2";
982
- declare const SDK_TAG: "@broberg/ai-sdk@0.1.2";
1041
+ declare const VERSION: "0.3.0";
1042
+ declare const SDK_TAG: "@broberg/ai-sdk@0.3.0";
983
1043
 
984
1044
  /** Built-in defaults. Every entry is overridable via AiConfig.defaults or a
985
1045
  * per-call override. Model IDs are current at scaffold time; callers pin their
@@ -1025,15 +1085,24 @@ declare class BudgetExceededError extends Error {
1025
1085
  }
1026
1086
  declare class BudgetGuard {
1027
1087
  private readonly config;
1028
- private spentUsd;
1088
+ private readonly store;
1029
1089
  constructor(config: BudgetConfig);
1030
1090
  /** Throws BudgetExceededError if `requested` would breach the per-call ceiling
1031
- * or push the rolling total past its ceiling. Call before firing the request. */
1032
- check(requested: number): void;
1091
+ * or push the rolling total past its ceiling. Call before firing the request.
1092
+ * Async because a persistent store may be I/O-backed. */
1093
+ check(requested: number): Promise<void>;
1033
1094
  /** Add an actual cost to the running total (after a successful call). */
1034
- record(actual: number): void;
1035
- get totalSpent(): number;
1095
+ record(actual: number): Promise<void>;
1096
+ totalSpent(): Promise<number>;
1097
+ }
1098
+
1099
+ interface SqliteBudgetStoreConfig {
1100
+ /** SQLite file path, e.g. "./ai-budget.db". */
1101
+ dbPath: string;
1102
+ /** Window/bucket key — use e.g. a day-stamp for a daily budget. Default "default". */
1103
+ key?: string;
1036
1104
  }
1105
+ declare function sqliteBudgetStore(config: SqliteBudgetStoreConfig): BudgetStore;
1037
1106
 
1038
1107
  /** A sink that does nothing. The default when no costSink is configured. */
1039
1108
  declare const noopSink: CostSink;
@@ -1146,4 +1215,21 @@ declare function httpTransport(req: TransportRequest): Promise<HttpResponse>;
1146
1215
  declare function parseClaudeCliJson(raw: string): SubprocessResponse;
1147
1216
  declare function subprocessTransport(req: TransportRequest): Promise<SubprocessResponse>;
1148
1217
 
1149
- export { type AiClient, type AiConfig, type BudgetConfig, BudgetExceededError, BudgetGuard, type CallOptions, type Capability, type ChatInput, type ChatRequest, type ChatResult, type ClassifyInput, type ClassifyResult, type ContentPart, type Contracts, type CostSink, type CostSummary, DEFAULT_TIER_MAP, type DesignInput, type DesignResult, type DiscordSinkConfig, type EmbeddingInput, type EmbeddingRequest, type EmbeddingResult, type ExtractInput, type ExtractResult, type FalAdapterConfig, type HttpResponse, type ImageInput, type ImageRequest, type ImageResult, type Message, type MockupInput, type MockupResult, type OpenAICompatibleConfig, type PricingEntry, type ProviderAdapter, type RerankInput, type RerankResult, type Role, SDK_TAG, type SqliteSinkConfig, type SubprocessResponse, type Tier, type TierSpec, type Tool, type ToolCall, type TranscribeInput, type TranscribeRequest, type TranscribeResult, type TranslateInput, type TranslateResult, type Transport, type TransportRequest, type TransportResponse, type UpmetricsSinkConfig, type Usage, VERSION, type VisionInput, aiConfigSchema, anthropicAdapter, anthropicApiAdapter, anthropicSubprocessAdapter, chatInputSchema, computeCost, createAI, deepinfraAdapter, defaultProviders, discordSink, embeddingInputSchema, falAdapter, falStubAdapter, freshUsage, fromProviderToolCall, geminiAdapter, getCostSummary, getPrice, httpTransport, imageInputSchema, makeContracts, makeOpenAICompatibleAdapter, messageSchema, multiSink, noopSink, openaiAdapter, openaiStubAdapter, openrouterAdapter, parseClaudeCliJson, parseJsonLoose, resolveTier, sqliteSink, stubProviders, subprocessTransport, tierSpecSchema, toProviderTools, toolSchema, translateInputSchema, upmetricsSink, visionInputSchema };
1218
+ /** HTTP error from a streaming connect carries `status` so the client's
1219
+ * pre-stream fallback can tell an eligible 429/5xx from a hard 4xx. */
1220
+ declare class StreamHttpError extends Error {
1221
+ readonly status: number;
1222
+ constructor(message: string, status: number);
1223
+ }
1224
+ interface StreamTransportRequest extends TransportRequest {
1225
+ /** Injectable fetch for tests. */
1226
+ fetch?: typeof fetch;
1227
+ }
1228
+ /**
1229
+ * Open an SSE stream and yield each event's `data:` payload as a raw string
1230
+ * (the JSON after `data: `), skipping the `[DONE]` terminator and non-data
1231
+ * lines. Throws StreamHttpError before the first yield on a non-2xx connect.
1232
+ */
1233
+ declare function streamTransport(req: StreamTransportRequest): AsyncIterable<string>;
1234
+
1235
+ export { type AiClient, type AiConfig, 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 DiscordSinkConfig, type EmbeddingInput, type EmbeddingRequest, type EmbeddingResult, type ExtractInput, type ExtractResult, type FalAdapterConfig, type HttpResponse, type ImageInput, type ImageRequest, type ImageResult, type Message, type MockupInput, type MockupResult, type OpenAICompatibleConfig, type PricingEntry, type ProviderAdapter, type RerankInput, type RerankResult, type Role, SDK_TAG, type SqliteBudgetStoreConfig, type SqliteSinkConfig, StreamHttpError, type SubprocessResponse, type Tier, type TierSpec, type Tool, type ToolCall, type TranscribeInput, type TranscribeRequest, type TranscribeResult, type TranslateInput, type TranslateResult, type Transport, type TransportRequest, type TransportResponse, type UpmetricsSinkConfig, type Usage, VERSION, type VisionInput, aiConfigSchema, anthropicAdapter, anthropicApiAdapter, anthropicSubprocessAdapter, chatInputSchema, computeCost, createAI, deepinfraAdapter, defaultProviders, discordSink, embeddingInputSchema, falAdapter, falStubAdapter, freshUsage, fromProviderToolCall, geminiAdapter, getCostSummary, getPrice, httpTransport, imageInputSchema, makeContracts, makeOpenAICompatibleAdapter, messageSchema, multiSink, noopSink, openaiAdapter, openaiStubAdapter, openrouterAdapter, parseClaudeCliJson, parseJsonLoose, resolveTier, sqliteBudgetStore, sqliteSink, streamTransport, stubProviders, subprocessTransport, tierSpecSchema, toProviderTools, toolSchema, translateInputSchema, upmetricsSink, visionInputSchema };