@providerprotocol/ai 0.0.12 → 0.0.14

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 (44) hide show
  1. package/dist/anthropic/index.d.ts +51 -15
  2. package/dist/anthropic/index.js +80 -29
  3. package/dist/anthropic/index.js.map +1 -1
  4. package/dist/{chunk-SUNYWHTH.js → chunk-MOU4U3PO.js} +55 -3
  5. package/dist/chunk-MOU4U3PO.js.map +1 -0
  6. package/dist/{chunk-Y6Q7JCNP.js → chunk-MSR5P65T.js} +1 -1
  7. package/dist/chunk-MSR5P65T.js.map +1 -0
  8. package/dist/{chunk-W4BB4BG2.js → chunk-SVYROCLD.js} +31 -11
  9. package/dist/chunk-SVYROCLD.js.map +1 -0
  10. package/dist/chunk-U4JJC2YX.js +234 -0
  11. package/dist/chunk-U4JJC2YX.js.map +1 -0
  12. package/dist/{chunk-X5G4EHL7.js → chunk-Z7RBRCRN.js} +1 -1
  13. package/dist/chunk-Z7RBRCRN.js.map +1 -0
  14. package/dist/google/index.d.ts +376 -7
  15. package/dist/google/index.js +149 -21
  16. package/dist/google/index.js.map +1 -1
  17. package/dist/http/index.d.ts +222 -25
  18. package/dist/http/index.js +3 -3
  19. package/dist/index.d.ts +1484 -198
  20. package/dist/index.js +233 -47
  21. package/dist/index.js.map +1 -1
  22. package/dist/ollama/index.d.ts +92 -20
  23. package/dist/ollama/index.js +31 -7
  24. package/dist/ollama/index.js.map +1 -1
  25. package/dist/openai/index.d.ts +340 -61
  26. package/dist/openai/index.js +105 -31
  27. package/dist/openai/index.js.map +1 -1
  28. package/dist/openrouter/index.d.ts +107 -51
  29. package/dist/openrouter/index.js +84 -24
  30. package/dist/openrouter/index.js.map +1 -1
  31. package/dist/provider-Bi0nyNhA.d.ts +505 -0
  32. package/dist/retry-BatS2hjD.d.ts +508 -0
  33. package/dist/xai/index.d.ts +97 -22
  34. package/dist/xai/index.js +129 -45
  35. package/dist/xai/index.js.map +1 -1
  36. package/package.json +8 -3
  37. package/dist/chunk-CUCRF5W6.js +0 -136
  38. package/dist/chunk-CUCRF5W6.js.map +0 -1
  39. package/dist/chunk-SUNYWHTH.js.map +0 -1
  40. package/dist/chunk-W4BB4BG2.js.map +0 -1
  41. package/dist/chunk-X5G4EHL7.js.map +0 -1
  42. package/dist/chunk-Y6Q7JCNP.js.map +0 -1
  43. package/dist/provider-CUJWjgNl.d.ts +0 -192
  44. package/dist/retry-I2661_rv.d.ts +0 -118
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createProvider
3
- } from "./chunk-Y6Q7JCNP.js";
3
+ } from "./chunk-MSR5P65T.js";
4
4
  import {
5
5
  AssistantMessage,
6
6
  Message,
@@ -10,21 +10,21 @@ import {
10
10
  isAssistantMessage,
11
11
  isToolResultMessage,
12
12
  isUserMessage
13
- } from "./chunk-W4BB4BG2.js";
13
+ } from "./chunk-SVYROCLD.js";
14
14
  import {
15
15
  ExponentialBackoff,
16
16
  LinearBackoff,
17
17
  NoRetry,
18
18
  RetryAfterStrategy,
19
19
  TokenBucket
20
- } from "./chunk-CUCRF5W6.js";
21
- import "./chunk-X5G4EHL7.js";
20
+ } from "./chunk-U4JJC2YX.js";
21
+ import "./chunk-Z7RBRCRN.js";
22
22
  import {
23
23
  DynamicKey,
24
24
  RoundRobinKeys,
25
25
  UPPError,
26
26
  WeightedKeys
27
- } from "./chunk-SUNYWHTH.js";
27
+ } from "./chunk-MOU4U3PO.js";
28
28
 
