@providerprotocol/ai 0.0.27 → 0.0.28

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.
Files changed (37) hide show
  1. package/dist/anthropic/index.d.ts +1 -1
  2. package/dist/anthropic/index.js +38 -1
  3. package/dist/anthropic/index.js.map +1 -1
  4. package/dist/{chunk-6AZVUI6H.js → chunk-ILR2D5PN.js} +7 -1
  5. package/dist/chunk-ILR2D5PN.js.map +1 -0
  6. package/dist/{chunk-MKDLXV4O.js → chunk-NSE7QN3P.js} +1 -1
  7. package/dist/chunk-NSE7QN3P.js.map +1 -0
  8. package/dist/embedding-DtyOFIsS.d.ts +158 -0
  9. package/dist/google/index.d.ts +1 -1
  10. package/dist/google/index.js +41 -4
  11. package/dist/google/index.js.map +1 -1
  12. package/dist/http/index.d.ts +2 -2
  13. package/dist/index.d.ts +430 -514
  14. package/dist/index.js +627 -3
  15. package/dist/index.js.map +1 -1
  16. package/dist/llm-DgDEy9il.d.ts +3118 -0
  17. package/dist/ollama/index.d.ts +1 -1
  18. package/dist/ollama/index.js +2 -1
  19. package/dist/ollama/index.js.map +1 -1
  20. package/dist/openai/index.d.ts +1 -1
  21. package/dist/openai/index.js +70 -3
  22. package/dist/openai/index.js.map +1 -1
  23. package/dist/openrouter/index.d.ts +20 -2
  24. package/dist/openrouter/index.js +134 -13
  25. package/dist/openrouter/index.js.map +1 -1
  26. package/dist/proxy/index.d.ts +2 -2
  27. package/dist/proxy/index.js +3 -2
  28. package/dist/proxy/index.js.map +1 -1
  29. package/dist/{retry-BhX8mIrL.d.ts → retry-DXLQnTuU.d.ts} +1 -1
  30. package/dist/xai/index.d.ts +1 -1
  31. package/dist/xai/index.js +7 -3
  32. package/dist/xai/index.js.map +1 -1
  33. package/package.json +1 -1
  34. package/dist/chunk-6AZVUI6H.js.map +0 -1
  35. package/dist/chunk-MKDLXV4O.js.map +0 -1
  36. package/dist/embedding-CK5oa38O.d.ts +0 -1235
  37. package/dist/provider-6-mJYOOl.d.ts +0 -1474
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  aggregateUsage,
3
3
  createTurn,
4
4
  emptyUsage
5
- } from "./chunk-MKDLXV4O.js";
5
+ } from "./chunk-NSE7QN3P.js";
6
6
  import {
7
7
  Image
8
8
  } from "./chunk-WAKD3OO5.js";
