@promptbook/remote-server 0.66.0-0 → 0.66.0-1

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.
package/umd/index.umd.js CHANGED
@@ -16,7 +16,7 @@
16
16
  /**
17
17
  * The version of the Promptbook library
18
18
  */
19
- var PROMPTBOOK_VERSION = '0.65.0';
19
+ var PROMPTBOOK_VERSION = '0.66.0-0';
20
20
  // TODO: !!!! List here all the versions and annotate + put into script
21
21
 
22
22
  /*! *****************************************************************************
@@ -660,6 +660,188 @@
660
660
  * TODO: [🎰] Some mechanism to auto-update available models
661
661
  */
662
662
 
663
+ /**
664
+ * Get current date in ISO 8601 format
665
+ *
666
+ * @private internal utility
667
+ */
668
+ function getCurrentIsoDate() {
669
+ return new Date().toISOString();
670
+ }
671
+
672
+ /**
673
+ * @@@
674
+ *
675
+ * Note: `$` is used to indicate that this function is not a pure function - it mutates given object
676
+ * Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
677
+ *
678
+ * @returns The same object as the input, but deeply frozen
679
+ * @public exported from `@promptbook/utils`
680
+ */
681
+ function $deepFreeze(objectValue) {
682
+ var e_1, _a;
683
+ var propertyNames = Object.getOwnPropertyNames(objectValue);
684
+ try {
685
+ for (var propertyNames_1 = __values(propertyNames), propertyNames_1_1 = propertyNames_1.next(); !propertyNames_1_1.done; propertyNames_1_1 = propertyNames_1.next()) {
686
+ var propertyName = propertyNames_1_1.value;
687
+ var value = objectValue[propertyName];
688
+ if (value && typeof value === 'object') {
689
+ $deepFreeze(value);
690
+ }
691
+ }
692
+ }
693
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
694
+ finally {
695
+ try {
696
+ if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
697
+ }
698
+ finally { if (e_1) throw e_1.error; }
699
+ }
700
+ return Object.freeze(objectValue);
701
+ }
702
+ /**
703
+ * TODO: [🧠] Is there a way how to meaningfully test this utility
704
+ */
705
+
706
+ // <- TODO: [🧠] Better system for generator warnings - not always "code" and "by `@promptbook/cli`"
707
+ /**
708
+ * The maximum number of iterations for a loops
709
+ *
710
+ * @private within the repository - too low-level in comparison with other `MAX_...`
711
+ */
712
+ var LOOP_LIMIT = 1000;
713
+ /**
714
+ * Nonce which is used for replacing things in strings
715
+ *
716
+ * @private within the repository
717
+ */
718
+ var REPLACING_NONCE = 'u$k42k%!V2zo34w7Fu#@QUHYPW';
719
+ /**
720
+ * The names of the parameters that are reserved for special purposes
721
+ *
722
+ * @public exported from `@promptbook/core`
723
+ */
724
+ $deepFreeze([
725
+ 'content',
726
+ 'context',
727
+ 'knowledge',
728
+ 'samples',
729
+ 'modelName',
730
+ 'currentDate',
731
+ // <- TODO: Add more like 'date', 'modelName',...
732
+ // <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
733
+ ]);
734
+ /**
735
+ * @@@
736
+ *
737
+ * @private within the repository
738
+ */
739
+ var RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
740
+ /**
741
+ * @@@
742
+ *
743
+ * @private within the repository
744
+ */
745
+ var RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
746
+ /**
747
+ * TODO: [🧠][🧜‍♂️] Maybe join remoteUrl and path into single value
748
+ */
749
+
750
+ /**
751
+ * This error type indicates that some limit was reached
752
+ *
753
+ * @public exported from `@promptbook/core`
754
+ */
755
+ var LimitReachedError = /** @class */ (function (_super) {
756
+ __extends(LimitReachedError, _super);
757
+ function LimitReachedError(message) {
758
+ var _this = _super.call(this, message) || this;
759
+ _this.name = 'LimitReachedError';
760
+ Object.setPrototypeOf(_this, LimitReachedError.prototype);
761
+ return _this;
762
+ }
763
+ return LimitReachedError;
764
+ }(Error));
765
+
766
+ /**
767
+ * Replaces parameters in template with values from parameters object
768
+ *
769
+ * @param template the template with parameters in {curly} braces
770
+ * @param parameters the object with parameters
771
+ * @returns the template with replaced parameters
772
+ * @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
773
+ * @public exported from `@promptbook/utils`
774
+ */
775
+ function replaceParameters(template, parameters) {
776
+ var e_1, _a;
777
+ try {
778
+ for (var _b = __values(Object.entries(parameters)), _c = _b.next(); !_c.done; _c = _b.next()) {
779
+ var _d = __read(_c.value, 2), parameterName = _d[0], parameterValue = _d[1];
780
+ if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
781
+ throw new UnexpectedError("Parameter {".concat(parameterName, "} has missing value"));
782
+ }
783
+ else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
784
+ // TODO: [🍵]
785
+ throw new UnexpectedError("Parameter {".concat(parameterName, "} is restricted to use"));
786
+ }
787
+ }
788
+ }
789
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
790
+ finally {
791
+ try {
792
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
793
+ }
794
+ finally { if (e_1) throw e_1.error; }
795
+ }
796
+ var replacedTemplate = template;
797
+ var match;
798
+ var loopLimit = LOOP_LIMIT;
799
+ var _loop_1 = function () {
800
+ if (loopLimit-- < 0) {
801
+ throw new LimitReachedError('Loop limit reached during parameters replacement in `replaceParameters`');
802
+ }
803
+ var precol = match.groups.precol;
804
+ var parameterName = match.groups.parameterName;
805
+ if (parameterName === '') {
806
+ return "continue";
807
+ }
808
+ if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
809
+ throw new PipelineExecutionError('Parameter is already opened or not closed');
810
+ }
811
+ if (parameters[parameterName] === undefined) {
812
+ throw new PipelineExecutionError("Parameter {".concat(parameterName, "} is not defined"));
813
+ }
814
+ var parameterValue = parameters[parameterName];
815
+ if (parameterValue === undefined) {
816
+ throw new PipelineExecutionError("Parameter {".concat(parameterName, "} is not defined"));
817
+ }
818
+ parameterValue = parameterValue.toString();
819
+ if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
820
+ parameterValue = parameterValue
821
+ .split('\n')
822
+ .map(function (line, index) { return (index === 0 ? line : "".concat(precol).concat(line)); })
823
+ .join('\n');
824
+ }
825
+ replacedTemplate =
826
+ replacedTemplate.substring(0, match.index + precol.length) +
827
+ parameterValue +
828
+ replacedTemplate.substring(match.index + precol.length + parameterName.length + 2);
829
+ };
830
+ while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
831
+ .exec(replacedTemplate))) {
832
+ _loop_1();
833
+ }
834
+ // [💫] Check if there are parameters that are not closed properly
835
+ if (/{\w+$/.test(replacedTemplate)) {
836
+ throw new PipelineExecutionError('Parameter is not closed');
837
+ }
838
+ // [💫] Check if there are parameters that are not opened properly
839
+ if (/^\w+}/.test(replacedTemplate)) {
840
+ throw new PipelineExecutionError('Parameter is not opened');
841
+ }
842
+ return replacedTemplate;
843
+ }
844
+
663
845
  /**
664
846
  * Counts number of characters in the text
665
847
  *
@@ -1031,183 +1213,42 @@
1031
1213
  }
1032
1214
 
1033
1215
  /**
1034
- * Get current date in ISO 8601 format
1216
+ * Computes the usage of the Anthropic Claude API based on the response from Anthropic Claude
1035
1217
  *
1036
- * @private internal utility
1037
- */
1038
- function getCurrentIsoDate() {
1039
- return new Date().toISOString();
1040
- }
1041
-
1042
- /**
1043
- * @@@
1044
- *
1045
- * Note: `$` is used to indicate that this function is not a pure function - it mutates given object
1046
- * Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
1047
- *
1048
- * @returns The same object as the input, but deeply frozen
1049
- * @public exported from `@promptbook/utils`
1218
+ * @param promptContent The content of the prompt
1219
+ * @param resultContent The content of the result (for embedding prompts or failed prompts pass empty string)
1220
+ * @param rawResponse The raw response from Anthropic Claude API
1221
+ * @throws {PipelineExecutionError} If the usage is not defined in the response from Anthropic Claude
1222
+ * @private internal utility of `AnthropicClaudeExecutionTools`
1050
1223
  */
