@promptbook/node 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
@@ -30,7 +30,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
30
30
  * @generated
31
31
  * @see https://github.com/webgptorg/promptbook
32
32
  */
33
- const PROMPTBOOK_ENGINE_VERSION = '0.86.22';
33
+ const PROMPTBOOK_ENGINE_VERSION = '0.86.31';
34
34
  /**
35
35
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
36
36
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -2117,119 +2117,60 @@ function addUsage(...usageItems) {
2117
2117
  }
2118
2118
 
2119
2119
  /**
2120
- * Extract all used variable names from ginen JavaScript/TypeScript script
2120
+ * Parses the given script and returns the list of all used variables that are not defined in the script
2121
2121
  *
2122
- * @param script JavaScript/TypeScript script
2123
- * @returns Set of variable names
2122
+ * @param script from which to extract the variables
2123
+ * @returns the list of variable names
2124
2124
  * @throws {ParseError} if the script is invalid
2125
- * @public exported from `@promptbook/utils` <- Note: [👖] This is usable elsewhere than in Promptbook, so keeping in utils
2125
+ * @public exported from `@promptbook/execute-javascript`
2126
2126
  */
2127
- function extractVariablesFromScript(script) {
2128
- if (script.trim() === '') {
2129
- return new Set();
2130
- }
2127
+ function extractVariablesFromJavascript(script) {
2131
2128
  const variables = new Set();
2132
- // JS keywords and builtins to exclude
2133
- const exclude = new Set([
2134
- // Keywords
2135
- 'break',
2136
- 'case',
2137
- 'catch',
2138
- 'class',
2139
- 'const',
2140
- 'continue',
2141
- 'debugger',
2142
- 'default',
2143
- 'delete',
2144
- 'do',
2145
- 'else',
2146
- 'export',
2147
- 'extends',
2148
- 'false',
2149
- 'finally',
2150
- 'for',
2151
- 'function',
2152
- 'if',
2153
- 'import',
2154
- 'in',
2155
- 'instanceof',
2156
- 'let',
2157
- 'new',
2158
- 'null',
2159
- 'return',
2160
- 'super',
2161
- 'switch',
2162
- 'this',
2163
- 'throw',
2164
- 'true',
2165
- 'try',
2166
- 'typeof',
2167
- 'var',
2168
- 'void',
2169
- 'while',
2170
- 'with',
2171
- 'yield',
2172
- // Common globals
2173
- 'console',
2174
- 'JSON',
2175
- 'Error',
2176
- // Typescript types
2177
- 'string',
2178
- 'number',
2179
- 'boolean',
2180
- 'object',
2181
- 'symbol',
2182
- // Common methods on built-in objects
2183
- 'test',
2184
- 'match',
2185
- 'exec',
2186
- 'replace',
2187
- 'search',
2188
- 'split',
2189
- ]);
2129
+ const originalScript = script;
2130
+ script = `(()=>{${script}})()`;
2190
2131
  try {
2191
- // Note: Extract variables from template literals like ${variable}
2192
- const templateRegex = /\$\{([a-zA-Z_$][a-zA-Z0-9_$]*)\}/g;
2193
- let match;
2194
- while ((match = templateRegex.exec(script)) !== null) {
2195
- const varName = match[1];
2196
- if (!exclude.has(varName)) {
2197
- variables.add(varName);
2132
+ for (let i = 0; i < LOOP_LIMIT; i++)
2133
+ try {
2134
+ eval(script); // <- TODO: Use `JavascriptExecutionTools.execute` here
2198
2135
  }
2199
- }
2200
- // Note: Process the script to handle normal variable usage
2201
- const processedScript = script
2202
- .replace(/'(?:\\.|[^'\\])*'/g, "''") // <- Note: Remove string literals
2203
- .replace(/"(?:\\.|[^"\\])*"/g, '""')
2204
- .replace(/`(?:\\.|[^`\\])*`/g, '``')
2205
- .replace(/\/(?:\\.|[^/\\])*\/[gimsuy]*/g, '{}'); // <- Note: Remove regex literals
2206
- // Note: Find identifiers in function arguments
2207
- const funcArgRegex = /\b([a-zA-Z_$][a-zA-Z0-9_$]*)\s*\(/g;
2208
- const funcNames = new Set();
2209
- while ((match = funcArgRegex.exec(processedScript)) !== null) {
2210
- funcNames.add(match[1]);
2211
- }
2212
- // Find variable declarations to exclude them
2213
- const declaredVars = new Set();
2214
- const declRegex = /\b(const|let|var)\s+([a-zA-Z_$][a-zA-Z0-9_$]*)\b/g;
2215
- while ((match = declRegex.exec(processedScript)) !== null) {
2216
- declaredVars.add(match[2]);
2217
- }
2218
- // Note: Find identifiers in the script
2219
- const identifierRegex = /\b([a-zA-Z_$][a-zA-Z0-9_$]*)\b/g;
2220
- while ((match = identifierRegex.exec(processedScript)) !== null) {
2221
- const name = match[1];
2222
- // Add if not excluded, not a function name, and not a declared variable
2223
- if (!exclude.has(name) && !funcNames.has(name) && !declaredVars.has(name)) {
2224
- variables.add(name);
2136
+ catch (error) {
2137
+ if (!(error instanceof ReferenceError)) {
2138
+ throw error;
2139
+ }
2140
+ /*
2141
+ Note: Parsing the error
2142
+ 🌟 Most devices:
2143
+ [PipelineUrlError: thing is not defined]
2144
+
2145
+ 🍏 iPhone`s Safari:
2146
+ [PipelineUrlError: Can't find variable: thing]
2147
+ */
2148
+ let variableName = undefined;
2149
+ if (error.message.startsWith(`Can't`)) {
2150
+ // 🍏 Case
2151
+ variableName = error.message.split(' ').pop();
2152
+ }
2153
+ else {
2154
+ // 🌟 Case
2155
+ variableName = error.message.split(' ').shift();
2156
+ }
2157
+ if (variableName === undefined) {
2158
+ throw error;
2159
+ }
2160
+ if (script.includes(variableName + '(')) {
2161
+ script = `const ${variableName} = ()=>'';` + script;
2162
+ }
2163
+ else {
2164
+ variables.add(variableName);
2165
+ script = `const ${variableName} = '';` + script;
2166
+ }
2225
2167
  }
2226
- }
2227
2168
  }
