@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
package/dist/index.js CHANGED
@@ -1,6 +1,14 @@
1
+ import {
2
+ aggregateUsage,
3
+ createTurn,
4
+ emptyUsage
5
+ } from "./chunk-SKY2JLA7.js";
1
6
  import {
2
7
  createProvider
3
8
  } from "./chunk-MSR5P65T.js";
9
+ import {
10
+ Image
11
+ } from "./chunk-WAKD3OO5.js";
4
12
  import {
5
13
  AssistantMessage,
6
14
  Message,
@@ -10,7 +18,7 @@ import {
10
18
  isAssistantMessage,
11
19
  isToolResultMessage,
12
20
  isUserMessage
13
- } from "./chunk-SVYROCLD.js";
21
+ } from "./chunk-UMKWXGO3.js";
14
22
  import {
15
23
  ExponentialBackoff,
16
24
  LinearBackoff,
@@ -22,62 +30,11 @@ import "./chunk-Z7RBRCRN.js";
22
30
  import {
23
31
  DynamicKey,
24
32
  RoundRobinKeys,
25
- UPPError,
26
33
  WeightedKeys
27
- } from "./chunk-MOU4U3PO.js";
28
-
29
- // src/types/turn.ts
30
- function createTurn(messages, toolExecutions, usage, cycles, data) {
31
- const response = messages.filter((m) => m.type === "assistant").pop();
32
- if (!response) {
33
- throw new Error("Turn must contain at least one assistant message");
34
- }
35
- return {
36
- messages,
37
- response,
38
- toolExecutions,
39
- usage,
40
- cycles,
41
- data
42
- };
43
- }
44
- function emptyUsage() {
45
- return {
46
- inputTokens: 0,
47
- outputTokens: 0,
48
- totalTokens: 0,
49
- cacheReadTokens: 0,
50
- cacheWriteTokens: 0,
51
- cycles: []
52
- };
53
- }
54
- function aggregateUsage(usages) {
55
- const cycles = [];
56
- let inputTokens = 0;
57
- let outputTokens = 0;
58
- let cacheReadTokens = 0;
59
- let cacheWriteTokens = 0;
60
- for (const usage of usages) {
61
- inputTokens += usage.inputTokens;
62
- outputTokens += usage.outputTokens;
63
- cacheReadTokens += usage.cacheReadTokens;
64
- cacheWriteTokens += usage.cacheWriteTokens;
65
- cycles.push({
66
- inputTokens: usage.inputTokens,
67
- outputTokens: usage.outputTokens,
68
- cacheReadTokens: usage.cacheReadTokens,
69
- cacheWriteTokens: usage.cacheWriteTokens
70
- });
71
- }
72
- return {
73
- inputTokens,
74
- outputTokens,
75
- totalTokens: inputTokens + outputTokens,
76
- cacheReadTokens,
77
- cacheWriteTokens,
78
- cycles
79
- };
80
- }
34
+ } from "./chunk-5FEAOEXV.js";
35
+ import {
36
+ UPPError
37
+ } from "./chunk-DZQHVGNV.js";
81
38
 
82
39
  // src/types/stream.ts