29
29
  // src/types/turn.ts
30
30
  function createTurn(messages, toolExecutions, usage, cycles, data) {
@@ -46,6 +46,8 @@ function emptyUsage() {
46
46
  inputTokens: 0,
47
47
  outputTokens: 0,
48
48
  totalTokens: 0,
49
+ cacheReadTokens: 0,
50
+ cacheWriteTokens: 0,
49
51
  cycles: []
50
52
  };
51
53
  }
@@ -53,18 +55,26 @@ function aggregateUsage(usages) {
53
55
  const cycles = [];
54
56
  let inputTokens = 0;
55
57
  let outputTokens = 0;
58
+ let cacheReadTokens = 0;
59
+ let cacheWriteTokens = 0;
56
60
  for (const usage of usages) {
57
61
  inputTokens += usage.inputTokens;
58
62
  outputTokens += usage.outputTokens;
63
+ cacheReadTokens += usage.cacheReadTokens;
64
+ cacheWriteTokens += usage.cacheWriteTokens;
59
65
  cycles.push({
60
66
  inputTokens: usage.inputTokens,
61
- outputTokens: usage.outputTokens
67
+ outputTokens: usage.outputTokens,
68
+ cacheReadTokens: usage.cacheReadTokens,
69
+ cacheWriteTokens: usage.cacheWriteTokens
62
70
  });
63
71
  }
64
72
  return {
65
73
  inputTokens,
66
74
  outputTokens,
67
75
  totalTokens: inputTokens + outputTokens,
76
+ cacheReadTokens,
77
+ cacheWriteTokens,
68
78
  cycles
69
79
  };
70
80
  }
