@promptbook/cli 0.61.0 → 0.62.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.
Files changed (55) hide show
  1. package/esm/index.es.js +259 -88
  2. package/esm/index.es.js.map +1 -1
  3. package/esm/typings/promptbook-collection/index.d.ts +3 -3
  4. package/esm/typings/src/_packages/core.index.d.ts +2 -1
  5. package/esm/typings/src/conversion/pipelineJsonToString.d.ts +2 -1
  6. package/esm/typings/src/execution/createPipelineExecutor.d.ts +1 -0
  7. package/esm/typings/src/execution/utils/usageToHuman.d.ts +15 -0
  8. package/esm/typings/src/execution/utils/usageToHuman.test.d.ts +1 -0
  9. package/esm/typings/src/llm-providers/_common/createLlmToolsFromEnv.d.ts +4 -0
  10. package/esm/typings/src/llm-providers/_common/getLlmToolsForCli.d.ts +12 -2
  11. package/esm/typings/src/llm-providers/_common/getLlmToolsForTestingAndScriptsAndPlayground.d.ts +12 -2
  12. package/esm/typings/src/llm-providers/_common/utils/cache/CacheLlmToolsOptions.d.ts +7 -1
  13. package/esm/typings/src/llm-providers/_common/utils/cache/cacheLlmTools.d.ts +7 -4
  14. package/esm/typings/src/llm-providers/_common/utils/count-total-usage/LlmExecutionToolsWithTotalUsage.d.ts +15 -0
  15. package/{umd/typings/src/llm-providers/_common/utils/count-total-cost/countTotalCost.d.ts → esm/typings/src/llm-providers/_common/utils/count-total-usage/countTotalUsage.d.ts} +5 -2
  16. package/esm/typings/src/llm-providers/_common/utils/{count-total-cost/limitTotalCost.d.ts → count-total-usage/limitTotalUsage.d.ts} +8 -5
  17. package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +1 -0
  18. package/esm/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionToolsOptions.d.ts +3 -0
  19. package/esm/typings/src/llm-providers/anthropic-claude/playground/playground.d.ts +1 -0
  20. package/esm/typings/src/llm-providers/multiple/joinLlmExecutionTools.d.ts +3 -0
  21. package/esm/typings/src/llm-providers/openai/computeOpenaiUsage.test.d.ts +1 -0
  22. package/esm/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +2 -1
  23. package/esm/typings/src/llm-providers/remote/interfaces/RemoteServerOptions.d.ts +3 -0
  24. package/esm/typings/src/llm-providers/remote/startRemoteServer.d.ts +1 -0
  25. package/esm/typings/src/prepare/preparePipeline.d.ts +0 -1
  26. package/esm/typings/src/types/PipelineJson/PreparationJson.d.ts +1 -1
  27. package/package.json +4 -4
  28. package/umd/index.umd.js +281 -92
  29. package/umd/index.umd.js.map +1 -1
  30. package/umd/typings/promptbook-collection/index.d.ts +3 -3
  31. package/umd/typings/src/_packages/core.index.d.ts +2 -1
  32. package/umd/typings/src/conversion/pipelineJsonToString.d.ts +2 -1
  33. package/umd/typings/src/execution/createPipelineExecutor.d.ts +1 -0
  34. package/umd/typings/src/execution/utils/usageToHuman.d.ts +15 -0
  35. package/umd/typings/src/execution/utils/usageToHuman.test.d.ts +1 -0
  36. package/umd/typings/src/llm-providers/_common/createLlmToolsFromEnv.d.ts +4 -0
  37. package/umd/typings/src/llm-providers/_common/getLlmToolsForCli.d.ts +12 -2
  38. package/umd/typings/src/llm-providers/_common/getLlmToolsForTestingAndScriptsAndPlayground.d.ts +12 -2
  39. package/umd/typings/src/llm-providers/_common/utils/cache/CacheLlmToolsOptions.d.ts +7 -1
  40. package/umd/typings/src/llm-providers/_common/utils/cache/cacheLlmTools.d.ts +7 -4
  41. package/umd/typings/src/llm-providers/_common/utils/count-total-usage/LlmExecutionToolsWithTotalUsage.d.ts +15 -0
  42. package/{esm/typings/src/llm-providers/_common/utils/count-total-cost/countTotalCost.d.ts → umd/typings/src/llm-providers/_common/utils/count-total-usage/countTotalUsage.d.ts} +5 -2
  43. package/umd/typings/src/llm-providers/_common/utils/{count-total-cost/limitTotalCost.d.ts → count-total-usage/limitTotalUsage.d.ts} +8 -5
  44. package/umd/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +1 -0
  45. package/umd/typings/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionToolsOptions.d.ts +3 -0
  46. package/umd/typings/src/llm-providers/anthropic-claude/playground/playground.d.ts +1 -0
  47. package/umd/typings/src/llm-providers/multiple/joinLlmExecutionTools.d.ts +3 -0
  48. package/umd/typings/src/llm-providers/openai/computeOpenaiUsage.test.d.ts +1 -0
  49. package/umd/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +2 -1
  50. package/umd/typings/src/llm-providers/remote/interfaces/RemoteServerOptions.d.ts +3 -0
  51. package/umd/typings/src/llm-providers/remote/startRemoteServer.d.ts +1 -0
  52. package/umd/typings/src/prepare/preparePipeline.d.ts +0 -1
  53. package/umd/typings/src/types/PipelineJson/PreparationJson.d.ts +1 -1
  54. package/esm/typings/src/llm-providers/_common/utils/count-total-cost/LlmExecutionToolsWithTotalCost.d.ts +0 -11
  55. package/umd/typings/src/llm-providers/_common/utils/count-total-cost/LlmExecutionToolsWithTotalCost.d.ts +0 -11
