@promptbook/core 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
@@ -27,7 +27,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
27
27
  * @generated
28
28
  * @see https://github.com/webgptorg/promptbook
29
29
  */
30
- const PROMPTBOOK_ENGINE_VERSION = '0.86.22';
30
+ const PROMPTBOOK_ENGINE_VERSION = '0.86.31';
31
31
  /**
32
32
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
33
33
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -2326,119 +2326,60 @@ function addUsage(...usageItems) {
2326
2326
  }
2327
2327
 
2328
2328
  /**
2329
- * Extract all used variable names from ginen JavaScript/TypeScript script
2329
+ * Parses the given script and returns the list of all used variables that are not defined in the script
2330
2330
  *
2331
- * @param script JavaScript/TypeScript script
2332
- * @returns Set of variable names
2331
+ * @param script from which to extract the variables
2332
+ * @returns the list of variable names
2333
2333
  * @throws {ParseError} if the script is invalid
2334
- * @public exported from `@promptbook/utils` <- Note: [👖] This is usable elsewhere than in Promptbook, so keeping in utils
2334
+ * @public exported from `@promptbook/execute-javascript`
2335
2335
  */
2336
- function extractVariablesFromScript(script) {
2337
- if (script.trim() === '') {
2338
- return new Set();
2339
- }
2336
+ function extractVariablesFromJavascript(script) {
2340
2337
  const variables = new Set();
2341
- // JS keywords and builtins to exclude
2342
- const exclude = new Set([
2343
- // Keywords
2344
- 'break',
2345
- 'case',
2346
- 'catch',
2347
- 'class',
2348
- 'const',
2349
- 'continue',
2350
- 'debugger',
2351
- 'default',
2352
- 'delete',
2353
- 'do',
2354
- 'else',
2355
- 'export',
2356
- 'extends',
2357
- 'false',
2358
- 'finally',
2359
- 'for',
2360
- 'function',
2361
- 'if',
2362
- 'import',
2363
- 'in',
2364
- 'instanceof',
2365
- 'let',
2366
- 'new',
2367
- 'null',
2368
- 'return',
2369
- 'super',
2370
- 'switch',
2371
- 'this',
2372
- 'throw',
2373
- 'true',
2374
- 'try',
2375
- 'typeof',
2376
- 'var',
2377
- 'void',
2378
- 'while',
2379
- 'with',
2380
- 'yield',
2381
- // Common globals
2382
- 'console',
2383
- 'JSON',
2384
- 'Error',
2385
- // Typescript types
2386
- 'string',
2387
- 'number',
2388
- 'boolean',
2389
- 'object',
2390
- 'symbol',
2391
- // Common methods on built-in objects
2392
- 'test',
2393
- 'match',
2394
- 'exec',
2395
- 'replace',
2396
- 'search',
2397
- 'split',
2398
- ]);
2338
+ const originalScript = script;
2339
+ script = `(()=>{${script}})()`;
2399
2340
  try {
2400
- // Note: Extract variables from template literals like ${variable}
2401
- const templateRegex = /\$\{([a-zA-Z_$][a-zA-Z0-9_$]*)\}/g;
2402
- let match;
2403
- while ((match = templateRegex.exec(script)) !== null) {
2404
- const varName = match[1];
2405
- if (!exclude.has(varName)) {
2406
- variables.add(varName);
2341
+ for (let i = 0; i < LOOP_LIMIT; i++)
2342
+ try {
2343
+ eval(script); // <- TODO: Use `JavascriptExecutionTools.execute` here
2407
2344
  }
2408
- }
2409
- // Note: Process the script to handle normal variable usage
2410
- const processedScript = script
2411
- .replace(/'(?:\\.|[^'\\])*'/g, "''") // <- Note: Remove string literals
2412
- .replace(/"(?:\\.|[^"\\])*"/g, '""')
2413
- .replace(/`(?:\\.|[^`\\])*`/g, '``')
2414
- .replace(/\/(?:\\.|[^/\\])*\/[gimsuy]*/g, '{}'); // <- Note: Remove regex literals
2415
- // Note: Find identifiers in function arguments
2416
- const funcArgRegex = /\b([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/g;
2417
- const funcNames = new Set();
2418
- while ((match = funcArgRegex.exec(processedScript)) !== null) {
2419
- funcNames.add(match[1]);
2420
- }
2421
- // Find variable declarations to exclude them
2422
- const declaredVars = new Set();
2423
- const declRegex = /\b(const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\b/g;
2424
- while ((match = declRegex.exec(processedScript)) !== null) {
2425
- declaredVars.add(match[2]);
2426
- }
2427
- // Note: Find identifiers in the script
2428
- const identifierRegex = /\b([a-zA-Z_$][a-zA-Z0-9_$]*)\b/g;
2429
- while ((match = identifierRegex.exec(processedScript)) !== null) {
2430
- const name = match[1];
2431
- // Add if not excluded, not a function name, and not a declared variable
2432
- if (!exclude.has(name) && !funcNames.has(name) && !declaredVars.has(name)) {
2433
- variables.add(name);
2345
+ catch (error) {
2346
+ if (!(error instanceof ReferenceError)) {
2347
+ throw error;
2348
+ }
2349
+ /*
2350
+ Note: Parsing the error
2351
+ 🌟 Most devices:
2352
+ [PipelineUrlError: thing is not defined]
2353
+
2354
+ 🍏 iPhone`s Safari:
2355
+ [PipelineUrlError: Can't find variable: thing]
2356
+ */
2357
+ let variableName = undefined;
2358
+ if (error.message.startsWith(`Can't`)) {
2359
+ // 🍏 Case
2360
+ variableName = error.message.split(' ').pop();
2361
+ }
2362
+ else {
2363
+ // 🌟 Case
2364
+ variableName = error.message.split(' ').shift();
2365
+ }
2366
+ if (variableName === undefined) {
2367
+ throw error;
2368
+ }
2369
+ if (script.includes(variableName + '(')) {
2370
+ script = `const ${variableName} = ()=>'';` + script;
2371
+ }
2372
+ else {
2373
+ variables.add(variableName);
2374
+ script = `const ${variableName} = '';` + script;
2375
+ }
2434
2376
  }
2435
- }
2436
2377
  }