83
40
  function createStreamResult(generator, turnPromise, abortController) {
@@ -725,223 +682,85 @@ function createChunkedStream(model, inputs, params, config, options) {
725
682
  }
726
683
 
727
684
  // src/core/image.ts
728
- import { readFile } from "fs/promises";
729
- var Image = class _Image {
730
- /** The underlying image source (bytes, base64, or URL) */
731
- source;
732
- /** MIME type of the image (e.g., 'image/jpeg', 'image/png') */
733
- mimeType;
734
- /** Image width in pixels, if known */
735
- width;
736
- /** Image height in pixels, if known */
737
- height;
738
- constructor(source, mimeType, width, height) {
739
- this.source = source;
740
- this.mimeType = mimeType;
741
- this.width = width;
742
- this.height = height;
743
- }
744
- /**
745
- * Whether this image has data loaded in memory.
746
- *
747
- * Returns `false` for URL-sourced images that reference external resources.
748
- * These must be fetched before their data can be accessed.
749
- */
750
- get hasData() {
751
- return this.source.type !== "url";
752
- }
753
- /**
754
- * Converts the image to a base64-encoded string.
755
- *
756
- * @returns The image data as a base64 string
757
- * @throws {Error} When the source is a URL (data must be fetched first)
758
- */
759
- toBase64() {
760
- if (this.source.type === "base64") {
761
- return this.source.data;
762
- }
763
- if (this.source.type === "bytes") {
764
- return btoa(
765
- Array.from(this.source.data).map((b) => String.fromCharCode(b)).join("")
766
- );
767
- }
768
- throw new Error("Cannot convert URL image to base64. Fetch the image first.");
769
- }
770
- /**
771
- * Converts the image to a data URL suitable for embedding in HTML or CSS.
772
- *
773
- * @returns A data URL in the format `data:{mimeType};base64,{data}`
774
- * @throws {Error} When the source is a URL (data must be fetched first)
775
- */
776
- toDataUrl() {
777
- const base64 = this.toBase64();
778
- return `data:${this.mimeType};base64,${base64}`;
779
- }
780
- /**
781
- * Gets the image data as raw bytes.
782
- *
783
- * @returns The image data as a Uint8Array
784
- * @throws {Error} When the source is a URL (data must be fetched first)
785
- */
786
- toBytes() {
787
- if (this.source.type === "bytes") {
788
- return this.source.data;
789
- }
790
- if (this.source.type === "base64") {
791
- const binaryString = atob(this.source.data);
792
- const bytes = new Uint8Array(binaryString.length);
793
- for (let i = 0; i < binaryString.length; i++) {
794
- bytes[i] = binaryString.charCodeAt(i);
795
- }
796
- return bytes;
797
- }
798
- throw new Error("Cannot get bytes from URL image. Fetch the image first.");
685
+ function image(options) {
686
+ const { model: modelRef, config = {}, params } = options;
687
+ const provider = modelRef.provider;
688
+ if (!provider.modalities.image) {
689
+ throw new UPPError(
690
+ `Provider '${provider.name}' does not support image modality`,
691
+ "INVALID_REQUEST",
692
+ provider.name,
693
+ "image"
694
+ );
799
695
  }
800
- /**
801
- * Gets the URL for URL-sourced images.
802
- *
803
- * @returns The image URL
804
- * @throws {Error} When the source is not a URL
805
- */
806
- toUrl() {
807
- if (this.source.type === "url") {
808
- return this.source.url;
696
+ const imageHandler = provider.modalities.image;
697
+ const boundModel = imageHandler.bind(modelRef.modelId);
698
+ const capabilities = boundModel.capabilities;
699
+ const instance = {
700
+ model: boundModel,
701
+ params,
702
+ capabilities,
703
+ async generate(input) {
704
+ const prompt = normalizeInput(input);
705
+ const response = await boundModel.generate({
706
+ prompt,
707
+ params,
708
+ config
709
+ });
710
+ return {
711
+ images: response.images,
712
+ metadata: response.metadata,
713
+ usage: response.usage
714
+ };
809
715
  }
810
- throw new Error("This image does not have a URL source.");
811
- }
812
- /**
813
- * Converts this Image to an ImageBlock for use in UPP messages.
814
- *
815
- * @returns An ImageBlock that can be included in message content arrays
816
- */
817
- toBlock() {
818
- return {
819
- type: "image",
820
- source: this.source,
821
- mimeType: this.mimeType,
822
- width: this.width,
823
- height: this.height
716
+ };
717
+ if (capabilities.streaming && boundModel.stream) {
718
+ const boundModelWithStream = boundModel;
719
+ instance.stream = function(input) {
720
+ const prompt = normalizeInput(input);
721
+ const abortController = new AbortController();
722
+ const providerStream = boundModelWithStream.stream({
723
+ prompt,
724
+ params,
725
+ config,
726
+ signal: abortController.signal
727
+ });
728
+ const resultPromise = providerStream.response.then((response) => ({
729
+ images: response.images,
730
+ metadata: response.metadata,
731
+ usage: response.usage
732
+ }));
733
+ return {
734
+ [Symbol.asyncIterator]: () => providerStream[Symbol.asyncIterator](),
735
+ result: resultPromise,
736
+ abort: () => abortController.abort()
737
+ };
824
738
  };
825
739
  }
826
- /**
827
- * Creates an Image by reading a file from disk.
828
- *
829
- * The file is read into memory as bytes. MIME type is automatically
830
- * detected from the file extension.
831
- *
832
- * @param path - Path to the image file
833
- * @returns Promise resolving to an Image with the file contents
834
- *
835
- * @example
836
- * ```typescript
837
- * const image = await Image.fromPath('./photos/vacation.jpg');
838
- * ```
839
- */
840
- static async fromPath(path) {
841
- const data = await readFile(path);
842
- const mimeType = detectMimeType(path);
843
- return new _Image(
844
- { type: "bytes", data: new Uint8Array(data) },
845
- mimeType
846
- );
847
- }
848
- /**
849
- * Creates an Image from a URL reference.
850
- *
851
- * The URL is stored as a reference and not fetched. Providers will handle
852
- * URL-to-data conversion if needed. MIME type is detected from the URL
853
- * path if not provided.
854
- *
855
- * @param url - URL pointing to the image
856
- * @param mimeType - Optional MIME type override
857
- * @returns An Image referencing the URL
858
- *
859
- * @example
860
- * ```typescript
861
- * const image = Image.fromUrl('https://example.com/logo.png');
862
- * ```
863
- */
864
- static fromUrl(url, mimeType) {
865
- const detected = mimeType || detectMimeTypeFromUrl(url);
866
- return new _Image({ type: "url", url }, detected);
867
- }
868
- /**
869
- * Creates an Image from raw byte data.
870
- *
871
- * @param data - The image data as a Uint8Array
872
- * @param mimeType - The MIME type of the image
873
- * @returns An Image containing the byte data
874
- *
875
- * @example
876
- * ```typescript
877
- * const image = Image.fromBytes(pngData, 'image/png');
878
- * ```
879
- */
880
- static fromBytes(data, mimeType) {
881
- return new _Image({ type: "bytes", data }, mimeType);
882
- }
883
- /**
884
- * Creates an Image from a base64-encoded string.
885
- *
886
- * @param base64 - The base64-encoded image data (without data URL prefix)
887
- * @param mimeType - The MIME type of the image
888
- * @returns An Image containing the base64 data
889
- *
890
- * @example
891
- * ```typescript
892
- * const image = Image.fromBase64(base64String, 'image/jpeg');
893
- * ```
894
- */
895
- static fromBase64(base64, mimeType) {
896
- return new _Image({ type: "base64", data: base64 }, mimeType);
897
- }
898
- /**
899
- * Creates an Image from an existing ImageBlock.
900
- *
901
- * Useful for converting content blocks received from providers back
902
- * into Image instances for further processing.
903
- *
904
- * @param block - An ImageBlock from message content
905
- * @returns An Image with the block's source and metadata
906
- */
907
- static fromBlock(block) {
908
- return new _Image(
909
- block.source,
910
- block.mimeType,
911
- block.width,
912
- block.height
913
- );
914
- }
915
- };
916
- function detectMimeType(path) {
917
- const ext = path.split(".").pop()?.toLowerCase();
918
- switch (ext) {
919
- case "jpg":
920
- case "jpeg":
921
- return "image/jpeg";
922
- case "png":
923
- return "image/png";
924
- case "gif":
925
- return "image/gif";
926
- case "webp":
927
- return "image/webp";
928
- case "svg":
929
- return "image/svg+xml";
930
- case "bmp":
931
- return "image/bmp";
932
- case "ico":
933
- return "image/x-icon";
934
- default:
935
- return "application/octet-stream";
740
+ if (capabilities.edit && boundModel.edit) {
741
+ const boundModelWithEdit = boundModel;
742
+ instance.edit = async function(input) {
743
+ const response = await boundModelWithEdit.edit({
744
+ image: input.image,
745
+ mask: input.mask,
746
+ prompt: input.prompt,
747
+ params,
748
+ config
749
+ });
750
+ return {
751
+ images: response.images,
752
+ metadata: response.metadata,
753
+ usage: response.usage
754
+ };
755
+ };
936
756
  }
757
+ return instance;
937
758
  }
938
- function detectMimeTypeFromUrl(url) {
939
- try {
940
- const pathname = new URL(url).pathname;
941
- return detectMimeType(pathname);
942
- } catch {
943
- return "application/octet-stream";
759
+ function normalizeInput(input) {
760
+ if (typeof input === "string") {
761
+ return input;
944
762
  }
763
+ return input.prompt;
945
764
  }
946
765
 
947
766
  // src/types/content.ts
@@ -1222,7 +1041,9 @@ var ai = {
1222
1041
  /** LLM instance factory */
1223
1042
  llm,
1224
1043
  /** Embedding instance factory */
1225
- embedding
1044
+ embedding,
1045
+ /** Image generation instance factory */
1046
+ image
1226
1047
  };
1227
1048
  export {
1228
1049
  AssistantMessage,
@@ -1249,6 +1070,7 @@ export {
1249
1070
  createTurn,
1250
1071
  embedding,
1251
1072
  emptyUsage,
1073
+ image,
1252
1074
  isAssistantMessage,
1253
1075
  isAudioBlock,
1254
1076
  isBinaryBlock,