Unverified Commit 3bd53556 authored by Yeuoly's avatar Yeuoly

feat: javascript code

parent 3f59a579
...@@ -135,4 +135,4 @@ BATCH_UPLOAD_LIMIT=10 ...@@ -135,4 +135,4 @@ BATCH_UPLOAD_LIMIT=10
# CODE EXECUTION CONFIGURATION # CODE EXECUTION CONFIGURATION
CODE_EXECUTION_ENDPOINT= CODE_EXECUTION_ENDPOINT=
CODE_EXECUTINO_API_KEY= CODE_EXECUTION_API_KEY=
...@@ -4,6 +4,7 @@ from typing import Literal, Optional ...@@ -4,6 +4,7 @@ from typing import Literal, Optional
from httpx import post from httpx import post
from pydantic import BaseModel from pydantic import BaseModel
from yarl import URL from yarl import URL
from core.helper.code_executor.javascript_transformer import NodeJsTemplateTransformer
from core.helper.code_executor.jina2_transformer import Jinja2TemplateTransformer from core.helper.code_executor.jina2_transformer import Jinja2TemplateTransformer
from core.helper.code_executor.python_transformer import PythonTemplateTransformer from core.helper.code_executor.python_transformer import PythonTemplateTransformer
...@@ -39,17 +40,20 @@ class CodeExecutor: ...@@ -39,17 +40,20 @@ class CodeExecutor:
template_transformer = PythonTemplateTransformer template_transformer = PythonTemplateTransformer
elif language == 'jinja2': elif language == 'jinja2':
template_transformer = Jinja2TemplateTransformer template_transformer = Jinja2TemplateTransformer
elif language == 'javascript':
template_transformer = NodeJsTemplateTransformer
else: else:
raise CodeExecutionException('Unsupported language') raise CodeExecutionException('Unsupported language')
runner = template_transformer.transform_caller(code, inputs) runner = template_transformer.transform_caller(code, inputs)
url = URL(CODE_EXECUTION_ENDPOINT) / 'v1' / 'sandbox' / 'run' url = URL(CODE_EXECUTION_ENDPOINT) / 'v1' / 'sandbox' / 'run'
headers = { headers = {
'X-Api-Key': CODE_EXECUTION_API_KEY 'X-Api-Key': CODE_EXECUTION_API_KEY
} }
data = { data = {
'language': language if language != 'jinja2' else 'python3', 'language': 'python3' if language == 'jinja2' else
'nodejs' if language == 'javascript' else
'python3' if language == 'python3' else None,
'code': runner, 'code': runner,
} }
......
# TODO import json
\ No newline at end of file import re
from core.helper.code_executor.template_transformer import TemplateTransformer
NODEJS_RUNNER = """// declare main function here
{{code}}
// execute main function, and return the result
// inputs is a dict, unstructured inputs
output = main({{inputs}})
// convert output to json and print
output = JSON.stringify(output)
result = `<<RESULT>>${output}<<RESULT>>`
console.log(result)
"""
class NodeJsTemplateTransformer(TemplateTransformer):
@classmethod
def transform_caller(cls, code: str, inputs: dict) -> str:
"""
Transform code to python runner
:param code: code
:param inputs: inputs
:return:
"""
# transform inputs to json string
inputs_str = json.dumps(inputs, indent=4)
# replace code and inputs
runner = NODEJS_RUNNER.replace('{{code}}', code)
runner = runner.replace('{{inputs}}', inputs_str)
return runner
@classmethod
def transform_response(cls, response: str) -> dict:
"""
Transform response to dict
:param response: response
:return:
"""
# extract result
result = re.search(r'<<RESULT>>(.*)<<RESULT>>', response, re.DOTALL)
if not result:
raise ValueError('Failed to parse result')
result = result.group(1)
return json.loads(result)
...@@ -15,6 +15,16 @@ MAX_STRING_LENGTH = 1000 ...@@ -15,6 +15,16 @@ MAX_STRING_LENGTH = 1000
MAX_STRING_ARRAY_LENGTH = 30 MAX_STRING_ARRAY_LENGTH = 30
MAX_NUMBER_ARRAY_LENGTH = 1000 MAX_NUMBER_ARRAY_LENGTH = 1000
JAVASCRIPT_DEFAULT_CODE = """function main({args1, args2}) {
return {
result: args1 + args2
}
}"""
PYTHON_DEFAULT_CODE = """def main(args1: int, args2: int) -> dict:
return {
"result": args1 + args2,
}"""
class CodeNode(BaseNode): class CodeNode(BaseNode):
_node_data_cls = CodeNodeData _node_data_cls = CodeNodeData
...@@ -42,9 +52,7 @@ class CodeNode(BaseNode): ...@@ -42,9 +52,7 @@ class CodeNode(BaseNode):
} }
], ],
"code_language": "javascript", "code_language": "javascript",
"code": "async function main(arg1, arg2) {\n return new Promise((resolve, reject) => {" "code": JAVASCRIPT_DEFAULT_CODE,
"\n if (true) {\n resolve({\n \"result\": arg1 + arg2"
"\n });\n } else {\n reject(\"e\");\n }\n });\n}",
"outputs": [ "outputs": [
{ {
"variable": "result", "variable": "result",
...@@ -68,8 +76,7 @@ class CodeNode(BaseNode): ...@@ -68,8 +76,7 @@ class CodeNode(BaseNode):
} }
], ],
"code_language": "python3", "code_language": "python3",
"code": "def main(\n arg1: int,\n arg2: int,\n) -> int:\n return {\n \"result\": arg1 " "code": PYTHON_DEFAULT_CODE,
"+ arg2\n }",
"outputs": [ "outputs": [
{ {
"variable": "result", "variable": "result",
......
...@@ -17,4 +17,4 @@ class CodeNodeData(BaseNodeData): ...@@ -17,4 +17,4 @@ class CodeNodeData(BaseNodeData):
variables: list[VariableSelector] variables: list[VariableSelector]
code_language: Literal['python3', 'javascript'] code_language: Literal['python3', 'javascript']
code: str code: str
outputs: dict[str, Output] outputs: dict[str, Output]
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment