@providerprotocol/ai 0.0.17 → 0.0.19

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 (45) hide show
  1. package/README.md +294 -114
  2. package/dist/anthropic/index.d.ts +1 -1
  3. package/dist/anthropic/index.js +5 -3
  4. package/dist/anthropic/index.js.map +1 -1
  5. package/dist/{chunk-MOU4U3PO.js → chunk-5FEAOEXV.js} +4 -68
  6. package/dist/chunk-5FEAOEXV.js.map +1 -0
  7. package/dist/chunk-DZQHVGNV.js +71 -0
  8. package/dist/chunk-DZQHVGNV.js.map +1 -0
  9. package/dist/chunk-SKY2JLA7.js +59 -0
  10. package/dist/chunk-SKY2JLA7.js.map +1 -0
  11. package/dist/{chunk-SVYROCLD.js → chunk-UMKWXGO3.js} +1 -1
  12. package/dist/chunk-UMKWXGO3.js.map +1 -0
  13. package/dist/chunk-WAKD3OO5.js +224 -0
  14. package/dist/chunk-WAKD3OO5.js.map +1 -0
  15. package/dist/content-DEl3z_W2.d.ts +276 -0
  16. package/dist/google/index.d.ts +3 -1
  17. package/dist/google/index.js +122 -4
  18. package/dist/google/index.js.map +1 -1
  19. package/dist/http/index.d.ts +2 -2
  20. package/dist/http/index.js +2 -1
  21. package/dist/image-Dhq-Yuq4.d.ts +456 -0
  22. package/dist/index.d.ts +59 -1460
  23. package/dist/index.js +89 -267
  24. package/dist/index.js.map +1 -1
  25. package/dist/ollama/index.d.ts +1 -1
  26. package/dist/ollama/index.js +5 -3
  27. package/dist/ollama/index.js.map +1 -1
  28. package/dist/openai/index.d.ts +47 -20
  29. package/dist/openai/index.js +309 -4
  30. package/dist/openai/index.js.map +1 -1
  31. package/dist/openrouter/index.d.ts +1 -1
  32. package/dist/openrouter/index.js +5 -3
  33. package/dist/openrouter/index.js.map +1 -1
  34. package/dist/{provider-D5MO3-pS.d.ts → provider-BBMBZuGn.d.ts} +11 -11
  35. package/dist/proxy/index.d.ts +652 -0
  36. package/dist/proxy/index.js +565 -0
  37. package/dist/proxy/index.js.map +1 -0
  38. package/dist/{retry-DZ4Sqmxp.d.ts → retry-DR7YRJDz.d.ts} +1 -1
  39. package/dist/stream-DRHy6q1a.d.ts +1013 -0
  40. package/dist/xai/index.d.ts +29 -1
  41. package/dist/xai/index.js +118 -4
  42. package/dist/xai/index.js.map +1 -1
  43. package/package.json +6 -1
  44. package/dist/chunk-MOU4U3PO.js.map +0 -1
  45. package/dist/chunk-SVYROCLD.js.map +0 -1
@@ -1,19 +1,24 @@
1
+ import {
2
+ Image
3
+ } from "../chunk-WAKD3OO5.js";
1
4
  import {
2
5
  AssistantMessage,
3
6
  isAssistantMessage,
4
7
  isToolResultMessage,
5
8
  isUserMessage
6
- } from "../chunk-SVYROCLD.js";
9
+ } from "../chunk-UMKWXGO3.js";
7
10
  import {
8
11
  parseSSEStream
9
12
  } from "../chunk-Z7RBRCRN.js";
10
13
  import {
11
- UPPError,
12
14
  doFetch,
13
15
  doStreamFetch,
14
16
  normalizeHttpError,
15
17
  resolveApiKey
16
- } from "../chunk-MOU4U3PO.js";
18
+ } from "../chunk-5FEAOEXV.js";
19
+ import {
20
+ UPPError
21
+ } from "../chunk-DZQHVGNV.js";
17
22
 
18
23
  // src/providers/openai/transform.completions.ts
19
24
  function transformRequest(request, modelId) {
@@ -1379,6 +1384,303 @@ function createEmbeddingHandler() {
1379
1384
  };
1380
1385
  }
1381
1386
 
