Local-Code-Interpreter

repository·main·Indexed 43 days ago

https://github.com/mrgreyfun/local-code-interpreter

A local implementation of OpenAI's Advanced Data Analysis (Code Interpreter) that allows users to execute Python code on their own device. It supports a wide range of models including GPT-3.5, GPT-4, and GPT-4o, as well as Azure OpenAI deployments. The tool features a web UI, Jupyter kernel integration for code execution, and the ability to save conversation histories as Jupyter notebooks.

Tokens
6.8K
Snippets
25
Records
33
Agent score
55%

What's inside Local-Code-Interpreter

  1. Run Local-Code-Interpreter and Save to Jupyter Notebook

    main

    To start the application, navigate to the src directory and run the web_ui.py script.

    Basic Execution

    cd src
    python web_ui.py

    Save Conversations to Jupyter Notebook

    You can use the -n or --notebook flag to save the conversation history and code into a Jupyter notebook. If no path is provided, it saves to the current working directory.

    python web_ui.py -n <path_to_notebook>
    cd src
    python web_ui.py -n my_session.ipynb
  2. Install Local-Code-Interpreter

    main

    To install the Local-Code-Interpreter, clone the repository and install the required Python dependencies. The program is tested on Windows 10 and CentOS Linux 7.8 with Python 3.9.16.

    Standard Installation

    Use the following commands to clone and install the base requirements:

    git clone https://github.com/MrGreyfun/Local-Code-Interpreter.git
    cd Local-Code-Interpreter
    pip install -r requirements.txt

    Full Installation

    For users who want additional packages commonly used for data processing and analysis, use the full requirements file:

    pip install -r requirements_full.txt
  3. Run the Local Code Interpreter Web UI

    main

    To start the application, navigate to the src directory and run the web_ui.py script.

    Basic Execution

    cd src
    python web_ui.py

    After running, open the URL generated in your terminal in a web browser.

    Save to Jupyter Notebook

    You can save your conversation history and code to a Jupyter notebook file using the -n or --notebook flag. You can optionally provide a path to save the file.

    # Save to default working directory
    python web_ui.py -n
    
    # Save to a specific path
    python web_ui.py -n <path_to_notebook>
    cd src
    python web_ui.py -n <path_to_notebook>
  4. How the response parsing strategy works

    main

    The response parser uses a strategy pattern via the ChoiceHandler class to process LLM response chunks. When a chunk is received, ChoiceHandler iterates through a predefined list of strategies. Each strategy implements a support() method to check if it can handle the current delta and an execute() method to perform the state updates.

    Supported Strategies:

    1. RoleChoiceStrategy: Updates the assistant's role name if delta.role is present.
    2. ContentChoiceStrategy: Adds text content to the bot_backend and updates history if delta.content is present.
    3. NameFunctionCallChoiceStrategy: Identifies the function name from tool_calls. It validates if the function exists in the jupyter_kernel.available_functions or additional_tools. If the function is missing, it appends an error to the history and sets whether_exit to True.
    4. ArgumentsFunctionCallChoiceStrategy: Extracts function arguments. It includes special handling for:
      • python: Handles 'hallucinatory' calls where raw code is provided instead of JSON.
      • execute_code: Parses JSON arguments to extract the code string.
    5. FinishReasonChoiceStrategy: Handles the end of a turn. If the finish_reason is tool_calls, it triggers the execution of the requested function (either via the Jupyter kernel or additional tools) and updates the history with the results.
  5. Manage conversation state with BotBackend

    main

    The BotBackend class manages the lifecycle of an AI code interpreter session, including the conversation history, Jupyter kernel state, and tool availability. It inherits from GPTResponseLog to track real-time generation states.

    Key capabilities:

    • Conversation Management: Methods like add_text_message, add_file_message, and add_gpt_response_content_message update the internal conversation list used for chat completions.
    • File Handling: add_file_message copies uploaded files into a unique Jupyter working directory and notifies the model via a system message. revoke_file allows removing the last uploaded file and its associated messages.
    • Kernel Control: send_interrupt_signal interrupts the running Jupyter kernel, and restart resets the conversation, clears the working directory, and restarts the kernel.
    backend = BotBackend()
    # Add user input
    backend.add_text_message("Calculate the square root of 144")
    # Add a file to the session
    backend.add_file_message("path/to/data.csv", "Initial bot message")
    # Reset the session
    backend.restart()
  6. Handle hallucinatory 'python' function calls

    main

    The parser contains logic to handle a common issue where LLMs (specifically GPT-3.5) attempt to call a function named python with raw code text instead of a valid JSON object in the arguments field.

    When ArgumentsFunctionCallChoiceStrategy detects a function named python, it:

    1. Takes the raw function_args_str.
    2. Updates the bot_backend code string directly.
    3. Updates the display block with a 🔴Working: prefix and a markdown python code block.
    4. Appends this formatted block to the conversation history.
  7. Configure config.json for Local-Code-Interpreter

    main

    Configuration is handled via a config.json file located in the src directory. You should base your configuration on the examples provided in the config_example directory.

    Key Configuration Rules

    1. Model Selection (model_name)

    The program requires models with function calling capabilities (version 0613 or newer).

    Supported Models:

    • gpt-3.5-turbo-0613 (and 16K version)
    • gpt-3.5-turbo-1106
    • gpt-3.5-turbo-0125
    • gpt-4-0613 (and 32K version)
    • gpt-4-1106-preview
    • gpt-4-0125-preview
    • gpt-4-turbo
    • gpt-4o
    • gpt-4o-2024-05-13
    • gpt-4o-2024-08-06
    • gpt-4o-mini
    • gpt-4o-mini-2024-07-18

    Note on Vision: gpt-4-vision-preview does not support function calling directly. To use vision, set the model to GPT-4V and set available to true (see Vision Model Settings).

    Azure OpenAI Users:

    • Set model_name to your deployment name.
    • Ensure the deployment is a 0613 or newer version.
    • Set API_VERSION to 2024-03-01-preview.

    2. Vision Model Settings

    To enable vision input using a non-end-to-end approach:

    • Set model_name to GPT-4V.
    • Set available to true.
    • Setting available to false disables vision-related system prompts and reduces API costs.

    3. Model Context Window

    The model_context_window field is used to slice conversations when they exceed capacity.

    • For Azure OpenAI, manually map deployment names to their integer context window:
      "<YOUR-DEPLOYMENT-NAME>": <context_window (integer)>

    4. API Key Handling

    You can either:

    1. Provide the key directly in config.json under API_KEY.
    2. Leave API_KEY as an empty string ("API_KEY": "") and set the OPENAI_API_KEY environment variable.
      • Windows: set OPENAI_API_KEY=<YOUR-API-KEY>
      • Linux: export OPENAI_API_KEY=<YOUR-API-KEY>
  8. Manage the Web UI state and lifecycle

    main

    The Web UI is built using Gradio and relies on a state_dict to manage the BotBackend instance. Key lifecycle operations include:

    • Initialization: The initialization(state_dict) function sets up the cache directory and instantiates the BotBackend if it doesn't exist. It also clears the OPENAI_API_KEY from the environment to ensure backend control.
    • Restarting the UI: restart_ui(history) clears the chat history and resets all UI components (textboxes, buttons) to their default states.
    • Restarting the Backend: restart_bot_backend(state_dict) triggers a full restart of the underlying BotBackend logic.
    • Stopping Generation: stop_generating(state_dict) interrupts a running code execution or updates the stop state to halt GPT response generation.
    # Conceptual usage of state management
    state = {"bot_backend": None}
    initialization(state)
    # ... interaction ...
    restart_ui(history)
    restart_bot_backend(state)
  9. Security Warning for Local Code Execution

    main
    Warning: Executing AI-generated code on your local device without manual review poses significant security risks. It is highly recommended to use a virtual machine (VM) or a sandboxed environment to protect your host system and data when using this tool. You assume all responsibility for the consequences of running generated code.
  10. Configure API settings via config.json

    main

    The backend reads configuration from a config.json file. The following keys are used to initialize the BotBackend and its OpenAI client:

    • API_TYPE: 'azure' or other (standard OpenAI).
    • API_base: The base URL for the API.
    • API_VERSION: The API version (specifically for Azure).
    • API_KEY: The authentication key. If empty in config.json, it attempts to read from the OPENAI_API_KEY environment variable.
    • model: A dictionary mapping model choices (e.g., 'GPT-4') to their actual model_name.
  11. Handle file uploads and undo operations

    main

    Files can be uploaded to the interpreter via add_file(state_dict, history, files).

    • Image Support: If an uploaded file is an image (e.g., .jpg, .png, .webp), it is copied to the jupyter_work_dir and rendered in the chat history using an HTML <img> tag.
    • File Management: Uploaded files are added to the BotBackend message history.
    • Undo: undo_upload_file(state_dict, history) allows removing the last uploaded file from the history and the backend. If no revocable files remain, the undo button is disabled in the UI.
  12. Handle function calls and responses in BotBackend

    main

    When the model decides to use a tool (like execute_code), use add_function_call_response_message to append both the assistant's function call and the resulting tool output to the conversation history.

    • function_response: The string output from the tool. If the output is very long (> 500 chars), it is automatically truncated to preserve context window space.
    • save_tokens: Boolean flag to determine if the response should be processed for token saving logic.
    # After executing the code returned by the model:
    backend.add_function_call_response_message(
        function_response="12.0", 
        save_tokens=True
    )