@@ -32,7 +32,7 @@ import {
32
32
  resolveEmbeddingHandler,
33
33
  resolveImageHandler,
34
34
  resolveLLMHandler
35
- } from "./chunk-6AZVUI6H.js";
35
+ } from "./chunk-ILR2D5PN.js";
36
36
  import {
37
37
  ExponentialBackoff,
38
38
  LinearBackoff,
@@ -61,6 +61,8 @@ var ContentBlockType = {
61
61
  Reasoning: "reasoning",
62
62
  /** Image content */
63
63
  Image: "image",
64
+ /** Document content (PDFs, text files) */
65
+ Document: "document",
64
66
  /** Audio content */
65
67
  Audio: "audio",
66
68
  /** Video content */
@@ -76,6 +78,14 @@ var ImageSourceType = {
76
78
  /** Raw bytes image data */
77
79
  Bytes: "bytes"
78
80
  };
81
+ var DocumentSourceType = {
82
+ /** Base64-encoded document data (for PDFs) */
83
+ Base64: "base64",
84
+ /** URL reference to document (for PDFs) */
85
+ Url: "url",
86
+ /** Plain text document content */
87
+ Text: "text"
88
+ };
79
89
  function text(content) {
80
90
  return { type: ContentBlockType.Text, text: content };
81
91
  }
@@ -91,6 +101,9 @@ function isReasoningBlock(block) {
91
101
  function isImageBlock(block) {
92
102
  return block.type === ContentBlockType.Image;
93
103
  }
104
+ function isDocumentBlock(block) {
105
+ return block.type === ContentBlockType.Document;
106
+ }
94
107
  function isAudioBlock(block) {
95
108
  return block.type === ContentBlockType.Audio;
96
109
  }
@@ -243,7 +256,7 @@ function inputToMessage(input) {
243
256
  if (isTextBlock(block)) {
244
257
  return new UserMessage(block.text);
245
258
  }
246
- if (isImageBlock(block) || isAudioBlock(block) || isVideoBlock(block) || isBinaryBlock(block)) {
259
+ if (isImageBlock(block) || isDocumentBlock(block) || isAudioBlock(block) || isVideoBlock(block) || isBinaryBlock(block)) {
247
260
  return new UserMessage([block]);
248
261
  }
249
262
  throw new Error("Invalid inference input");
@@ -597,6 +610,14 @@ function validateMediaCapabilities(messages, capabilities, providerName) {
597
610
  ModalityType.LLM
598
611
  );
599
612
  }
613
+ if (block.type === "document" && !capabilities.documentInput) {
614
+ throw new UPPError(
615
+ `Provider '${providerName}' does not support document input`,
616
+ ErrorCode.InvalidRequest,
617
+ providerName,
618
+ ModalityType.LLM
619
+ );
620
+ }
600
621
  if (block.type === "video" && !capabilities.videoInput) {
601
622
  throw new UPPError(
602
623
  `Provider '${providerName}' does not support video input`,
@@ -938,6 +959,604 @@ function normalizeInput(input) {
938
959
  return input.prompt;
939
960
  }
940
961
 
962
+ // src/core/media/document.ts
963
+ var Document = class _Document {
964
+ /** The underlying document source (base64, url, or text) */
965
+ source;
966
+ /** MIME type of the document ('application/pdf' or 'text/plain') */
967
+ mimeType;
968
+ /** Optional document title (used for citations) */
969
+ title;
970
+ constructor(source, mimeType, title) {
971
+ this.source = source;
972
+ this.mimeType = mimeType;
973
+ this.title = title;
974
+ }
975
+ /**
976
+ * Whether this document has data loaded in memory.
977
+ *
978
+ * Returns `false` for URL-sourced documents that reference external resources.
979
+ */
980
+ get hasData() {
981
+ return this.source.type !== "url";
982
+ }
983
+ /**
984
+ * Whether this document is a PDF.
985
+ */
986
+ get isPdf() {
987
+ return this.mimeType === "application/pdf";
988
+ }
989
+ /**
990
+ * Whether this document is plain text.
991
+ */
992
+ get isText() {
993
+ return this.mimeType === "text/plain";
994
+ }
995
+ /**
996
+ * Converts the document to a base64-encoded string.
997
+ *
998
+ * @returns The document data as a base64 string
999
+ * @throws {Error} When the source is a URL or plain text
1000
+ */
1001
+ toBase64() {
1002
+ if (this.source.type === "base64") {
1003
+ return this.source.data;
1004
+ }
1005
+ throw new Error("Cannot convert to base64. Only base64-sourced documents support this.");
1006
+ }
1007
+ /**
1008
+ * Gets the plain text content for text documents.
1009
+ *
1010
+ * @returns The document text content
1011
+ * @throws {Error} When the source is not plain text
1012
+ */
1013
+ toText() {
1014
+ if (this.source.type === "text") {
1015
+ return this.source.data;
1016
+ }
1017
+ throw new Error("Cannot get text content. Only text-sourced documents support this.");
1018
+ }
1019
+ /**
1020
+ * Gets the URL for URL-sourced documents.
1021
+ *
1022
+ * @returns The document URL
1023
+ * @throws {Error} When the source is not a URL
1024
+ */
1025
+ toUrl() {
1026
+ if (this.source.type === "url") {
1027
+ return this.source.url;
1028
+ }
1029
+ throw new Error("This document does not have a URL source.");
1030
+ }
1031
+ /**
1032
+ * Converts this Document to a DocumentBlock for use in UPP messages.
1033
+ *
1034
+ * @returns A DocumentBlock that can be included in message content arrays
1035
+ */
1036
+ toBlock() {
1037
+ return {
1038
+ type: "document",
1039
+ source: this.source,
1040
+ mimeType: this.mimeType,
1041
+ title: this.title
1042
+ };
1043
+ }
1044
+ /**
1045
+ * Creates a Document by reading a file from disk.
1046
+ *
1047
+ * The file is read into memory and base64-encoded. MIME type is automatically
1048
+ * detected from the file extension.
1049
+ *
1050
+ * @param path - Path to the document file
1051
+ * @param title - Optional document title
1052
+ * @returns Promise resolving to a Document with the file contents
1053
+ *
1054
+ * @example
1055
+ * ```typescript
1056
+ * const doc = await Document.fromPath('./reports/annual.pdf');
1057
+ * const docWithTitle = await Document.fromPath('./report.pdf', 'Annual Report 2024');
1058
+ * ```
1059
+ */
1060
+ static async fromPath(path, title) {
1061
+ const file = Bun.file(path);
1062
+ const exists = await file.exists();
1063
+ if (!exists) {
1064
+ throw new Error(`Document file not found at path: ${path}`);
1065
+ }
1066
+ let data;
1067
+ try {
1068
+ data = await file.arrayBuffer();
1069
+ } catch (error) {
1070
+ const message = error instanceof Error ? error.message : "Unknown error";
1071
+ throw new Error(`Failed to read document file at path: ${path}. ${message}`);
1072
+ }
1073
+ if (data.byteLength === 0) {
1074
+ throw new Error(`Document file is empty at path: ${path}`);
1075
+ }
1076
+ const base64 = Buffer.from(data).toString("base64");
1077
+ const mimeType = detectMimeType(path);
1078
+ return new _Document(
1079
+ { type: "base64", data: base64 },
1080
+ mimeType,
1081
+ title
1082
+ );
1083
+ }
1084
+ /**
1085
+ * Creates a Document from a URL reference.
1086
+ *
1087
+ * The URL is stored as a reference and not fetched. Providers will handle
1088
+ * URL fetching if needed. Only PDF URLs are supported.
1089
+ * URLs must use the http or https protocol.
1090
+ *
1091
+ * @param url - URL pointing to the PDF document
1092
+ * @param title - Optional document title
1093
+ * @returns A Document referencing the URL
1094
+ *
1095
+ * @example
1096
+ * ```typescript
1097
+ * const doc = Document.fromUrl('https://example.com/report.pdf');
1098
+ * ```
1099
+ */
1100
+ static fromUrl(url, title) {
1101
+ let parsedUrl;
1102
+ try {
1103
+ parsedUrl = new URL(url);
1104
+ } catch (error) {
1105
+ const message = error instanceof Error ? error.message : "Invalid URL";
1106
+ throw new Error(`Invalid document URL: ${message}`);
1107
+ }
1108
+ if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") {
1109
+ throw new Error(`Document URL must use http or https: ${url}`);
1110
+ }
1111
+ return new _Document(
1112
+ { type: "url", url },
1113
+ "application/pdf",
1114
+ title
1115
+ );
1116
+ }
1117
+ /**
1118
+ * Creates a Document from base64-encoded data.
1119
+ *
1120
+ * @param base64 - The base64-encoded document data
1121
+ * @param mimeType - The MIME type ('application/pdf' or 'text/plain')
1122
+ * @param title - Optional document title
1123
+ * @returns A Document containing the base64 data
1124
+ *
1125
+ * @example
1126
+ * ```typescript
1127
+ * const doc = Document.fromBase64(pdfBase64, 'application/pdf', 'Contract');
1128
+ * ```
1129
+ */
1130
+ static fromBase64(base64, mimeType, title) {
1131
+ return new _Document(
1132
+ { type: "base64", data: base64 },
1133
+ mimeType,
1134
+ title
1135
+ );
1136
+ }
1137
+ /**
1138
+ * Creates a Document from plain text content.
1139
+ *
1140
+ * @param text - The document text content
1141
+ * @param title - Optional document title
1142
+ * @returns A Document containing the text
1143
+ *
1144
+ * @example
1145
+ * ```typescript
1146
+ * const doc = Document.fromText('This is the document content.', 'Notes');
1147
+ * ```
1148
+ */
1149
+ static fromText(text2, title) {
1150
+ return new _Document(
1151
+ { type: "text", data: text2 },
1152
+ "text/plain",
1153
+ title
1154
+ );
1155
+ }
1156
+ /**
1157
+ * Creates a Document from an existing DocumentBlock.
1158
+ *
1159
+ * Useful for converting content blocks received from providers back
1160
+ * into Document instances for further processing.
1161
+ *
1162
+ * @param block - A DocumentBlock from message content
1163
+ * @returns A Document with the block's source and metadata
1164
+ */
1165
+ static fromBlock(block) {
1166
+ return new _Document(
1167
+ block.source,
1168
+ block.mimeType,
1169
+ block.title
1170
+ );
1171
+ }
1172
+ };
1173
+ function detectMimeType(path) {
1174
+ const ext = path.split(".").pop()?.toLowerCase();
1175
+ switch (ext) {
1176
+ case "pdf":
1177
+ return "application/pdf";
1178
+ case "txt":
1179
+ case "text":
1180
+ case "md":
1181
+ case "markdown":
1182
+ return "text/plain";
1183
+ default:
1184
+ return "application/octet-stream";
1185
+ }
1186
+ }
1187
+
1188
+ // src/core/media/Audio.ts
1189
+ var Audio = class _Audio {
1190
+ /** The audio data as raw bytes */
1191
+ data;
1192
+ /** MIME type of the audio (e.g., 'audio/mp3', 'audio/wav') */
1193
+ mimeType;
1194
+ /** Duration in seconds, if known */
1195
+ duration;
1196
+ constructor(data, mimeType, duration) {
1197
+ this.data = data;
1198
+ this.mimeType = mimeType;
1199
+ this.duration = duration;
1200
+ }
1201
+ /**
1202
+ * Gets the size of the audio data in bytes.
1203
+ */
1204
+ get size() {
1205
+ return this.data.length;
1206
+ }
1207
+ /**
1208
+ * Converts the audio to a base64-encoded string.
1209
+ *
1210
+ * @returns The audio data as a base64 string
1211
+ */
1212
+ toBase64() {
1213
+ return btoa(
1214
+ Array.from(this.data).map((b) => String.fromCharCode(b)).join("")
1215
+ );
1216
+ }
1217
+ /**
1218
+ * Converts the audio to a data URL suitable for embedding.
1219
+ *
1220
+ * @returns A data URL in the format `data:{mimeType};base64,{data}`
1221
+ */
1222
+ toDataUrl() {
1223
+ const base64 = this.toBase64();
1224
+ return `data:${this.mimeType};base64,${base64}`;
1225
+ }
1226
+ /**
1227
+ * Gets the audio data as raw bytes.
1228
+ *
1229
+ * @returns The audio data as a Uint8Array
1230
+ */
1231
+ toBytes() {
1232
+ return this.data;
1233
+ }
1234
+ /**
1235
+ * Converts this Audio to an AudioBlock for use in UPP messages.
1236
+ *
1237
+ * @returns An AudioBlock that can be included in message content arrays
1238
+ */
1239
+ toBlock() {
1240
+ return {
1241
+ type: "audio",
1242
+ data: this.data,
1243
+ mimeType: this.mimeType,
1244
+ duration: this.duration
1245
+ };
1246
+ }
1247
+ /**
1248
+ * Creates an Audio by reading a file from disk.
1249
+ *
1250
+ * The file is read into memory as bytes. MIME type is automatically
1251
+ * detected from the file extension.
1252
+ *
1253
+ * @param path - Path to the audio file
1254
+ * @param duration - Optional duration in seconds
1255
+ * @returns Promise resolving to an Audio with the file contents
1256
+ *
1257
+ * @example
1258
+ * ```typescript
1259
+ * const audio = await Audio.fromPath('./recordings/interview.mp3');
1260
+ * ```
1261
+ */
1262
+ static async fromPath(path, duration) {
1263
+ const file = Bun.file(path);
1264
+ const exists = await file.exists();
1265
+ if (!exists) {
1266
+ throw new Error(`Audio file not found at path: ${path}`);
1267
+ }
1268
+ let arrayBuffer;
1269
+ try {
1270
+ arrayBuffer = await file.arrayBuffer();
1271
+ } catch (error) {
1272
+ const message = error instanceof Error ? error.message : "Unknown error";
1273
+ throw new Error(`Failed to read audio file at path: ${path}. ${message}`);
1274
+ }
1275
+ if (arrayBuffer.byteLength === 0) {
1276
+ throw new Error(`Audio file is empty at path: ${path}`);
1277
+ }
1278
+ const mimeType = detectMimeType2(path);
1279
+ return new _Audio(
1280
+ new Uint8Array(arrayBuffer),
1281
+ mimeType,
1282
+ duration
1283
+ );
1284
+ }
1285
+ /**
1286
+ * Creates an Audio from raw byte data.
1287
+ *
1288
+ * @param data - The audio data as a Uint8Array
1289
+ * @param mimeType - The MIME type of the audio
1290
+ * @param duration - Optional duration in seconds
1291
+ * @returns An Audio containing the byte data
1292
+ *
1293
+ * @example
1294
+ * ```typescript
1295
+ * const audio = Audio.fromBytes(wavData, 'audio/wav');
1296
+ * ```
1297
+ */
1298
+ static fromBytes(data, mimeType, duration) {
1299
+ return new _Audio(data, mimeType, duration);
1300
+ }
1301
+ /**
1302
+ * Creates an Audio from a base64-encoded string.
1303
+ *
1304
+ * @param base64 - The base64-encoded audio data (without data URL prefix)
1305
+ * @param mimeType - The MIME type of the audio
1306
+ * @param duration - Optional duration in seconds
1307
+ * @returns An Audio containing the decoded data
1308
+ *
1309
+ * @example
1310
+ * ```typescript
1311
+ * const audio = Audio.fromBase64(base64String, 'audio/mp3');
1312
+ * ```
1313
+ */
1314
+ static fromBase64(base64, mimeType, duration) {
1315
+ const binaryString = atob(base64);
1316
+ const bytes = new Uint8Array(binaryString.length);
1317
+ for (let i = 0; i < binaryString.length; i++) {
1318
+ bytes[i] = binaryString.charCodeAt(i);
1319
+ }
1320
+ return new _Audio(bytes, mimeType, duration);
1321
+ }
1322
+ /**
1323
+ * Creates an Audio from an existing AudioBlock.
1324
+ *
1325
+ * Useful for converting content blocks received from providers back
1326
+ * into Audio instances for further processing.
1327
+ *
1328
+ * @param block - An AudioBlock from message content
1329
+ * @returns An Audio with the block's data and metadata
1330
+ */
1331
+ static fromBlock(block) {
1332
+ return new _Audio(
1333
+ block.data,
1334
+ block.mimeType,
1335
+ block.duration
1336
+ );
1337
+ }
1338
+ };
1339
+ function detectMimeType2(path) {
1340
+ const ext = path.split(".").pop()?.toLowerCase();
1341
+ switch (ext) {
1342
+ case "mp3":
1343
+ return "audio/mp3";
1344
+ case "wav":
1345
+ return "audio/wav";
1346
+ case "ogg":
1347
+ case "oga":
1348
+ return "audio/ogg";
1349
+ case "flac":
1350
+ return "audio/flac";
1351
+ case "aac":
1352
+ return "audio/aac";
1353
+ case "m4a":
1354
+ return "audio/mp4";
1355
+ case "webm":
1356
+ return "audio/webm";
1357
+ case "aiff":
1358
+ case "aif":
1359
+ return "audio/aiff";
1360
+ default:
1361
+ return "application/octet-stream";
1362
+ }
1363
+ }
1364
+
1365
+ // src/core/media/Video.ts
1366
+ var Video = class _Video {
1367
+ /** The video data as raw bytes */
1368
+ data;
1369
+ /** MIME type of the video (e.g., 'video/mp4', 'video/webm') */
1370
+ mimeType;
1371
+ /** Duration in seconds, if known */
1372
+ duration;
1373
+ /** Video width in pixels, if known */
1374
+ width;
1375
+ /** Video height in pixels, if known */
1376
+ height;
1377
+ constructor(data, mimeType, options) {
1378
+ this.data = data;
1379
+ this.mimeType = mimeType;
1380
+ this.duration = options?.duration;
1381
+ this.width = options?.width;
1382
+ this.height = options?.height;
1383
+ }
1384
+ /**
1385
+ * Gets the size of the video data in bytes.
1386
+ */
1387
+ get size() {
1388
+ return this.data.length;
1389
+ }
1390
+ /**
1391
+ * Converts the video to a base64-encoded string.
1392
+ *
1393
+ * @returns The video data as a base64 string
1394
+ */
1395
+ toBase64() {
1396
+ return btoa(
1397
+ Array.from(this.data).map((b) => String.fromCharCode(b)).join("")
1398
+ );
1399
+ }
1400
+ /**
1401
+ * Converts the video to a data URL suitable for embedding.
1402
+ *
1403
+ * @returns A data URL in the format `data:{mimeType};base64,{data}`
1404
+ */
1405
+ toDataUrl() {
1406
+ const base64 = this.toBase64();
1407
+ return `data:${this.mimeType};base64,${base64}`;
1408
+ }
1409
+ /**
1410
+ * Gets the video data as raw bytes.
1411
+ *
1412
+ * @returns The video data as a Uint8Array
1413
+ */
1414
+ toBytes() {
1415
+ return this.data;
1416
+ }
1417
+ /**
1418
+ * Converts this Video to a VideoBlock for use in UPP messages.
1419
+ *
1420
+ * @returns A VideoBlock that can be included in message content arrays
1421
+ */
1422
+ toBlock() {
1423
+ return {
1424
+ type: "video",
1425
+ data: this.data,
1426
+ mimeType: this.mimeType,
1427
+ duration: this.duration,
1428
+ width: this.width,
1429
+ height: this.height
1430
+ };
1431
+ }
1432
+ /**
1433
+ * Creates a Video by reading a file from disk.
1434
+ *
1435
+ * The file is read into memory as bytes. MIME type is automatically
1436
+ * detected from the file extension.
1437
+ *
1438
+ * @param path - Path to the video file
1439
+ * @param options - Optional metadata (duration, width, height)
1440
+ * @returns Promise resolving to a Video with the file contents
1441
+ *
1442
+ * @example
1443
+ * ```typescript
1444
+ * const video = await Video.fromPath('./clips/demo.mp4');
1445
+ * const videoWithMeta = await Video.fromPath('./clip.mp4', { duration: 30, width: 1920, height: 1080 });
1446
+ * ```
1447
+ */
1448
+ static async fromPath(path, options) {
1449
+ const file = Bun.file(path);
1450
+ const exists = await file.exists();
1451
+ if (!exists) {
1452
+ throw new Error(`Video file not found at path: ${path}`);
1453
+ }
1454
+ let arrayBuffer;
1455
+ try {
1456
+ arrayBuffer = await file.arrayBuffer();
1457
+ } catch (error) {
1458
+ const message = error instanceof Error ? error.message : "Unknown error";
1459
+ throw new Error(`Failed to read video file at path: ${path}. ${message}`);
1460
+ }
1461
+ if (arrayBuffer.byteLength === 0) {
1462
+ throw new Error(`Video file is empty at path: ${path}`);
1463
+ }
1464
+ const mimeType = detectMimeType3(path);
1465
+ return new _Video(
1466
+ new Uint8Array(arrayBuffer),
1467
+ mimeType,
1468
+ options
1469
+ );
1470
+ }
1471
+ /**
1472
+ * Creates a Video from raw byte data.
1473
+ *
1474
+ * @param data - The video data as a Uint8Array
1475
+ * @param mimeType - The MIME type of the video
1476
+ * @param options - Optional metadata (duration, width, height)
1477
+ * @returns A Video containing the byte data
1478
+ *
1479
+ * @example
1480
+ * ```typescript
1481
+ * const video = Video.fromBytes(mp4Data, 'video/mp4');
1482
+ * const videoWithMeta = Video.fromBytes(data, 'video/mp4', { duration: 60 });
1483
+ * ```
1484
+ */
1485
+ static fromBytes(data, mimeType, options) {
1486
+ return new _Video(data, mimeType, options);
1487
+ }
1488
+ /**
1489
+ * Creates a Video from a base64-encoded string.
1490
+ *
1491
+ * @param base64 - The base64-encoded video data (without data URL prefix)
1492
+ * @param mimeType - The MIME type of the video
1493
+ * @param options - Optional metadata (duration, width, height)
1494
+ * @returns A Video containing the decoded data
1495
+ *
1496
+ * @example
1497
+ * ```typescript
1498
+ * const video = Video.fromBase64(base64String, 'video/mp4');
1499
+ * ```
1500
+ */
1501
+ static fromBase64(base64, mimeType, options) {
1502
+ const binaryString = atob(base64);
1503
+ const bytes = new Uint8Array(binaryString.length);
1504
+ for (let i = 0; i < binaryString.length; i++) {
1505
+ bytes[i] = binaryString.charCodeAt(i);
1506
+ }
1507
+ return new _Video(bytes, mimeType, options);
1508
+ }
1509
+ /**
1510
+ * Creates a Video from an existing VideoBlock.
1511
+ *
1512
+ * Useful for converting content blocks received from providers back
1513
+ * into Video instances for further processing.
1514
+ *
1515
+ * @param block - A VideoBlock from message content
1516
+ * @returns A Video with the block's data and metadata
1517
+ */
1518
+ static fromBlock(block) {
1519
+ return new _Video(
1520
+ block.data,
1521
+ block.mimeType,
1522
+ {
1523
+ duration: block.duration,
1524
+ width: block.width,
1525
+ height: block.height
1526
+ }
1527
+ );
1528
+ }
1529
+ };
1530
+ function detectMimeType3(path) {
1531
+ const ext = path.split(".").pop()?.toLowerCase();
1532
+ switch (ext) {
1533
+ case "mp4":
1534
+ case "m4v":
1535
+ return "video/mp4";
1536
+ case "webm":
1537
+ return "video/webm";
1538
+ case "ogv":
1539
+ case "ogg":
1540
+ return "video/ogg";
1541
+ case "mov":
1542
+ return "video/quicktime";
1543
+ case "avi":
1544
+ return "video/x-msvideo";
1545
+ case "mpeg":
1546
+ case "mpg":
1547
+ return "video/mpeg";
1548
+ case "wmv":
1549
+ return "video/x-ms-wmv";
1550
+ case "3gp":
1551
+ case "3gpp":
1552
+ return "video/3gpp";
1553
+ case "flv":
1554
+ return "video/x-flv";
1555
+ default:
1556
+ return "application/octet-stream";
1557
+ }
1558
+ }
1559
+
941
1560
  // src/types/thread.ts
942
1561
  var Thread = class _Thread {
943
1562
  /** Unique thread identifier */
@@ -1202,7 +1821,10 @@ var ai = {
1202
1821
  };
1203
1822
  export {
1204
1823
  AssistantMessage,
1824
+ Audio,
1205
1825
  ContentBlockType,
1826
+ Document,
1827
+ DocumentSourceType,
1206
1828
  DynamicKey,
1207
1829
  ErrorCode,
1208
1830
  ExponentialBackoff,
@@ -1221,6 +1843,7 @@ export {
1221
1843
  ToolResultMessage,
1222
1844
  UPPError,
1223
1845
  UserMessage,
1846
+ Video,
1224
1847
  WeightedKeys,
1225
1848
  aggregateUsage,
1226
1849
  ai,
@@ -1235,6 +1858,7 @@ export {
1235
1858
  isAssistantMessage,
1236
1859
  isAudioBlock,
1237
1860
  isBinaryBlock,
1861
+ isDocumentBlock,
1238
1862
  isImageBlock,
1239
1863
  isReasoningBlock,
1240
1864
  isTextBlock,