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