@promptbook/google 0.102.0-9 → 0.103.0-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.
Files changed (33) hide show
  1. package/esm/index.es.js +942 -11
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/color.index.d.ts +2 -0
  4. package/esm/typings/src/_packages/components.index.d.ts +4 -0
  5. package/esm/typings/src/_packages/core.index.d.ts +6 -0
  6. package/esm/typings/src/_packages/utils.index.d.ts +2 -0
  7. package/esm/typings/src/book-components/Chat/Chat/ChatMessageItem.d.ts +9 -1
  8. package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +4 -0
  9. package/esm/typings/src/book-components/Chat/save/_common/ChatSaveFormatDefinition.d.ts +43 -5
  10. package/esm/typings/src/book-components/Chat/save/html/htmlSaveFormatDefinition.d.ts +9 -2
  11. package/esm/typings/src/book-components/Chat/save/index.d.ts +38 -8
  12. package/esm/typings/src/book-components/Chat/save/json/jsonSaveFormatDefinition.d.ts +6 -2
  13. package/esm/typings/src/book-components/Chat/save/markdown/mdSaveFormatDefinition.d.ts +5 -1
  14. package/esm/typings/src/book-components/Chat/save/pdf/pdfSaveFormatDefinition.d.ts +6 -2
  15. package/esm/typings/src/book-components/Chat/save/react/reactSaveFormatDefinition.d.ts +16 -0
  16. package/esm/typings/src/book-components/Chat/save/text/txtSaveFormatDefinition.d.ts +5 -1
  17. package/esm/typings/src/book-components/Chat/types/ChatMessage.d.ts +1 -1
  18. package/esm/typings/src/book-components/Chat/types/ChatParticipant.d.ts +1 -1
  19. package/esm/typings/src/book-components/Chat/utils/exportChatHistory.d.ts +1 -1
  20. package/esm/typings/src/book-components/icons/SaveIcon.d.ts +10 -0
  21. package/esm/typings/src/config.d.ts +26 -4
  22. package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +1 -1
  23. package/esm/typings/src/utils/color/Color.d.ts +8 -0
  24. package/esm/typings/src/utils/color/operators/darken.d.ts +2 -1
  25. package/esm/typings/src/utils/color/operators/grayscale.d.ts +2 -1
  26. package/esm/typings/src/utils/color/operators/lighten.d.ts +2 -1
  27. package/esm/typings/src/utils/color/operators/mixWithColor.d.ts +2 -1
  28. package/esm/typings/src/utils/color/operators/saturate.d.ts +13 -0
  29. package/esm/typings/src/utils/serialization/serializeToPromptbookJavascript.d.ts +22 -0
  30. package/esm/typings/src/version.d.ts +1 -1
  31. package/package.json +2 -2
  32. package/umd/index.umd.js +942 -11
  33. package/umd/index.umd.js.map +1 -1
package/esm/index.es.js CHANGED
@@ -16,7 +16,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
16
16
  * @generated
17
17
  * @see https://github.com/webgptorg/promptbook
18
18
  */