@@ -313,7 +323,6 @@ async function executeGenerate(model, config, system, params, tools, toolStrateg
313
323
  const data = structure ? structuredData : void 0;
314
324
  return createTurn(
315
325
  allMessages.slice(history.length),
316
- // Only messages from this turn
317
326
  toolExecutions,
318
327
  aggregateUsage(usages),
319
328
  cycles,
@@ -430,10 +439,25 @@ async function executeTools(message, tools, toolStrategy, executions, onEvent) {
430
439
  }
431
440
  const startTime = Date.now();
432
441
  onEvent?.(toolExecutionStart(call.toolCallId, tool.name, startTime, index));
433
- await toolStrategy?.onToolCall?.(tool, call.arguments);
442
+ let effectiveParams = call.arguments;
443
+ await toolStrategy?.onToolCall?.(tool, effectiveParams);
434
444
  if (toolStrategy?.onBeforeCall) {
435
- const shouldRun = await toolStrategy.onBeforeCall(tool, call.arguments);
436
- if (!shouldRun) {
445
+ const beforeResult = await toolStrategy.onBeforeCall(tool, effectiveParams);
446
+ const isBeforeCallResult = (value) => typeof value === "object" && value !== null && "proceed" in value;
447
+ if (isBeforeCallResult(beforeResult)) {
448
+ if (!beforeResult.proceed) {
449
+ const endTime = Date.now();
450
+ onEvent?.(toolExecutionEnd(call.toolCallId, tool.name, "Tool execution skipped", true, endTime, index));
451
+ return {
452
+ toolCallId: call.toolCallId,
453
+ result: "Tool execution skipped",
454
+ isError: true
455
+ };
456
+ }
457
+ if (beforeResult.params !== void 0) {
458
+ effectiveParams = beforeResult.params;
459
+ }
460
+ } else if (!beforeResult) {
437
461
  const endTime = Date.now();
438
462
  onEvent?.(toolExecutionEnd(call.toolCallId, tool.name, "Tool execution skipped", true, endTime, index));
439
463
  return {
@@ -446,7 +470,7 @@ async function executeTools(message, tools, toolStrategy, executions, onEvent) {
446
470
  let approved = true;
447
471
  if (tool.approval) {
448
472
  try {
449
- approved = await tool.approval(call.arguments);
473
+ approved = await tool.approval(effectiveParams);
450
474
  } catch (error) {
451
475
  throw error;
452
476
  }
@@ -456,7 +480,7 @@ async function executeTools(message, tools, toolStrategy, executions, onEvent) {
456
480
  const execution = {
457
481
  toolName: tool.name,
458
482
  toolCallId: call.toolCallId,
459
- arguments: call.arguments,
483
+ arguments: effectiveParams,
460
484
  result: "Tool execution denied",
461
485
  isError: true,
462
486
  duration: endTime - startTime,
@@ -471,13 +495,19 @@ async function executeTools(message, tools, toolStrategy, executions, onEvent) {
471
495
  };
472
496
  }
473
497
  try {
474
- const result = await tool.run(call.arguments);
498
+ let result = await tool.run(effectiveParams);
475
499
  const endTime = Date.now();
476
- await toolStrategy?.onAfterCall?.(tool, call.arguments, result);
500
+ if (toolStrategy?.onAfterCall) {
501
+ const afterResult = await toolStrategy.onAfterCall(tool, effectiveParams, result);
502
+ const isAfterCallResult = (value) => typeof value === "object" && value !== null && "result" in value;
503
+ if (isAfterCallResult(afterResult)) {
504
+ result = afterResult.result;
505
+ }
506
+ }
477
507
  const execution = {
478
508
  toolName: tool.name,
479
509
  toolCallId: call.toolCallId,
480
- arguments: call.arguments,
510
+ arguments: effectiveParams,
481
511
  result,
482
512
  isError: false,
483
513
  duration: endTime - startTime,
@@ -492,12 +522,12 @@ async function executeTools(message, tools, toolStrategy, executions, onEvent) {
492
522
  };
493
523
  } catch (error) {
494
524
  const endTime = Date.now();
495
- await toolStrategy?.onError?.(tool, call.arguments, error);
525
+ await toolStrategy?.onError?.(tool, effectiveParams, error);
496
526
  const errorMessage = error instanceof Error ? error.message : String(error);
497
527
  const execution = {
498
528
  toolName: tool.name,
499
529
  toolCallId: call.toolCallId,
500
- arguments: call.arguments,
530
+ arguments: effectiveParams,
501
531
  result: errorMessage,
502
532
  isError: true,
503
533
  duration: endTime - startTime,
@@ -550,9 +580,13 @@ function validateMediaCapabilities(messages, capabilities, providerName) {
550
580
  // src/core/image.ts
551
581
  import { readFile } from "fs/promises";
552
582
  var Image = class _Image {
583
+ /** The underlying image source (bytes, base64, or URL) */
553
584
  source;
585
+ /** MIME type of the image (e.g., 'image/jpeg', 'image/png') */
554
586
  mimeType;
587
+ /** Image width in pixels, if known */
555
588
  width;
589
+ /** Image height in pixels, if known */
556
590
  height;
557
591
  constructor(source, mimeType, width, height) {
558
592
  this.source = source;
@@ -561,13 +595,19 @@ var Image = class _Image {
561
595
  this.height = height;
562
596
  }
563
597
  /**
564
- * Check if this image has data loaded (false for URL sources)
598
+ * Whether this image has data loaded in memory.
599
+ *
600
+ * Returns `false` for URL-sourced images that reference external resources.
601
+ * These must be fetched before their data can be accessed.
565
602
  */
566
603
  get hasData() {
567
604
  return this.source.type !== "url";
568
605
  }
569
606
  /**
570
- * Convert to base64 string (throws if source is URL)
607
+ * Converts the image to a base64-encoded string.
608
+ *
609
+ * @returns The image data as a base64 string
610
+ * @throws {Error} When the source is a URL (data must be fetched first)
571
611
  */
572
612
  toBase64() {
573
613
  if (this.source.type === "base64") {
@@ -581,14 +621,20 @@ var Image = class _Image {
581
621
  throw new Error("Cannot convert URL image to base64. Fetch the image first.");
582
622
  }
583
623
  /**
584
- * Convert to data URL (throws if source is URL)
624
+ * Converts the image to a data URL suitable for embedding in HTML or CSS.
625
+ *
626
+ * @returns A data URL in the format `data:{mimeType};base64,{data}`
627
+ * @throws {Error} When the source is a URL (data must be fetched first)
585
628
  */
586
629
  toDataUrl() {
587
630
  const base64 = this.toBase64();
588
631
  return `data:${this.mimeType};base64,${base64}`;
589
632
  }
590
633
  /**
591
- * Get raw bytes (throws if source is URL)
634
+ * Gets the image data as raw bytes.
635
+ *
636
+ * @returns The image data as a Uint8Array
637
+ * @throws {Error} When the source is a URL (data must be fetched first)
592
638
  */
593
639
  toBytes() {
594
640
  if (this.source.type === "bytes") {
@@ -605,7 +651,10 @@ var Image = class _Image {
605
651
  throw new Error("Cannot get bytes from URL image. Fetch the image first.");
606
652
  }
607
653
  /**
608
- * Get the URL (only for URL sources)
654
+ * Gets the URL for URL-sourced images.
655
+ *
656
+ * @returns The image URL
657
+ * @throws {Error} When the source is not a URL
609
658
  */
610
659
  toUrl() {
611
660
  if (this.source.type === "url") {
@@ -614,7 +663,9 @@ var Image = class _Image {
614
663
  throw new Error("This image does not have a URL source.");
615
664
  }
616
665
  /**
617
- * Convert to ImageBlock for use in messages
666
+ * Converts this Image to an ImageBlock for use in UPP messages.
667
+ *
668
+ * @returns An ImageBlock that can be included in message content arrays
618
669
  */
619
670
  toBlock() {
620
671
  return {
@@ -626,7 +677,18 @@ var Image = class _Image {
626
677
  };
627
678
  }
628
679
  /**
629
- * Create from file path (reads file into memory)
680
+ * Creates an Image by reading a file from disk.
681
+ *
682
+ * The file is read into memory as bytes. MIME type is automatically
683
+ * detected from the file extension.
684
+ *
685
+ * @param path - Path to the image file
686
+ * @returns Promise resolving to an Image with the file contents
687
+ *
688
+ * @example
689
+ * ```typescript
690
+ * const image = await Image.fromPath('./photos/vacation.jpg');
691
+ * ```
630
692
  */
631
693
  static async fromPath(path) {
632
694
  const data = await readFile(path);
@@ -637,26 +699,63 @@ var Image = class _Image {
637
699
  );
638
700
  }
639
701
  /**
640
- * Create from URL reference (does not fetch - providers handle URL conversion)
702
+ * Creates an Image from a URL reference.
703
+ *
704
+ * The URL is stored as a reference and not fetched. Providers will handle
705
+ * URL-to-data conversion if needed. MIME type is detected from the URL
706
+ * path if not provided.
707
+ *
708
+ * @param url - URL pointing to the image
709
+ * @param mimeType - Optional MIME type override
710
+ * @returns An Image referencing the URL
711
+ *
712
+ * @example
713
+ * ```typescript
714
+ * const image = Image.fromUrl('https://example.com/logo.png');
715
+ * ```
641
716
  */
642
717
  static fromUrl(url, mimeType) {
643
718
  const detected = mimeType || detectMimeTypeFromUrl(url);
644
719
  return new _Image({ type: "url", url }, detected);
645
720
  }
646
721
  /**
647
- * Create from raw bytes
722
+ * Creates an Image from raw byte data.
723
+ *
724
+ * @param data - The image data as a Uint8Array
725
+ * @param mimeType - The MIME type of the image
726
+ * @returns An Image containing the byte data
727
+ *
728
+ * @example
729
+ * ```typescript
730
+ * const image = Image.fromBytes(pngData, 'image/png');
731
+ * ```
648
732
  */
649
733
  static fromBytes(data, mimeType) {
650
734
  return new _Image({ type: "bytes", data }, mimeType);
651
735
  }
652
736
  /**
653
- * Create from base64 string
737
+ * Creates an Image from a base64-encoded string.
738
+ *
739
+ * @param base64 - The base64-encoded image data (without data URL prefix)
740
+ * @param mimeType - The MIME type of the image
741
+ * @returns An Image containing the base64 data
742
+ *
743
+ * @example
744
+ * ```typescript
745
+ * const image = Image.fromBase64(base64String, 'image/jpeg');
746
+ * ```
654
747
  */
655
748
  static fromBase64(base64, mimeType) {
656
749
  return new _Image({ type: "base64", data: base64 }, mimeType);
657
750
  }
658
751
  /**
659
- * Create from an existing ImageBlock
752
+ * Creates an Image from an existing ImageBlock.
753
+ *
754
+ * Useful for converting content blocks received from providers back
755
+ * into Image instances for further processing.
756
+ *
757
+ * @param block - An ImageBlock from message content
758
+ * @returns An Image with the block's source and metadata
660
759
  */
661
760
  static fromBlock(block) {
662
761
  return new _Image(
@@ -729,7 +828,9 @@ var Thread = class _Thread {
729
828
  /** Last update timestamp */
730
829
  _updatedAt;
731
830
  /**
732
- * Create a new thread, optionally with initial messages
831
+ * Creates a new thread instance.
832
+ *
833
+ * @param messages - Optional initial messages to populate the thread
733
834
  */
734
835
  constructor(messages) {
735
836
  this.id = generateId();
@@ -737,16 +838,23 @@ var Thread = class _Thread {
737
838
  this._createdAt = /* @__PURE__ */ new Date();
738
839
  this._updatedAt = /* @__PURE__ */ new Date();
739
840
  }
740
- /** All messages in the thread (readonly) */
841
+ /**
842
+ * All messages in the thread (readonly).
843
+ */
741
844
  get messages() {
742
845
  return this._messages;
743
846
  }
744
- /** Number of messages */
847
+ /**
848
+ * Number of messages in the thread.
849
+ */
745
850
  get length() {
746
851
  return this._messages.length;
747
852
  }
748
853
  /**
749
- * Append messages from a turn
854
+ * Appends all messages from a Turn to the thread.
855
+ *
856
+ * @param turn - The Turn containing messages to append
857
+ * @returns This thread instance for chaining
750
858
  */
751
859
  append(turn) {
752
860
  this._messages.push(...turn.messages);
@@ -754,7 +862,10 @@ var Thread = class _Thread {
754
862
  return this;
755
863
  }
756
864
  /**
757
- * Add raw messages
865
+ * Adds raw messages to the thread.
866
+ *
867
+ * @param messages - Messages to add
868
+ * @returns This thread instance for chaining
758
869
  */
759
870
  push(...messages) {
760
871
  this._messages.push(...messages);
@@ -762,7 +873,19 @@ var Thread = class _Thread {
762
873
  return this;
763
874
  }
764
875
  /**
765
- * Add a user message
876
+ * Adds a user message to the thread.
877
+ *
878
+ * @param content - String or array of content blocks
879
+ * @returns This thread instance for chaining
880
+ *
881
+ * @example
882
+ * ```typescript
883
+ * thread.user('Hello, world!');
884
+ * thread.user([
885
+ * { type: 'text', text: 'Describe this image:' },
886
+ * { type: 'image', source: { type: 'url', url: '...' }, mimeType: 'image/png' }
887
+ * ]);
888
+ * ```
766
889
  */
767
890
  user(content) {
768
891
  this._messages.push(new UserMessage(content));
@@ -770,7 +893,15 @@ var Thread = class _Thread {
770
893
  return this;
771
894
  }
772
895
  /**
773
- * Add an assistant message
896
+ * Adds an assistant message to the thread.
897
+ *
898
+ * @param content - String or array of content blocks
899
+ * @returns This thread instance for chaining
900
+ *
901
+ * @example
902
+ * ```typescript
903
+ * thread.assistant('I can help with that!');
904
+ * ```
774
905
  */
775
906
  assistant(content) {
776
907
  this._messages.push(new AssistantMessage(content));
@@ -778,25 +909,53 @@ var Thread = class _Thread {
778
909
  return this;
779
910
  }
780
911
  /**
781
- * Get messages by type
912
+ * Filters messages by type.
913
+ *
914
+ * @param type - The message type to filter by
915
+ * @returns Array of messages matching the type
916
+ *
917
+ * @example
918
+ * ```typescript
919
+ * const userMessages = thread.filter('user');
920
+ * const assistantMessages = thread.filter('assistant');
921
+ * ```
782
922
  */
783
923
  filter(type) {
784
924
  return this._messages.filter((m) => m.type === type);
785
925
  }
786
926
  /**
787
- * Get the last N messages
927
+ * Returns the last N messages from the thread.
928
+ *
929
+ * @param count - Number of messages to return
930
+ * @returns Array of the last N messages
931
+ *
932
+ * @example
933
+ * ```typescript
934
+ * const recent = thread.tail(5);
935
+ * ```
788
936
  */
789
937
  tail(count) {
790
938
  return this._messages.slice(-count);
791
939
  }
792
940
  /**
793
- * Create a new thread with a subset of messages
941
+ * Creates a new thread with a subset of messages.
942
+ *
943
+ * @param start - Start index (inclusive)
944
+ * @param end - End index (exclusive)
945
+ * @returns New Thread containing the sliced messages
946
+ *
947
+ * @example
948
+ * ```typescript
949
+ * const subset = thread.slice(0, 10);
950
+ * ```
794
951
  */
795
952
  slice(start, end) {
796
953
  return new _Thread(this._messages.slice(start, end));
797
954
  }
798
955
  /**
799
- * Clear all messages
956
+ * Removes all messages from the thread.
957
+ *
958
+ * @returns This thread instance for chaining
800
959
  */
801
960
  clear() {
802
961
  this._messages = [];
@@ -804,13 +963,23 @@ var Thread = class _Thread {
804
963
  return this;
805
964
  }
806
965
  /**
807
- * Convert to plain message array
966
+ * Converts the thread to a plain message array.
967
+ *
968
+ * @returns Copy of the internal message array
808
969
  */
809
970
  toMessages() {
810
971
  return [...this._messages];
811
972
  }
812
973
  /**
813
- * Serialize to JSON
974
+ * Serializes the thread to JSON format.
975
+ *
976
+ * @returns JSON-serializable representation of the thread
977
+ *
978
+ * @example
979
+ * ```typescript
980
+ * const json = thread.toJSON();
981
+ * localStorage.setItem('thread', JSON.stringify(json));
982
+ * ```
814
983
  */
815
984
  toJSON() {
816
985
  return {
@@ -821,7 +990,16 @@ var Thread = class _Thread {
821
990
  };
822
991
  }
823
992
  /**
824
- * Deserialize from JSON
993
+ * Deserializes a thread from JSON format.
994
+ *
995
+ * @param json - The JSON representation to deserialize
996
+ * @returns Reconstructed Thread instance
997
+ *
998
+ * @example
999
+ * ```typescript
1000
+ * const json = JSON.parse(localStorage.getItem('thread'));
1001
+ * const thread = Thread.fromJSON(json);
1002
+ * ```
825
1003
  */
826
1004
  static fromJSON(json) {
827
1005
  const messages = json.messages.map((m) => _Thread.messageFromJSON(m));
@@ -832,13 +1010,22 @@ var Thread = class _Thread {
832
1010
  return thread;
833
1011
  }
834
1012
  /**
835
- * Iterate over messages
1013
+ * Enables iteration over messages with for...of loops.
1014
+ *
1015
+ * @returns Iterator over the thread's messages
1016
+ *
1017
+ * @example
1018
+ * ```typescript
1019
+ * for (const message of thread) {
1020
+ * console.log(message.text);
1021
+ * }
1022
+ * ```
836
1023
  */
837
1024
  [Symbol.iterator]() {
838
1025
  return this._messages[Symbol.iterator]();
839
1026
  }
840
1027
  /**
841
- * Convert a message to JSON
1028
+ * Converts a message to JSON format.
842
1029
  */
843
1030
  messageToJSON(m) {
844
1031
  const base = {
@@ -859,7 +1046,7 @@ var Thread = class _Thread {
859
1046
  return base;
860
1047
  }
861
1048
  /**
862
- * Reconstruct a message from JSON
1049
+ * Reconstructs a message from JSON format.
863
1050
  */
864
1051
  static messageFromJSON(json) {
865
1052
  const options = {
@@ -885,9 +1072,8 @@ var Thread = class _Thread {
885
1072
 
886
1073
  // src/index.ts
887
1074
  var ai = {
1075
+ /** LLM instance factory */
888
1076
  llm
889
- // embedding, // Coming soon
890
- // image, // Coming soon
891
1077
  };
892
1078
  export {
893
1079
  AssistantMessage,