@promptbook/cli 0.86.22 → 0.86.31

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
@@ -44,7 +44,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
44
44
  * @generated
45
45
  * @see https://github.com/webgptorg/promptbook
46
46
  */
47
- const PROMPTBOOK_ENGINE_VERSION = '0.86.22';
47
+ const PROMPTBOOK_ENGINE_VERSION = '0.86.31';
48
48
  /**
49
49
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
50
50
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -3237,158 +3237,6 @@ function renderPromptbookMermaid(pipelineJson, options) {
3237
3237
  * TODO: [🕌] When more than 2 functionalities, split into separate functions
3238
3238
  */
3239
3239
 
3240
- /**
3241
- * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
3242
- *
3243
- * @public exported from `@promptbook/core`
3244
- */
3245
- class ParseError extends Error {
3246
- constructor(message) {
3247
- super(message);
3248
- this.name = 'ParseError';
3249
- Object.setPrototypeOf(this, ParseError.prototype);
3250
- }
3251
- }
3252
- /**
3253
- * TODO: Maybe split `ParseError` and `ApplyError`
3254
- */
3255
-
3256
- /**
3257
- * Extract all used variable names from ginen JavaScript/TypeScript script
3258
- *
3259
- * @param script JavaScript/TypeScript script
3260
- * @returns Set of variable names
3261
- * @throws {ParseError} if the script is invalid
3262
- * @public exported from `@promptbook/utils` <- Note: [👖] This is usable elsewhere than in Promptbook, so keeping in utils
3263
- */
3264
- function extractVariablesFromScript(script) {
3265
- if (script.trim() === '') {
3266
- return new Set();
3267
- }
3268
- const variables = new Set();
3269
- // JS keywords and builtins to exclude
3270
- const exclude = new Set([
3271
- // Keywords
3272
- 'break',
3273
- 'case',
3274
- 'catch',
3275
- 'class',
3276
- 'const',
3277
- 'continue',
3278
- 'debugger',
3279
- 'default',
3280
- 'delete',
3281
- 'do',
3282
- 'else',
3283
- 'export',
3284
- 'extends',
3285
- 'false',
3286
- 'finally',
3287
- 'for',
3288
- 'function',
3289
- 'if',
3290
- 'import',
3291
- 'in',
3292
- 'instanceof',
3293
- 'let',
3294
- 'new',
3295
- 'null',
3296
- 'return',
3297
- 'super',
3298
- 'switch',
3299
- 'this',
3300
- 'throw',
3301
- 'true',
3302
- 'try',
3303
- 'typeof',
3304
- 'var',
3305
- 'void',
3306
- 'while',
3307
- 'with',
3308
- 'yield',
3309
- // Common globals
3310
- 'console',
3311
- 'JSON',
3312
- 'Error',
3313
- // Typescript types
3314
- 'string',
3315
- 'number',
3316
- 'boolean',
3317
- 'object',
3318
- 'symbol',
3319
- // Common methods on built-in objects
3320
- 'test',
3321
- 'match',
3322
- 'exec',
3323
- 'replace',
3324
- 'search',
3325
- 'split',
3326
- ]);
3327
- try {
3328
- // Note: Extract variables from template literals like ${variable}
3329
- const templateRegex = /\$\{([a-zA-Z_$][a-zA-Z0-9_$]*)\}/g;
3330
- let match;
3331
- while ((match = templateRegex.exec(script)) !== null) {
3332
- const varName = match[1];
3333
- if (!exclude.has(varName)) {
3334
- variables.add(varName);
3335
- }
3336
- }
3337
- // Note: Process the script to handle normal variable usage
3338
- const processedScript = script
3339
- .replace(/'(?:\\.|[^'\\])*'/g, "''") // <- Note: Remove string literals
3340
- .replace(/"(?:\\.|[^"\\])*"/g, '""')
3341
- .replace(/`(?:\\.|[^`\\])*`/g, '``')
3342
- .replace(/\/(?:\\.|[^/\\])*\/[gimsuy]*/g, '{}'); // <- Note: Remove regex literals
3343
- // Note: Find identifiers in function arguments
3344
- const funcArgRegex = /\b([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/g;
3345
- const funcNames = new Set();
3346
- while ((match = funcArgRegex.exec(processedScript)) !== null) {
3347
- funcNames.add(match[1]);
3348
- }
3349
- // Find variable declarations to exclude them
3350
- const declaredVars = new Set();
3351
- const declRegex = /\b(const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\b/g;
3352
- while ((match = declRegex.exec(processedScript)) !== null) {
3353
- declaredVars.add(match[2]);
3354
- }
3355
- // Note: Find identifiers in the script
3356
- const identifierRegex = /\b([a-zA-Z_$][a-zA-Z0-9_$]*)\b/g;
3357
- while ((match = identifierRegex.exec(processedScript)) !== null) {
3358
- const name = match[1];
3359
- // Add if not excluded, not a function name, and not a declared variable
3360
- if (!exclude.has(name) && !funcNames.has(name) && !declaredVars.has(name)) {
3361
- variables.add(name);
3362
- }
3363
- }
3364
- }
3365
- catch (error) {
3366
- if (!(error instanceof Error)) {
3367
- throw error;
3368
- }
3369
- throw new ParseError(spaceTrim((block) => `
3370
- Can not extract variables from the script
3371
- ${block(error.stack || error.message)}
3372
-
3373
- Found variables:
3374
- ${Array.from(variables)
3375
- .map((variableName, i) => `${i + 1}) ${variableName}`)
3376
- .join('\n')}
3377
-
3378
-
3379
- The script:
3380
-
3381
- \`\`\`javascript
3382
- ${block(script)}
3383
- \`\`\`
3384
- `));
3385
- }
3386
- return variables;
3387
- }
3388
- /**
3389
- * TODO: [🔣] Support for multiple languages - python, java,...
3390
- */
3391
-
3392
3240
  /**
3393
3241
  * This error indicates problems parsing the format value
3394
3242
  *
@@ -3505,6 +3353,22 @@ class NotFoundError extends Error {
3505
3353
  }
3506
3354
  }
3507
3355
 
3356
+ /**
3357
+ * This error indicates that the promptbook in a markdown format cannot be parsed into a valid promptbook object
3358
+ *
3359
+ * @public exported from `@promptbook/core`
3360
+ */
3361
+ class ParseError extends Error {
3362
+ constructor(message) {
3363
+ super(message);
3364
+ this.name = 'ParseError';
3365
+ Object.setPrototypeOf(this, ParseError.prototype);
3366
+ }
3367
+ }
3368
+ /**
3369
+ * TODO: Maybe split `ParseError` and `ApplyError`
3370
+ */
3371
+
3508
3372
  /**
3509
3373
  * This error indicates that the promptbook object has valid syntax (=can be parsed) but contains logical errors (like circular dependencies)
3510
3374
  *
@@ -4685,6 +4549,7 @@ class JavascriptEvalExecutionTools {
4685
4549
  // Note: Custom functions are exposed to the current scope as variables
4686
4550
  `const ${functionName} = customFunctions.${functionName};`)
4687
4551
  .join('\n');
4552
+ script = templateParameters(script, parameters);
4688
4553
  const statementToEvaluate = spaceTrim((block) => `
4689
4554
 
4690
4555
  // Build-in functions:
@@ -5584,6 +5449,83 @@ function createTask(options) {
5584
5449
  * TODO: [🐚] Split into more files and make `PrepareTask` & `RemoteTask` + split the function
5585
5450
  */