package/esm/index.es.js CHANGED
@@ -8,6 +8,7 @@ import { format } from 'prettier';
8
8
  import parserHtml from 'prettier/parser-html';
9
9
  import hexEncoder from 'crypto-js/enc-hex';
10
10
  import sha256 from 'crypto-js/sha256';
11
+ import * as dotenv from 'dotenv';
11
12
  import Anthropic from '@anthropic-ai/sdk';
12
13
  import OpenAI from 'openai';
13
14
  import glob from 'glob-promise';
@@ -150,7 +151,7 @@ new Function("\n try {\n if (typeof WorkerGlobalScope !== 'undefined'
150
151
  /**
151
152
  * The version of the Promptbook library
152
153
  */
153
- var PROMPTBOOK_VERSION = '0.61.0-30';
154
+ var PROMPTBOOK_VERSION = '0.62.0-0';
154
155
  // TODO: !!!! List here all the versions and annotate + put into script
155
156
 
156
157
  /**
@@ -552,7 +553,8 @@ function promptTemplateParameterJsonToString(promptTemplateParameterJson) {
552
553
  /**
553
554
  * TODO: !!!! Implement new features and commands into `promptTemplateParameterJsonToString`
554
555
  * TODO: [🧠] Is there a way to auto-detect missing features in pipelineJsonToString
555
- * TODO: Escape all
556
+ * TODO: [🏛] Maybe make some markdown builder
557
+ * TODO: [🏛] Escape all
556
558
  */
557
559
 
558
560
  /**
@@ -747,7 +749,7 @@ function forEachAsync(array, options, callbackfunction) {
747
749
  });
748
750
  }
749
751
 
750
- var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.61.0-30",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:[{id:1,promptbookVersion:"0.61.0-30",modelUsage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",promptbookVersion:"0.61.0-30",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:[{id:1,promptbookVersion:"0.61.0-30",modelUsage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",promptbookVersion:"0.61.0-30",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:[{id:1,promptbookVersion:"0.61.0-30",modelUsage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",promptbookVersion:"0.61.0-30",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:[{id:1,promptbookVersion:"0.61.0-30",modelUsage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
752
+ var PipelineCollection = [{title:"Prepare Knowledge from Markdown",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-from-markdown.ptbk.md",promptbookVersion:"0.62.0-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:[{id:1,promptbookVersion:"0.62.0-0",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-knowledge-from-markdown.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-keywords.ptbk.md",promptbookVersion:"0.62.0-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:[{id:1,promptbookVersion:"0.62.0-0",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-knowledge-keywords.ptbk.md"},{title:"Prepare Title",pipelineUrl:"https://promptbook.studio/promptbook/prepare-knowledge-title.ptbk.md",promptbookVersion:"0.62.0-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:[{id:1,promptbookVersion:"0.62.0-0",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-knowledge-title.ptbk.md"},{title:"Prepare Keywords",pipelineUrl:"https://promptbook.studio/promptbook/prepare-persona.ptbk.md",promptbookVersion:"0.62.0-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:[{id:1,promptbookVersion:"0.62.0-0",usage:{price:{value:0},input:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}},output:{tokensCount:{value:0},charactersCount:{value:0},wordsCount:{value:0},sentencesCount:{value:0},linesCount:{value:0},paragraphsCount:{value:0},pagesCount:{value:0}}}}],sourceFile:"./promptbook-collection/prepare-persona.ptbk.md"}];
751
753
 
752
754
  /**
753
755
  * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
@@ -2126,6 +2128,9 @@ function joinLlmExecutionTools() {
2126
2128
  }
2127
2129
  return new (MultipleLlmExecutionTools.bind.apply(MultipleLlmExecutionTools, __spreadArray([void 0], __read(llmExecutionTools), false)))();
2128
2130
  }
2131
+ /**
2132
+ * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
2133
+ */
2129
2134
 
2130
2135
  /**
2131
2136
  * Determine if the pipeline is fully prepared
@@ -3248,6 +3253,7 @@ function createPipelineExecutor(options) {
3248
3253
  }
3249
3254
  /**
3250
3255
  * TODO: Use isVerbose here (not only pass to `preparePipeline`)
3256
+ * TODO: [🧠] Use here `countTotalUsage` and put preparation and prepared pipiline to report
3251
3257
  * TODO: [🪂] Use maxParallelCount here (not only pass to `preparePipeline`)
3252
3258
  * TODO: [♈] Probbably move expectations from templates to parameters
3253
3259
  * TODO: [🧠] When not meet expectations in PROMPT_DIALOG, make some way to tell the user
@@ -3456,6 +3462,86 @@ TODO: [🧊] This is how it can look in future
3456
3462
  * [ ] One piece can have multiple sources
3457
3463
  */
3458
3464
 
3465
+ /**
3466
+ * Intercepts LLM tools and counts total usage of the tools
3467
+ *
3468
+ * @param llmTools LLM tools to be intercepted with usage counting
3469
+ * @returns LLM tools with same functionality with added total cost counting
3470
+ */
3471
+ function countTotalUsage(llmTools) {
3472
+ var _this = this;
3473
+ var totalUsage = ZERO_USAGE;
3474
+ var proxyTools = {
3475
+ get title() {
3476
+ // TODO: [🧠] Maybe put here some suffix
3477
+ return llmTools.title;
3478
+ },
3479
+ get description() {
3480
+ // TODO: [🧠] Maybe put here some suffix
3481
+ return llmTools.description;
3482
+ },
3483
+ listModels: function () {
3484
+ return /* not await */ llmTools.listModels();
3485
+ },
3486
+ getTotalUsage: function () {
3487
+ // <- Note: [🥫] Not using getter `get totalUsage` but `getTotalUsage` to allow this object to be proxied
3488
+ return totalUsage;
3489
+ },
3490
+ };
3491
+ if (llmTools.callChatModel !== undefined) {
3492
+ proxyTools.callChatModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
3493
+ var promptResult;
3494
+ return __generator(this, function (_a) {
3495
+ switch (_a.label) {
3496
+ case 0: return [4 /*yield*/, llmTools.callChatModel(prompt)];
3497
+ case 1:
3498
+ promptResult = _a.sent();
3499
+ totalUsage = addUsage(totalUsage, promptResult.usage);
3500
+ return [2 /*return*/, promptResult];
3501
+ }
3502
+ });
3503
+ }); };
3504
+ }
3505
+ if (llmTools.callCompletionModel !== undefined) {
3506
+ proxyTools.callCompletionModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
3507
+ var promptResult;
3508
+ return __generator(this, function (_a) {
3509
+ switch (_a.label) {
3510
+ case 0: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
3511
+ case 1:
3512
+ promptResult = _a.sent();
3513
+ totalUsage = addUsage(totalUsage, promptResult.usage);
3514
+ return [2 /*return*/, promptResult];
3515
+ }
3516
+ });
3517
+ }); };
3518
+ }
3519
+ if (llmTools.callEmbeddingModel !== undefined) {
3520
+ proxyTools.callEmbeddingModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
3521
+ var promptResult;
3522
+ return __generator(this, function (_a) {
3523
+ switch (_a.label) {
3524
+ case 0: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
3525
+ case 1:
3526
+ promptResult = _a.sent();
3527
+ totalUsage = addUsage(totalUsage, promptResult.usage);
3528
+ return [2 /*return*/, promptResult];
3529
+ }
3530
+ });
3531
+ }); };
3532
+ }
3533
+ // <- Note: [🤖]
3534
+ return proxyTools;
3535
+ }
3536
+ /**
3537
+ * TODO: [🔼] !!! Export via `@promptbookcore/`
3538
+ * TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
3539
+ * TODO: [🧠] Is there some meaningfull way how to test this util
3540
+ * TODO: [🧠][🌯] Maybe a way how to hide ability to `get totalUsage`
3541
+ * > const [llmToolsWithUsage,getUsage] = countTotalUsage(llmTools);
3542
+ * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
3543
+ */
3544
+
3459
3545
  /**
3460
3546
  * Prepares the persona for the pipeline
3461
3547
  *
@@ -3579,23 +3665,24 @@ function prepareTemplates(pipeline, options) {
3579
3665
  */
