From 6ae3f2059ed064aed91c0e0995f78f7749bd9caa Mon Sep 17 00:00:00 2001 From: Nathan Hoos <128712250+unaidedelf8777@users.noreply.github.com> Date: Mon, 25 Sep 2023 22:08:22 +0000 Subject: [PATCH 01/12] Modified to comply with generator update, and so that no changes to the base interpreter class or anything in the core folder was needed. Update README from base/main merge rebased branch to main. (#2) * fix: stop overwriting boolean config values Without the default set to None, any boolean CLI flag that isn't passed reverts to its default state even if it is configured in the config.yaml file. * The Generator Update (English docs) * Improved --conversations, --config --------- quality of life and error messages errors and stuff again re-add readline method because doc formatting removed it somehow fix readline method of wrapper added file upload and download functionality finalized upload and download commands. tested stuff visual Improved --conversations, --config The Generator Update (English docs) fix: stop overwriting boolean config values Without the default set to None, any boolean CLI flag that isn't passed reverts to its default state even if it is configured in the config.yaml file. Update WINDOWS.md Warns the user to re-launch cmd windows after installing llama locally Fix ARM64 llama-cpp-python Install on Apple Silicon This commit updates the `MACOS.md` documentation to include detailed steps for correctly installing `llama-cpp-python` with ARM64 architecture support on Apple Silicon-based macOS systems. The update provides: - A prerequisite check for Xcode Command Line Tools. - Step-by-step installation instructions for `llama-cpp-python` with ARM64 and Metal support. - A verification step to confirm the correct installation of `llama-cpp-python` for ARM64 architecture. - An additional step for installing server components for `llama-cpp-python`. This commit resolves the issue described in `ARM64 Installation Issue with llama-cpp-python on Apple Silicon Macs for interpreter --local #503`. Broken empty message response fix crash on unknwon command on call to display help message removed unnecessary spaces Update get_relevant_procedures.py Fixed a typo in the instructions to the model The Generator Update The Generator Update The Generator Update - Azure fix The Generator Update - Azure function calling The Generator Update - Azure fix Better debugging Better debugging Proper TokenTrimming for new models Generator Update Fixes (Updated Version) Generator Update Quick Fixes Added example JARVIS Colab Notebook Added example JARVIS Colab Notebook Skip wrap_in_trap on Windows fix: allow args to have choices and defaults This allows non-boolean args to define possible options and default values, which were ignored previously. feat: add semgrep code scanning via --safe flag This reintroduces the --safe functionality from #24. --safe has 3 possible values auto, ask, and off Code scanning is opt-in. fix: default to 'off' for scan_code attribute fix: toggle code_scan based on auto_run setting; update --scan docs revert: undo default and choices change to cli.py This is being removed from this PR in favor of a standalone fix in #511 feat: cleanup code scanning and convert to safe mode docs: fix naming of safe_mode flag in README fix: pass debug_mode flag into file cleanup for code scan fix: remove extra tempfile import from scan_code util Fixed first message inturruption error Holding `--safe` docs for pip release fix: stop overwriting safe_mode config.yaml setting with default in args Fixed `%load` magic command But I think we should deprecate it in favor of `--conversations`. Generalized API key error message Better model validation, better config debugging Better config debugging Better config debugging Better config debugging Better --config Cleaned up initial message Generator Update Quick Fixes II Force then squashing (#3) --- .vscode/settings.json | 3 + README.md | 81 +-- del.py | 20 + docs/MACOS.md | 56 +- docs/WINDOWS.md | 4 + interpreter/cli/cli.py | 31 +- .../container_utils/container_utils.py | 313 ++++++++++ .../container_utils/download_file.py | 52 ++ .../container_utils/upload_file.py | 59 ++ .../create_code_interpreter.py | 123 +++- .../code_interpreters/dockerfiles/Dockerfile | 71 +++ .../code_interpreters/dockerfiles/dev_note.md | 22 + .../dockerfiles/docker_manager.py | 63 ++ .../code_interpreters/dockerfiles/hash.json | 4 + .../dockerfiles/requirements.txt | 25 + interpreter/code_interpreters/language_map.py | 17 + .../languages/applescript.py | 8 + .../code_interpreters/languages/html.py | 3 + .../code_interpreters/languages/javascript.py | 22 +- .../code_interpreters/languages/python.py | 14 +- interpreter/code_interpreters/languages/r.py | 22 +- .../code_interpreters/languages/shell.py | 17 +- .../subprocess_code_interpreter.py | 113 ++-- interpreter/core/core.py | 43 +- interpreter/core/respond.py | 31 +- interpreter/llm/convert_to_coding_llm.py | 4 + interpreter/llm/setup_llm.py | 4 +- interpreter/llm/setup_local_text_llm.py | 3 +- interpreter/llm/setup_openai_coding_llm.py | 19 +- interpreter/llm/setup_text_llm.py | 10 +- interpreter/rag/get_relevant_procedures.py | 4 +- .../conversation_navigator.py | 22 +- .../terminal_interface/magic_commands.py | 162 +++-- .../terminal_interface/terminal_interface.py | 37 +- .../validate_llm_settings.py | 3 +- interpreter/utils/scan_code.py | 75 +++ interpreter/utils/temporary_file.py | 47 ++ poetry.lock | 558 +++++++++++++++++- pyproject.toml | 7 +- 39 files changed, 1959 insertions(+), 213 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 del.py create mode 100644 interpreter/code_interpreters/container_utils/container_utils.py create mode 100644 interpreter/code_interpreters/container_utils/download_file.py create mode 100644 interpreter/code_interpreters/container_utils/upload_file.py create mode 100644 interpreter/code_interpreters/dockerfiles/Dockerfile create mode 100644 interpreter/code_interpreters/dockerfiles/dev_note.md create mode 100644 interpreter/code_interpreters/dockerfiles/docker_manager.py create mode 100644 interpreter/code_interpreters/dockerfiles/hash.json create mode 100644 interpreter/code_interpreters/dockerfiles/requirements.txt create mode 100644 interpreter/code_interpreters/language_map.py create mode 100644 interpreter/utils/scan_code.py create mode 100644 interpreter/utils/temporary_file.py diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..457f44d9ba --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.analysis.typeCheckingMode": "basic" +} \ No newline at end of file diff --git a/README.md b/README.md index c7ae42e590..1c6dca0cb0 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,10 @@ https://github.com/KillianLucas/open-interpreter/assets/63927363/37152071-680d-4 [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1WKmRXZgsErej2xUriKzxrEAXdxMSgWbb?usp=sharing) +#### Along with an example implementation of a voice interface (inspired by _Her_): + +[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/drive/1NojYGHDgxH6Y1G1oxThEBBb2AtyODBIK) + ## Quick Start ```shell @@ -93,6 +97,15 @@ This combines the power of GPT-4's Code Interpreter with the flexibility of your ## Commands +**Update:** The Generator Update (0.1.5) introduced streaming: + +```python +message = "What operating system are we on?" + +for chunk in interpreter.chat(message, display=False, stream=True): + print(chunk) +``` + ### Interactive Chat To start an interactive chat in your terminal, either run `interpreter` from the command line: @@ -107,6 +120,15 @@ Or `interpreter.chat()` from a .py file: interpreter.chat() ``` +**You can also stream each chunk:** + +```python +message = "What operating system are we on?" + +for chunk in interpreter.chat(message, display=False, stream=True): + print(chunk) +``` + ### Programmatic Chat For more precise control, you can pass messages directly to `.chat(message)`: @@ -131,13 +153,13 @@ interpreter.reset() ### Save and Restore Chats -`interpreter.chat()` returns a List of messages when return_messages=True, which can be used to resume a conversation with `interpreter.load(messages)`: +`interpreter.chat()` returns a List of messages, which can be used to resume a conversation with `interpreter.messages = messages`: ```python -messages = interpreter.chat("My name is Killian.", return_messages=True) # Save messages to 'messages' +messages = interpreter.chat("My name is Killian.") # Save messages to 'messages' interpreter.reset() # Reset interpreter ("Killian" will be forgotten) -interpreter.load(messages) # Resume chat from 'messages' ("Killian" will be remembered) +interpreter.messages = messages # Resume chat from 'messages' ("Killian" will be remembered) ``` ### Customize System Message @@ -151,20 +173,26 @@ Run shell commands with -y so the user doesn't have to confirm them. print(interpreter.system_message) ``` -### Change the Model +### Change your Language Model -For `gpt-3.5-turbo`, use fast mode: +Open Interpreter uses [LiteLLM](https://docs.litellm.ai/docs/providers/) to connect to language models. + +You can change the model by setting the model parameter: ```shell -interpreter --fast +interpreter --model gpt-3.5-turbo +interpreter --model claude-2 +interpreter --model command-nightly ``` -In Python, you will need to set the model manually: +In Python, set the model on the object: ```python interpreter.model = "gpt-3.5-turbo" ``` +[Find the appropriate "model" string for your language model here.](https://docs.litellm.ai/docs/providers/) + ### Running Open Interpreter locally ⓘ **Issues running locally?** Read our new [GPU setup guide](./docs/GPU.md) and [Windows setup guide](./docs/WINDOWS.md). @@ -175,10 +203,10 @@ You can run `interpreter` in local mode from the command line to use `Code Llama interpreter --local ``` -Or run any Hugging Face model **locally** by using its repo ID (e.g. "tiiuae/falcon-180B"): +Or run any Hugging Face model **locally** by running `--local` in conjunction with a repo ID (e.g. "tiiuae/falcon-180B"): ```shell -interpreter --model tiiuae/falcon-180B +interpreter --local --model tiiuae/falcon-180B ``` #### Local model params @@ -191,25 +219,6 @@ Smaller context windows will use less RAM, so we recommend trying a shorter wind interpreter --max_tokens 2000 --context_window 16000 ``` -### Azure Support - -To connect to an Azure deployment, the `--use-azure` flag will walk you through setting this up: - -```shell -interpreter --use-azure -``` - -In Python, set the following variables: - -``` -interpreter.use_azure = True -interpreter.api_key = "your_openai_api_key" -interpreter.azure_api_base = "your_azure_api_base" -interpreter.azure_api_version = "your_azure_api_version" -interpreter.azure_deployment_name = "your_azure_deployment_name" -interpreter.azure_api_type = "azure" -``` - ### Debug mode To help contributors inspect Open Interpreter, `--debug` mode is highly verbose. @@ -239,24 +248,18 @@ provided, it defaults to 'messages.json'. is provided, it defaults to 'messages.json'. • `%help`: Show the help message. -Feel free to try out these commands and let us know your feedback! +### Configuration -### Configuration with .env +Open Interpreter allows you to set default behaviors using a `config.yaml` file. -Open Interpreter allows you to set default behaviors using a .env file. This provides a flexible way to configure the interpreter without changing command-line arguments every time. +This provides a flexible way to configure the interpreter without changing command-line arguments every time. -Here's a sample .env configuration: +Run the following command to open the configuration file: ``` -INTERPRETER_CLI_AUTO_RUN=False -INTERPRETER_CLI_FAST_MODE=False -INTERPRETER_CLI_LOCAL_RUN=False -INTERPRETER_CLI_DEBUG=False -INTERPRETER_CLI_USE_AZURE=False +interpreter --config ``` -You can modify these values in the .env file to change the default behavior of the Open Interpreter. - ## Safety Notice Since generated code is executed in your local environment, it can interact with your files and system settings, potentially leading to unexpected outcomes like data loss or security risks. diff --git a/del.py b/del.py new file mode 100644 index 0000000000..47d789165b --- /dev/null +++ b/del.py @@ -0,0 +1,20 @@ +from textual.app import App +from textual_terminal import Terminal + +class TerminalApp(App): + + async def on_mount(self) -> None: + # Create a layout with two terminals + await self.layout.dock(Terminal(command="htop", id="terminal_htop"), edge="top", size=10) + await self.layout.dock(Terminal(command="bash", id="terminal_bash"), edge="bottom") + + async def on_ready(self) -> None: + # Start the commands in each terminal + terminal_htop: Terminal = await self.get_widget("terminal_htop") + await terminal_htop.start() + + terminal_bash: Terminal = await self.get_widget("terminal_bash") + await terminal_bash.start() + +app = TerminalApp() +app.run() diff --git a/docs/MACOS.md b/docs/MACOS.md index d5a6faa3a0..ce625c928c 100644 --- a/docs/MACOS.md +++ b/docs/MACOS.md @@ -4,42 +4,80 @@ When running Open Interpreter on macOS with Code-Llama (either because you did not enter an OpenAI API key or you ran `interpreter --local`) you may want to make sure it works correctly by following the instructions below. -Tested on **MacOS Ventura 13.5** with **M2 Pro Chip**. +Tested on **MacOS Ventura 13.5** with **M2 Pro Chip** and **MacOS Ventura 13.5.1** with **M1 Max**. I use conda as a virtual environment but you can choose whatever you want. If you go with conda you will find the Apple M1 version of miniconda here: [Link](https://docs.conda.io/projects/miniconda/en/latest/) -``` +```bash conda create -n openinterpreter python=3.11.4 ``` **Activate your environment:** -``` +```bash conda activate openinterpreter ``` **Install open-interpreter:** -``` +```bash pip install open-interpreter ``` **Uninstall any previously installed llama-cpp-python packages:** -``` +```bash pip uninstall llama-cpp-python -y ``` -**Install llama-cpp-python with Apple Silicon support:** +## Install llama-cpp-python with Apple Silicon support + +### Prerequisites: Xcode Command Line Tools + +Before running the `CMAKE_ARGS` command to install `llama-cpp-python`, make sure you have Xcode Command Line Tools installed on your system. These tools include compilers and build systems essential for source code compilation. -Part 1 +Before proceeding, make sure you have the Xcode Command Line Tools installed. You can check whether they are installed by running: +```bash +xcode-select -p ``` -CMAKE_ARGS="-DLLAMA_METAL=on" FORCE_CMAKE=1 pip install -U llama-cpp-python --no-cache-dir + +If this command returns a path, then the Xcode Command Line Tools are already installed. If not, you'll get an error message, and you can install them by running: + +```bash +xcode-select --install ``` -Part 2 +Follow the on-screen instructions to complete the installation. Once installed, you can proceed with installing an Apple Silicon compatible `llama-cpp-python`. + +--- +### Step 1: Installing llama-cpp-python with ARM64 Architecture and Metal Support + +```bash +CMAKE_ARGS="-DCMAKE_OSX_ARCHITECTURES=arm64 -DLLAMA_METAL=on" FORCE_CMAKE=1 pip install --upgrade --force-reinstall llama-cpp-python --no-cache-dir +--no-cache-dir ``` + +### Step 2: Verifying Installation of llama-cpp-python with ARM64 Support + +After completing the installation, you can verify that `llama-cpp-python` was correctly installed with ARM64 architecture support by running the following command: + +```bash +lipo -info /path/to/libllama.dylib +``` + +Replace `/path/to/` with the actual path to the `libllama.dylib` file. You should see output similar to: + +```bash +Non-fat file: /Users/[user]/miniconda3/envs/openinterpreter/lib/python3.11/site-packages/llama_cpp/libllama.dylib is architecture: arm64 +``` + +If the architecture is indicated as `arm64`, then you've successfully installed the ARM64 version of `llama-cpp-python`. + +### Step 3: Installing Server Components for llama-cpp-python + + +```bash pip install 'llama-cpp-python[server]' ``` diff --git a/docs/WINDOWS.md b/docs/WINDOWS.md index a7405ae387..c69b1435dd 100644 --- a/docs/WINDOWS.md +++ b/docs/WINDOWS.md @@ -40,3 +40,7 @@ The resolve this issue, perform the following steps. ``` Alternatively, if you want to include GPU suppport, follow the steps in [Local Language Models with GPU Support](./GPU.md) + +6. Make sure you close and re-launch any cmd windows that were running interpreter + + diff --git a/interpreter/cli/cli.py b/interpreter/cli/cli.py index 4391994ec6..e5d0867e31 100644 --- a/interpreter/cli/cli.py +++ b/interpreter/cli/cli.py @@ -2,6 +2,7 @@ import subprocess import os import platform +import pkg_resources import appdirs from ..utils.display_markdown_message import display_markdown_message from ..terminal_interface.conversation_navigator import conversation_navigator @@ -72,6 +73,20 @@ "nickname": "ak", "help_text": "optionally set the API key for your llm calls (this will override environment variables)", "type": str + }, + { + "name": "use_containers", + "nickname": "uc", + "help_text": "optionally use a Docker Container for the interpreters code execution. this will seperate execution from your main computer. this also allows execution on a remote server via the 'DOCKER_HOST' environment variable and the dockerengine api.", + "type": bool + }, + { + + "name": "safe_mode", + "nickname": "safe", + "help_text": "optionally enable safety mechanisms like code scanning; valid options are off, ask, and auto", + "type": str, + "choices": ["off", "ask", "auto"] } ] @@ -82,7 +97,7 @@ def cli(interpreter): # Add arguments for arg in arguments: if arg["type"] == bool: - parser.add_argument(f'-{arg["nickname"]}', f'--{arg["name"]}', dest=arg["name"], help=arg["help_text"], action='store_true') + parser.add_argument(f'-{arg["nickname"]}', f'--{arg["name"]}', dest=arg["name"], help=arg["help_text"], action='store_true', default=None) else: parser.add_argument(f'-{arg["nickname"]}', f'--{arg["name"]}', dest=arg["name"], help=arg["help_text"], type=arg["type"]) @@ -90,6 +105,7 @@ def cli(interpreter): parser.add_argument('--config', dest='config', action='store_true', help='open config.yaml file in text editor') parser.add_argument('--conversations', dest='conversations', action='store_true', help='list conversations to resume') parser.add_argument('-f', '--fast', dest='fast', action='store_true', help='(depracated) runs `interpreter --model gpt-3.5-turbo`') + parser.add_argument('--version', dest='version', action='store_true', help="get Open Interpreter's version number") # TODO: Implement model explorer # parser.add_argument('--models', dest='models', action='store_true', help='list avaliable models') @@ -99,7 +115,8 @@ def cli(interpreter): # This should be pushed into an open_config.py util # If --config is used, open the config.yaml file in the Open Interpreter folder of the user's config dir if args.config: - config_path = os.path.join(appdirs.user_config_dir(), 'Open Interpreter', 'config.yaml') + config_dir = appdirs.user_config_dir("Open Interpreter") + config_path = os.path.join(config_dir, 'config.yaml') print(f"Opening `{config_path}`...") # Use the default system editor to open the file if platform.system() == 'Windows': @@ -111,6 +128,7 @@ def cli(interpreter): except FileNotFoundError: # Fallback to using 'open' on macOS if 'xdg-open' is not available subprocess.call(['open', config_path]) + return # TODO Implement model explorer """ @@ -126,6 +144,10 @@ def cli(interpreter): if attr_value is not None and hasattr(interpreter, attr_name): setattr(interpreter, attr_name, attr_value) + # if safe_mode and auto_run are enabled, safe_mode disables auto_run + if interpreter.auto_run and not interpreter.safe_mode == "off": + setattr(interpreter, "auto_run", False) + # Default to CodeLlama if --local is on but --model is unset if interpreter.local and args.model is None: # This will cause the terminal_interface to walk the user through setting up a local LLM @@ -136,6 +158,11 @@ def cli(interpreter): conversation_navigator(interpreter) return + if args.version: + version = pkg_resources.get_distribution("open-interpreter").version + print(f"Open Interpreter {version}") + return + # Depracated --fast if args.fast: # This will cause the terminal_interface to walk the user through setting up a local LLM diff --git a/interpreter/code_interpreters/container_utils/container_utils.py b/interpreter/code_interpreters/container_utils/container_utils.py new file mode 100644 index 0000000000..4277199f74 --- /dev/null +++ b/interpreter/code_interpreters/container_utils/container_utils.py @@ -0,0 +1,313 @@ +# Standard library imports +import atexit +import hashlib +import json +import os +import re +import select +import shutil +import struct +import subprocess +import threading +import time + + +# Third-party imports +import docker +from docker import DockerClient +from docker.errors import DockerException +from rich import print as Print + + +def get_files_hash(*file_paths): + """Return the SHA256 hash of multiple files.""" + hasher = hashlib.sha256() + for file_path in file_paths: + with open(file_path, "rb") as f: + while chunk := f.read(4096): + hasher.update(chunk) + return hasher.hexdigest() + + +def build_docker_images( + dockerfile_dir = os.path.join(os.path.abspath(os.path.dirname(os.path.dirname(__file__))), "dockerfiles") +, +): + """ + Builds a Docker image for the Open Interpreter runtime container if needed. + + Args: + dockerfile_dir (str): The directory containing the Dockerfile and requirements.txt files. + + Returns: + None + """ + try: + client = DockerClient.from_env() + except DockerException: + Print("ERROR: Could not connect to Docker daemon. Is Docker Engine installed and running?") + Print( + "\nFor information on Docker installation, visit: https://docs.docker.com/engine/install/" + ) + return + + image_name = "openinterpreter-runtime-container" + hash_file_path = os.path.join(dockerfile_dir, "hash.json") + + dockerfile_name = "Dockerfile" + requirements_name = "requirements.txt" + dockerfile_path = os.path.join(dockerfile_dir, dockerfile_name) + requirements_path = os.path.join(dockerfile_dir, requirements_name) + + if not os.path.exists(dockerfile_path) or not os.path.exists(requirements_path): + Print("ERROR: Dockerfile or requirements.txt not found. Did you delete or rename them?") + raise RuntimeError( + "No container Dockerfiles or requirements.txt found. Make sure they are in the dockerfiles/ subdir of the module." + ) + + current_hash = get_files_hash(dockerfile_path, requirements_path) + + stored_hashes = {} + if os.path.exists(hash_file_path): + with open(hash_file_path, "rb") as f: + stored_hashes = json.load(f) + + original_hash = stored_hashes.get("original_hash") + previous_hash = stored_hashes.get("last_hash") + + if current_hash == original_hash: + images = client.images.list(name=image_name, all=True) + if not images: + Print("Downloading default image from Docker Hub, please wait...") + client.images.pull("unaidedelf/openinterpreter-runtime-container", tag="latest") + elif current_hash != previous_hash: + Print("Dockerfile or requirements.txt has changed. Building container...") + + try: + # Run the subprocess without capturing stdout and stderr + # This will allow Docker's output to be printed to the console in real-time + subprocess.run( + [ + "docker", + "build", + "-t", + f"{image_name}:latest", + dockerfile_dir, + ], + check=True, # This will raise a CalledProcessError if the command returns a non-zero exit code + text=True, + ) + + # Update the stored current hash + stored_hashes["current_hash"] = current_hash + with open(hash_file_path, "w") as f: + json.dump(stored_hashes, f) + + except subprocess.CalledProcessError: + # Suppress Docker's error messages and display your own error message + Print("Docker Build Error: Building Docker image failed. Please review the error message above and resolve the issue.") + + except FileNotFoundError: + Print("ERROR: The 'docker' command was not found on your system.") + Print( + "Please ensure Docker Engine is installed and the 'docker' command is available in your PATH." + ) + Print( + "For information on Docker installation, visit: https://docs.docker.com/engine/install/" + ) + Print("If Docker is installed, try starting a new terminal session.") + + +class DockerStreamWrapper: + def __init__(self, exec_id, sock): + self.exec_id = exec_id + self._sock = sock + self._stdout_r, self._stdout_w = os.pipe() + self._stderr_r, self._stderr_w = os.pipe() + self.stdout = self.Stream(self, self._stdout_r) + self.stderr = self.Stream(self, self._stderr_r) + + ## stdin pipe and fd. dosent need a pipe, but its easier and thread safe and less mem intensive than a queue.Queue() + self._stdin_r, self._stdin_w = os.pipe() # Pipe for stdin + self.stdin = os.fdopen(self._stdin_w, 'w') + self._stdin_buffer = b"" # Buffer for stdin data. more complex = better fr + + ## start recieving thread to watch socket, and send data from stdin pipe. + self._stop_event = threading.Event() + self._thread = threading.Thread(target=self._listen, daemon=True) + self._thread.start() + + class Stream: + def __init__(self, parent, read_fd): + self.parent = parent + self._read_fd = read_fd + self._buffer = "" + + def readline(self): + while '\n' not in self._buffer: + ready_to_read, _, _ = select.select([self._read_fd], [], [], None) + if not ready_to_read: + return '' + chunk = os.read(self._read_fd, 1024).decode('utf-8') + self._buffer += chunk + + newline_pos = self._buffer.find('\n') + line = self._buffer[:newline_pos] + self._buffer = self._buffer[newline_pos + 1:] + return line + + def _listen(self): + while not self._stop_event.is_set(): + ready_to_read, _, _ = select.select([self._sock, self._stdin_r], [], [], None) + + for s in ready_to_read: + if s == self._sock: + raw_data = self._sock.recv(2048) + stdout, stderr = self.demux_docker_stream(raw_data) + os.write(self._stdout_w, stdout.encode()) + os.write(self._stderr_w, stderr.encode()) + elif s == self._stdin_r: + # Read from the read end of the stdin pipe and add to the buffer + data_to_write = os.read(self._stdin_r, 2048).decode('utf-8') + + # Remove escape characters for quotes but leave other backslashes untouched + data_to_write = re.sub(r'\\([\'"])', r'\1', data_to_write) + + data_to_write = data_to_write.replace('\\n', '\n') + + self._stdin_buffer += data_to_write.encode() + + # Check for newline and send line by line + while b'\n' in self._stdin_buffer: + newline_pos = self._stdin_buffer.find(b'\n') + line = self._stdin_buffer[:newline_pos + 1] # Include the newline + self._stdin_buffer = self._stdin_buffer[newline_pos + 1:] + + + # Send the line to the Docker container + self._sock.sendall(line) + + + def demux_docker_stream(self, data): + stdout = "" + stderr = "" + offset = 0 + while offset + 8 <= len(data): + header = data[offset:offset + 8] + stream_type, length = struct.unpack('>BxxxL', header) + offset += 8 + chunk = data[offset:offset + length].decode('utf-8') + offset += length + if stream_type == 1: + stdout += chunk + elif stream_type == 2: + stderr += chunk + + return stdout, stderr + + def flush(self): + pass + + def close(self): + self._stop_event.set() + self._thread.join() + os.close(self._stdout_r) + os.close(self._stdout_w) + os.close(self._stderr_r) + os.close(self._stderr_w) + + + +class DockerProcWrapper: + def __init__(self, command, session_path): + self.client = docker.APIClient() + self.image_name = "openinterpreter-runtime-container:latest" + self.session_path = session_path + self.exec_id = None + self.exec_socket = None + atexit.register(atexit_destroy, self) + + os.makedirs(self.session_path, exist_ok=True) + + + # Initialize container + self.init_container() + + self.init_exec_instance(command) + + + self.wrapper = DockerStreamWrapper(self.exec_id, self.exec_socket) + self.stdout = self.wrapper.stdout + self.stderr = self.wrapper.stderr + self.stdin = self.wrapper.stdin + + self.stdin.write(command + "\n") + + def init_container(self): + self.container = None + try: + containers = self.client.containers( + filters={"label": f"session_id={os.path.basename(self.session_path)}"}, all=True) + if containers: + self.container = containers[0] + container_id = self.container.get('Id') + container_info = self.client.inspect_container(container_id) + if container_info.get('State', {}).get('Running') is False: + self.client.start(container=container_id) + self.wait_for_container_start(container_id) + else: + host_config = self.client.create_host_config( + binds={self.session_path: {'bind': '/mnt/data', 'mode': 'rw'}} + ) + + self.container = self.client.create_container( + image=self.image_name, + detach=True, + command="/bin/bash -i", + labels={'session_id': os.path.basename(self.session_path)}, + host_config=host_config, + user="docker", + stdin_open=True, + tty=False + ) + + self.client.start(container=self.container.get('Id')) + self.wait_for_container_start(self.container.get('Id')) + + + except Exception as e: + print(f"An error occurred: {e}") + + def init_exec_instance(self, command): + if self.container: + self.exec_id = self.client.exec_create( + self.container.get("Id"), + cmd="/bin/bash", + stdin=True, + stdout=True, + stderr=True, + workdir="/mnt/data", + user="docker", + tty=False + + )['Id'] + self.exec_socket = self.client.exec_start( + self.exec_id, socket=True, tty=False, demux=False)._sock + + + def wait_for_container_start(self, container_id, timeout=30): + start_time = time.time() + while True: + container_info = self.client.inspect_container(container_id) + if container_info.get('State', {}).get('Running') is True: + return True + elif time.time() - start_time > timeout: + raise TimeoutError( + "Container did not start within the specified timeout.") + time.sleep(1) + + +def atexit_destroy(self): + shutil.rmtree(self.session_path) + self.client.stop(self.container.get("Id")) + self.client.remove_container(self.container.get("Id")) diff --git a/interpreter/code_interpreters/container_utils/download_file.py b/interpreter/code_interpreters/container_utils/download_file.py new file mode 100644 index 0000000000..eb6fbb9221 --- /dev/null +++ b/interpreter/code_interpreters/container_utils/download_file.py @@ -0,0 +1,52 @@ +import docker +import tarfile +import os +import tempfile +import appdirs +from tqdm import tqdm + + +def download_file_from_container(container_id, file_path_in_container, local_dir): + # Check if the specified local directory exists + if not os.path.isdir(local_dir): + # If not, use a "Downloads" folder in the user's data directory as the default + local_dir = os.path.join(appdirs.user_data_dir(), "Open Interpreter", "downloads") + print(f"file is being downloaded to {local_dir}") + # Create the Downloads directory if it doesn't exist + os.makedirs(local_dir, exist_ok=True) + + # Create a Docker client + client = docker.from_env() + + # Get the container + container = client.containers.get(container_id) + + # Use get_archive to get a file from the container + stream, stat = container.get_archive(file_path_in_container) + + # Get the file name from the stat info + file_name = os.path.basename(stat['name']) + # Get the size of the file from the stat object for the progress bar + total_size = stat['size'] + # Initialize the progress bar + pbar = tqdm(total=total_size, unit="B", unit_scale=True, desc="Downloading") + + # Update the progress bar within the loop where chunks are being written + with tempfile.NamedTemporaryFile(delete=False) as temp_file: + for chunk in stream: + temp_file.write(chunk) + pbar.update(len(chunk)) + temp_file.flush() + pbar.close() + + # Open the temporary tar file for reading + with tarfile.open(temp_file.name, 'r') as tar: + # Extract the file to the local directory + tar.extractall(path=local_dir) + + # Delete the temporary tar file + os.remove(temp_file.name) + + # Return the path to the extracted file + return os.path.join(local_dir, file_name) + diff --git a/interpreter/code_interpreters/container_utils/upload_file.py b/interpreter/code_interpreters/container_utils/upload_file.py new file mode 100644 index 0000000000..07cdf4af0f --- /dev/null +++ b/interpreter/code_interpreters/container_utils/upload_file.py @@ -0,0 +1,59 @@ +import io +import tarfile +import os +import docker +from tqdm import tqdm + +def copy_file_to_container(container_id, local_path, path_in_container): + # Validate input + if not os.path.exists(local_path): + raise ValueError(f"The specified local path {local_path} does not exist.") + + # Create a Docker client + client = docker.APIClient() + + # Get the container + container = client.containers()[0] + + container_id = container.get("Id") + + # Get the directory path and name in the container + dir_path_in_container = os.path.dirname(path_in_container) + name = os.path.basename(path_in_container) + + # Calculate the total size of the content to be uploaded + total_size = 0 + for dirpath, dirnames, filenames in os.walk(local_path): + for filename in filenames: + filepath = os.path.join(dirpath, filename) + total_size += os.path.getsize(filepath) + + # Create a tarball in memory + file_data = io.BytesIO() + with tarfile.open(fileobj=file_data, mode='w') as tar: + # Check if the local path is a directory or a file + if os.path.isdir(local_path): + # Add the entire directory to the tar archive with the specified name + tar.add(local_path, arcname=name) + else: + # Add the local file to the tar archive with the specified file name + tar.add(local_path, arcname=name) + + # Seek to the beginning of the in-memory tarball + file_data.seek(0) + + # Create a tqdm progress bar + with tqdm(total=total_size, unit='B', unit_scale=True, desc='Uploading') as pbar: + # Define a generator to read the file data in chunks and update the progress bar + def file_data_with_progress(): + chunk_size = 1024 # Define an appropriate chunk size + while True: + chunk = file_data.read(chunk_size) + if not chunk: + break + pbar.update(len(chunk)) + yield chunk + file_data.close() + + # Use put_archive to copy the file or directory into the container + client.put_archive(container=container_id, path=dir_path_in_container, data=file_data_with_progress()) diff --git a/interpreter/code_interpreters/create_code_interpreter.py b/interpreter/code_interpreters/create_code_interpreter.py index 41e99d78d9..5d32123ac5 100644 --- a/interpreter/code_interpreters/create_code_interpreter.py +++ b/interpreter/code_interpreters/create_code_interpreter.py @@ -1,28 +1,113 @@ +<<<<<<< HEAD +import inspect +import os +import uuid +import weakref - -from .languages.python import Python -from .languages.shell import Shell -from .languages.javascript import JavaScript -from .languages.html import HTML +import appdirs from .languages.applescript import AppleScript +from .languages.html import HTML +from .languages.javascript import JavaScript +from .languages.python import Python from .languages.r import R +from .languages.shell import Shell +======= +from .language_map import language_map +>>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) + +LANGUAGE_MAP = { + "python": Python, + "bash": Shell, + "shell": Shell, + "javascript": JavaScript, + "html": HTML, + "applescript": AppleScript, + "r": R, +} + +# Global dictionary to store the session IDs by the weak reference of the calling objects +SESSION_IDS_BY_OBJECT = weakref.WeakKeyDictionary() + + +def create_code_interpreter(language, use_containers=False): + """ + Creates and returns a CodeInterpreter instance for the specified language. + + The function uses weak references to associate session IDs with calling Interpreter objects, + ensuring that the objects can be garbage collected when they are no longer in use. The function + also uses the inspect module to traverse the call stack and identify the calling Interpreter + object. This allows the function to associate a unique session ID with each Interpreter object, + even when the object is passed as a parameter through multiple function calls. -def create_code_interpreter(language): + Parameters: + - language (str): The programming language for which the CodeInterpreter is to be created. + - use_containers (bool): A flag indicating whether to use containers. If True, a session ID is + generated and associated with the calling Interpreter object. + + Returns: + - CodeInterpreter: An instance of the CodeInterpreter class for the specified language, + configured with the session ID if use_containers is True. + + Raises: + - RuntimeError: If unable to access the current frame. + - ValueError: If the specified language is unknown or unsupported. + """ + + from ..core.core import Interpreter # Case in-sensitive language = language.lower() - language_map = { - "python": Python, - "bash": Shell, - "shell": Shell, - "javascript": JavaScript, - "html": HTML, - "applescript": AppleScript, - "r": R, - } +<<<<<<< HEAD + caller_object = None + + if use_containers: + # Get the current frame + current_frame = inspect.currentframe() + + if current_frame is None: + raise RuntimeError("Failed to access the current frame") + + # Initialize frame count + frame_count = 0 + + # Keep going back through the stack frames with a limit of 5 frames back to + # prevent seeing other instances other than the calling one. + while current_frame.f_back and frame_count < 5: + current_frame = current_frame.f_back + frame_count += 1 + # Iterate over local variables in the current frame + for var_value in current_frame.f_locals.values(): + if isinstance(var_value, Interpreter): + # Found an instance of Interpreter + caller_object = var_value + break + + if caller_object: + break + + if caller_object and caller_object not in SESSION_IDS_BY_OBJECT.keys(): + session_id = f"ses-{str(uuid.uuid4())}" + SESSION_IDS_BY_OBJECT[caller_object] = session_id + +======= +>>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) try: - CodeInterpreter = language_map[language] - return CodeInterpreter() - except KeyError: - raise ValueError(f"Unknown or unsupported language: {language}") + # Retrieve the specific CodeInterpreter class based on the language + CodeInterpreter = LANGUAGE_MAP[language] + + # Retrieve the session ID for the current calling object, if available + session_id = SESSION_IDS_BY_OBJECT.get(caller_object, None) if caller_object else None + + if not use_containers: + return CodeInterpreter() + + session_path = os.path.join( + appdirs.user_data_dir("Open Interpreter"), "sessions", session_id + ) + if not os.path.exists(session_path): + os.makedirs(session_path) + return CodeInterpreter(session_id=session_id, use_docker=use_containers) + except KeyError as exc: + raise ValueError(f"Unknown or unsupported language: {language}. \n ") from exc + \ No newline at end of file diff --git a/interpreter/code_interpreters/dockerfiles/Dockerfile b/interpreter/code_interpreters/dockerfiles/Dockerfile new file mode 100644 index 0000000000..2517002a8d --- /dev/null +++ b/interpreter/code_interpreters/dockerfiles/Dockerfile @@ -0,0 +1,71 @@ +# Base image +FROM debian:bullseye + +# Set environment variables to disable prompts +ENV DEBIAN_FRONTEND=noninteractive + +# Update package list and install essential utilities and runtimes +RUN apt-get update && apt-get install -y \ + jq \ + build-essential \ + python3 \ + python3-pip \ + python3-dev \ + curl \ + libssl-dev \ + libexpat1 \ + r-base \ + r-base-dev + +# Install NodeJS +RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - && \ + apt-get install -y nodejs + +# Copy unified requirements.txt into the image +COPY ./requirements.txt /tmp/ + +# Install Python packages +RUN awk '/\[python\]/, /^\s*$/' /tmp/requirements.txt | grep -v '^\[python\]' > /tmp/python_requirements.txt && \ + pip3 install --no-cache-dir -r /tmp/python_requirements.txt --no-input + +# Create an initial empty package.json +RUN echo '{}' > /tmp/package.json + +RUN awk '/\[node\]/, /^\s*$/' /tmp/requirements.txt | grep -v '^\[node\]' > /tmp/node_requirements.txt && \ + while read -r package; do \ + name=$(echo $package | grep -Eo "^[a-zA-Z0-9_-]+") && \ + version=$(echo $package | grep -Eo "[>=<]+[0-9.]+"); \ + if [ -z "$version" ]; then version="*"; fi && \ + jq ".dependencies.\"$name\" = \"$version\"" /tmp/package.json > /tmp/package_temp.json && mv /tmp/package_temp.json /tmp/package.json; \ + done < /tmp/node_requirements.txt + + + +# Install NodeJS packages +RUN npm install --save --yes --no-package-lock --prefix /tmp + +# Install R packages +RUN awk '/\[r\]/,/^\s*$/' /tmp/requirements.txt | grep -v '^\[r\]' > /tmp/r_requirements.txt && \ + while read -r package; do \ + R -e "install.packages('$package', repos='http://cran.rstudio.com/', dependencies=TRUE, INSTALL_opts = c('--no-tests'))"; \ + done < /tmp/r_requirements.txt + +# Install NodeJS packages + +# Remove temporary files +RUN rm /tmp/package.json /tmp/node_requirements.txt /tmp/python_requirements.txt /tmp/r_requirements.txt + +# Create user with sudo only in the container for security. +RUN useradd docker && echo "docker:docker" | chpasswd +RUN mkdir -p /mnt/data && chown -R docker:docker /mnt/data + +RUN apt-get update && apt-get install -y sudo + +RUN usermod -aG sudo docker + +RUN echo "docker ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers + +USER docker + +# Set work directory +WORKDIR /mnt/data diff --git a/interpreter/code_interpreters/dockerfiles/dev_note.md b/interpreter/code_interpreters/dockerfiles/dev_note.md new file mode 100644 index 0000000000..25635278c3 --- /dev/null +++ b/interpreter/code_interpreters/dockerfiles/dev_note.md @@ -0,0 +1,22 @@ +======================================================================= + NOTE TO DEVELOPERS +======================================================================= + +Please avoid manually editing the following files: +- Dockerfile +- requirements.txt +- hash.json + +These files are key components for Open-Interpreter's containerized execution features. Manually editing them can disrupt the program's ability to: + +1. Know when to rebuild the Docker image. +2. Perform other related functionalities efficiently. + +If you need to make adjustments, kindly use the 'DockerManager' class. It offers convenient methods like: +- add_dependency +- remove_dependency +- add_language + +Your cooperation helps maintain a smooth and reliable development workflow. + +======================================================================= diff --git a/interpreter/code_interpreters/dockerfiles/docker_manager.py b/interpreter/code_interpreters/dockerfiles/docker_manager.py new file mode 100644 index 0000000000..149bec37e5 --- /dev/null +++ b/interpreter/code_interpreters/dockerfiles/docker_manager.py @@ -0,0 +1,63 @@ +class DockerManager: + def __init__(self, requirements_file='requirements.txt', docker_file='Dockerfile'): + self.requirements_file = requirements_file + self.docker_file = docker_file + + def add_dependency(self, language, dependency): + lines = [] + language_section_found = False + dependency_name = dependency.split('==')[0] + + with open(self.requirements_file, 'r') as f: + lines = f.readlines() + + for i, line in enumerate(lines): + if line.strip() == f'[{language}]': + language_section_found = True + elif language_section_found: + if line.strip() == '' or line.strip().startswith('['): + break + existing_dependency_name = line.strip().split('==')[0] + if existing_dependency_name == dependency_name: + print(f"Dependency {dependency} already exists under [{language}].") + return + + if not language_section_found: + print(f"Error: Language section [{language}] not found. Please add it first.") + return + + lines.insert(i, f"{dependency}\n") + + with open(self.requirements_file, 'w') as f: + f.writelines(lines) + + def remove_dependency(self, language, dependency_name): + lines = [] + language_section_found = False + + with open(self.requirements_file, 'r') as f: + lines = f.readlines() + + for i, line in enumerate(lines): + if line.strip() == f'[{language}]': + language_section_found = True + elif language_section_found: + if line.strip() == '' or line.strip().startswith('['): + break + existing_dependency_name = line.strip().split('==')[0] + if existing_dependency_name == dependency_name: + del lines[i] + break + else: + raise ValueError(f"Error: Language section [{language}] or dependency {dependency_name} not found. please add the language using the '.add_language' method") + + with open(self.requirements_file, 'w') as f: + f.writelines(lines) + + + def add_language(self, language, install_command): + with open(self.docker_file, 'a') as f: + f.write(f'\n# Install {language}\nRUN {install_command}\n') + + with open(self.requirements_file, 'a') as f: + f.write(f"\n[{language}]\n") diff --git a/interpreter/code_interpreters/dockerfiles/hash.json b/interpreter/code_interpreters/dockerfiles/hash.json new file mode 100644 index 0000000000..18026c04cc --- /dev/null +++ b/interpreter/code_interpreters/dockerfiles/hash.json @@ -0,0 +1,4 @@ +{ + "original_hash": "bf472f80a3acd23a1d9b689da1f3c5834a1a728bf51265e034f0b1bbe44a8435", + "last_hash": "bf472f80a3acd23a1d9b689da1f3c5834a1a728bf51265e034f0b1bbe44a8435" +} \ No newline at end of file diff --git a/interpreter/code_interpreters/dockerfiles/requirements.txt b/interpreter/code_interpreters/dockerfiles/requirements.txt new file mode 100644 index 0000000000..cec9d6f9fc --- /dev/null +++ b/interpreter/code_interpreters/dockerfiles/requirements.txt @@ -0,0 +1,25 @@ +[python] +transformers +datasets +numpy==1.21.2 +pandas==1.3.3 +matplotlib==3.4.3 +seaborn==0.11.2 +scipy==1.7.1 +scikit-learn==0.24.2 +statsmodels==0.12.2 +beautifulsoup4==4.10.0 +nltk==3.6.2 +spacy==3.1.3 +plotly==5.3.1 +bokeh==2.4.0 +dash==2.0.0 +scrapy==2.5.0 +geopandas==0.9.0 +torch==2.0 + +[r] +cowplot + +[node] +chalk==2.0 \ No newline at end of file diff --git a/interpreter/code_interpreters/language_map.py b/interpreter/code_interpreters/language_map.py new file mode 100644 index 0000000000..b6beaeed0d --- /dev/null +++ b/interpreter/code_interpreters/language_map.py @@ -0,0 +1,17 @@ +from .languages.python import Python +from .languages.shell import Shell +from .languages.javascript import JavaScript +from .languages.html import HTML +from .languages.applescript import AppleScript +from .languages.r import R + + +language_map = { + "python": Python, + "bash": Shell, + "shell": Shell, + "javascript": JavaScript, + "html": HTML, + "applescript": AppleScript, + "r": R, +} diff --git a/interpreter/code_interpreters/languages/applescript.py b/interpreter/code_interpreters/languages/applescript.py index 862c9f99b1..4d786493f6 100644 --- a/interpreter/code_interpreters/languages/applescript.py +++ b/interpreter/code_interpreters/languages/applescript.py @@ -2,8 +2,16 @@ from ..subprocess_code_interpreter import SubprocessCodeInterpreter class AppleScript(SubprocessCodeInterpreter): +<<<<<<< HEAD + def __init__(self, **kwargs): + super().__init__(**kwargs) +======= + file_extension = "applescript" + proper_name = "AppleScript" + def __init__(self): super().__init__() +>>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) self.start_cmd = os.environ.get('SHELL', '/bin/zsh') def preprocess_code(self, code): diff --git a/interpreter/code_interpreters/languages/html.py b/interpreter/code_interpreters/languages/html.py index ba4ccde932..965b38717b 100644 --- a/interpreter/code_interpreters/languages/html.py +++ b/interpreter/code_interpreters/languages/html.py @@ -4,6 +4,9 @@ from ..base_code_interpreter import BaseCodeInterpreter class HTML(BaseCodeInterpreter): + file_extension = "html" + proper_name = "HTML" + def __init__(self): super().__init__() diff --git a/interpreter/code_interpreters/languages/javascript.py b/interpreter/code_interpreters/languages/javascript.py index b6be88aefa..37bf5aab96 100644 --- a/interpreter/code_interpreters/languages/javascript.py +++ b/interpreter/code_interpreters/languages/javascript.py @@ -2,8 +2,16 @@ import re class JavaScript(SubprocessCodeInterpreter): +<<<<<<< HEAD + def __init__(self, **kwargs): + super().__init__(**kwargs) +======= + file_extension = "js" + proper_name = "JavaScript" + def __init__(self): super().__init__() +>>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) self.start_cmd = "node -i" def preprocess_code(self, code): @@ -50,12 +58,12 @@ def preprocess_javascript(code): # Wrap in a try-catch and add end of execution marker processed_code = f""" -try {{ -{processed_code} -}} catch (e) {{ - console.log(e); -}} -console.log("## end_of_execution ##"); -""" + try {{ + {processed_code} + }} catch (e) {{ + console.log(e); + }} + console.log("## end_of_execution ##"); + """ return processed_code \ No newline at end of file diff --git a/interpreter/code_interpreters/languages/python.py b/interpreter/code_interpreters/languages/python.py index 3c7ee16167..7cba356386 100644 --- a/interpreter/code_interpreters/languages/python.py +++ b/interpreter/code_interpreters/languages/python.py @@ -4,9 +4,21 @@ import re class Python(SubprocessCodeInterpreter): +<<<<<<< HEAD + def __init__(self, **kwargs): + super().__init__(**kwargs) + if 'use_docker' in kwargs and kwargs['use_docker']: + self.start_cmd = "python3 -i -q -u" + else: + self.start_cmd = sys.executable + " -i -q -u" +======= + file_extension = "py" + proper_name = "Python" + def __init__(self): super().__init__() self.start_cmd = sys.executable + " -i -q -u" +>>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) def preprocess_code(self, code): return preprocess_python(code) @@ -45,7 +57,7 @@ def preprocess_python(code): code = "\n".join(code_lines) # Add end command (we'll be listening for this so we know when it ends) - code += '\n\nprint("## end_of_execution ##")' + code += '\n\nprint("## end_of_execution ##")\n' return code diff --git a/interpreter/code_interpreters/languages/r.py b/interpreter/code_interpreters/languages/r.py index b9733f871b..6e23a13e50 100644 --- a/interpreter/code_interpreters/languages/r.py +++ b/interpreter/code_interpreters/languages/r.py @@ -2,8 +2,16 @@ import re class R(SubprocessCodeInterpreter): +<<<<<<< HEAD + def __init__(self, **kwargs): + super().__init__(**kwargs) +======= + file_extension = "r" + proper_name = "R" + def __init__(self): super().__init__() +>>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) self.start_cmd = "R -q --vanilla" # Start R in quiet and vanilla mode def preprocess_code(self, code): @@ -25,13 +33,13 @@ def preprocess_code(self, code): # Wrap in a tryCatch for error handling and add end of execution marker processed_code = f""" -tryCatch({{ -{processed_code} -}}, error=function(e){{ - cat("## execution_error ##\\n", conditionMessage(e), "\\n"); -}}) -cat("## end_of_execution ##\\n"); -""" + tryCatch({{ + {processed_code} + }}, error=function(e){{ + cat("## execution_error ##\\n", conditionMessage(e), "\\n"); + }}) + cat("## end_of_execution ##\\n"); + """ # Count the number of lines of processed_code # (R echoes all code back for some reason, but we can skip it if we track this!) self.code_line_count = len(processed_code.split("\n")) - 1 diff --git a/interpreter/code_interpreters/languages/shell.py b/interpreter/code_interpreters/languages/shell.py index 5d77eacf6a..da49b77c0a 100644 --- a/interpreter/code_interpreters/languages/shell.py +++ b/interpreter/code_interpreters/languages/shell.py @@ -4,8 +4,16 @@ import os class Shell(SubprocessCodeInterpreter): +<<<<<<< HEAD + def __init__(self, **kwargs): + super().__init__(**kwargs) +======= + file_extension = "sh" + proper_name = "Shell" + def __init__(self): super().__init__() +>>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) # Determine the start command based on the platform if platform.system() == 'Windows': @@ -39,7 +47,8 @@ def preprocess_shell(code): code = add_active_line_prints(code) # Wrap in a trap for errors - code = wrap_in_trap(code) + if platform.system() != 'Windows': + code = wrap_in_trap(code) # Add end command (we'll be listening for this so we know when it ends) code += '\necho "## end_of_execution ##"' @@ -63,7 +72,7 @@ def wrap_in_trap(code): Wrap Bash code with a trap to catch errors and display them. """ trap_code = """ -trap 'echo "An error occurred on line $LINENO"; exit' ERR -set -E -""" + trap 'echo "An error occurred on line $LINENO"; exit' ERR + set -E + """ return trap_code + code diff --git a/interpreter/code_interpreters/subprocess_code_interpreter.py b/interpreter/code_interpreters/subprocess_code_interpreter.py index 04428cece0..2895b9efe7 100644 --- a/interpreter/code_interpreters/subprocess_code_interpreter.py +++ b/interpreter/code_interpreters/subprocess_code_interpreter.py @@ -1,30 +1,53 @@ - - +import os +import queue import subprocess import threading -import queue import time import traceback + +import appdirs from .base_code_interpreter import BaseCodeInterpreter +from .container_utils.container_utils import DockerProcWrapper + class SubprocessCodeInterpreter(BaseCodeInterpreter): - def __init__(self): + """ + A code interpreter that uses subprocess to execute code in a separate process. + + Attributes: + - start_cmd (str): The command to start the interpreter process. + - process (subprocess.Popen): The interpreter process. + - debug_mode (bool): Whether to print debug information. + - output_queue (queue.Queue): A queue to store the output of the interpreter process. + - done (threading.Event): An event to signal when the interpreter process has finished executing. + - contain (bool): Whether to run the interpreter process inside a Docker container. + - session_id (str): The ID of the Docker container session, if `contain` is True. + """ + + def __init__(self, **kwargs): self.start_cmd = "" self.process = None self.debug_mode = False self.output_queue = queue.Queue() self.done = threading.Event() + self.contain = kwargs.get("use_docker", False) + if self.contain: + self.session_id = kwargs.get("session_id") - def detect_active_line(self, line): + @staticmethod + def detect_active_line(line): return None - - def detect_end_of_execution(self, line): + + @staticmethod + def detect_end_of_execution(line): return None - - def line_postprocessor(self, line): + + @staticmethod + def line_postprocessor(line): return line - - def preprocess_code(self, code): + + @staticmethod + def preprocess_code(code): """ This needs to insert an end_of_execution marker of some kind, which can be detected by detect_end_of_execution. @@ -32,27 +55,45 @@ def preprocess_code(self, code): Optionally, add active line markers for detect_active_line. """ return code - + def terminate(self): self.process.terminate() def start_process(self): - if self.process: - self.terminate() - - self.process = subprocess.Popen(self.start_cmd.split(), - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - text=True, - bufsize=0, - universal_newlines=True) - threading.Thread(target=self.handle_stream_output, - args=(self.process.stdout, False), - daemon=True).start() - threading.Thread(target=self.handle_stream_output, - args=(self.process.stderr, True), - daemon=True).start() + """ + Starts the process for the code interpreter. If the interpreter is running in a Docker container, + it uses the DockerProcWrapper class to start the process. Otherwise, it uses subprocess.Popen + to start the process. + + The method also starts two threads to handle the stdout and stderr streams of the process. + + Returns: + None + """ + + if self.contain: + self.process = DockerProcWrapper( + self.start_cmd, # splitting cmd causes problems with docker + session_path=os.path.join( + appdirs.user_data_dir("Open Interpreter"), "sessions", self.session_id + ),) + else: + self.process = subprocess.Popen( + self.start_cmd.split(), + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + bufsize=0, + universal_newlines=True, + ) + + threading.Thread( + target=self.handle_stream_output, args=(self.process.stdout, False), daemon=True + ).start() + threading.Thread( + target=self.handle_stream_output, args=(self.process.stderr, True), daemon=True + ).start() def run(self, code): retry_count = 0 @@ -63,10 +104,9 @@ def run(self, code): code = self.preprocess_code(code) if not self.process: self.start_process() - except: + except subprocess.SubprocessError: yield {"output": traceback.format_exc()} return - while retry_count <= max_retries: if self.debug_mode: @@ -78,7 +118,8 @@ def run(self, code): self.process.stdin.write(code + "\n") self.process.stdin.flush() break - except: + except subprocess.SubprocessError: + yield {"output": traceback.format_exc()} if retry_count != 0: # For UX, I like to hide this if it happens once. Obviously feels better to not see errors # Most of the time it doesn't matter, but we should figure out why it happens frequently with: @@ -100,8 +141,8 @@ def run(self, code): else: time.sleep(0.1) try: - output = self.output_queue.get(timeout=0.3) # Waits for 0.3 seconds - yield output + # Waits for 0.3 seconds + yield self.output_queue.get(timeout=0.3) except queue.Empty: if self.done.is_set(): # Try to yank 3 more times from it... maybe there's something in there... @@ -113,14 +154,14 @@ def run(self, code): break def handle_stream_output(self, stream, is_error_stream): - for line in iter(stream.readline, ''): + for line in iter(stream.readline, ""): if self.debug_mode: print(f"Received output line:\n{line}\n---") line = self.line_postprocessor(line) if line is None: - continue # `line = None` is the postprocessor's signal to discard completely + continue # `line = None` is the postprocessor's signal to discard completely if self.detect_active_line(line): active_line = self.detect_active_line(line) @@ -135,4 +176,4 @@ def handle_stream_output(self, stream, is_error_stream): self.done.set() else: self.output_queue.put({"output": line}) - + \ No newline at end of file diff --git a/interpreter/core/core.py b/interpreter/core/core.py index d74332ff1d..aa499a7bb5 100644 --- a/interpreter/core/core.py +++ b/interpreter/core/core.py @@ -11,10 +11,11 @@ from ..terminal_interface.validate_llm_settings import validate_llm_settings import appdirs import os -import json from datetime import datetime +import json from ..utils.check_for_update import check_for_update from ..utils.display_markdown_message import display_markdown_message +from ..code_interpreters.container_utils.container_utils import build_docker_images class Interpreter: def cli(self): @@ -30,10 +31,11 @@ def __init__(self): self.auto_run = False self.debug_mode = False self.max_output = 2000 + self.safe_mode = "off" # Conversation history self.conversation_history = True - self.conversation_name = datetime.now().strftime("%B_%d_%Y_%H-%M-%S") + self.conversation_filename = None self.conversation_history_path = os.path.join(appdirs.user_data_dir("Open Interpreter"), "conversations") # LLM settings @@ -51,13 +53,23 @@ def __init__(self): config = get_config() self.__dict__.update(config) + # Container options + self.use_containers = False + + # Check for update if not self.local: # This should actually be pushed into the utility if check_for_update(): display_markdown_message("> **A new version of Open Interpreter is available.**\n>Please run: `pip install --upgrade open-interpreter`\n\n---") + + def chat(self, message=None, display=True, stream=False): + + if self.use_containers: + build_docker_images() # Build images if needed. does nothing if already built + if stream: return self._streaming_chat(message=message, display=display) @@ -87,30 +99,43 @@ def _streaming_chat(self, message=None, display=True): return # One-off message - if message: + if message or message == "": + if message == "": + message = "No entry from user - please suggest something to enter" self.messages.append({"role": "user", "message": message}) - yield from self._respond() - # Save conversation + # Save conversation if we've turned conversation_history on if self.conversation_history: + + # If it's the first message, set the conversation name + if not self.conversation_filename: + + first_few_words = "_".join(self.messages[0]["message"][:25].split(" ")[:-1]) + for char in "<>:\"/\\|?*!": # Invalid characters for filenames + first_few_words = first_few_words.replace(char, "") + + date = datetime.now().strftime("%B_%d_%Y_%H-%M-%S") + self.conversation_filename = "__".join([first_few_words, date]) + ".json" + # Check if the directory exists, if not, create it if not os.path.exists(self.conversation_history_path): os.makedirs(self.conversation_history_path) # Write or overwrite the file - with open(os.path.join(self.conversation_history_path, self.conversation_name + '.json'), 'w') as f: + + with open(os.path.join(self.conversation_history_path, self.conversation_filename), 'w') as f: json.dump(self.messages, f) return - - raise Exception("`interpreter.chat()` requires a display. Set `display=True` or pass a message into `interpreter.chat(message)`.") + raise Exception("`interpreter.chat()` requires a display. Set `display=True` or pass a message into `interpreter.chat(message)`.") + def _respond(self): yield from respond(self) def reset(self): self.messages = [] - self.conversation_name = datetime.now().strftime("%B %d, %Y") + self.conversation_filename = None for code_interpreter in self._code_interpreters.values(): code_interpreter.terminate() self._code_interpreters = {} \ No newline at end of file diff --git a/interpreter/core/respond.py b/interpreter/core/respond.py index 3d247e17d1..449d3bb2ea 100644 --- a/interpreter/core/respond.py +++ b/interpreter/core/respond.py @@ -21,11 +21,12 @@ def respond(interpreter): # Open Procedures is an open-source database of tiny, up-to-date coding tutorials. # We can query it semantically and append relevant tutorials/procedures to our system message + get_relevant_procedures(interpreter.messages[-2:]) if not interpreter.local: try: system_message += "\n\n" + get_relevant_procedures(interpreter.messages[-2:]) except: - # This can fail for odd SLL reasons. It's not necessary, so we can continue + # This can fail for odd SSL reasons. It's not necessary, so we can continue pass # Add user info to system_message, like OS, CWD, etc @@ -75,7 +76,7 @@ def respond(interpreter): except Exception as e: if 'auth' in str(e).lower() or 'api key' in str(e).lower(): output = traceback.format_exc() - raise Exception(f"{output}\n\nThere might be an issue with your API key(s).\n\nTo reset your OPENAI_API_KEY (for example):\n Mac/Linux: 'export OPENAI_API_KEY=your-key-here',\n Windows: 'setx OPENAI_API_KEY your-key-here' then restart terminal.\n\n") + raise Exception(f"{output}\n\nThere might be an issue with your API key(s).\n\nTo reset your API key (we'll use OPENAI_API_KEY for this example, but you may need to reset your ANTHROPIC_API_KEY, HUGGINGFACE_API_KEY, etc):\n Mac/Linux: 'export OPENAI_API_KEY=your-key-here',\n Windows: 'setx OPENAI_API_KEY your-key-here' then restart terminal.\n\n") else: raise @@ -101,7 +102,11 @@ def respond(interpreter): # Get a code interpreter to run it language = interpreter.messages[-1]["language"] if language not in interpreter._code_interpreters: - interpreter._code_interpreters[language] = create_code_interpreter(language) + if interpreter.use_containers: + interpreter._code_interpreters[language] = create_code_interpreter(language, use_containers=True) + else: + interpreter._code_interpreters[language] = create_code_interpreter(language) + code_interpreter = interpreter._code_interpreters[language] # Yield a message, such that the user can stop code execution if they want to @@ -112,16 +117,17 @@ def respond(interpreter): # We need to tell python what we (the generator) should do if they exit break - # Track if you've sent_output. - # If you never do, we'll send an empty string (to indicate that code has been run) - sent_output = False - # Yield each line, also append it to last messages' output interpreter.messages[-1]["output"] = "" - for line in code_interpreter.run(code): + + code_to_run = code + + if not code_to_run.endswith("\n"): + code_to_run += "\n" + + for line in code_interpreter.run(code_to_run): yield line if "output" in line: - sent_output = True output = interpreter.messages[-1]["output"] output += "\n" + line["output"] @@ -130,11 +136,6 @@ def respond(interpreter): interpreter.messages[-1]["output"] = output.strip() - if sent_output == False: - # Indicate that the code has been run by sending an empty string - # I think we can remove this now that we send "executing".. right? - yield {"output": ""} - except: output = traceback.format_exc() yield {"output": output.strip()} @@ -146,4 +147,4 @@ def respond(interpreter): # Doesn't want to run code. We're done break - return \ No newline at end of file + return diff --git a/interpreter/llm/convert_to_coding_llm.py b/interpreter/llm/convert_to_coding_llm.py index 6ef626e6a6..c8e85acae7 100644 --- a/interpreter/llm/convert_to_coding_llm.py +++ b/interpreter/llm/convert_to_coding_llm.py @@ -20,6 +20,10 @@ def coding_llm(messages): if debug_mode: print("Chunk in coding_llm", chunk) + + if ('choices' not in chunk or len(chunk['choices']) == 0): + # This happens sometimes + continue content = chunk['choices'][0]['delta'].get('content', "") diff --git a/interpreter/llm/setup_llm.py b/interpreter/llm/setup_llm.py index a2760cc9e7..b2b517b15a 100644 --- a/interpreter/llm/setup_llm.py +++ b/interpreter/llm/setup_llm.py @@ -4,6 +4,7 @@ from .convert_to_coding_llm import convert_to_coding_llm from .setup_openai_coding_llm import setup_openai_coding_llm import os +import litellm def setup_llm(interpreter): """ @@ -11,7 +12,8 @@ def setup_llm(interpreter): returns a Coding LLM (a generator that streams deltas with `message` and `code`). """ - if not interpreter.local and "gpt-" in interpreter.model: + if (not interpreter.local + and (interpreter.model in litellm.open_ai_chat_completion_models or interpreter.model.startswith("azure/"))): # Function calling LLM coding_llm = setup_openai_coding_llm(interpreter) else: diff --git a/interpreter/llm/setup_local_text_llm.py b/interpreter/llm/setup_local_text_llm.py index fc1a765d00..2caa353c8f 100644 --- a/interpreter/llm/setup_local_text_llm.py +++ b/interpreter/llm/setup_local_text_llm.py @@ -60,7 +60,7 @@ def setup_local_text_llm(interpreter): elif answers["selected_model"].startswith("Large"): selected_model = combined_models[-1]["filename"] - if selected_model == None: + if selected_model is None: # This means they either selected See More, # Or the model only had 1 or 2 options @@ -265,7 +265,6 @@ def local_text_llm(messages): else: max_tokens = DEFAULT_MAX_TOKENS - messages = tt.trim( messages, max_tokens=(context_window-max_tokens-25), diff --git a/interpreter/llm/setup_openai_coding_llm.py b/interpreter/llm/setup_openai_coding_llm.py index 0c7aaf343f..a8dcfa16fe 100644 --- a/interpreter/llm/setup_openai_coding_llm.py +++ b/interpreter/llm/setup_openai_coding_llm.py @@ -2,6 +2,7 @@ from ..utils.merge_deltas import merge_deltas from ..utils.parse_partial_json import parse_partial_json from ..utils.convert_to_openai_messages import convert_to_openai_messages +from ..utils.display_markdown_message import display_markdown_message import tokentrim as tt @@ -38,7 +39,7 @@ def coding_llm(messages): # Convert messages messages = convert_to_openai_messages(messages) - # Add OpenAI's reccomended function message + # Add OpenAI's recommended function message messages[0]["content"] += "\n\nOnly use the function you have been provided with." # Seperate out the system_message from messages @@ -47,7 +48,17 @@ def coding_llm(messages): messages = messages[1:] # Trim messages, preserving the system_message - messages = tt.trim(messages=messages, system_message=system_message, model=interpreter.model) + try: + messages = tt.trim(messages=messages, system_message=system_message, model=interpreter.model) + except: + if interpreter.context_window: + messages = tt.trim(messages=messages, system_message=system_message, max_tokens=interpreter.context_window) + else: + display_markdown_message(""" + **We were unable to determine the context window of this model.** Defaulting to 3000. + If your model can handle more, run `interpreter --context_window {token limit}` or `interpreter.context_window = {token limit}`. + """) + messages = tt.trim(messages=messages, system_message=system_message, max_tokens=3000) if interpreter.debug_mode: print("Sending this to the OpenAI LLM:", messages) @@ -76,6 +87,10 @@ def coding_llm(messages): if interpreter.debug_mode: litellm.set_verbose = True + # Report what we're sending to LiteLLM + if interpreter.debug_mode: + print("Sending this to LiteLLM:", params) + response = litellm.completion(**params) accumulated_deltas = {} diff --git a/interpreter/llm/setup_text_llm.py b/interpreter/llm/setup_text_llm.py index 686afcd2c5..de662ddd44 100644 --- a/interpreter/llm/setup_text_llm.py +++ b/interpreter/llm/setup_text_llm.py @@ -79,7 +79,11 @@ def base_llm(messages): try: messages = tt.trim(messages, system_message=system_message, model=interpreter.model) except: - # If we don't know the model, just do 3000. + display_markdown_message(""" + **We were unable to determine the context window of this model.** Defaulting to 3000. + If your model can handle more, run `interpreter --context_window {token limit}` or `interpreter.context_window = {token limit}`. + Also, please set max_tokens: `interpreter --max_tokens {max tokens per response}` or `interpreter.max_tokens = {max tokens per response}` + """) messages = tt.trim(messages, system_message=system_message, max_tokens=3000) if interpreter.debug_mode: @@ -108,6 +112,10 @@ def base_llm(messages): if interpreter.debug_mode: litellm.set_verbose = True + # Report what we're sending to LiteLLM + if interpreter.debug_mode: + print("Sending this to LiteLLM:", params) + return litellm.completion(**params) return base_llm \ No newline at end of file diff --git a/interpreter/rag/get_relevant_procedures.py b/interpreter/rag/get_relevant_procedures.py index 2c38ffb5f4..e84f823860 100644 --- a/interpreter/rag/get_relevant_procedures.py +++ b/interpreter/rag/get_relevant_procedures.py @@ -9,7 +9,7 @@ def get_relevant_procedures(messages): query = {"query": convert_to_openai_messages(messages)} url = "https://open-procedures.replit.app/search/" - relevant_procedures = requests.get(url, json=query).json()["procedures"] - relevant_procedures = "[Recommended Procedures]\n" + "\n---\n".join(relevant_procedures) + "\nIn your plan, include steps and, if present, **EXACT CODE SNIPPETS** (especially for depracation notices, **WRITE THEM INTO YOUR PLAN -- underneath each numbered step** as they will VANISH once you execute your first line of code, so WRITE THEM DOWN NOW if you need them) from the above procedures if they are relevant to the task. Again, include **VERBATIM CODE SNIPPETS** from the procedures above if they are relevent to the task **directly in your plan.**" + relevant_procedures = requests.post(url, json=query).json()["procedures"] + relevant_procedures = "[Recommended Procedures]\n" + "\n---\n".join(relevant_procedures) + "\nIn your plan, include steps and, if present, **EXACT CODE SNIPPETS** (especially for deprecation notices, **WRITE THEM INTO YOUR PLAN -- underneath each numbered step** as they will VANISH once you execute your first line of code, so WRITE THEM DOWN NOW if you need them) from the above procedures if they are relevant to the task. Again, include **VERBATIM CODE SNIPPETS** from the procedures above if they are relevent to the task **directly in your plan.**" return relevant_procedures \ No newline at end of file diff --git a/interpreter/terminal_interface/conversation_navigator.py b/interpreter/terminal_interface/conversation_navigator.py index 6b3e68975c..a2a1c624ca 100644 --- a/interpreter/terminal_interface/conversation_navigator.py +++ b/interpreter/terminal_interface/conversation_navigator.py @@ -28,24 +28,34 @@ def conversation_navigator(interpreter): # Get list of all JSON files in the directory json_files = [f for f in os.listdir(conversations_dir) if f.endswith('.json')] - json_files.append("> Open folder") # Add the option to open the folder + + # Make a dict that maps reformatted "First few words... (September 23rd)" -> "First_few_words__September_23rd.json" (original file name) + readable_names_and_filenames = {} + for filename in json_files: + name = filename.replace(".json", "").replace(".JSON", "").replace("__", "... (").replace("_", " ") + ")" + readable_names_and_filenames[name] = filename + + # Add the option to open the folder. This doesn't map to a filename, we'll catch it + readable_names_and_filenames["> Open folder"] = None # Use inquirer to let the user select a file questions = [ - inquirer.List('file', + inquirer.List('name', message="", - choices=json_files, + choices=readable_names_and_filenames.keys(), ), ] answers = inquirer.prompt(questions) # If the user selected to open the folder, do so and return - if answers['file'] == "> Open folder": + if answers['name'] == "> Open folder": open_folder(conversations_dir) return + selected_filename = readable_names_and_filenames[answers['name']] + # Open the selected file and load the JSON data - with open(os.path.join(conversations_dir, answers['file']), 'r') as f: + with open(os.path.join(conversations_dir, selected_filename), 'r') as f: messages = json.load(f) # Pass the data into render_past_conversation @@ -53,7 +63,7 @@ def conversation_navigator(interpreter): # Set the interpreter's settings to the loaded messages interpreter.messages = messages - interpreter.conversation_name = answers['file'].replace(".json", "") + interpreter.conversation_filename = selected_filename # Start the chat interpreter.chat() diff --git a/interpreter/terminal_interface/magic_commands.py b/interpreter/terminal_interface/magic_commands.py index 8a438270e3..cfb3aa99fa 100644 --- a/interpreter/terminal_interface/magic_commands.py +++ b/interpreter/terminal_interface/magic_commands.py @@ -1,6 +1,13 @@ -from ..utils.display_markdown_message import display_markdown_message import json import os +import appdirs +import docker + +from ..utils.display_markdown_message import display_markdown_message +from ..code_interpreters.container_utils.download_file import download_file_from_container +from ..code_interpreters.container_utils.upload_file import copy_file_to_container +from ..code_interpreters.create_code_interpreter import SESSION_IDS_BY_OBJECT + def handle_undo(self, arguments): # Removes all messages after the most recent user entry (and the entry itself). @@ -8,7 +15,7 @@ def handle_undo(self, arguments): # Also gives a visual representation of the messages removed. if len(self.messages) == 0: - return + return # Find the index of the last 'role': 'user' entry last_user_index = None for i, message in enumerate(self.messages): @@ -22,37 +29,40 @@ def handle_undo(self, arguments): removed_messages = self.messages[last_user_index:] self.messages = self.messages[:last_user_index] - print("") # Aesthetics. + print("") # Aesthetics. # Print out a preview of what messages were removed. for message in removed_messages: - if 'content' in message and message['content'] != None: - display_markdown_message(f"**Removed message:** `\"{message['content'][:30]}...\"`") - elif 'function_call' in message: - display_markdown_message(f"**Removed codeblock**") # TODO: Could add preview of code removed here. - - print("") # Aesthetics. + if 'content' in message and message['content'] != None: + display_markdown_message( + f"**Removed message:** `\"{message['content'][:30]}...\"`") + elif 'function_call' in message: + # TODO: Could add preview of code removed here. + display_markdown_message(f"**Removed codeblock**") + + print("") # Aesthetics. + def handle_help(self, arguments): commands_description = { - "%debug [true/false]": "Toggle debug mode. Without arguments or with 'true', it enters debug mode. With 'false', it exits debug mode.", - "%reset": "Resets the current session.", - "%undo": "Remove previous messages and its response from the message history.", - "%save_message [path]": "Saves messages to a specified JSON path. If no path is provided, it defaults to 'messages.json'.", - "%load_message [path]": "Loads messages from a specified JSON path. If no path is provided, it defaults to 'messages.json'.", - "%help": "Show this help message.", + "%debug [true/false]": "Toggle debug mode. Without arguments or with 'true', it enters debug mode. With 'false', it exits debug mode.", + "%reset": "Resets the current session.", + "%undo": "Remove previous messages and its response from the message history.", + "%save_message [path]": "Saves messages to a specified JSON path. If no path is provided, it defaults to 'messages.json'.", + "%load_message [path]": "Loads messages from a specified JSON path. If no path is provided, it defaults to 'messages.json'.", + "%help": "Show this help message.", } base_message = [ - "> **Available Commands:**\n\n" + "> **Available Commands:**\n\n" ] # Add each command and its description to the message for cmd, desc in commands_description.items(): - base_message.append(f"- `{cmd}`: {desc}\n") + base_message.append(f"- `{cmd}`: {desc}\n") additional_info = [ - "\n\nFor further assistance, please join our community Discord or consider contributing to the project's development." + "\n\nFor further assistance, please join our community Discord or consider contributing to the project's development." ] # Combine the base message with the additional info @@ -72,47 +82,131 @@ def handle_debug(self, arguments=None): else: display_markdown_message("> Unknown argument to debug command.") + def handle_reset(self, arguments): self.reset() display_markdown_message("> Reset Done") + def default_handle(self, arguments): display_markdown_message("> Unknown command") - self.handle_help(arguments) + handle_help(self,arguments) def handle_save_message(self, json_path): if json_path == "": - json_path = "messages.json" + json_path = "messages.json" if not json_path.endswith(".json"): - json_path += ".json" + json_path += ".json" with open(json_path, 'w') as f: - json.dump(self.messages, f, indent=2) + json.dump(self.messages, f, indent=2) + + display_markdown_message( + f"> messages json export to {os.path.abspath(json_path)}") - display_markdown_message(f"> messages json export to {os.path.abspath(json_path)}") def handle_load_message(self, json_path): if json_path == "": - json_path = "messages.json" + json_path = "messages.json" if not json_path.endswith(".json"): - json_path += ".json" + json_path += ".json" with open(json_path, 'r') as f: - self.load(json.load(f)) + self.messages = json.load(f) + + display_markdown_message( + f"> messages json loaded from {os.path.abspath(json_path)}") + +def handle_container_upload(self, *args): + + if self.use_containers: + try: + client = docker.APIClient() + except: + error_message = ( + "We were not able to connect to the Docker Container daemon. " + "Please ensure Docker is installed and running. If you have not run any code yet, " + "you will need to in order to start a container." + ) + display_markdown_message(f"{error_message}") + return + + for filepath in args: + if os.path.exists(filepath): + session_id = SESSION_IDS_BY_OBJECT.get(self) + containers = client.containers(filters={"label": f"session_id={session_id}"}) + if containers: + container_id = containers[0]['Id'] + # /mnt/data is default workdir for container + copy_file_to_container( + container_id=container_id, local_path=filepath, path_in_container=f"/mnt/data/{os.path.basename(filepath)}" + ) + success_message = f"File [{filepath}](#) successfully uploaded to container in dir `/mnt/data`." + display_markdown_message(success_message) + else: + no_container_message = ( + "No container found to upload to. Please run any code to start one. " + "This will be fixed in a later update." + ) + display_markdown_message(f"**'{no_container_message}'**") + else: + file_not_found_message = f"File `{filepath}` does not exist." + display_markdown_message(file_not_found_message) + else: + ignore_command_message = "File uploads are only used when using containerized code execution. Ignoring command." + display_markdown_message(f"**{ignore_command_message}**") + +def handle_container_download(self, *args): + if self.use_containers: + try: + client = docker.APIClient() + except Exception as e: + print("[BOLD][RED]Unable to connect to the Docker Container daemon. Please ensure Docker is installed and running. ignoring command[/BOLD]") + return + + session_id = SESSION_IDS_BY_OBJECT.get(self) + if session_id is None: + print("No session found. Please run any code to start one.") + return + + containers = client.containers(filters={"label": f"session_id={session_id}"}) + if not containers: + print("No container found to download from. Please run any code to start one.") + return + + container_id = containers[0]['Id'] + + # Define the local directory where the files will be downloaded. + # Using 'Open Interpreter' as the appname and no author. + local_dir = appdirs.user_data_dir(appname="Open Interpreter") + + for file_path_in_container in args: + # Construct the local file path + local_file_path = os.path.join(local_dir, os.path.basename(file_path_in_container)) + + # Attempt to download the file and handle exceptions + try: + download_file_from_container(container_id, file_path_in_container, local_file_path) + print(f"File downloaded to {local_file_path}") + except docker.errors.NotFound: + print(f"File {file_path_in_container} not found in the container.") + else: + print("File downloads are only used when using containerized code execution. Ignoring command.") - display_markdown_message(f"> messages json loaded from {os.path.abspath(json_path)}") def handle_magic_command(self, user_input): # split the command into the command and the arguments, by the first whitespace switch = { - "help": handle_help, - "debug": handle_debug, - "reset": handle_reset, - "save_message": handle_save_message, - "load_message": handle_load_message, - "undo": handle_undo, + "help": handle_help, + "debug": handle_debug, + "reset": handle_reset, + "save_message": handle_save_message, + "load_message": handle_load_message, + "undo": handle_undo, + "upload": handle_container_upload, + "download": handle_container_download, } user_input = user_input[1:].strip() # Capture the part after the `%` command = user_input.split(" ")[0] arguments = user_input[len(command):].strip() action = switch.get(command, default_handle) # Get the function from the dictionary, or default_handle if not found - action(self, arguments) # Execute the function \ No newline at end of file + action(self, arguments) # Execute the function. diff --git a/interpreter/terminal_interface/terminal_interface.py b/interpreter/terminal_interface/terminal_interface.py index fe9469d5d9..6edf09402c 100644 --- a/interpreter/terminal_interface/terminal_interface.py +++ b/interpreter/terminal_interface/terminal_interface.py @@ -8,13 +8,24 @@ from .magic_commands import handle_magic_command from ..utils.display_markdown_message import display_markdown_message from ..utils.truncate_output import truncate_output +from ..utils.scan_code import scan_code def terminal_interface(interpreter, message): if not interpreter.auto_run: - display_markdown_message("""**Open Interpreter** will require approval before running code. Use `interpreter -y` to bypass this. + interpreter_intro_message = [ + "**Open Interpreter** will require approval before running code." + ] - Press `CTRL-C` to exit. - """) + if interpreter.safe_mode != "off": + interpreter_intro_message.append(f"**Safe Mode**: {interpreter.safe_mode}") + else: + interpreter_intro_message.append( + "Use `interpreter -y` to bypass this." + ) + + interpreter_intro_message.append("Press `CTRL-C` to exit.") + + display_markdown_message("\n\n".join(interpreter_intro_message)) active_block = None @@ -87,6 +98,26 @@ def terminal_interface(interpreter, message): # End the active block so you can run input() below it active_block.end() + should_scan_code = False + + if not interpreter.scan_code == "off": + if interpreter.scan_code == "auto": + should_scan_code = True + elif interpreter.scan_code == 'ask': + response = input(" Would you like to scan this code? (y/n)\n\n ") + print("") # <- Aesthetic choice + + if response.strip().lower() == "y": + should_scan_code = True + + if should_scan_code: + # Get code language and actual code from the chunk + # We need to give these to semgrep when we start our scan + language = chunk["executing"]["language"] + code = chunk["executing"]["code"] + + scan_code(code, language, interpreter) + response = input(" Would you like to run this code? (y/n)\n\n ") print("") # <- Aesthetic choice diff --git a/interpreter/terminal_interface/validate_llm_settings.py b/interpreter/terminal_interface/validate_llm_settings.py index cf03150ab0..64fd5b4598 100644 --- a/interpreter/terminal_interface/validate_llm_settings.py +++ b/interpreter/terminal_interface/validate_llm_settings.py @@ -83,7 +83,8 @@ def validate_llm_settings(interpreter): **Tip:** To save this key for later, run `export OPENAI_API_KEY=your_api_key` on Mac/Linux or `setx OPENAI_API_KEY your_api_key` on Windows. ---""") - + + interpreter.api_key = response time.sleep(2) break diff --git a/interpreter/utils/scan_code.py b/interpreter/utils/scan_code.py new file mode 100644 index 0000000000..441892da25 --- /dev/null +++ b/interpreter/utils/scan_code.py @@ -0,0 +1,75 @@ +import os +import subprocess + +from .temporary_file import create_temporary_file, cleanup_temporary_file +from ..code_interpreters.language_map import language_map + + +def get_language_file_extension(language_name): + """ + Get the file extension for a given language + """ + language = language_map[language_name.lower()] + + if language.file_extension: + return language.file_extension + else: + return language + + +def get_language_proper_name(language_name): + """ + Get the proper name for a given language + """ + language = language_map[language_name.lower()] + + if language.proper_name: + return language.proper_name + else: + return language + + +def scan_code(code, language, interpreter): + """ + Scan code with semgrep + """ + + temp_file = create_temporary_file( + code, get_language_file_extension(language), verbose=interpreter.debug_mode + ) + + temp_path = os.path.dirname(temp_file) + file_name = os.path.basename(temp_file) + + if interpreter.debug_mode: + print(f"Scanning {language} code in {file_name}") + print("---") + + # Run semgrep + try: + # HACK: we need to give the subprocess shell access so that the semgrep from our pyproject.toml is available + # the global namespace might have semgrep from guarddog installed, but guarddog is currenlty + # pinned to an old semgrep version that has issues with reading the semgrep registry + # while scanning a single file like the temporary one we generate + # if guarddog solves [#249](https://github.com/DataDog/guarddog/issues/249) we can change this approach a bit + scan = subprocess.run( + f"cd {temp_path} && semgrep scan --config auto --quiet --error {file_name}", + shell=True, + ) + + if scan.returncode == 0: + language_name = get_language_proper_name(language) + print( + f" {'Code Scaner: ' if interpreter.safe_mode == 'auto' else ''}No issues were found in this {language_name} code." + ) + print("") + + # TODO: it would be great if we could capture any vulnerabilities identified by semgrep + # and add them to the conversation history + + except Exception as e: + print(f"Could not scan {language} code.") + print(e) + print("") # <- Aesthetic choice + + cleanup_temporary_file(temp_file, verbose=interpreter.debug_mode) diff --git a/interpreter/utils/temporary_file.py b/interpreter/utils/temporary_file.py new file mode 100644 index 0000000000..c72bf5f30a --- /dev/null +++ b/interpreter/utils/temporary_file.py @@ -0,0 +1,47 @@ +import os +import tempfile + + +def cleanup_temporary_file(temp_file_name, verbose=False): + """ + clean up temporary file + """ + + try: + # clean up temporary file + os.remove(temp_file_name) + + if verbose: + print(f"Cleaning up temporary file {temp_file_name}") + print("---") + + except Exception as e: + print(f"Could not clean up temporary file.") + print(e) + print("") + + +def create_temporary_file(contents, extension=None, verbose=False): + """ + create a temporary file with the given contents + """ + + try: + # Create a temporary file + with tempfile.NamedTemporaryFile( + mode="w", delete=False, suffix=f".{extension}" if extension else "" + ) as f: + f.write(contents) + temp_file_name = f.name + f.close() + + if verbose: + print(f"Created temporary file {temp_file_name}") + print("---") + + return temp_file_name + + except Exception as e: + print(f"Could not create temporary file.") + print(e) + print("") diff --git a/poetry.lock b/poetry.lock index 4bdef1e2ed..f9c0ce72e9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -200,6 +200,28 @@ jinxed = {version = ">=1.1.0", markers = "platform_system == \"Windows\""} six = ">=1.9.0" wcwidth = ">=0.1.4" +[[package]] +name = "boltons" +version = "21.0.0" +description = "When they're not builtins, they're boltons." +optional = false +python-versions = "*" +files = [ + {file = "boltons-21.0.0-py2.py3-none-any.whl", hash = "sha256:b9bb7b58b2b420bbe11a6025fdef6d3e5edc9f76a42fb467afe7ca212ef9948b"}, + {file = "boltons-21.0.0.tar.gz", hash = "sha256:65e70a79a731a7fe6e98592ecfb5ccf2115873d01dbc576079874629e5c90f13"}, +] + +[[package]] +name = "bracex" +version = "2.4" +description = "Bash style brace expander." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bracex-2.4-py3-none-any.whl", hash = "sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418"}, + {file = "bracex-2.4.tar.gz", hash = "sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb"}, +] + [[package]] name = "certifi" version = "2023.7.22" @@ -295,6 +317,39 @@ files = [ {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, ] +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "click-option-group" +version = "0.5.6" +description = "Option groups missing in Click" +optional = false +python-versions = ">=3.6,<4" +files = [ + {file = "click-option-group-0.5.6.tar.gz", hash = "sha256:97d06703873518cc5038509443742b25069a3c7562d1ea72ff08bfadde1ce777"}, + {file = "click_option_group-0.5.6-py3-none-any.whl", hash = "sha256:38a26d963ee3ad93332ddf782f9259c5bdfe405e73408d943ef5e7d0c3767ec7"}, +] + +[package.dependencies] +Click = ">=7.0,<9" + +[package.extras] +docs = ["Pallets-Sphinx-Themes", "m2r2", "sphinx"] +tests = ["pytest"] +tests-cov = ["coverage", "coveralls", "pytest", "pytest-cov"] + [[package]] name = "colorama" version = "0.4.6" @@ -306,6 +361,40 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +<<<<<<< HEAD +name = "docker" +version = "6.1.3" +description = "A Python library for the Docker Engine API." +optional = false +python-versions = ">=3.7" +files = [ + {file = "docker-6.1.3-py3-none-any.whl", hash = "sha256:aecd2277b8bf8e506e484f6ab7aec39abe0038e29fa4a6d3ba86c3fe01844ed9"}, + {file = "docker-6.1.3.tar.gz", hash = "sha256:aa6d17830045ba5ef0168d5eaa34d37beeb113948c413affe1d5991fc11f9a20"}, +] + +[package.dependencies] +packaging = ">=14.0" +pywin32 = {version = ">=304", markers = "sys_platform == \"win32\""} +requests = ">=2.26.0" +urllib3 = ">=1.26.0" +websocket-client = ">=0.32.0" + +[package.extras] +ssh = ["paramiko (>=2.4.3)"] + +======= +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + +>>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) [[package]] name = "exceptiongroup" version = "1.1.3" @@ -320,6 +409,20 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "face" +version = "22.0.0" +description = "A command-line application framework (and CLI parser). Friendly for users, full-featured for developers." +optional = false +python-versions = "*" +files = [ + {file = "face-22.0.0-py3-none-any.whl", hash = "sha256:344fe31562d0f6f444a45982418f3793d4b14f9abb98ccca1509d22e0a3e7e35"}, + {file = "face-22.0.0.tar.gz", hash = "sha256:d5d692f90bc8f5987b636e47e36384b9bbda499aaf0a77aa0b0bbe834c76923d"}, +] + +[package.dependencies] +boltons = ">=20.0.0" + [[package]] name = "filelock" version = "3.12.4" @@ -486,6 +589,25 @@ gitdb = ">=4.0.1,<5" [package.extras] test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-sugar"] +[[package]] +name = "glom" +version = "22.1.0" +description = "A declarative object transformer and formatter, for conglomerating nested data." +optional = false +python-versions = "*" +files = [ + {file = "glom-22.1.0-py2.py3-none-any.whl", hash = "sha256:5339da206bf3532e01a83a35aca202960ea885156986d190574b779598e9e772"}, + {file = "glom-22.1.0.tar.gz", hash = "sha256:1510c6587a8f9c64a246641b70033cbc5ebde99f02ad245693678038e821aeb5"}, +] + +[package.dependencies] +attrs = "*" +boltons = ">=19.3.0" +face = ">=20.1.0" + +[package.extras] +yaml = ["PyYAML"] + [[package]] name = "huggingface-hub" version = "0.16.4" @@ -589,15 +711,50 @@ files = [ [package.dependencies] ansicon = {version = "*", markers = "platform_system == \"Windows\""} +[[package]] +name = "jsonschema" +version = "4.19.1" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.19.1-py3-none-any.whl", hash = "sha256:cd5f1f9ed9444e554b38ba003af06c0a8c2868131e56bfbef0550fb450c0330e"}, + {file = "jsonschema-4.19.1.tar.gz", hash = "sha256:ec84cc37cfa703ef7cd4928db24f9cb31428a5d0fa77747b8b51a847458e0bbf"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "jsonschema-specifications" +version = "2023.7.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.7.1-py3-none-any.whl", hash = "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1"}, + {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"}, +] + +[package.dependencies] +referencing = ">=0.28.0" + [[package]] name = "litellm" -version = "0.1.738" +version = "0.1.736" description = "Library to easily interface with LLM API providers" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "litellm-0.1.738-py3-none-any.whl", hash = "sha256:dbb563aa1658ba90a1678a7bed0b53fe8712476cdadca61245c21f053ac54177"}, - {file = "litellm-0.1.738.tar.gz", hash = "sha256:67069c76b215e5f5deae91777f205f27641337ba5aa963c2abe720f3e3bee077"}, + {file = "litellm-0.1.736-py3-none-any.whl", hash = "sha256:2918b3b0e807b39b6575e36c02624352fafd5ba2f01c923782f8f3b863793bb4"}, + {file = "litellm-0.1.736.tar.gz", hash = "sha256:3d4dc22bee2cb11243d8111f61493acc0f32b4bfe46eb478b2b940c85e1b546b"}, ] [package.dependencies] @@ -758,6 +915,16 @@ files = [ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] +[[package]] +name = "peewee" +version = "3.16.3" +description = "a little orm" +optional = false +python-versions = "*" +files = [ + {file = "peewee-3.16.3.tar.gz", hash = "sha256:12b30e931193bc37b11f7c2ac646e3f67125a8b1a543ad6ab37ad124c8df7d16"}, +] + [[package]] name = "pluggy" version = "1.3.0" @@ -846,6 +1013,48 @@ files = [ {file = "python_editor-1.0.4-py3-none-any.whl", hash = "sha256:1bf6e860a8ad52a14c3ee1252d5dc25b2030618ed80c022598f00176adc8367d"}, ] +[[package]] +<<<<<<< HEAD +name = "pywin32" +version = "306" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +files = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, +] + +======= +name = "python-lsp-jsonrpc" +version = "1.0.0" +description = "JSON RPC 2.0 server library" +optional = false +python-versions = "*" +files = [ + {file = "python-lsp-jsonrpc-1.0.0.tar.gz", hash = "sha256:7bec170733db628d3506ea3a5288ff76aa33c70215ed223abdb0d95e957660bd"}, + {file = "python_lsp_jsonrpc-1.0.0-py3-none-any.whl", hash = "sha256:079b143be64b0a378bdb21dff5e28a8c1393fe7e8a654ef068322d754e545fc7"}, +] + +[package.dependencies] +ujson = ">=3.0.0" + +[package.extras] +test = ["coverage", "pycodestyle", "pyflakes", "pylint", "pytest", "pytest-cov"] + +>>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) [[package]] name = "pyyaml" version = "6.0.1" @@ -919,6 +1128,21 @@ files = [ [package.dependencies] setuptools = ">=41.0" +[[package]] +name = "referencing" +version = "0.30.2" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.30.2-py3-none-any.whl", hash = "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"}, + {file = "referencing-0.30.2.tar.gz", hash = "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + [[package]] name = "regex" version = "2023.8.8" @@ -1055,6 +1279,213 @@ pygments = ">=2.13.0,<3.0.0" [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] +[[package]] +name = "rpds-py" +version = "0.10.3" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.10.3-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:485747ee62da83366a44fbba963c5fe017860ad408ccd6cd99aa66ea80d32b2e"}, + {file = "rpds_py-0.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c55f9821f88e8bee4b7a72c82cfb5ecd22b6aad04033334f33c329b29bfa4da0"}, + {file = "rpds_py-0.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3b52a67ac66a3a64a7e710ba629f62d1e26ca0504c29ee8cbd99b97df7079a8"}, + {file = "rpds_py-0.10.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3aed39db2f0ace76faa94f465d4234aac72e2f32b009f15da6492a561b3bbebd"}, + {file = "rpds_py-0.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:271c360fdc464fe6a75f13ea0c08ddf71a321f4c55fc20a3fe62ea3ef09df7d9"}, + {file = "rpds_py-0.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef5fddfb264e89c435be4adb3953cef5d2936fdeb4463b4161a6ba2f22e7b740"}, + {file = "rpds_py-0.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a771417c9c06c56c9d53d11a5b084d1de75de82978e23c544270ab25e7c066ff"}, + {file = "rpds_py-0.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:52b5cbc0469328e58180021138207e6ec91d7ca2e037d3549cc9e34e2187330a"}, + {file = "rpds_py-0.10.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6ac3fefb0d168c7c6cab24fdfc80ec62cd2b4dfd9e65b84bdceb1cb01d385c33"}, + {file = "rpds_py-0.10.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8d54bbdf5d56e2c8cf81a1857250f3ea132de77af543d0ba5dce667183b61fec"}, + {file = "rpds_py-0.10.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cd2163f42868865597d89399a01aa33b7594ce8e2c4a28503127c81a2f17784e"}, + {file = "rpds_py-0.10.3-cp310-none-win32.whl", hash = "sha256:ea93163472db26ac6043e8f7f93a05d9b59e0505c760da2a3cd22c7dd7111391"}, + {file = "rpds_py-0.10.3-cp310-none-win_amd64.whl", hash = "sha256:7cd020b1fb41e3ab7716d4d2c3972d4588fdfbab9bfbbb64acc7078eccef8860"}, + {file = "rpds_py-0.10.3-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:1d9b5ee46dcb498fa3e46d4dfabcb531e1f2e76b477e0d99ef114f17bbd38453"}, + {file = "rpds_py-0.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:563646d74a4b4456d0cf3b714ca522e725243c603e8254ad85c3b59b7c0c4bf0"}, + {file = "rpds_py-0.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e626b864725680cd3904414d72e7b0bd81c0e5b2b53a5b30b4273034253bb41f"}, + {file = "rpds_py-0.10.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:485301ee56ce87a51ccb182a4b180d852c5cb2b3cb3a82f7d4714b4141119d8c"}, + {file = "rpds_py-0.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:42f712b4668831c0cd85e0a5b5a308700fe068e37dcd24c0062904c4e372b093"}, + {file = "rpds_py-0.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c9141af27a4e5819d74d67d227d5047a20fa3c7d4d9df43037a955b4c748ec5"}, + {file = "rpds_py-0.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef750a20de1b65657a1425f77c525b0183eac63fe7b8f5ac0dd16f3668d3e64f"}, + {file = "rpds_py-0.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e1a0ffc39f51aa5f5c22114a8f1906b3c17eba68c5babb86c5f77d8b1bba14d1"}, + {file = "rpds_py-0.10.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f4c179a7aeae10ddf44c6bac87938134c1379c49c884529f090f9bf05566c836"}, + {file = "rpds_py-0.10.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:176287bb998fd1e9846a9b666e240e58f8d3373e3bf87e7642f15af5405187b8"}, + {file = "rpds_py-0.10.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6446002739ca29249f0beaaf067fcbc2b5aab4bc7ee8fb941bd194947ce19aff"}, + {file = "rpds_py-0.10.3-cp311-none-win32.whl", hash = "sha256:c7aed97f2e676561416c927b063802c8a6285e9b55e1b83213dfd99a8f4f9e48"}, + {file = "rpds_py-0.10.3-cp311-none-win_amd64.whl", hash = "sha256:8bd01ff4032abaed03f2db702fa9a61078bee37add0bd884a6190b05e63b028c"}, + {file = "rpds_py-0.10.3-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:4cf0855a842c5b5c391dd32ca273b09e86abf8367572073bd1edfc52bc44446b"}, + {file = "rpds_py-0.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:69b857a7d8bd4f5d6e0db4086da8c46309a26e8cefdfc778c0c5cc17d4b11e08"}, + {file = "rpds_py-0.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:975382d9aa90dc59253d6a83a5ca72e07f4ada3ae3d6c0575ced513db322b8ec"}, + {file = "rpds_py-0.10.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:35fbd23c1c8732cde7a94abe7fb071ec173c2f58c0bd0d7e5b669fdfc80a2c7b"}, + {file = "rpds_py-0.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:106af1653007cc569d5fbb5f08c6648a49fe4de74c2df814e234e282ebc06957"}, + {file = "rpds_py-0.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce5e7504db95b76fc89055c7f41e367eaadef5b1d059e27e1d6eabf2b55ca314"}, + {file = "rpds_py-0.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aca759ada6b1967fcfd4336dcf460d02a8a23e6abe06e90ea7881e5c22c4de6"}, + {file = "rpds_py-0.10.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b5d4bdd697195f3876d134101c40c7d06d46c6ab25159ed5cbd44105c715278a"}, + {file = "rpds_py-0.10.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a657250807b6efd19b28f5922520ae002a54cb43c2401e6f3d0230c352564d25"}, + {file = "rpds_py-0.10.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:177c9dd834cdf4dc39c27436ade6fdf9fe81484758885f2d616d5d03c0a83bd2"}, + {file = "rpds_py-0.10.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e22491d25f97199fc3581ad8dd8ce198d8c8fdb8dae80dea3512e1ce6d5fa99f"}, + {file = "rpds_py-0.10.3-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:2f3e1867dd574014253b4b8f01ba443b9c914e61d45f3674e452a915d6e929a3"}, + {file = "rpds_py-0.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c22211c165166de6683de8136229721f3d5c8606cc2c3d1562da9a3a5058049c"}, + {file = "rpds_py-0.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40bc802a696887b14c002edd43c18082cb7b6f9ee8b838239b03b56574d97f71"}, + {file = "rpds_py-0.10.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e271dd97c7bb8eefda5cca38cd0b0373a1fea50f71e8071376b46968582af9b"}, + {file = "rpds_py-0.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:95cde244e7195b2c07ec9b73fa4c5026d4a27233451485caa1cd0c1b55f26dbd"}, + {file = "rpds_py-0.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08a80cf4884920863623a9ee9a285ee04cef57ebedc1cc87b3e3e0f24c8acfe5"}, + {file = "rpds_py-0.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:763ad59e105fca09705d9f9b29ecffb95ecdc3b0363be3bb56081b2c6de7977a"}, + {file = "rpds_py-0.10.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:187700668c018a7e76e89424b7c1042f317c8df9161f00c0c903c82b0a8cac5c"}, + {file = "rpds_py-0.10.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5267cfda873ad62591b9332fd9472d2409f7cf02a34a9c9cb367e2c0255994bf"}, + {file = "rpds_py-0.10.3-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:2ed83d53a8c5902ec48b90b2ac045e28e1698c0bea9441af9409fc844dc79496"}, + {file = "rpds_py-0.10.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:255f1a10ae39b52122cce26ce0781f7a616f502feecce9e616976f6a87992d6b"}, + {file = "rpds_py-0.10.3-cp38-none-win32.whl", hash = "sha256:a019a344312d0b1f429c00d49c3be62fa273d4a1094e1b224f403716b6d03be1"}, + {file = "rpds_py-0.10.3-cp38-none-win_amd64.whl", hash = "sha256:efb9ece97e696bb56e31166a9dd7919f8f0c6b31967b454718c6509f29ef6fee"}, + {file = "rpds_py-0.10.3-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:570cc326e78ff23dec7f41487aa9c3dffd02e5ee9ab43a8f6ccc3df8f9327623"}, + {file = "rpds_py-0.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cff7351c251c7546407827b6a37bcef6416304fc54d12d44dbfecbb717064717"}, + {file = "rpds_py-0.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:177914f81f66c86c012311f8c7f46887ec375cfcfd2a2f28233a3053ac93a569"}, + {file = "rpds_py-0.10.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:448a66b8266de0b581246ca7cd6a73b8d98d15100fb7165974535fa3b577340e"}, + {file = "rpds_py-0.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bbac1953c17252f9cc675bb19372444aadf0179b5df575ac4b56faaec9f6294"}, + {file = "rpds_py-0.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9dd9d9d9e898b9d30683bdd2b6c1849449158647d1049a125879cb397ee9cd12"}, + {file = "rpds_py-0.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8c71ea77536149e36c4c784f6d420ffd20bea041e3ba21ed021cb40ce58e2c9"}, + {file = "rpds_py-0.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16a472300bc6c83fe4c2072cc22b3972f90d718d56f241adabc7ae509f53f154"}, + {file = "rpds_py-0.10.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b9255e7165083de7c1d605e818025e8860636348f34a79d84ec533546064f07e"}, + {file = "rpds_py-0.10.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:53d7a3cd46cdc1689296348cb05ffd4f4280035770aee0c8ead3bbd4d6529acc"}, + {file = "rpds_py-0.10.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22da15b902f9f8e267020d1c8bcfc4831ca646fecb60254f7bc71763569f56b1"}, + {file = "rpds_py-0.10.3-cp39-none-win32.whl", hash = "sha256:850c272e0e0d1a5c5d73b1b7871b0a7c2446b304cec55ccdb3eaac0d792bb065"}, + {file = "rpds_py-0.10.3-cp39-none-win_amd64.whl", hash = "sha256:de61e424062173b4f70eec07e12469edde7e17fa180019a2a0d75c13a5c5dc57"}, + {file = "rpds_py-0.10.3-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:af247fd4f12cca4129c1b82090244ea5a9d5bb089e9a82feb5a2f7c6a9fe181d"}, + {file = "rpds_py-0.10.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ad59efe24a4d54c2742929001f2d02803aafc15d6d781c21379e3f7f66ec842"}, + {file = "rpds_py-0.10.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642ed0a209ced4be3a46f8cb094f2d76f1f479e2a1ceca6de6346a096cd3409d"}, + {file = "rpds_py-0.10.3-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:37d0c59548ae56fae01c14998918d04ee0d5d3277363c10208eef8c4e2b68ed6"}, + {file = "rpds_py-0.10.3-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aad6ed9e70ddfb34d849b761fb243be58c735be6a9265b9060d6ddb77751e3e8"}, + {file = "rpds_py-0.10.3-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8f94fdd756ba1f79f988855d948ae0bad9ddf44df296770d9a58c774cfbcca72"}, + {file = "rpds_py-0.10.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77076bdc8776a2b029e1e6ffbe6d7056e35f56f5e80d9dc0bad26ad4a024a762"}, + {file = "rpds_py-0.10.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:87d9b206b1bd7a0523375dc2020a6ce88bca5330682ae2fe25e86fd5d45cea9c"}, + {file = "rpds_py-0.10.3-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:8efaeb08ede95066da3a3e3c420fcc0a21693fcd0c4396d0585b019613d28515"}, + {file = "rpds_py-0.10.3-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:a4d9bfda3f84fc563868fe25ca160c8ff0e69bc4443c5647f960d59400ce6557"}, + {file = "rpds_py-0.10.3-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:d27aa6bbc1f33be920bb7adbb95581452cdf23005d5611b29a12bb6a3468cc95"}, + {file = "rpds_py-0.10.3-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ed8313809571a5463fd7db43aaca68ecb43ca7a58f5b23b6e6c6c5d02bdc7882"}, + {file = "rpds_py-0.10.3-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:e10e6a1ed2b8661201e79dff5531f8ad4cdd83548a0f81c95cf79b3184b20c33"}, + {file = "rpds_py-0.10.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:015de2ce2af1586ff5dc873e804434185199a15f7d96920ce67e50604592cae9"}, + {file = "rpds_py-0.10.3-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ae87137951bb3dc08c7d8bfb8988d8c119f3230731b08a71146e84aaa919a7a9"}, + {file = "rpds_py-0.10.3-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0bb4f48bd0dd18eebe826395e6a48b7331291078a879295bae4e5d053be50d4c"}, + {file = "rpds_py-0.10.3-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09362f86ec201288d5687d1dc476b07bf39c08478cde837cb710b302864e7ec9"}, + {file = "rpds_py-0.10.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:821392559d37759caa67d622d0d2994c7a3f2fb29274948ac799d496d92bca73"}, + {file = "rpds_py-0.10.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7170cbde4070dc3c77dec82abf86f3b210633d4f89550fa0ad2d4b549a05572a"}, + {file = "rpds_py-0.10.3-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:5de11c041486681ce854c814844f4ce3282b6ea1656faae19208ebe09d31c5b8"}, + {file = "rpds_py-0.10.3-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:4ed172d0c79f156c1b954e99c03bc2e3033c17efce8dd1a7c781bc4d5793dfac"}, + {file = "rpds_py-0.10.3-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:11fdd1192240dda8d6c5d18a06146e9045cb7e3ba7c06de6973000ff035df7c6"}, + {file = "rpds_py-0.10.3-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:f602881d80ee4228a2355c68da6b296a296cd22bbb91e5418d54577bbf17fa7c"}, + {file = "rpds_py-0.10.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:691d50c99a937709ac4c4cd570d959a006bd6a6d970a484c84cc99543d4a5bbb"}, + {file = "rpds_py-0.10.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24cd91a03543a0f8d09cb18d1cb27df80a84b5553d2bd94cba5979ef6af5c6e7"}, + {file = "rpds_py-0.10.3-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fc2200e79d75b5238c8d69f6a30f8284290c777039d331e7340b6c17cad24a5a"}, + {file = "rpds_py-0.10.3-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea65b59882d5fa8c74a23f8960db579e5e341534934f43f3b18ec1839b893e41"}, + {file = "rpds_py-0.10.3-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:829e91f3a8574888b73e7a3feb3b1af698e717513597e23136ff4eba0bc8387a"}, + {file = "rpds_py-0.10.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eab75a8569a095f2ad470b342f2751d9902f7944704f0571c8af46bede438475"}, + {file = "rpds_py-0.10.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:061c3ff1f51ecec256e916cf71cc01f9975af8fb3af9b94d3c0cc8702cfea637"}, + {file = "rpds_py-0.10.3-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:39d05e65f23a0fe897b6ac395f2a8d48c56ac0f583f5d663e0afec1da89b95da"}, + {file = "rpds_py-0.10.3-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:4eca20917a06d2fca7628ef3c8b94a8c358f6b43f1a621c9815243462dcccf97"}, + {file = "rpds_py-0.10.3-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e8d0f0eca087630d58b8c662085529781fd5dc80f0a54eda42d5c9029f812599"}, + {file = "rpds_py-0.10.3.tar.gz", hash = "sha256:fcc1ebb7561a3e24a6588f7c6ded15d80aec22c66a070c757559b57b17ffd1cb"}, +] + +[[package]] +name = "ruamel-yaml" +version = "0.17.32" +description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" +optional = false +python-versions = ">=3" +files = [ + {file = "ruamel.yaml-0.17.32-py3-none-any.whl", hash = "sha256:23cd2ed620231677564646b0c6a89d138b6822a0d78656df7abda5879ec4f447"}, + {file = "ruamel.yaml-0.17.32.tar.gz", hash = "sha256:ec939063761914e14542972a5cba6d33c23b0859ab6342f61cf070cfc600efc2"}, +] + +[package.dependencies] +"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.12\""} + +[package.extras] +docs = ["ryd"] +jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] + +[[package]] +name = "ruamel-yaml-clib" +version = "0.2.7" +description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" +optional = false +python-versions = ">=3.5" +files = [ + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d5859983f26d8cd7bb5c287ef452e8aacc86501487634573d260968f753e1d71"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:debc87a9516b237d0466a711b18b6ebeb17ba9f391eb7f91c649c5c4ec5006c7"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:df5828871e6648db72d1c19b4bd24819b80a755c4541d3409f0f7acd0f335c80"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:efa08d63ef03d079dcae1dfe334f6c8847ba8b645d08df286358b1f5293d24ab"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, + {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:370445fd795706fd291ab00c9df38a0caed0f17a6fb46b0f607668ecb16ce763"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win32.whl", hash = "sha256:ecdf1a604009bd35c674b9225a8fa609e0282d9b896c03dd441a91e5f53b534e"}, + {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win_amd64.whl", hash = "sha256:f34019dced51047d6f70cb9383b2ae2853b7fc4dce65129a5acd49f4f9256646"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aa261c29a5545adfef9296b7e33941f46aa5bbd21164228e833412af4c9c75f"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f01da5790e95815eb5a8a138508c01c758e5f5bc0ce4286c4f7028b8dd7ac3d0"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:40d030e2329ce5286d6b231b8726959ebbe0404c92f0a578c0e2482182e38282"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c3ca1fbba4ae962521e5eb66d72998b51f0f4d0f608d3c0347a48e1af262efa7"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win32.whl", hash = "sha256:7bdb4c06b063f6fd55e472e201317a3bb6cdeeee5d5a38512ea5c01e1acbdd93"}, + {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:be2a7ad8fd8f7442b24323d24ba0b56c51219513cfa45b9ada3b87b76c374d4b"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91a789b4aa0097b78c93e3dc4b40040ba55bef518f84a40d4442f713b4094acb"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:99e77daab5d13a48a4054803d052ff40780278240a902b880dd37a51ba01a307"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:3243f48ecd450eddadc2d11b5feb08aca941b5cd98c9b1db14b2fd128be8c697"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8831a2cedcd0f0927f788c5bdf6567d9dc9cc235646a434986a852af1cb54b4b"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win32.whl", hash = "sha256:3110a99e0f94a4a3470ff67fc20d3f96c25b13d24c6980ff841e82bafe827cac"}, + {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:92460ce908546ab69770b2e576e4f99fbb4ce6ab4b245345a3869a0a0410488f"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5bc0667c1eb8f83a3752b71b9c4ba55ef7c7058ae57022dd9b29065186a113d9"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:4a4d8d417868d68b979076a9be6a38c676eca060785abaa6709c7b31593c35d1"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf9a6bc4a0221538b1a7de3ed7bca4c93c02346853f44e1cd764be0023cd3640"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a7b301ff08055d73223058b5c46c55638917f04d21577c95e00e0c4d79201a6b"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win32.whl", hash = "sha256:d5e51e2901ec2366b79f16c2299a03e74ba4531ddcfacc1416639c557aef0ad8"}, + {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:184faeaec61dbaa3cace407cffc5819f7b977e75360e8d5ca19461cd851a5fc5"}, + {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, +] + +[[package]] +name = "semgrep" +version = "1.41.0" +description = "Lightweight static analysis for many languages. Find bug variants with patterns that look like source code." +optional = false +python-versions = ">=3.7" +files = [ + {file = "semgrep-1.41.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-any.whl", hash = "sha256:bb1679826cb14a9444e5cfb5dcb1cd9c20071baf9ae541eed200076721362ad6"}, + {file = "semgrep-1.41.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-macosx_10_14_x86_64.whl", hash = "sha256:fbcc2ea85e828023f2da51dcf93684d09b95b062716f585587d27485b0af5c37"}, + {file = "semgrep-1.41.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-macosx_11_0_arm64.whl", hash = "sha256:0ebb2f992618f145c49e5c8de56ed7aec57819b9736128c3690a95213fa0da79"}, + {file = "semgrep-1.41.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-musllinux_1_0_aarch64.manylinux2014_aarch64.whl", hash = "sha256:551dc331001674d742afd80aa3b7e8a0ee5ede28f3502ca915338d6548e161d6"}, + {file = "semgrep-1.41.0.tar.gz", hash = "sha256:d7231b5a65a77da14af9da66d95044ee41137b03da1380f6c646b1e2b60ef81d"}, +] + +[package.dependencies] +attrs = ">=21.3" +boltons = ">=21.0,<22.0" +click = ">=8.1,<9.0" +click-option-group = ">=0.5,<1.0" +colorama = ">=0.4.0,<0.5.0" +defusedxml = ">=0.7.1,<0.8.0" +glom = ">=22.1,<23.0" +jsonschema = ">=4.6,<5.0" +packaging = ">=21.0" +peewee = ">=3.14,<4.0" +python-lsp-jsonrpc = ">=1.0.0,<1.1.0" +requests = ">=2.22,<3.0" +rich = ">=12.6.0" +"ruamel.yaml" = ">=0.16.0,<0.18" +tomli = ">=2.0.1,<2.1.0" +typing-extensions = ">=4.2,<5.0" +urllib3 = ">=1.26,<2.0" +wcmatch = ">=8.3,<9.0" + +[package.extras] +experiments = ["jsonnet (>=0.18,<1.0)"] + [[package]] name = "setuptools" version = "68.2.2" @@ -1309,22 +1740,105 @@ files = [ {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, ] +[[package]] +name = "ujson" +version = "5.8.0" +description = "Ultra fast JSON encoder and decoder for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ujson-5.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f4511560d75b15ecb367eef561554959b9d49b6ec3b8d5634212f9fed74a6df1"}, + {file = "ujson-5.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9399eaa5d1931a0ead49dce3ffacbea63f3177978588b956036bfe53cdf6af75"}, + {file = "ujson-5.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4e7bb7eba0e1963f8b768f9c458ecb193e5bf6977090182e2b4f4408f35ac76"}, + {file = "ujson-5.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40931d7c08c4ce99adc4b409ddb1bbb01635a950e81239c2382cfe24251b127a"}, + {file = "ujson-5.8.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d53039d39de65360e924b511c7ca1a67b0975c34c015dd468fca492b11caa8f7"}, + {file = "ujson-5.8.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bdf04c6af3852161be9613e458a1fb67327910391de8ffedb8332e60800147a2"}, + {file = "ujson-5.8.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a70f776bda2e5072a086c02792c7863ba5833d565189e09fabbd04c8b4c3abba"}, + {file = "ujson-5.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f26629ac531d712f93192c233a74888bc8b8212558bd7d04c349125f10199fcf"}, + {file = "ujson-5.8.0-cp310-cp310-win32.whl", hash = "sha256:7ecc33b107ae88405aebdb8d82c13d6944be2331ebb04399134c03171509371a"}, + {file = "ujson-5.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:3b27a8da7a080add559a3b73ec9ebd52e82cc4419f7c6fb7266e62439a055ed0"}, + {file = "ujson-5.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:193349a998cd821483a25f5df30b44e8f495423840ee11b3b28df092ddfd0f7f"}, + {file = "ujson-5.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ddeabbc78b2aed531f167d1e70387b151900bc856d61e9325fcdfefb2a51ad8"}, + {file = "ujson-5.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ce24909a9c25062e60653073dd6d5e6ec9d6ad7ed6e0069450d5b673c854405"}, + {file = "ujson-5.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27a2a3c7620ebe43641e926a1062bc04e92dbe90d3501687957d71b4bdddaec4"}, + {file = "ujson-5.8.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b852bdf920fe9f84e2a2c210cc45f1b64f763b4f7d01468b33f7791698e455e"}, + {file = "ujson-5.8.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:20768961a6a706170497129960762ded9c89fb1c10db2989c56956b162e2a8a3"}, + {file = "ujson-5.8.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e0147d41e9fb5cd174207c4a2895c5e24813204499fd0839951d4c8784a23bf5"}, + {file = "ujson-5.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e3673053b036fd161ae7a5a33358ccae6793ee89fd499000204676baafd7b3aa"}, + {file = "ujson-5.8.0-cp311-cp311-win32.whl", hash = "sha256:a89cf3cd8bf33a37600431b7024a7ccf499db25f9f0b332947fbc79043aad879"}, + {file = "ujson-5.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:3659deec9ab9eb19e8646932bfe6fe22730757c4addbe9d7d5544e879dc1b721"}, + {file = "ujson-5.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:102bf31c56f59538cccdfec45649780ae00657e86247c07edac434cb14d5388c"}, + {file = "ujson-5.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:299a312c3e85edee1178cb6453645217ba23b4e3186412677fa48e9a7f986de6"}, + {file = "ujson-5.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2e385a7679b9088d7bc43a64811a7713cc7c33d032d020f757c54e7d41931ae"}, + {file = "ujson-5.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad24ec130855d4430a682c7a60ca0bc158f8253ec81feed4073801f6b6cb681b"}, + {file = "ujson-5.8.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16fde596d5e45bdf0d7de615346a102510ac8c405098e5595625015b0d4b5296"}, + {file = "ujson-5.8.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6d230d870d1ce03df915e694dcfa3f4e8714369cce2346686dbe0bc8e3f135e7"}, + {file = "ujson-5.8.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9571de0c53db5cbc265945e08f093f093af2c5a11e14772c72d8e37fceeedd08"}, + {file = "ujson-5.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7cba16b26efe774c096a5e822e4f27097b7c81ed6fb5264a2b3f5fd8784bab30"}, + {file = "ujson-5.8.0-cp312-cp312-win32.whl", hash = "sha256:48c7d373ff22366eecfa36a52b9b55b0ee5bd44c2b50e16084aa88b9de038916"}, + {file = "ujson-5.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:5ac97b1e182d81cf395ded620528c59f4177eee024b4b39a50cdd7b720fdeec6"}, + {file = "ujson-5.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2a64cc32bb4a436e5813b83f5aab0889927e5ea1788bf99b930fad853c5625cb"}, + {file = "ujson-5.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e54578fa8838ddc722539a752adfce9372474114f8c127bb316db5392d942f8b"}, + {file = "ujson-5.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9721cd112b5e4687cb4ade12a7b8af8b048d4991227ae8066d9c4b3a6642a582"}, + {file = "ujson-5.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d9707e5aacf63fb919f6237d6490c4e0244c7f8d3dc2a0f84d7dec5db7cb54c"}, + {file = "ujson-5.8.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0be81bae295f65a6896b0c9030b55a106fb2dec69ef877253a87bc7c9c5308f7"}, + {file = "ujson-5.8.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ae7f4725c344bf437e9b881019c558416fe84ad9c6b67426416c131ad577df67"}, + {file = "ujson-5.8.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9ab282d67ef3097105552bf151438b551cc4bedb3f24d80fada830f2e132aeb9"}, + {file = "ujson-5.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:94c7bd9880fa33fcf7f6d7f4cc032e2371adee3c5dba2922b918987141d1bf07"}, + {file = "ujson-5.8.0-cp38-cp38-win32.whl", hash = "sha256:bf5737dbcfe0fa0ac8fa599eceafae86b376492c8f1e4b84e3adf765f03fb564"}, + {file = "ujson-5.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:11da6bed916f9bfacf13f4fc6a9594abd62b2bb115acfb17a77b0f03bee4cfd5"}, + {file = "ujson-5.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:69b3104a2603bab510497ceabc186ba40fef38ec731c0ccaa662e01ff94a985c"}, + {file = "ujson-5.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9249fdefeb021e00b46025e77feed89cd91ffe9b3a49415239103fc1d5d9c29a"}, + {file = "ujson-5.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2873d196725a8193f56dde527b322c4bc79ed97cd60f1d087826ac3290cf9207"}, + {file = "ujson-5.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a4dafa9010c366589f55afb0fd67084acd8added1a51251008f9ff2c3e44042"}, + {file = "ujson-5.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a42baa647a50fa8bed53d4e242be61023bd37b93577f27f90ffe521ac9dc7a3"}, + {file = "ujson-5.8.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f3554eaadffe416c6f543af442066afa6549edbc34fe6a7719818c3e72ebfe95"}, + {file = "ujson-5.8.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fb87decf38cc82bcdea1d7511e73629e651bdec3a43ab40985167ab8449b769c"}, + {file = "ujson-5.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:407d60eb942c318482bbfb1e66be093308bb11617d41c613e33b4ce5be789adc"}, + {file = "ujson-5.8.0-cp39-cp39-win32.whl", hash = "sha256:0fe1b7edaf560ca6ab023f81cbeaf9946a240876a993b8c5a21a1c539171d903"}, + {file = "ujson-5.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:3f9b63530a5392eb687baff3989d0fb5f45194ae5b1ca8276282fb647f8dcdb3"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:efeddf950fb15a832376c0c01d8d7713479fbeceaed1eaecb2665aa62c305aec"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d8283ac5d03e65f488530c43d6610134309085b71db4f675e9cf5dff96a8282"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb0142f6f10f57598655340a3b2c70ed4646cbe674191da195eb0985a9813b83"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07d459aca895eb17eb463b00441986b021b9312c6c8cc1d06880925c7f51009c"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d524a8c15cfc863705991d70bbec998456a42c405c291d0f84a74ad7f35c5109"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d6f84a7a175c75beecde53a624881ff618e9433045a69fcfb5e154b73cdaa377"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b748797131ac7b29826d1524db1cc366d2722ab7afacc2ce1287cdafccddbf1f"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e72ba76313d48a1a3a42e7dc9d1db32ea93fac782ad8dde6f8b13e35c229130"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f504117a39cb98abba4153bf0b46b4954cc5d62f6351a14660201500ba31fe7f"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a8c91b6f4bf23f274af9002b128d133b735141e867109487d17e344d38b87d94"}, + {file = "ujson-5.8.0.tar.gz", hash = "sha256:78e318def4ade898a461b3d92a79f9441e7e0e4d2ad5419abed4336d702c7425"}, +] + [[package]] name = "urllib3" -version = "2.0.5" +version = "1.26.16" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.7" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ - {file = "urllib3-2.0.5-py3-none-any.whl", hash = "sha256:ef16afa8ba34a1f989db38e1dbbe0c302e4289a47856990d0682e374563ce35e"}, - {file = "urllib3-2.0.5.tar.gz", hash = "sha256:13abf37382ea2ce6fb744d4dad67838eec857c9f4f57009891805e0b5e123594"}, + {file = "urllib3-1.26.16-py2.py3-none-any.whl", hash = "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f"}, + {file = "urllib3-1.26.16.tar.gz", hash = "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] + +[[package]] +name = "wcmatch" +version = "8.5" +description = "Wildcard/glob file name matcher." +optional = false +python-versions = ">=3.8" +files = [ + {file = "wcmatch-8.5-py3-none-any.whl", hash = "sha256:14554e409b142edeefab901dc68ad570b30a72a8ab9a79106c5d5e9a6d241bd5"}, + {file = "wcmatch-8.5.tar.gz", hash = "sha256:86c17572d0f75cbf3bcb1a18f3bf2f9e72b39a9c08c9b4a74e991e1882a8efb3"}, +] + +[package.dependencies] +bracex = ">=2.1.1" [[package]] name = "wcwidth" @@ -1337,6 +1851,22 @@ files = [ {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, ] +[[package]] +name = "websocket-client" +version = "1.6.3" +description = "WebSocket client for Python with low level API options" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websocket-client-1.6.3.tar.gz", hash = "sha256:3aad25d31284266bcfcfd1fd8a743f63282305a364b8d0948a43bd606acc652f"}, + {file = "websocket_client-1.6.3-py3-none-any.whl", hash = "sha256:6cfc30d051ebabb73a5fa246efdcc14c8fbebbd0330f8984ac3bb6d9edd2ad03"}, +] + +[package.extras] +docs = ["Sphinx (>=6.0)", "sphinx-rtd-theme (>=1.1.0)"] +optional = ["python-socks", "wsaccel"] +test = ["websockets"] + [[package]] name = "wget" version = "3.2" @@ -1452,4 +1982,8 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "f02c8f01a4cb4b735db54d90c470d933b2ce99b1932107ae5284f47443aafef6" +<<<<<<< HEAD +content-hash = "913fce8b41a4ce58b5905473d876de02a8ff78968a15900b6519fd860d9ba6e8" +======= +content-hash = "87377d33bbe74e1ebc114878798d463d645015784475b584fd1504931400e0de" +>>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) diff --git a/pyproject.toml b/pyproject.toml index 4b56cd5f3b..c63be6109a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "open-interpreter" packages = [ {include = "interpreter"}, ] -version = "0.1.5" +version = "0.1.7" description = "Let language models run code locally." authors = ["Killian Lucas "] readme = "README.md" @@ -27,6 +27,11 @@ wget = "^3.2" huggingface-hub = "^0.16.4" litellm = "^0.1.590" pyyaml = "^6.0.1" +<<<<<<< HEAD +docker = "^6.1.3" +======= +semgrep = "^1.41.0" +>>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) [tool.poetry.dependencies.pyreadline3] version = "^3.4.1" markers = "sys_platform == 'win32'" From 54b2451a787e4fd8774daf1c9b76801bf12245d0 Mon Sep 17 00:00:00 2001 From: Nathan Hoos <128712250+unaidedelf8777@users.noreply.github.com> Date: Tue, 3 Oct 2023 22:44:15 +0000 Subject: [PATCH 02/12] fixed my oopsies. --- del.py | 20 -- interpreter/code_interpreters/__init__.py | 3 + .../container_utils/container_utils.py | 30 +- .../create_code_interpreter.py | 28 +- .../code_interpreters/dockerfiles/Dockerfile | 41 ++- .../code_interpreters/dockerfiles/hash.json | 4 +- .../dockerfiles/requirements.txt | 16 +- .../languages/applescript.py | 11 +- .../code_interpreters/languages/html.py | 5 +- .../code_interpreters/languages/javascript.py | 11 +- .../code_interpreters/languages/python.py | 13 +- interpreter/code_interpreters/languages/r.py | 11 +- .../code_interpreters/languages/shell.py | 11 +- .../subprocess_code_interpreter.py | 6 +- poetry.lock | 297 +++++++++--------- pyproject.toml | 3 - 16 files changed, 234 insertions(+), 276 deletions(-) delete mode 100644 del.py diff --git a/del.py b/del.py deleted file mode 100644 index 47d789165b..0000000000 --- a/del.py +++ /dev/null @@ -1,20 +0,0 @@ -from textual.app import App -from textual_terminal import Terminal - -class TerminalApp(App): - - async def on_mount(self) -> None: - # Create a layout with two terminals - await self.layout.dock(Terminal(command="htop", id="terminal_htop"), edge="top", size=10) - await self.layout.dock(Terminal(command="bash", id="terminal_bash"), edge="bottom") - - async def on_ready(self) -> None: - # Start the commands in each terminal - terminal_htop: Terminal = await self.get_widget("terminal_htop") - await terminal_htop.start() - - terminal_bash: Terminal = await self.get_widget("terminal_bash") - await terminal_bash.start() - -app = TerminalApp() -app.run() diff --git a/interpreter/code_interpreters/__init__.py b/interpreter/code_interpreters/__init__.py index e69de29bb2..4c37be853a 100644 --- a/interpreter/code_interpreters/__init__.py +++ b/interpreter/code_interpreters/__init__.py @@ -0,0 +1,3 @@ +from .dockerfiles.docker_manager import DockerManager as ContainerConfig + +__all__ = ["ContainerConfig"] diff --git a/interpreter/code_interpreters/container_utils/container_utils.py b/interpreter/code_interpreters/container_utils/container_utils.py index 4277199f74..d1b0b4af11 100644 --- a/interpreter/code_interpreters/container_utils/container_utils.py +++ b/interpreter/code_interpreters/container_utils/container_utils.py @@ -16,6 +16,8 @@ import docker from docker import DockerClient from docker.errors import DockerException +from docker.utils import kwargs_from_env +from docker.tls import TLSConfig from rich import print as Print @@ -45,9 +47,9 @@ def build_docker_images( try: client = DockerClient.from_env() except DockerException: - Print("ERROR: Could not connect to Docker daemon. Is Docker Engine installed and running?") + Print("[bold red]ERROR[/bold red]: Could not connect to Docker daemon. Is Docker Engine installed and running?") Print( - "\nFor information on Docker installation, visit: https://docs.docker.com/engine/install/" + "\nFor information on Docker installation, visit: https://docs.docker.com/engine/install/ and follow the instructions for your system." ) return @@ -79,7 +81,9 @@ def build_docker_images( images = client.images.list(name=image_name, all=True) if not images: Print("Downloading default image from Docker Hub, please wait...") - client.images.pull("unaidedelf/openinterpreter-runtime-container", tag="latest") + subprocess.run(["docker", "pull", "unaidedelf/openinterpreter-runtime-container:latest"]) + subprocess.run(["docker", "tag", "unaidedelf/openinterpreter-runtime-container:latest", image_name ], + check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) elif current_hash != previous_hash: Print("Dockerfile or requirements.txt has changed. Building container...") @@ -99,7 +103,7 @@ def build_docker_images( ) # Update the stored current hash - stored_hashes["current_hash"] = current_hash + stored_hashes["last_hash"] = current_hash with open(hash_file_path, "w") as f: json.dump(stored_hashes, f) @@ -208,7 +212,7 @@ def demux_docker_stream(self, data): def flush(self): pass - def close(self): + def terminate(self): self._stop_event.set() self._thread.join() os.close(self._stdout_r) @@ -220,7 +224,10 @@ def close(self): class DockerProcWrapper: def __init__(self, command, session_path): - self.client = docker.APIClient() + client_kwargs = kwargs_from_env() + if client_kwargs.get('tls'): + client_kwargs['tls'] = TLSConfig(**client_kwargs['tls']) + self.client = docker.APIClient(**client_kwargs) self.image_name = "openinterpreter-runtime-container:latest" self.session_path = session_path self.exec_id = None @@ -263,7 +270,6 @@ def init_container(self): self.container = self.client.create_container( image=self.image_name, detach=True, - command="/bin/bash -i", labels={'session_id': os.path.basename(self.session_path)}, host_config=host_config, user="docker", @@ -280,6 +286,11 @@ def init_container(self): def init_exec_instance(self, command): if self.container: + container_info = self.client.inspect_container(self.container.get('Id')) + + if container_info.get("State").get('Running') is False: # Not sure of the cause of this, but this works for now. + self.client.start(self.container.get("Id")) + self.exec_id = self.client.exec_create( self.container.get("Id"), cmd="/bin/bash", @@ -291,8 +302,11 @@ def init_exec_instance(self, command): tty=False )['Id'] + # when socket=True, this returns a socketIO socket, so we just kinda hijack the underlying socket + # since docker sets up the socketio wierd and tries to make it hard to mess with and write to. + # We make the socket "Cooperative" self.exec_socket = self.client.exec_start( - self.exec_id, socket=True, tty=False, demux=False)._sock + self.exec_id, socket=True, tty=False, demux=False)._sock def wait_for_container_start(self, container_id, timeout=30): diff --git a/interpreter/code_interpreters/create_code_interpreter.py b/interpreter/code_interpreters/create_code_interpreter.py index 5d32123ac5..69eb9d9034 100644 --- a/interpreter/code_interpreters/create_code_interpreter.py +++ b/interpreter/code_interpreters/create_code_interpreter.py @@ -1,29 +1,12 @@ -<<<<<<< HEAD import inspect import os import uuid import weakref import appdirs -from .languages.applescript import AppleScript -from .languages.html import HTML -from .languages.javascript import JavaScript -from .languages.python import Python -from .languages.r import R -from .languages.shell import Shell -======= from .language_map import language_map ->>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) - -LANGUAGE_MAP = { - "python": Python, - "bash": Shell, - "shell": Shell, - "javascript": JavaScript, - "html": HTML, - "applescript": AppleScript, - "r": R, -} + + # Global dictionary to store the session IDs by the weak reference of the calling objects SESSION_IDS_BY_OBJECT = weakref.WeakKeyDictionary() @@ -57,7 +40,6 @@ def create_code_interpreter(language, use_containers=False): # Case in-sensitive language = language.lower() -<<<<<<< HEAD caller_object = None if use_containers: @@ -90,16 +72,14 @@ def create_code_interpreter(language, use_containers=False): session_id = f"ses-{str(uuid.uuid4())}" SESSION_IDS_BY_OBJECT[caller_object] = session_id -======= ->>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) try: # Retrieve the specific CodeInterpreter class based on the language - CodeInterpreter = LANGUAGE_MAP[language] + CodeInterpreter = language_map[language] # Retrieve the session ID for the current calling object, if available session_id = SESSION_IDS_BY_OBJECT.get(caller_object, None) if caller_object else None - if not use_containers: + if not use_containers or session_id is None: return CodeInterpreter() session_path = os.path.join( diff --git a/interpreter/code_interpreters/dockerfiles/Dockerfile b/interpreter/code_interpreters/dockerfiles/Dockerfile index 2517002a8d..761207e7c0 100644 --- a/interpreter/code_interpreters/dockerfiles/Dockerfile +++ b/interpreter/code_interpreters/dockerfiles/Dockerfile @@ -4,8 +4,20 @@ FROM debian:bullseye # Set environment variables to disable prompts ENV DEBIAN_FRONTEND=noninteractive +# Create user with sudo only in the container for security. +RUN useradd docker && echo "docker:docker" | chpasswd && mkdir -p /home/docker && chown docker:docker /home/docker +RUN mkdir -p /mnt/data && chown -R docker:docker /mnt/data + +RUN apt-get update && apt-get install -y sudo + +RUN usermod -aG sudo docker + +RUN echo "docker ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers +# add write perms for user 'docker' in the correct dirs ( where it cant mess things up much. it does have passwordless sudo, so it can override this if it figures out it has sudo.) +RUN chown -R docker:docker /mnt/data + # Update package list and install essential utilities and runtimes -RUN apt-get update && apt-get install -y \ +RUN sudo apt-get update && apt-get install -y \ jq \ build-essential \ python3 \ @@ -17,9 +29,16 @@ RUN apt-get update && apt-get install -y \ r-base \ r-base-dev -# Install NodeJS -RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - && \ - apt-get install -y nodejs +# install nodejs stuff +RUN sudo apt-get update +RUN sudo apt-get install -y ca-certificates curl gnupg +RUN sudo mkdir -p /etc/apt/keyrings +RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +RUN NODE_MAJOR=20 +RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list +RUN sudo apt-get update +RUN sudo apt-get install nodejs -y + # Copy unified requirements.txt into the image COPY ./requirements.txt /tmp/ @@ -55,17 +74,5 @@ RUN awk '/\[r\]/,/^\s*$/' /tmp/requirements.txt | grep -v '^\[r\]' > /tmp/r_requ # Remove temporary files RUN rm /tmp/package.json /tmp/node_requirements.txt /tmp/python_requirements.txt /tmp/r_requirements.txt -# Create user with sudo only in the container for security. -RUN useradd docker && echo "docker:docker" | chpasswd -RUN mkdir -p /mnt/data && chown -R docker:docker /mnt/data - -RUN apt-get update && apt-get install -y sudo - -RUN usermod -aG sudo docker - -RUN echo "docker ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers - -USER docker - -# Set work directory +# workdir set. pray it dosent try to go exploring. WORKDIR /mnt/data diff --git a/interpreter/code_interpreters/dockerfiles/hash.json b/interpreter/code_interpreters/dockerfiles/hash.json index 18026c04cc..633d7ba48f 100644 --- a/interpreter/code_interpreters/dockerfiles/hash.json +++ b/interpreter/code_interpreters/dockerfiles/hash.json @@ -1,4 +1,4 @@ { - "original_hash": "bf472f80a3acd23a1d9b689da1f3c5834a1a728bf51265e034f0b1bbe44a8435", - "last_hash": "bf472f80a3acd23a1d9b689da1f3c5834a1a728bf51265e034f0b1bbe44a8435" + "original_hash": "fa63fa21b690fe37b4e3580221440008bbb9a31a3d58a5d77dbf76c776dd7c80", + "last_hash": "fa63fa21b690fe37b4e3580221440008bbb9a31a3d58a5d77dbf76c776dd7c80" } \ No newline at end of file diff --git a/interpreter/code_interpreters/dockerfiles/requirements.txt b/interpreter/code_interpreters/dockerfiles/requirements.txt index cec9d6f9fc..0da60e08a9 100644 --- a/interpreter/code_interpreters/dockerfiles/requirements.txt +++ b/interpreter/code_interpreters/dockerfiles/requirements.txt @@ -1,25 +1,11 @@ [python] -transformers -datasets numpy==1.21.2 pandas==1.3.3 matplotlib==3.4.3 -seaborn==0.11.2 -scipy==1.7.1 -scikit-learn==0.24.2 -statsmodels==0.12.2 beautifulsoup4==4.10.0 -nltk==3.6.2 -spacy==3.1.3 -plotly==5.3.1 -bokeh==2.4.0 -dash==2.0.0 -scrapy==2.5.0 -geopandas==0.9.0 -torch==2.0 [r] -cowplot + [node] chalk==2.0 \ No newline at end of file diff --git a/interpreter/code_interpreters/languages/applescript.py b/interpreter/code_interpreters/languages/applescript.py index 4d786493f6..78168e4577 100644 --- a/interpreter/code_interpreters/languages/applescript.py +++ b/interpreter/code_interpreters/languages/applescript.py @@ -2,16 +2,13 @@ from ..subprocess_code_interpreter import SubprocessCodeInterpreter class AppleScript(SubprocessCodeInterpreter): -<<<<<<< HEAD - def __init__(self, **kwargs): - super().__init__(**kwargs) -======= + file_extension = "applescript" proper_name = "AppleScript" - def __init__(self): - super().__init__() ->>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) + def __init__(self, **kwargs): + super().__init__(**kwargs) + self.start_cmd = os.environ.get('SHELL', '/bin/zsh') def preprocess_code(self, code): diff --git a/interpreter/code_interpreters/languages/html.py b/interpreter/code_interpreters/languages/html.py index 965b38717b..3be7cbcf40 100644 --- a/interpreter/code_interpreters/languages/html.py +++ b/interpreter/code_interpreters/languages/html.py @@ -7,8 +7,9 @@ class HTML(BaseCodeInterpreter): file_extension = "html" proper_name = "HTML" - def __init__(self): - super().__init__() + def __init__(self, **kwargs): + super().__init__(**kwargs) # include kwargs though they dont do anything in this case. + # This is just so we dont need more logic in the create interpreter function def run(self, code): # Create a temporary HTML file with the content diff --git a/interpreter/code_interpreters/languages/javascript.py b/interpreter/code_interpreters/languages/javascript.py index 37bf5aab96..4a078e7df7 100644 --- a/interpreter/code_interpreters/languages/javascript.py +++ b/interpreter/code_interpreters/languages/javascript.py @@ -2,16 +2,13 @@ import re class JavaScript(SubprocessCodeInterpreter): -<<<<<<< HEAD - def __init__(self, **kwargs): - super().__init__(**kwargs) -======= + file_extension = "js" proper_name = "JavaScript" + + def __init__(self, **kwargs): + super().__init__(**kwargs) - def __init__(self): - super().__init__() ->>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) self.start_cmd = "node -i" def preprocess_code(self, code): diff --git a/interpreter/code_interpreters/languages/python.py b/interpreter/code_interpreters/languages/python.py index 7cba356386..f18cf1c509 100644 --- a/interpreter/code_interpreters/languages/python.py +++ b/interpreter/code_interpreters/languages/python.py @@ -4,21 +4,16 @@ import re class Python(SubprocessCodeInterpreter): -<<<<<<< HEAD + + file_extension = "py" + proper_name = "Python" + def __init__(self, **kwargs): super().__init__(**kwargs) if 'use_docker' in kwargs and kwargs['use_docker']: self.start_cmd = "python3 -i -q -u" else: self.start_cmd = sys.executable + " -i -q -u" -======= - file_extension = "py" - proper_name = "Python" - - def __init__(self): - super().__init__() - self.start_cmd = sys.executable + " -i -q -u" ->>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) def preprocess_code(self, code): return preprocess_python(code) diff --git a/interpreter/code_interpreters/languages/r.py b/interpreter/code_interpreters/languages/r.py index 6e23a13e50..13e54d6848 100644 --- a/interpreter/code_interpreters/languages/r.py +++ b/interpreter/code_interpreters/languages/r.py @@ -2,16 +2,13 @@ import re class R(SubprocessCodeInterpreter): -<<<<<<< HEAD - def __init__(self, **kwargs): - super().__init__(**kwargs) -======= + + file_extension = "r" proper_name = "R" - def __init__(self): - super().__init__() ->>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) + def __init__(self, **kwargs): + super().__init__(**kwargs) self.start_cmd = "R -q --vanilla" # Start R in quiet and vanilla mode def preprocess_code(self, code): diff --git a/interpreter/code_interpreters/languages/shell.py b/interpreter/code_interpreters/languages/shell.py index da49b77c0a..a202b08768 100644 --- a/interpreter/code_interpreters/languages/shell.py +++ b/interpreter/code_interpreters/languages/shell.py @@ -4,17 +4,12 @@ import os class Shell(SubprocessCodeInterpreter): -<<<<<<< HEAD - def __init__(self, **kwargs): - super().__init__(**kwargs) -======= + file_extension = "sh" proper_name = "Shell" - def __init__(self): - super().__init__() ->>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) - + def __init__(self, **kwargs): + super().__init__(**kwargs) # Determine the start command based on the platform if platform.system() == 'Windows': self.start_cmd = 'cmd.exe' diff --git a/interpreter/code_interpreters/subprocess_code_interpreter.py b/interpreter/code_interpreters/subprocess_code_interpreter.py index 2895b9efe7..54e02886b7 100644 --- a/interpreter/code_interpreters/subprocess_code_interpreter.py +++ b/interpreter/code_interpreters/subprocess_code_interpreter.py @@ -30,8 +30,8 @@ def __init__(self, **kwargs): self.debug_mode = False self.output_queue = queue.Queue() self.done = threading.Event() - self.contain = kwargs.get("use_docker", False) - if self.contain: + self.use_containers = kwargs.get("use_docker", False) + if self.use_containers: self.session_id = kwargs.get("session_id") @staticmethod @@ -71,7 +71,7 @@ def start_process(self): None """ - if self.contain: + if self.use_containers: self.process = DockerProcWrapper( self.start_cmd, # splitting cmd causes problems with docker session_path=os.path.join( diff --git a/poetry.lock b/poetry.lock index f9c0ce72e9..1167b00773 100644 --- a/poetry.lock +++ b/poetry.lock @@ -235,86 +235,101 @@ files = [ [[package]] name = "charset-normalizer" -version = "3.2.0" +version = "3.3.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7.0" files = [ - {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, - {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, + {file = "charset-normalizer-3.3.0.tar.gz", hash = "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-win32.whl", hash = "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d"}, + {file = "charset_normalizer-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-win32.whl", hash = "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786"}, + {file = "charset_normalizer-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-win32.whl", hash = "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df"}, + {file = "charset_normalizer-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dc45229747b67ffc441b3de2f3ae5e62877a282ea828a5bdb67883c4ee4a8810"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f4a0033ce9a76e391542c182f0d48d084855b5fcba5010f707c8e8c34663d77"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ada214c6fa40f8d800e575de6b91a40d0548139e5dc457d2ebb61470abf50186"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b1121de0e9d6e6ca08289583d7491e7fcb18a439305b34a30b20d8215922d43c"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1063da2c85b95f2d1a430f1c33b55c9c17ffaf5e612e10aeaad641c55a9e2b9d"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70f1d09c0d7748b73290b29219e854b3207aea922f839437870d8cc2168e31cc"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:250c9eb0f4600361dd80d46112213dff2286231d92d3e52af1e5a6083d10cad9"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:750b446b2ffce1739e8578576092179160f6d26bd5e23eb1789c4d64d5af7dc7"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:fc52b79d83a3fe3a360902d3f5d79073a993597d48114c29485e9431092905d8"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:588245972aca710b5b68802c8cad9edaa98589b1b42ad2b53accd6910dad3545"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e39c7eb31e3f5b1f88caff88bcff1b7f8334975b46f6ac6e9fc725d829bc35d4"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-win32.whl", hash = "sha256:abecce40dfebbfa6abf8e324e1860092eeca6f7375c8c4e655a8afb61af58f2c"}, + {file = "charset_normalizer-3.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:24a91a981f185721542a0b7c92e9054b7ab4fea0508a795846bc5b0abf8118d4"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:67b8cc9574bb518ec76dc8e705d4c39ae78bb96237cb533edac149352c1f39fe"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac71b2977fb90c35d41c9453116e283fac47bb9096ad917b8819ca8b943abecd"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3ae38d325b512f63f8da31f826e6cb6c367336f95e418137286ba362925c877e"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:542da1178c1c6af8873e143910e2269add130a299c9106eef2594e15dae5e482"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:30a85aed0b864ac88309b7d94be09f6046c834ef60762a8833b660139cfbad13"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aae32c93e0f64469f74ccc730a7cb21c7610af3a775157e50bbd38f816536b38"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15b26ddf78d57f1d143bdf32e820fd8935d36abe8a25eb9ec0b5a71c82eb3895"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f5d10bae5d78e4551b7be7a9b29643a95aded9d0f602aa2ba584f0388e7a557"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:249c6470a2b60935bafd1d1d13cd613f8cd8388d53461c67397ee6a0f5dce741"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c5a74c359b2d47d26cdbbc7845e9662d6b08a1e915eb015d044729e92e7050b7"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:b5bcf60a228acae568e9911f410f9d9e0d43197d030ae5799e20dca8df588287"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:187d18082694a29005ba2944c882344b6748d5be69e3a89bf3cc9d878e548d5a"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:81bf654678e575403736b85ba3a7867e31c2c30a69bc57fe88e3ace52fb17b89"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-win32.whl", hash = "sha256:85a32721ddde63c9df9ebb0d2045b9691d9750cb139c161c80e500d210f5e26e"}, + {file = "charset_normalizer-3.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:468d2a840567b13a590e67dd276c570f8de00ed767ecc611994c301d0f8c014f"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-win32.whl", hash = "sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a"}, + {file = "charset_normalizer-3.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884"}, + {file = "charset_normalizer-3.3.0-py3-none-any.whl", hash = "sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2"}, ] [[package]] @@ -362,7 +377,17 @@ files = [ ] [[package]] -<<<<<<< HEAD +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + +[[package]] name = "docker" version = "6.1.3" description = "A Python library for the Docker Engine API." @@ -383,18 +408,6 @@ websocket-client = ">=0.32.0" [package.extras] ssh = ["paramiko (>=2.4.3)"] -======= -name = "defusedxml" -version = "0.7.1" -description = "XML bomb protection for Python stdlib modules" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, - {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, -] - ->>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) [[package]] name = "exceptiongroup" version = "1.1.3" @@ -748,21 +761,23 @@ referencing = ">=0.28.0" [[package]] name = "litellm" -version = "0.1.736" +version = "0.1.807" description = "Library to easily interface with LLM API providers" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "litellm-0.1.736-py3-none-any.whl", hash = "sha256:2918b3b0e807b39b6575e36c02624352fafd5ba2f01c923782f8f3b863793bb4"}, - {file = "litellm-0.1.736.tar.gz", hash = "sha256:3d4dc22bee2cb11243d8111f61493acc0f32b4bfe46eb478b2b940c85e1b546b"}, + {file = "litellm-0.1.807-py3-none-any.whl", hash = "sha256:1f2a61c7c1eb43c1959314f94b13f29cfe75d57bf8e8ff80873182ae0ff34082"}, + {file = "litellm-0.1.807.tar.gz", hash = "sha256:554f6bac0ccc136b0bcb1d7512ab6bbcd0dfb3a8fadec7818d0ac156455ac4ef"}, ] [package.dependencies] -importlib-metadata = ">=6.8.0,<7.0.0" +appdirs = ">=1.4.4,<2.0.0" +click = "*" +importlib-metadata = ">=6.8.0" openai = ">=0.27.0,<0.29.0" python-dotenv = ">=0.2.0" -tiktoken = ">=0.4.0,<0.5.0" -tokenizers = ">=0.14.0,<0.15.0" +tiktoken = ">=0.4.0" +tokenizers = "*" [[package]] name = "markdown-it-py" @@ -884,13 +899,13 @@ files = [ [[package]] name = "openai" -version = "0.28.0" +version = "0.28.1" description = "Python client library for the OpenAI API" optional = false python-versions = ">=3.7.1" files = [ - {file = "openai-0.28.0-py3-none-any.whl", hash = "sha256:d207ece78469be5648eb87b825753282225155a29d0eec6e02013ddbf8c31c0c"}, - {file = "openai-0.28.0.tar.gz", hash = "sha256:417b78c4c2864ba696aedaf1ccff77be1f04a581ab1739f0a56e0aae19e5a794"}, + {file = "openai-0.28.1-py3-none-any.whl", hash = "sha256:d18690f9e3d31eedb66b57b88c2165d760b24ea0a01f150dd3f068155088ce68"}, + {file = "openai-0.28.1.tar.gz", hash = "sha256:4be1dad329a65b4ce1a660fe6d5431b438f429b5855c883435f0f7fcb6d2dcc8"}, ] [package.dependencies] @@ -906,13 +921,13 @@ wandb = ["numpy", "openpyxl (>=3.0.7)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1 [[package]] name = "packaging" -version = "23.1" +version = "23.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] [[package]] @@ -1014,7 +1029,23 @@ files = [ ] [[package]] -<<<<<<< HEAD +name = "python-lsp-jsonrpc" +version = "1.0.0" +description = "JSON RPC 2.0 server library" +optional = false +python-versions = "*" +files = [ + {file = "python-lsp-jsonrpc-1.0.0.tar.gz", hash = "sha256:7bec170733db628d3506ea3a5288ff76aa33c70215ed223abdb0d95e957660bd"}, + {file = "python_lsp_jsonrpc-1.0.0-py3-none-any.whl", hash = "sha256:079b143be64b0a378bdb21dff5e28a8c1393fe7e8a654ef068322d754e545fc7"}, +] + +[package.dependencies] +ujson = ">=3.0.0" + +[package.extras] +test = ["coverage", "pycodestyle", "pyflakes", "pylint", "pytest", "pytest-cov"] + +[[package]] name = "pywin32" version = "306" description = "Python for Window Extensions" @@ -1037,24 +1068,6 @@ files = [ {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, ] -======= -name = "python-lsp-jsonrpc" -version = "1.0.0" -description = "JSON RPC 2.0 server library" -optional = false -python-versions = "*" -files = [ - {file = "python-lsp-jsonrpc-1.0.0.tar.gz", hash = "sha256:7bec170733db628d3506ea3a5288ff76aa33c70215ed223abdb0d95e957660bd"}, - {file = "python_lsp_jsonrpc-1.0.0-py3-none-any.whl", hash = "sha256:079b143be64b0a378bdb21dff5e28a8c1393fe7e8a654ef068322d754e545fc7"}, -] - -[package.dependencies] -ujson = ">=3.0.0" - -[package.extras] -test = ["coverage", "pycodestyle", "pyflakes", "pylint", "pytest", "pytest-cov"] - ->>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) [[package]] name = "pyyaml" version = "6.0.1" @@ -1263,13 +1276,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.5.3" +version = "13.6.0" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.7.0" files = [ - {file = "rich-13.5.3-py3-none-any.whl", hash = "sha256:9257b468badc3d347e146a4faa268ff229039d4c2d176ab0cffb4c4fbc73d5d9"}, - {file = "rich-13.5.3.tar.gz", hash = "sha256:87b43e0543149efa1253f485cd845bb7ee54df16c9617b8a893650ab84b4acb6"}, + {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"}, + {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"}, ] [package.dependencies] @@ -1387,13 +1400,13 @@ files = [ [[package]] name = "ruamel-yaml" -version = "0.17.32" +version = "0.17.33" description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" optional = false python-versions = ">=3" files = [ - {file = "ruamel.yaml-0.17.32-py3-none-any.whl", hash = "sha256:23cd2ed620231677564646b0c6a89d138b6822a0d78656df7abda5879ec4f447"}, - {file = "ruamel.yaml-0.17.32.tar.gz", hash = "sha256:ec939063761914e14542972a5cba6d33c23b0859ab6342f61cf070cfc600efc2"}, + {file = "ruamel.yaml-0.17.33-py3-none-any.whl", hash = "sha256:2080c7a02b8a30fb3c06727cdf3e254a64055eedf3aa2d17c2b669639c04971b"}, + {file = "ruamel.yaml-0.17.33.tar.gz", hash = "sha256:5c56aa0bff2afceaa93bffbfc78b450b7dc1e01d5edb80b3a570695286ae62b1"}, ] [package.dependencies] @@ -1451,16 +1464,16 @@ files = [ [[package]] name = "semgrep" -version = "1.41.0" +version = "1.42.0" description = "Lightweight static analysis for many languages. Find bug variants with patterns that look like source code." optional = false python-versions = ">=3.7" files = [ - {file = "semgrep-1.41.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-any.whl", hash = "sha256:bb1679826cb14a9444e5cfb5dcb1cd9c20071baf9ae541eed200076721362ad6"}, - {file = "semgrep-1.41.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-macosx_10_14_x86_64.whl", hash = "sha256:fbcc2ea85e828023f2da51dcf93684d09b95b062716f585587d27485b0af5c37"}, - {file = "semgrep-1.41.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-macosx_11_0_arm64.whl", hash = "sha256:0ebb2f992618f145c49e5c8de56ed7aec57819b9736128c3690a95213fa0da79"}, - {file = "semgrep-1.41.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-musllinux_1_0_aarch64.manylinux2014_aarch64.whl", hash = "sha256:551dc331001674d742afd80aa3b7e8a0ee5ede28f3502ca915338d6548e161d6"}, - {file = "semgrep-1.41.0.tar.gz", hash = "sha256:d7231b5a65a77da14af9da66d95044ee41137b03da1380f6c646b1e2b60ef81d"}, + {file = "semgrep-1.42.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-any.whl", hash = "sha256:b84bfec84ebe4a1e1e9ea6e1be5f9b8c03ce4e38740980a28fa5961ffed6a812"}, + {file = "semgrep-1.42.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-macosx_10_14_x86_64.whl", hash = "sha256:7f1763ffadd3ddadae78c138ed20dcdc0dbe5dbf3aaa0205b2ca52609d27879f"}, + {file = "semgrep-1.42.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-macosx_11_0_arm64.whl", hash = "sha256:b181fbfe8122e642fe290b25e1f0a311d0202e355c89bab989d738a5282fb812"}, + {file = "semgrep-1.42.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-musllinux_1_0_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1a869e65bc1d29f50d3336d0e29550325ed15042cfcf6ff5fe003e75fe4202c"}, + {file = "semgrep-1.42.0.tar.gz", hash = "sha256:308978610f4f0ae15268f127678762ef4d8b6092f814fda54b83c53454446d34"}, ] [package.dependencies] @@ -1812,17 +1825,17 @@ files = [ [[package]] name = "urllib3" -version = "1.26.16" +version = "1.26.17" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ - {file = "urllib3-1.26.16-py2.py3-none-any.whl", hash = "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f"}, - {file = "urllib3-1.26.16.tar.gz", hash = "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"}, + {file = "urllib3-1.26.17-py2.py3-none-any.whl", hash = "sha256:94a757d178c9be92ef5539b8840d48dc9cf1b2709c9d6b588232a055c524458b"}, + {file = "urllib3-1.26.17.tar.gz", hash = "sha256:24d6a242c28d29af46c3fae832c36db3bbebcc533dd1bb549172cd739c82df21"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +brotli = ["brotli (==1.0.9)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] @@ -1842,13 +1855,13 @@ bracex = ">=2.1.1" [[package]] name = "wcwidth" -version = "0.2.6" +version = "0.2.8" description = "Measures the displayed width of unicode strings in a terminal" optional = false python-versions = "*" files = [ - {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, - {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, + {file = "wcwidth-0.2.8-py2.py3-none-any.whl", hash = "sha256:77f719e01648ed600dfa5402c347481c0992263b81a027344f3e1ba25493a704"}, + {file = "wcwidth-0.2.8.tar.gz", hash = "sha256:8705c569999ffbb4f6a87c6d1b80f324bd6db952f5eb0b95bc07517f4c1813d4"}, ] [[package]] @@ -1982,8 +1995,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.10" -<<<<<<< HEAD -content-hash = "913fce8b41a4ce58b5905473d876de02a8ff78968a15900b6519fd860d9ba6e8" -======= -content-hash = "87377d33bbe74e1ebc114878798d463d645015784475b584fd1504931400e0de" ->>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) +content-hash = "878bd3a8334d3178d84c396045acb5d5f9400fa273fa53f32d4eb98d01a031e0" diff --git a/pyproject.toml b/pyproject.toml index c63be6109a..8fc799ea8d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,11 +27,8 @@ wget = "^3.2" huggingface-hub = "^0.16.4" litellm = "^0.1.590" pyyaml = "^6.0.1" -<<<<<<< HEAD docker = "^6.1.3" -======= semgrep = "^1.41.0" ->>>>>>> 76a220ef (feat: add semgrep code scanning via --safe flag) [tool.poetry.dependencies.pyreadline3] version = "^3.4.1" markers = "sys_platform == 'win32'" From 03fb194548dece9331265e2342847b572d86a7cc Mon Sep 17 00:00:00 2001 From: Nathan Hoos <128712250+unaidedelf8777@users.noreply.github.com> Date: Thu, 5 Oct 2023 00:02:20 +0000 Subject: [PATCH 03/12] Fully Working. All functionality tested, but still havent done idiot testing. --- interpreter/__init__.py | 40 +- interpreter/cli/cli.py | 5 +- interpreter/code_interpreters/__init__.py | 2 - .../container_utils/container_utils.py | 3 +- .../dockerfiles/docker_manager.py | 30 +- interpreter/core/core.py | 12 +- poetry.lock | 364 +++++++++++------- 7 files changed, 279 insertions(+), 177 deletions(-) diff --git a/interpreter/__init__.py b/interpreter/__init__.py index 6ca64ffaa0..efd4748c54 100644 --- a/interpreter/__init__.py +++ b/interpreter/__init__.py @@ -1,15 +1,41 @@ -from .core.core import Interpreter import sys +from .core.core import Interpreter +from .cli.cli import cli + -# This is done so when users `import interpreter`, -# they get an instance of interpreter: -sys.modules["interpreter"] = Interpreter() +def create_interpreter(**kwargs): + """ + Factory function to create an instance of Interpreter with the provided keyword arguments. + + Parameters: + **kwargs: Keyword arguments to be set as attributes in the Interpreter instance. + + Returns: + An instance of Interpreter initialized with the provided arguments. + """ + # Create a new interpreter instance + new_interpreter = Interpreter() + + # Iterate through the provided keyword arguments + for key, value in kwargs.items(): + # Check if the attribute exists in the interpreter + if hasattr(new_interpreter, key): + # Check if the provided value is of the correct type + if isinstance(value, type(getattr(new_interpreter, key))): + setattr(new_interpreter, key, value) + else: + print( + f"Type mismatch: '{key}' should be of type {type(getattr(new_interpreter, key))}. Using the default value instead.") + + else: + print( + f"Unknown attribute: '{key}'. Ignoring.") + + + return new_interpreter -# **This is a controversial thing to do,** -# because perhaps modules ought to behave like modules. -# But I think it saves a step, removes friction, and looks good. # ____ ____ __ __ # / __ \____ ___ ____ / _/___ / /____ _________ ________ / /____ _____ diff --git a/interpreter/cli/cli.py b/interpreter/cli/cli.py index e5d0867e31..f49ec2be61 100644 --- a/interpreter/cli/cli.py +++ b/interpreter/cli/cli.py @@ -6,6 +6,7 @@ import appdirs from ..utils.display_markdown_message import display_markdown_message from ..terminal_interface.conversation_navigator import conversation_navigator +from ..core.core import Interpreter arguments = [ { @@ -90,7 +91,7 @@ } ] -def cli(interpreter): +def cli(): parser = argparse.ArgumentParser(description="Open Interpreter") @@ -112,6 +113,8 @@ def cli(interpreter): args = parser.parse_args() + interpreter = Interpreter() + # This should be pushed into an open_config.py util # If --config is used, open the config.yaml file in the Open Interpreter folder of the user's config dir if args.config: diff --git a/interpreter/code_interpreters/__init__.py b/interpreter/code_interpreters/__init__.py index 4c37be853a..8b13789179 100644 --- a/interpreter/code_interpreters/__init__.py +++ b/interpreter/code_interpreters/__init__.py @@ -1,3 +1 @@ -from .dockerfiles.docker_manager import DockerManager as ContainerConfig -__all__ = ["ContainerConfig"] diff --git a/interpreter/code_interpreters/container_utils/container_utils.py b/interpreter/code_interpreters/container_utils/container_utils.py index d1b0b4af11..8175bf61c5 100644 --- a/interpreter/code_interpreters/container_utils/container_utils.py +++ b/interpreter/code_interpreters/container_utils/container_utils.py @@ -81,6 +81,7 @@ def build_docker_images( images = client.images.list(name=image_name, all=True) if not images: Print("Downloading default image from Docker Hub, please wait...") + subprocess.run(["docker", "pull", "unaidedelf/openinterpreter-runtime-container:latest"]) subprocess.run(["docker", "tag", "unaidedelf/openinterpreter-runtime-container:latest", image_name ], check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) @@ -306,7 +307,7 @@ def init_exec_instance(self, command): # since docker sets up the socketio wierd and tries to make it hard to mess with and write to. # We make the socket "Cooperative" self.exec_socket = self.client.exec_start( - self.exec_id, socket=True, tty=False, demux=False)._sock + self.exec_id, socket=True, tty=False, demux=False)._sock # type: ignore def wait_for_container_start(self, container_id, timeout=30): diff --git a/interpreter/code_interpreters/dockerfiles/docker_manager.py b/interpreter/code_interpreters/dockerfiles/docker_manager.py index 149bec37e5..6446fd106b 100644 --- a/interpreter/code_interpreters/dockerfiles/docker_manager.py +++ b/interpreter/code_interpreters/dockerfiles/docker_manager.py @@ -1,14 +1,17 @@ +import os + class DockerManager: - def __init__(self, requirements_file='requirements.txt', docker_file='Dockerfile'): - self.requirements_file = requirements_file - self.docker_file = docker_file + + here = os.path.abspath(__file__) + requirements_file = os.path.normpath(os.path.join(here, "..", "requirements.txt")) + docker_file = os.path.normpath(os.path.join(here,"..", "Dockerfile")) - def add_dependency(self, language, dependency): + def add_dependency(language, dependency): lines = [] language_section_found = False dependency_name = dependency.split('==')[0] - with open(self.requirements_file, 'r') as f: + with open(DockerManager.requirements_file, 'r') as f: lines = f.readlines() for i, line in enumerate(lines): @@ -28,14 +31,14 @@ def add_dependency(self, language, dependency): lines.insert(i, f"{dependency}\n") - with open(self.requirements_file, 'w') as f: + with open(DockerManager.requirements_file, 'w') as f: f.writelines(lines) - def remove_dependency(self, language, dependency_name): + def remove_dependency(language, dependency_name): lines = [] language_section_found = False - with open(self.requirements_file, 'r') as f: + with open(DockerManager.requirements_file, 'r') as f: lines = f.readlines() for i, line in enumerate(lines): @@ -49,15 +52,8 @@ def remove_dependency(self, language, dependency_name): del lines[i] break else: - raise ValueError(f"Error: Language section [{language}] or dependency {dependency_name} not found. please add the language using the '.add_language' method") + raise ValueError(f"Error: Language section [{language}] or dependency {dependency_name} not found.") - with open(self.requirements_file, 'w') as f: + with open(DockerManager.requirements_file, 'w') as f: f.writelines(lines) - - def add_language(self, language, install_command): - with open(self.docker_file, 'a') as f: - f.write(f'\n# Install {language}\nRUN {install_command}\n') - - with open(self.requirements_file, 'a') as f: - f.write(f"\n[{language}]\n") diff --git a/interpreter/core/core.py b/interpreter/core/core.py index aa499a7bb5..b4cbfa399c 100644 --- a/interpreter/core/core.py +++ b/interpreter/core/core.py @@ -1,9 +1,7 @@ """ This file defines the Interpreter class. -It's the main file. `import interpreter` will import an instance of this class. +running ```import interpreter``` followed by ```interpreter.create_interpreter(**kwargs)``` will create an instance of this class. """ -from interpreter.utils import display_markdown_message -from ..cli.cli import cli from ..utils.get_config import get_config from .respond import respond from ..llm.setup_llm import setup_llm @@ -18,8 +16,6 @@ from ..code_interpreters.container_utils.container_utils import build_docker_images class Interpreter: - def cli(self): - cli(self) def __init__(self): # State @@ -49,12 +45,14 @@ def __init__(self): self.max_budget = None self._llm = None + # Container options + self.use_containers = False + # Load config defaults config = get_config() self.__dict__.update(config) - # Container options - self.use_containers = False + # Check for update diff --git a/poetry.lock b/poetry.lock index 1167b00773..35a1d9bd15 100644 --- a/poetry.lock +++ b/poetry.lock @@ -710,6 +710,23 @@ blessed = ">=1.19.0" python-editor = ">=1.0.4" readchar = ">=3.0.6" +[[package]] +name = "jinja2" +version = "3.1.2" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + [[package]] name = "jinxed" version = "1.2.0" @@ -761,19 +778,20 @@ referencing = ">=0.28.0" [[package]] name = "litellm" -version = "0.1.807" +version = "0.1.819" description = "Library to easily interface with LLM API providers" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "litellm-0.1.807-py3-none-any.whl", hash = "sha256:1f2a61c7c1eb43c1959314f94b13f29cfe75d57bf8e8ff80873182ae0ff34082"}, - {file = "litellm-0.1.807.tar.gz", hash = "sha256:554f6bac0ccc136b0bcb1d7512ab6bbcd0dfb3a8fadec7818d0ac156455ac4ef"}, + {file = "litellm-0.1.819-py3-none-any.whl", hash = "sha256:4aefb79dc3a10bdf9d42ac69a0b3f07b1553b81e3a9bcb9add077a5e34f643a3"}, + {file = "litellm-0.1.819.tar.gz", hash = "sha256:d253825781236fd42c8c8d0199ac4453d6bad5d78e496f7581fd15b11468c959"}, ] [package.dependencies] appdirs = ">=1.4.4,<2.0.0" click = "*" importlib-metadata = ">=6.8.0" +jinja2 = ">=3.1.2,<4.0.0" openai = ">=0.27.0,<0.29.0" python-dotenv = ">=0.2.0" tiktoken = ">=0.4.0" @@ -803,6 +821,75 @@ profiling = ["gprof2dot"] rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] +[[package]] +name = "markupsafe" +version = "2.1.3" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, + {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, + {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, + {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, + {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, + {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, + {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, +] + [[package]] name = "mdurl" version = "0.1.2" @@ -1158,99 +1245,99 @@ rpds-py = ">=0.7.0" [[package]] name = "regex" -version = "2023.8.8" +version = "2023.10.3" description = "Alternative regular expression module, to replace re." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "regex-2023.8.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:88900f521c645f784260a8d346e12a1590f79e96403971241e64c3a265c8ecdb"}, - {file = "regex-2023.8.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3611576aff55918af2697410ff0293d6071b7e00f4b09e005d614686ac4cd57c"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8a0ccc8f2698f120e9e5742f4b38dc944c38744d4bdfc427616f3a163dd9de5"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c662a4cbdd6280ee56f841f14620787215a171c4e2d1744c9528bed8f5816c96"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf0633e4a1b667bfe0bb10b5e53fe0d5f34a6243ea2530eb342491f1adf4f739"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:551ad543fa19e94943c5b2cebc54c73353ffff08228ee5f3376bd27b3d5b9800"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54de2619f5ea58474f2ac211ceea6b615af2d7e4306220d4f3fe690c91988a61"}, - {file = "regex-2023.8.8-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5ec4b3f0aebbbe2fc0134ee30a791af522a92ad9f164858805a77442d7d18570"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3ae646c35cb9f820491760ac62c25b6d6b496757fda2d51be429e0e7b67ae0ab"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ca339088839582d01654e6f83a637a4b8194d0960477b9769d2ff2cfa0fa36d2"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:d9b6627408021452dcd0d2cdf8da0534e19d93d070bfa8b6b4176f99711e7f90"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:bd3366aceedf274f765a3a4bc95d6cd97b130d1dda524d8f25225d14123c01db"}, - {file = "regex-2023.8.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7aed90a72fc3654fba9bc4b7f851571dcc368120432ad68b226bd593f3f6c0b7"}, - {file = "regex-2023.8.8-cp310-cp310-win32.whl", hash = "sha256:80b80b889cb767cc47f31d2b2f3dec2db8126fbcd0cff31b3925b4dc6609dcdb"}, - {file = "regex-2023.8.8-cp310-cp310-win_amd64.whl", hash = "sha256:b82edc98d107cbc7357da7a5a695901b47d6eb0420e587256ba3ad24b80b7d0b"}, - {file = "regex-2023.8.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1e7d84d64c84ad97bf06f3c8cb5e48941f135ace28f450d86af6b6512f1c9a71"}, - {file = "regex-2023.8.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ce0f9fbe7d295f9922c0424a3637b88c6c472b75eafeaff6f910494a1fa719ef"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06c57e14ac723b04458df5956cfb7e2d9caa6e9d353c0b4c7d5d54fcb1325c46"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e7a9aaa5a1267125eef22cef3b63484c3241aaec6f48949b366d26c7250e0357"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b7408511fca48a82a119d78a77c2f5eb1b22fe88b0d2450ed0756d194fe7a9a"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14dc6f2d88192a67d708341f3085df6a4f5a0c7b03dec08d763ca2cd86e9f559"}, - {file = "regex-2023.8.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48c640b99213643d141550326f34f0502fedb1798adb3c9eb79650b1ecb2f177"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0085da0f6c6393428bf0d9c08d8b1874d805bb55e17cb1dfa5ddb7cfb11140bf"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:964b16dcc10c79a4a2be9f1273fcc2684a9eedb3906439720598029a797b46e6"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7ce606c14bb195b0e5108544b540e2c5faed6843367e4ab3deb5c6aa5e681208"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:40f029d73b10fac448c73d6eb33d57b34607f40116e9f6e9f0d32e9229b147d7"}, - {file = "regex-2023.8.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3b8e6ea6be6d64104d8e9afc34c151926f8182f84e7ac290a93925c0db004bfd"}, - {file = "regex-2023.8.8-cp311-cp311-win32.whl", hash = "sha256:942f8b1f3b223638b02df7df79140646c03938d488fbfb771824f3d05fc083a8"}, - {file = "regex-2023.8.8-cp311-cp311-win_amd64.whl", hash = "sha256:51d8ea2a3a1a8fe4f67de21b8b93757005213e8ac3917567872f2865185fa7fb"}, - {file = "regex-2023.8.8-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e951d1a8e9963ea51efd7f150450803e3b95db5939f994ad3d5edac2b6f6e2b4"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:704f63b774218207b8ccc6c47fcef5340741e5d839d11d606f70af93ee78e4d4"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22283c769a7b01c8ac355d5be0715bf6929b6267619505e289f792b01304d898"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91129ff1bb0619bc1f4ad19485718cc623a2dc433dff95baadbf89405c7f6b57"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de35342190deb7b866ad6ba5cbcccb2d22c0487ee0cbb251efef0843d705f0d4"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b993b6f524d1e274a5062488a43e3f9f8764ee9745ccd8e8193df743dbe5ee61"}, - {file = "regex-2023.8.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3026cbcf11d79095a32d9a13bbc572a458727bd5b1ca332df4a79faecd45281c"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:293352710172239bf579c90a9864d0df57340b6fd21272345222fb6371bf82b3"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d909b5a3fff619dc7e48b6b1bedc2f30ec43033ba7af32f936c10839e81b9217"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:3d370ff652323c5307d9c8e4c62efd1956fb08051b0e9210212bc51168b4ff56"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:b076da1ed19dc37788f6a934c60adf97bd02c7eea461b73730513921a85d4235"}, - {file = "regex-2023.8.8-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e9941a4ada58f6218694f382e43fdd256e97615db9da135e77359da257a7168b"}, - {file = "regex-2023.8.8-cp36-cp36m-win32.whl", hash = "sha256:a8c65c17aed7e15a0c824cdc63a6b104dfc530f6fa8cb6ac51c437af52b481c7"}, - {file = "regex-2023.8.8-cp36-cp36m-win_amd64.whl", hash = "sha256:aadf28046e77a72f30dcc1ab185639e8de7f4104b8cb5c6dfa5d8ed860e57236"}, - {file = "regex-2023.8.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:423adfa872b4908843ac3e7a30f957f5d5282944b81ca0a3b8a7ccbbfaa06103"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ae594c66f4a7e1ea67232a0846649a7c94c188d6c071ac0210c3e86a5f92109"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e51c80c168074faa793685656c38eb7a06cbad7774c8cbc3ea05552d615393d8"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09b7f4c66aa9d1522b06e31a54f15581c37286237208df1345108fcf4e050c18"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e73e5243af12d9cd6a9d6a45a43570dbe2e5b1cdfc862f5ae2b031e44dd95a8"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:941460db8fe3bd613db52f05259c9336f5a47ccae7d7def44cc277184030a116"}, - {file = "regex-2023.8.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f0ccf3e01afeb412a1a9993049cb160d0352dba635bbca7762b2dc722aa5742a"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:2e9216e0d2cdce7dbc9be48cb3eacb962740a09b011a116fd7af8c832ab116ca"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5cd9cd7170459b9223c5e592ac036e0704bee765706445c353d96f2890e816c8"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4873ef92e03a4309b3ccd8281454801b291b689f6ad45ef8c3658b6fa761d7ac"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:239c3c2a339d3b3ddd51c2daef10874410917cd2b998f043c13e2084cb191684"}, - {file = "regex-2023.8.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:1005c60ed7037be0d9dea1f9c53cc42f836188227366370867222bda4c3c6bd7"}, - {file = "regex-2023.8.8-cp37-cp37m-win32.whl", hash = "sha256:e6bd1e9b95bc5614a7a9c9c44fde9539cba1c823b43a9f7bc11266446dd568e3"}, - {file = "regex-2023.8.8-cp37-cp37m-win_amd64.whl", hash = "sha256:9a96edd79661e93327cfeac4edec72a4046e14550a1d22aa0dd2e3ca52aec921"}, - {file = "regex-2023.8.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2181c20ef18747d5f4a7ea513e09ea03bdd50884a11ce46066bb90fe4213675"}, - {file = "regex-2023.8.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a2ad5add903eb7cdde2b7c64aaca405f3957ab34f16594d2b78d53b8b1a6a7d6"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9233ac249b354c54146e392e8a451e465dd2d967fc773690811d3a8c240ac601"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:920974009fb37b20d32afcdf0227a2e707eb83fe418713f7a8b7de038b870d0b"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2b6c5dfe0929b6c23dde9624483380b170b6e34ed79054ad131b20203a1a63"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96979d753b1dc3b2169003e1854dc67bfc86edf93c01e84757927f810b8c3c93"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ae54a338191e1356253e7883d9d19f8679b6143703086245fb14d1f20196be9"}, - {file = "regex-2023.8.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2162ae2eb8b079622176a81b65d486ba50b888271302190870b8cc488587d280"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c884d1a59e69e03b93cf0dfee8794c63d7de0ee8f7ffb76e5f75be8131b6400a"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf9273e96f3ee2ac89ffcb17627a78f78e7516b08f94dc435844ae72576a276e"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:83215147121e15d5f3a45d99abeed9cf1fe16869d5c233b08c56cdf75f43a504"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:3f7454aa427b8ab9101f3787eb178057c5250478e39b99540cfc2b889c7d0586"}, - {file = "regex-2023.8.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0640913d2c1044d97e30d7c41728195fc37e54d190c5385eacb52115127b882"}, - {file = "regex-2023.8.8-cp38-cp38-win32.whl", hash = "sha256:0c59122ceccb905a941fb23b087b8eafc5290bf983ebcb14d2301febcbe199c7"}, - {file = "regex-2023.8.8-cp38-cp38-win_amd64.whl", hash = "sha256:c12f6f67495ea05c3d542d119d270007090bad5b843f642d418eb601ec0fa7be"}, - {file = "regex-2023.8.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:82cd0a69cd28f6cc3789cc6adeb1027f79526b1ab50b1f6062bbc3a0ccb2dbc3"}, - {file = "regex-2023.8.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bb34d1605f96a245fc39790a117ac1bac8de84ab7691637b26ab2c5efb8f228c"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:987b9ac04d0b38ef4f89fbc035e84a7efad9cdd5f1e29024f9289182c8d99e09"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dd6082f4e2aec9b6a0927202c85bc1b09dcab113f97265127c1dc20e2e32495"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7eb95fe8222932c10d4436e7a6f7c99991e3fdd9f36c949eff16a69246dee2dc"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7098c524ba9f20717a56a8d551d2ed491ea89cbf37e540759ed3b776a4f8d6eb"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b694430b3f00eb02c594ff5a16db30e054c1b9589a043fe9174584c6efa8033"}, - {file = "regex-2023.8.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2aeab3895d778155054abea5238d0eb9a72e9242bd4b43f42fd911ef9a13470"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:988631b9d78b546e284478c2ec15c8a85960e262e247b35ca5eaf7ee22f6050a"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:67ecd894e56a0c6108ec5ab1d8fa8418ec0cff45844a855966b875d1039a2e34"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:14898830f0a0eb67cae2bbbc787c1a7d6e34ecc06fbd39d3af5fe29a4468e2c9"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:f2200e00b62568cfd920127782c61bc1c546062a879cdc741cfcc6976668dfcf"}, - {file = "regex-2023.8.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9691a549c19c22d26a4f3b948071e93517bdf86e41b81d8c6ac8a964bb71e5a6"}, - {file = "regex-2023.8.8-cp39-cp39-win32.whl", hash = "sha256:6ab2ed84bf0137927846b37e882745a827458689eb969028af8032b1b3dac78e"}, - {file = "regex-2023.8.8-cp39-cp39-win_amd64.whl", hash = "sha256:5543c055d8ec7801901e1193a51570643d6a6ab8751b1f7dd9af71af467538bb"}, - {file = "regex-2023.8.8.tar.gz", hash = "sha256:fcbdc5f2b0f1cd0f6a56cdb46fe41d2cce1e644e3b68832f3eeebc5fb0f7712e"}, + {file = "regex-2023.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4c34d4f73ea738223a094d8e0ffd6d2c1a1b4c175da34d6b0de3d8d69bee6bcc"}, + {file = "regex-2023.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8f4e49fc3ce020f65411432183e6775f24e02dff617281094ba6ab079ef0915"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cd1bccf99d3ef1ab6ba835308ad85be040e6a11b0977ef7ea8c8005f01a3c29"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81dce2ddc9f6e8f543d94b05d56e70d03a0774d32f6cca53e978dc01e4fc75b8"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c6b4d23c04831e3ab61717a707a5d763b300213db49ca680edf8bf13ab5d91b"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c15ad0aee158a15e17e0495e1e18741573d04eb6da06d8b84af726cfc1ed02ee"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6239d4e2e0b52c8bd38c51b760cd870069f0bdf99700a62cd509d7a031749a55"}, + {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4a8bf76e3182797c6b1afa5b822d1d5802ff30284abe4599e1247be4fd6b03be"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9c727bbcf0065cbb20f39d2b4f932f8fa1631c3e01fcedc979bd4f51fe051c5"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3ccf2716add72f80714b9a63899b67fa711b654be3fcdd34fa391d2d274ce767"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:107ac60d1bfdc3edb53be75e2a52aff7481b92817cfdddd9b4519ccf0e54a6ff"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:00ba3c9818e33f1fa974693fb55d24cdc8ebafcb2e4207680669d8f8d7cca79a"}, + {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f0a47efb1dbef13af9c9a54a94a0b814902e547b7f21acb29434504d18f36e3a"}, + {file = "regex-2023.10.3-cp310-cp310-win32.whl", hash = "sha256:36362386b813fa6c9146da6149a001b7bd063dabc4d49522a1f7aa65b725c7ec"}, + {file = "regex-2023.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:c65a3b5330b54103e7d21cac3f6bf3900d46f6d50138d73343d9e5b2900b2353"}, + {file = "regex-2023.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90a79bce019c442604662d17bf69df99090e24cdc6ad95b18b6725c2988a490e"}, + {file = "regex-2023.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c7964c2183c3e6cce3f497e3a9f49d182e969f2dc3aeeadfa18945ff7bdd7051"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ef80829117a8061f974b2fda8ec799717242353bff55f8a29411794d635d964"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5addc9d0209a9afca5fc070f93b726bf7003bd63a427f65ef797a931782e7edc"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c148bec483cc4b421562b4bcedb8e28a3b84fcc8f0aa4418e10898f3c2c0eb9b"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d1f21af4c1539051049796a0f50aa342f9a27cde57318f2fc41ed50b0dbc4ac"}, + {file = "regex-2023.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b9ac09853b2a3e0d0082104036579809679e7715671cfbf89d83c1cb2a30f58"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ebedc192abbc7fd13c5ee800e83a6df252bec691eb2c4bedc9f8b2e2903f5e2a"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d8a993c0a0ffd5f2d3bda23d0cd75e7086736f8f8268de8a82fbc4bd0ac6791e"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:be6b7b8d42d3090b6c80793524fa66c57ad7ee3fe9722b258aec6d0672543fd0"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4023e2efc35a30e66e938de5aef42b520c20e7eda7bb5fb12c35e5d09a4c43f6"}, + {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0d47840dc05e0ba04fe2e26f15126de7c755496d5a8aae4a08bda4dd8d646c54"}, + {file = "regex-2023.10.3-cp311-cp311-win32.whl", hash = "sha256:9145f092b5d1977ec8c0ab46e7b3381b2fd069957b9862a43bd383e5c01d18c2"}, + {file = "regex-2023.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:b6104f9a46bd8743e4f738afef69b153c4b8b592d35ae46db07fc28ae3d5fb7c"}, + {file = "regex-2023.10.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff507ae210371d4b1fe316d03433ac099f184d570a1a611e541923f78f05037"}, + {file = "regex-2023.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be5e22bbb67924dea15039c3282fa4cc6cdfbe0cbbd1c0515f9223186fc2ec5f"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a992f702c9be9c72fa46f01ca6e18d131906a7180950958f766c2aa294d4b41"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7434a61b158be563c1362d9071358f8ab91b8d928728cd2882af060481244c9e"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2169b2dcabf4e608416f7f9468737583ce5f0a6e8677c4efbf795ce81109d7c"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9e908ef5889cda4de038892b9accc36d33d72fb3e12c747e2799a0e806ec841"}, + {file = "regex-2023.10.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12bd4bc2c632742c7ce20db48e0d99afdc05e03f0b4c1af90542e05b809a03d9"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bc72c231f5449d86d6c7d9cc7cd819b6eb30134bb770b8cfdc0765e48ef9c420"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bce8814b076f0ce5766dc87d5a056b0e9437b8e0cd351b9a6c4e1134a7dfbda9"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ba7cd6dc4d585ea544c1412019921570ebd8a597fabf475acc4528210d7c4a6f"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b0c7d2f698e83f15228ba41c135501cfe7d5740181d5903e250e47f617eb4292"}, + {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5a8f91c64f390ecee09ff793319f30a0f32492e99f5dc1c72bc361f23ccd0a9a"}, + {file = "regex-2023.10.3-cp312-cp312-win32.whl", hash = "sha256:ad08a69728ff3c79866d729b095872afe1e0557251da4abb2c5faff15a91d19a"}, + {file = "regex-2023.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:39cdf8d141d6d44e8d5a12a8569d5a227f645c87df4f92179bd06e2e2705e76b"}, + {file = "regex-2023.10.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4a3ee019a9befe84fa3e917a2dd378807e423d013377a884c1970a3c2792d293"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76066d7ff61ba6bf3cb5efe2428fc82aac91802844c022d849a1f0f53820502d"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe50b61bab1b1ec260fa7cd91106fa9fece57e6beba05630afe27c71259c59b"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fd88f373cb71e6b59b7fa597e47e518282455c2734fd4306a05ca219a1991b0"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ab05a182c7937fb374f7e946f04fb23a0c0699c0450e9fb02ef567412d2fa3"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dac37cf08fcf2094159922edc7a2784cfcc5c70f8354469f79ed085f0328ebdf"}, + {file = "regex-2023.10.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e54ddd0bb8fb626aa1f9ba7b36629564544954fff9669b15da3610c22b9a0991"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3367007ad1951fde612bf65b0dffc8fd681a4ab98ac86957d16491400d661302"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:16f8740eb6dbacc7113e3097b0a36065a02e37b47c936b551805d40340fb9971"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:f4f2ca6df64cbdd27f27b34f35adb640b5d2d77264228554e68deda54456eb11"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:39807cbcbe406efca2a233884e169d056c35aa7e9f343d4e78665246a332f597"}, + {file = "regex-2023.10.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7eece6fbd3eae4a92d7c748ae825cbc1ee41a89bb1c3db05b5578ed3cfcfd7cb"}, + {file = "regex-2023.10.3-cp37-cp37m-win32.whl", hash = "sha256:ce615c92d90df8373d9e13acddd154152645c0dc060871abf6bd43809673d20a"}, + {file = "regex-2023.10.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f649fa32fe734c4abdfd4edbb8381c74abf5f34bc0b3271ce687b23729299ed"}, + {file = "regex-2023.10.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b98b7681a9437262947f41c7fac567c7e1f6eddd94b0483596d320092004533"}, + {file = "regex-2023.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:91dc1d531f80c862441d7b66c4505cd6ea9d312f01fb2f4654f40c6fdf5cc37a"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82fcc1f1cc3ff1ab8a57ba619b149b907072e750815c5ba63e7aa2e1163384a4"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7979b834ec7a33aafae34a90aad9f914c41fd6eaa8474e66953f3f6f7cbd4368"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef71561f82a89af6cfcbee47f0fabfdb6e63788a9258e913955d89fdd96902ab"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd829712de97753367153ed84f2de752b86cd1f7a88b55a3a775eb52eafe8a94"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00e871d83a45eee2f8688d7e6849609c2ca2a04a6d48fba3dff4deef35d14f07"}, + {file = "regex-2023.10.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:706e7b739fdd17cb89e1fbf712d9dc21311fc2333f6d435eac2d4ee81985098c"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cc3f1c053b73f20c7ad88b0d1d23be7e7b3901229ce89f5000a8399746a6e039"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6f85739e80d13644b981a88f529d79c5bdf646b460ba190bffcaf6d57b2a9863"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:741ba2f511cc9626b7561a440f87d658aabb3d6b744a86a3c025f866b4d19e7f"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e77c90ab5997e85901da85131fd36acd0ed2221368199b65f0d11bca44549711"}, + {file = "regex-2023.10.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:979c24cbefaf2420c4e377ecd1f165ea08cc3d1fbb44bdc51bccbbf7c66a2cb4"}, + {file = "regex-2023.10.3-cp38-cp38-win32.whl", hash = "sha256:58837f9d221744d4c92d2cf7201c6acd19623b50c643b56992cbd2b745485d3d"}, + {file = "regex-2023.10.3-cp38-cp38-win_amd64.whl", hash = "sha256:c55853684fe08d4897c37dfc5faeff70607a5f1806c8be148f1695be4a63414b"}, + {file = "regex-2023.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2c54e23836650bdf2c18222c87f6f840d4943944146ca479858404fedeb9f9af"}, + {file = "regex-2023.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69c0771ca5653c7d4b65203cbfc5e66db9375f1078689459fe196fe08b7b4930"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ac965a998e1388e6ff2e9781f499ad1eaa41e962a40d11c7823c9952c77123e"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c0e8fae5b27caa34177bdfa5a960c46ff2f78ee2d45c6db15ae3f64ecadde14"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c56c3d47da04f921b73ff9415fbaa939f684d47293f071aa9cbb13c94afc17d"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ef1e014eed78ab650bef9a6a9cbe50b052c0aebe553fb2881e0453717573f52"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d29338556a59423d9ff7b6eb0cb89ead2b0875e08fe522f3e068b955c3e7b59b"}, + {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9c6d0ced3c06d0f183b73d3c5920727268d2201aa0fe6d55c60d68c792ff3588"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:994645a46c6a740ee8ce8df7911d4aee458d9b1bc5639bc968226763d07f00fa"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:66e2fe786ef28da2b28e222c89502b2af984858091675044d93cb50e6f46d7af"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:11175910f62b2b8c055f2b089e0fedd694fe2be3941b3e2633653bc51064c528"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:06e9abc0e4c9ab4779c74ad99c3fc10d3967d03114449acc2c2762ad4472b8ca"}, + {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fb02e4257376ae25c6dd95a5aec377f9b18c09be6ebdefa7ad209b9137b73d48"}, + {file = "regex-2023.10.3-cp39-cp39-win32.whl", hash = "sha256:3b2c3502603fab52d7619b882c25a6850b766ebd1b18de3df23b2f939360e1bd"}, + {file = "regex-2023.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:adbccd17dcaff65704c856bd29951c58a1bd4b2b0f8ad6b826dbd543fe740988"}, + {file = "regex-2023.10.3.tar.gz", hash = "sha256:3fef4f844d2290ee0ba57addcec17eec9e3df73f10a2748485dfd6a3a188cc0f"}, ] [[package]] @@ -1400,17 +1487,17 @@ files = [ [[package]] name = "ruamel-yaml" -version = "0.17.33" +version = "0.17.35" description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" optional = false python-versions = ">=3" files = [ - {file = "ruamel.yaml-0.17.33-py3-none-any.whl", hash = "sha256:2080c7a02b8a30fb3c06727cdf3e254a64055eedf3aa2d17c2b669639c04971b"}, - {file = "ruamel.yaml-0.17.33.tar.gz", hash = "sha256:5c56aa0bff2afceaa93bffbfc78b450b7dc1e01d5edb80b3a570695286ae62b1"}, + {file = "ruamel.yaml-0.17.35-py3-none-any.whl", hash = "sha256:b105e3e6fc15b41fdb201ba1b95162ae566a4ef792b9f884c46b4ccc5513a87a"}, + {file = "ruamel.yaml-0.17.35.tar.gz", hash = "sha256:801046a9caacb1b43acc118969b49b96b65e8847f29029563b29ac61d02db61b"}, ] [package.dependencies] -"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.12\""} +"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""} [package.extras] docs = ["ryd"] @@ -1418,62 +1505,55 @@ jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] [[package]] name = "ruamel-yaml-clib" -version = "0.2.7" +version = "0.2.8" description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" files = [ - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d5859983f26d8cd7bb5c287ef452e8aacc86501487634573d260968f753e1d71"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:debc87a9516b237d0466a711b18b6ebeb17ba9f391eb7f91c649c5c4ec5006c7"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:df5828871e6648db72d1c19b4bd24819b80a755c4541d3409f0f7acd0f335c80"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:efa08d63ef03d079dcae1dfe334f6c8847ba8b645d08df286358b1f5293d24ab"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, - {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:370445fd795706fd291ab00c9df38a0caed0f17a6fb46b0f607668ecb16ce763"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win32.whl", hash = "sha256:ecdf1a604009bd35c674b9225a8fa609e0282d9b896c03dd441a91e5f53b534e"}, - {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-win_amd64.whl", hash = "sha256:f34019dced51047d6f70cb9383b2ae2853b7fc4dce65129a5acd49f4f9256646"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aa261c29a5545adfef9296b7e33941f46aa5bbd21164228e833412af4c9c75f"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f01da5790e95815eb5a8a138508c01c758e5f5bc0ce4286c4f7028b8dd7ac3d0"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:40d030e2329ce5286d6b231b8726959ebbe0404c92f0a578c0e2482182e38282"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c3ca1fbba4ae962521e5eb66d72998b51f0f4d0f608d3c0347a48e1af262efa7"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win32.whl", hash = "sha256:7bdb4c06b063f6fd55e472e201317a3bb6cdeeee5d5a38512ea5c01e1acbdd93"}, - {file = "ruamel.yaml.clib-0.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:be2a7ad8fd8f7442b24323d24ba0b56c51219513cfa45b9ada3b87b76c374d4b"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:91a789b4aa0097b78c93e3dc4b40040ba55bef518f84a40d4442f713b4094acb"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:99e77daab5d13a48a4054803d052ff40780278240a902b880dd37a51ba01a307"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:3243f48ecd450eddadc2d11b5feb08aca941b5cd98c9b1db14b2fd128be8c697"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8831a2cedcd0f0927f788c5bdf6567d9dc9cc235646a434986a852af1cb54b4b"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win32.whl", hash = "sha256:3110a99e0f94a4a3470ff67fc20d3f96c25b13d24c6980ff841e82bafe827cac"}, - {file = "ruamel.yaml.clib-0.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:92460ce908546ab69770b2e576e4f99fbb4ce6ab4b245345a3869a0a0410488f"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5bc0667c1eb8f83a3752b71b9c4ba55ef7c7058ae57022dd9b29065186a113d9"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:4a4d8d417868d68b979076a9be6a38c676eca060785abaa6709c7b31593c35d1"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:bf9a6bc4a0221538b1a7de3ed7bca4c93c02346853f44e1cd764be0023cd3640"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a7b301ff08055d73223058b5c46c55638917f04d21577c95e00e0c4d79201a6b"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win32.whl", hash = "sha256:d5e51e2901ec2366b79f16c2299a03e74ba4531ddcfacc1416639c557aef0ad8"}, - {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:184faeaec61dbaa3cace407cffc5819f7b977e75360e8d5ca19461cd851a5fc5"}, - {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, + {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"}, + {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"}, ] [[package]] name = "semgrep" -version = "1.42.0" +version = "1.43.0" description = "Lightweight static analysis for many languages. Find bug variants with patterns that look like source code." optional = false python-versions = ">=3.7" files = [ - {file = "semgrep-1.42.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-any.whl", hash = "sha256:b84bfec84ebe4a1e1e9ea6e1be5f9b8c03ce4e38740980a28fa5961ffed6a812"}, - {file = "semgrep-1.42.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-macosx_10_14_x86_64.whl", hash = "sha256:7f1763ffadd3ddadae78c138ed20dcdc0dbe5dbf3aaa0205b2ca52609d27879f"}, - {file = "semgrep-1.42.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-macosx_11_0_arm64.whl", hash = "sha256:b181fbfe8122e642fe290b25e1f0a311d0202e355c89bab989d738a5282fb812"}, - {file = "semgrep-1.42.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-musllinux_1_0_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1a869e65bc1d29f50d3336d0e29550325ed15042cfcf6ff5fe003e75fe4202c"}, - {file = "semgrep-1.42.0.tar.gz", hash = "sha256:308978610f4f0ae15268f127678762ef4d8b6092f814fda54b83c53454446d34"}, + {file = "semgrep-1.43.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-any.whl", hash = "sha256:d5ce764fa2a26c08010c0e527680fbdf10352b3cafecacf90d1fef191302c466"}, + {file = "semgrep-1.43.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-macosx_10_14_x86_64.whl", hash = "sha256:e0484cd677f0703339e71a634bf99395789e2cb4d07a2852709c92405353e89c"}, + {file = "semgrep-1.43.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-macosx_11_0_arm64.whl", hash = "sha256:e9cc95bc911eec9dc01170788f9681379c6b6cf91855efcb4ac0e6fe220681a8"}, + {file = "semgrep-1.43.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-musllinux_1_0_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e06b139836e42d2c13121ccd4b466f80d72d4309c1953e0368826c8bf7723d9d"}, + {file = "semgrep-1.43.0.tar.gz", hash = "sha256:8bfb8fb4aaecde4b36eb86c4057a13cf7eaf67c54bd7a062e31aa2be0335205f"}, ] [package.dependencies] From acb8dbc71316718e82b61afb5efb2bfbdf3b5d66 Mon Sep 17 00:00:00 2001 From: Nathan Hoos <128712250+unaidedelf8777@users.noreply.github.com> Date: Thu, 5 Oct 2023 00:52:14 +0000 Subject: [PATCH 04/12] left one merge header accidentaly. fixed that. --- interpreter/code_interpreters/create_code_interpreter.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/interpreter/code_interpreters/create_code_interpreter.py b/interpreter/code_interpreters/create_code_interpreter.py index 1625533702..69eb9d9034 100644 --- a/interpreter/code_interpreters/create_code_interpreter.py +++ b/interpreter/code_interpreters/create_code_interpreter.py @@ -1,4 +1,3 @@ -<<<<<<< HEAD import inspect import os import uuid @@ -8,9 +7,6 @@ from .language_map import language_map -======= -from .language_map import language_map ->>>>>>> upstream/main # Global dictionary to store the session IDs by the weak reference of the calling objects SESSION_IDS_BY_OBJECT = weakref.WeakKeyDictionary() @@ -44,7 +40,6 @@ def create_code_interpreter(language, use_containers=False): # Case in-sensitive language = language.lower() -<<<<<<< HEAD caller_object = None if use_containers: @@ -77,8 +72,6 @@ def create_code_interpreter(language, use_containers=False): session_id = f"ses-{str(uuid.uuid4())}" SESSION_IDS_BY_OBJECT[caller_object] = session_id -======= ->>>>>>> upstream/main try: # Retrieve the specific CodeInterpreter class based on the language CodeInterpreter = language_map[language] From 1858ffba365debe9c142bcba80530c66c9c14b04 Mon Sep 17 00:00:00 2001 From: Nathan Hoos <128712250+unaidedelf8777@users.noreply.github.com> Date: Thu, 5 Oct 2023 00:57:43 +0000 Subject: [PATCH 05/12] I forgot a header apparently. lol --- interpreter/code_interpreters/languages/applescript.py | 8 -------- interpreter/code_interpreters/languages/html.py | 5 ----- interpreter/code_interpreters/languages/javascript.py | 8 -------- interpreter/code_interpreters/languages/python.py | 9 --------- interpreter/code_interpreters/languages/r.py | 8 -------- interpreter/code_interpreters/languages/shell.py | 8 -------- 6 files changed, 46 deletions(-) diff --git a/interpreter/code_interpreters/languages/applescript.py b/interpreter/code_interpreters/languages/applescript.py index 74b7446127..78168e4577 100644 --- a/interpreter/code_interpreters/languages/applescript.py +++ b/interpreter/code_interpreters/languages/applescript.py @@ -2,7 +2,6 @@ from ..subprocess_code_interpreter import SubprocessCodeInterpreter class AppleScript(SubprocessCodeInterpreter): -<<<<<<< HEAD file_extension = "applescript" proper_name = "AppleScript" @@ -10,13 +9,6 @@ class AppleScript(SubprocessCodeInterpreter): def __init__(self, **kwargs): super().__init__(**kwargs) -======= - file_extension = "applescript" - proper_name = "AppleScript" - - def __init__(self): - super().__init__() ->>>>>>> upstream/main self.start_cmd = os.environ.get('SHELL', '/bin/zsh') def preprocess_code(self, code): diff --git a/interpreter/code_interpreters/languages/html.py b/interpreter/code_interpreters/languages/html.py index f6d5fc86e3..3be7cbcf40 100644 --- a/interpreter/code_interpreters/languages/html.py +++ b/interpreter/code_interpreters/languages/html.py @@ -7,14 +7,9 @@ class HTML(BaseCodeInterpreter): file_extension = "html" proper_name = "HTML" -<<<<<<< HEAD def __init__(self, **kwargs): super().__init__(**kwargs) # include kwargs though they dont do anything in this case. # This is just so we dont need more logic in the create interpreter function -======= - def __init__(self): - super().__init__() ->>>>>>> upstream/main def run(self, code): # Create a temporary HTML file with the content diff --git a/interpreter/code_interpreters/languages/javascript.py b/interpreter/code_interpreters/languages/javascript.py index e312ce1712..4a078e7df7 100644 --- a/interpreter/code_interpreters/languages/javascript.py +++ b/interpreter/code_interpreters/languages/javascript.py @@ -2,7 +2,6 @@ import re class JavaScript(SubprocessCodeInterpreter): -<<<<<<< HEAD file_extension = "js" proper_name = "JavaScript" @@ -10,13 +9,6 @@ class JavaScript(SubprocessCodeInterpreter): def __init__(self, **kwargs): super().__init__(**kwargs) -======= - file_extension = "js" - proper_name = "JavaScript" - - def __init__(self): - super().__init__() ->>>>>>> upstream/main self.start_cmd = "node -i" def preprocess_code(self, code): diff --git a/interpreter/code_interpreters/languages/python.py b/interpreter/code_interpreters/languages/python.py index f851571e6d..f18cf1c509 100644 --- a/interpreter/code_interpreters/languages/python.py +++ b/interpreter/code_interpreters/languages/python.py @@ -4,7 +4,6 @@ import re class Python(SubprocessCodeInterpreter): -<<<<<<< HEAD file_extension = "py" proper_name = "Python" @@ -15,14 +14,6 @@ def __init__(self, **kwargs): self.start_cmd = "python3 -i -q -u" else: self.start_cmd = sys.executable + " -i -q -u" -======= - file_extension = "py" - proper_name = "Python" - - def __init__(self): - super().__init__() - self.start_cmd = sys.executable + " -i -q -u" ->>>>>>> upstream/main def preprocess_code(self, code): return preprocess_python(code) diff --git a/interpreter/code_interpreters/languages/r.py b/interpreter/code_interpreters/languages/r.py index 6df8ac4b64..13e54d6848 100644 --- a/interpreter/code_interpreters/languages/r.py +++ b/interpreter/code_interpreters/languages/r.py @@ -2,7 +2,6 @@ import re class R(SubprocessCodeInterpreter): -<<<<<<< HEAD file_extension = "r" @@ -10,13 +9,6 @@ class R(SubprocessCodeInterpreter): def __init__(self, **kwargs): super().__init__(**kwargs) -======= - file_extension = "r" - proper_name = "R" - - def __init__(self): - super().__init__() ->>>>>>> upstream/main self.start_cmd = "R -q --vanilla" # Start R in quiet and vanilla mode def preprocess_code(self, code): diff --git a/interpreter/code_interpreters/languages/shell.py b/interpreter/code_interpreters/languages/shell.py index e9fea68858..a202b08768 100644 --- a/interpreter/code_interpreters/languages/shell.py +++ b/interpreter/code_interpreters/languages/shell.py @@ -4,17 +4,9 @@ import os class Shell(SubprocessCodeInterpreter): -<<<<<<< HEAD file_extension = "sh" proper_name = "Shell" -======= - file_extension = "sh" - proper_name = "Shell" - - def __init__(self): - super().__init__() ->>>>>>> upstream/main def __init__(self, **kwargs): super().__init__(**kwargs) From e2716cdde0e2001fcce290fc44e6d7adb611d23b Mon Sep 17 00:00:00 2001 From: Nathan Hoos <128712250+unaidedelf8777@users.noreply.github.com> Date: Sun, 15 Oct 2023 15:20:53 -0500 Subject: [PATCH 06/12] Dev done (#4) * Add filedialog for upload cmd * minor things --- .../container_utils/download_file.py | 2 +- .../components/file_dialog.py | 47 +++++++++++++ .../terminal_interface/magic_commands.py | 45 ++++++++++-- poetry.lock | 69 ++++++++++++++++++- pyproject.toml | 2 + 5 files changed, 159 insertions(+), 6 deletions(-) create mode 100644 interpreter/terminal_interface/components/file_dialog.py diff --git a/interpreter/code_interpreters/container_utils/download_file.py b/interpreter/code_interpreters/container_utils/download_file.py index eb6fbb9221..dc3047e5d7 100644 --- a/interpreter/code_interpreters/container_utils/download_file.py +++ b/interpreter/code_interpreters/container_utils/download_file.py @@ -22,7 +22,7 @@ def download_file_from_container(container_id, file_path_in_container, local_dir container = client.containers.get(container_id) # Use get_archive to get a file from the container - stream, stat = container.get_archive(file_path_in_container) + stream, stat = container.get_archive(os.path.join("/mnt/data/", file_path_in_container)) # Get the file name from the stat info file_name = os.path.basename(stat['name']) diff --git a/interpreter/terminal_interface/components/file_dialog.py b/interpreter/terminal_interface/components/file_dialog.py new file mode 100644 index 0000000000..4c0bdbb377 --- /dev/null +++ b/interpreter/terminal_interface/components/file_dialog.py @@ -0,0 +1,47 @@ +"""Simple class and method to launch the users system filedialog """ + +from PyQt5.QtWidgets import QApplication, QFileDialog, QMessageBox + +class FileDialog: + def get_path(self, type=None): + """ + Open a file dialog and return the selected file or folder path. + + :param type: str, optional (default=None) + Specifies the type of path to select ("file", "folder", or None). + If None, the user will be asked whether to select a file or a folder. + :return: str + The path selected by the user. If the user cancels the operation, it returns None. + """ + app = QApplication.instance() + if app is None: + app = QApplication([]) + + options = QFileDialog.Options() + options |= QFileDialog.ReadOnly + + if type is None: + msg_box = QMessageBox() + msg_box.setWindowTitle("Choose Action") + msg_box.setText("Do you want to select a file or a folder?") + btn_file = msg_box.addButton("File", QMessageBox.YesRole) + btn_folder = msg_box.addButton("Folder", QMessageBox.NoRole) + msg_box.addButton(QMessageBox.Cancel) + user_choice = msg_box.exec_() + + if user_choice == QMessageBox.Cancel: + return None + type = "file" if msg_box.clickedButton() == btn_file else "folder" + + if type == "file": + path, _ = QFileDialog.getOpenFileName(None, "Open File", "", + "All Files (*)", options=options) + elif type == "folder": + path = QFileDialog.getExistingDirectory(None, "Open Folder", + "", options=options) + else: + path = self.get_path(type=None) # this or val err, may aswell explicitly pass none. + + return path + + diff --git a/interpreter/terminal_interface/magic_commands.py b/interpreter/terminal_interface/magic_commands.py index cfb3aa99fa..9e5ef8b8c5 100644 --- a/interpreter/terminal_interface/magic_commands.py +++ b/interpreter/terminal_interface/magic_commands.py @@ -8,6 +8,8 @@ from ..code_interpreters.container_utils.upload_file import copy_file_to_container from ..code_interpreters.create_code_interpreter import SESSION_IDS_BY_OBJECT +from rich import print as Print + def handle_undo(self, arguments): # Removes all messages after the most recent user entry (and the entry itself). @@ -51,6 +53,10 @@ def handle_help(self, arguments): "%save_message [path]": "Saves messages to a specified JSON path. If no path is provided, it defaults to 'messages.json'.", "%load_message [path]": "Loads messages from a specified JSON path. If no path is provided, it defaults to 'messages.json'.", "%help": "Show this help message.", + "%upload": "open a File Dialog, and select a file to upload to the container. only used when using containerized code execution", + "%upload folder": "same as upload command, except you can upload a folder instead of just a file.", + "%upload file": "same as upload command, except you can upload a file.", + "%download" : "Download a file or directory given the file or folder name in the container." } base_message = [ @@ -115,8 +121,18 @@ def handle_load_message(self, json_path): display_markdown_message( f"> messages json loaded from {os.path.abspath(json_path)}") -def handle_container_upload(self, *args): - +def handle_container_upload(self,type=None, *args): + def is_gui_available(): + try: + from PyQt5.QtWidgets import QApplication + app = QApplication([]) + del app + return True + except Exception as e: + print(f"An error occurred: {str(e)}") + return False + + args = list(args) if self.use_containers: try: client = docker.APIClient() @@ -128,7 +144,28 @@ def handle_container_upload(self, *args): ) display_markdown_message(f"{error_message}") return - + if len(args) == 0: + if is_gui_available(): + try: + from .components.file_dialog import FileDialog + + fd = FileDialog() + if type is not None: + path = fd.get_path(type=type) + else: + path = fd.get_path(type=None) + if path is not None: # if none, they exited + + args.append(path) + else: # We shall now exit on them out of spite + return + except ImportError as e: + Print(f"Internal import error {e}") + return + else: + Print(f" No filepath provided. please provide one. use the command %upload ") + return + for filepath in args: if os.path.exists(filepath): session_id = SESSION_IDS_BY_OBJECT.get(self) @@ -159,7 +196,7 @@ def handle_container_download(self, *args): try: client = docker.APIClient() except Exception as e: - print("[BOLD][RED]Unable to connect to the Docker Container daemon. Please ensure Docker is installed and running. ignoring command[/BOLD]") + print("[BOLD][RED]Unable to connect to the Docker Container daemon. Please ensure Docker is installed and running. ignoring command[/RED][/BOLD]") return session_id = SESSION_IDS_BY_OBJECT.get(self) diff --git a/poetry.lock b/poetry.lock index 6967cb7261..0344aa1ed9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1056,6 +1056,67 @@ files = [ [package.extras] plugins = ["importlib-metadata"] +[[package]] +name = "pyqt5" +version = "5.15.10" +description = "Python bindings for the Qt cross platform application toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "PyQt5-5.15.10-cp37-abi3-macosx_10_13_x86_64.whl", hash = "sha256:93288d62ebd47b1933d80c27f5d43c7c435307b84d480af689cef2474e87e4c8"}, + {file = "PyQt5-5.15.10-cp37-abi3-manylinux_2_17_x86_64.whl", hash = "sha256:b89478d16d4118664ff58ed609e0a804d002703c9420118de7e4e70fa1cb5486"}, + {file = "PyQt5-5.15.10-cp37-abi3-win32.whl", hash = "sha256:ff99b4f91aa8eb60510d5889faad07116d3340041916e46c07d519f7cad344e1"}, + {file = "PyQt5-5.15.10-cp37-abi3-win_amd64.whl", hash = "sha256:501355f327e9a2c38db0428e1a236d25ebcb99304cd6e668c05d1188d514adec"}, + {file = "PyQt5-5.15.10.tar.gz", hash = "sha256:d46b7804b1b10a4ff91753f8113e5b5580d2b4462f3226288e2d84497334898a"}, +] + +[package.dependencies] +PyQt5-Qt5 = ">=5.15.2" +PyQt5-sip = ">=12.13,<13" + +[[package]] +name = "pyqt5-qt5" +version = "5.15.2" +description = "The subset of a Qt installation needed by PyQt5." +optional = false +python-versions = "*" +files = [ + {file = "PyQt5_Qt5-5.15.2-py3-none-macosx_10_13_intel.whl", hash = "sha256:76980cd3d7ae87e3c7a33bfebfaee84448fd650bad6840471d6cae199b56e154"}, + {file = "PyQt5_Qt5-5.15.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:1988f364ec8caf87a6ee5d5a3a5210d57539988bf8e84714c7d60972692e2f4a"}, + {file = "PyQt5_Qt5-5.15.2-py3-none-win32.whl", hash = "sha256:9cc7a768b1921f4b982ebc00a318ccb38578e44e45316c7a4a850e953e1dd327"}, + {file = "PyQt5_Qt5-5.15.2-py3-none-win_amd64.whl", hash = "sha256:750b78e4dba6bdf1607febedc08738e318ea09e9b10aea9ff0d73073f11f6962"}, +] + +[[package]] +name = "pyqt5-sip" +version = "12.13.0" +description = "The sip module support for PyQt5" +optional = false +python-versions = ">=3.7" +files = [ + {file = "PyQt5_sip-12.13.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a7e3623b2c743753625c4650ec7696362a37fb36433b61824cf257f6d3d43cca"}, + {file = "PyQt5_sip-12.13.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6e4ac714252370ca037c7d609da92388057165edd4f94e63354f6d65c3ed9d53"}, + {file = "PyQt5_sip-12.13.0-cp310-cp310-win32.whl", hash = "sha256:d5032da3fff62da055104926ffe76fd6044c1221f8ad35bb60804bcb422fe866"}, + {file = "PyQt5_sip-12.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:9a8cdd6cb66adcbe5c941723ed1544eba05cf19b6c961851b58ccdae1c894afb"}, + {file = "PyQt5_sip-12.13.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0f85fb633a522f04e48008de49dce1ff1d947011b48885b8428838973fbca412"}, + {file = "PyQt5_sip-12.13.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ec60162e034c42fb99859206d62b83b74f987d58937b3a82bdc07b5c3d190dec"}, + {file = "PyQt5_sip-12.13.0-cp311-cp311-win32.whl", hash = "sha256:205cd449d08a2b024a468fb6100cd7ed03e946b4f49706f508944006f955ae1a"}, + {file = "PyQt5_sip-12.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:1c8371682f77852256f1f2d38c41e2e684029f43330f0635870895ab01c02f6c"}, + {file = "PyQt5_sip-12.13.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7fe3375b508c5bc657d73b9896bba8a768791f1f426c68053311b046bcebdddf"}, + {file = "PyQt5_sip-12.13.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:773731b1b5ab1a7cf5621249f2379c95e3d2905e9bd96ff3611b119586daa876"}, + {file = "PyQt5_sip-12.13.0-cp312-cp312-win32.whl", hash = "sha256:fb4a5271fa3f6bc2feb303269a837a95a6d8dd16be553aa40e530de7fb81bfdf"}, + {file = "PyQt5_sip-12.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:3a4498f3b1b15f43f5d12963accdce0fd652b0bcaae6baf8008663365827444c"}, + {file = "PyQt5_sip-12.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9b984c2620a7a7eaf049221b09ae50a345317add2624c706c7d2e9e6632a9587"}, + {file = "PyQt5_sip-12.13.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3188a06956aef86f604fb0d14421a110fad70d2a9e943dbacbfc3303f651dade"}, + {file = "PyQt5_sip-12.13.0-cp38-cp38-win32.whl", hash = "sha256:108a15f603e1886988c4b0d9d41cb74c9f9815bf05cefc843d559e8c298a10ce"}, + {file = "PyQt5_sip-12.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:db228cd737f5cbfc66a3c3e50042140cb80b30b52edc5756dbbaa2346ec73137"}, + {file = "PyQt5_sip-12.13.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5338773bbaedaa4f16a73c142fb23cc18c327be6c338813af70260b756c7bc92"}, + {file = "PyQt5_sip-12.13.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:29fa9cc964517c9fc3f94f072b9a2aeef4e7a2eda1879cb835d9e06971161cdf"}, + {file = "PyQt5_sip-12.13.0-cp39-cp39-win32.whl", hash = "sha256:96414c93f3d33963887cf562d50d88b955121fbfd73f937c8eca46643e77bf61"}, + {file = "PyQt5_sip-12.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:bbc7cd498bf19e0862097be1ad2243e824dea56726f00c11cff1b547c2d31d01"}, + {file = "PyQt5_sip-12.13.0.tar.gz", hash = "sha256:7f321daf84b9c9dbca61b80e1ef37bdaffc0e93312edae2cd7da25b953971d91"}, +] + [[package]] name = "pyreadline3" version = "3.4.1" @@ -1512,30 +1573,36 @@ python-versions = ">=3.6" files = [ {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:d92f81886165cb14d7b067ef37e142256f1c6a90a65cd156b063a43da1708cfd"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b5edda50e5e9e15e54a6a8a0070302b00c518a9d32accc2346ad6c984aacd279"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:7048c338b6c86627afb27faecf418768acb6331fc24cfa56c93e8c9780f815fa"}, {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3fcc54cb0c8b811ff66082de1680b4b14cf8a81dce0d4fbf665c2265a81e07a1"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:665f58bfd29b167039f714c6998178d27ccd83984084c286110ef26b230f259f"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"}, {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:9eb5dee2772b0f704ca2e45b1713e4e5198c18f515b52743576d196348f374d3"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"}, {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"}, @@ -2103,4 +2170,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "ccf0aaa9ae52c3b6d45011661827e845956721114202585962d4b07098edf903" +content-hash = "0f576cb3fa5a373d22ebac0ceb7510e290bf38584a9249c76d3a3d76ba79c63a" diff --git a/pyproject.toml b/pyproject.toml index 46e69a6404..c0c127218f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,8 @@ pyyaml = "^6.0.1" docker = "^6.1.3" semgrep = "^1.41.0" yaspin = "^3.0.1" +pyqt5-qt5 = "5.15.2" +pyqt5 = "5.15.10" [tool.poetry.dependencies.pyreadline3] version = "^3.4.1" markers = "sys_platform == 'win32'" From e770bd055bca7cef77339463b7b0cd42e8d74daa Mon Sep 17 00:00:00 2001 From: Nathan Hoos <128712250+unaidedelf8777@users.noreply.github.com> Date: Fri, 20 Oct 2023 21:51:39 +0000 Subject: [PATCH 07/12] Add container timeout for easier server integration of OI. controllable via env var 'OI_CONTAINER_TIMEOUT'. defaults to no timeout. Also add type safety to core/core.py --- .../container_utils/__init__.py | 38 ++++ .../container_utils/auto_remove.py | 68 +++++++ .../container_utils/build_image.py | 108 +++++++++++ .../container_utils/container_utils.py | 179 ++++++------------ .../create_code_interpreter.py | 79 ++------ .../subprocess_code_interpreter.py | 16 +- interpreter/core/core.py | 35 +++- interpreter/core/respond.py | 4 +- .../terminal_interface/magic_commands.py | 18 +- poetry.lock | 8 +- pyproject.toml | 2 +- 11 files changed, 335 insertions(+), 220 deletions(-) create mode 100644 interpreter/code_interpreters/container_utils/__init__.py create mode 100644 interpreter/code_interpreters/container_utils/auto_remove.py create mode 100644 interpreter/code_interpreters/container_utils/build_image.py diff --git a/interpreter/code_interpreters/container_utils/__init__.py b/interpreter/code_interpreters/container_utils/__init__.py new file mode 100644 index 0000000000..04e19b0576 --- /dev/null +++ b/interpreter/code_interpreters/container_utils/__init__.py @@ -0,0 +1,38 @@ +import appdirs +import shutil +import atexit +import os +import re + +import docker +from docker.tls import TLSConfig +from docker.utils import kwargs_from_env + + +def destroy(): # this fn is called when the entire program exits. registered with atexit in the __init__.py + # Prepare the Docker client + client_kwargs = kwargs_from_env() + if client_kwargs.get('tls'): + client_kwargs['tls'] = TLSConfig(**client_kwargs['tls']) + client = docker.APIClient(**client_kwargs) + + # Get all containers + all_containers = client.containers(all=True) + + # Filter containers based on the label + for container in all_containers: + labels = container['Labels'] + if labels: + session_id = labels.get('session_id') + if session_id and re.match(r'^ses-', session_id): + # Stop the container if it's running + if container['State'] == 'running': + client.stop(container=container['Id']) + # Remove the container + client.remove_container(container=container['Id']) + session_path = os.path.join(appdirs.user_data_dir("Open Interpreter"), "sessions", session_id) + if os.path.exists(session_path): + shutil.rmtree(session_path) + +atexit.register(destroy) + diff --git a/interpreter/code_interpreters/container_utils/auto_remove.py b/interpreter/code_interpreters/container_utils/auto_remove.py new file mode 100644 index 0000000000..a717151574 --- /dev/null +++ b/interpreter/code_interpreters/container_utils/auto_remove.py @@ -0,0 +1,68 @@ +import threading +import time +from functools import wraps + +def access_aware(cls): + class AccessAwareWrapper: + def __init__(self, wrapped, auto_remove_timeout, close_callback=None): + self._wrapped = wrapped + self._last_accessed = time.time() + self._auto_remove = auto_remove_timeout is not None + self._timeout = auto_remove_timeout + self.close_callback = close_callback # Store the callback + if self._auto_remove: + self._monitor_thread = threading.Thread(target=self._monitor_object, daemon=True) + self._monitor_thread.start() + + def _monitor_object(self): + while True: + time.sleep(1) # Check every second + if self._auto_remove and self.check_timeout(): + # If a close_callback is defined, call it + if self.close_callback: + try: + self.close_callback() # Call the callback + except Exception as e: + # Log or handle the exception as required + return f"An error occurred during callback: {e}" + + try: + self._wrapped.stop() + except Exception: + continue # why care? we are removing it anyway + + # If the wrapped object has a __del__ method, call it + if self._wrapped and hasattr(self._wrapped, '__del__'): + try: + self._wrapped.__del__() + except Exception as e: + # Log or handle the exception as required + return f"An error occurred during deletion: {e}" + + # Remove the strong reference to the wrapped object. this makes it go bye bye. + self._wrapped = None + break + + def touch(self): + self._last_accessed = time.time() + + def check_timeout(self): + return time.time() - self._last_accessed > self._timeout + + def __getattr__(self, attr): + if self._wrapped is None: + raise ValueError("Object has been removed due to inactivity.") + self.touch() # Update last accessed time + return getattr(self._wrapped, attr) # Use the actual object here + + def __del__(self): + if self._auto_remove: + self._monitor_thread.join() # Ensure the monitoring thread is cleaned up + + @wraps(cls) + def wrapper(*args, **kwargs): + auto_remove_timeout = kwargs.pop('auto_remove_timeout', None) # Extract the auto_remove_timeout argument + close_callback = kwargs.pop('close_callback', None) # Extract the close_callback argument + obj = cls(*args, **kwargs) # Create an instance of the original class + return AccessAwareWrapper(obj, auto_remove_timeout, close_callback) # Wrap it + return wrapper diff --git a/interpreter/code_interpreters/container_utils/build_image.py b/interpreter/code_interpreters/container_utils/build_image.py new file mode 100644 index 0000000000..12d95286d6 --- /dev/null +++ b/interpreter/code_interpreters/container_utils/build_image.py @@ -0,0 +1,108 @@ +import os +import json +import hashlib +import subprocess +from docker import DockerClient +from docker.errors import DockerException +from rich import print as Print + +def get_files_hash(*file_paths): + """Return the SHA256 hash of multiple files.""" + hasher = hashlib.sha256() + for file_path in file_paths: + with open(file_path, "rb") as f: + while chunk := f.read(4096): + hasher.update(chunk) + return hasher.hexdigest() + + +def build_docker_images( + dockerfile_dir = os.path.join(os.path.abspath(os.path.dirname(os.path.dirname(__file__))), "dockerfiles") +, +): + """ + Builds a Docker image for the Open Interpreter runtime container if needed. + + Args: + dockerfile_dir (str): The directory containing the Dockerfile and requirements.txt files. + + Returns: + None + """ + try: + client = DockerClient.from_env() + except DockerException: + Print("[bold red]ERROR[/bold red]: Could not connect to Docker daemon. Is Docker Engine installed and running?") + Print( + "\nFor information on Docker installation, visit: https://docs.docker.com/engine/install/ and follow the instructions for your system." + ) + return + + image_name = "openinterpreter-runtime-container" + hash_file_path = os.path.join(dockerfile_dir, "hash.json") + + dockerfile_name = "Dockerfile" + requirements_name = "requirements.txt" + dockerfile_path = os.path.join(dockerfile_dir, dockerfile_name) + requirements_path = os.path.join(dockerfile_dir, requirements_name) + + if not os.path.exists(dockerfile_path) or not os.path.exists(requirements_path): + Print("ERROR: Dockerfile or requirements.txt not found. Did you delete or rename them?") + raise RuntimeError( + "No container Dockerfiles or requirements.txt found. Make sure they are in the dockerfiles/ subdir of the module." + ) + + current_hash = get_files_hash(dockerfile_path, requirements_path) + + stored_hashes = {} + if os.path.exists(hash_file_path): + with open(hash_file_path, "rb") as f: + stored_hashes = json.load(f) + + original_hash = stored_hashes.get("original_hash") + previous_hash = stored_hashes.get("last_hash") + + if current_hash == original_hash: + images = client.images.list(name=image_name, all=True) + if not images: + Print("Downloading default image from Docker Hub, please wait...") + + subprocess.run(["docker", "pull", "unaidedelf/openinterpreter-runtime-container:latest"]) + subprocess.run(["docker", "tag", "unaidedelf/openinterpreter-runtime-container:latest", image_name ], + check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + elif current_hash != previous_hash: + Print("Dockerfile or requirements.txt has changed. Building container...") + + try: + # Run the subprocess without capturing stdout and stderr + # This will allow Docker's output to be printed to the console in real-time + subprocess.run( + [ + "docker", + "build", + "-t", + f"{image_name}:latest", + dockerfile_dir, + ], + check=True, # This will raise a CalledProcessError if the command returns a non-zero exit code + text=True, + ) + + # Update the stored current hash + stored_hashes["last_hash"] = current_hash + with open(hash_file_path, "w") as f: + json.dump(stored_hashes, f) + + except subprocess.CalledProcessError: + # Suppress Docker's error messages and display your own error message + Print("Docker Build Error: Building Docker image failed. Please review the error message above and resolve the issue.") + + except FileNotFoundError: + Print("ERROR: The 'docker' command was not found on your system.") + Print( + "Please ensure Docker Engine is installed and the 'docker' command is available in your PATH." + ) + Print( + "For information on Docker installation, visit: https://docs.docker.com/engine/install/" + ) + Print("If Docker is installed, try starting a new terminal session.") diff --git a/interpreter/code_interpreters/container_utils/container_utils.py b/interpreter/code_interpreters/container_utils/container_utils.py index 8175bf61c5..da9c23a9f5 100644 --- a/interpreter/code_interpreters/container_utils/container_utils.py +++ b/interpreter/code_interpreters/container_utils/container_utils.py @@ -1,127 +1,21 @@ -# Standard library imports -import atexit -import hashlib -import json +"""wrapper classes of the Docker python sdk which allows interaction like its a subprocess object.""" import os import re import select -import shutil import struct -import subprocess import threading import time -# Third-party imports +# Third-party imports +import appdirs import docker -from docker import DockerClient -from docker.errors import DockerException from docker.utils import kwargs_from_env from docker.tls import TLSConfig from rich import print as Print - -def get_files_hash(*file_paths): - """Return the SHA256 hash of multiple files.""" - hasher = hashlib.sha256() - for file_path in file_paths: - with open(file_path, "rb") as f: - while chunk := f.read(4096): - hasher.update(chunk) - return hasher.hexdigest() - - -def build_docker_images( - dockerfile_dir = os.path.join(os.path.abspath(os.path.dirname(os.path.dirname(__file__))), "dockerfiles") -, -): - """ - Builds a Docker image for the Open Interpreter runtime container if needed. - - Args: - dockerfile_dir (str): The directory containing the Dockerfile and requirements.txt files. - - Returns: - None - """ - try: - client = DockerClient.from_env() - except DockerException: - Print("[bold red]ERROR[/bold red]: Could not connect to Docker daemon. Is Docker Engine installed and running?") - Print( - "\nFor information on Docker installation, visit: https://docs.docker.com/engine/install/ and follow the instructions for your system." - ) - return - - image_name = "openinterpreter-runtime-container" - hash_file_path = os.path.join(dockerfile_dir, "hash.json") - - dockerfile_name = "Dockerfile" - requirements_name = "requirements.txt" - dockerfile_path = os.path.join(dockerfile_dir, dockerfile_name) - requirements_path = os.path.join(dockerfile_dir, requirements_name) - - if not os.path.exists(dockerfile_path) or not os.path.exists(requirements_path): - Print("ERROR: Dockerfile or requirements.txt not found. Did you delete or rename them?") - raise RuntimeError( - "No container Dockerfiles or requirements.txt found. Make sure they are in the dockerfiles/ subdir of the module." - ) - - current_hash = get_files_hash(dockerfile_path, requirements_path) - - stored_hashes = {} - if os.path.exists(hash_file_path): - with open(hash_file_path, "rb") as f: - stored_hashes = json.load(f) - - original_hash = stored_hashes.get("original_hash") - previous_hash = stored_hashes.get("last_hash") - - if current_hash == original_hash: - images = client.images.list(name=image_name, all=True) - if not images: - Print("Downloading default image from Docker Hub, please wait...") - - subprocess.run(["docker", "pull", "unaidedelf/openinterpreter-runtime-container:latest"]) - subprocess.run(["docker", "tag", "unaidedelf/openinterpreter-runtime-container:latest", image_name ], - check=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - elif current_hash != previous_hash: - Print("Dockerfile or requirements.txt has changed. Building container...") - - try: - # Run the subprocess without capturing stdout and stderr - # This will allow Docker's output to be printed to the console in real-time - subprocess.run( - [ - "docker", - "build", - "-t", - f"{image_name}:latest", - dockerfile_dir, - ], - check=True, # This will raise a CalledProcessError if the command returns a non-zero exit code - text=True, - ) - - # Update the stored current hash - stored_hashes["last_hash"] = current_hash - with open(hash_file_path, "w") as f: - json.dump(stored_hashes, f) - - except subprocess.CalledProcessError: - # Suppress Docker's error messages and display your own error message - Print("Docker Build Error: Building Docker image failed. Please review the error message above and resolve the issue.") - - except FileNotFoundError: - Print("ERROR: The 'docker' command was not found on your system.") - Print( - "Please ensure Docker Engine is installed and the 'docker' command is available in your PATH." - ) - Print( - "For information on Docker installation, visit: https://docs.docker.com/engine/install/" - ) - Print("If Docker is installed, try starting a new terminal session.") - +# Modules +from .auto_remove import access_aware class DockerStreamWrapper: def __init__(self, exec_id, sock): @@ -222,26 +116,41 @@ def terminate(self): os.close(self._stderr_w) - +# The `@access_aware` decorator enables automatic container cleanup based on activity monitoring. +# It functions under the following conditions: +# 1. The container is subject to removal when it remains unaccessed beyond the duration specified by `auto_remove_timeout`. +# 2. This feature necessitates a non-None argument; absence of a valid argument renders this functionality inactive. +# 3. During interactive sessions, the auto-removal feature is disabled to prevent unintended interruptions. +# 4. The "INTERPRETER_CONTAINER_TIMEOUT" environment variable allows customization of the timeout period. +# It accepts an integer value representing the desired timeout in seconds. +# 5. In the event of an unexpected program termination, the container is still ensured to be removed, +# courtesy of the integration with the `atexit` module, safeguarding system resources from being unnecessarily occupied. +@access_aware class DockerProcWrapper: - def __init__(self, command, session_path): + def __init__(self, command, session_id, auto_remove_timeout=None, close_callback=None, mount=False): ## Mounting isnt implemented in main code, but i did it here prior so we just hide it behind a flag for now. + + # Docker stuff client_kwargs = kwargs_from_env() if client_kwargs.get('tls'): client_kwargs['tls'] = TLSConfig(**client_kwargs['tls']) self.client = docker.APIClient(**client_kwargs) self.image_name = "openinterpreter-runtime-container:latest" - self.session_path = session_path self.exec_id = None self.exec_socket = None - atexit.register(atexit_destroy, self) - os.makedirs(self.session_path, exist_ok=True) + # close callback + self.close_callback = close_callback + + # session info + self.session_id = session_id + self.session_path = os.path.join(appdirs.user_data_dir("Open Interpreter"), "sessions", session_id) + self.mount = mount # Initialize container self.init_container() - self.init_exec_instance(command) + self.init_exec_instance() self.wrapper = DockerStreamWrapper(self.exec_id, self.exec_socket) @@ -255,7 +164,7 @@ def init_container(self): self.container = None try: containers = self.client.containers( - filters={"label": f"session_id={os.path.basename(self.session_path)}"}, all=True) + filters={"label": f"session_id={self.session_id}"}, all=True) if containers: self.container = containers[0] container_id = self.container.get('Id') @@ -264,9 +173,15 @@ def init_container(self): self.client.start(container=container_id) self.wait_for_container_start(container_id) else: - host_config = self.client.create_host_config( - binds={self.session_path: {'bind': '/mnt/data', 'mode': 'rw'}} - ) + if self.mount: + + os.makedirs(self.session_path, exist_ok=True) + + host_config = self.client.create_host_config( + binds={self.session_path: {'bind': '/mnt/data', 'mode': 'rw'}} + ) + else: + host_config = None self.container = self.client.create_container( image=self.image_name, @@ -285,7 +200,7 @@ def init_container(self): except Exception as e: print(f"An error occurred: {e}") - def init_exec_instance(self, command): + def init_exec_instance(self): if self.container: container_info = self.client.inspect_container(self.container.get('Id')) @@ -320,9 +235,21 @@ def wait_for_container_start(self, container_id, timeout=30): raise TimeoutError( "Container did not start within the specified timeout.") time.sleep(1) + + def terminate(self): + self.wrapper.terminate() + self.client.stop(self.container.get("Id")) + self.client.remove_container(self.container.get("Id")) + + def stop(self): + self.wrapper.terminate() + self.client.stop(self.container.get("Id"), 30) + + + def __del__(self): + self.terminate() + + + -def atexit_destroy(self): - shutil.rmtree(self.session_path) - self.client.stop(self.container.get("Id")) - self.client.remove_container(self.container.get("Id")) diff --git a/interpreter/code_interpreters/create_code_interpreter.py b/interpreter/code_interpreters/create_code_interpreter.py index 69eb9d9034..7df43d5434 100644 --- a/interpreter/code_interpreters/create_code_interpreter.py +++ b/interpreter/code_interpreters/create_code_interpreter.py @@ -1,28 +1,17 @@ -import inspect import os import uuid -import weakref +from functools import partial import appdirs from .language_map import language_map - -# Global dictionary to store the session IDs by the weak reference of the calling objects -SESSION_IDS_BY_OBJECT = weakref.WeakKeyDictionary() - - -def create_code_interpreter(language, use_containers=False): +def create_code_interpreter(interpreter, language, use_containers=False): """ Creates and returns a CodeInterpreter instance for the specified language. - The function uses weak references to associate session IDs with calling Interpreter objects, - ensuring that the objects can be garbage collected when they are no longer in use. The function - also uses the inspect module to traverse the call stack and identify the calling Interpreter - object. This allows the function to associate a unique session ID with each Interpreter object, - even when the object is passed as a parameter through multiple function calls. - Parameters: + - interpreter (Interpreter): The calling Interpreter object. - language (str): The programming language for which the CodeInterpreter is to be created. - use_containers (bool): A flag indicating whether to use containers. If True, a session ID is generated and associated with the calling Interpreter object. @@ -32,62 +21,26 @@ def create_code_interpreter(language, use_containers=False): configured with the session ID if use_containers is True. Raises: - - RuntimeError: If unable to access the current frame. - ValueError: If the specified language is unknown or unsupported. """ - from ..core.core import Interpreter # Case in-sensitive language = language.lower() - caller_object = None - - if use_containers: - # Get the current frame - current_frame = inspect.currentframe() - - if current_frame is None: - raise RuntimeError("Failed to access the current frame") - - # Initialize frame count - frame_count = 0 - - # Keep going back through the stack frames with a limit of 5 frames back to - # prevent seeing other instances other than the calling one. - while current_frame.f_back and frame_count < 5: - current_frame = current_frame.f_back - frame_count += 1 - - # Iterate over local variables in the current frame - for var_value in current_frame.f_locals.values(): - if isinstance(var_value, Interpreter): - # Found an instance of Interpreter - caller_object = var_value - break - - if caller_object: - break - - if caller_object and caller_object not in SESSION_IDS_BY_OBJECT.keys(): - session_id = f"ses-{str(uuid.uuid4())}" - SESSION_IDS_BY_OBJECT[caller_object] = session_id + if language not in language_map: + raise ValueError(f"Unknown or unsupported language: {language}") - try: - # Retrieve the specific CodeInterpreter class based on the language - CodeInterpreter = language_map[language] + CodeInterpreter = language_map[language] - # Retrieve the session ID for the current calling object, if available - session_id = SESSION_IDS_BY_OBJECT.get(caller_object, None) if caller_object else None + if not use_containers: + return CodeInterpreter() - if not use_containers or session_id is None: - return CodeInterpreter() + if interpreter.session_id: + session_id = interpreter.session_id + else: + session_id = f"ses-{str(uuid.uuid4())}" + interpreter.session_id = session_id + + timeout = os.getenv("OI_CONTAINER_TIMEOUT", None) - session_path = os.path.join( - appdirs.user_data_dir("Open Interpreter"), "sessions", session_id - ) - if not os.path.exists(session_path): - os.makedirs(session_path) - return CodeInterpreter(session_id=session_id, use_docker=use_containers) - except KeyError as exc: - raise ValueError(f"Unknown or unsupported language: {language}. \n ") from exc - \ No newline at end of file + return CodeInterpreter(session_id=session_id, use_containers=use_containers, close_callback=partial(interpreter.container_callback, language=language), auto_remove_timeout=timeout) diff --git a/interpreter/code_interpreters/subprocess_code_interpreter.py b/interpreter/code_interpreters/subprocess_code_interpreter.py index 54e02886b7..7435e9097d 100644 --- a/interpreter/code_interpreters/subprocess_code_interpreter.py +++ b/interpreter/code_interpreters/subprocess_code_interpreter.py @@ -4,8 +4,8 @@ import threading import time import traceback - import appdirs + from .base_code_interpreter import BaseCodeInterpreter from .container_utils.container_utils import DockerProcWrapper @@ -24,15 +24,16 @@ class SubprocessCodeInterpreter(BaseCodeInterpreter): - session_id (str): The ID of the Docker container session, if `contain` is True. """ - def __init__(self, **kwargs): + def __init__(self, use_containers=False, **container_args): + self.container_args = container_args self.start_cmd = "" self.process = None self.debug_mode = False self.output_queue = queue.Queue() self.done = threading.Event() - self.use_containers = kwargs.get("use_docker", False) + self.use_containers = use_containers if self.use_containers: - self.session_id = kwargs.get("session_id") + self.session_id = container_args.get("session_id") @staticmethod def detect_active_line(line): @@ -73,10 +74,9 @@ def start_process(self): if self.use_containers: self.process = DockerProcWrapper( - self.start_cmd, # splitting cmd causes problems with docker - session_path=os.path.join( - appdirs.user_data_dir("Open Interpreter"), "sessions", self.session_id - ),) + command=self.start_cmd, + **self.container_args + ) else: self.process = subprocess.Popen( self.start_cmd.split(), diff --git a/interpreter/core/core.py b/interpreter/core/core.py index 5e8ac71bdd..1cfd9a5bb3 100644 --- a/interpreter/core/core.py +++ b/interpreter/core/core.py @@ -7,6 +7,14 @@ import appdirs import os from datetime import datetime +from typing import (Optional, + Union, + Iterator, + Any, + Callable, + List, + Dict + ) from ..cli.cli import cli from ..utils.get_config import get_config, user_config_path @@ -19,8 +27,11 @@ from ..rag.get_relevant_procedures_string import get_relevant_procedures_string from ..utils.check_for_update import check_for_update from ..utils.display_markdown_message import display_markdown_message -from ..code_interpreters.container_utils.container_utils import build_docker_images +from ..code_interpreters.container_utils.build_image import build_docker_images from ..utils.embed import embed_function +from ..terminal_interface.magic_commands import handle_magic_command + + class Interpreter: @@ -66,6 +77,7 @@ def __init__(self): # Container options self.use_containers = False + self.session_id = None # Load config defaults self.extend_config(self.config_file) @@ -81,14 +93,14 @@ def __init__(self): - def extend_config(self, config_path): + def extend_config(self, config_path: str) -> None: if self.debug_mode: print(f'Extending configuration from `{config_path}`') config = get_config(config_path) self.__dict__.update(config) - def chat(self, message=None, display=True, stream=False): + def chat(self, message: Optional[str] = None, display: bool = True, stream: bool = False) -> Union[List[Dict[str, Any]], None]: if self.use_containers: build_docker_images() # Build images if needed. does nothing if already built @@ -102,7 +114,7 @@ def chat(self, message=None, display=True, stream=False): return self.messages - def _streaming_chat(self, message=None, display=True): + def _streaming_chat(self, message: Optional[str] = None, display: bool = True) -> Iterator: # If we have a display, # we can validate our LLM settings w/ the user first @@ -149,12 +161,12 @@ def _streaming_chat(self, message=None, display=True): json.dump(self.messages, f) return - raise Exception("`interpreter.chat()` requires a display. Set `display=True` or pass a message into `interpreter.chat(message)`.") + raise ValueError("`interpreter.chat()` requires a display. Set `interpreter.display=True` or pass a message into `interpreter.chat(message)`.") - def _respond(self): + def _respond(self) -> Iterator: yield from respond(self) - def reset(self): + def reset(self) -> None: for code_interpreter in self._code_interpreters.values(): code_interpreter.terminate() self._code_interpreters = {} @@ -165,10 +177,13 @@ def reset(self): self.__init__() - # These functions are worth exposing to developers # I wish we could just dynamically expose all of our functions to devs... - def generate_system_message(self): + def generate_system_message(self) -> str: return generate_system_message(self) - def get_relevant_procedures_string(self): + + def get_relevant_procedures_string(self) -> str: return get_relevant_procedures_string(self) + + def container_callback(self, language: str) -> None: + self._code_interpreters.pop(language) diff --git a/interpreter/core/respond.py b/interpreter/core/respond.py index bd128a9e98..786f141ca9 100644 --- a/interpreter/core/respond.py +++ b/interpreter/core/respond.py @@ -110,9 +110,9 @@ def respond(interpreter): language = interpreter.messages[-1]["language"] if language not in interpreter._code_interpreters: if interpreter.use_containers: - interpreter._code_interpreters[language] = create_code_interpreter(language, use_containers=True) + interpreter._code_interpreters[language] = create_code_interpreter(interpreter, language, use_containers=True) else: - interpreter._code_interpreters[language] = create_code_interpreter(language) + interpreter._code_interpreters[language] = create_code_interpreter(interpreter, language, use_containers=False) code_interpreter = interpreter._code_interpreters[language] diff --git a/interpreter/terminal_interface/magic_commands.py b/interpreter/terminal_interface/magic_commands.py index 4cfb0b160c..5973659f7a 100644 --- a/interpreter/terminal_interface/magic_commands.py +++ b/interpreter/terminal_interface/magic_commands.py @@ -8,7 +8,6 @@ from ..utils.display_markdown_message import display_markdown_message from ..code_interpreters.container_utils.download_file import download_file_from_container from ..code_interpreters.container_utils.upload_file import copy_file_to_container -from ..code_interpreters.create_code_interpreter import SESSION_IDS_BY_OBJECT from rich import print as Print @@ -164,14 +163,17 @@ def is_gui_available(): return except ImportError as e: Print(f"Internal import error {e}") - return + return else: - Print(f" No filepath provided. please provide one. use the command %upload ") + Print(f"No GUI available for your system.\n please provide a filepath manually. use the command %upload ") return for filepath in args: if os.path.exists(filepath): - session_id = SESSION_IDS_BY_OBJECT.get(self) + session_id = self.session_id + if session_id is None: + Print("[BOLD] [RED] No session found. Please run any code to start one. [/RED] [/BOLD]") + return containers = client.containers(filters={"label": f"session_id={session_id}"}) if containers: container_id = containers[0]['Id'] @@ -179,7 +181,7 @@ def is_gui_available(): copy_file_to_container( container_id=container_id, local_path=filepath, path_in_container=f"/mnt/data/{os.path.basename(filepath)}" ) - success_message = f"File [{filepath}](#) successfully uploaded to container in dir `/mnt/data`." + success_message = f"[{filepath}](#) successfully uploaded to container in dir `/mnt/data`." display_markdown_message(success_message) else: no_container_message = ( @@ -202,7 +204,7 @@ def handle_container_download(self, *args): print("[BOLD][RED]Unable to connect to the Docker Container daemon. Please ensure Docker is installed and running. ignoring command[/RED][/BOLD]") return - session_id = SESSION_IDS_BY_OBJECT.get(self) + session_id = self.session_id if session_id is None: print("No session found. Please run any code to start one.") return @@ -219,6 +221,10 @@ def handle_container_download(self, *args): local_dir = appdirs.user_data_dir(appname="Open Interpreter") for file_path_in_container in args: + + if not file_path_in_container.startswith("/mnt/data"): + file_path_in_container = os.path.join("/mnt/data", file_path_in_container) + # Construct the local file path local_file_path = os.path.join(local_dir, os.path.basename(file_path_in_container)) diff --git a/poetry.lock b/poetry.lock index bb524a9bec..0f2c302445 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1135,13 +1135,13 @@ referencing = ">=0.28.0" [[package]] name = "litellm" -version = "0.7.10" +version = "0.8.3" description = "Library to easily interface with LLM API providers" optional = false python-versions = ">=3.8,<4.0" files = [ - {file = "litellm-0.7.10-py3-none-any.whl", hash = "sha256:ba0793ff372d5053b767cde167b06165a5d1e6e15ebbe4a226e1914f5b8b9472"}, - {file = "litellm-0.7.10.tar.gz", hash = "sha256:6714099b914d5d8f8843d5ff7801abcde7a5c8bf1e96d3a3c65dc6745bfd8b2d"}, + {file = "litellm-0.8.3-py3-none-any.whl", hash = "sha256:fcc62ad3f82b3bf725334df2279d10d9ed87d1a28012073ae662f856652fb6b8"}, + {file = "litellm-0.8.3.tar.gz", hash = "sha256:24ebd9a2bb16e0b2563b16cef7a9623fadb66d4584928e30a001569d5602e43a"}, ] [package.dependencies] @@ -3233,4 +3233,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "3d829bf7cda7cc0485f83fc26bc1f7ef9863a01b2a5cc7e90b255a76228bcdd8" +content-hash = "efc0fdfcd547181cad96b426135f90c647c7691b736abf5219bcacdc242a82f9" diff --git a/pyproject.toml b/pyproject.toml index 411ff252bc..bad0697572 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ python-dotenv = "^1.0.0" inquirer = "^3.1.3" wget = "^3.2" huggingface-hub = "^0.17.3" -litellm = "^0.7.5" +litellm = "0.8.3" pyyaml = "^6.0.1" docker = "^6.1.3" semgrep = "^1.41.0" From 3907b16b3472c8b95ac0366c22269d91b089aa7c Mon Sep 17 00:00:00 2001 From: Nathan Hoos <128712250+unaidedelf8777@users.noreply.github.com> Date: Fri, 20 Oct 2023 22:04:44 +0000 Subject: [PATCH 08/12] Update things, resolve merge conflicts. --- poetry.lock | 439 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 427 insertions(+), 12 deletions(-) diff --git a/poetry.lock b/poetry.lock index c043d50add..d4d50a06d3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -277,6 +277,28 @@ jinxed = {version = ">=1.1.0", markers = "platform_system == \"Windows\""} six = ">=1.9.0" wcwidth = ">=0.1.4" +[[package]] +name = "boltons" +version = "21.0.0" +description = "When they're not builtins, they're boltons." +optional = false +python-versions = "*" +files = [ + {file = "boltons-21.0.0-py2.py3-none-any.whl", hash = "sha256:b9bb7b58b2b420bbe11a6025fdef6d3e5edc9f76a42fb467afe7ca212ef9948b"}, + {file = "boltons-21.0.0.tar.gz", hash = "sha256:65e70a79a731a7fe6e98592ecfb5ccf2115873d01dbc576079874629e5c90f13"}, +] + +[[package]] +name = "bracex" +version = "2.4" +description = "Bash style brace expander." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bracex-2.4-py3-none-any.whl", hash = "sha256:efdc71eff95eaff5e0f8cfebe7d01adf2c8637c8c92edaf63ef348c241a82418"}, + {file = "bracex-2.4.tar.gz", hash = "sha256:a27eaf1df42cf561fed58b7a8f3fdf129d1ea16a81e1fadd1d17989bc6384beb"}, +] + [[package]] name = "certifi" version = "2023.7.22" @@ -479,6 +501,25 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} +[[package]] +name = "click-option-group" +version = "0.5.6" +description = "Option groups missing in Click" +optional = false +python-versions = ">=3.6,<4" +files = [ + {file = "click-option-group-0.5.6.tar.gz", hash = "sha256:97d06703873518cc5038509443742b25069a3c7562d1ea72ff08bfadde1ce777"}, + {file = "click_option_group-0.5.6-py3-none-any.whl", hash = "sha256:38a26d963ee3ad93332ddf782f9259c5bdfe405e73408d943ef5e7d0c3767ec7"}, +] + +[package.dependencies] +Click = ">=7.0,<9" + +[package.extras] +docs = ["Pallets-Sphinx-Themes", "m2r2", "sphinx"] +tests = ["pytest"] +tests-cov = ["coverage", "coveralls", "pytest", "pytest-cov"] + [[package]] name = "colorama" version = "0.4.6" @@ -553,6 +594,20 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "face" +version = "22.0.0" +description = "A command-line application framework (and CLI parser). Friendly for users, full-featured for developers." +optional = false +python-versions = "*" +files = [ + {file = "face-22.0.0-py3-none-any.whl", hash = "sha256:344fe31562d0f6f444a45982418f3793d4b14f9abb98ccca1509d22e0a3e7e35"}, + {file = "face-22.0.0.tar.gz", hash = "sha256:d5d692f90bc8f5987b636e47e36384b9bbda499aaf0a77aa0b0bbe834c76923d"}, +] + +[package.dependencies] +boltons = ">=20.0.0" + [[package]] name = "fastapi" version = "0.104.0" @@ -721,13 +776,13 @@ gitpython = "*" [[package]] name = "gitdb" -version = "4.0.10" +version = "4.0.11" description = "Git Object Database" optional = false python-versions = ">=3.7" files = [ - {file = "gitdb-4.0.10-py3-none-any.whl", hash = "sha256:c286cf298426064079ed96a9e4a9d39e7f3e9bf15ba60701e95f5492f28415c7"}, - {file = "gitdb-4.0.10.tar.gz", hash = "sha256:6eb990b69df4e15bad899ea868dc46572c3f75339735663b81de79b06f17eb9a"}, + {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, + {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, ] [package.dependencies] @@ -750,6 +805,25 @@ gitdb = ">=4.0.1,<5" [package.extras] test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest", "pytest-cov", "pytest-instafail", "pytest-subtests", "pytest-sugar"] +[[package]] +name = "glom" +version = "22.1.0" +description = "A declarative object transformer and formatter, for conglomerating nested data." +optional = false +python-versions = "*" +files = [ + {file = "glom-22.1.0-py2.py3-none-any.whl", hash = "sha256:5339da206bf3532e01a83a35aca202960ea885156986d190574b779598e9e772"}, + {file = "glom-22.1.0.tar.gz", hash = "sha256:1510c6587a8f9c64a246641b70033cbc5ebde99f02ad245693678038e821aeb5"}, +] + +[package.dependencies] +attrs = "*" +boltons = ">=19.3.0" +face = ">=20.1.0" + +[package.extras] +yaml = ["PyYAML"] + [[package]] name = "grpcio" version = "1.59.0" @@ -1025,6 +1099,41 @@ files = [ [package.dependencies] ansicon = {version = "*", markers = "platform_system == \"Windows\""} +[[package]] +name = "jsonschema" +version = "4.19.1" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.19.1-py3-none-any.whl", hash = "sha256:cd5f1f9ed9444e554b38ba003af06c0a8c2868131e56bfbef0550fb450c0330e"}, + {file = "jsonschema-4.19.1.tar.gz", hash = "sha256:ec84cc37cfa703ef7cd4928db24f9cb31428a5d0fa77747b8b51a847458e0bbf"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "jsonschema-specifications" +version = "2023.7.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.7.1-py3-none-any.whl", hash = "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1"}, + {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"}, +] + +[package.dependencies] +referencing = ">=0.28.0" + [[package]] name = "litellm" version = "0.8.6" @@ -1938,6 +2047,21 @@ files = [ [package.dependencies] setuptools = ">=41.0" +[[package]] +name = "referencing" +version = "0.30.2" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.30.2-py3-none-any.whl", hash = "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"}, + {file = "referencing-0.30.2.tar.gz", hash = "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + [[package]] name = "regex" version = "2023.10.3" @@ -2074,6 +2198,214 @@ pygments = ">=2.13.0,<3.0.0" [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] +[[package]] +name = "rpds-py" +version = "0.10.6" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.10.6-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:6bdc11f9623870d75692cc33c59804b5a18d7b8a4b79ef0b00b773a27397d1f6"}, + {file = "rpds_py-0.10.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:26857f0f44f0e791f4a266595a7a09d21f6b589580ee0585f330aaccccb836e3"}, + {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7f5e15c953ace2e8dde9824bdab4bec50adb91a5663df08d7d994240ae6fa31"}, + {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:61fa268da6e2e1cd350739bb61011121fa550aa2545762e3dc02ea177ee4de35"}, + {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c48f3fbc3e92c7dd6681a258d22f23adc2eb183c8cb1557d2fcc5a024e80b094"}, + {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0503c5b681566e8b722fe8c4c47cce5c7a51f6935d5c7012c4aefe952a35eed"}, + {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:734c41f9f57cc28658d98270d3436dba65bed0cfc730d115b290e970150c540d"}, + {file = "rpds_py-0.10.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a5d7ed104d158c0042a6a73799cf0eb576dfd5fc1ace9c47996e52320c37cb7c"}, + {file = "rpds_py-0.10.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e3df0bc35e746cce42579826b89579d13fd27c3d5319a6afca9893a9b784ff1b"}, + {file = "rpds_py-0.10.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:73e0a78a9b843b8c2128028864901f55190401ba38aae685350cf69b98d9f7c9"}, + {file = "rpds_py-0.10.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5ed505ec6305abd2c2c9586a7b04fbd4baf42d4d684a9c12ec6110deefe2a063"}, + {file = "rpds_py-0.10.6-cp310-none-win32.whl", hash = "sha256:d97dd44683802000277bbf142fd9f6b271746b4846d0acaf0cefa6b2eaf2a7ad"}, + {file = "rpds_py-0.10.6-cp310-none-win_amd64.whl", hash = "sha256:b455492cab07107bfe8711e20cd920cc96003e0da3c1f91297235b1603d2aca7"}, + {file = "rpds_py-0.10.6-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:e8cdd52744f680346ff8c1ecdad5f4d11117e1724d4f4e1874f3a67598821069"}, + {file = "rpds_py-0.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:66414dafe4326bca200e165c2e789976cab2587ec71beb80f59f4796b786a238"}, + {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc435d059f926fdc5b05822b1be4ff2a3a040f3ae0a7bbbe672babb468944722"}, + {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8e7f2219cb72474571974d29a191714d822e58be1eb171f229732bc6fdedf0ac"}, + {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3953c6926a63f8ea5514644b7afb42659b505ece4183fdaaa8f61d978754349e"}, + {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2bb2e4826be25e72013916eecd3d30f66fd076110de09f0e750163b416500721"}, + {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bf347b495b197992efc81a7408e9a83b931b2f056728529956a4d0858608b80"}, + {file = "rpds_py-0.10.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:102eac53bb0bf0f9a275b438e6cf6904904908562a1463a6fc3323cf47d7a532"}, + {file = "rpds_py-0.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40f93086eef235623aa14dbddef1b9fb4b22b99454cb39a8d2e04c994fb9868c"}, + {file = "rpds_py-0.10.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e22260a4741a0e7a206e175232867b48a16e0401ef5bce3c67ca5b9705879066"}, + {file = "rpds_py-0.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f4e56860a5af16a0fcfa070a0a20c42fbb2012eed1eb5ceeddcc7f8079214281"}, + {file = "rpds_py-0.10.6-cp311-none-win32.whl", hash = "sha256:0774a46b38e70fdde0c6ded8d6d73115a7c39d7839a164cc833f170bbf539116"}, + {file = "rpds_py-0.10.6-cp311-none-win_amd64.whl", hash = "sha256:4a5ee600477b918ab345209eddafde9f91c0acd931f3776369585a1c55b04c57"}, + {file = "rpds_py-0.10.6-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:5ee97c683eaface61d38ec9a489e353d36444cdebb128a27fe486a291647aff6"}, + {file = "rpds_py-0.10.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0713631d6e2d6c316c2f7b9320a34f44abb644fc487b77161d1724d883662e31"}, + {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5a53f5998b4bbff1cb2e967e66ab2addc67326a274567697379dd1e326bded7"}, + {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a555ae3d2e61118a9d3e549737bb4a56ff0cec88a22bd1dfcad5b4e04759175"}, + {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:945eb4b6bb8144909b203a88a35e0a03d22b57aefb06c9b26c6e16d72e5eb0f0"}, + {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:52c215eb46307c25f9fd2771cac8135d14b11a92ae48d17968eda5aa9aaf5071"}, + {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1b3cd23d905589cb205710b3988fc8f46d4a198cf12862887b09d7aaa6bf9b9"}, + {file = "rpds_py-0.10.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64ccc28683666672d7c166ed465c09cee36e306c156e787acef3c0c62f90da5a"}, + {file = "rpds_py-0.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:516a611a2de12fbea70c78271e558f725c660ce38e0006f75139ba337d56b1f6"}, + {file = "rpds_py-0.10.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9ff93d3aedef11f9c4540cf347f8bb135dd9323a2fc705633d83210d464c579d"}, + {file = "rpds_py-0.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d858532212f0650be12b6042ff4378dc2efbb7792a286bee4489eaa7ba010586"}, + {file = "rpds_py-0.10.6-cp312-none-win32.whl", hash = "sha256:3c4eff26eddac49d52697a98ea01b0246e44ca82ab09354e94aae8823e8bda02"}, + {file = "rpds_py-0.10.6-cp312-none-win_amd64.whl", hash = "sha256:150eec465dbc9cbca943c8e557a21afdcf9bab8aaabf386c44b794c2f94143d2"}, + {file = "rpds_py-0.10.6-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:cf693eb4a08eccc1a1b636e4392322582db2a47470d52e824b25eca7a3977b53"}, + {file = "rpds_py-0.10.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4134aa2342f9b2ab6c33d5c172e40f9ef802c61bb9ca30d21782f6e035ed0043"}, + {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e782379c2028a3611285a795b89b99a52722946d19fc06f002f8b53e3ea26ea9"}, + {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f6da6d842195fddc1cd34c3da8a40f6e99e4a113918faa5e60bf132f917c247"}, + {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4a9fe992887ac68256c930a2011255bae0bf5ec837475bc6f7edd7c8dfa254e"}, + {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b788276a3c114e9f51e257f2a6f544c32c02dab4aa7a5816b96444e3f9ffc336"}, + {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caa1afc70a02645809c744eefb7d6ee8fef7e2fad170ffdeacca267fd2674f13"}, + {file = "rpds_py-0.10.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bddd4f91eede9ca5275e70479ed3656e76c8cdaaa1b354e544cbcf94c6fc8ac4"}, + {file = "rpds_py-0.10.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:775049dfa63fb58293990fc59473e659fcafd953bba1d00fc5f0631a8fd61977"}, + {file = "rpds_py-0.10.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c6c45a2d2b68c51fe3d9352733fe048291e483376c94f7723458cfd7b473136b"}, + {file = "rpds_py-0.10.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0699ab6b8c98df998c3eacf51a3b25864ca93dab157abe358af46dc95ecd9801"}, + {file = "rpds_py-0.10.6-cp38-none-win32.whl", hash = "sha256:ebdab79f42c5961682654b851f3f0fc68e6cc7cd8727c2ac4ffff955154123c1"}, + {file = "rpds_py-0.10.6-cp38-none-win_amd64.whl", hash = "sha256:24656dc36f866c33856baa3ab309da0b6a60f37d25d14be916bd3e79d9f3afcf"}, + {file = "rpds_py-0.10.6-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:0898173249141ee99ffcd45e3829abe7bcee47d941af7434ccbf97717df020e5"}, + {file = "rpds_py-0.10.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9e9184fa6c52a74a5521e3e87badbf9692549c0fcced47443585876fcc47e469"}, + {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5752b761902cd15073a527b51de76bbae63d938dc7c5c4ad1e7d8df10e765138"}, + {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:99a57006b4ec39dbfb3ed67e5b27192792ffb0553206a107e4aadb39c5004cd5"}, + {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09586f51a215d17efdb3a5f090d7cbf1633b7f3708f60a044757a5d48a83b393"}, + {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e225a6a14ecf44499aadea165299092ab0cba918bb9ccd9304eab1138844490b"}, + {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2039f8d545f20c4e52713eea51a275e62153ee96c8035a32b2abb772b6fc9e5"}, + {file = "rpds_py-0.10.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:34ad87a831940521d462ac11f1774edf867c34172010f5390b2f06b85dcc6014"}, + {file = "rpds_py-0.10.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dcdc88b6b01015da066da3fb76545e8bb9a6880a5ebf89e0f0b2e3ca557b3ab7"}, + {file = "rpds_py-0.10.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:25860ed5c4e7f5e10c496ea78af46ae8d8468e0be745bd233bab9ca99bfd2647"}, + {file = "rpds_py-0.10.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7854a207ef77319ec457c1eb79c361b48807d252d94348305db4f4b62f40f7f3"}, + {file = "rpds_py-0.10.6-cp39-none-win32.whl", hash = "sha256:e6fcc026a3f27c1282c7ed24b7fcac82cdd70a0e84cc848c0841a3ab1e3dea2d"}, + {file = "rpds_py-0.10.6-cp39-none-win_amd64.whl", hash = "sha256:e98c4c07ee4c4b3acf787e91b27688409d918212dfd34c872201273fdd5a0e18"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:68fe9199184c18d997d2e4293b34327c0009a78599ce703e15cd9a0f47349bba"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3339eca941568ed52d9ad0f1b8eb9fe0958fa245381747cecf2e9a78a5539c42"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a360cfd0881d36c6dc271992ce1eda65dba5e9368575663de993eeb4523d895f"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:031f76fc87644a234883b51145e43985aa2d0c19b063e91d44379cd2786144f8"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f36a9d751f86455dc5278517e8b65580eeee37d61606183897f122c9e51cef3"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:052a832078943d2b2627aea0d19381f607fe331cc0eb5df01991268253af8417"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:023574366002bf1bd751ebaf3e580aef4a468b3d3c216d2f3f7e16fdabd885ed"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:defa2c0c68734f4a82028c26bcc85e6b92cced99866af118cd6a89b734ad8e0d"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:879fb24304ead6b62dbe5034e7b644b71def53c70e19363f3c3be2705c17a3b4"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:53c43e10d398e365da2d4cc0bcaf0854b79b4c50ee9689652cdc72948e86f487"}, + {file = "rpds_py-0.10.6-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:3777cc9dea0e6c464e4b24760664bd8831738cc582c1d8aacf1c3f546bef3f65"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:40578a6469e5d1df71b006936ce95804edb5df47b520c69cf5af264d462f2cbb"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:cf71343646756a072b85f228d35b1d7407da1669a3de3cf47f8bbafe0c8183a4"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:10f32b53f424fc75ff7b713b2edb286fdbfc94bf16317890260a81c2c00385dc"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:81de24a1c51cfb32e1fbf018ab0bdbc79c04c035986526f76c33e3f9e0f3356c"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac17044876e64a8ea20ab132080ddc73b895b4abe9976e263b0e30ee5be7b9c2"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5e8a78bd4879bff82daef48c14d5d4057f6856149094848c3ed0ecaf49f5aec2"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78ca33811e1d95cac8c2e49cb86c0fb71f4d8409d8cbea0cb495b6dbddb30a55"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c63c3ef43f0b3fb00571cff6c3967cc261c0ebd14a0a134a12e83bdb8f49f21f"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:7fde6d0e00b2fd0dbbb40c0eeec463ef147819f23725eda58105ba9ca48744f4"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:79edd779cfc46b2e15b0830eecd8b4b93f1a96649bcb502453df471a54ce7977"}, + {file = "rpds_py-0.10.6-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9164ec8010327ab9af931d7ccd12ab8d8b5dc2f4c6a16cbdd9d087861eaaefa1"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:d29ddefeab1791e3c751e0189d5f4b3dbc0bbe033b06e9c333dca1f99e1d523e"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:30adb75ecd7c2a52f5e76af50644b3e0b5ba036321c390b8e7ec1bb2a16dd43c"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd609fafdcdde6e67a139898196698af37438b035b25ad63704fd9097d9a3482"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6eef672de005736a6efd565577101277db6057f65640a813de6c2707dc69f396"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cf4393c7b41abbf07c88eb83e8af5013606b1cdb7f6bc96b1b3536b53a574b8"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ad857f42831e5b8d41a32437f88d86ead6c191455a3499c4b6d15e007936d4cf"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d7360573f1e046cb3b0dceeb8864025aa78d98be4bb69f067ec1c40a9e2d9df"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d08f63561c8a695afec4975fae445245386d645e3e446e6f260e81663bfd2e38"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:f0f17f2ce0f3529177a5fff5525204fad7b43dd437d017dd0317f2746773443d"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:442626328600bde1d09dc3bb00434f5374948838ce75c41a52152615689f9403"}, + {file = "rpds_py-0.10.6-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e9616f5bd2595f7f4a04b67039d890348ab826e943a9bfdbe4938d0eba606971"}, + {file = "rpds_py-0.10.6.tar.gz", hash = "sha256:4ce5a708d65a8dbf3748d2474b580d606b1b9f91b5c6ab2a316e0b0cf7a4ba50"}, +] + +[[package]] +name = "ruamel-yaml" +version = "0.17.40" +description = "ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order" +optional = false +python-versions = ">=3" +files = [ + {file = "ruamel.yaml-0.17.40-py3-none-any.whl", hash = "sha256:b16b6c3816dff0a93dca12acf5e70afd089fa5acb80604afd1ffa8b465b7722c"}, + {file = "ruamel.yaml-0.17.40.tar.gz", hash = "sha256:6024b986f06765d482b5b07e086cc4b4cd05dd22ddcbc758fa23d54873cf313d"}, +] + +[package.dependencies] +"ruamel.yaml.clib" = {version = ">=0.2.7", markers = "platform_python_implementation == \"CPython\" and python_version < \"3.13\""} + +[package.extras] +docs = ["mercurial (>5.7)", "ryd"] +jinja2 = ["ruamel.yaml.jinja2 (>=0.2)"] + +[[package]] +name = "ruamel-yaml-clib" +version = "0.2.8" +description = "C version of reader, parser and emitter for ruamel.yaml derived from libyaml" +optional = false +python-versions = ">=3.6" +files = [ + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:d92f81886165cb14d7b067ef37e142256f1c6a90a65cd156b063a43da1708cfd"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win32.whl", hash = "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d"}, + {file = "ruamel.yaml.clib-0.2.8-cp310-cp310-win_amd64.whl", hash = "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:b5edda50e5e9e15e54a6a8a0070302b00c518a9d32accc2346ad6c984aacd279"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win32.whl", hash = "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7"}, + {file = "ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl", hash = "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:7048c338b6c86627afb27faecf418768acb6331fc24cfa56c93e8c9780f815fa"}, + {file = "ruamel.yaml.clib-0.2.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92"}, + {file = "ruamel.yaml.clib-0.2.8-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-macosx_12_0_arm64.whl", hash = "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3fcc54cb0c8b811ff66082de1680b4b14cf8a81dce0d4fbf665c2265a81e07a1"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win32.whl", hash = "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b"}, + {file = "ruamel.yaml.clib-0.2.8-cp37-cp37m-win_amd64.whl", hash = "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:665f58bfd29b167039f714c6998178d27ccd83984084c286110ef26b230f259f"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win32.whl", hash = "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe"}, + {file = "ruamel.yaml.clib-0.2.8-cp38-cp38-win_amd64.whl", hash = "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:9eb5dee2772b0f704ca2e45b1713e4e5198c18f515b52743576d196348f374d3"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win32.whl", hash = "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5"}, + {file = "ruamel.yaml.clib-0.2.8-cp39-cp39-win_amd64.whl", hash = "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15"}, + {file = "ruamel.yaml.clib-0.2.8.tar.gz", hash = "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512"}, +] + +[[package]] +name = "semgrep" +version = "1.45.0" +description = "Lightweight static analysis for many languages. Find bug variants with patterns that look like source code." +optional = false +python-versions = ">=3.7" +files = [ + {file = "semgrep-1.45.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-any.whl", hash = "sha256:b466501971f9491ab089d01e29dec6fab404b5f99e1279c888d4a8e6aac3b443"}, + {file = "semgrep-1.45.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-macosx_10_14_x86_64.whl", hash = "sha256:4f2bc7482746d3383d909d46a0d878184580eac1b2cafe65c4192f2d226d3df5"}, + {file = "semgrep-1.45.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-macosx_11_0_arm64.whl", hash = "sha256:7bac4ac8c613ba9851cce28537117636f7356489324cb55503a6f90be51d6e91"}, + {file = "semgrep-1.45.0-cp37.cp38.cp39.cp310.cp311.py37.py38.py39.py310.py311-none-musllinux_1_0_aarch64.manylinux2014_aarch64.whl", hash = "sha256:519aa0752d206b2442895be6ba279d4826783f1db0b994f87a5855bdce310078"}, + {file = "semgrep-1.45.0.tar.gz", hash = "sha256:f2efad4236a0cf8b397e8f367b49d77a5ea0ec92de518f158247160041dbd980"}, +] + +[package.dependencies] +attrs = ">=21.3" +boltons = ">=21.0,<22.0" +click = ">=8.1,<9.0" +click-option-group = ">=0.5,<1.0" +colorama = ">=0.4.0,<0.5.0" +defusedxml = ">=0.7.1,<0.8.0" +glom = ">=22.1,<23.0" +jsonschema = ">=4.6,<5.0" +packaging = ">=21.0" +peewee = ">=3.14,<4.0" +python-lsp-jsonrpc = ">=1.0.0,<1.1.0" +requests = ">=2.22,<3.0" +rich = ">=12.6.0" +"ruamel.yaml" = ">=0.16.0,<0.18" +tomli = ">=2.0.1,<2.1.0" +typing-extensions = ">=4.2,<5.0" +urllib3 = ">=1.26,<2.0" +wcmatch = ">=8.3,<9.0" + +[package.extras] +experiments = ["jsonnet (>=0.18,<1.0)"] + [[package]] name = "setuptools" version = "68.2.2" @@ -2405,22 +2737,91 @@ files = [ {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"}, ] +[[package]] +name = "ujson" +version = "5.8.0" +description = "Ultra fast JSON encoder and decoder for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ujson-5.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f4511560d75b15ecb367eef561554959b9d49b6ec3b8d5634212f9fed74a6df1"}, + {file = "ujson-5.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9399eaa5d1931a0ead49dce3ffacbea63f3177978588b956036bfe53cdf6af75"}, + {file = "ujson-5.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4e7bb7eba0e1963f8b768f9c458ecb193e5bf6977090182e2b4f4408f35ac76"}, + {file = "ujson-5.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40931d7c08c4ce99adc4b409ddb1bbb01635a950e81239c2382cfe24251b127a"}, + {file = "ujson-5.8.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d53039d39de65360e924b511c7ca1a67b0975c34c015dd468fca492b11caa8f7"}, + {file = "ujson-5.8.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bdf04c6af3852161be9613e458a1fb67327910391de8ffedb8332e60800147a2"}, + {file = "ujson-5.8.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a70f776bda2e5072a086c02792c7863ba5833d565189e09fabbd04c8b4c3abba"}, + {file = "ujson-5.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f26629ac531d712f93192c233a74888bc8b8212558bd7d04c349125f10199fcf"}, + {file = "ujson-5.8.0-cp310-cp310-win32.whl", hash = "sha256:7ecc33b107ae88405aebdb8d82c13d6944be2331ebb04399134c03171509371a"}, + {file = "ujson-5.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:3b27a8da7a080add559a3b73ec9ebd52e82cc4419f7c6fb7266e62439a055ed0"}, + {file = "ujson-5.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:193349a998cd821483a25f5df30b44e8f495423840ee11b3b28df092ddfd0f7f"}, + {file = "ujson-5.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ddeabbc78b2aed531f167d1e70387b151900bc856d61e9325fcdfefb2a51ad8"}, + {file = "ujson-5.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ce24909a9c25062e60653073dd6d5e6ec9d6ad7ed6e0069450d5b673c854405"}, + {file = "ujson-5.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27a2a3c7620ebe43641e926a1062bc04e92dbe90d3501687957d71b4bdddaec4"}, + {file = "ujson-5.8.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b852bdf920fe9f84e2a2c210cc45f1b64f763b4f7d01468b33f7791698e455e"}, + {file = "ujson-5.8.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:20768961a6a706170497129960762ded9c89fb1c10db2989c56956b162e2a8a3"}, + {file = "ujson-5.8.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e0147d41e9fb5cd174207c4a2895c5e24813204499fd0839951d4c8784a23bf5"}, + {file = "ujson-5.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e3673053b036fd161ae7a5a33358ccae6793ee89fd499000204676baafd7b3aa"}, + {file = "ujson-5.8.0-cp311-cp311-win32.whl", hash = "sha256:a89cf3cd8bf33a37600431b7024a7ccf499db25f9f0b332947fbc79043aad879"}, + {file = "ujson-5.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:3659deec9ab9eb19e8646932bfe6fe22730757c4addbe9d7d5544e879dc1b721"}, + {file = "ujson-5.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:102bf31c56f59538cccdfec45649780ae00657e86247c07edac434cb14d5388c"}, + {file = "ujson-5.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:299a312c3e85edee1178cb6453645217ba23b4e3186412677fa48e9a7f986de6"}, + {file = "ujson-5.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2e385a7679b9088d7bc43a64811a7713cc7c33d032d020f757c54e7d41931ae"}, + {file = "ujson-5.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad24ec130855d4430a682c7a60ca0bc158f8253ec81feed4073801f6b6cb681b"}, + {file = "ujson-5.8.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16fde596d5e45bdf0d7de615346a102510ac8c405098e5595625015b0d4b5296"}, + {file = "ujson-5.8.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:6d230d870d1ce03df915e694dcfa3f4e8714369cce2346686dbe0bc8e3f135e7"}, + {file = "ujson-5.8.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9571de0c53db5cbc265945e08f093f093af2c5a11e14772c72d8e37fceeedd08"}, + {file = "ujson-5.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7cba16b26efe774c096a5e822e4f27097b7c81ed6fb5264a2b3f5fd8784bab30"}, + {file = "ujson-5.8.0-cp312-cp312-win32.whl", hash = "sha256:48c7d373ff22366eecfa36a52b9b55b0ee5bd44c2b50e16084aa88b9de038916"}, + {file = "ujson-5.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:5ac97b1e182d81cf395ded620528c59f4177eee024b4b39a50cdd7b720fdeec6"}, + {file = "ujson-5.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2a64cc32bb4a436e5813b83f5aab0889927e5ea1788bf99b930fad853c5625cb"}, + {file = "ujson-5.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e54578fa8838ddc722539a752adfce9372474114f8c127bb316db5392d942f8b"}, + {file = "ujson-5.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9721cd112b5e4687cb4ade12a7b8af8b048d4991227ae8066d9c4b3a6642a582"}, + {file = "ujson-5.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d9707e5aacf63fb919f6237d6490c4e0244c7f8d3dc2a0f84d7dec5db7cb54c"}, + {file = "ujson-5.8.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0be81bae295f65a6896b0c9030b55a106fb2dec69ef877253a87bc7c9c5308f7"}, + {file = "ujson-5.8.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ae7f4725c344bf437e9b881019c558416fe84ad9c6b67426416c131ad577df67"}, + {file = "ujson-5.8.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9ab282d67ef3097105552bf151438b551cc4bedb3f24d80fada830f2e132aeb9"}, + {file = "ujson-5.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:94c7bd9880fa33fcf7f6d7f4cc032e2371adee3c5dba2922b918987141d1bf07"}, + {file = "ujson-5.8.0-cp38-cp38-win32.whl", hash = "sha256:bf5737dbcfe0fa0ac8fa599eceafae86b376492c8f1e4b84e3adf765f03fb564"}, + {file = "ujson-5.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:11da6bed916f9bfacf13f4fc6a9594abd62b2bb115acfb17a77b0f03bee4cfd5"}, + {file = "ujson-5.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:69b3104a2603bab510497ceabc186ba40fef38ec731c0ccaa662e01ff94a985c"}, + {file = "ujson-5.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9249fdefeb021e00b46025e77feed89cd91ffe9b3a49415239103fc1d5d9c29a"}, + {file = "ujson-5.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2873d196725a8193f56dde527b322c4bc79ed97cd60f1d087826ac3290cf9207"}, + {file = "ujson-5.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a4dafa9010c366589f55afb0fd67084acd8added1a51251008f9ff2c3e44042"}, + {file = "ujson-5.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a42baa647a50fa8bed53d4e242be61023bd37b93577f27f90ffe521ac9dc7a3"}, + {file = "ujson-5.8.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f3554eaadffe416c6f543af442066afa6549edbc34fe6a7719818c3e72ebfe95"}, + {file = "ujson-5.8.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:fb87decf38cc82bcdea1d7511e73629e651bdec3a43ab40985167ab8449b769c"}, + {file = "ujson-5.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:407d60eb942c318482bbfb1e66be093308bb11617d41c613e33b4ce5be789adc"}, + {file = "ujson-5.8.0-cp39-cp39-win32.whl", hash = "sha256:0fe1b7edaf560ca6ab023f81cbeaf9946a240876a993b8c5a21a1c539171d903"}, + {file = "ujson-5.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:3f9b63530a5392eb687baff3989d0fb5f45194ae5b1ca8276282fb647f8dcdb3"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:efeddf950fb15a832376c0c01d8d7713479fbeceaed1eaecb2665aa62c305aec"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d8283ac5d03e65f488530c43d6610134309085b71db4f675e9cf5dff96a8282"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb0142f6f10f57598655340a3b2c70ed4646cbe674191da195eb0985a9813b83"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07d459aca895eb17eb463b00441986b021b9312c6c8cc1d06880925c7f51009c"}, + {file = "ujson-5.8.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:d524a8c15cfc863705991d70bbec998456a42c405c291d0f84a74ad7f35c5109"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d6f84a7a175c75beecde53a624881ff618e9433045a69fcfb5e154b73cdaa377"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b748797131ac7b29826d1524db1cc366d2722ab7afacc2ce1287cdafccddbf1f"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e72ba76313d48a1a3a42e7dc9d1db32ea93fac782ad8dde6f8b13e35c229130"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f504117a39cb98abba4153bf0b46b4954cc5d62f6351a14660201500ba31fe7f"}, + {file = "ujson-5.8.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a8c91b6f4bf23f274af9002b128d133b735141e867109487d17e344d38b87d94"}, + {file = "ujson-5.8.0.tar.gz", hash = "sha256:78e318def4ade898a461b3d92a79f9441e7e0e4d2ad5419abed4336d702c7425"}, +] + [[package]] name = "urllib3" -version = "2.0.7" +version = "1.26.18" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false -python-versions = ">=3.7" +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ - {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"}, - {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"}, + {file = "urllib3-1.26.18-py2.py3-none-any.whl", hash = "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07"}, + {file = "urllib3-1.26.18.tar.gz", hash = "sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0"}, ] [package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] +brotli = ["brotli (==1.0.9)", "brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] +secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] +socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "uvicorn" @@ -2584,6 +2985,20 @@ files = [ [package.dependencies] anyio = ">=3.0.0" +[[package]] +name = "wcmatch" +version = "8.5" +description = "Wildcard/glob file name matcher." +optional = false +python-versions = ">=3.8" +files = [ + {file = "wcmatch-8.5-py3-none-any.whl", hash = "sha256:14554e409b142edeefab901dc68ad570b30a72a8ab9a79106c5d5e9a6d241bd5"}, + {file = "wcmatch-8.5.tar.gz", hash = "sha256:86c17572d0f75cbf3bcb1a18f3bf2f9e72b39a9c08c9b4a74e991e1882a8efb3"}, +] + +[package.dependencies] +bracex = ">=2.1.1" + [[package]] name = "wcwidth" version = "0.2.8" @@ -2819,4 +3234,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.10" -content-hash = "2ea4e2d34f63c6d07bbf5adcc477ab74cb6991270c1f319a45ce2c7a209459a1" +content-hash = "0f23835864e7762730f6b215e086842606f6afeb1d78a0959a4eaee0bd4001fd" From 295ddfa45d3a3f9c5f0faae86326e8f414f78b4c Mon Sep 17 00:00:00 2001 From: Nathan Hoos <128712250+unaidedelf8777@users.noreply.github.com> Date: Fri, 20 Oct 2023 22:56:32 +0000 Subject: [PATCH 09/12] fixed the tests, since they imported and assumed that was a instance, but is wasnt. now uses interpreter.create_interpreter() --- interpreter/core/core.py | 1 - tests/test_interpreter.py | 33 ++++++++++++++++++--------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/interpreter/core/core.py b/interpreter/core/core.py index 1cfd9a5bb3..5e59bdd7d6 100644 --- a/interpreter/core/core.py +++ b/interpreter/core/core.py @@ -29,7 +29,6 @@ from ..utils.display_markdown_message import display_markdown_message from ..code_interpreters.container_utils.build_image import build_docker_images from ..utils.embed import embed_function -from ..terminal_interface.magic_commands import handle_magic_command diff --git a/tests/test_interpreter.py b/tests/test_interpreter.py index ad95506302..bd6eda06da 100644 --- a/tests/test_interpreter.py +++ b/tests/test_interpreter.py @@ -2,24 +2,25 @@ from random import randint import time import pytest -import interpreter +import interpreter as i from interpreter.utils.count_tokens import count_tokens, count_messages_tokens import time -interpreter.auto_run = True -interpreter.model = "gpt-4" -interpreter.temperature = 0 - # this function will run before each test # we're clearing out the messages Array so we can start fresh and reduce token usage -def setup_function(): + +@pytest.fixture(scope="function") # This will make the interpreter instance available to all test cases. +def interpreter(): + interpreter = i.create_interpreter() interpreter.reset() interpreter.temperature = 0 interpreter.auto_run = True interpreter.model = "gpt-4" interpreter.debug_mode = False + yield interpreter + # this function will run after each test # we're introducing some sleep to help avoid timeout issues with the OpenAI API @@ -27,7 +28,7 @@ def teardown_function(): time.sleep(5) -def test_config_loading(): +def test_config_loading(interpreter): # because our test is running from the root directory, we need to do some # path manipulation to get the actual path to the config file or our config # loader will try to load from the wrong directory and fail @@ -43,7 +44,7 @@ def test_config_loading(): assert temperature_ok and model_ok and debug_mode_ok -def test_system_message_appending(): +def test_system_message_appending(interpreter): ping_system_message = ( "Respond to a `ping` with a `pong`. No code. No explanations. Just `pong`." ) @@ -61,12 +62,12 @@ def test_system_message_appending(): ] -def test_reset(): +def test_reset(interpreter): # make sure that interpreter.reset() clears out the messages Array assert interpreter.messages == [] -def test_token_counter(): +def test_token_counter(interpreter): system_tokens = count_tokens(text=interpreter.system_message, model=interpreter.model) prompt = "How many tokens is this?" @@ -88,20 +89,22 @@ def test_token_counter(): assert system_tokens_ok and prompt_tokens_ok -def test_hello_world(): +def test_hello_world(interpreter): hello_world_response = "Hello, World!" hello_world_message = f"Please reply with just the words {hello_world_response} and nothing else. Do not run code. No confirmation just the text." messages = interpreter.chat(hello_world_message) + print(messages) + assert messages == [ {"role": "user", "message": hello_world_message}, {"role": "assistant", "message": hello_world_response}, ] @pytest.mark.skip(reason="Math is hard") -def test_math(): +def test_math(interpreter): # we'll generate random integers between this min and max in our math tests min_number = randint(1, 99) max_number = randint(1001, 9999) @@ -122,19 +125,19 @@ def test_math(): assert str(round(test_result, 2)) in messages[-1]["message"] -def test_delayed_exec(): +def test_delayed_exec(interpreter): interpreter.chat( """Can you write a single block of code and run_code it that prints something, then delays 1 second, then prints something else? No talk just code. Thanks!""" ) @pytest.mark.skip(reason="This works fine when I run it but fails frequently in Github Actions... will look into it after the hackathon") -def test_nested_loops_and_multiple_newlines(): +def test_nested_loops_and_multiple_newlines(interpreter): interpreter.chat( """Can you write a nested for loop in python and shell and run them? Don't forget to properly format your shell script and use semicolons where necessary. Also put 1-3 newlines between each line in the code. Only generate and execute the code. No explanations. Thanks!""" ) -def test_markdown(): +def test_markdown(interpreter): interpreter.chat( """Hi, can you test out a bunch of markdown features? Try writing a fenced code block, a table, headers, everything. DO NOT write the markdown inside a markdown code block, just write it raw.""" ) From 888450639634679c777ae756d2fc84cdc312d620 Mon Sep 17 00:00:00 2001 From: Nathan Hoos <128712250+unaidedelf8777@users.noreply.github.com> Date: Sat, 21 Oct 2023 18:15:08 +0000 Subject: [PATCH 10/12] typo in interpreter/code_interpreters/languages/python.py --- .../code_interpreters/languages/python.py | 2 +- interpreter/llm/get_schema.py | 45 +++++++++++++++++++ interpreter/llm/setup_openai_coding_llm.py | 27 ++--------- 3 files changed, 49 insertions(+), 25 deletions(-) create mode 100644 interpreter/llm/get_schema.py diff --git a/interpreter/code_interpreters/languages/python.py b/interpreter/code_interpreters/languages/python.py index 11e44782da..804f0b6fdd 100644 --- a/interpreter/code_interpreters/languages/python.py +++ b/interpreter/code_interpreters/languages/python.py @@ -12,7 +12,7 @@ class Python(SubprocessCodeInterpreter): def __init__(self, **kwargs): super().__init__(**kwargs) - if 'use_docker' in kwargs and kwargs['use_docker']: + if 'use_containers' in kwargs and kwargs['use_containers']: self.start_cmd = "python3 -i -q -u" else: executable = sys.executable diff --git a/interpreter/llm/get_schema.py b/interpreter/llm/get_schema.py new file mode 100644 index 0000000000..ff77fd5ca0 --- /dev/null +++ b/interpreter/llm/get_schema.py @@ -0,0 +1,45 @@ +"""Function to enable / disable different lang based on operating system. """ +import platform +import copy + +BASE_FUNCTION_SCHEMA = { + "name": "execute", + "description": + "Executes code on the user's machine, **in the users local environment**, and returns the output", + "parameters": { + "type": "object", + "properties": { + "language": { + "type": "string", + "description": + "The programming language (required parameter to the `execute` function)", + "enum": ["python", "R", "shell", "javascript", "html",] + }, + "code": { + "type": "string", + "description": "The code to execute (required)" + } + }, + "required": ["language", "code"] + }, +} + +def get_schema(): + # Detect the operating system + os_type = platform.system().lower() + + # Define the base languages that are common to all supported operating systems + base_languages = ["python", "R", "shell", "javascript", "html"] + + # Copy the schema to avoid modifying the original + corrected_schema = copy.deepcopy(BASE_FUNCTION_SCHEMA) + + # Add 'powershell' if the OS is Windows, 'applescript' if macOS, or none if it's another OS + if os_type == 'windows': + base_languages.append('powershell') + elif os_type == 'darwin': # Darwin is the system name for macOS + base_languages.append('applescript') + + corrected_schema['parameters']['properties']['language']['enum'] = base_languages + + return corrected_schema diff --git a/interpreter/llm/setup_openai_coding_llm.py b/interpreter/llm/setup_openai_coding_llm.py index 763dc4f181..1f6aa9cb57 100644 --- a/interpreter/llm/setup_openai_coding_llm.py +++ b/interpreter/llm/setup_openai_coding_llm.py @@ -3,31 +3,10 @@ from ..utils.parse_partial_json import parse_partial_json from ..utils.convert_to_openai_messages import convert_to_openai_messages from ..utils.display_markdown_message import display_markdown_message +from .get_schema import get_schema import tokentrim as tt -function_schema = { - "name": "execute", - "description": - "Executes code on the user's machine, **in the users local environment**, and returns the output", - "parameters": { - "type": "object", - "properties": { - "language": { - "type": "string", - "description": - "The programming language (required parameter to the `execute` function)", - "enum": ["python", "R", "shell", "applescript", "javascript", "html", "powershell"] - }, - "code": { - "type": "string", - "description": "The code to execute (required)" - } - }, - "required": ["language", "code"] - }, -} - def setup_openai_coding_llm(interpreter): """ Takes an Interpreter (which includes a ton of LLM settings), @@ -68,7 +47,7 @@ def coding_llm(messages): 'model': interpreter.model, 'messages': messages, 'stream': True, - 'functions': [function_schema] + 'functions': [get_schema()] } # Optional inputs @@ -135,4 +114,4 @@ def coding_llm(messages): if code_delta: yield {"code": code_delta} - return coding_llm \ No newline at end of file + return coding_llm From 2af31a989c91caee107eacbeac24a272ef98feb7 Mon Sep 17 00:00:00 2001 From: Nathan Hoos <128712250+unaidedelf8777@users.noreply.github.com> Date: Sat, 21 Oct 2023 20:08:36 +0000 Subject: [PATCH 11/12] fix html interpreter so that we can treat it like a subprocess code interpreter, though it isnt. this is for simplicity. --- interpreter/code_interpreters/languages/html.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/interpreter/code_interpreters/languages/html.py b/interpreter/code_interpreters/languages/html.py index 3be7cbcf40..3b39345a03 100644 --- a/interpreter/code_interpreters/languages/html.py +++ b/interpreter/code_interpreters/languages/html.py @@ -7,9 +7,8 @@ class HTML(BaseCodeInterpreter): file_extension = "html" proper_name = "HTML" - def __init__(self, **kwargs): - super().__init__(**kwargs) # include kwargs though they dont do anything in this case. - # This is just so we dont need more logic in the create interpreter function + def __init__(self, **kwargs): ## accept the kwargs though we dont use them, since its easier this way. + super().__init__() def run(self, code): # Create a temporary HTML file with the content From 12888318c9be12ff8d2fc6f820cb76f4a57d4cf2 Mon Sep 17 00:00:00 2001 From: Nathan Hoos <128712250+unaidedelf8777@users.noreply.github.com> Date: Sat, 21 Oct 2023 20:27:33 +0000 Subject: [PATCH 12/12] fix html interpreter so that we can treat it like a subprocess code interpreter, though it isnt. this is for simplicity. --- .../container_utils/upload_file.py | 5 ++++- .../code_interpreters/create_code_interpreter.py | 3 +++ interpreter/code_interpreters/languages/html.py | 15 +++++++++++++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/interpreter/code_interpreters/container_utils/upload_file.py b/interpreter/code_interpreters/container_utils/upload_file.py index 07cdf4af0f..ecf79fd1de 100644 --- a/interpreter/code_interpreters/container_utils/upload_file.py +++ b/interpreter/code_interpreters/container_utils/upload_file.py @@ -1,10 +1,11 @@ +"""Short function to upload a file to a docker container via the docker module. yes its hacky, but its easy and I didnt want to over complicate.""" import io import tarfile import os import docker from tqdm import tqdm -def copy_file_to_container(container_id, local_path, path_in_container): +def copy_file_to_container(container_id, local_path, path_in_container, pbar=True): # Validate input if not os.path.exists(local_path): raise ValueError(f"The specified local path {local_path} does not exist.") @@ -57,3 +58,5 @@ def file_data_with_progress(): # Use put_archive to copy the file or directory into the container client.put_archive(container=container_id, path=dir_path_in_container, data=file_data_with_progress()) + + return path_in_container diff --git a/interpreter/code_interpreters/create_code_interpreter.py b/interpreter/code_interpreters/create_code_interpreter.py index 7df43d5434..247d5f916f 100644 --- a/interpreter/code_interpreters/create_code_interpreter.py +++ b/interpreter/code_interpreters/create_code_interpreter.py @@ -43,4 +43,7 @@ def create_code_interpreter(interpreter, language, use_containers=False): timeout = os.getenv("OI_CONTAINER_TIMEOUT", None) + if timeout is not None: + timeout = int(timeout) + return CodeInterpreter(session_id=session_id, use_containers=use_containers, close_callback=partial(interpreter.container_callback, language=language), auto_remove_timeout=timeout) diff --git a/interpreter/code_interpreters/languages/html.py b/interpreter/code_interpreters/languages/html.py index 3b39345a03..20a7baa268 100644 --- a/interpreter/code_interpreters/languages/html.py +++ b/interpreter/code_interpreters/languages/html.py @@ -2,6 +2,7 @@ import tempfile import os from ..base_code_interpreter import BaseCodeInterpreter +from ..container_utils.upload_file import copy_file_to_container class HTML(BaseCodeInterpreter): file_extension = "html" @@ -9,13 +10,23 @@ class HTML(BaseCodeInterpreter): def __init__(self, **kwargs): ## accept the kwargs though we dont use them, since its easier this way. super().__init__() - + self.kwargs = kwargs def run(self, code): # Create a temporary HTML file with the content with tempfile.NamedTemporaryFile(delete=False, suffix=".html") as f: f.write(code.encode()) + save_dir = os.path.realpath(f.name) + + if self.kwargs.get("use_containers"): + save_dir = copy_file_to_container( + local_path=os.path.realpath(f.name), + path_in_container=os.path.join("/mnt/data", f.name), + container_id=self.kwargs.get("session_id"), + pbar=False + ) + # Open the HTML file with the default web browser webbrowser.open('file://' + os.path.realpath(f.name)) - yield {"output": f"Saved to {os.path.realpath(f.name)} and opened with the user's default web browser."} \ No newline at end of file + yield {"output": f"Saved to {save_dir} and opened with the user's default web browser."} \ No newline at end of file