@promptbook/node 0.100.0-45 → 0.100.0-46

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
@@ -3,8 +3,9 @@ import { stat, access, constants, readFile, writeFile, readdir, mkdir, unlink }
3
3
  import { basename, join, dirname, relative } from 'path';
4
4
  import spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
5
5
  import JSZip from 'jszip';
6
- import { format } from 'prettier';
7
6
  import parserHtml from 'prettier/parser-html';
7
+ import parserMarkdown from 'prettier/parser-markdown';
8
+ import { format } from 'prettier/standalone';
8
9
  import { randomBytes } from 'crypto';
9
10
  import { Subject } from 'rxjs';
10
11
  import { forTime } from 'waitasecond';
@@ -30,7 +31,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
30
31
  * @generated
31
32
  * @see https://github.com/webgptorg/promptbook
32
33
  */
33
- const PROMPTBOOK_ENGINE_VERSION = '0.100.0-45';
34
+ const PROMPTBOOK_ENGINE_VERSION = '0.100.0-46';
34
35
  /**
35
36
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
36
37
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -238,6 +239,13 @@ const DEFAULT_IS_AUTO_INSTALLED = false;
238
239
  * @public exported from `@promptbook/core`
239
240
  */
240
241
  const DEFAULT_TASK_SIMULATED_DURATION_MS = 5 * 60 * 1000; // 5 minutes
