@promptbook/node 0.65.0-7 → 0.66.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 (28) hide show
  1. package/esm/index.es.js +89 -60
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/src/_packages/utils.index.d.ts +10 -8
  4. package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +0 -1
  5. package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionToolsOptions.d.ts +0 -2
  6. package/esm/typings/src/llm-providers/anthropic-claude/anthropic-claude-models.d.ts +2 -2
  7. package/esm/typings/src/llm-providers/anthropic-claude/createAnthropicClaudeExecutionTools.d.ts +3 -2
  8. package/esm/typings/src/llm-providers/anthropic-claude/playground/playground.d.ts +1 -1
  9. package/esm/typings/src/llm-providers/mocked/fakeTextToExpectations.d.ts +1 -0
  10. package/esm/typings/src/llm-providers/multiple/joinLlmExecutionTools.d.ts +1 -1
  11. package/esm/typings/src/llm-providers/openai/openai-models.d.ts +2 -1
  12. package/esm/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +0 -1
  13. package/esm/typings/src/llm-providers/remote/interfaces/RemoteLlmExecutionToolsOptions.d.ts +0 -3
  14. package/esm/typings/src/llm-providers/remote/startRemoteServer.d.ts +0 -1
  15. package/esm/typings/src/utils/currentDate.d.ts +2 -0
  16. package/esm/typings/src/utils/deepFreeze.d.ts +2 -1
  17. package/esm/typings/src/utils/environment/getGlobalScope.d.ts +9 -0
  18. package/esm/typings/src/utils/environment/isRunningInBrowser.d.ts +8 -0
  19. package/esm/typings/src/utils/environment/isRunningInNode.d.ts +8 -0
  20. package/esm/typings/src/utils/environment/isRunningInWebWorker.d.ts +8 -0
  21. package/esm/typings/src/utils/files/isDirectoryExisting.d.ts +3 -1
  22. package/esm/typings/src/utils/files/isFileExisting.d.ts +3 -1
  23. package/esm/typings/src/utils/files/listAllFiles.d.ts +3 -1
  24. package/esm/typings/src/utils/random/randomSeed.d.ts +1 -0
  25. package/package.json +4 -4
  26. package/umd/index.umd.js +89 -60
  27. package/umd/index.umd.js.map +1 -1
  28. package/esm/typings/src/utils/isRunningInWhatever.d.ts +0 -18
package/esm/index.es.js CHANGED
@@ -17,7 +17,7 @@ import OpenAI from 'openai';
17
17
  /**
18
18
  * The version of the Promptbook library
19
19
  */
20
- var PROMPTBOOK_VERSION = '0.65.0-6';
20
+ var PROMPTBOOK_VERSION = '0.65.0';
21
21
  // TODO: !!!! List here all the versions and annotate + put into script
22
22
 
23
23
  /*! *****************************************************************************
@@ -142,12 +142,13 @@ function __spreadArray(to, from, pack) {
142
142
  /**
143
143
  * @@@
144
144
  *
145
+ * Note: `$` is used to indicate that this function is not a pure function - it mutates given object
145
146
  * Note: This function mutates the object and returns the original (but mutated-deep-freezed) object
146
147
  *
147
148
  * @returns The same object as the input, but deeply frozen
148
149
  * @public exported from `@promptbook/utils`
149
150
  */