1387
+ // src/providers/openai/image.ts
1388
+ var OPENAI_IMAGES_API_URL = "https://api.openai.com/v1/images/generations";
1389
+ var OPENAI_IMAGES_EDIT_URL = "https://api.openai.com/v1/images/edits";
1390
+ function getCapabilities(modelId) {
1391
+ const isGptImage = modelId.startsWith("gpt-image");
1392
+ const isDalle2 = modelId === "dall-e-2";
1393
+ return {
1394
+ generate: true,
1395
+ streaming: isGptImage,
1396
+ edit: true,
1397
+ maxImages: isDalle2 ? 10 : isGptImage ? 10 : 1
1398
+ };
1399
+ }
1400
+ function createImageHandler() {
1401
+ let providerRef = null;
1402
+ return {
1403
+ _setProvider(provider) {
1404
+ providerRef = provider;
1405
+ },
1406
+ bind(modelId) {
1407
+ if (!providerRef) {
1408
+ throw new UPPError(
1409
+ "Provider reference not set. Handler must be used with createProvider().",
1410
+ "INVALID_REQUEST",
1411
+ "openai",
1412
+ "image"
1413
+ );
1414
+ }
1415
+ const capabilities = getCapabilities(modelId);
1416
+ const model = {
1417
+ modelId,
1418
+ capabilities,
1419
+ get provider() {
1420
+ return providerRef;
1421
+ },
1422
+ async generate(request) {
1423
+ return executeGenerate(modelId, request);
1424
+ },
1425
+ async edit(request) {
1426
+ return executeEdit(modelId, request);
1427
+ }
1428
+ };
1429
+ if (capabilities.streaming) {
1430
+ model.stream = function(request) {
1431
+ return executeStream(modelId, request);
1432
+ };
1433
+ }
1434
+ return model;
1435
+ }
1436
+ };
1437
+ }
1438
+ async function executeGenerate(modelId, request) {
1439
+ const apiKey = await resolveApiKey(
1440
+ request.config,
1441
+ "OPENAI_API_KEY",
1442
+ "openai",
1443
+ "image"
1444
+ );
1445
+ const baseUrl = request.config.baseUrl ? `${request.config.baseUrl.replace(/\/$/, "")}/v1/images/generations` : OPENAI_IMAGES_API_URL;
1446
+ const body = {
1447
+ model: modelId,
1448
+ prompt: request.prompt
1449
+ };
1450
+ if (request.params) {
1451
+ const { n, size, quality, style, background, output_format, output_compression, response_format, moderation, user } = request.params;
1452
+ if (n !== void 0) body.n = n;
1453
+ if (size !== void 0) body.size = size;
1454
+ if (quality !== void 0) body.quality = quality;
1455
+ if (style !== void 0) body.style = style;
1456
+ if (background !== void 0) body.background = background;
1457
+ if (output_format !== void 0) body.output_format = output_format;
1458
+ if (output_compression !== void 0) body.output_compression = output_compression;
1459
+ if (response_format !== void 0) body.response_format = response_format;
1460
+ if (moderation !== void 0) body.moderation = moderation;
1461
+ if (user !== void 0) body.user = user;
1462
+ }
1463
+ const headers = {
1464
+ "Content-Type": "application/json",
1465
+ Authorization: `Bearer ${apiKey}`
1466
+ };
1467
+ if (request.config.headers) {
1468
+ for (const [key, value] of Object.entries(request.config.headers)) {
1469
+ if (value !== void 0) {
1470
+ headers[key] = value;
1471
+ }
1472
+ }
1473
+ }
1474
+ const response = await doFetch(baseUrl, {
1475
+ method: "POST",
1476
+ headers,
1477
+ body: JSON.stringify(body),
1478
+ signal: request.signal
1479
+ }, request.config, "openai", "image");
1480
+ const data = await response.json();
1481
+ return transformResponse3(data);
1482
+ }
1483
+ async function executeEdit(modelId, request) {
1484
+ const apiKey = await resolveApiKey(
1485
+ request.config,
1486
+ "OPENAI_API_KEY",
1487
+ "openai",
1488
+ "image"
1489
+ );
1490
+ const baseUrl = request.config.baseUrl ? `${request.config.baseUrl.replace(/\/$/, "")}/v1/images/edits` : OPENAI_IMAGES_EDIT_URL;
1491
+ const formData = new FormData();
1492
+ formData.append("model", modelId);
1493
+ formData.append("prompt", request.prompt);
1494
+ const imageBytes = request.image.toBytes();
1495
+ const imageBlob = new Blob([imageBytes], { type: request.image.mimeType });
1496
+ formData.append("image", imageBlob, "image.png");
1497
+ if (request.mask) {
1498
+ const maskBytes = request.mask.toBytes();
1499
+ const maskBlob = new Blob([maskBytes], { type: request.mask.mimeType });
1500
+ formData.append("mask", maskBlob, "mask.png");
1501
+ }
1502
+ if (request.params) {
1503
+ const { n, size, response_format, user } = request.params;
1504
+ if (n !== void 0) formData.append("n", String(n));
1505
+ if (size !== void 0) formData.append("size", size);
1506
+ if (response_format !== void 0) formData.append("response_format", response_format);
1507
+ if (user !== void 0) formData.append("user", user);
1508
+ }
1509
+ const headers = {
1510
+ Authorization: `Bearer ${apiKey}`
1511
+ };
1512
+ if (request.config.headers) {
1513
+ for (const [key, value] of Object.entries(request.config.headers)) {
1514
+ if (value !== void 0) {
1515
+ headers[key] = value;
1516
+ }
1517
+ }
1518
+ }
1519
+ const response = await doFetch(baseUrl, {
1520
+ method: "POST",
1521
+ headers,
1522
+ body: formData,
1523
+ signal: request.signal
1524
+ }, request.config, "openai", "image");
1525
+ const data = await response.json();
1526
+ return transformResponse3(data);
1527
+ }
1528
+ function executeStream(modelId, request) {
1529
+ const abortController = new AbortController();
1530
+ let resolveResponse;
1531
+ let rejectResponse;
1532
+ const responsePromise = new Promise((resolve, reject) => {
1533
+ resolveResponse = resolve;
1534
+ rejectResponse = reject;
1535
+ });
1536
+ async function* generateStream() {
1537
+ try {
1538
+ const apiKey = await resolveApiKey(
1539
+ request.config,
1540
+ "OPENAI_API_KEY",
1541
+ "openai",
1542
+ "image"
1543
+ );
1544
+ const baseUrl = request.config.baseUrl ? `${request.config.baseUrl.replace(/\/$/, "")}/v1/images/generations` : OPENAI_IMAGES_API_URL;
1545
+ const body = {
1546
+ model: modelId,
1547
+ prompt: request.prompt,
1548
+ stream: true
1549
+ };
1550
+ if (request.params) {
1551
+ const { n, size, quality, background, output_format, partial_images, moderation, user } = request.params;
1552
+ if (n !== void 0) body.n = n;
1553
+ if (size !== void 0) body.size = size;
1554
+ if (quality !== void 0) body.quality = quality;
1555
+ if (background !== void 0) body.background = background;
1556
+ if (output_format !== void 0) body.output_format = output_format;
1557
+ if (partial_images !== void 0) body.partial_images = partial_images;
1558
+ if (moderation !== void 0) body.moderation = moderation;
1559
+ if (user !== void 0) body.user = user;
1560
+ }
1561
+ const headers = {
1562
+ "Content-Type": "application/json",
1563
+ Authorization: `Bearer ${apiKey}`,
1564
+ Accept: "text/event-stream"
1565
+ };
1566
+ if (request.config.headers) {
1567
+ for (const [key, value] of Object.entries(request.config.headers)) {
1568
+ if (value !== void 0) {
1569
+ headers[key] = value;
1570
+ }
1571
+ }
1572
+ }
1573
+ const mergedSignal = request.signal ? AbortSignal.any([abortController.signal, request.signal]) : abortController.signal;
1574
+ const response = await doFetch(baseUrl, {
1575
+ method: "POST",
1576
+ headers,
1577
+ body: JSON.stringify(body),
1578
+ signal: mergedSignal
1579
+ }, request.config, "openai", "image");
1580
+ const reader = response.body?.getReader();
1581
+ if (!reader) {
1582
+ throw new UPPError(
1583
+ "No response body for streaming",
1584
+ "PROVIDER_ERROR",
1585
+ "openai",
1586
+ "image"
1587
+ );
1588
+ }
1589
+ const decoder = new TextDecoder();
1590
+ let buffer = "";
1591
+ const generatedImages = [];
1592
+ let responseMetadata = {};
1593
+ while (true) {
1594
+ const { done, value } = await reader.read();
1595
+ if (done) break;
1596
+ buffer += decoder.decode(value, { stream: true });
1597
+ const lines = buffer.split("\n");
1598
+ buffer = lines.pop() ?? "";
1599
+ for (const line of lines) {
1600
+ if (line.startsWith("data: ")) {
1601
+ const data = line.slice(6);
1602
+ if (data === "[DONE]") {
1603
+ continue;
1604
+ }
1605
+ try {
1606
+ const chunk = JSON.parse(data);
1607
+ if (chunk.type === "image_generation.partial_image" && chunk.data?.b64_json) {
1608
+ const previewImage = Image.fromBase64(chunk.data.b64_json, "image/png");
1609
+ yield {
1610
+ type: "preview",
1611
+ image: previewImage,
1612
+ index: chunk.index ?? 0
1613
+ };
1614
+ } else if (chunk.type === "image_generation.completed" && chunk.data) {
1615
+ const image = chunk.data.b64_json ? Image.fromBase64(chunk.data.b64_json, "image/png") : Image.fromUrl(chunk.data.url ?? "", "image/png");
1616
+ const genImage = {
1617
+ image,
1618
+ metadata: chunk.data.revised_prompt ? { revised_prompt: chunk.data.revised_prompt } : void 0
1619
+ };
1620
+ generatedImages.push(genImage);
1621
+ yield {
1622
+ type: "complete",
1623
+ image: genImage,
1624
+ index: chunk.index ?? generatedImages.length - 1
1625
+ };
1626
+ } else if (chunk.type === "response.done") {
1627
+ responseMetadata = chunk.data;
1628
+ }
1629
+ } catch {
1630
+ }
1631
+ }
1632
+ }
1633
+ }
1634
+ resolveResponse({
1635
+ images: generatedImages,
1636
+ metadata: responseMetadata,
1637
+ usage: {
1638
+ imagesGenerated: generatedImages.length
1639
+ }
1640
+ });
1641
+ } catch (error) {
1642
+ rejectResponse(error);
1643
+ throw error;
1644
+ }
1645
+ }
1646
+ const generator = generateStream();
1647
+ return {
1648
+ [Symbol.asyncIterator]: () => generator,
1649
+ response: responsePromise
1650
+ };
1651
+ }
1652
+ function transformResponse3(data) {
1653
+ const images = data.data.map((item) => {
1654
+ let image;
1655
+ if (item.b64_json) {
1656
+ image = Image.fromBase64(item.b64_json, "image/png");
1657
+ } else if (item.url) {
1658
+ image = Image.fromUrl(item.url, "image/png");
1659
+ } else {
1660
+ throw new UPPError(
1661
+ "No image data in response",
1662
+ "PROVIDER_ERROR",
1663
+ "openai",
1664
+ "image"
1665
+ );
1666
+ }
1667
+ return {
1668
+ image,
1669
+ metadata: item.revised_prompt ? { revised_prompt: item.revised_prompt } : void 0
1670
+ };
1671
+ });
1672
+ return {
1673
+ images,
1674
+ usage: data.usage ? {
1675
+ imagesGenerated: images.length,
1676
+ inputTokens: data.usage.input_tokens,
1677
+ outputTokens: data.usage.output_tokens
1678
+ } : {
1679
+ imagesGenerated: images.length
1680
+ }
1681
+ };
1682
+ }
1683
+
1382
1684
  // src/providers/openai/types.ts
