From b822cd48d2ff0ade1e56c7ac4687c0eab59963af Mon Sep 17 00:00:00 2001 From: Fuegovic <32828263+fuegovic@users.noreply.github.com> Date: Thu, 7 Dec 2023 14:27:52 -0500 Subject: [PATCH] bug fix: remove 3rd party code interpreter (#1306) --- api/app/clients/tools/CodeInterpreter.js | 52 ------------------ api/app/clients/tools/index.js | 2 - api/app/clients/tools/manifest.json | 13 ----- api/app/clients/tools/util/handleTools.js | 2 - pyserver/Dockerfile | 11 ---- pyserver/requirements.txt | 4 -- pyserver/server.py | 65 ----------------------- 7 files changed, 149 deletions(-) delete mode 100644 api/app/clients/tools/CodeInterpreter.js delete mode 100644 pyserver/Dockerfile delete mode 100644 pyserver/requirements.txt delete mode 100644 pyserver/server.py diff --git a/api/app/clients/tools/CodeInterpreter.js b/api/app/clients/tools/CodeInterpreter.js deleted file mode 100644 index 9671b97424..0000000000 --- a/api/app/clients/tools/CodeInterpreter.js +++ /dev/null @@ -1,52 +0,0 @@ -const { Tool } = require('langchain/tools'); -const WebSocket = require('ws'); -const { promisify } = require('util'); -const fs = require('fs'); - -class CodeInterpreter extends Tool { - constructor() { - super(); - this.name = 'code-interpreter'; - this.description = `If there is plotting or any image related tasks, save the result as .png file. - No need show the image or plot. USE print(variable_name) if you need output.You can run python codes with this plugin.You have to use print function in python code to get any result from this plugin. - This does not support user input. Even if the code has input() function, change it to an appropriate value. - You can show the user the code with input() functions. But the code passed to the plug-in should not contain input(). - You should provide properly formatted code to this plugin. If the code is executed successfully, the stdout will be returned to you. You have to print that to the user, and if the user had - asked for an explanation, you have to provide one. If the output is "Error From here" or any other error message, - tell the user "Python Engine Failed" and continue with whatever you are supposed to do.`; - - // Create a promisified version of fs.unlink - this.unlinkAsync = promisify(fs.unlink); - } - - async _call(input) { - const websocket = new WebSocket('ws://localhost:3380'); // Update with your WebSocket server URL - - // Wait until the WebSocket connection is open - await new Promise((resolve) => { - websocket.onopen = resolve; - }); - - // Send the Python code to the server - websocket.send(input); - - // Wait for the result from the server - const result = await new Promise((resolve) => { - websocket.onmessage = (event) => { - resolve(event.data); - }; - - // Handle WebSocket connection closed - websocket.onclose = () => { - resolve('Python Engine Failed'); - }; - }); - - // Close the WebSocket connection - websocket.close(); - - return result; - } -} - -module.exports = CodeInterpreter; diff --git a/api/app/clients/tools/index.js b/api/app/clients/tools/index.js index a5e64a2b9f..ad8b61a7fc 100644 --- a/api/app/clients/tools/index.js +++ b/api/app/clients/tools/index.js @@ -15,7 +15,6 @@ const E2BTools = require('./structured/E2BTools'); const CodeSherpa = require('./structured/CodeSherpa'); const CodeSherpaTools = require('./structured/CodeSherpaTools'); const availableTools = require('./manifest.json'); -const CodeInterpreter = require('./CodeInterpreter'); const CodeBrew = require('./CodeBrew'); module.exports = { @@ -36,6 +35,5 @@ module.exports = { ChatTool, CodeSherpa, CodeSherpaTools, - CodeInterpreter, CodeBrew, }; diff --git a/api/app/clients/tools/manifest.json b/api/app/clients/tools/manifest.json index ac4423c705..d5f2c75d3d 100644 --- a/api/app/clients/tools/manifest.json +++ b/api/app/clients/tools/manifest.json @@ -165,19 +165,6 @@ } ] }, - { - "name": "Code Interpreter", - "pluginKey": "codeinterpreter", - "description": "[Experimental] Analyze files and run code online with ease. Requires dockerized python server in /pyserver/", - "icon": "/assets/code.png", - "authConfig": [ - { - "authField": "OPENAI_API_KEY", - "label": "OpenAI API Key", - "description": "Gets Code from Open AI API" - } - ] - }, { "name": "CodeBrew", "pluginKey": "CodeBrew", diff --git a/api/app/clients/tools/util/handleTools.js b/api/app/clients/tools/util/handleTools.js index e26dc3344f..6109e2b9c2 100644 --- a/api/app/clients/tools/util/handleTools.js +++ b/api/app/clients/tools/util/handleTools.js @@ -7,7 +7,6 @@ const { Calculator } = require('langchain/tools/calculator'); const { WebBrowser } = require('langchain/tools/webbrowser'); const { availableTools, - CodeInterpreter, AIPluginTool, GoogleSearchAPI, WolframAlphaAPI, @@ -96,7 +95,6 @@ const loadTools = async ({ }) => { const toolConstructors = { calculator: Calculator, - codeinterpreter: CodeInterpreter, google: GoogleSearchAPI, wolfram: functions ? StructuredWolfram : WolframAlphaAPI, 'dall-e': OpenAICreateImage, diff --git a/pyserver/Dockerfile b/pyserver/Dockerfile deleted file mode 100644 index 99da2f92ce..0000000000 --- a/pyserver/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM python:3.9 - -WORKDIR /app - -COPY server.py . -COPY requirements.txt . - -RUN pip install -r requirements.txt -RUN rm requirements.txt - -CMD ["python", "server.py"] \ No newline at end of file diff --git a/pyserver/requirements.txt b/pyserver/requirements.txt deleted file mode 100644 index 2bf1038a9f..0000000000 --- a/pyserver/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -numpy -matplotlib -websockets -pandas \ No newline at end of file diff --git a/pyserver/server.py b/pyserver/server.py deleted file mode 100644 index e24fc66aa5..0000000000 --- a/pyserver/server.py +++ /dev/null @@ -1,65 +0,0 @@ -import asyncio -import websockets -import io -import sys -import os as ps -import shutil - - -def execute_code(code): - try: - stdout_capture = io.StringIO() - sys.stdout = stdout_capture - exec(code, globals()) - stdout_output = stdout_capture.getvalue() - sys.stdout = sys.__stdout__ - return stdout_output - except Exception as e: - return str(e) - - -def move_files(): - assets_path = "/app/pyassets" # Update the assets folder path - current_dir = ps.getcwd() - moved_files = [] - for filename in ps.listdir(current_dir): - full_path = ps.path.join(current_dir, filename) - if ps.path.isfile(full_path) and filename != 'server.py': - new_path = ps.path.join(assets_path, filename) - shutil.move(full_path, new_path) - moved_files.append(filename) - return moved_files - - -def generate_links(filenames): - base_url = ps.environ['BASE_URL'] - if(base_url == ''): - return - base_url = base_url + '/assets/pyassets' - links = [f"![{filename}]({base_url}/{filename})" for filename in filenames] - return links - - -async def handle_client(websocket, path): - try: - code = await websocket.recv() - result = execute_code(code) - filenames = move_files() - links = generate_links(filenames) - final_result = f"{result}\n" - final_result += "\n".join(links) - await websocket.send(final_result) - except websockets.exceptions.ConnectionClosed: - pass - -async def server(websocket, path): - print(f"Incoming connection from {websocket.remote_address}") - while True: - await handle_client(websocket, path) - -start_server = websockets.serve(server, '0.0.0.0', 3380) - -print('Server started, listening on localhost:3380') - -asyncio.get_event_loop().run_until_complete(start_server) -asyncio.get_event_loop().run_forever() \ No newline at end of file