242
+ /**
243
+ * API request timeout in milliseconds
244
+ * Can be overridden via API_REQUEST_TIMEOUT environment variable
245
+ *
246
+ * @public exported from `@promptbook/core`
247
+ */
248
+ parseInt(process.env.API_REQUEST_TIMEOUT || '90000');
241
249
  /**
242
250
  * Indicates whether pipeline logic validation is enabled. When true, the pipeline logic is checked for consistency.
243
251
  *
@@ -1287,7 +1295,7 @@ function prettifyMarkdown(content) {
1287
1295
  try {
1288
1296
  return format(content, {
1289
1297
  parser: 'markdown',
1290
- plugins: [parserHtml],
1298
+ plugins: [parserMarkdown, parserHtml],
1291
1299
  // TODO: DRY - make some import or auto-copy of .prettierrc
1292
1300
  endOfLine: 'lf',
1293
1301
  tabWidth: 4,
@@ -5011,64 +5019,74 @@ function createPipelineExecutor(options) {
5011
5019
  });
5012
5020
  });
5013
5021
  };
5014
- const pipelineExecutor = (inputParameters) => createTask({
5015
- taskType: 'EXECUTION',
5016
- title: pipeline.title,
5017
- taskProcessCallback(updateOngoingResult, updateTldr) {
5018
- return pipelineExecutorWithCallback(inputParameters, async (newOngoingResult) => {
5019
- var _a;
5020
- updateOngoingResult(newOngoingResult);
5021
- // Calculate and update tldr based on pipeline progress
5022
- const cv = newOngoingResult;
5023
- // Calculate progress based on pipeline tasks
5024
- const totalTasks = pipeline.tasks.length;
5025
- let completedTasks = 0;
5026
- let currentTaskName = '';
5027
- // Check execution report for completed tasks
5028
- if ((_a = cv === null || cv === void 0 ? void 0 : cv.executionReport) === null || _a === void 0 ? void 0 : _a.promptExecutions) {
5029
- const executedTaskTitles = new Set(cv.executionReport.promptExecutions.map((execution) => execution.prompt.title));
5030
- // Count completed tasks by matching titles
5031
- const completedTasksByTitle = pipeline.tasks.filter((task) => executedTaskTitles.has(task.title));
5032
- completedTasks = completedTasksByTitle.length;
5033
- // Find current task being executed (first task not yet completed)
5034
- const remainingTasks = pipeline.tasks.filter((task) => !executedTaskTitles.has(task.title));
5035
- if (remainingTasks.length > 0) {
5036
- currentTaskName = remainingTasks[0].name;
5022
+ const pipelineExecutor = (inputParameters) => {
5023
+ const startTime = new Date().getTime();
5024
+ return createTask({
5025
+ taskType: 'EXECUTION',
5026
+ title: pipeline.title,
5027
+ taskProcessCallback(updateOngoingResult, updateTldr) {
5028
+ return pipelineExecutorWithCallback(inputParameters, async (newOngoingResult) => {
5029
+ var _a, _b;
5030
+ updateOngoingResult(newOngoingResult);
5031
+ // Calculate and update tldr based on pipeline progress
5032
+ const cv = newOngoingResult;
5033
+ // Calculate progress based on parameters resolved vs total parameters
5034
+ const totalParameters = pipeline.parameters.filter(p => !p.isInput).length;
5035
+ let resolvedParameters = 0;
5036
+ let currentTaskTitle = '';
5037
+ // Get the resolved parameters from output parameters
5038
+ if (cv === null || cv === void 0 ? void 0 : cv.outputParameters) {
5039
+ // Count how many output parameters have non-empty values
5040
+ resolvedParameters = Object.values(cv.outputParameters).filter(value => value !== undefined && value !== null && String(value).trim() !== '').length;
5037
5041
  }
5038
- }
5039
- // Calculate progress percentage
5040
- let percent = totalTasks > 0 ? completedTasks / totalTasks : 0;
5041
- // Add time-based progress for current task (assuming 5 minutes total)
5042
- if (completedTasks < totalTasks) {
5043
- const elapsedMs = new Date().getTime() - new Date().getTime(); // Will be overridden by actual elapsed time in task
5044
- const totalMs = 5 * 60 * 1000; // 5 minutes
5045
- const timeProgress = Math.min(elapsedMs / totalMs, 1);
5046
- // Add partial progress for current task
5047
- percent += (1 / totalTasks) * timeProgress;
5048
- }
5049
- // Clamp to [0,1]
5050
- percent = Math.min(Math.max(percent, 0), 1);
5051
- // Generate message
5052
- let message = '';
5053
- if (currentTaskName) {
5054
- // Find the task to get its title
5055
- const currentTask = pipeline.tasks.find((task) => task.name === currentTaskName);
5056
- const taskTitle = (currentTask === null || currentTask === void 0 ? void 0 : currentTask.title) || currentTaskName;
5057
- message = `Working on task ${taskTitle}`;
5058
- }
5059
- else if (completedTasks === 0) {
5060
- message = 'Starting pipeline execution';
5061
- }
5062
- else {
5063
- message = `Processing pipeline (${completedTasks}/${totalTasks} tasks completed)`;
5064
- }
5065
- updateTldr({
5066
- percent: percent,
5067
- message,
5042
+ // Try to determine current task from execution report
5043
+ if (((_a = cv === null || cv === void 0 ? void 0 : cv.executionReport) === null || _a === void 0 ? void 0 : _a.promptExecutions) && cv.executionReport.promptExecutions.length > 0) {
5044
+ const lastExecution = cv.executionReport.promptExecutions[cv.executionReport.promptExecutions.length - 1];
5045
+ if ((_b = lastExecution === null || lastExecution === void 0 ? void 0 : lastExecution.prompt) === null || _b === void 0 ? void 0 : _b.title) {
5046
+ currentTaskTitle = lastExecution.prompt.title;
5047
+ }
5048
+ }
5049
+ // Calculate base progress percentage
5050
+ let percent = totalParameters > 0 ? resolvedParameters / totalParameters : 0;
5051
+ // Add time-based progress for current task if we haven't completed all parameters
5052
+ if (resolvedParameters < totalParameters) {
5053
+ const elapsedMs = new Date().getTime() - startTime;
5054
+ const estimatedTotalMs = totalParameters * 30 * 1000; // Estimate 30 seconds per parameter
5055
+ const timeProgress = Math.min(elapsedMs / estimatedTotalMs, 0.9); // Cap at 90% for time-based progress
5056
+ // If we have time progress but no parameter progress, show time progress
5057
+ if (percent === 0 && timeProgress > 0) {
5058
+ percent = Math.min(timeProgress, 0.1); // Show some progress but not more than 10%
5059
+ }
5060
+ else if (percent < 1) {
5061
+ // Add partial progress for current task
5062
+ const taskProgress = totalParameters > 0 ? (1 / totalParameters) * 0.5 : 0; // 50% of task progress
5063
+ percent = Math.min(percent + taskProgress, 0.95); // Cap at 95% until fully complete
5064
+ }
5065
+ }
5066
+ // Clamp to [0,1]
5067
+ percent = Math.min(Math.max(percent, 0), 1);
5068
+ // Generate message
5069
+ let message = '';
5070
+ if (currentTaskTitle) {
5071
+ message = `Executing: ${currentTaskTitle}`;
5072
+ }
5073
+ else if (resolvedParameters === 0) {
5074
+ message = 'Starting pipeline execution';
5075
+ }
5076
+ else if (resolvedParameters < totalParameters) {
5077
+ message = `Processing pipeline (${resolvedParameters}/${totalParameters} parameters resolved)`;
5078
+ }
5079
+ else {
5080
+ message = 'Completing pipeline execution';
5081
+ }
5082
+ updateTldr({
5083
+ percent: percent,
5084
+ message,
5085
+ });
5068
5086
  });
5069
- });
5070
- },
5071
- });
5087
+ },
5088
+ });
5089
+ };
5072
5090
  // <- TODO: Make types such as there is no need to do `as` for `createTask`
5073
5091
  return pipelineExecutor;
5074
5092
  }
@@ -5204,7 +5222,7 @@ async function preparePersona(personaDescription, tools, options) {
5204
5222
  const result = await preparePersonaExecutor({
5205
5223
  availableModels /* <- Note: Passing as JSON */,