1383
1685
  function webSearchTool(options) {
1384
1686
  if (options) {
@@ -1452,6 +1754,7 @@ function createOpenAIProvider() {
1452
1754
  const responsesHandler = createResponsesLLMHandler();
1453
1755
  const completionsHandler = createCompletionsLLMHandler();
1454
1756
  const embeddingHandler = createEmbeddingHandler();
1757
+ const imageHandler = createImageHandler();
1455
1758
  const fn = function(modelId, options) {
1456
1759
  const apiMode = options?.api ?? "responses";
1457
1760
  currentApiMode = apiMode;
@@ -1461,7 +1764,8 @@ function createOpenAIProvider() {
1461
1764
  get llm() {
1462
1765
  return currentApiMode === "completions" ? completionsHandler : responsesHandler;
1463
1766
  },
1464
- embedding: embeddingHandler
1767
+ embedding: embeddingHandler,
1768
+ image: imageHandler
1465
1769
  };
1466
1770
  Object.defineProperties(fn, {
1467
1771
  name: {
@@ -1484,6 +1788,7 @@ function createOpenAIProvider() {
1484
1788
  responsesHandler._setProvider?.(provider);
1485
1789
  completionsHandler._setProvider?.(provider);
1486
1790
  embeddingHandler._setProvider?.(provider);
1791
+ imageHandler._setProvider?.(provider);
1487
1792
  return provider;
1488
1793
  }
1489
1794
  var openai = createOpenAIProvider();