2437
2378
  catch (error) {
2438
2379
  if (!(error instanceof Error)) {
2439
2380
  throw error;
2440
2381
  }
2441
- throw new ParseError(spaceTrim((block) => `
2382
+ throw new ParseError(spaceTrim$1((block) => `
2442
2383
  Can not extract variables from the script
2443
2384
  ${block(error.stack || error.message)}
2444
2385
 
@@ -2451,7 +2392,7 @@ function extractVariablesFromScript(script) {
2451
2392
  The script:
2452
2393
 
2453
2394
  \`\`\`javascript
2454
- ${block(script)}
2395
+ ${block(originalScript)}
2455
2396
  \`\`\`
2456
2397
  `));
2457
2398
  }
@@ -2472,19 +2413,24 @@ function extractVariablesFromScript(script) {
2472
2413
  function extractParameterNamesFromTask(task) {
2473
2414
  const { title, description, taskType, content, preparedContent, jokerParameterNames, foreach } = task;
2474
2415
  const parameterNames = new Set();
2416
+ let contentParameters;
2417
+ if (taskType !== 'SCRIPT_TASK') {
2418
+ contentParameters = extractParameterNames(content);
2419
+ }
2420
+ else {
2421
+ // TODO: What if script is not javascript?
2422
+ // const { contentLanguage } = task;
2423
+ // if (contentLanguage !== 'javascript') {
2424
+ contentParameters = extractVariablesFromJavascript(content);
2425
+ }
2475
2426
  for (const parameterName of [
2476
2427
  ...extractParameterNames(title),
2477
2428
  ...extractParameterNames(description || ''),
2478
- ...extractParameterNames(content),
2429
+ ...contentParameters,
2479
2430
  ...extractParameterNames(preparedContent || ''),
2480
2431
  ]) {
2481
2432
  parameterNames.add(parameterName);
2482
2433
  }
2483
- if (taskType === 'SCRIPT_TASK') {
2484
- for (const parameterName of extractVariablesFromScript(content)) {
2485
- parameterNames.add(parameterName);
2486
- }
2487
- }
2488
2434
  for (const jokerName of jokerParameterNames || []) {
2489
2435
  parameterNames.add(jokerName);
2490
2436
  }