5206
5224
  personaDescription,
5207
- }).asPromise();
5225
+ }).asPromise({ isCrashedOnError: true });
5208
5226
  const { outputParameters } = result;
5209
5227
  const { modelsRequirements: modelsRequirementsJson } = outputParameters;
5210
5228
  let modelsRequirementsUnchecked = jsonParse(modelsRequirementsJson);
@@ -6094,7 +6112,7 @@ async function preparePipeline(pipeline, tools, options) {
6094
6112
  });
6095
6113
  const result = await prepareTitleExecutor({
6096
6114
  book: sources.map(({ content }) => content).join('\n\n'),
6097
- }).asPromise();
6115
+ }).asPromise({ isCrashedOnError: true });
6098
6116
  const { outputParameters } = result;
6099
6117
  const { title: titleRaw } = outputParameters;
6100
6118
  if (isVerbose) {
@@ -10802,31 +10820,23 @@ function extractBlock(markdown) {
10802
10820
  return content;
10803
10821
  }
10804
10822
 
10823
+ /**
10824
+ * @private internal for `preserve`
10825
+ */
10826
+ const _preserved = [];
10805
10827
  /**
10806
10828
  * Does nothing, but preserves the function in the bundle
10807
10829
  * Compiler is tricked into thinking the function is used
10808
10830
  *
10809
10831
  * @param value any function to preserve
10810
10832
  * @returns nothing
10811
- * @private internal function of `JavascriptExecutionTools` and `JavascriptEvalExecutionTools`
10812
- */
10813
- function preserve(func) {
10814
- // Note: NOT calling the function
10815
- (async () => {
10816
- // TODO: [💩] Change to `await forEver` or `forTime(Infinity)`
10817
- await forTime(100000000);
10818
- // [1]
10819
- try {
10820
- await func();
10821
- }
10822
- finally {
10823
- // do nothing
10824
- }
10825
- })();
10833
+ * @private within the repository
10834
+ */
10835
+ function $preserve(...value) {
10836
+ _preserved.push(...value);
10826
10837
  }
10827
10838
  /**
10828
- * TODO: Probably remove in favour of `keepImported`
10829
- * TODO: [1] This maybe does memory leak
10839
+ * Note: [💞] Ignore a discrepancy between file name and entity name
10830
10840
  */
10831
10841
 
10832
10842
  // Note: [💎]
@@ -10854,25 +10864,25 @@ class JavascriptEvalExecutionTools {
10854
10864
  // Note: [💎]
10855
10865
  // Note: Using direct eval, following variables are in same scope as eval call so they are accessible from inside the evaluated script:
10856
10866
  const spaceTrim$1 = (_) => spaceTrim(_);
10857
- preserve(spaceTrim$1);
10867
+ $preserve(spaceTrim$1);
10858
10868
  const removeQuotes$1 = removeQuotes;
10859
- preserve(removeQuotes$1);
10869
+ $preserve(removeQuotes$1);
10860
10870
  const unwrapResult$1 = unwrapResult;
10861
- preserve(unwrapResult$1);
10871
+ $preserve(unwrapResult$1);
10862
10872
  const trimEndOfCodeBlock$1 = trimEndOfCodeBlock;
10863
- preserve(trimEndOfCodeBlock$1);
10873
+ $preserve(trimEndOfCodeBlock$1);
10864
10874
  const trimCodeBlock$1 = trimCodeBlock;
10865
- preserve(trimCodeBlock$1);
10875
+ $preserve(trimCodeBlock$1);
10866
10876
  // TODO: DRY [🍯]
10867
10877
  const trim = (str) => str.trim();
10868
- preserve(trim);
10878
+ $preserve(trim);
10869
10879
  // TODO: DRY [🍯]
10870
10880
  const reverse = (str) => str.split('').reverse().join('');
10871
- preserve(reverse);
10881
+ $preserve(reverse);
10872
10882
  const removeEmojis$1 = removeEmojis;
10873
- preserve(removeEmojis$1);
10883
+ $preserve(removeEmojis$1);
10874
10884
  const prettifyMarkdown$1 = prettifyMarkdown;
10875
- preserve(prettifyMarkdown$1);
10885
+ $preserve(prettifyMarkdown$1);
10876
10886
  //-------[n12:]---
10877
10887
  const capitalize$1 = capitalize;
10878
10888
  const decapitalize$1 = decapitalize;
@@ -10888,18 +10898,18 @@ class JavascriptEvalExecutionTools {
10888
10898
  // TODO: DRY [🍯]
10889
10899
  Array.from(parseKeywordsFromString(input)).join(', '); /* <- TODO: [🧠] What is the best format comma list, bullet list,...? */
10890
10900
  const normalizeTo_SCREAMING_CASE$1 = normalizeTo_SCREAMING_CASE;
10891
- preserve(capitalize$1);
10892
- preserve(decapitalize$1);
10893
- preserve(nameToUriPart$1);
10894
- preserve(nameToUriParts$1);
10895
- preserve(removeDiacritics$1);
10896
- preserve(normalizeWhitespaces$1);
10897
- preserve(normalizeToKebabCase$1);
10898
- preserve(normalizeTo_camelCase$1);
10899
- preserve(normalizeTo_snake_case$1);
10900
- preserve(normalizeTo_PascalCase$1);
10901
- preserve(parseKeywords);
10902
- preserve(normalizeTo_SCREAMING_CASE$1);
10901
+ $preserve(capitalize$1);
10902
+ $preserve(decapitalize$1);
10903
+ $preserve(nameToUriPart$1);
10904
+ $preserve(nameToUriParts$1);
10905
+ $preserve(removeDiacritics$1);
10906
+ $preserve(normalizeWhitespaces$1);
10907
+ $preserve(normalizeToKebabCase$1);
10908
+ $preserve(normalizeTo_camelCase$1);
10909
+ $preserve(normalizeTo_snake_case$1);
10910
+ $preserve(normalizeTo_PascalCase$1);
10911
+ $preserve(parseKeywords);
10912
+ $preserve(normalizeTo_SCREAMING_CASE$1);
10903
10913
  //-------[/n12]---
10904
10914
  if (!script.includes('return')) {
10905
10915
  script = `return ${script}`;