150
- function deepFreeze(objectValue) {
151
+ function $deepFreeze(objectValue) {
151
152
  var e_1, _a;
152
153
  var propertyNames = Object.getOwnPropertyNames(objectValue);
153
154
  try {
@@ -155,7 +156,7 @@ function deepFreeze(objectValue) {
155
156
  var propertyName = propertyNames_1_1.value;
156
157
  var value = objectValue[propertyName];
157
158
  if (value && typeof value === 'object') {
158
- deepFreeze(value);
159
+ $deepFreeze(value);
159
160
  }
160
161
  }
161
162
  }
@@ -178,7 +179,7 @@ function deepFreeze(objectValue) {
178
179
  * @private this is in comparison to `deepFreeze` a more specific utility and maybe not very good practice to use without specific reason and considerations
179
180
  */
180
181
  function deepFreezeWithSameType(objectValue) {
181
- return deepFreeze(objectValue);
182
+ return $deepFreeze(objectValue);
182
183
  }
183
184
  /**
184
185
  * TODO: [🧠] Is there a way how to meaningfully test this utility
@@ -226,7 +227,7 @@ var REPLACING_NONCE = 'u$k42k%!V2zo34w7Fu#@QUHYPW';
226
227
  *
227
228
  * @public exported from `@promptbook/core`
228
229
  */
229
- var RESERVED_PARAMETER_NAMES = deepFreeze([
230
+ var RESERVED_PARAMETER_NAMES = $deepFreeze([
230
231
  'content',
231
232
  'context',
232
233
  'knowledge',
@@ -524,7 +525,7 @@ function deepClone(objectValue) {
524
525
  *
525
526
  * @public exported from `@promptbook/core`
526
527
  */
527
- var ZERO_USAGE = deepFreeze({
528
+ var ZERO_USAGE = $deepFreeze({
528
529
  price: { value: 0 },
529
530
  input: {
530
531
  tokensCount: { value: 0 },
@@ -692,7 +693,7 @@ function forEachAsync(array, options, callbackfunction) {
692
693
  });
693
694
  }
694
695
 
695
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.65.0-6",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",dependentParameterNames:["knowledgeContent"],resultingParameterName:"knowledgePieces"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",promptbookVersion:"0.65.0-6",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"keywords"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",promptbookVersion:"0.65.0-6",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"title"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",promptbookVersion:"0.65.0-6",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",modelRequirements:{modelVariant:"CHAT",modelName:"gpt-4-turbo"},content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Sample\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n### Option `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Option `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Option `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",expectFormat:"JSON",dependentParameterNames:["availableModelNames","personaDescription"],resultingParameterName:"modelRequirements"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
696
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.65.0",parameters:[{name:"knowledgeContent",description:"Markdown document content",isInput:true,isOutput:false},{name:"knowledgePieces",description:"The knowledge JSON object",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced data researcher, extract the important knowledge from the document.\n\n# Rules\n\n- Make pieces of information concise, clear, and easy to understand\n- One piece of information should be approximately 1 paragraph\n- Divide the paragraphs by markdown horizontal lines ---\n- Omit irrelevant information\n- Group redundant information\n- Write just extracted information, nothing else\n\n# The document\n\nTake information from this document:\n\n> {knowledgeContent}",dependentParameterNames:["knowledgeContent"],resultingParameterName:"knowledgePieces"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",promptbookVersion:"0.65.0",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"keywords",description:"Keywords separated by comma",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced data researcher, detect the important keywords in the document.\n\n# Rules\n\n- Write just keywords separated by comma\n\n# The document\n\nTake information from this document:\n\n> {knowledgePieceContent}",dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"keywords"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",promptbookVersion:"0.65.0",parameters:[{name:"knowledgePieceContent",description:"The content",isInput:true,isOutput:false},{name:"title",description:"The title of the document",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"knowledge",title:"Knowledge",modelRequirements:{modelVariant:"CHAT",modelName:"claude-3-opus-20240229"},content:"You are experienced content creator, write best title for the document.\n\n# Rules\n\n- Write just title, nothing else\n- Title should be concise and clear\n- Write maximum 5 words for the title\n\n# The document\n\n> {knowledgePieceContent}",expectations:{words:{min:1,max:8}},dependentParameterNames:["knowledgePieceContent"],resultingParameterName:"title"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",promptbookVersion:"0.65.0",parameters:[{name:"availableModelNames",description:"List of available model names separated by comma (,)",isInput:true,isOutput:false},{name:"personaDescription",description:"Description of the persona",isInput:true,isOutput:false},{name:"modelRequirements",description:"Specific requirements for the model",isInput:false,isOutput:true}],promptTemplates:[{blockType:"PROMPT_TEMPLATE",name:"make-model-requirements",title:"Make modelRequirements",modelRequirements:{modelVariant:"CHAT",modelName:"gpt-4-turbo"},content:"You are experienced AI engineer, you need to create virtual assistant.\nWrite\n\n## Sample\n\n```json\n{\n\"modelName\": \"gpt-4o\",\n\"systemMessage\": \"You are experienced AI engineer and helpfull assistant.\",\n\"temperature\": 0.7\n}\n```\n\n## Instructions\n\n### Option `modelName`\n\nPick from the following models:\n\n- {availableModelNames}\n\n### Option `systemMessage`\n\nThe system message is used to communicate instructions or provide context to the model at the beginning of a conversation. It is displayed in a different format compared to user messages, helping the model understand its role in the conversation. The system message typically guides the model's behavior, sets the tone, or specifies desired output from the model. By utilizing the system message effectively, users can steer the model towards generating more accurate and relevant responses.\n\nFor example:\n\n> You are an experienced AI engineer and helpful assistant.\n\n> You are a friendly and knowledgeable chatbot.\n\n### Option `temperature`\n\nThe sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit.\n\nYou can pick a value between 0 and 2. For example:\n\n- `0.1`: Low temperature, extremely conservative and deterministic\n- `0.5`: Medium temperature, balanced between conservative and creative\n- `1.0`: High temperature, creative and bit random\n- `1.5`: Very high temperature, extremely creative and often chaotic and unpredictable\n- `2.0`: Maximum temperature, completely random and unpredictable, for some extreme creative use cases\n\n# The assistant\n\nTake this description of the persona:\n\n> {personaDescription}",expectFormat:"JSON",dependentParameterNames:["availableModelNames","personaDescription"],resultingParameterName:"modelRequirements"}],knowledgeSources:[],knowledgePieces:[],personas:[],preparations:[],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
696
697
 
697
698
  /**
698
699
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
@@ -2797,20 +2798,20 @@ function createPipelineExecutor(options) {
2797
2798
  case 'EMBEDDING': return [3 /*break*/, 12];
2798
2799
  }
2799
2800
  return [3 /*break*/, 14];
2800
- case 8: return [4 /*yield*/, llmTools.callChatModel(deepFreeze(prompt))];
2801
+ case 8: return [4 /*yield*/, llmTools.callChatModel($deepFreeze(prompt))];
2801
2802
  case 9:
2802
2803
  chatResult = _u.sent();
2803
2804
  // TODO: [🍬] Destroy chatThread
2804
2805
  result = chatResult;
2805
2806
  resultString = chatResult.content;
2806
2807
  return [3 /*break*/, 15];
2807
- case 10: return [4 /*yield*/, llmTools.callCompletionModel(deepFreeze(prompt))];
2808
+ case 10: return [4 /*yield*/, llmTools.callCompletionModel($deepFreeze(prompt))];
2808
2809
  case 11:
2809
2810
  completionResult = _u.sent();
2810
2811
  result = completionResult;
2811
2812
  resultString = completionResult.content;
2812
2813
  return [3 /*break*/, 15];
2813
- case 12: return [4 /*yield*/, llmTools.callEmbeddingModel(deepFreeze(prompt))];
2814
+ case 12: return [4 /*yield*/, llmTools.callEmbeddingModel($deepFreeze(prompt))];
2814
2815
  case 13:
2815
2816
  embeddingResult = _u.sent();
2816
2817
  result = embeddingResult;
@@ -2838,7 +2839,7 @@ function createPipelineExecutor(options) {
2838
2839
  _u.label = 19;
2839
2840
  case 19:
2840
2841
  _u.trys.push([19, 21, , 22]);
2841
- return [4 /*yield*/, scriptTools.execute(deepFreeze({
2842
+ return [4 /*yield*/, scriptTools.execute($deepFreeze({
2842
2843
  scriptLanguage: currentTemplate.contentLanguage,
2843
2844
  script: preparedContent,
2844
2845
  parameters: parameters,
@@ -2886,7 +2887,7 @@ function createPipelineExecutor(options) {
2886
2887
  if (tools.userInterface === undefined) {
2887
2888
  throw new PipelineExecutionError('User interface tools are not available');
2888
2889
  }
2889
- return [4 /*yield*/, tools.userInterface.promptDialog(deepFreeze({
2890
+ return [4 /*yield*/, tools.userInterface.promptDialog($deepFreeze({
2890
2891
  promptTitle: currentTemplate.title,
2891
2892
  promptMessage: replaceParameters(currentTemplate.description || '', parameters),
2892
2893
  defaultValue: replaceParameters(preparedContent, parameters),
@@ -3681,7 +3682,9 @@ function prepareTemplates(pipeline, options) {
3681
3682
  promptTemplates = pipeline.promptTemplates, parameters = pipeline.parameters, knowledgePiecesCount = pipeline.knowledgePiecesCount;
3682
3683
  // TODO: !!!!! Apply samples to each template (if missing and is for the template defined)
3683
3684
  TODO_USE(parameters);
3684
- promptTemplatesPrepared = new Array(promptTemplates.length);
3685
+ promptTemplatesPrepared = new Array(
3686
+ // <- TODO: [🧱] Implement in a functional (not new Class) way
3687
+ promptTemplates.length);
3685
3688
  return [4 /*yield*/, forEachAsync(promptTemplates, { maxParallelCount: maxParallelCount /* <- TODO: [🪂] When there are subtasks, this maximul limit can be broken */ }, function (template, index) { return __awaiter(_this, void 0, void 0, function () {
3686
3689
  var dependentParameterNames, preparedContent, preparedTemplate;
3687
3690
  return __generator(this, function (_a) {
@@ -3754,7 +3757,9 @@ function preparePipeline(pipeline, options) {
3754
3757
  // <- TODO: [🧊]
3755
3758
  currentPreparation,
3756
3759
  ];
3757
- preparedPersonas = new Array(personas.length);
3760
+ preparedPersonas = new Array(
3761
+ // <- TODO: [🧱] Implement in a functional (not new Class) way
3762
+ personas.length);
3758
3763
  return [4 /*yield*/, forEachAsync(personas, { maxParallelCount: maxParallelCount /* <- TODO: [🪂] When there are subtasks, this maximul limit can be broken */ }, function (persona, index) { return __awaiter(_this, void 0, void 0, function () {
3759
3764
  var modelRequirements, preparedPersona;
3760
3765
  return __generator(this, function (_a) {
@@ -5831,12 +5836,23 @@ var CollectionError = /** @class */ (function (_super) {
5831
5836
  return CollectionError;
5832
5837
  }(Error));
5833
5838
 
5839
+ /**
5840
+ * Detects if the code is running in a Node.js environment
5841
+ *
5842
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
5843
+ *
5844
+ * @public exported from `@promptbook/utils`
5845
+ */
5846
+ var $isRunningInNode = new Function("\n try {\n return this === global;\n } catch (e) {\n return false;\n }\n");
5847
+
5834
5848
  /**
5835
5849
  * Checks if the file exists
5836
5850
  *
5851
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the filesystem
5852
+ *
5837
5853
  * @private within the repository
5838
5854
  */
5839
- function isFileExisting(filePath) {
5855
+ function $isFileExisting(filePath) {
5840
5856
  return __awaiter(this, void 0, void 0, function () {
5841
5857
  var isReadAccessAllowed, isFile;
5842
5858
  return __generator(this, function (_a) {
@@ -5868,9 +5884,11 @@ function isFileExisting(filePath) {
5868
5884
  /**
5869
5885
  * Checks if the directory exists
5870
5886
  *
5887
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the filesystem
5888
+ *
5871
5889
  * @private within the repository
5872
5890
  */
5873
- function isDirectoryExisting(directoryPath) {
5891
+ function $isDirectoryExisting(directoryPath) {
5874
5892
  return __awaiter(this, void 0, void 0, function () {
5875
5893
  var isReadAccessAllowed, isDirectory;
5876
5894
  return __generator(this, function (_a) {
@@ -5903,18 +5921,20 @@ function isDirectoryExisting(directoryPath) {
5903
5921
  /**
5904
5922
  * Reads all files in the directory
5905
5923
  *
5924
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the filesystem
5925
+ *
5906
5926
  * @param path
5907
5927
  * @param isRecursive
5908
5928
  * @returns List of all files in the directory
5909
5929
  * @private internal function of `createCollectionFromDirectory`
5910
5930
  */
5911
- function listAllFiles(path, isRecursive) {
5931
+ function $listAllFiles(path, isRecursive) {
5912
5932
  return __awaiter(this, void 0, void 0, function () {
5913
5933
  var dirents, fileNames, _a, _b, dirent, subPath, _c, _d, _e, _f, e_1_1;
5914
5934
  var e_1, _g;
5915
5935
  return __generator(this, function (_h) {
5916
5936
  switch (_h.label) {
5917
- case 0: return [4 /*yield*/, isDirectoryExisting(path)];
5937
+ case 0: return [4 /*yield*/, $isDirectoryExisting(path)];
5918
5938
  case 1:
5919
5939
  if (!(_h.sent())) {
5920
5940
  throw new Error("Directory \"".concat(path, "\" does not exist or is not readable"));
@@ -5942,7 +5962,7 @@ function listAllFiles(path, isRecursive) {
5942
5962
  _d = (_c = fileNames.push).apply;
5943
5963
  _e = [fileNames];
5944
5964
  _f = [[]];
5945
- return [4 /*yield*/, listAllFiles(subPath, isRecursive)];
5965
+ return [4 /*yield*/, $listAllFiles(subPath, isRecursive)];
5946
5966
  case 5:
5947
5967
  _d.apply(_c, _e.concat([__spreadArray.apply(void 0, _f.concat([__read.apply(void 0, [(_h.sent())]), false]))]));
5948
5968
  _h.label = 6;
@@ -5970,25 +5990,6 @@ function listAllFiles(path, isRecursive) {
5970
5990
  * TODO: [🖇] What about symlinks?
5971
5991
  */
5972
5992
 
5973
- /**
5974
- * Detects if the code is running in a browser environment in main thread (Not in a web worker)
5975
- *
5976
- * @public exported from `@promptbook/utils`
5977
- */
5978
- new Function("\n try {\n return this === window;\n } catch (e) {\n return false;\n }\n");
5979
- /**
5980
- * Detects if the code is running in a Node.js environment
5981
- *
5982
- * @public exported from `@promptbook/utils`
5983
- */
5984
- var isRunningInNode = new Function("\n try {\n return this === global;\n } catch (e) {\n return false;\n }\n");
5985
- /**
5986
- * Detects if the code is running in a web worker
5987
- *
5988
- * @public exported from `@promptbook/utils`
5989
- */
5990
- new Function("\n try {\n if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {\n return true;\n } else {\n return false;\n }\n } catch (e) {\n return false;\n }\n");
5991
-
5992
5993
  /**
5993
5994
  * Constructs Promptbook from async sources
5994
5995
  * It can be one of the following:
@@ -6093,11 +6094,11 @@ function createCollectionFromDirectory(path, options) {
6093
6094
  return __generator(this, function (_f) {
6094
6095
  switch (_f.label) {
6095
6096
  case 0:
6096
- if (!isRunningInNode()) {
6097
+ if (!$isRunningInNode()) {
6097
6098
  throw new Error('Function `createCollectionFromDirectory` can only be run in Node.js environment because it reads the file system.');
6098
6099
  }
6099
6100
  makedLibraryFilePath = join$1(path, "".concat(PIPELINE_COLLECTION_BASE_FILENAME, ".json"));
6100
- return [4 /*yield*/, isFileExisting(makedLibraryFilePath)];
6101
+ return [4 /*yield*/, $isFileExisting(makedLibraryFilePath)];
6101
6102
  case 1:
6102
6103
  if (!(_f.sent())) {
6103
6104
  console.info(colors.yellow("Tip: Prebuild your pipeline collection (file with supposed prebuild ".concat(makedLibraryFilePath, " not found) with CLI util \"ptbk make\" to speed up the collection creation.")));
@@ -6117,7 +6118,7 @@ function createCollectionFromDirectory(path, options) {
6117
6118
  if (isVerbose) {
6118
6119
  console.info(colors.cyan("Creating pipeline collection from path ".concat(path.split('\\').join('/'))));
6119
6120
  }
6120
- return [4 /*yield*/, listAllFiles(path, isRecursive)];
6121
+ return [4 /*yield*/, $listAllFiles(path, isRecursive)];
6121
6122
  case 1:
6122
6123
  fileNames = _b.sent();
6123
6124
  // Note: First load all .ptbk.json and then .ptbk.md files
@@ -6295,7 +6296,7 @@ var EnvironmentMismatchError = /** @class */ (function (_super) {
6295
6296
  * @public exported from `@promptbook/node`
6296
6297
  */
6297
6298
  function createLlmToolsFromConfigurationFromEnv() {
6298
- if (!isRunningInNode()) {
6299
+ if (!$isRunningInNode()) {
6299
6300
  throw new EnvironmentMismatchError('Function `createLlmToolsFromEnv` works only in Node.js environment');
6300
6301
  }
6301
6302
  dotenv.config();
@@ -6366,7 +6367,9 @@ var RemoteLlmExecutionTools = /** @class */ (function () {
6366
6367
  */
6367
6368
  RemoteLlmExecutionTools.prototype.makeConnection = function () {
6368
6369
  var _this = this;
6369
- return new Promise(function (resolve, reject) {
6370
+ return new Promise(
6371
+ // <- TODO: [🧱] Implement in a functional (not new Class) way
6372
+ function (resolve, reject) {
6370
6373
  var socket = io(_this.options.remoteUrl, {
6371
6374
  path: _this.options.path,
6372
6375
  // path: `${this.remoteUrl.pathname}/socket.io`,
@@ -6469,7 +6472,6 @@ var RemoteLlmExecutionTools = /** @class */ (function () {
6469
6472
  return RemoteLlmExecutionTools;
6470
6473
  }());
6471
6474
  /**
6472
- * TODO: [🍜] !!!!!! Default remote remoteUrl and path for anonymous server
6473
6475
  * TODO: [🍓] Allow to list compatible models with each variant
6474
6476
  * TODO: [🗯] RemoteLlmExecutionTools should extend Destroyable and implement IDestroyable
6475
6477
  * TODO: [🧠][🌰] Allow to pass `title` for tracking purposes
@@ -6489,12 +6491,21 @@ function computeUsage(value) {
6489
6491
  /**
6490
6492
  * List of available Anthropic Claude models with pricing
6491
6493
  *
6492
- * Note: Done at 2024-05-25
6494
+ * Note: Done at 2024-08-16
6493
6495
  *
6494
6496
  * @see https://docs.anthropic.com/en/docs/models-overview
6495
6497
  * @public exported from `@promptbook/anthropic-claude`
6496
6498
  */
6497
6499
  var ANTHROPIC_CLAUDE_MODELS = [
6500
+ {
6501
+ modelVariant: 'CHAT',
6502
+ modelTitle: 'Claude 3.5 Sonnet',
6503
+ modelName: 'claude-3-5-sonnet-20240620',
6504
+ pricing: {
6505
+ prompt: computeUsage("$3.00 / 1M tokens"),
6506
+ output: computeUsage("$15.00 / 1M tokens"),
6507
+ },
6508
+ },
6498
6509
  {
6499
6510
  modelVariant: 'CHAT',
6500
6511
  modelTitle: 'Claude 3 Opus',
@@ -6556,7 +6567,7 @@ var ANTHROPIC_CLAUDE_MODELS = [
6556
6567
  * TODO: [🧠] !!! Add embedding models OR Anthropic has only chat+completion models?
6557
6568
  * TODO: [🧠] Some mechanism to propagate unsureness
6558
6569
  * TODO: [🧠][👮‍♀️] Put here more info like description, isVision, trainingDateCutoff, languages, strengths ( Top-level performance, intelligence, fluency, and understanding), contextWindow,...
6559
- * TODO: [🕚] Make this list dynamic - dynamically can be listed modelNames but not modelVariant, legacy status, context length and pricing
6570
+ * TODO: [🎰] Some mechanism to auto-update available models
6560
6571
  */
6561
6572
 
6562
6573
  /**
@@ -6620,7 +6631,9 @@ var AnthropicClaudeExecutionTools = /** @class */ (function () {
6620
6631
  var anthropicOptions = __assign({}, options);
6621
6632
  delete anthropicOptions.isVerbose;
6622
6633
  delete anthropicOptions.isProxied;
6623
- this.client = new Anthropic(anthropicOptions);
6634
+ this.client = new Anthropic(
6635
+ // <- TODO: [🧱] Implement in a functional (not new Class) way
6636
+ anthropicOptions);
6624
6637
  }
6625
6638
  Object.defineProperty(AnthropicClaudeExecutionTools.prototype, "title", {
6626
6639
  get: function () {
@@ -6641,7 +6654,7 @@ var AnthropicClaudeExecutionTools = /** @class */ (function () {
6641
6654
  */
6642
6655
  AnthropicClaudeExecutionTools.prototype.callChatModel = function (prompt) {
6643
6656
  return __awaiter(this, void 0, void 0, function () {
6644
- var content, parameters, modelRequirements, modelName, rawPromptContent, rawRequest, start, complete, rawResponse, resultContent, usage;
6657
+ var content, parameters, modelRequirements, modelName, rawPromptContent, rawRequest, start, complete, rawResponse, contentBlock, resultContent, usage;
6645
6658
  return __generator(this, function (_a) {
6646
6659
  switch (_a.label) {
6647
6660
  case 0:
@@ -6687,11 +6700,16 @@ var AnthropicClaudeExecutionTools = /** @class */ (function () {
6687
6700
  if (rawResponse.content.length > 1) {
6688
6701
  throw new PipelineExecutionError('More than one content blocks from Anthropic Claude');
6689
6702
  }
6690
- resultContent = rawResponse.content[0].text;
6703
+ contentBlock = rawResponse.content[0];
6704
+ if (contentBlock.type !== 'text') {
6705
+ throw new PipelineExecutionError("Returned content is not \"text\" type but \"".concat(contentBlock.type, "\""));
6706
+ }
6707
+ console.log('!!!!!! rawResponse.usage', rawResponse.usage);
6708
+ resultContent = contentBlock.text;
6691
6709
  // eslint-disable-next-line prefer-const
6692
6710
  complete = getCurrentIsoDate();
6693
6711
  usage = {
6694
- price: { value: 0, isUncertain: true } /* <- TODO: [🐞] Compute usage */,
6712
+ price: { value: 0, isUncertain: true } /* <- TODO: [🐞] !!!!!! Compute usage */,
6695
6713
  input: __assign({ tokensCount: uncertainNumber(rawResponse.usage.input_tokens) }, computeUsageCounts(prompt.content)),
6696
6714
  output: __assign({ tokensCount: uncertainNumber(rawResponse.usage.output_tokens) }, computeUsageCounts(prompt.content)),
6697
6715
  };
@@ -6822,7 +6840,6 @@ var AnthropicClaudeExecutionTools = /** @class */ (function () {
6822
6840
  * TODO: Maybe Create some common util for callChatModel and callCompletionModel
6823
6841
  * TODO: Maybe make custom OpenaiError
6824
6842
  * TODO: [🧠][🈁] Maybe use `isDeterministic` from options
6825
- * TODO: [🍜] !!!!!! Auto use anonymous server in browser
6826
6843
  * TODO: [🧠][🌰] Allow to pass `title` for tracking purposes
6827
6844
  * TODO: [📅] Maybe instead of `RemoteLlmExecutionToolsOptions` use `proxyWithAnonymousRemoteServer` (if implemented)
6828
6845
  */
@@ -6843,11 +6860,14 @@ function createAnthropicClaudeExecutionTools(options) {
6843
6860
  },
6844
6861
  ], models: ANTHROPIC_CLAUDE_MODELS }));
6845
6862
  }
6846
- return new AnthropicClaudeExecutionTools(options);
6863
+ return new AnthropicClaudeExecutionTools(
6864
+ // <- TODO: [🧱] Implement in a functional (not new Class) way
6865
+ options);
6847
6866
  }
6848
6867
  /**
6849
- * TODO: !!!!!! Make this with all LLM providers
6850
- * TODO: !!!!!! Maybe change all `new AnthropicClaudeExecutionTools` -> `createAnthropicClaudeExecutionTools` in manual
6868
+ * TODO: [🧠] !!!! Make anonymous this with all LLM providers
6869
+ * TODO: [🧠] !!!! Maybe change all `new AnthropicClaudeExecutionTools` -> `createAnthropicClaudeExecutionTools` in manual
6870
+ * TODO: [🧠] Maybe auto-detect usage in browser and determine default value of `isProxied`
6851
6871
  */
6852
6872
 
6853
6873
  /**
@@ -7191,7 +7211,8 @@ var OPENAI_MODELS = [
7191
7211
  /**
7192
7212
  * Note: [🤖] Add models of new variant
7193
7213
  * TODO: [🧠] Some mechanism to propagate unsureness
7194
- * TODO: [🕚][👮‍♀️] Make this list dynamic - dynamically can be listed modelNames but not modelVariant, legacy status, context length and pricing
7214
+ * TODO: [🎰] Some mechanism to auto-update available models
7215
+ * TODO: [🎰][👮‍♀️] Make this list dynamic - dynamically can be listed modelNames but not modelVariant, legacy status, context length and pricing
7195
7216
  * TODO: [🧠][👮‍♀️] Put here more info like description, isVision, trainingDateCutoff, languages, strengths ( Top-level performance, intelligence, fluency, and understanding), contextWindow,...
7196
7217
  * @see https://platform.openai.com/docs/models/gpt-4-turbo-and-gpt-4
7197
7218
  * @see https://openai.com/api/pricing/
@@ -7214,7 +7235,11 @@ var AzureOpenAiExecutionTools = /** @class */ (function () {
7214
7235
  */
7215
7236
  function AzureOpenAiExecutionTools(options) {
7216
7237
  this.options = options;
7217
- this.client = new OpenAIClient("https://".concat(options.resourceName, ".openai.azure.com/"), new AzureKeyCredential(options.apiKey));
7238
+ this.client = new OpenAIClient(
7239
+ // <- TODO: [🧱] Implement in a functional (not new Class) way
7240
+ "https://".concat(options.resourceName, ".openai.azure.com/"), new AzureKeyCredential(
7241
+ // <- TODO: [🧱] Implement in a functional (not new Class) way
7242
+ options.apiKey));
7218
7243
  }
7219
7244
  Object.defineProperty(AzureOpenAiExecutionTools.prototype, "title", {
7220
7245
  get: function () {
@@ -7797,7 +7822,11 @@ var EXECUTION_TOOLS_CLASSES = {
7797
7822
  return new OpenAiExecutionTools(__assign(__assign({}, options), { dangerouslyAllowBrowser: true /* <- TODO: [🧠] !!! Some mechanism for auto-detection of browser, maybe hide in `OpenAiExecutionTools` */ }));
7798
7823
  },
7799
7824
  createAnthropicClaudeExecutionTools: createAnthropicClaudeExecutionTools,
7800
- createAzureOpenAiExecutionTools: function (options) { return new AzureOpenAiExecutionTools(options); },
7825
+ createAzureOpenAiExecutionTools: function (options) {
7826
+ return new AzureOpenAiExecutionTools(
7827
+ // <- TODO: [🧱] Implement in a functional (not new Class) way
7828
+ options);
7829
+ },
7801
7830
  // <- Note: [🦑] Add here new LLM provider
7802
7831
  };
7803
7832
  /**
@@ -7846,7 +7875,7 @@ function createLlmToolsFromConfiguration(configuration, options) {
7846
7875
  */
7847
7876
  function createLlmToolsFromEnv(options) {
7848
7877
  if (options === void 0) { options = {}; }
7849
- if (!isRunningInNode()) {
7878
+ if (!$isRunningInNode()) {
7850
7879
  throw new EnvironmentMismatchError('Function `createLlmToolsFromEnv` works only in Node.js environment');
7851
7880
  }
7852
7881
  var configuration = createLlmToolsFromConfigurationFromEnv();
@@ -7906,7 +7935,7 @@ function nameToSubfolderPath(name) {
7906
7935
  var FilesStorage = /** @class */ (function () {
7907
7936
  function FilesStorage(options) {
7908
7937
  this.options = options;
7909
- if (!isRunningInNode()) {
7938
+ if (!$isRunningInNode()) {
7910
7939
  throw new EnvironmentMismatchError("FilesStorage works only in Node.js environment");
7911
7940
  }
7912
7941
  }
@@ -7929,7 +7958,7 @@ var FilesStorage = /** @class */ (function () {
7929
7958
  switch (_a.label) {
7930
7959
  case 0:
7931
7960
  filename = this.getFilenameForKey(key);
7932
- return [4 /*yield*/, isFileExisting(filename)];
7961
+ return [4 /*yield*/, $isFileExisting(filename)];
7933
7962
  case 1:
7934
7963
  if (!(_a.sent())) {
7935
7964
  return [2 /*return*/, null];