5586
5451
 
5452
+ /**
5453
+ * Parses the given script and returns the list of all used variables that are not defined in the script
5454
+ *
5455
+ * @param script from which to extract the variables
5456
+ * @returns the list of variable names
5457
+ * @throws {ParseError} if the script is invalid
5458
+ * @public exported from `@promptbook/execute-javascript`
5459
+ */
5460
+ function extractVariablesFromJavascript(script) {
5461
+ const variables = new Set();
5462
+ const originalScript = script;
5463
+ script = `(()=>{${script}})()`;
5464
+ try {
5465
+ for (let i = 0; i < LOOP_LIMIT; i++)
5466
+ try {
5467
+ eval(script); // <- TODO: Use `JavascriptExecutionTools.execute` here
5468
+ }
5469
+ catch (error) {
5470
+ if (!(error instanceof ReferenceError)) {
5471
+ throw error;
5472
+ }
5473
+ /*
5474
+ Note: Parsing the error
5475
+ 🌟 Most devices:
5476
+ [PipelineUrlError: thing is not defined]
5477
+
5478
+ 🍏 iPhone`s Safari:
5479
+ [PipelineUrlError: Can't find variable: thing]
5480
+ */
5481
+ let variableName = undefined;
5482
+ if (error.message.startsWith(`Can't`)) {
5483
+ // 🍏 Case
5484
+ variableName = error.message.split(' ').pop();
5485
+ }
5486
+ else {
5487
+ // 🌟 Case
5488
+ variableName = error.message.split(' ').shift();
5489
+ }
5490
+ if (variableName === undefined) {
5491
+ throw error;
5492
+ }
5493
+ if (script.includes(variableName + '(')) {
5494
+ script = `const ${variableName} = ()=>'';` + script;
5495
+ }
5496
+ else {
5497
+ variables.add(variableName);
5498
+ script = `const ${variableName} = '';` + script;
5499
+ }
5500
+ }
5501
+ }
5502
+ catch (error) {
5503
+ if (!(error instanceof Error)) {
5504
+ throw error;
5505
+ }
5506
+ throw new ParseError(spaceTrim$1((block) => `
5507
+ Can not extract variables from the script
5508
+ ${block(error.stack || error.message)}
5509
+
5510
+ Found variables:
5511
+ ${Array.from(variables)
5512
+ .map((variableName, i) => `${i + 1}) ${variableName}`)
5513
+ .join('\n')}
5514
+
5515
+
5516
+ The script:
5517
+
5518
+ \`\`\`javascript
5519
+ ${block(originalScript)}
5520
+ \`\`\`
5521
+ `));
5522
+ }
5523
+ return variables;
5524
+ }
5525
+ /**
5526
+ * TODO: [🔣] Support for multiple languages - python, java,...
5527
+ */
5528
+
5587
5529
  /**
5588
5530
  * Parses the task and returns the set of all used parameters
5589
5531
  *
@@ -5595,19 +5537,24 @@ function createTask(options) {
5595
5537
  function extractParameterNamesFromTask(task) {
5596
5538
  const { title, description, taskType, content, preparedContent, jokerParameterNames, foreach } = task;
5597
5539
  const parameterNames = new Set();
5540
+ let contentParameters;
5541
+ if (taskType !== 'SCRIPT_TASK') {
5542
+ contentParameters = extractParameterNames(content);
5543
+ }
5544
+ else {
5545
+ // TODO: What if script is not javascript?
5546
+ // const { contentLanguage } = task;
5547
+ // if (contentLanguage !== 'javascript') {
5548
+ contentParameters = extractVariablesFromJavascript(content);
5549
+ }
5598
5550
  for (const parameterName of [
5599
5551
  ...extractParameterNames(title),
5600
5552
  ...extractParameterNames(description || ''),
5601
- ...extractParameterNames(content),
5553
+ ...contentParameters,
5602
5554
  ...extractParameterNames(preparedContent || ''),
5603
5555
  ]) {
5604
5556
  parameterNames.add(parameterName);
5605
5557
  }
5606
- if (taskType === 'SCRIPT_TASK') {
5607
- for (const parameterName of extractVariablesFromScript(content)) {
5608
- parameterNames.add(parameterName);
5609
- }
5610
- }
5611
5558
  for (const jokerName of jokerParameterNames || []) {
5612
5559
  parameterNames.add(jokerName);
5613
5560
  }