2228
2169
  catch (error) {
2229
2170
  if (!(error instanceof Error)) {
2230
2171
  throw error;
2231
2172
  }
2232
- throw new ParseError(spaceTrim((block) => `
2173
+ throw new ParseError(spaceTrim$1((block) => `
2233
2174
  Can not extract variables from the script
2234
2175
  ${block(error.stack || error.message)}
2235
2176
 
@@ -2242,7 +2183,7 @@ function extractVariablesFromScript(script) {
2242
2183
  The script:
2243
2184
 
2244
2185
  \`\`\`javascript
2245
- ${block(script)}
2186
+ ${block(originalScript)}
2246
2187
  \`\`\`
2247
2188
  `));
2248
2189
  }
@@ -2263,19 +2204,24 @@ function extractVariablesFromScript(script) {
2263
2204
  function extractParameterNamesFromTask(task) {
2264
2205
  const { title, description, taskType, content, preparedContent, jokerParameterNames, foreach } = task;
2265
2206
  const parameterNames = new Set();
2207
+ let contentParameters;
2208
+ if (taskType !== 'SCRIPT_TASK') {
2209
+ contentParameters = extractParameterNames(content);
2210
+ }
2211
+ else {
2212
+ // TODO: What if script is not javascript?
2213
+ // const { contentLanguage } = task;
2214
+ // if (contentLanguage !== 'javascript') {
2215
+ contentParameters = extractVariablesFromJavascript(content);
2216
+ }
2266
2217
  for (const parameterName of [
2267
2218
  ...extractParameterNames(title),
2268
2219
  ...extractParameterNames(description || ''),
2269
- ...extractParameterNames(content),
2220
+ ...contentParameters,
2270
2221
  ...extractParameterNames(preparedContent || ''),
2271
2222
  ]) {
2272
2223
  parameterNames.add(parameterName);
2273
2224
  }
2274
- if (taskType === 'SCRIPT_TASK') {
2275
- for (const parameterName of extractVariablesFromScript(content)) {
2276
- parameterNames.add(parameterName);
2277
- }
2278
- }
2279
2225
  for (const jokerName of jokerParameterNames || []) {
2280
2226
  parameterNames.add(jokerName);
2281
2227
  }
@@ -10065,6 +10011,7 @@ class JavascriptEvalExecutionTools {
10065
10011
  // Note: Custom functions are exposed to the current scope as variables
10066
10012
  `const ${functionName} = customFunctions.${functionName};`)
10067
10013
  .join('\n');
10014
+ script = templateParameters(script, parameters);
10068
10015
  const statementToEvaluate = spaceTrim((block) => `
10069
10016
 
10070
10017
  // Build-in functions: