@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 +106 -159
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/_packages/execute-javascript.index.d.ts +2 -0
- package/esm/typings/src/_packages/utils.index.d.ts +0 -2
- package/esm/typings/src/scripting/javascript/utils/extractVariablesFromJavascript.d.ts +14 -0
- package/esm/typings/src/scripting/javascript/utils/extractVariablesFromScript.test.d.ts +1 -0
- package/package.json +1 -1
- package/umd/index.umd.js +106 -159
- package/umd/index.umd.js.map +1 -1
- package/esm/typings/src/conversion/utils/extractVariablesFromScript.d.ts +0 -14
- /package/esm/typings/src/{conversion/utils/extractVariablesFromScript.test.d.ts → scripting/javascript/utils/extractVariablesFromJavascript.test.d.ts} +0 -0
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.
|
|
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
|
-
...
|
|
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
|
}
|