@broberg/ai-sdk 0.6.0 → 0.7.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 +171 -4
- package/dist/index.js +124 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ interface TierSpec {
|
|
|
13
13
|
transport: Transport;
|
|
14
14
|
}
|
|
15
15
|
/** High-level capability a call exercises. Mirrors the capability layer (F5). */
|
|
16
|
-
type Capability = "chat" | "vision" | "video" | "translate" | "image" | "embedding" | "transcribe" | "mockup" | "design" | "extract" | "classify" | "rerank";
|
|
16
|
+
type Capability = "chat" | "vision" | "video" | "translate" | "image" | "embedding" | "transcribe" | "ocr" | "moderation" | "mockup" | "design" | "extract" | "classify" | "rerank";
|
|
17
17
|
type Role = "system" | "user" | "assistant" | "tool";
|
|
18
18
|
/** A piece of message content. Text everywhere; image parts feed vision. */
|
|
19
19
|
type ContentPart = {
|
|
@@ -180,6 +180,34 @@ interface TranscribeResult {
|
|
|
180
180
|
text: string;
|
|
181
181
|
usage: Usage;
|
|
182
182
|
}
|
|
183
|
+
interface OcrRequest {
|
|
184
|
+
/** A URL, data-URL, or raw bytes of the document/image. */
|
|
185
|
+
document: string | Uint8Array;
|
|
186
|
+
mimeType?: string;
|
|
187
|
+
spec: TierSpec;
|
|
188
|
+
}
|
|
189
|
+
interface OcrPage {
|
|
190
|
+
index: number;
|
|
191
|
+
markdown: string;
|
|
192
|
+
}
|
|
193
|
+
interface OcrResult {
|
|
194
|
+
pages: OcrPage[];
|
|
195
|
+
usage: Usage;
|
|
196
|
+
}
|
|
197
|
+
interface ModerationRequest {
|
|
198
|
+
input: string[];
|
|
199
|
+
spec: TierSpec;
|
|
200
|
+
}
|
|
201
|
+
interface ModerationItem {
|
|
202
|
+
/** True if any category tripped. */
|
|
203
|
+
flagged: boolean;
|
|
204
|
+
categories: Record<string, boolean>;
|
|
205
|
+
categoryScores: Record<string, number>;
|
|
206
|
+
}
|
|
207
|
+
interface ModerationResult {
|
|
208
|
+
results: ModerationItem[];
|
|
209
|
+
usage: Usage;
|
|
210
|
+
}
|
|
183
211
|
/** The thin contract every provider implements (F4). A provider need only
|
|
184
212
|
* support the capabilities it offers — `chat` is the baseline; vision/image/
|
|
185
213
|
* embedding are optional and absence is a typed capability gap. */
|
|
@@ -196,6 +224,8 @@ interface ProviderAdapter {
|
|
|
196
224
|
image?(req: ImageRequest): Promise<ImageResult>;
|
|
197
225
|
embedding?(req: EmbeddingRequest): Promise<EmbeddingResult>;
|
|
198
226
|
transcribe?(req: TranscribeRequest): Promise<TranscribeResult>;
|
|
227
|
+
ocr?(req: OcrRequest): Promise<OcrResult>;
|
|
228
|
+
moderate?(req: ModerationRequest): Promise<ModerationResult>;
|
|
199
229
|
}
|
|
200
230
|
interface TranslateResult {
|
|
201
231
|
text: string;
|
|
@@ -971,6 +1001,135 @@ declare const transcribeInputSchema: z.ZodObject<{
|
|
|
971
1001
|
labels?: Record<string, string> | undefined;
|
|
972
1002
|
durationSec?: number | undefined;
|
|
973
1003
|
}>;
|
|
1004
|
+
declare const ocrInputSchema: z.ZodObject<{
|
|
1005
|
+
tier: z.ZodOptional<z.ZodEnum<["fast", "smart", "powerful", "cheap", "vision", "video", "embedding"]>>;
|
|
1006
|
+
override: z.ZodOptional<z.ZodObject<{
|
|
1007
|
+
provider: z.ZodOptional<z.ZodString>;
|
|
1008
|
+
model: z.ZodOptional<z.ZodString>;
|
|
1009
|
+
transport: z.ZodOptional<z.ZodEnum<["http", "subprocess"]>>;
|
|
1010
|
+
}, "strip", z.ZodTypeAny, {
|
|
1011
|
+
provider?: string | undefined;
|
|
1012
|
+
model?: string | undefined;
|
|
1013
|
+
transport?: "http" | "subprocess" | undefined;
|
|
1014
|
+
}, {
|
|
1015
|
+
provider?: string | undefined;
|
|
1016
|
+
model?: string | undefined;
|
|
1017
|
+
transport?: "http" | "subprocess" | undefined;
|
|
1018
|
+
}>>;
|
|
1019
|
+
fallback: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodEnum<["fast", "smart", "powerful", "cheap", "vision", "video", "embedding"]>, z.ZodObject<{
|
|
1020
|
+
provider: z.ZodString;
|
|
1021
|
+
model: z.ZodString;
|
|
1022
|
+
transport: z.ZodEnum<["http", "subprocess"]>;
|
|
1023
|
+
}, "strip", z.ZodTypeAny, {
|
|
1024
|
+
provider: string;
|
|
1025
|
+
model: string;
|
|
1026
|
+
transport: "http" | "subprocess";
|
|
1027
|
+
}, {
|
|
1028
|
+
provider: string;
|
|
1029
|
+
model: string;
|
|
1030
|
+
transport: "http" | "subprocess";
|
|
1031
|
+
}>]>, "many">>;
|
|
1032
|
+
purpose: z.ZodOptional<z.ZodString>;
|
|
1033
|
+
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1034
|
+
/** A URL, data-URL, or raw bytes of the document/image. */
|
|
1035
|
+
document: z.ZodUnion<[z.ZodString, z.ZodType<Uint8Array<ArrayBuffer>, z.ZodTypeDef, Uint8Array<ArrayBuffer>>]>;
|
|
1036
|
+
/** image/* → routed as an image; anything else → a document (PDF etc.). */
|
|
1037
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
1038
|
+
}, "strip", z.ZodTypeAny, {
|
|
1039
|
+
document: string | Uint8Array<ArrayBuffer>;
|
|
1040
|
+
mimeType?: string | undefined;
|
|
1041
|
+
tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
|
|
1042
|
+
override?: {
|
|
1043
|
+
provider?: string | undefined;
|
|
1044
|
+
model?: string | undefined;
|
|
1045
|
+
transport?: "http" | "subprocess" | undefined;
|
|
1046
|
+
} | undefined;
|
|
1047
|
+
fallback?: ("fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | {
|
|
1048
|
+
provider: string;
|
|
1049
|
+
model: string;
|
|
1050
|
+
transport: "http" | "subprocess";
|
|
1051
|
+
})[] | undefined;
|
|
1052
|
+
purpose?: string | undefined;
|
|
1053
|
+
labels?: Record<string, string> | undefined;
|
|
1054
|
+
}, {
|
|
1055
|
+
document: string | Uint8Array<ArrayBuffer>;
|
|
1056
|
+
mimeType?: string | undefined;
|
|
1057
|
+
tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
|
|
1058
|
+
override?: {
|
|
1059
|
+
provider?: string | undefined;
|
|
1060
|
+
model?: string | undefined;
|
|
1061
|
+
transport?: "http" | "subprocess" | undefined;
|
|
1062
|
+
} | undefined;
|
|
1063
|
+
fallback?: ("fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | {
|
|
1064
|
+
provider: string;
|
|
1065
|
+
model: string;
|
|
1066
|
+
transport: "http" | "subprocess";
|
|
1067
|
+
})[] | undefined;
|
|
1068
|
+
purpose?: string | undefined;
|
|
1069
|
+
labels?: Record<string, string> | undefined;
|
|
1070
|
+
}>;
|
|
1071
|
+
declare const moderationInputSchema: z.ZodObject<{
|
|
1072
|
+
tier: z.ZodOptional<z.ZodEnum<["fast", "smart", "powerful", "cheap", "vision", "video", "embedding"]>>;
|
|
1073
|
+
override: z.ZodOptional<z.ZodObject<{
|
|
1074
|
+
provider: z.ZodOptional<z.ZodString>;
|
|
1075
|
+
model: z.ZodOptional<z.ZodString>;
|
|
1076
|
+
transport: z.ZodOptional<z.ZodEnum<["http", "subprocess"]>>;
|
|
1077
|
+
}, "strip", z.ZodTypeAny, {
|
|
1078
|
+
provider?: string | undefined;
|
|
1079
|
+
model?: string | undefined;
|
|
1080
|
+
transport?: "http" | "subprocess" | undefined;
|
|
1081
|
+
}, {
|
|
1082
|
+
provider?: string | undefined;
|
|
1083
|
+
model?: string | undefined;
|
|
1084
|
+
transport?: "http" | "subprocess" | undefined;
|
|
1085
|
+
}>>;
|
|
1086
|
+
fallback: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodEnum<["fast", "smart", "powerful", "cheap", "vision", "video", "embedding"]>, z.ZodObject<{
|
|
1087
|
+
provider: z.ZodString;
|
|
1088
|
+
model: z.ZodString;
|
|
1089
|
+
transport: z.ZodEnum<["http", "subprocess"]>;
|
|
1090
|
+
}, "strip", z.ZodTypeAny, {
|
|
1091
|
+
provider: string;
|
|
1092
|
+
model: string;
|
|
1093
|
+
transport: "http" | "subprocess";
|
|
1094
|
+
}, {
|
|
1095
|
+
provider: string;
|
|
1096
|
+
model: string;
|
|
1097
|
+
transport: "http" | "subprocess";
|
|
1098
|
+
}>]>, "many">>;
|
|
1099
|
+
purpose: z.ZodOptional<z.ZodString>;
|
|
1100
|
+
labels: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
1101
|
+
input: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
1102
|
+
}, "strip", z.ZodTypeAny, {
|
|
1103
|
+
input: string | string[];
|
|
1104
|
+
tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
|
|
1105
|
+
override?: {
|
|
1106
|
+
provider?: string | undefined;
|
|
1107
|
+
model?: string | undefined;
|
|
1108
|
+
transport?: "http" | "subprocess" | undefined;
|
|
1109
|
+
} | undefined;
|
|
1110
|
+
fallback?: ("fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | {
|
|
1111
|
+
provider: string;
|
|
1112
|
+
model: string;
|
|
1113
|
+
transport: "http" | "subprocess";
|
|
1114
|
+
})[] | undefined;
|
|
1115
|
+
purpose?: string | undefined;
|
|
1116
|
+
labels?: Record<string, string> | undefined;
|
|
1117
|
+
}, {
|
|
1118
|
+
input: string | string[];
|
|
1119
|
+
tier?: "fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | undefined;
|
|
1120
|
+
override?: {
|
|
1121
|
+
provider?: string | undefined;
|
|
1122
|
+
model?: string | undefined;
|
|
1123
|
+
transport?: "http" | "subprocess" | undefined;
|
|
1124
|
+
} | undefined;
|
|
1125
|
+
fallback?: ("fast" | "smart" | "powerful" | "cheap" | "vision" | "video" | "embedding" | {
|
|
1126
|
+
provider: string;
|
|
1127
|
+
model: string;
|
|
1128
|
+
transport: "http" | "subprocess";
|
|
1129
|
+
})[] | undefined;
|
|
1130
|
+
purpose?: string | undefined;
|
|
1131
|
+
labels?: Record<string, string> | undefined;
|
|
1132
|
+
}>;
|
|
974
1133
|
declare const aiConfigSchema: z.ZodObject<{
|
|
975
1134
|
defaults: z.ZodOptional<z.ZodRecord<z.ZodEnum<["fast", "smart", "powerful", "cheap", "vision", "video", "embedding"]>, z.ZodObject<{
|
|
976
1135
|
provider: z.ZodString;
|
|
@@ -1029,6 +1188,8 @@ type TranslateInput = z.infer<typeof translateInputSchema>;
|
|
|
1029
1188
|
type ImageInput = z.infer<typeof imageInputSchema>;
|
|
1030
1189
|
type EmbeddingInput = z.infer<typeof embeddingInputSchema>;
|
|
1031
1190
|
type TranscribeInput = z.infer<typeof transcribeInputSchema>;
|
|
1191
|
+
type OcrInput = z.infer<typeof ocrInputSchema>;
|
|
1192
|
+
type ModerationInput = z.infer<typeof moderationInputSchema>;
|
|
1032
1193
|
type AiConfig = z.infer<typeof aiConfigSchema>;
|
|
1033
1194
|
/** The public facade. Defined here because it depends on the derived inputs. */
|
|
1034
1195
|
interface AiClient {
|
|
@@ -1043,6 +1204,10 @@ interface AiClient {
|
|
|
1043
1204
|
image(input: ImageInput): Promise<ImageResult>;
|
|
1044
1205
|
embedding(input: EmbeddingInput): Promise<EmbeddingResult>;
|
|
1045
1206
|
transcribe(input: TranscribeInput): Promise<TranscribeResult>;
|
|
1207
|
+
/** OCR (F016.2) — document/image → structured markdown, billed per page. Mistral. */
|
|
1208
|
+
ocr(input: OcrInput): Promise<OcrResult>;
|
|
1209
|
+
/** Moderation (F016.4) — classify text against safety categories. Mistral. */
|
|
1210
|
+
moderate(input: ModerationInput): Promise<ModerationResult>;
|
|
1046
1211
|
/** Prompt-contract capabilities (F5.5) layered on chat/vision. */
|
|
1047
1212
|
contracts: Contracts;
|
|
1048
1213
|
}
|
|
@@ -1094,6 +1259,8 @@ declare function openrouterAdapter(config?: {
|
|
|
1094
1259
|
declare function mistralAdapter(config?: {
|
|
1095
1260
|
apiKey?: string;
|
|
1096
1261
|
baseUrl?: string;
|
|
1262
|
+
fetch?: typeof fetch;
|
|
1263
|
+
pricePerPage?: number;
|
|
1097
1264
|
}): ProviderAdapter;
|
|
1098
1265
|
|
|
1099
1266
|
interface FalAdapterConfig {
|
|
@@ -1143,8 +1310,8 @@ declare const falStubAdapter: ProviderAdapter;
|
|
|
1143
1310
|
* wires the live adapters. */
|
|
1144
1311
|
declare const stubProviders: Record<string, ProviderAdapter>;
|
|
1145
1312
|
|
|
1146
|
-
declare const VERSION: "0.
|
|
1147
|
-
declare const SDK_TAG: "@broberg/ai-sdk@0.
|
|
1313
|
+
declare const VERSION: "0.7.0";
|
|
1314
|
+
declare const SDK_TAG: "@broberg/ai-sdk@0.7.0";
|
|
1148
1315
|
|
|
1149
1316
|
/** Built-in defaults. Every entry is overridable via AiConfig.defaults or a
|
|
1150
1317
|
* per-call override. Model IDs are current at scaffold time; callers pin their
|
|
@@ -1337,4 +1504,4 @@ interface StreamTransportRequest extends TransportRequest {
|
|
|
1337
1504
|
*/
|
|
1338
1505
|
declare function streamTransport(req: StreamTransportRequest): AsyncIterable<string>;
|
|
1339
1506
|
|
|
1340
|
-
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 VideoInput, 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, mistralAdapter, multiSink, noopSink, openaiAdapter, openaiStubAdapter, openrouterAdapter, parseClaudeCliJson, parseJsonLoose, resolveTier, sqliteBudgetStore, sqliteSink, streamTransport, stubProviders, subprocessTransport, tierSpecSchema, toProviderTools, toolSchema, translateInputSchema, upmetricsSink, visionInputSchema };
|
|
1507
|
+
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 ModerationInput, type ModerationItem, type ModerationRequest, type ModerationResult, type OcrInput, type OcrPage, type OcrRequest, type OcrResult, 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 VideoInput, 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, mistralAdapter, multiSink, noopSink, openaiAdapter, openaiStubAdapter, openrouterAdapter, parseClaudeCliJson, parseJsonLoose, resolveTier, sqliteBudgetStore, sqliteSink, streamTransport, stubProviders, subprocessTransport, tierSpecSchema, toProviderTools, toolSchema, translateInputSchema, upmetricsSink, visionInputSchema };
|
package/dist/index.js
CHANGED
|
@@ -278,7 +278,9 @@ var PRICING = {
|
|
|
278
278
|
"mistral:magistral-small-latest": { inputPer1M: 0.5, outputPer1M: 1.5, version: MS },
|
|
279
279
|
"mistral:devstral-latest": { inputPer1M: 0.4, outputPer1M: 2, version: MS },
|
|
280
280
|
"mistral:codestral-latest": { inputPer1M: 0.3, outputPer1M: 0.9, version: MS },
|
|
281
|
-
"mistral:open-mistral-nemo": { inputPer1M: 0.15, outputPer1M: 0.15, version: MS }
|
|
281
|
+
"mistral:open-mistral-nemo": { inputPer1M: 0.15, outputPer1M: 0.15, version: MS },
|
|
282
|
+
// Moderation (F016.4) — per input token; output 0. (OCR is per-page in the adapter.)
|
|
283
|
+
"mistral:mistral-moderation-latest": { inputPer1M: 0.1, outputPer1M: 0, version: MS }
|
|
282
284
|
};
|
|
283
285
|
function getPrice(provider, model) {
|
|
284
286
|
const exact = PRICING[`${provider}:${model}`];
|
|
@@ -1025,12 +1027,77 @@ function openrouterAdapter(config = {}) {
|
|
|
1025
1027
|
}
|
|
1026
1028
|
|
|
1027
1029
|
// src/providers/mistral.ts
|
|
1030
|
+
var MISTRAL_OCR_PRICE_PER_PAGE = 2e-3;
|
|
1028
1031
|
function mistralAdapter(config = {}) {
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1032
|
+
const baseUrl = config.baseUrl ?? "https://api.mistral.ai/v1";
|
|
1033
|
+
const base = makeOpenAICompatibleAdapter({ name: "mistral", baseUrl, apiKey: config.apiKey });
|
|
1034
|
+
function key() {
|
|
1035
|
+
const k = config.apiKey ?? process.env.MISTRAL_API_KEY;
|
|
1036
|
+
if (!k) throw new Error("mistral adapter: API key not set (env MISTRAL_API_KEY)");
|
|
1037
|
+
return k;
|
|
1038
|
+
}
|
|
1039
|
+
const fetchImpl = config.fetch ?? fetch;
|
|
1040
|
+
async function ocr(req) {
|
|
1041
|
+
const isImage = (req.mimeType ?? "").startsWith("image/");
|
|
1042
|
+
const url = typeof req.document === "string" ? req.document : `data:${req.mimeType ?? "application/pdf"};base64,${Buffer.from(req.document).toString("base64")}`;
|
|
1043
|
+
const document = isImage ? { type: "image_url", image_url: url } : { type: "document_url", document_url: url };
|
|
1044
|
+
const res = await fetchImpl(`${baseUrl}/ocr`, {
|
|
1045
|
+
method: "POST",
|
|
1046
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${key()}` },
|
|
1047
|
+
body: JSON.stringify({ model: req.spec.model, document })
|
|
1048
|
+
});
|
|
1049
|
+
if (!res.ok) {
|
|
1050
|
+
const body = await res.text().catch(() => "");
|
|
1051
|
+
throw new Error(`mistral ocr ${res.status}: ${body.slice(0, 300)}`);
|
|
1052
|
+
}
|
|
1053
|
+
const data = await res.json();
|
|
1054
|
+
const pages = (data.pages ?? []).map((p, i) => ({
|
|
1055
|
+
index: p.index ?? i,
|
|
1056
|
+
markdown: p.markdown ?? ""
|
|
1057
|
+
}));
|
|
1058
|
+
const pagesProcessed = data.usage_info?.pages_processed ?? pages.length;
|
|
1059
|
+
const usage = freshUsage({
|
|
1060
|
+
provider: "mistral",
|
|
1061
|
+
model: req.spec.model,
|
|
1062
|
+
transport: "http",
|
|
1063
|
+
capability: "ocr",
|
|
1064
|
+
inputTokens: 0,
|
|
1065
|
+
outputTokens: 0
|
|
1066
|
+
});
|
|
1067
|
+
usage.costUsd = pagesProcessed * (config.pricePerPage ?? MISTRAL_OCR_PRICE_PER_PAGE);
|
|
1068
|
+
return { pages, usage };
|
|
1069
|
+
}
|
|
1070
|
+
async function moderate(req) {
|
|
1071
|
+
const res = await fetchImpl(`${baseUrl}/moderations`, {
|
|
1072
|
+
method: "POST",
|
|
1073
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${key()}` },
|
|
1074
|
+
body: JSON.stringify({ model: req.spec.model, input: req.input })
|
|
1075
|
+
});
|
|
1076
|
+
if (!res.ok) {
|
|
1077
|
+
const body = await res.text().catch(() => "");
|
|
1078
|
+
throw new Error(`mistral moderation ${res.status}: ${body.slice(0, 300)}`);
|
|
1079
|
+
}
|
|
1080
|
+
const data = await res.json();
|
|
1081
|
+
const results = (data.results ?? []).map((r) => {
|
|
1082
|
+
const categories = r.categories ?? {};
|
|
1083
|
+
return {
|
|
1084
|
+
flagged: Object.values(categories).some(Boolean),
|
|
1085
|
+
categories,
|
|
1086
|
+
categoryScores: r.category_scores ?? {}
|
|
1087
|
+
};
|
|
1088
|
+
});
|
|
1089
|
+
const estIn = req.input.reduce((n, s) => n + Math.ceil(s.length / 4), 0);
|
|
1090
|
+
const usage = freshUsage({
|
|
1091
|
+
provider: "mistral",
|
|
1092
|
+
model: req.spec.model,
|
|
1093
|
+
transport: "http",
|
|
1094
|
+
capability: "moderation",
|
|
1095
|
+
inputTokens: data.usage?.prompt_tokens ?? estIn,
|
|
1096
|
+
outputTokens: 0
|
|
1097
|
+
});
|
|
1098
|
+
return { results, usage };
|
|
1099
|
+
}
|
|
1100
|
+
return { ...base, ocr, moderate };
|
|
1034
1101
|
}
|
|
1035
1102
|
|
|
1036
1103
|
// src/providers/fal.ts
|
|
@@ -1432,6 +1499,17 @@ var transcribeInputSchema = z.object({
|
|
|
1432
1499
|
durationSec: z.number().positive().optional(),
|
|
1433
1500
|
...callOptions
|
|
1434
1501
|
});
|
|
1502
|
+
var ocrInputSchema = z.object({
|
|
1503
|
+
/** A URL, data-URL, or raw bytes of the document/image. */
|
|
1504
|
+
document: z.union([z.string(), z.instanceof(Uint8Array)]),
|
|
1505
|
+
/** image/* → routed as an image; anything else → a document (PDF etc.). */
|
|
1506
|
+
mimeType: z.string().optional(),
|
|
1507
|
+
...callOptions
|
|
1508
|
+
});
|
|
1509
|
+
var moderationInputSchema = z.object({
|
|
1510
|
+
input: z.union([z.string(), z.array(z.string())]),
|
|
1511
|
+
...callOptions
|
|
1512
|
+
});
|
|
1435
1513
|
var budgetSchema = z.object({
|
|
1436
1514
|
perCallUsd: z.number().positive().optional(),
|
|
1437
1515
|
rollingUsd: z.number().positive().optional()
|
|
@@ -1451,6 +1529,8 @@ var DEFAULT_IMAGE_SPEC = {
|
|
|
1451
1529
|
model: "fal-ai/flux/schnell",
|
|
1452
1530
|
transport: "http"
|
|
1453
1531
|
};
|
|
1532
|
+
var DEFAULT_OCR_SPEC = { provider: "mistral", model: "mistral-ocr-latest", transport: "http" };
|
|
1533
|
+
var DEFAULT_MODERATION_SPEC = { provider: "mistral", model: "mistral-moderation-latest", transport: "http" };
|
|
1454
1534
|
function createAI(config = {}) {
|
|
1455
1535
|
const cfg = aiConfigSchema.parse(config);
|
|
1456
1536
|
const providers = cfg.providers ?? defaultProviders;
|
|
@@ -1694,6 +1774,42 @@ function createAI(config = {}) {
|
|
|
1694
1774
|
}
|
|
1695
1775
|
});
|
|
1696
1776
|
},
|
|
1777
|
+
async ocr(input) {
|
|
1778
|
+
input = ocrInputSchema.parse(input);
|
|
1779
|
+
return runCapability({
|
|
1780
|
+
primary: { ...DEFAULT_OCR_SPEC, ...input.override },
|
|
1781
|
+
fallback: input.fallback,
|
|
1782
|
+
capability: "ocr",
|
|
1783
|
+
purpose: input.purpose,
|
|
1784
|
+
labels: input.labels,
|
|
1785
|
+
estIn: 0,
|
|
1786
|
+
// OCR cost is per-page, not token-based
|
|
1787
|
+
estOut: 0,
|
|
1788
|
+
invoke: async (spec) => {
|
|
1789
|
+
const adapter = pickProvider(spec.provider);
|
|
1790
|
+
if (!adapter.ocr) throw new Error(`createAI: provider "${spec.provider}" does not support ocr`);
|
|
1791
|
+
return adapter.ocr({ document: input.document, mimeType: input.mimeType, spec });
|
|
1792
|
+
}
|
|
1793
|
+
});
|
|
1794
|
+
},
|
|
1795
|
+
async moderate(input) {
|
|
1796
|
+
input = moderationInputSchema.parse(input);
|
|
1797
|
+
const items = Array.isArray(input.input) ? input.input : [input.input];
|
|
1798
|
+
return runCapability({
|
|
1799
|
+
primary: { ...DEFAULT_MODERATION_SPEC, ...input.override },
|
|
1800
|
+
fallback: input.fallback,
|
|
1801
|
+
capability: "moderation",
|
|
1802
|
+
purpose: input.purpose,
|
|
1803
|
+
labels: input.labels,
|
|
1804
|
+
estIn: items.reduce((n, s) => n + estTokens(s), 0),
|
|
1805
|
+
estOut: 0,
|
|
1806
|
+
invoke: async (spec) => {
|
|
1807
|
+
const adapter = pickProvider(spec.provider);
|
|
1808
|
+
if (!adapter.moderate) throw new Error(`createAI: provider "${spec.provider}" does not support moderation`);
|
|
1809
|
+
return adapter.moderate({ input: items, spec });
|
|
1810
|
+
}
|
|
1811
|
+
});
|
|
1812
|
+
},
|
|
1697
1813
|
async embedding(input) {
|
|
1698
1814
|
input = embeddingInputSchema.parse(input);
|
|
1699
1815
|
const tier = input.tier ?? EMBEDDING_DEFAULT_TIER;
|
|
@@ -1820,8 +1936,8 @@ var stubProviders = {
|
|
|
1820
1936
|
};
|
|
1821
1937
|
|
|
1822
1938
|
// src/version.ts
|
|
1823
|
-
var VERSION = "0.
|
|
1824
|
-
var SDK_TAG = "@broberg/ai-sdk@0.
|
|
1939
|
+
var VERSION = "0.7.0";
|
|
1940
|
+
var SDK_TAG = "@broberg/ai-sdk@0.7.0";
|
|
1825
1941
|
|
|
1826
1942
|
// src/cost/budget-store.ts
|
|
1827
1943
|
function sqliteBudgetStore(config) {
|