From ff76c4bd5dffcff9b2c035953d358de56859515e Mon Sep 17 00:00:00 2001 From: Richards Tu <142148415+richards199999@users.noreply.github.com> Date: Tue, 23 Apr 2024 09:07:21 +0800 Subject: [PATCH] Add new tool: Judge0 CE (#3684) Co-authored-by: crazywoola <427733928@qq.com> --- .../builtin/judge0ce/_assets/icon.svg | 21 ++++++ .../provider/builtin/judge0ce/judge0ce.py | 23 +++++++ .../provider/builtin/judge0ce/judge0ce.yaml | 29 ++++++++ .../judge0ce/tools/getExecutionResult.py | 37 ++++++++++ .../judge0ce/tools/getExecutionResult.yaml | 23 +++++++ .../judge0ce/tools/submitCodeExecutionTask.py | 49 ++++++++++++++ .../tools/submitCodeExecutionTask.yaml | 67 +++++++++++++++++++ 7 files changed, 249 insertions(+) create mode 100644 api/core/tools/provider/builtin/judge0ce/_assets/icon.svg create mode 100644 api/core/tools/provider/builtin/judge0ce/judge0ce.py create mode 100644 api/core/tools/provider/builtin/judge0ce/judge0ce.yaml create mode 100644 api/core/tools/provider/builtin/judge0ce/tools/getExecutionResult.py create mode 100644 api/core/tools/provider/builtin/judge0ce/tools/getExecutionResult.yaml create mode 100644 api/core/tools/provider/builtin/judge0ce/tools/submitCodeExecutionTask.py create mode 100644 api/core/tools/provider/builtin/judge0ce/tools/submitCodeExecutionTask.yaml diff --git a/api/core/tools/provider/builtin/judge0ce/_assets/icon.svg b/api/core/tools/provider/builtin/judge0ce/_assets/icon.svg new file mode 100644 index 0000000000..3e7e33da6e --- /dev/null +++ b/api/core/tools/provider/builtin/judge0ce/_assets/icon.svg @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/api/core/tools/provider/builtin/judge0ce/judge0ce.py b/api/core/tools/provider/builtin/judge0ce/judge0ce.py new file mode 100644 index 0000000000..d45e3c7bd1 --- /dev/null +++ b/api/core/tools/provider/builtin/judge0ce/judge0ce.py @@ -0,0 +1,23 @@ +from typing import Any + +from core.tools.errors import ToolProviderCredentialValidationError +from core.tools.provider.builtin.judge0ce.tools.submitCodeExecutionTask import SubmitCodeExecutionTaskTool +from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController + + +class Judge0CEProvider(BuiltinToolProviderController): + def _validate_credentials(self, credentials: dict[str, Any]) -> None: + try: + SubmitCodeExecutionTaskTool().fork_tool_runtime( + meta={ + "credentials": credentials, + } + ).invoke( + user_id='', + tool_parameters={ + "source_code": "print('hello world')", + "language_id": 71, + }, + ) + except Exception as e: + raise ToolProviderCredentialValidationError(str(e)) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/judge0ce/judge0ce.yaml b/api/core/tools/provider/builtin/judge0ce/judge0ce.yaml new file mode 100644 index 0000000000..5f0a471827 --- /dev/null +++ b/api/core/tools/provider/builtin/judge0ce/judge0ce.yaml @@ -0,0 +1,29 @@ +identity: + author: Richards Tu + name: judge0ce + label: + en_US: Judge0 CE + zh_Hans: Judge0 CE + pt_BR: Judge0 CE + description: + en_US: Judge0 CE is an open-source code execution system. Support various languages, including C, C++, Java, Python, Ruby, etc. + zh_Hans: Judge0 CE 是一个开源的代码执行系统。支持多种语言,包括 C、C++、Java、Python、Ruby 等。 + pt_BR: Judge0 CE é um sistema de execução de código de código aberto. Suporta várias linguagens, incluindo C, C++, Java, Python, Ruby, etc. + icon: icon.svg +credentials_for_provider: + X-RapidAPI-Key: + type: secret-input + required: true + label: + en_US: RapidAPI Key + zh_Hans: RapidAPI Key + pt_BR: RapidAPI Key + help: + en_US: RapidAPI Key is required to access the Judge0 CE API. + zh_Hans: RapidAPI Key 是访问 Judge0 CE API 所必需的。 + pt_BR: RapidAPI Key é necessário para acessar a API do Judge0 CE. + placeholder: + en_US: Enter your RapidAPI Key + zh_Hans: 输入你的 RapidAPI Key + pt_BR: Insira sua RapidAPI Key + url: https://rapidapi.com/judge0-official/api/judge0-ce diff --git a/api/core/tools/provider/builtin/judge0ce/tools/getExecutionResult.py b/api/core/tools/provider/builtin/judge0ce/tools/getExecutionResult.py new file mode 100644 index 0000000000..6c70f35001 --- /dev/null +++ b/api/core/tools/provider/builtin/judge0ce/tools/getExecutionResult.py @@ -0,0 +1,37 @@ +from typing import Any, Union + +import requests + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + + +class GetExecutionResultTool(BuiltinTool): + def _invoke(self, + user_id: str, + tool_parameters: dict[str, Any], + ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + """ + invoke tools + """ + api_key = self.runtime.credentials['X-RapidAPI-Key'] + + url = f"https://judge0-ce.p.rapidapi.com/submissions/{tool_parameters['token']}" + headers = { + "X-RapidAPI-Key": api_key + } + + response = requests.get(url, headers=headers) + + if response.status_code == 200: + result = response.json() + return self.create_text_message(text=f"Submission details:\n" + f"stdout: {result.get('stdout', '')}\n" + f"stderr: {result.get('stderr', '')}\n" + f"compile_output: {result.get('compile_output', '')}\n" + f"message: {result.get('message', '')}\n" + f"status: {result['status']['description']}\n" + f"time: {result.get('time', '')} seconds\n" + f"memory: {result.get('memory', '')} bytes") + else: + return self.create_text_message(text=f"Error retrieving submission details: {response.text}") \ No newline at end of file diff --git a/api/core/tools/provider/builtin/judge0ce/tools/getExecutionResult.yaml b/api/core/tools/provider/builtin/judge0ce/tools/getExecutionResult.yaml new file mode 100644 index 0000000000..3f4f09c977 --- /dev/null +++ b/api/core/tools/provider/builtin/judge0ce/tools/getExecutionResult.yaml @@ -0,0 +1,23 @@ +identity: + name: getExecutionResult + author: Richards Tu + label: + en_US: Get Execution Result + zh_Hans: 获取执行结果 +description: + human: + en_US: A tool for retrieving the details of a code submission by a specific token from submitCodeExecutionTask. + zh_Hans: 一个用于通过 submitCodeExecutionTask 工具提供的特定令牌来检索代码提交详细信息的工具。 + llm: A tool for retrieving the details of a code submission by a specific token from submitCodeExecutionTask. +parameters: + - name: token + type: string + required: true + label: + en_US: Token + zh_Hans: 令牌 + human_description: + en_US: The submission's unique token. + zh_Hans: 提交的唯一令牌。 + llm_description: The submission's unique token. MUST get from submitCodeExecution. + form: llm diff --git a/api/core/tools/provider/builtin/judge0ce/tools/submitCodeExecutionTask.py b/api/core/tools/provider/builtin/judge0ce/tools/submitCodeExecutionTask.py new file mode 100644 index 0000000000..1bdffc0230 --- /dev/null +++ b/api/core/tools/provider/builtin/judge0ce/tools/submitCodeExecutionTask.py @@ -0,0 +1,49 @@ +import json +from typing import Any, Union + +from httpx import post + +from core.tools.entities.tool_entities import ToolInvokeMessage +from core.tools.tool.builtin_tool import BuiltinTool + + +class SubmitCodeExecutionTaskTool(BuiltinTool): + def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]: + """ + invoke tools + """ + api_key = self.runtime.credentials['X-RapidAPI-Key'] + + source_code = tool_parameters['source_code'] + language_id = tool_parameters['language_id'] + stdin = tool_parameters.get('stdin', '') + expected_output = tool_parameters.get('expected_output', '') + additional_files = tool_parameters.get('additional_files', '') + + url = "https://judge0-ce.p.rapidapi.com/submissions" + + querystring = {"base64_encoded": "false", "fields": "*"} + + payload = { + "language_id": language_id, + "source_code": source_code, + "stdin": stdin, + "expected_output": expected_output, + "additional_files": additional_files, + } + + headers = { + "content-type": "application/json", + "Content-Type": "application/json", + "X-RapidAPI-Key": api_key, + "X-RapidAPI-Host": "judge0-ce.p.rapidapi.com" + } + + response = post(url, data=json.dumps(payload), headers=headers, params=querystring) + + if response.status_code != 201: + raise Exception(response.text) + + token = response.json()['token'] + + return self.create_text_message(text=token) \ No newline at end of file diff --git a/api/core/tools/provider/builtin/judge0ce/tools/submitCodeExecutionTask.yaml b/api/core/tools/provider/builtin/judge0ce/tools/submitCodeExecutionTask.yaml new file mode 100644 index 0000000000..e36efbcb55 --- /dev/null +++ b/api/core/tools/provider/builtin/judge0ce/tools/submitCodeExecutionTask.yaml @@ -0,0 +1,67 @@ +identity: + name: submitCodeExecutionTask + author: Richards Tu + label: + en_US: Submit Code Execution Task + zh_Hans: 提交代码执行任务 +description: + human: + en_US: A tool for submitting code execution task to Judge0 CE. + zh_Hans: 一个用于向 Judge0 CE 提交代码执行任务的工具。 + llm: A tool for submitting a new code execution task to Judge0 CE. It takes in the source code, language ID, standard input (optional), expected output (optional), and additional files (optional) as parameters; and returns a unique token representing the submission. +parameters: + - name: source_code + type: string + required: true + label: + en_US: Source Code + zh_Hans: 源代码 + human_description: + en_US: The source code to be executed. + zh_Hans: 要执行的源代码。 + llm_description: The source code to be executed. + form: llm + - name: language_id + type: number + required: true + label: + en_US: Language ID + zh_Hans: 语言 ID + human_description: + en_US: The ID of the language in which the source code is written. + zh_Hans: 源代码所使用的语言的 ID。 + llm_description: The ID of the language in which the source code is written. For example, 50 for C++, 71 for Python, etc. + form: llm + - name: stdin + type: string + required: false + label: + en_US: Standard Input + zh_Hans: 标准输入 + human_description: + en_US: The standard input to be provided to the program. + zh_Hans: 提供给程序的标准输入。 + llm_description: The standard input to be provided to the program. Optional. + form: llm + - name: expected_output + type: string + required: false + label: + en_US: Expected Output + zh_Hans: 期望输出 + human_description: + en_US: The expected output of the program. Used for comparison in some scenarios. + zh_Hans: 程序的期望输出。在某些场景下用于比较。 + llm_description: The expected output of the program. Used for comparison in some scenarios. Optional. + form: llm + - name: additional_files + type: string + required: false + label: + en_US: Additional Files + zh_Hans: 附加文件 + human_description: + en_US: Base64 encoded additional files for the submission. + zh_Hans: 提交的 Base64 编码的附加文件。 + llm_description: Base64 encoded additional files for the submission. Optional. + form: llm