1051
- function $deepFreeze(objectValue) {
1052
- var e_1, _a;
1053
- var propertyNames = Object.getOwnPropertyNames(objectValue);
1054
- try {
1055
- for (var propertyNames_1 = __values(propertyNames), propertyNames_1_1 = propertyNames_1.next(); !propertyNames_1_1.done; propertyNames_1_1 = propertyNames_1.next()) {
1056
- var propertyName = propertyNames_1_1.value;
1057
- var value = objectValue[propertyName];
1058
- if (value && typeof value === 'object') {
1059
- $deepFreeze(value);
1060
- }
1061
- }
1224
+ function computeAnthropicClaudeUsage(promptContent, // <- Note: Intentionally using [] to access type properties to bring jsdoc from Prompt/PromptResult to consumer
1225
+ resultContent, rawResponse) {
1226
+ var _a, _b;
1227
+ if (rawResponse.usage === undefined) {
1228
+ throw new PipelineExecutionError('The usage is not defined in the response from Anthropic Claude');
1062
1229
  }
1063
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1064
- finally {
1065
- try {
1066
- if (propertyNames_1_1 && !propertyNames_1_1.done && (_a = propertyNames_1.return)) _a.call(propertyNames_1);
1067
- }
1068
- finally { if (e_1) throw e_1.error; }
1230
+ if (((_a = rawResponse.usage) === null || _a === void 0 ? void 0 : _a.input_tokens) === undefined) {
1231
+ throw new PipelineExecutionError('In Anthropic Claude response `usage.prompt_tokens` not defined');
1069
1232
  }
1070
- return Object.freeze(objectValue);
1071
- }
1072
- /**
1073
- * TODO: [🧠] Is there a way how to meaningfully test this utility
1074
- */
1075
-
1076
- // <- TODO: [🧠] Better system for generator warnings - not always "code" and "by `@promptbook/cli`"
1077
- /**
1078
- * The maximum number of iterations for a loops
1079
- *
1080
- * @private within the repository - too low-level in comparison with other `MAX_...`
1081
- */
1082
- var LOOP_LIMIT = 1000;
1083
- /**
1084
- * Nonce which is used for replacing things in strings
1085
- *
1086
- * @private within the repository
1087
- */
1088
- var REPLACING_NONCE = 'u$k42k%!V2zo34w7Fu#@QUHYPW';
1089
- /**
1090
- * The names of the parameters that are reserved for special purposes
1091
- *
1092
- * @public exported from `@promptbook/core`
1093
- */
1094
- $deepFreeze([
1095
- 'content',
1096
- 'context',
1097
- 'knowledge',
1098
- 'samples',
1099
- 'modelName',
1100
- 'currentDate',
1101
- // <- TODO: Add more like 'date', 'modelName',...
1102
- // <- TODO: Add [emoji] + instructions ACRY when adding new reserved parameter
1103
- ]);
1104
- /**
1105
- * @@@
1106
- *
1107
- * @private within the repository
1108
- */
1109
- var RESERVED_PARAMETER_MISSING_VALUE = 'MISSING-' + REPLACING_NONCE;
1110
- /**
1111
- * @@@
1112
- *
1113
- * @private within the repository
1114
- */
1115
- var RESERVED_PARAMETER_RESTRICTED = 'RESTRICTED-' + REPLACING_NONCE;
1116
-
1117
- /**
1118
- * This error type indicates that some limit was reached
1119
- *
1120
- * @public exported from `@promptbook/core`
1121
- */
1122
- var LimitReachedError = /** @class */ (function (_super) {
1123
- __extends(LimitReachedError, _super);
1124
- function LimitReachedError(message) {
1125
- var _this = _super.call(this, message) || this;
1126
- _this.name = 'LimitReachedError';
1127
- Object.setPrototypeOf(_this, LimitReachedError.prototype);
1128
- return _this;
1129
- }
1130
- return LimitReachedError;
1131
- }(Error));
1132
-
1133
- /**
1134
- * Replaces parameters in template with values from parameters object
1135
- *
1136
- * @param template the template with parameters in {curly} braces
1137
- * @param parameters the object with parameters
1138
- * @returns the template with replaced parameters
1139
- * @throws {PipelineExecutionError} if parameter is not defined, not closed, or not opened
1140
- * @public exported from `@promptbook/utils`
1141
- */
1142
- function replaceParameters(template, parameters) {
1143
- var e_1, _a;
1144
- try {
1145
- for (var _b = __values(Object.entries(parameters)), _c = _b.next(); !_c.done; _c = _b.next()) {
1146
- var _d = __read(_c.value, 2), parameterName = _d[0], parameterValue = _d[1];
1147
- if (parameterValue === RESERVED_PARAMETER_MISSING_VALUE) {
1148
- throw new UnexpectedError("Parameter {".concat(parameterName, "} has missing value"));
1149
- }
1150
- else if (parameterValue === RESERVED_PARAMETER_RESTRICTED) {
1151
- // TODO: [🍵]
1152
- throw new UnexpectedError("Parameter {".concat(parameterName, "} is restricted to use"));
1153
- }
1154
- }
1233
+ var inputTokens = rawResponse.usage.input_tokens;
1234
+ var outputTokens = ((_b = rawResponse.usage) === null || _b === void 0 ? void 0 : _b.output_tokens) || 0;
1235
+ var modelInfo = ANTHROPIC_CLAUDE_MODELS.find(function (model) { return model.modelName === rawResponse.model; });
1236
+ var price;
1237
+ if (modelInfo === undefined || modelInfo.pricing === undefined) {
1238
+ price = uncertainNumber();
1155
1239
  }
1156
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1157
- finally {
1158
- try {
1159
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
1160
- }
1161
- finally { if (e_1) throw e_1.error; }
1240
+ else {
1241
+ price = uncertainNumber(inputTokens * modelInfo.pricing.prompt + outputTokens * modelInfo.pricing.output);
1162
1242
  }
1163
- var replacedTemplate = template;
1164
- var match;
1165
- var loopLimit = LOOP_LIMIT;
1166
- var _loop_1 = function () {
1167
- if (loopLimit-- < 0) {
1168
- throw new LimitReachedError('Loop limit reached during parameters replacement in `replaceParameters`');
1169
- }
1170
- var precol = match.groups.precol;
1171
- var parameterName = match.groups.parameterName;
1172
- if (parameterName === '') {
1173
- return "continue";
1174
- }
1175
- if (parameterName.indexOf('{') !== -1 || parameterName.indexOf('}') !== -1) {
1176
- throw new PipelineExecutionError('Parameter is already opened or not closed');
1177
- }
1178
- if (parameters[parameterName] === undefined) {
1179
- throw new PipelineExecutionError("Parameter {".concat(parameterName, "} is not defined"));
1180
- }
1181
- var parameterValue = parameters[parameterName];
1182
- if (parameterValue === undefined) {
1183
- throw new PipelineExecutionError("Parameter {".concat(parameterName, "} is not defined"));
1184
- }
1185
- parameterValue = parameterValue.toString();
1186
- if (parameterValue.includes('\n') && /^\s*\W{0,3}\s*$/.test(precol)) {
1187
- parameterValue = parameterValue
1188
- .split('\n')
1189
- .map(function (line, index) { return (index === 0 ? line : "".concat(precol).concat(line)); })
1190
- .join('\n');
1191
- }
1192
- replacedTemplate =
1193
- replacedTemplate.substring(0, match.index + precol.length) +
1194
- parameterValue +
1195
- replacedTemplate.substring(match.index + precol.length + parameterName.length + 2);
1243
+ return {
1244
+ price: price,
1245
+ input: __assign({ tokensCount: uncertainNumber(rawResponse.usage.input_tokens) }, computeUsageCounts(promptContent)),
1246
+ output: __assign({ tokensCount: uncertainNumber(outputTokens) }, computeUsageCounts(resultContent)),
1196
1247
  };
1197
- while ((match = /^(?<precol>.*){(?<parameterName>\w+)}(.*)/m /* <- Not global */
1198
- .exec(replacedTemplate))) {
1199
- _loop_1();
1200
- }
1201
- // [💫] Check if there are parameters that are not closed properly
1202
- if (/{\w+$/.test(replacedTemplate)) {
1203
- throw new PipelineExecutionError('Parameter is not closed');
1204
- }
1205
- // [💫] Check if there are parameters that are not opened properly
1206
- if (/^\w+}/.test(replacedTemplate)) {
1207
- throw new PipelineExecutionError('Parameter is not opened');
1208
- }
1209
- return replacedTemplate;
1210
1248
  }
1249
+ /**
1250
+ * TODO: [🤝] DRY Maybe some common abstraction between `computeOpenaiUsage` and `computeAnthropicClaudeUsage`
1251
+ */
1211
1252
 
1212
1253
  /**
1213
1254
  * Execution Tools for calling Anthropic Claude API.
@@ -1228,9 +1269,8 @@
1228
1269
  var anthropicOptions = __assign({}, options);
1229
1270
  delete anthropicOptions.isVerbose;
1230
1271
  delete anthropicOptions.isProxied;
1231
- this.client = new Anthropic__default["default"](
1232
- // <- TODO: [🧱] Implement in a functional (not new Class) way
1233
- anthropicOptions);
1272
+ this.client = new Anthropic__default["default"](anthropicOptions);
1273
+ // <- TODO: !!!!!! Lazy-load client
1234
1274
  }
1235
1275
  Object.defineProperty(AnthropicClaudeExecutionTools.prototype, "title", {
1236
1276
  get: function () {
@@ -1301,15 +1341,10 @@
1301
1341
  if (contentBlock.type !== 'text') {
1302
1342
  throw new PipelineExecutionError("Returned content is not \"text\" type but \"".concat(contentBlock.type, "\""));
1303
1343
  }
1304
- console.log('!!!!!! rawResponse.usage', rawResponse.usage);
1305
1344
  resultContent = contentBlock.text;
1306
1345
  // eslint-disable-next-line prefer-const
1307
1346
  complete = getCurrentIsoDate();
1308
- usage = {
1309
- price: { value: 0, isUncertain: true } /* <- TODO: [🐞] !!!!!! Compute usage */,
1310
- input: __assign({ tokensCount: uncertainNumber(rawResponse.usage.input_tokens) }, computeUsageCounts(prompt.content)),
1311
- output: __assign({ tokensCount: uncertainNumber(rawResponse.usage.output_tokens) }, computeUsageCounts(prompt.content)),
1312
- };
1347
+ usage = computeAnthropicClaudeUsage(content, '', rawResponse);
1313
1348
  return [2 /*return*/, {
1314
1349
  content: resultContent,
1315
1350
  modelName: rawResponse.model,
@@ -1834,9 +1869,8 @@
1834
1869
  this.options = options;
1835
1870
  this.client = new openai.OpenAIClient(
1836
1871
  // <- TODO: [🧱] Implement in a functional (not new Class) way
1837
- "https://".concat(options.resourceName, ".openai.azure.com/"), new openai.AzureKeyCredential(
1838
- // <- TODO: [🧱] Implement in a functional (not new Class) way
1839
- options.apiKey));
1872
+ "https://".concat(options.resourceName, ".openai.azure.com/"), new openai.AzureKeyCredential(options.apiKey));
1873
+ // <- TODO: !!!!!! Lazy-load client
1840
1874
  }
1841
1875
  Object.defineProperty(AzureOpenAiExecutionTools.prototype, "title", {
1842
1876
  get: function () {
@@ -2106,6 +2140,9 @@
2106
2140
  output: __assign({ tokensCount: uncertainNumber(outputTokens) }, computeUsageCounts(resultContent)),
2107
2141
  };
2108
2142
  }
2143
+ /**
2144
+ * TODO: [🤝] DRY Maybe some common abstraction between `computeOpenaiUsage` and `computeAnthropicClaudeUsage`
2145
+ */
2109
2146
 
2110
2147
  /**
2111
2148
  * Execution Tools for calling OpenAI API.
@@ -2126,6 +2163,7 @@
2126
2163
  delete openAiOptions.isVerbose;
2127
2164
  delete openAiOptions.user;
2128
2165
  this.client = new OpenAI__default["default"](__assign({}, openAiOptions));
2166
+ // <- TODO: !!!!!! Lazy-load client
2129
2167
  }
2130
2168
  Object.defineProperty(OpenAiExecutionTools.prototype, "title", {
2131
2169
  get: function () {
@@ -2427,7 +2465,7 @@
2427
2465
  // <- Note: [🦑] Add here new LLM provider
2428
2466
  };
2429
2467
  /**
2430
- * TODO: [🧠] Better file name than `config.ts` + maybe move to two separate files
2468
+ * TODO: !!!!!!! Make global register for this
2431
2469
  * TODO: [🧠][🎌] Adding this should be responsibility of each provider package NOT this one central place
2432
2470
  */
2433
2471