diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa4739ae0..a16810bf2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -127,6 +127,14 @@ Cleanup and renaming
- Change command `PTBK_NAME` to `PROMPTBOOK_NAME` _(but keep backward compatibility and preserve alias `PTBK`)_
- Rename `runRemoteServer` -> `startRemoteServer` and return `Destroyable` object
+## !!! This branch !!!
+
+- Implement `JavascriptExecutionTools`
+- Deprecate `JavascriptEvalExecutionTools`
+- Do not allow to use `JavascriptEvalExecutionTools` in node.js environment
+
+---
+
## Upcomming
- Rename "natural" -> "llm"
diff --git a/samples/usage/logging/logging.ts.todo b/samples/usage/logging/logging.ts.todo
index 5e49213a2..4ff13c86a 100644
--- a/samples/usage/logging/logging.ts.todo
+++ b/samples/usage/logging/logging.ts.todo
@@ -34,7 +34,7 @@ async function main() {
openAiApiKey: process.env.OPENAI_API_KEY,
}),
script: [
- new JavascriptEvalExecutionTools({
+ new JavascriptExecutionTools({
isVerbose: true,
}),
],
diff --git a/samples/usage/remote/index.html b/samples/usage/remote/index.html
index fa25a662b..5d99a9d32 100644
--- a/samples/usage/remote/index.html
+++ b/samples/usage/remote/index.html
@@ -52,7 +52,7 @@
esting remote server of PromptBook
clientId,
}),
script: [
- new JavascriptEvalExecutionTools({
+ new JavascriptExecutionTools({
isVerbose: true,
}),
],
diff --git a/samples/usage/simple-script/simple-script.js b/samples/usage/simple-script/simple-script.js
index 1c1398f83..5df27f8f6 100644
--- a/samples/usage/simple-script/simple-script.js
+++ b/samples/usage/simple-script/simple-script.js
@@ -1,7 +1,7 @@
#!/usr/bin/env node
import { PromptbookLibrary } from '@promptbook/core';
-import { JavascriptEvalExecutionTools } from '@promptbook/execute-javascript';
+import { JavascriptExecutionTools } from '@promptbook/execute-javascript';
import { OpenAiExecutionTools } from '@promptbook/openai';
import { assertsExecutionSuccessful, executionReportJsonToString } from '@promptbook/utils';
import chalk from 'chalk';
@@ -38,7 +38,7 @@ async function main() {
openAiApiKey: process.env.OPENAI_API_KEY,
}),
script: [
- new JavascriptEvalExecutionTools({
+ new JavascriptExecutionTools({
isVerbose: true,
}),
],
diff --git a/src/execution/plugins/script-execution-tools/custom-function-async.test.ts.test.ts b/src/execution/plugins/script-execution-tools/custom-function-async.test.ts.test.ts
index 5931635cf..2f6e4903c 100644
--- a/src/execution/plugins/script-execution-tools/custom-function-async.test.ts.test.ts
+++ b/src/execution/plugins/script-execution-tools/custom-function-async.test.ts.test.ts
@@ -36,7 +36,7 @@ describe('createPromptbookExecutor + custom async function ', () => {
tools: {
natural: new MockedEchoNaturalExecutionTools({ isVerbose: true }),
script: [
- new JavascriptEvalExecutionTools({
+ new JavascriptExecutionTools({
isVerbose: true,
// Note: [🕎]
diff --git a/src/execution/plugins/script-execution-tools/custom-function-missing.test.ts b/src/execution/plugins/script-execution-tools/custom-function-missing.test.ts
index 8ae55a561..2c051c87f 100644
--- a/src/execution/plugins/script-execution-tools/custom-function-missing.test.ts
+++ b/src/execution/plugins/script-execution-tools/custom-function-missing.test.ts
@@ -6,7 +6,7 @@ import { assertsExecutionSuccessful } from '../../assertsExecutionSuccessful';
import { createPromptbookExecutor } from '../../createPromptbookExecutor';
import { MockedEchoNaturalExecutionTools } from '../natural-execution-tools/mocked/MockedEchoNaturalExecutionTools';
import { CallbackInterfaceTools } from '../user-interface-execution-tools/callback/CallbackInterfaceTools';
-import { JavascriptEvalExecutionTools } from './javascript/JavascriptEvalExecutionTools';
+import { JavascriptExecutionTools } from './javascript/JavascriptExecutionTools';
describe('createPromptbookExecutor + missing custom function', () => {
const promptbook = promptbookStringToJson(
@@ -36,7 +36,7 @@ describe('createPromptbookExecutor + missing custom function', () => {
tools: {
natural: new MockedEchoNaturalExecutionTools({ isVerbose: true }),
script: [
- new JavascriptEvalExecutionTools({
+ new JavascriptExecutionTools({
isVerbose: true,
// Note: [🕎]
diff --git a/src/execution/plugins/script-execution-tools/custom-function-with-dependencies.test.ts b/src/execution/plugins/script-execution-tools/custom-function-with-dependencies.test.ts
index dc6464afa..35375a33b 100644
--- a/src/execution/plugins/script-execution-tools/custom-function-with-dependencies.test.ts
+++ b/src/execution/plugins/script-execution-tools/custom-function-with-dependencies.test.ts
@@ -6,7 +6,7 @@ import { PromptbookString } from '../../../types/PromptbookString';
import { createPromptbookExecutor } from '../../createPromptbookExecutor';
import { MockedEchoNaturalExecutionTools } from '../natural-execution-tools/mocked/MockedEchoNaturalExecutionTools';
import { CallbackInterfaceTools } from '../user-interface-execution-tools/callback/CallbackInterfaceTools';
-import { JavascriptEvalExecutionTools } from './javascript/JavascriptEvalExecutionTools';
+import { JavascriptExecutionTools } from './javascript/JavascriptExecutionTools';
describe('createPromptbookExecutor + custom function with dependencies', () => {
const promptbook = promptbookStringToJson(
@@ -37,7 +37,7 @@ describe('createPromptbookExecutor + custom function with dependencies', () => {
tools: {
natural: new MockedEchoNaturalExecutionTools({ isVerbose: true }),
script: [
- new JavascriptEvalExecutionTools({
+ new JavascriptExecutionTools({
isVerbose: true,
// Note: [🕎]
diff --git a/src/execution/plugins/script-execution-tools/custom-function.test.ts b/src/execution/plugins/script-execution-tools/custom-function.test.ts
index 10f3ce71b..c0aff58eb 100644
--- a/src/execution/plugins/script-execution-tools/custom-function.test.ts
+++ b/src/execution/plugins/script-execution-tools/custom-function.test.ts
@@ -5,7 +5,7 @@ import { PromptbookString } from '../../../types/PromptbookString';
import { createPromptbookExecutor } from '../../createPromptbookExecutor';
import { MockedEchoNaturalExecutionTools } from '../natural-execution-tools/mocked/MockedEchoNaturalExecutionTools';
import { CallbackInterfaceTools } from '../user-interface-execution-tools/callback/CallbackInterfaceTools';
-import { JavascriptEvalExecutionTools } from './javascript/JavascriptEvalExecutionTools';
+import { JavascriptExecutionTools } from './javascript/JavascriptExecutionTools';
describe('createPromptbookExecutor + custom function without dependencies', () => {
const promptbook = promptbookStringToJson(
@@ -35,7 +35,7 @@ describe('createPromptbookExecutor + custom function without dependencies', () =
tools: {
natural: new MockedEchoNaturalExecutionTools({ isVerbose: true }),
script: [
- new JavascriptEvalExecutionTools({
+ new JavascriptExecutionTools({
isVerbose: true,
// Note: [🕎]
diff --git a/src/execution/plugins/script-execution-tools/javascript/JavascriptEvalExecutionTools.test.ts b/src/execution/plugins/script-execution-tools/javascript/JavascriptEvalExecutionTools.test.ts
deleted file mode 100644
index c7fb0da9a..000000000
--- a/src/execution/plugins/script-execution-tools/javascript/JavascriptEvalExecutionTools.test.ts
+++ /dev/null
@@ -1,140 +0,0 @@
-import { describe, expect, it } from '@jest/globals';
-import spaceTrim from 'spacetrim';
-import { JavascriptEvalExecutionTools } from './JavascriptEvalExecutionTools';
-
-describe('JavascriptEvalExecutionTools', () => {
- const javascriptEvalExecutionTools = new JavascriptEvalExecutionTools({
- isVerbose: true,
- // Note: [🕎] Custom functions are tested elsewhere
- });
-
- it('should evaluate supersimple statement', () => {
- expect(
- javascriptEvalExecutionTools.execute({
- scriptLanguage: 'javascript',
- parameters: {
- animal: 'cat',
- },
- script: 'animal',
- }),
- ).resolves.toEqual('cat');
- expect(
- javascriptEvalExecutionTools.execute({
- scriptLanguage: 'javascript',
- parameters: {
- animal: 'cat',
- },
- script: 'return animal',
- }),
- ).resolves.toEqual('cat');
- });
-
- it('should evaluate single statement', () => {
- expect(
- javascriptEvalExecutionTools.execute({
- scriptLanguage: 'javascript',
- parameters: {
- animal: 'cat',
- },
- script: "return animal.split('').reverse().join('-')",
- }),
- ).resolves.toEqual('t-a-c');
- });
-
- it('should evaluate build-in function', () => {
- expect(
- javascriptEvalExecutionTools.execute({
- scriptLanguage: 'javascript',
- parameters: {
- animal: '"cat"',
- },
- script: 'return removeQuotes(animal)',
- }),
- ).resolves.toEqual('cat');
-
- expect(
- javascriptEvalExecutionTools.execute({
- scriptLanguage: 'javascript',
- parameters: {
- animal: 'The animal is: "dog"',
- },
- script: 'return unwrapResult(animal)',
- }),
- ).resolves.toEqual('dog');
- });
-
- it('should evaluate multiple statements', () => {
- expect(
- javascriptEvalExecutionTools.execute({
- scriptLanguage: 'javascript',
- parameters: {
- animal: 'cat',
- sound: 'meow',
- },
- script: spaceTrim(`
- const sentence1 = animal + ' makes ' + sound + '.';
- const sentence2 = \`Two \${animal}s makes \${sound} \${sound}.\`;
- const sentence3 = \`Three \${animal}s makes \${sound} \${sound} \${sound}.\`;
- return spaceTrim(\`
- \${sentence1}
- \${sentence2}
- \${sentence3}
- \`);
- `),
- }),
- ).resolves.toEqual(
- spaceTrim(`
- cat makes meow.
- Two cats makes meow meow.
- Three cats makes meow meow meow.
- `),
- );
- });
-
- it('should throw error from script', () => {
- () =>
- expect(
- javascriptEvalExecutionTools.execute({
- scriptLanguage: 'javascript',
- parameters: {},
- script: "throw new Error('Some error')",
- }),
- ).rejects.toThrowError('Some error');
- });
-
- it('should evaluate custom function', () => {
- expect(
- javascriptEvalExecutionTools.execute({
- scriptLanguage: 'javascript',
- parameters: {
- animal: 'cat',
- sound: 'meow',
- },
- script: spaceTrim(`
- function makeSentence(animal, sound) {
- return animal + ' makes ' + sound + '.';
- }
- return makeSentence(animal, sound);
- `),
- }),
- ).resolves.toEqual('cat makes meow.');
- });
-
- it('should fail on python script', () => {
- expect(
- javascriptEvalExecutionTools.execute({
- scriptLanguage: 'python',
- parameters: {
- animal: 'cat',
- },
- script: spaceTrim(`
- print(animal);
- `),
- }),
- ).rejects.toThrowError(/not supported/i);
- });
-});
-
-/**
- * TODO: !! Make shared test between JavascriptEvalExecutionTools and JavascriptExecutionTools to test the same functionality when implemented via vm2
- */
diff --git a/src/execution/plugins/script-execution-tools/javascript/JavascriptEvalExecutionTools.ts b/src/execution/plugins/script-execution-tools/javascript/JavascriptEvalExecutionTools.ts
index e2b54e3ae..6cbf7ebbe 100644
--- a/src/execution/plugins/script-execution-tools/javascript/JavascriptEvalExecutionTools.ts
+++ b/src/execution/plugins/script-execution-tools/javascript/JavascriptEvalExecutionTools.ts
@@ -13,6 +13,7 @@ import {
parseKeywordsFromString,
} from 'n12';
import { spaceTrim as _spaceTrim } from 'spacetrim';
+import { isRunningInNode } from '../../../../utils/isRunningInWhatever';
import { prettifyMarkdown as _prettifyMarkdown } from '../../../../utils/markdown/prettifyMarkdown';
import { removeEmojis as _removeEmojis } from '../../../../utils/removeEmojis';
import { removeQuotes as _removeQuotes } from '../../../../utils/removeQuotes';
@@ -20,17 +21,24 @@ import { trimCodeBlock as _trimCodeBlock } from '../../../../utils/trimCodeBlock
import { trimEndOfCodeBlock as _trimEndOfCodeBlock } from '../../../../utils/trimEndOfCodeBlock';
import { unwrapResult as _unwrapResult } from '../../../../utils/unwrapResult';
import { ScriptExecutionTools, ScriptExecutionToolsExecuteOptions } from '../../../ScriptExecutionTools';
-import { JavascriptExecutionToolsOptions } from './JavascriptExecutionToolsOptions';
+import type { JavascriptExecutionToolsOptions } from './JavascriptExecutionToolsOptions';
import { preserve } from './utils/preserve';
/**
* ScriptExecutionTools for JavaScript implemented via eval
*
+ * @deprecated Use `JavascriptExecutionTools` instead
* Warning: It is used for testing and mocking
* **NOT intended to use in the production** due to its unsafe nature, use `JavascriptExecutionTools` instead.
*/
export class JavascriptEvalExecutionTools implements ScriptExecutionTools {
- public constructor(private readonly options: JavascriptExecutionToolsOptions) {}
+
+ public constructor(private readonly options: JavascriptExecutionToolsOptions) {
+ if (isRunningInNode()) {
+ throw new Error(`JavascriptEvalExecutionTools is not intended to be used in Node.js environment`);
+ }
+ }
+
/**
* Executes a JavaScript
diff --git a/src/execution/plugins/script-execution-tools/javascript/JavascriptExecutionTools.test.ts b/src/execution/plugins/script-execution-tools/javascript/JavascriptExecutionTools.test.ts
new file mode 100644
index 000000000..ee92c471f
--- /dev/null
+++ b/src/execution/plugins/script-execution-tools/javascript/JavascriptExecutionTools.test.ts
@@ -0,0 +1,148 @@
+import { describe, expect, it } from '@jest/globals';
+import spaceTrim from 'spacetrim';
+import { JavascriptEvalExecutionTools } from './JavascriptEvalExecutionTools';
+import { JavascriptExecutionTools } from './JavascriptExecutionTools';
+
+describe('JavascriptEvalExecutionTools', () => {
+ const javascriptEvalExecutionTools = new JavascriptEvalExecutionTools({
+ isVerbose: true,
+ // Note: [🕎] Custom functions are tested elsewhere
+ });
+
+ const javascriptExecutionTools = new JavascriptExecutionTools({
+ isVerbose: true,
+ // Note: [🕎] Custom functions are tested elsewhere
+ });
+
+ for (const [name, executionTools] of Object.entries({ javascriptEvalExecutionTools, javascriptExecutionTools })) {
+ it(`should evaluate supersimple statement in ${name}`, () => {
+ expect(
+ executionTools.execute({
+ scriptLanguage: 'javascript',
+ parameters: {
+ animal: 'cat',
+ },
+ script: 'animal',
+ }),
+ ).resolves.toEqual('cat');
+ expect(
+ executionTools.execute({
+ scriptLanguage: 'javascript',
+ parameters: {
+ animal: 'cat',
+ },
+ script: 'return animal',
+ }),
+ ).resolves.toEqual('cat');
+ });
+
+ it(`should evaluate single statement in ${name}`, () => {
+ expect(
+ executionTools.execute({
+ scriptLanguage: 'javascript',
+ parameters: {
+ animal: 'cat',
+ },
+ script: "return animal.split('').reverse().join('-')",
+ }),
+ ).resolves.toEqual('t-a-c');
+ });
+
+ it(`should evaluate build-in function in ${name}`, () => {
+ expect(
+ executionTools.execute({
+ scriptLanguage: 'javascript',
+ parameters: {
+ animal: '"cat"',
+ },
+ script: 'return removeQuotes(animal)',
+ }),
+ ).resolves.toEqual('cat');
+
+ expect(
+ executionTools.execute({
+ scriptLanguage: 'javascript',
+ parameters: {
+ animal: 'The animal is: "dog"',
+ },
+ script: 'return unwrapResult(animal)',
+ }),
+ ).resolves.toEqual('dog');
+ });
+
+ it(`should evaluate multiple statements in ${name}`, () => {
+ expect(
+ executionTools.execute({
+ scriptLanguage: 'javascript',
+ parameters: {
+ animal: 'cat',
+ sound: 'meow',
+ },
+ script: spaceTrim(`
+ const sentence1 = animal + ' makes ' + sound + '.';
+ const sentence2 = \`Two \${animal}s makes \${sound} \${sound}.\`;
+ const sentence3 = \`Three \${animal}s makes \${sound} \${sound} \${sound}.\`;
+ return spaceTrim(\`
+ \${sentence1}
+ \${sentence2}
+ \${sentence3}
+ \`);
+ `),
+ }),
+ ).resolves.toEqual(
+ spaceTrim(`
+ cat makes meow.
+ Two cats makes meow meow.
+ Three cats makes meow meow meow.
+ `),
+ );
+ });
+
+ it(`should throw error from script in ${name}`, () => {
+ () =>
+ expect(
+ executionTools.execute({
+ scriptLanguage: 'javascript',
+ parameters: {},
+ script: "throw new Error('Some error')",
+ }),
+ ).rejects.toThrowError('Some error');
+ });
+
+ it(`should evaluate custom function in ${name}`, () => {
+ expect(
+ executionTools.execute({
+ scriptLanguage: 'javascript',
+ parameters: {
+ animal: 'cat',
+ sound: 'meow',
+ },
+ script: spaceTrim(`
+ function makeSentence(animal, sound) {
+ return animal + ' makes ' + sound + '.';
+ }
+ return makeSentence(animal, sound);
+ `),
+ }),
+ ).resolves.toEqual('cat makes meow.');
+ });
+
+ it(`should fail on python script in ${name}`, () => {
+ expect(
+ executionTools.execute({
+ scriptLanguage: 'python',
+ parameters: {
+ animal: 'cat',
+ },
+ script: spaceTrim(`
+ print(animal);
+ `),
+ }),
+ ).rejects.toThrowError(/not supported/i);
+ });
+ }
+});
+
+/**
+ * TODO: !! Make shared test between JavascriptEvalExecutionTools and JavascriptExecutionTools to test the same functionality when implemented via vm2
+ */
diff --git a/src/execution/plugins/script-execution-tools/postprocessing.test.ts b/src/execution/plugins/script-execution-tools/postprocessing.test.ts
index 5d6964b5a..a38f4bb9b 100644
--- a/src/execution/plugins/script-execution-tools/postprocessing.test.ts
+++ b/src/execution/plugins/script-execution-tools/postprocessing.test.ts
@@ -5,7 +5,7 @@ import { PromptbookString } from '../../../types/PromptbookString';
import { createPromptbookExecutor } from '../../createPromptbookExecutor';
import { MockedEchoNaturalExecutionTools } from '../natural-execution-tools/mocked/MockedEchoNaturalExecutionTools';
import { CallbackInterfaceTools } from '../user-interface-execution-tools/callback/CallbackInterfaceTools';
-import { JavascriptEvalExecutionTools } from './javascript/JavascriptEvalExecutionTools';
+import { JavascriptExecutionTools } from './javascript/JavascriptExecutionTools';
describe('createPromptbookExecutor + postprocessing', () => {
const promptbook = promptbookStringToJson(
@@ -38,7 +38,7 @@ describe('createPromptbookExecutor + postprocessing', () => {
tools: {
natural: new MockedEchoNaturalExecutionTools({ isVerbose: true }),
script: [
- new JavascriptEvalExecutionTools({
+ new JavascriptExecutionTools({
isVerbose: true,
// Note: [🕎] Custom functions are tested elsewhere
}),
diff --git a/src/execution/plugins/script-execution-tools/script-execution-errors.test.ts b/src/execution/plugins/script-execution-tools/script-execution-errors.test.ts
index 171308119..08d01abc2 100644
--- a/src/execution/plugins/script-execution-tools/script-execution-errors.test.ts
+++ b/src/execution/plugins/script-execution-tools/script-execution-errors.test.ts
@@ -6,7 +6,7 @@ import { assertsExecutionSuccessful } from '../../assertsExecutionSuccessful';
import { createPromptbookExecutor } from '../../createPromptbookExecutor';
import { MockedEchoNaturalExecutionTools } from '../natural-execution-tools/mocked/MockedEchoNaturalExecutionTools';
import { CallbackInterfaceTools } from '../user-interface-execution-tools/callback/CallbackInterfaceTools';
-import { JavascriptEvalExecutionTools } from './javascript/JavascriptEvalExecutionTools';
+import { JavascriptExecutionTools } from './javascript/JavascriptExecutionTools';
describe('createPromptbookExecutor + executing scripts in promptbook', () => {
const promptbook = promptbookStringToJson(
@@ -37,7 +37,7 @@ describe('createPromptbookExecutor + executing scripts in promptbook', () => {
tools: {
natural: new MockedEchoNaturalExecutionTools({ isVerbose: true }),
script: [
- new JavascriptEvalExecutionTools({
+ new JavascriptExecutionTools({
isVerbose: true,
// Note: [🕎] Custom functions are tested elsewhere
}),
diff --git a/src/execution/plugins/script-execution-tools/script-execution-tools.test.ts b/src/execution/plugins/script-execution-tools/script-execution-tools.test.ts
index e7e596d2c..63936bc10 100644
--- a/src/execution/plugins/script-execution-tools/script-execution-tools.test.ts
+++ b/src/execution/plugins/script-execution-tools/script-execution-tools.test.ts
@@ -6,7 +6,7 @@ import { assertsExecutionSuccessful } from '../../assertsExecutionSuccessful';
import { createPromptbookExecutor } from '../../createPromptbookExecutor';
import { MockedEchoNaturalExecutionTools } from '../natural-execution-tools/mocked/MockedEchoNaturalExecutionTools';
import { CallbackInterfaceTools } from '../user-interface-execution-tools/callback/CallbackInterfaceTools';
-import { JavascriptEvalExecutionTools } from './javascript/JavascriptEvalExecutionTools';
+import { JavascriptExecutionTools } from './javascript/JavascriptEvalExecutionTools';
describe('createPromptbookExecutor + executing scripts in promptbook', () => {
const promptbook = promptbookStringToJson(
@@ -34,7 +34,7 @@ describe('createPromptbookExecutor + executing scripts in promptbook', () => {
tools: {
natural: new MockedEchoNaturalExecutionTools({ isVerbose: true }),
script: [
- new JavascriptEvalExecutionTools({
+ new JavascriptExecutionTools({
isVerbose: true,
// Note: [🕎] Custom functions are tested elsewhere
}),