@promptbook/cli 0.92.0-26 → 0.92.0-27

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
@@ -47,7 +47,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
47
47
  * @generated
48
48
  * @see https://github.com/webgptorg/promptbook
49
49
  */
50
- const PROMPTBOOK_ENGINE_VERSION = '0.92.0-26';
50
+ const PROMPTBOOK_ENGINE_VERSION = '0.92.0-27';
51
51
  /**
52
52
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
53
53
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -2663,6 +2663,23 @@ class RemoteLlmExecutionTools {
2663
2663
  * TODO: [🧠] Maybe remove `@promptbook/remote-client` and just use `@promptbook/core`
2664
2664
  */
2665
2665
 
2666
+ /**
2667
+ * Parses the task and returns the list of all parameter names
2668
+ *
2669
+ * @param template the string template with parameters in {curly} braces
2670
+ * @returns the list of parameter names
2671
+ * @public exported from `@promptbook/utils`
2672
+ */
2673
+ function extractParameterNames(template) {
2674
+ const matches = template.matchAll(/{\w+}/g);
2675
+ const parameterNames = new Set();
2676
+ for (const match of matches) {
2677
+ const parameterName = match[0].slice(1, -1);
2678
+ parameterNames.add(parameterName);
2679
+ }
2680
+ return parameterNames;
2681
+ }
2682
+
2666
2683
  /**
2667
2684
  * Stores data in memory (HEAP)
2668
2685
  *
@@ -2752,20 +2769,34 @@ function cacheLlmTools(llmTools, options = {}) {
2752
2769
  const callCommonModel = async (prompt) => {
2753
2770
  const { parameters, content, modelRequirements } = prompt;
2754
2771
  // <- Note: These are relevant things from the prompt that the cache key should depend on.
2772
+ // TODO: Maybe some standalone function for normalization of content for cache
2773
+ let normalizedContent = content;
2774
+ normalizedContent = normalizedContent.replace(/\s+/g, ' ');
2775
+ normalizedContent = normalizedContent.split('\r\n').join('\n');
2776
+ normalizedContent = spaceTrim(normalizedContent);
2777
+ // Note: Do not need to save everything in the cache, just the relevant parameters
2778
+ const relevantParameterNames = extractParameterNames(content);
2779
+ const relevantParameters = Object.fromEntries(Object.entries(parameters).filter(([key]) => relevantParameterNames.has(key)));
2780
+ const keyHashBase = { relevantParameters, normalizedContent, modelRequirements };
2755
2781
  const key = titleToName(prompt.title.substring(0, MAX_FILENAME_LENGTH - 10) +
2756
2782
  '-' +
2757
- sha256(hexEncoder.parse(JSON.stringify({ parameters, content, modelRequirements }))).toString( /* hex */));
2783
+ sha256(hexEncoder.parse(JSON.stringify(keyHashBase)))
2784
+ .toString( /* hex */)
2785
+ .substring(0, 10 - 1));
2758
2786
  const cacheItem = !isCacheReloaded ? await storage.getItem(key) : null;
2759
2787
  if (cacheItem) {
2760
- console.log('!!! Cache hit for key:', key);
2788
+ console.log('!!! Cache hit for key:', { key, keyHashBase });
2761
2789
  return cacheItem.promptResult;
2762
2790
  }
2763
2791
  console.log('!!! Cache miss for key:', key, {
2764
2792
  prompt,
2765
2793
  'prompt.title': prompt.title,
2766
2794
  MAX_FILENAME_LENGTH,
2795
+ keyHashBase,
2767
2796
  parameters,
2797
+ relevantParameters,
2768
2798
  content,
2799
+ normalizedContent,
2769
2800
  modelRequirements,
2770
2801
  });
2771
2802
  let promptResult;
@@ -2788,7 +2819,16 @@ function cacheLlmTools(llmTools, options = {}) {
2788
2819
  await storage.setItem(key, {
2789
2820
  date: $getCurrentDate(),
2790
2821
  promptbookVersion: PROMPTBOOK_ENGINE_VERSION,
2791
- prompt,
2822
+ bookVersion: BOOK_LANGUAGE_VERSION,
2823
+ prompt: {
2824
+ ...prompt,
2825
+ parameters: Object.entries(parameters).length === Object.entries(relevantParameters).length
2826
+ ? parameters
2827
+ : {
2828
+ ...relevantParameters,
2829
+ note: `<- Note: Only relevant parameters are stored in the cache`,
2830
+ },
2831
+ },
2792
2832
  promptResult,
2793
2833
  });
2794
2834
  return promptResult;
@@ -3230,11 +3270,16 @@ function joinLlmExecutionTools(...llmExecutionTools) {
3230
3270
  */
3231
3271
 
3232
3272
  /**
3233
- * @@@
3273
+ * Creates LLM execution tools from provided configuration objects
3274
+ *
3275
+ * Instantiates and configures LLM tool instances for each configuration entry,
3276
+ * combining them into a unified interface via MultipleLlmExecutionTools.
3234
3277
  *
3235
3278
  * Note: This function is not cached, every call creates new instance of `MultipleLlmExecutionTools`
3236
3279
  *
3237
- * @returns @@@
3280
+ * @param configuration Array of LLM tool configurations to instantiate
3281
+ * @param options Additional options for configuring the LLM tools
3282
+ * @returns A unified interface combining all successfully instantiated LLM tools
3238
3283
  * @public exported from `@promptbook/core`
3239
3284
  */
3240
3285
  function createLlmToolsFromConfiguration(configuration, options = {}) {
@@ -3273,7 +3318,11 @@ function createLlmToolsFromConfiguration(configuration, options = {}) {
3273
3318
  /**
3274
3319
  * TODO: [🎌] Together with `createLlmToolsFromConfiguration` + 'EXECUTION_TOOLS_CLASSES' gets to `@promptbook/core` ALL model providers, make this more efficient
3275
3320
  * TODO: [🧠][🎌] Dynamically install required providers
3276
- * TODO: @@@ write discussion about this - wizzard
3321
+ * TODO: We should implement an interactive configuration wizard that would:
3322
+ * 1. Detect which LLM providers are available in the environment
3323
+ * 2. Guide users through required configuration settings for each provider
3324
+ * 3. Allow testing connections before completing setup
3325
+ * 4. Generate appropriate configuration code for application integration
3277
3326
  * TODO: [🧠][🍛] Which name is better `createLlmToolsFromConfig` or `createLlmToolsFromConfiguration`?
3278
3327
  * TODO: [🧠] Is there some meaningfull way how to test this util
3279
3328
  * TODO: This should be maybe not under `_common` but under `utils`
@@ -3281,11 +3330,14 @@ function createLlmToolsFromConfiguration(configuration, options = {}) {
3281
3330
  */
3282
3331
 
3283
3332
  /**
3284
- * @@@
3333
+ * Automatically configures LLM tools from environment variables in Node.js
3334
+ *
3335
+ * This utility function detects available LLM providers based on environment variables
3336
+ * and creates properly configured LLM execution tools for each detected provider.
3285
3337
  *
3286
3338
  * Note: This function is not cached, every call creates new instance of `MultipleLlmExecutionTools`
3287
3339
  *
3288
- * @@@ .env
3340
+ * Supports environment variables from .env files when dotenv is configured
3289
3341
  * Note: `$` is used to indicate that this function is not a pure function - it uses filesystem to access `.env` file
3290
3342
  *
3291
3343
  * It looks for environment variables:
@@ -3293,7 +3345,8 @@ function createLlmToolsFromConfiguration(configuration, options = {}) {
3293
3345
  * - `process.env.ANTHROPIC_CLAUDE_API_KEY`
3294
3346
  * - ...
3295
3347
  *
3296
- * @returns @@@
3348
+ * @param options Configuration options for the LLM tools
3349
+ * @returns A unified interface containing all detected and configured LLM tools
3297
3350
  * @public exported from `@promptbook/node`
3298
3351
  */
3299
3352
  async function $provideLlmToolsFromEnv(options = {}) {
@@ -3319,7 +3372,16 @@ async function $provideLlmToolsFromEnv(options = {}) {
3319
3372
  return createLlmToolsFromConfiguration(configuration, options);
3320
3373
  }
3321
3374
  /**
3322
- * TODO: @@@ write `$provideLlmToolsFromEnv` vs `$provideLlmToolsConfigurationFromEnv` vs `createLlmToolsFromConfiguration`
3375
+ * TODO: The architecture for LLM tools configuration consists of three key functions:
3376
+ * 1. `$provideLlmToolsFromEnv` - High-level function that detects available providers from env vars and returns ready-to-use LLM tools
3377
+ * 2. `$provideLlmToolsConfigurationFromEnv` - Middle layer that extracts configuration objects from environment variables
3378
+ * 3. `createLlmToolsFromConfiguration` - Low-level function that instantiates LLM tools from explicit configuration
3379
+ *
3380
+ * This layered approach allows flexibility in how tools are configured:
3381
+ * - Use $provideLlmToolsFromEnv for automatic detection and setup in Node.js environments
3382
+ * - Use $provideLlmToolsConfigurationFromEnv to extract config objects for modification before instantiation
3383
+ * - Use createLlmToolsFromConfiguration for explicit control over tool configurations
3384
+ *
3323
3385
  * TODO: [🧠][🍛] Which name is better `$provideLlmToolsFromEnv` or `$provideLlmToolsFromEnvironment`?
3324
3386
  * TODO: [🧠] Is there some meaningfull way how to test this util
3325
3387
  * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
@@ -4787,23 +4849,6 @@ function taskParameterJsonToString(taskParameterJson) {
4787
4849
  * TODO: [🧠] Should be in generated .book.md file GENERATOR_WARNING
4788
4850
  */
4789
4851
 
4790
- /**
4791
- * Parses the task and returns the list of all parameter names
4792
- *
4793
- * @param template the string template with parameters in {curly} braces
4794
- * @returns the list of parameter names
4795
- * @public exported from `@promptbook/utils`
4796
- */
4797
- function extractParameterNames(template) {
4798
- const matches = template.matchAll(/{\w+}/g);
4799
- const parameterNames = new Set();
4800
- for (const match of matches) {
4801
- const parameterName = match[0].slice(1, -1);
4802
- parameterNames.add(parameterName);
4803
- }
4804
- return parameterNames;
4805
- }
4806
-
4807
4852
  /**
4808
4853
  * Unprepare just strips the preparation data of the pipeline
4809
4854
  *
@@ -8191,7 +8236,7 @@ const sectionCommandParser = {
8191
8236
  /**
8192
8237
  * Parses the boilerplate command
8193
8238
  *
8194
- * Note: @@@ This command is used as boilerplate for new commands - it should NOT be used in any `.book` file
8239
+ * Note: @@ This command is used as boilerplate for new commands - it should NOT be used in any `.book` file
8195
8240
  *
8196
8241
  * @see `documentationUrl` for more details
8197
8242
  * @private within the commands folder
@@ -9127,17 +9172,20 @@ const ImageGeneratorFormfactorDefinition = {
9127
9172
  };
9128
9173
 
9129
9174
  /**
9130
- * Matcher is form of app that @@@
9175
+ * Matcher is form of app that evaluates (spreadsheet) content against defined criteria or patterns,
9176
+ * determining if it matches or meets specific requirements. Used for classification,
9177
+ * validation, filtering, and quality assessment of inputs.
9131
9178
  *
9132
9179
  * @public exported from `@promptbook/core`
9133
9180
  */
9134
9181
  const MatcherFormfactorDefinition = {
9135
9182
  name: 'EXPERIMENTAL_MATCHER',
9136
- description: `@@@`,
9183
+ description: `An evaluation system that determines whether content meets specific criteria or patterns.
9184
+ Used for content validation, quality assessment, and intelligent filtering tasks. Currently in experimental phase.`,
9137
9185
  documentationUrl: `https://github.com/webgptorg/promptbook/discussions/177`,
9138
9186
  pipelineInterface: {
9139
9187
  inputParameters: [
9140
- /* @@@ */
9188
+ /* Input parameters for content to be matched and criteria to match against */
9141
9189
  {
9142
9190
  name: 'nonce',
9143
9191
  description: 'Just to prevent EXPERIMENTAL_MATCHER to be set as implicit formfactor',
@@ -9146,7 +9194,7 @@ const MatcherFormfactorDefinition = {
9146
9194
  },
9147
9195
  ],
9148
9196
  outputParameters: [
9149
- /* @@@ */
9197
+ /* Output parameters containing match results, confidence scores, and relevant metadata */
9150
9198
  ],
9151
9199
  },
9152
9200
  };
@@ -9183,13 +9231,16 @@ const SheetsFormfactorDefinition = {
9183
9231
  };
9184
9232
 
9185
9233
  /**
9186
- * Translator is form of app that @@@
9234
+ * Translator is form of app that transforms input text from one form to another,
9235
+ * such as language translation, style conversion, tone modification, or other text transformations.
9187
9236
  *
9188
9237
  * @public exported from `@promptbook/core`
9189
9238
  */
9190
9239
  const TranslatorFormfactorDefinition = {
9191
9240
  name: 'TRANSLATOR',
9192
- description: `@@@`,
9241
+ description: `A text transformation system that converts input content into different forms,
9242
+ including language translations, paraphrasing, style conversions, and tone adjustments.
9243
+ This form factor takes one input and produces one transformed output.`,
9193
9244
  documentationUrl: `https://github.com/webgptorg/promptbook/discussions/175`,
9194
9245
  pipelineInterface: {
9195
9246
  inputParameters: [
@@ -10316,7 +10367,10 @@ function parseCommand(raw, usagePlace) {
10316
10367
  `));
10317
10368
  }
10318
10369
  /**
10319
- * @@@
10370
+ * Generates a markdown-formatted message listing all supported commands
10371
+ * with their descriptions and documentation links
10372
+ *
10373
+ * @returns A formatted markdown string containing all available commands and their details
10320
10374
  */
10321
10375
  function getSupportedCommandsMessage() {
10322
10376
  return COMMANDS.flatMap(({ name, aliasNames, description, documentationUrl }) =>
@@ -10327,7 +10381,10 @@ function getSupportedCommandsMessage() {
10327
10381
  ]).join('\n');
10328
10382
  }
10329
10383
  /**
10330
- * @@@
10384
+ * Attempts to parse a command variant using the provided input parameters
10385
+ *
10386
+ * @param input Object containing command parsing information including raw command text and normalized values
10387
+ * @returns A parsed Command object if successful, or null if the command cannot be parsed
10331
10388
  */
10332
10389
  function parseCommandVariant(input) {
10333
10390
  const { commandNameRaw, usagePlace, normalized, args, raw, rawArgs } = input;
@@ -15089,14 +15146,18 @@ function computeUsageCounts(content) {
15089
15146
  /**
15090
15147
  * Make UncertainNumber
15091
15148
  *
15092
- * @param value
15149
+ * @param value value of the uncertain number, if `NaN` or `undefined`, it will be set to 0 and `isUncertain=true`
15150
+ * @param isUncertain if `true`, the value is uncertain, otherwise depends on the value
15093
15151
  *
15094
15152
  * @private utility for initializating UncertainNumber
15095
15153
  */
15096
- function uncertainNumber(value) {
15154
+ function uncertainNumber(value, isUncertain) {
15097
15155
  if (value === null || value === undefined || Number.isNaN(value)) {
15098
15156
  return UNCERTAIN_ZERO_VALUE;
15099
15157
  }
15158
+ if (isUncertain === true) {
15159
+ return { value, isUncertain };
15160
+ }
15100
15161
  return { value };
15101
15162
  }
15102
15163
 
@@ -17003,10 +17064,14 @@ resultContent, rawResponse) {
17003
17064
  }
17004
17065
  const inputTokens = rawResponse.usage.prompt_tokens;
17005
17066
  const outputTokens = ((_b = rawResponse.usage) === null || _b === void 0 ? void 0 : _b.completion_tokens) || 0;
17067
+ let isUncertain = false;
17006
17068
  let modelInfo = OPENAI_MODELS.find((model) => model.modelName === rawResponse.model);
17007
17069
  if (modelInfo === undefined) {
17008
- // Note: Model is not in the list of known models, maybe just a different version of the same model
17009
- modelInfo = OPENAI_MODELS.find((model) => model.modelName.startsWith(rawResponse.model || SALT_NONCE));
17070
+ // Note: Model is not in the list of known models, fallback to the family of the models and mark price as uncertain
17071
+ modelInfo = OPENAI_MODELS.find((model) => (rawResponse.model || SALT_NONCE).startsWith(model.modelName));
17072
+ if (modelInfo !== undefined) {
17073
+ isUncertain = true;
17074
+ }
17010
17075
  }
17011
17076
  console.log('!!! computeOpenAiUsage', {
17012
17077
  inputTokens,
@@ -17022,7 +17087,7 @@ resultContent, rawResponse) {
17022
17087
  price = uncertainNumber();
17023
17088
  }
17024
17089
  else {
17025
- price = uncertainNumber(inputTokens * modelInfo.pricing.prompt + outputTokens * modelInfo.pricing.output);
17090
+ price = uncertainNumber(inputTokens * modelInfo.pricing.prompt + outputTokens * modelInfo.pricing.output, isUncertain);
17026
17091
  }
17027
17092
  return {
17028
17093
  price,