19
- const PROMPTBOOK_ENGINE_VERSION = '0.102.0-9';
19
+ const PROMPTBOOK_ENGINE_VERSION = '0.103.0-0';
20
20
  /**
21
21
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
22
22
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -602,6 +602,895 @@ function $getCurrentDate() {
602
602
  return new Date().toISOString();
603
603
  }
604
604
 
605
+ /**
606
+ * @private util of `@promptbook/color`
607
+ * @de
608
+ */
609
+ class TakeChain {
610
+ constructor(value) {
611
+ this.value = value;
612
+ }
613
+ then(callback) {
614
+ const newValue = callback(this.value);
615
+ return take(newValue);
616
+ }
617
+ }
618
+
619
+ /**
620
+ * A function that takes an initial value and returns a proxy object with chainable methods.
621
+ *
622
+ * @param {*} initialValue - The initial value.
623
+ * @returns {Proxy<WithTake<TValue>>} - A proxy object with a `take` method.
624
+ *
625
+ * @private util of `@promptbook/color`
626
+ * @deprecated [🤡] Use some better functional library instead of `TakeChain`
627
+ */
628
+ function take(initialValue) {
629
+ if (initialValue instanceof TakeChain) {
630
+ return initialValue;
631
+ }
632
+ return new Proxy(new TakeChain(initialValue), {
633
+ get(target, property, receiver) {
634
+ if (Reflect.has(target, property)) {
635
+ return Reflect.get(target, property, receiver);
636
+ }
637
+ else if (Reflect.has(initialValue, property)) {
638
+ return Reflect.get(initialValue, property, receiver);
639
+ }
640
+ else {
641
+ return undefined;
642
+ }
643
+ },
644
+ });
645
+ }
646
+
647
+ /**
648
+ * 🎨 List of all 140 color names which are supported by CSS
649
+ *
650
+ * @public exported from `@promptbook/color`
651
+ */
652
+ const CSS_COLORS = {
653
+ transparent: 'rgba(0,0,0,0)',
654
+ aliceblue: '#f0f8ff',
655
+ antiquewhite: '#faebd7',
656
+ aqua: '#00ffff',
657
+ aquamarine: '#7fffd4',
658
+ azure: '#f0ffff',
659
+ beige: '#f5f5dc',
660
+ bisque: '#ffe4c4',
661
+ black: '#000000',
662
+ blanchedalmond: '#ffebcd',
663
+ blue: '#0000ff',
664
+ blueviolet: '#8a2be2',
665
+ brown: '#a52a2a',
666
+ burlywood: '#deb887',
667
+ cadetblue: '#5f9ea0',
668
+ chartreuse: '#7fff00',
669
+ chocolate: '#d2691e',
670
+ coral: '#ff7f50',
671
+ cornflowerblue: '#6495ed',
672
+ cornsilk: '#fff8dc',
673
+ crimson: '#dc143c',
674
+ cyan: '#00ffff',
675
+ darkblue: '#00008b',
676
+ darkcyan: '#008b8b',
677
+ darkgoldenrod: '#b8860b',
678
+ darkgray: '#a9a9a9',
679
+ darkgrey: '#a9a9a9',
680
+ darkgreen: '#006400',
681
+ darkkhaki: '#bdb76b',
682
+ darkmagenta: '#8b008b',
683
+ darkolivegreen: '#556b2f',
684
+ darkorange: '#ff8c00',
685
+ darkorchid: '#9932cc',
686
+ darkred: '#8b0000',
687
+ darksalmon: '#e9967a',
688
+ darkseagreen: '#8fbc8f',
689
+ darkslateblue: '#483d8b',
690
+ darkslategray: '#2f4f4f',
691
+ darkslategrey: '#2f4f4f',
692
+ darkturquoise: '#00ced1',
693
+ darkviolet: '#9400d3',
694
+ deeppink: '#ff1493',
695
+ deepskyblue: '#00bfff',
696
+ dimgray: '#696969',
697
+ dimgrey: '#696969',
698
+ dodgerblue: '#1e90ff',
699
+ firebrick: '#b22222',
700
+ floralwhite: '#fffaf0',
701
+ forestgreen: '#228b22',
702
+ fuchsia: '#ff00ff',
703
+ gainsboro: '#dcdcdc',
704
+ ghostwhite: '#f8f8ff',
705
+ gold: '#ffd700',
706
+ goldenrod: '#daa520',
707
+ gray: '#808080',
708
+ grey: '#808080',
709
+ green: '#008000',
710
+ greenyellow: '#adff2f',
711
+ honeydew: '#f0fff0',
712
+ hotpink: '#ff69b4',
713
+ indianred: '#cd5c5c',
714
+ indigo: '#4b0082',
715
+ ivory: '#fffff0',
716
+ khaki: '#f0e68c',
717
+ lavender: '#e6e6fa',
718
+ lavenderblush: '#fff0f5',
719
+ lawngreen: '#7cfc00',
720
+ lemonchiffon: '#fffacd',
721
+ lightblue: '#add8e6',
722
+ lightcoral: '#f08080',
723
+ lightcyan: '#e0ffff',
724
+ lightgoldenrodyellow: '#fafad2',
725
+ lightgray: '#d3d3d3',
726
+ lightgrey: '#d3d3d3',
727
+ lightgreen: '#90ee90',
728
+ lightpink: '#ffb6c1',
729
+ lightsalmon: '#ffa07a',
730
+ lightseagreen: '#20b2aa',
731
+ lightskyblue: '#87cefa',
732
+ lightslategray: '#778899',
733
+ lightslategrey: '#778899',
734
+ lightsteelblue: '#b0c4de',
735
+ lightyellow: '#ffffe0',
736
+ lime: '#00ff00',
737
+ limegreen: '#32cd32',
738
+ linen: '#faf0e6',
739
+ magenta: '#ff00ff',
740
+ maroon: '#800000',
741
+ mediumaquamarine: '#66cdaa',
742
+ mediumblue: '#0000cd',
743
+ mediumorchid: '#ba55d3',
744
+ mediumpurple: '#9370db',
745
+ mediumseagreen: '#3cb371',
746
+ mediumslateblue: '#7b68ee',
747
+ mediumspringgreen: '#00fa9a',
748
+ mediumturquoise: '#48d1cc',
749
+ mediumvioletred: '#c71585',
750
+ midnightblue: '#191970',
751
+ mintcream: '#f5fffa',
752
+ mistyrose: '#ffe4e1',
753
+ moccasin: '#ffe4b5',
754
+ navajowhite: '#ffdead',
755
+ navy: '#000080',
756
+ oldlace: '#fdf5e6',
757
+ olive: '#808000',
758
+ olivedrab: '#6b8e23',
759
+ orange: '#ffa500',
760
+ orangered: '#ff4500',
761
+ orchid: '#da70d6',
762
+ palegoldenrod: '#eee8aa',
763
+ palegreen: '#98fb98',
764
+ paleturquoise: '#afeeee',
765
+ palevioletred: '#db7093',
766
+ papayawhip: '#ffefd5',
767
+ peachpuff: '#ffdab9',
768
+ peru: '#cd853f',
769
+ pink: '#ffc0cb',
770
+ plum: '#dda0dd',
771
+ powderblue: '#b0e0e6',
772
+ purple: '#800080',
773
+ rebeccapurple: '#663399',
774
+ red: '#ff0000',
775
+ rosybrown: '#bc8f8f',
776
+ royalblue: '#4169e1',
777
+ saddlebrown: '#8b4513',
778
+ salmon: '#fa8072',
779
+ sandybrown: '#f4a460',
780
+ seagreen: '#2e8b57',
781
+ seashell: '#fff5ee',
782
+ sienna: '#a0522d',
783
+ silver: '#c0c0c0',
784
+ skyblue: '#87ceeb',
785
+ slateblue: '#6a5acd',
786
+ slategray: '#708090',
787
+ slategrey: '#708090',
788
+ snow: '#fffafa',
789
+ springgreen: '#00ff7f',
790
+ steelblue: '#4682b4',
791
+ tan: '#d2b48c',
792
+ teal: '#008080',
793
+ thistle: '#d8bfd8',
794
+ tomato: '#ff6347',
795
+ turquoise: '#40e0d0',
796
+ violet: '#ee82ee',
797
+ wheat: '#f5deb3',
798
+ white: '#ffffff',
799
+ whitesmoke: '#f5f5f5',
800
+ yellow: '#ffff00',
801
+ yellowgreen: '#9acd32',
802
+ };
803
+ /**
804
+ * Note: [💞] Ignore a discrepancy between file name and entity name
805
+ */
806
+
807
+ /**
808
+ * Validates that a channel value is a valid number within the range of 0 to 255.
809
+ * Throws an error if the value is not valid.
810
+ *
811
+ * @param channelName - The name of the channel being validated.
812
+ * @param value - The value of the channel to validate.
813
+ * @throws Will throw an error if the value is not a valid channel number.
814
+ *
815
+ * @private util of `@promptbook/color`
816
+ */
817
+ function checkChannelValue(channelName, value) {
818
+ if (typeof value !== 'number') {
819
+ throw new Error(`${channelName} channel value is not number but ${typeof value}`);
820
+ }
821
+ if (isNaN(value)) {
822
+ throw new Error(`${channelName} channel value is NaN`);
823
+ }
824
+ if (Math.round(value) !== value) {
825
+ throw new Error(`${channelName} channel is not whole number, it is ${value}`);
826
+ }
827
+ if (value < 0) {
828
+ throw new Error(`${channelName} channel is lower than 0, it is ${value}`);
829
+ }
830
+ if (value > 255) {
831
+ throw new Error(`${channelName} channel is greater than 255, it is ${value}`);
832
+ }
833
+ }
834
+ /**
835
+ * TODO: [🧠][🚓] Is/which combination it better to use asserts/check, validate or is utility function?
836
+ */
837
+
838
+ /**
839
+ * Color object represents an RGB color with alpha channel
840
+ *
841
+ * Note: There is no fromObject/toObject because the most logical way to serialize color is as a hex string (#009edd)
842
+ *
843
+ * @public exported from `@promptbook/color`
844
+ */
845
+ class Color {
846
+ /**
847
+ * Creates a new Color instance from miscellaneous formats
848
+ * - It can receive Color instance and just return the same instance
849
+ * - It can receive color in string format for example `#009edd`, `rgb(0,158,221)`, `rgb(0%,62%,86.7%)`, `hsl(197.1,100%,43.3%)`
850
+ *
851
+ * Note: This is not including fromImage because detecting color from an image is heavy task which requires async stuff and we cannot safely determine with overloading if return value will be a promise
852
+ *
853
+ * @param color
854
+ * @returns Color object
855
+ */
856
+ static from(color) {
857
+ if (color instanceof Color) {
858
+ return take(color);
859
+ }
860
+ else if (Color.isColor(color)) {
861
+ return take(color);
862
+ }
863
+ else if (typeof color === 'string') {
864
+ return Color.fromString(color);
865
+ }
866
+ else {
867
+ console.error({ color });
868
+ throw new Error(`Can not create color from given object`);
869
+ }
870
+ }
871
+ /**
872
+ * Creates a new Color instance from miscellaneous string formats
873
+ *
874
+ * @param color as a string for example `#009edd`, `rgb(0,158,221)`, `rgb(0%,62%,86.7%)`, `hsl(197.1,100%,43.3%)`, `red`, `darkgrey`,...
875
+ * @returns Color object
876
+ */
877
+ static fromString(color) {
878
+ if (CSS_COLORS[color]) {
879
+ return Color.fromString(CSS_COLORS[color]);
880
+ // -----
881
+ }
882
+ else if (Color.isHexColorString(color)) {
883
+ return Color.fromHex(color);
884
+ // -----
885
+ }
886
+ else if (/^hsl\(\s*(\d+)\s*,\s*(\d+(?:\.\d+)?%)\s*,\s*(\d+(?:\.\d+)?%)\)$/.test(color)) {
887
+ return Color.fromHsl(color);
888
+ // -----
889
+ }
890
+ else if (/^rgb\((\s*[0-9-.%]+\s*,?){3}\)$/.test(color)) {
891
+ // TODO: [0] Should be fromRgbString and fromRgbaString one or two functions
892
+ return Color.fromRgbString(color);
893
+ // -----
894
+ }
895
+ else if (/^rgba\((\s*[0-9-.%]+\s*,?){4}\)$/.test(color)) {
896
+ return Color.fromRgbaString(color);
897
+ // -----
898
+ }
899
+ else {
900
+ throw new Error(`Can not create a new Color instance from string "${color}".`);
901
+ }
902
+ }
903
+ /**
904
+ * Gets common color
905
+ *
906
+ * @param key as a css string like `midnightblue`
907
+ * @returns Color object
908
+ */
909
+ static get(key) {
910
+ if (!CSS_COLORS[key]) {
911
+ throw new Error(`"${key}" is not a common css color.`);
912
+ }
913
+ return Color.fromString(CSS_COLORS[key]);
914
+ }
915
+ /**
916
+ * Creates a new Color instance from average color of given image
917
+ *
918
+ * @param image as a source for example `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAA1JREFUGFdjYJh39z8ABJgCe/ZvAS4AAAAASUVORK5CYII=`
919
+ * @returns Color object
920
+ */
921
+ static async fromImage(image) {
922
+ return Color.fromHex(`#009edd`);
923
+ }
924
+ /**
925
+ * Creates a new Color instance from color in hex format
926
+ *
927
+ * @param color in hex for example `#009edd`, `009edd`, `#555`,...
928
+ * @returns Color object
929
+ */
930
+ static fromHex(hex) {
931
+ const hexOriginal = hex;
932
+ if (hex.startsWith('#')) {
933
+ hex = hex.substring(1);
934
+ }
935
+ if (hex.length === 3) {
936
+ return Color.fromHex3(hex);
937
+ }
938
+ if (hex.length === 6) {
939
+ return Color.fromHex6(hex);
940
+ }
941
+ if (hex.length === 8) {
942
+ return Color.fromHex8(hex);
943
+ }
944
+ throw new Error(`Can not parse color from hex string "${hexOriginal}"`);
945
+ }
946
+ /**
947
+ * Creates a new Color instance from color in hex format with 3 color digits (without alpha channel)
948
+ *
949
+ * @param color in hex for example `09d`
950
+ * @returns Color object
951
+ */
952
+ static fromHex3(hex) {
953
+ const r = parseInt(hex.substr(0, 1), 16) * 16;
954
+ const g = parseInt(hex.substr(1, 1), 16) * 16;
955
+ const b = parseInt(hex.substr(2, 1), 16) * 16;
956
+ return take(new Color(r, g, b));
957
+ }
958
+ /**
959
+ * Creates a new Color instance from color in hex format with 6 color digits (without alpha channel)
960
+ *
961
+ * @param color in hex for example `009edd`
962
+ * @returns Color object
963
+ */
964
+ static fromHex6(hex) {
965
+ const r = parseInt(hex.substr(0, 2), 16);
966
+ const g = parseInt(hex.substr(2, 2), 16);
967
+ const b = parseInt(hex.substr(4, 2), 16);
968
+ return take(new Color(r, g, b));
969
+ }
970
+ /**
971
+ * Creates a new Color instance from color in hex format with 8 color digits (with alpha channel)
972
+ *
973
+ * @param color in hex for example `009edd`
974
+ * @returns Color object
975
+ */
976
+ static fromHex8(hex) {
977
+ const r = parseInt(hex.substr(0, 2), 16);
978
+ const g = parseInt(hex.substr(2, 2), 16);
979
+ const b = parseInt(hex.substr(4, 2), 16);
980
+ const a = parseInt(hex.substr(6, 2), 16);
981
+ return take(new Color(r, g, b, a));
982
+ }
983
+ /**
984
+ * Creates a new Color instance from color in hsl format
985
+ *
986
+ * @param color as a hsl for example `hsl(197.1,100%,43.3%)`
987
+ * @returns Color object
988
+ */
989
+ static fromHsl(hsl) {
990
+ const match = hsl.match(/^hsl\(\s*([0-9.]+)\s*,\s*([0-9.]+)%\s*,\s*([0-9.]+)%\s*\)$/);
991
+ if (!match) {
992
+ throw new Error(`Invalid hsl string format: "${hsl}"`);
993
+ }
994
+ const h = parseFloat(match[1]);
995
+ const s = parseFloat(match[2]) / 100;
996
+ const l = parseFloat(match[3]) / 100;
997
+ // HSL to RGB conversion
998
+ const c = (1 - Math.abs(2 * l - 1)) * s;
999
+ const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
1000
+ const m = l - c / 2;
1001
+ let r1 = 0, g1 = 0, b1 = 0;
1002
+ if (h >= 0 && h < 60) {
1003
+ r1 = c;
1004
+ g1 = x;
1005
+ b1 = 0;
1006
+ }
1007
+ else if (h >= 60 && h < 120) {
1008
+ r1 = x;
1009
+ g1 = c;
1010
+ b1 = 0;
1011
+ }
1012
+ else if (h >= 120 && h < 180) {
1013
+ r1 = 0;
1014
+ g1 = c;
1015
+ b1 = x;
1016
+ }
1017
+ else if (h >= 180 && h < 240) {
1018
+ r1 = 0;
1019
+ g1 = x;
1020
+ b1 = c;
1021
+ }
1022
+ else if (h >= 240 && h < 300) {
1023
+ r1 = x;
1024
+ g1 = 0;
1025
+ b1 = c;
1026
+ }
1027
+ else if (h >= 300 && h < 360) {
1028
+ r1 = c;
1029
+ g1 = 0;
1030
+ b1 = x;
1031
+ }
1032
+ const r = Math.round((r1 + m) * 255);
1033
+ const g = Math.round((g1 + m) * 255);
1034
+ const b = Math.round((b1 + m) * 255);
1035
+ return take(new Color(r, g, b));
1036
+ }
1037
+ /**
1038
+ * Creates a new Color instance from color in rgb format
1039
+ *
1040
+ * @param color as a rgb for example `rgb(0,158,221)`, `rgb(0%,62%,86.7%)`
1041
+ * @returns Color object
1042
+ */
1043
+ static fromRgbString(rgb) {
1044
+ const match = rgb.match(/^rgb\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/);
1045
+ if (!match) {
1046
+ throw new Error(`Invalid rgb string format: "${rgb}"`);
1047
+ }
1048
+ const parseChannel = (value) => {
1049
+ if (value.endsWith('%')) {
1050
+ // Percentage value
1051
+ const percent = parseFloat(value);
1052
+ return Math.round((percent / 100) * 255);
1053
+ }
1054
+ else {
1055
+ // Numeric value
1056
+ return Math.round(parseFloat(value));
1057
+ }
1058
+ };
1059
+ const r = parseChannel(match[1]);
1060
+ const g = parseChannel(match[2]);
1061
+ const b = parseChannel(match[3]);
1062
+ return take(new Color(r, g, b));
1063
+ }
1064
+ /**
1065
+ * Creates a new Color instance from color in rbga format
1066
+ *
1067
+ * @param color as a rgba for example `rgba(0,158,221,0.5)`, `rgb(0%,62%,86.7%,50%)`
1068
+ * @returns Color object
1069
+ */
1070
+ static fromRgbaString(rgba) {
1071
+ const match = rgba.match(/^rgba\(\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*,\s*([0-9.%-]+)\s*\)$/);
1072
+ if (!match) {
1073
+ throw new Error(`Invalid rgba string format: "${rgba}"`);
1074
+ }
1075
+ const parseChannel = (value) => {
1076
+ if (value.endsWith('%')) {
1077
+ const percent = parseFloat(value);
1078
+ return Math.round((percent / 100) * 255);
1079
+ }
1080
+ else {
1081
+ return Math.round(parseFloat(value));
1082
+ }
1083
+ };
1084
+ const parseAlpha = (value) => {
1085
+ if (value.endsWith('%')) {
1086
+ const percent = parseFloat(value);
1087
+ return Math.round((percent / 100) * 255);
1088
+ }
1089
+ else {
1090
+ const alphaFloat = parseFloat(value);
1091
+ // If alpha is between 0 and 1, treat as float
1092
+ if (alphaFloat <= 1) {
1093
+ return Math.round(alphaFloat * 255);
1094
+ }
1095
+ // Otherwise, treat as 0-255
1096
+ return Math.round(alphaFloat);
1097
+ }
1098
+ };
1099
+ const r = parseChannel(match[1]);
1100
+ const g = parseChannel(match[2]);
1101
+ const b = parseChannel(match[3]);
1102
+ const a = parseAlpha(match[4]);
1103
+ return take(new Color(r, g, b, a));
1104
+ }
1105
+ /**
1106
+ * Creates a new Color for color channels values
1107
+ *
1108
+ * @param red number from 0 to 255
1109
+ * @param green number from 0 to 255
1110
+ * @param blue number from 0 to 255
1111
+ * @param alpha number from 0 (transparent) to 255 (opaque = default)
1112
+ * @returns Color object
1113
+ */
1114
+ static fromValues(red, green, blue, alpha = 255) {
1115
+ return take(new Color(red, green, blue, alpha));
1116
+ }
1117
+ /**
1118
+ * Checks if the given value is a valid Color object.
1119
+ *
1120
+ * @param {unknown} value - The value to check.
1121
+ * @return {value is WithTake<Color>} Returns true if the value is a valid Color object, false otherwise.
1122
+ */
1123
+ static isColor(value) {
1124
+ if (typeof value !== 'object') {
1125
+ return false;
1126
+ }
1127
+ if (value === null) {
1128
+ return false;
1129
+ }
1130
+ if (typeof value.red !== 'number' ||
1131
+ typeof value.green !== 'number' ||
1132
+ typeof value.blue !== 'number' ||
1133
+ typeof value.alpha !== 'number') {
1134
+ return false;
1135
+ }
1136
+ if (typeof value.then !== 'function') {
1137
+ return false;
1138
+ }
1139
+ return true;
1140
+ }
1141
+ /**
1142
+ * Checks if the given value is a valid hex color string
1143
+ *
1144
+ * @param value - value to check
1145
+ * @returns true if the value is a valid hex color string (e.g., `#009edd`, `#fff`, etc.)
1146
+ */
1147
+ static isHexColorString(value) {
1148
+ return typeof value === 'string' && /^#(?:[0-9a-fA-F]{3}){1,2}$/.test(value);
1149
+ }
1150
+ /**
1151
+ * Creates new Color object
1152
+ *
1153
+ * Note: Consider using one of static methods like `from` or `fromString`
1154
+ *
1155
+ * @param red number from 0 to 255
1156
+ * @param green number from 0 to 255
1157
+ * @param blue number from 0 to 255
1158
+ * @param alpha number from 0 (transparent) to 255 (opaque)
1159
+ */
1160
+ constructor(red, green, blue, alpha = 255) {
1161
+ this.red = red;
1162
+ this.green = green;
1163
+ this.blue = blue;
1164
+ this.alpha = alpha;
1165
+ checkChannelValue('Red', red);
1166
+ checkChannelValue('Green', green);
1167
+ checkChannelValue('Blue', blue);
1168
+ checkChannelValue('Alpha', alpha);
1169
+ }
1170
+ /**
1171
+ * Shortcut for `red` property
1172
+ * Number from 0 to 255
1173
+ * @alias red
1174
+ */
1175
+ get r() {
1176
+ return this.red;
1177
+ }
1178
+ /**
1179
+ * Shortcut for `green` property
1180
+ * Number from 0 to 255
1181
+ * @alias green
1182
+ */
1183
+ get g() {
1184
+ return this.green;
1185
+ }
1186
+ /**
1187
+ * Shortcut for `blue` property
1188
+ * Number from 0 to 255
1189
+ * @alias blue
1190
+ */
1191
+ get b() {
1192
+ return this.blue;
1193
+ }
1194
+ /**
1195
+ * Shortcut for `alpha` property
1196
+ * Number from 0 (transparent) to 255 (opaque)
1197
+ * @alias alpha
1198
+ */
1199
+ get a() {
1200
+ return this.alpha;
1201
+ }
1202
+ /**
1203
+ * Shortcut for `alpha` property
1204
+ * Number from 0 (transparent) to 255 (opaque)
1205
+ * @alias alpha
1206
+ */
1207
+ get opacity() {
1208
+ return this.alpha;
1209
+ }
1210
+ /**
1211
+ * Shortcut for 1-`alpha` property
1212
+ */
1213
+ get transparency() {
1214
+ return 255 - this.alpha;
1215
+ }
1216
+ clone() {
1217
+ return take(new Color(this.red, this.green, this.blue, this.alpha));
1218
+ }
1219
+ toString() {
1220
+ return this.toHex();
1221
+ }
1222
+ toHex() {
1223
+ if (this.alpha === 255) {
1224
+ return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
1225
+ .toString(16)
1226
+ .padStart(2, '0')}`;
1227
+ }
1228
+ else {
1229
+ return `#${this.red.toString(16).padStart(2, '0')}${this.green.toString(16).padStart(2, '0')}${this.blue
1230
+ .toString(16)
1231
+ .padStart(2, '0')}${this.alpha.toString(16).padStart(2, '0')}`;
1232
+ }
1233
+ }
1234
+ toRgb() {
1235
+ if (this.alpha === 255) {
1236
+ return `rgb(${this.red}, ${this.green}, ${this.blue})`;
1237
+ }
1238
+ else {
1239
+ return `rgba(${this.red}, ${this.green}, ${this.blue}, ${Math.round((this.alpha / 255) * 100)}%)`;
1240
+ }
1241
+ }
1242
+ toHsl() {
1243
+ throw new Error(`Getting HSL is not implemented`);
1244
+ }
1245
+ }
1246
+ /**
1247
+ * TODO: [🥻] Split Color class and color type
1248
+ * TODO: For each method a corresponding static method should be created
1249
+ * Like clone can be done by color.clone() OR Color.clone(color)
1250
+ * TODO: Probably as an independent LIB OR add to LIB xyzt (ask @roseckyj)
1251
+ * TODO: !! Transfer back to Collboard (whole directory)
1252
+ * TODO: Maybe [🏌️‍♂️] change ACRY toString => (toHex) toRgb when there will be toRgb and toRgba united
1253
+ * TODO: Convert getters to methods - getters only for values
1254
+ * TODO: Write tests
1255
+ * TODO: Getters for alpha, opacity, transparency, r, b, g, h, s, l, a,...
1256
+ * TODO: [0] Should be fromRgbString and fromRgbaString one or two functions + one or two regex
1257
+ * TODO: Use rgb, rgba, hsl for testing and parsing with the same regex
1258
+ * TODO: Regex for rgb, rgba, hsl does not support all options like deg, rad, turn,...
1259
+ * TODO: Convolution matrix
1260
+ * TODO: Maybe connect with textures
1261
+ */
1262
+
1263
+ /**
1264
+ * Converts HSL values to RGB values
1265
+ *
1266
+ * @param hue [0-1]
1267
+ * @param saturation [0-1]
1268
+ * @param lightness [0-1]
1269
+ * @returns [red, green, blue] [0-255]
1270
+ *
1271
+ * @private util of `@promptbook/color`
1272
+ */
1273
+ function hslToRgb(hue, saturation, lightness) {
1274
+ let red;
1275
+ let green;
1276
+ let blue;
1277
+ if (saturation === 0) {
1278
+ // achromatic
1279
+ red = lightness;
1280
+ green = lightness;
1281
+ blue = lightness;
1282
+ }
1283
+ else {
1284
+ // TODO: Extract to separate function
1285
+ const hue2rgb = (p, q, t) => {
1286
+ if (t < 0)
1287
+ t += 1;
1288
+ if (t > 1)
1289
+ t -= 1;
1290
+ if (t < 1 / 6)
1291
+ return p + (q - p) * 6 * t;
1292
+ if (t < 1 / 2)
1293
+ return q;
1294
+ if (t < 2 / 3)
1295
+ return p + (q - p) * (2 / 3 - t) * 6;
1296
+ return p;
1297
+ };
1298
+ const q = lightness < 0.5 ? lightness * (1 + saturation) : lightness + saturation - lightness * saturation;
1299
+ const p = 2 * lightness - q;
1300
+ red = hue2rgb(p, q, hue + 1 / 3);
1301
+ green = hue2rgb(p, q, hue);
1302
+ blue = hue2rgb(p, q, hue - 1 / 3);
1303
+ }
1304
+ return [Math.round(red * 255), Math.round(green * 255), Math.round(blue * 255)];
1305
+ }
1306
+ /**
1307
+ * TODO: Properly name all used internal variables
1308
+ */
1309
+
1310
+ /**
1311
+ * Converts RGB values to HSL values
1312
+ *
1313
+ * @param red [0-255]
1314
+ * @param green [0-255]
1315
+ * @param blue [0-255]
1316
+ * @returns [hue, saturation, lightness] [0-1]
1317
+ *
1318
+ * @private util of `@promptbook/color`
1319
+ */
1320
+ function rgbToHsl(red, green, blue) {
1321
+ red /= 255;
1322
+ green /= 255;
1323
+ blue /= 255;
1324
+ const max = Math.max(red, green, blue);
1325
+ const min = Math.min(red, green, blue);
1326
+ let hue;
1327
+ let saturation;
1328
+ const lightness = (max + min) / 2;
1329
+ if (max === min) {
1330
+ // achromatic
1331
+ hue = 0;
1332
+ saturation = 0;
1333
+ }
1334
+ else {
1335
+ const d = max - min;
1336
+ saturation = lightness > 0.5 ? d / (2 - max - min) : d / (max + min);
1337
+ switch (max) {
1338
+ case red:
1339
+ hue = (green - blue) / d + (green < blue ? 6 : 0);
1340
+ break;
1341
+ case green:
1342
+ hue = (blue - red) / d + 2;
1343
+ break;
1344
+ case blue:
1345
+ hue = (red - green) / d + 4;
1346
+ break;
1347
+ default:
1348
+ hue = 0;
1349
+ }
1350
+ hue /= 6;
1351
+ }
1352
+ return [hue, saturation, lightness];
1353
+ }
1354
+ /**
1355
+ * TODO: Properly name all used internal variables
1356
+ */
1357
+
1358
+ /**
1359
+ * Makes color transformer which lighten the given color
1360
+ *
1361
+ * @param amount from 0 to 1
1362
+ *
1363
+ * @public exported from `@promptbook/color`
1364
+ */
1365
+ function lighten(amount) {
1366
+ return ({ red, green, blue, alpha }) => {
1367
+ const [h, s, lInitial] = rgbToHsl(red, green, blue);
1368
+ let l = lInitial + amount;
1369
+ l = Math.max(0, Math.min(l, 1)); // Replace lodash clamp with Math.max and Math.min
1370
+ const [r, g, b] = hslToRgb(h, s, l);
1371
+ return Color.fromValues(r, g, b, alpha);
1372
+ };
1373
+ }
1374
+ /**
1375
+ * TODO: Maybe implement by mix+hsl
1376
+ */
1377
+
1378
+ /**
1379
+ * Calculates distance between two colors
1380
+ *
1381
+ * @param color1 first color
1382
+ * @param color2 second color
1383
+ *
1384
+ * Note: This function is inefficient. Use colorDistanceSquared instead if possible.
1385
+ *
1386
+ * @public exported from `@promptbook/color`
1387
+ */
1388
+ /**
1389
+ * Calculates distance between two colors without square root
1390
+ *
1391
+ * @param color1 first color
1392
+ * @param color2 second color
1393
+ *
1394
+ * @public exported from `@promptbook/color`
1395
+ */
1396
+ function colorDistanceSquared(color1, color2) {
1397
+ const rmean = (color1.red + color2.red) / 2;
1398
+ const r = color1.red - color2.red;
1399
+ const g = color1.green - color2.green;
1400
+ const b = color1.blue - color2.blue;
1401
+ const weightR = 2 + rmean / 256;
1402
+ const weightG = 4.0;
1403
+ const weightB = 2 + (255 - rmean) / 256;
1404
+ const distance = weightR * r * r + weightG * g * g + weightB * b * b;
1405
+ return distance;
1406
+ }
1407
+
1408
+ /**
1409
+ * Makes color transformer which finds the nearest color from the given list
1410
+ *
1411
+ * @param colors array of colors to choose from
1412
+ *
1413
+ * @public exported from `@promptbook/color`
1414
+ */
1415
+ function nearest(...colors) {
1416
+ return (color) => {
1417
+ const distances = colors.map((c) => colorDistanceSquared(c, color));
1418
+ const minDistance = Math.min(...distances);
1419
+ const minIndex = distances.indexOf(minDistance);
1420
+ const nearestColor = colors[minIndex];
1421
+ return nearestColor;
1422
+ };
1423
+ }
1424
+
1425
+ /**
1426
+ * Color transformer which returns the negative color
1427
+ *
1428
+ * @public exported from `@promptbook/color`
1429
+ */
1430
+ function negative(color) {
1431
+ const r = 255 - color.red;
1432
+ const g = 255 - color.green;
1433
+ const b = 255 - color.blue;
1434
+ return Color.fromValues(r, g, b, color.alpha);
1435
+ }
1436
+
1437
+ /**
1438
+ * Makes color transformer which finds the furthest color from the given list
1439
+ *
1440
+ * @param colors array of colors to choose from
1441
+ *
1442
+ * @public exported from `@promptbook/color`
1443
+ */
1444
+ function furthest(...colors) {
1445
+ return (color) => {
1446
+ const furthestColor = negative(nearest(...colors.map(negative))(color));
1447
+ return furthestColor;
1448
+ };
1449
+ }
1450
+ /**
1451
+ * Makes color transformer which finds the best text color (black or white) for the given background color
1452
+ *
1453
+ * @public exported from `@promptbook/color`
1454
+ */
1455
+ furthest(Color.get('white'), Color.from('black'));
1456
+
1457
+ /**
1458
+ * Makes color transformer which returns a grayscale version of the color
1459
+ *
1460
+ * @param amount from 0 to 1
1461
+ *
1462
+ * @public exported from `@promptbook/color`
1463
+ */
1464
+ function grayscale(amount) {
1465
+ return ({ red, green, blue, alpha }) => {
1466
+ const average = (red + green + blue) / 3;
1467
+ red = Math.round(average * amount + red * (1 - amount));
1468
+ green = Math.round(average * amount + green * (1 - amount));
1469
+ blue = Math.round(average * amount + blue * (1 - amount));
1470
+ return Color.fromValues(red, green, blue, alpha);
1471
+ };
1472
+ }
1473
+
1474
+ /**
1475
+ * Makes color transformer which saturate the given color
1476
+ *
1477
+ * @param amount from -1 to 1
1478
+ *
1479
+ * @public exported from `@promptbook/color`
1480
+ */
1481
+ function saturate(amount) {
1482
+ return ({ red, green, blue, alpha }) => {
1483
+ const [h, sInitial, l] = rgbToHsl(red, green, blue);
1484
+ let s = sInitial + amount;
1485
+ s = Math.max(0, Math.min(s, 1));
1486
+ const [r, g, b] = hslToRgb(h, s, l);
1487
+ return Color.fromValues(r, g, b, alpha);
1488
+ };
1489
+ }
1490
+ /**
1491
+ * TODO: Maybe implement by mix+hsl
1492
+ */
1493
+
605
1494
  /**
606
1495
  * Name for the Promptbook
607
1496
  *
@@ -622,6 +1511,32 @@ const ADMIN_EMAIL = 'pavol@ptbk.io';
622
1511
  * @public exported from `@promptbook/core`
623
1512
  */
624
1513
  const ADMIN_GITHUB_NAME = 'hejny';
1514
+ // <- TODO: [🐊] Pick the best claim
1515
+ /**
1516
+ * Color of the Promptbook
1517
+ *
1518
+ * TODO: [🗽] Unite branding and make single place for it
1519
+ *
1520
+ * @public exported from `@promptbook/core`
1521
+ */
1522
+ const PROMPTBOOK_COLOR = Color.fromHex('#79EAFD');
1523
+ // <- TODO: [🧠] Using `Color` here increases the package size approx 3kb, maybe remove it
1524
+ /**
1525
+ * Dark color of the Promptbook
1526
+ *
1527
+ * TODO: [🗽] Unite branding and make single place for it
1528
+ *
1529
+ * @public exported from `@promptbook/core`
1530
+ */
1531
+ PROMPTBOOK_COLOR.then(lighten(0.1)).then(saturate(0.9)).then(grayscale(0.9));
1532
+ /**
1533
+ * Color of the user (in chat)
1534
+ *
1535
+ * TODO: [🗽] Unite branding and make single place for it
1536
+ *
1537
+ * @public exported from `@promptbook/core`
1538
+ */
1539
+ Color.fromHex('#1D4ED8');
625
1540
  // <- TODO: [🧠] Better system for generator warnings - not always "code" and "by `@promptbook/cli`"
626
1541
  /**
627
1542
  * The maximum number of iterations for a loops
@@ -1307,16 +2222,21 @@ function createExecutionToolsFromVercelProvider(options) {
1307
2222
  ...additionalChatSettings,
1308
2223
  });
1309
2224
  const rawPromptContent = templateParameters(content, { ...parameters, modelName });
1310
- const rawRequest = {
1311
- // <- TODO: [☂]
1312
- inputFormat: 'messages',
1313
- mode: {
1314
- type: 'regular',
1315
- tools: [
1316
- /* <- TODO: Pass the tools */
2225
+ // Support for passing a chat thread (multi-message conversation)
2226
+ let promptMessages;
2227
+ if ('thread' in prompt && Array.isArray(prompt.thread)) {
2228
+ promptMessages = prompt.thread.map((msg) => ({
2229
+ role: msg.role === 'assistant' ? 'assistant' : (msg.role === 'system' ? 'system' : 'user'),
2230
+ content: [
2231
+ {
2232
+ type: 'text',
2233
+ text: msg.content,
2234
+ },
1317
2235
  ],
1318
- },
1319
- prompt: [
2236
+ }));
2237
+ }
2238
+ else {
2239
+ promptMessages = [
1320
2240
  ...(modelRequirements.systemMessage === undefined
1321
2241
  ? []
1322
2242
  : [
@@ -1334,7 +2254,18 @@ function createExecutionToolsFromVercelProvider(options) {
1334
2254
  },
1335
2255
  ],
1336
2256
  },
1337
- ],
2257
+ ];
2258
+ }
2259
+ const rawRequest = {
2260
+ // <- TODO: [☂]
2261
+ inputFormat: 'messages',
2262
+ mode: {
2263
+ type: 'regular',
2264
+ tools: [
2265
+ /* <- TODO: Pass the tools */
2266
+ ],
2267
+ },
2268
+ prompt: promptMessages,
1338
2269
  };
1339
2270
  const start = $getCurrentDate();
1340
2271
  if (options.isVerbose) {