3580
3666
  function preparePipeline(pipeline, options) {
3581
3667
  return __awaiter(this, void 0, void 0, function () {
3582
- var _a, maxParallelCount, parameters, promptTemplates,
3668
+ var llmTools, _a, maxParallelCount, _b, isVerbose, parameters, promptTemplates,
3583
3669
  /*
3584
3670
  <- TODO: [🧠][0] `promptbookVersion` */
3585
3671
  knowledgeSources /*
3586
3672
  <- TODO: [🧊] `knowledgePieces` */, personas /*
3587
- <- TODO: [🧊] `preparations` */, currentPreparation, preparations, preparedPersonas, knowledgeSourcesPrepared, partialknowledgePiecesPrepared, knowledgePiecesPrepared, promptTemplatesPrepared /* TODO: parameters: parametersPrepared*/;
3673
+ <- TODO: [🧊] `preparations` */, llmToolsWithUsage, currentPreparation, preparations, preparedPersonas, knowledgeSourcesPrepared, partialknowledgePiecesPrepared, knowledgePiecesPrepared, promptTemplatesPrepared /* TODO: parameters: parametersPrepared*/;
3588
3674
  var _this = this;
3589
- return __generator(this, function (_b) {
3590
- switch (_b.label) {
3675
+ return __generator(this, function (_c) {
3676
+ switch (_c.label) {
3591
3677
  case 0:
3592
- _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a;
3678
+ llmTools = options.llmTools, _a = options.maxParallelCount, maxParallelCount = _a === void 0 ? MAX_PARALLEL_COUNT : _a, _b = options.isVerbose, isVerbose = _b === void 0 ? false : _b;
3593
3679
  parameters = pipeline.parameters, promptTemplates = pipeline.promptTemplates, knowledgeSources = pipeline.knowledgeSources, personas = pipeline.personas;
3680
+ llmToolsWithUsage = countTotalUsage(llmTools);
3594
3681
  currentPreparation = {
3595
3682
  id: 1,
3596
3683
  // TODO: [🍥]> date: $currentDate(),
3597
3684
  promptbookVersion: PROMPTBOOK_VERSION,
3598
- modelUsage: ZERO_USAGE,
3685
+ usage: ZERO_USAGE,
3599
3686
  };
3600
3687
  preparations = [
3601
3688
  // ...preparations
@@ -3607,7 +3694,11 @@ function preparePipeline(pipeline, options) {
3607
3694
  var modelRequirements, preparedPersona;
3608
3695
  return __generator(this, function (_a) {
3609
3696
  switch (_a.label) {
3610
- case 0: return [4 /*yield*/, preparePersona(persona.description, options)];
3697
+ case 0: return [4 /*yield*/, preparePersona(persona.description, {
3698
+ llmTools: llmToolsWithUsage,
3699
+ maxParallelCount: maxParallelCount /* <- TODO: [🪂] */,
3700
+ isVerbose: isVerbose,
3701
+ })];
3611
3702
  case 1:
3612
3703
  modelRequirements = _a.sent();
3613
3704
  preparedPersona = __assign(__assign({}, persona), { modelRequirements: modelRequirements, preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id] });
@@ -3617,20 +3708,30 @@ function preparePipeline(pipeline, options) {
3617
3708
  });
3618
3709
  }); })];
3619
3710
  case 1:
3620
- _b.sent();
3711
+ _c.sent();
3621
3712
  knowledgeSourcesPrepared = knowledgeSources.map(function (source) { return (__assign(__assign({}, source), { preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id] })); });
3622
- return [4 /*yield*/, prepareKnowledgePieces(knowledgeSources /* <- TODO: [🧊] {knowledgeSources, knowledgePieces} */, options)];
3713
+ return [4 /*yield*/, prepareKnowledgePieces(knowledgeSources /* <- TODO: [🧊] {knowledgeSources, knowledgePieces} */, {
3714
+ llmTools: llmToolsWithUsage,
3715
+ maxParallelCount: maxParallelCount /* <- TODO: [🪂] */,
3716
+ isVerbose: isVerbose,
3717
+ })];
3623
3718
  case 2:
3624
- partialknowledgePiecesPrepared = _b.sent();
3719
+ partialknowledgePiecesPrepared = _c.sent();
3625
3720
  knowledgePiecesPrepared = partialknowledgePiecesPrepared.map(function (piece) { return (__assign(__assign({}, piece), { preparationIds: [/* TODO: [🧊] -> */ currentPreparation.id] })); });
3626
3721
  return [4 /*yield*/, prepareTemplates({
3627
3722
  parameters: parameters,
3628
3723
  promptTemplates: promptTemplates,
3629
3724
  knowledgePiecesCount: knowledgePiecesPrepared.length,
3630
- }, options)];
3725
+ }, {
3726
+ llmTools: llmToolsWithUsage,
3727
+ maxParallelCount: maxParallelCount /* <- TODO: [🪂] */,
3728
+ isVerbose: isVerbose,
3729
+ })];
3631
3730
  case 3:
3632
- promptTemplatesPrepared = (_b.sent()).promptTemplatesPrepared;
3731
+ promptTemplatesPrepared = (_c.sent()).promptTemplatesPrepared;
3633
3732
  // ----- /Templates preparation -----
3733
+ // Note: Count total usage
3734
+ currentPreparation.usage = llmToolsWithUsage.getTotalUsage();
3634
3735
  return [2 /*return*/, __assign(__assign({}, pipeline), { promptTemplates: promptTemplatesPrepared, knowledgeSources: knowledgeSourcesPrepared, knowledgePieces: knowledgePiecesPrepared, personas: preparedPersonas, preparations: preparations })];
3635
3736
  }
3636
3737
  });
@@ -3641,7 +3742,6 @@ function preparePipeline(pipeline, options) {
3641
3742
  * TODO: Write tests for `preparePipeline`
3642
3743
  * TODO: [🏏] Leverage the batch API and build queues @see https://platform.openai.com/docs/guides/batch
3643
3744
  * TODO: [🧊] In future one preparation can take data from previous preparation and save tokens and time
3644
- * TODO: [🎐] !!!!! Use here countTotalUsage
3645
3745
  * TODO: [🛠] Actions, instruments (and maybe knowledge) => Functions and tools
3646
3746
  */
3647
3747
 
@@ -5957,6 +6057,69 @@ function listAllFiles(path, isRecursive) {
5957
6057
  * Note: [🟢] This code should never be published outside of `@pipeline/node`
5958
6058
  */
5959
6059
 
6060
+ /**
6061
+ * Stringify the PipelineJson with proper formatting
6062
+ *
6063
+ * Note: [0] It can be used for more JSON types like whole collection of pipelines, single knowledge piece, etc.
6064
+ * Note: In contrast to JSON.stringify, this function ensures that **embedding index** is on single line
6065
+ */
6066
+ function stringifyPipelineJson(pipeline) {
6067
+ var pipelineJsonStringified = JSON.stringify(pipeline, null, 4);
6068
+ for (var i = 0; i < LOOP_LIMIT; i++) {
6069
+ pipelineJsonStringified = pipelineJsonStringified.replace(/(-?0\.\d+),[\n\s]+(-?0\.\d+)/gms, "$1".concat(REPLACING_NONCE, "$2"));
6070
+ }
6071
+ pipelineJsonStringified = pipelineJsonStringified.split(REPLACING_NONCE).join(', ');
6072
+ pipelineJsonStringified += '\n';
6073
+ return pipelineJsonStringified;
6074
+ }
6075
+ /**
6076
+ * TODO: [🐝] Not Working propperly @see https://promptbook.studio/samples/mixed-knowledge.ptbk.md
6077
+ * TODO: [🧠][0] Maybe rename to `stringifyPipelineJson`, `stringifyIndexedJson`,...
6078
+ * TODO: [🧠] Maybe more elegant solution than replacing via regex
6079
+ * TODO: [🍙] Make some standart order of json properties
6080
+ */
6081
+
6082
+ /**
6083
+ * Function usageToWorktime will take usage and estimate saved worktime in hours of reading / writing
6084
+ *
6085
+ * Note: This is an estimate based of theese sources:
6086
+ * - https://jecas.cz/doba-cteni
6087
+ * - https://www.originalnitonery.cz/blog/psani-vsemi-deseti-se-muzete-naucit-i-sami-doma
6088
+ */
6089
+ function usageToWorktime(usage) {
6090
+ var value = usage.input.wordsCount.value / (200 /* words per minute */ * 60) +
6091
+ usage.output.wordsCount.value / (40 /* words per minute */ * 60);
6092
+ var isUncertain = usage.input.wordsCount.isUncertain || usage.output.wordsCount.isUncertain;
6093
+ var uncertainNumber = { value: value };
6094
+ if (isUncertain === true) {
6095
+ uncertainNumber.isUncertain = true;
6096
+ }
6097
+ return uncertainNumber;
6098
+ }
6099
+
6100
+ /**
6101
+ * Function `usageToHuman` will take usage and convert it to human readable report
6102
+ */
6103
+ function usageToHuman(usage) {
6104
+ var report = 'Usage:';
6105
+ var uncertainNumberToHuman = function (_a) {
6106
+ var value = _a.value, isUncertain = _a.isUncertain;
6107
+ return "".concat(isUncertain ? 'approximately ' : '').concat(Math.round(value * 100) / 100);
6108
+ };
6109
+ report += '\n' + "- Cost ".concat(uncertainNumberToHuman(usage.price), " USD");
6110
+ report += '\n' + "- Saved ".concat(uncertainNumberToHuman(usageToWorktime(usage)), " hours of human time");
6111
+ return spaceTrim(report);
6112
+ }
6113
+ /**
6114
+ * TODO: Use "$1" not "1 USD"
6115
+ * TODO: Use markdown formatting like "Cost approximately **$1**"
6116
+ * TODO: Report in minutes, seconds, days NOT 0.1 hours
6117
+ * TODO: [🧠] Maybe make from `uncertainNumberToHuman` separate exported utility
6118
+ * TODO: When negligible usage, report "Negligible" or just don't report it
6119
+ * TODO: [🧠] Maybe use "~" instead of "approximately"
6120
+ * TODO: [🏛] Maybe make some markdown builder
6121
+ */
6122
+
5960
6123
  /**
5961
6124
  * This error type indicates that you try to use a feature that is not available in the current environment
5962
6125
  */
@@ -6036,7 +6199,7 @@ var FilesStorage = /** @class */ (function () {
6036
6199
  switch (_a.label) {
6037
6200
  case 0:
6038
6201
  filename = this.getFilenameForKey(key);
6039
- fileContent = JSON.stringify(value, null, 4);
6202
+ fileContent = stringifyPipelineJson(value);
6040
6203
  return [4 /*yield*/, mkdir(dirname(filename), { recursive: true })];
6041
6204
  case 1:
6042
6205
  _a.sent(); // <- [0]
@@ -6103,7 +6266,7 @@ function computeUsageCounts(content) {
6103
6266
  * @private utility for initializating UncertainNumber
6104
6267
  */
6105
6268
  function uncertainNumber(value) {
6106
- if (value === null || value === undefined || Number.isNaN(NaN)) {
6269
+ if (value === null || value === undefined || Number.isNaN(value)) {
6107
6270
  return { value: 0, isUncertain: true };
6108
6271
  }
6109
6272
  return { value: value };
@@ -6417,6 +6580,7 @@ var AnthropicClaudeExecutionTools = /** @class */ (function () {
6417
6580
  * TODO: Maybe Create some common util for callChatModel and callCompletionModel
6418
6581
  * TODO: Maybe make custom OpenaiError
6419
6582
  * TODO: [🧠][🈁] Maybe use `isDeterministic` from options
6583
+ * TODO: [🍜] Auto use anonymous server in browser
6420
6584
  */
6421
6585
 
6422
6586
  /**
@@ -7110,6 +7274,8 @@ var OpenAiExecutionTools = /** @class */ (function () {
7110
7274
  *
7111
7275
  * Note: This function is not cached, every call creates new instance of `LlmExecutionTools`
7112
7276
  *
7277
+ * @@@ .env
7278
+ *
7113
7279
  * It looks for environment variables:
7114
7280
  * - `process.env.OPENAI_API_KEY`
7115
7281
  * - `process.env.ANTHROPIC_CLAUDE_API_KEY`
@@ -7122,6 +7288,7 @@ function createLlmToolsFromEnv(options) {
7122
7288
  throw new EnvironmentMismatchError('Function `createLlmToolsFromEnv` works only in Node.js environment');
7123
7289
  }
7124
7290
  var _a = options.isVerbose, isVerbose = _a === void 0 ? false : _a;
7291
+ dotenv.config(); // <- TODO: !!!!!! Double check [🟢]
7125
7292
  var llmTools = [];
7126
7293
  if (typeof process.env.OPENAI_API_KEY === 'string') {
7127
7294
  llmTools.push(new OpenAiExecutionTools({
@@ -7146,6 +7313,7 @@ function createLlmToolsFromEnv(options) {
7146
7313
  }
7147
7314
  }
7148
7315
  /**
7316
+ * TODO: [🍜] Use `createLlmToolsFromConfiguration`
7149
7317
  * TODO: [🔼] !!! Export via `@promptbook/node`
7150
7318
  * TODO: @@@ write discussion about this - wizzard
7151
7319
  * TODO: Add Azure
@@ -7153,6 +7321,7 @@ function createLlmToolsFromEnv(options) {
7153
7321
  * TODO: [🧠] Is there some meaningfull way how to test this util
7154
7322
  * TODO: [🧠] Maybe pass env as argument
7155
7323
  * Note: [🟢] This code should never be published outside of `@promptbook/node`
7324
+ * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
7156
7325
  */
7157
7326
 
7158
7327
  /**
@@ -7220,14 +7389,17 @@ function $currentDate() {
7220
7389
  /**
7221
7390
  * Intercepts LLM tools and counts total usage of the tools
7222
7391
  *
7223
- * @param llmTools LLM tools to be intercepted with usage counting
7392
+ * Note: It can take extended `LlmExecutionTools` and cache the
7393
+ *
7394
+ * @param llmTools LLM tools to be intercepted with usage counting, it can contain extra methods like `totalUsage`
7224
7395
  * @returns LLM tools with same functionality with added total cost counting
7225
7396
  */
7226
7397
  function cacheLlmTools(llmTools, options) {
7227
7398
  var _this = this;
7228
7399
  if (options === void 0) { options = {}; }
7229
- var _a = options.storage, storage = _a === void 0 ? new MemoryStorage() : _a;
7230
- var proxyTools = {
7400
+ var _a = options.storage, storage = _a === void 0 ? new MemoryStorage() : _a, _b = options.isReloaded, isReloaded = _b === void 0 ? false : _b;
7401
+ var proxyTools = __assign(__assign({}, llmTools), {
7402
+ // <- Note: [🥫]
7231
7403
  get title() {
7232
7404
  // TODO: [🧠] Maybe put here some suffix
7233
7405
  return llmTools.title;
@@ -7235,54 +7407,59 @@ function cacheLlmTools(llmTools, options) {
7235
7407
  get description() {
7236
7408
  // TODO: [🧠] Maybe put here some suffix
7237
7409
  return llmTools.description;
7238
- },
7239
- listModels: function () {
7410
+ }, listModels: function () {
7240
7411
  // TODO: [🧠] Should be model listing also cached?
7241
7412
  return /* not await */ llmTools.listModels();
7242
- },
7243
- };
7413
+ } });
7244
7414
  var callCommonModel = function (prompt) { return __awaiter(_this, void 0, void 0, function () {
7245
- var key, cacheItem, promptResult, _a;
7246
- return __generator(this, function (_b) {
7247
- switch (_b.label) {
7415
+ var key, cacheItem, _a, promptResult, _b;
7416
+ return __generator(this, function (_c) {
7417
+ switch (_c.label) {
7248
7418
  case 0:
7249
7419
  key = titleToName(prompt.title.substring(0, MAX_FILENAME_LENGTH - 10) +
7250
7420
  '-' +
7251
7421
  sha256(hexEncoder.parse(JSON.stringify(prompt.parameters))).toString( /* hex */));
7422
+ if (!!isReloaded) return [3 /*break*/, 2];
7252
7423
  return [4 /*yield*/, storage.getItem(key)];
7253
7424
  case 1:
7254
- cacheItem = _b.sent();
7425
+ _a = _c.sent();
7426
+ return [3 /*break*/, 3];
7427
+ case 2:
7428
+ _a = null;
7429
+ _c.label = 3;
7430
+ case 3:
7431
+ cacheItem = _a;
7255
7432
  if (cacheItem) {
7256
7433
  return [2 /*return*/, cacheItem.promptResult];
7257
7434
  }
7258
- _a = prompt.modelRequirements.modelVariant;
7259
- switch (_a) {
7260
- case 'CHAT': return [3 /*break*/, 2];
7261
- case 'COMPLETION': return [3 /*break*/, 4];
7262
- case 'EMBEDDING': return [3 /*break*/, 6];
7435
+ _b = prompt.modelRequirements.modelVariant;
7436
+ switch (_b) {
7437
+ case 'CHAT': return [3 /*break*/, 4];
7438
+ case 'COMPLETION': return [3 /*break*/, 6];
7439
+ case 'EMBEDDING': return [3 /*break*/, 8];
7263
7440
  }
7264
- return [3 /*break*/, 8];
7265
- case 2: return [4 /*yield*/, llmTools.callChatModel(prompt)];
7266
- case 3:
7267
- promptResult = _b.sent();
7268
- return [3 /*break*/, 9];
7269
- case 4: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
7441
+ return [3 /*break*/, 10];
7442
+ case 4: return [4 /*yield*/, llmTools.callChatModel(prompt)];
7270
7443
  case 5:
7271
- promptResult = _b.sent();
7272
- return [3 /*break*/, 9];
7273
- case 6: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
7444
+ promptResult = _c.sent();
7445
+ return [3 /*break*/, 11];
7446
+ case 6: return [4 /*yield*/, llmTools.callCompletionModel(prompt)];
7274
7447
  case 7:
7275
- promptResult = _b.sent();
7276
- return [3 /*break*/, 9];
7277
- case 8: throw new PipelineExecutionError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
7278
- case 9: return [4 /*yield*/, storage.setItem(key, {
7448
+ promptResult = _c.sent();
7449
+ return [3 /*break*/, 11];
7450
+ case 8: return [4 /*yield*/, llmTools.callEmbeddingModel(prompt)];
7451
+ case 9:
7452
+ promptResult = _c.sent();
7453
+ return [3 /*break*/, 11];
7454
+ case 10: throw new PipelineExecutionError("Unknown model variant \"".concat(prompt.modelRequirements.modelVariant, "\""));
7455
+ case 11: return [4 /*yield*/, storage.setItem(key, {
7279
7456
  date: $currentDate(),
7280
7457
  promptbookVersion: PROMPTBOOK_VERSION,
7281
7458
  prompt: prompt,
7282
7459
  promptResult: promptResult,
7283
7460
  })];
7284
- case 10:
7285
- _b.sent();
7461
+ case 12:
7462
+ _c.sent();
7286
7463
  return [2 /*return*/, promptResult];
7287
7464
  }
7288
7465
  });
@@ -7313,10 +7490,11 @@ function cacheLlmTools(llmTools, options) {
7313
7490
  }
7314
7491
  /**
7315
7492
  * TODO: [🔼] !!! Export via `@promptbook/core`
7316
- * TODO: @@@ write discussion about this and storages
7317
- * write how to combine multiple interceptors
7318
7493
  * TODO: [🧠][💸] Maybe make some common abstraction `interceptLlmTools` and use here (or use javascript Proxy?)
7319
7494
  * TODO: [🧠] Is there some meaningfull way how to test this util
7495
+ * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
7496
+ * @@@ write discussion about this and storages
7497
+ * @@@ write how to combine multiple interceptors
7320
7498
  */
7321
7499
 
7322
7500
  /**
@@ -7324,38 +7502,21 @@ function cacheLlmTools(llmTools, options) {
7324
7502
  *
7325
7503
  * @private within the repository - for CLI utils
7326
7504
  */
7327
- function getLlmToolsForCli() {
7505
+ function getLlmToolsForCli(options) {
7328
7506
  if (!isRunningInNode()) {
7329
7507
  throw new EnvironmentMismatchError('Function `getLlmToolsForTestingAndScriptsAndPlayground` works only in Node.js environment');
7330
7508
  }
7331
- return cacheLlmTools(createLlmToolsFromEnv(), {
7509
+ var _a = (options !== null && options !== void 0 ? options : {}).isCacheReloaded, isCacheReloaded = _a === void 0 ? false : _a;
7510
+ return cacheLlmTools(countTotalUsage(
7511
+ // <- Note: for example here we don`t want the [🌯]
7512
+ createLlmToolsFromEnv()), {
7332
7513
  storage: new FilesStorage({ cacheFolderPath: join(process.cwd(), EXECUTIONS_CACHE_DIRNAME) }),
7514
+ isReloaded: isCacheReloaded,
7333
7515
  });
7334
7516
  }
7335
7517
  /**
7336
7518
  * Note: [🟡] This code should never be published outside of `@promptbook/cli`
7337
- */
7338
-
7339
- /**
7340
- * Stringify the PipelineJson with proper formatting
7341
- *
7342
- * Note: [0] It can be used for more JSON types like whole collection of pipelines, single knowledge piece, etc.
7343
- * Note: In contrast to JSON.stringify, this function ensures that **embedding index** is on single line
7344
- */
7345
- function stringifyPipelineJson(pipeline) {
7346
- var pipelineJsonStringified = JSON.stringify(pipeline, null, 4);
7347
- for (var i = 0; i < LOOP_LIMIT; i++) {
7348
- pipelineJsonStringified = pipelineJsonStringified.replace(/(-?0\.\d+),[\n\s]+(-?0\.\d+)/gms, "$1".concat(REPLACING_NONCE, "$2"));
7349
- }
7350
- pipelineJsonStringified = pipelineJsonStringified.split(REPLACING_NONCE).join(', ');
7351
- pipelineJsonStringified += '\n';
7352
- return pipelineJsonStringified;
7353
- }
7354
- /**
7355
- * TODO: [🐝] Not Working propperly @see https://promptbook.studio/samples/mixed-knowledge.ptbk.md
7356
- * TODO: [🧠][0] Maybe rename to `stringifyPipelineJson`, `stringifyIndexedJson`,...
7357
- * TODO: [🧠] Maybe more elegant solution than replacing via regex
7358
- * TODO: [🍙] Make some standart order of json properties
7519
+ * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
7359
7520
  */
7360
7521
 
7361
7522
  /**
@@ -7365,24 +7526,26 @@ function stringifyPipelineJson(pipeline) {
7365
7526
  */
7366
7527
  function initializeMakeCommand(program) {
7367
7528
  var _this = this;
7368
- var helloCommand = program.command('make');
7369
- helloCommand.description(spaceTrim("\n Makes a new pipeline collection in given folder\n "));
7370
- helloCommand.argument('<path>', 'Path to promptbook directory');
7371
- helloCommand.option('--project-name', "Name of the project for whom collection is", 'Project');
7372
- helloCommand.option('-f, --format <format>', spaceTrim("\n Output format of builded collection \"javascript\", \"typescript\" or \"json\"\n\n Note: You can use multiple formats separated by comma\n "), 'javascript' /* <- Note: [🏳‍🌈] */);
7373
- helloCommand.option('--no-validation', "Do not validate logic of pipelines in collection", true);
7374
- helloCommand.option('--validation', "Types of validations separated by comma (options \"logic\",\"imports\")", 'logic,imports');
7375
- helloCommand.option('--verbose', "Is verbose", false);
7376
- helloCommand.option('-o, --out-file <path>', spaceTrim("\n Where to save the builded collection\n\n Note: If you keep it \"".concat(PIPELINE_COLLECTION_BASE_FILENAME, "\" it will be saved in the root of the promptbook directory\n If you set it to a path, it will be saved in that path\n BUT you can use only one format and set correct extension\n ")), PIPELINE_COLLECTION_BASE_FILENAME);
7377
- helloCommand.action(function (path, _a) {
7378
- var projectName = _a.projectName, format = _a.format, validation = _a.validation, verbose = _a.verbose, outFile = _a.outFile;
7529
+ var makeCommand = program.command('make');
7530
+ makeCommand.description(spaceTrim("\n Makes a new pipeline collection in given folder\n "));
7531
+ makeCommand.argument('<path>', 'Path to promptbook directory');
7532
+ makeCommand.option('--project-name', "Name of the project for whom collection is", 'Project');
7533
+ makeCommand.option('-f, --format <format>', spaceTrim("\n Output format of builded collection \"javascript\", \"typescript\" or \"json\"\n\n Note: You can use multiple formats separated by comma\n "), 'javascript' /* <- Note: [🏳‍🌈] */);
7534
+ makeCommand.option('--no-validation', "Do not validate logic of pipelines in collection", true);
7535
+ makeCommand.option('--validation', "Types of validations separated by comma (options \"logic\",\"imports\")", 'logic,imports');
7536
+ makeCommand.option('--reload-cache', "Use LLM models even if cached ", false);
7537
+ makeCommand.option('--verbose', "Is verbose", false);
7538
+ makeCommand.option('-o, --out-file <path>', spaceTrim("\n Where to save the builded collection\n\n Note: If you keep it \"".concat(PIPELINE_COLLECTION_BASE_FILENAME, "\" it will be saved in the root of the promptbook directory\n If you set it to a path, it will be saved in that path\n BUT you can use only one format and set correct extension\n ")), PIPELINE_COLLECTION_BASE_FILENAME);
7539
+ makeCommand.action(function (path, _a) {
7540
+ var projectName = _a.projectName, format = _a.format, validation = _a.validation, reloadCache = _a.reloadCache, verbose = _a.verbose, outFile = _a.outFile;
7379
7541
  return __awaiter(_this, void 0, void 0, function () {
7380
- var isVerbose, formats, validations, llmTools, collection, validations_1, validations_1_1, validation_1, _b, _c, pipelineUrl, pipeline, e_1_1, e_2_1, collectionJson, collectionJsonString, saveFile;
7542
+ var isCacheReloaded, isVerbose, formats, validations, llmTools, collection, validations_1, validations_1_1, validation_1, _b, _c, pipelineUrl, pipeline, e_1_1, e_2_1, collectionJson, collectionJsonString, saveFile;
7381
7543
  var e_2, _d, e_1, _e;
7382
7544
  var _this = this;
7383
7545
  return __generator(this, function (_f) {
7384
7546
  switch (_f.label) {
7385
7547
  case 0:
7548
+ isCacheReloaded = reloadCache;
7386
7549
  isVerbose = verbose;
7387
7550
  formats = (format || '')
7388
7551
  .split(',')
@@ -7396,11 +7559,14 @@ function initializeMakeCommand(program) {
7396
7559
  console.error(colors.red("You can use only one format when saving to a file"));
7397
7560
  process.exit(1);
7398
7561
  }
7399
- llmTools = getLlmToolsForCli();
7562
+ llmTools = getLlmToolsForCli({
7563
+ isCacheReloaded: isCacheReloaded,
7564
+ });
7400
7565
  return [4 /*yield*/, createCollectionFromDirectory(path, {
7401
7566
  llmTools: llmTools,
7402
7567
  isVerbose: isVerbose,
7403
7568
  isRecursive: true,
7569
+ // <- TODO: [🍖] isCacheReloaded
7404
7570
  })];
7405
7571
  case 1:
7406
7572
  collection = _f.sent();
@@ -7506,6 +7672,11 @@ function initializeMakeCommand(program) {
7506
7672
  _f.sent();
7507
7673
  _f.label = 23;
7508
7674
  case 23:
7675
+ if (isVerbose) {
7676
+ // TODO: !!!!!! Test that this works
7677
+ console.info(colors.green("Collection builded"));
7678
+ console.info(colors.cyan(usageToHuman(llmTools.getTotalUsage())));
7679
+ }
7509
7680
  process.exit(0);
7510
7681
  return [2 /*return*/];
7511
7682
  }