1. Architecture Overview
Open Interpreter is a Python application that bridges large language models (LLMs) and local code execution. It equips a function-calling LLM with an exec() capability, accepting a language identifier and code string, then streams the model's messages, generated code, and execution output to the user via a terminal interface, Python API, or HTTP/WebSocket server.
The system operates in a request-response loop: the user provides natural language input, the LLM generates code, the code runs on the local machine, and the output feeds back to the LLM for further reasoning — repeating until the task is complete.
Architecture Diagram
┌─────────────────────────────────────────────────────────┐
│ User Input │
│ (Terminal CLI / Python API / Server) │
└───────────────────────┬─────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────┐
│ OpenInterpreter (core.py) │
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Messages[] │ │ System Msg │ │ Settings │ │
│ └──────┬──────┘ └──────────────┘ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────┐ │
│ │ respond.py │ │
│ │ (orchestrates LLM ↔ Computer loop) │ │
│ └──────┬──────────────────┬───────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────┐ ┌───────────────┐ │
│ │ LLM Layer │ │ Computer │ │
│ │ (llm.py) │ │ (computer.py) │ │
│ │ LiteLLM │ │ ┌─────────┐ │ │
│ │ routing │ │ │Terminal │ │ │
│ └────────────┘ │ │Languages│ │ │
│ │ └─────────┘ │ │
│ │ ┌─────────┐ │ │
│ │ │Keyboard │ │ │
│ │ │Mouse │ │ │
│ │ │Display │ │ │
│ │ │Browser │ │ │
│ │ │Files │ │ │
│ │ │AI │ │ │
│ │ └─────────┘ │ │
│ └───────────────┘ │
└─────────────────────────────────────────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌───────────────────────┐
│ LLM Provider │ │ Local OS / Runtime │
│ (OpenAI, etc.) │ │ (Python, bash, etc.) │
└─────────────────┘ └───────────────────────┘
Component Inventory
| Component | Path | Role |
|---|---|---|
OpenInterpreter |
interpreter/core/core.py |
Central orchestrator; holds state, settings, messages |
respond |
interpreter/core/respond.py |
Main LLM↔Computer response loop |
Llm |
interpreter/core/llm/llm.py |
LLM abstraction layer, delegates to LiteLLM |
Computer |
interpreter/core/computer/computer.py |
Computer control abstraction (terminal, keyboard, mouse, etc.) |
Terminal |
interpreter/core/computer/terminal/terminal.py |
Multi-language code execution engine |
AsyncInterpreter |
interpreter/core/async_core.py |
Async wrapper with WebSocket/REST server |
Server |
interpreter/core/async_core.py |
FastAPI server with authentication middleware |
terminal_interface |
interpreter/terminal_interface/terminal_interface.py |
Interactive CLI view layer |
start_terminal_interface |
interpreter/terminal_interface/start_terminal_interface.py |
CLI argument parsing and startup |
magic_commands |
interpreter/terminal_interface/magic_commands.py |
%command handlers for interactive sessions |
profiles |
interpreter/terminal_interface/profiles/profiles.py |
YAML/Python profile loading system |
computer_use |
interpreter/computer_use/loop.py |
Anthropic computer use (OS control) module |
Technology Stack
| Layer | Technology |
|---|---|
| Language | Python 3.11+ |
| LLM routing | LiteLLM |
| HTTP server | FastAPI + Uvicorn |
| WebSocket | FastAPI WebSocket |
| Async bridge | janus (sync↔async queue) |
| Terminal rendering | Rich (Markdown, code blocks, spinners) |
| Code scanning | semgrep (optional, for safe mode) |
| Computer vision | pytesseract (optional) |
| Telemetry | PostHog |
| Package management | Poetry |
| Code formatting | Black + isort (pre-commit hooks) |
| OS control | Anthropic computer use beta API |
Data Flow: Main Response Loop
- User input arrives (string or LMC message)
OpenInterpreter.chat()appends the message toself.messagesrespond()is called, which: a. Builds system prompt + conversation history b. Callsllm.run()(via LiteLLM) with function-calling enabled c. Streams response chunks as LMC messages- If the LLM returns code:
a. A confirmation chunk is yielded (unless
auto_run=True) b. On approval,computer.run(language, code)executes the code c. Output is appended as aconsolemessage and fed back to step 3 - Loop continues until the LLM produces a message-only response (no code)
- If
loop=True, the loop continues withloop_messageuntil aloop_breakerphrase appears
2. System Requirements
Runtime Requirements
| Requirement | Detail |
|---|---|
| Python | 3.11+ (3.11.7 used by installers) |
| pip | Latest |
| OS | Windows 10+, macOS 12+, Linux (glibc 2.17+) |
| Network | Internet access required for hosted LLMs; not required for local models |
Optional Dependencies by Feature
| Feature | Package | Install Extra |
|---|---|---|
| Server mode | fastapi, uvicorn, janus, shortuuid |
[server] |
| Local models | psutil, wget, inquirer |
[local] |
| OS control | anthropic |
[os] |
| Code scanning | semgrep |
Manual: pip install semgrep |
| Vision (local) | pytesseract |
Manual: pip install pytesseract |
| Token counting | tiktoken |
Bundled with litellm |
Development Requirements
| Tool | Version | Purpose |
|---|---|---|
| Poetry | 1.7+ | Dependency management |
| Black | 23.10.1 | Code formatting |
| isort | 5.12.0 | Import sorting |
| pre-commit | Latest | Git hooks |
| pytest | Latest | Testing |
3. Configuration Reference
Environment Variables
| Variable | Type | Default | Description | Required? |
|---|---|---|---|---|
OPENAI_API_KEY |
string | — | OpenAI API key | For OpenAI models |
ANTHROPIC_API_KEY |
string | — | Anthropic API key | For Claude models and OS mode |
INTERPRETER_API_KEY |
string | None |
API key for server authentication | No (server unauthenticated if unset) |
INTERPRETER_ID |
string | Current timestamp | Server instance identifier | No |
INTERPRETER_HOST |
string | 127.0.0.1 |
Server bind address | No |
INTERPRETER_PORT |
string | 8000 |
Server bind port | No |
INTERPRETER_REQUIRE_AUTH |
string | — | Enable WebSocket authentication | No |
INTERPRETER_REQUIRE_ACKNOWLEDGE |
string | False |
Require client ACK for WebSocket messages | No |
INTERPRETER_INSECURE_ROUTES |
string | — | Enable /run, /upload, /download endpoints |
No |
DISABLE_TELEMETRY |
string | false |
Disable PostHog telemetry | No |
EDITOR |
string | vim |
Editor for interactive editing | No |
Important
When
INTERPRETER_API_KEYis not set, the server accepts all requests without authentication. In production, always set this variable to restrict access.
CLI Flags (Complete Reference)
| Flag | Short | Type | Default | Description |
|---|---|---|---|---|
--profile |
-p |
string | default.yaml |
Profile file to load |
--custom_instructions |
-ci |
string | — | Appended to system message |
--system_message |
-sm |
string | (built-in) | Override the base system prompt |
--auto_run |
-y |
bool | False |
Auto-approve all code execution |
--no_highlight_active_line |
-nhl |
bool | False |
Disable active line highlighting |
--verbose |
-v |
bool | False |
Print detailed logs |
--model |
-m |
string | — | LLM model identifier |
--temperature |
-t |
float | — | Sampling temperature |
--llm_supports_vision |
-lsv |
bool | — | Force vision support flag |
--llm_supports_functions |
-lsf |
bool | — | Force function calling flag |
--context_window |
-cw |
int | — | Context window size (tokens) |
--max_tokens |
-x |
int | — | Max output tokens |
--max_budget |
-b |
float | — | Max spending in USD |
--api_base |
-ab |
string | — | Custom API endpoint URL |
--api_key |
-ak |
string | — | API key (overrides env) |
--api_version |
-av |
string | — | API version string |
--max_output |
-xo |
int | 2800 |
Max chars for code output |
--loop |
— | bool | False |
Loop until task completion |
--disable_telemetry |
-dt |
bool | False |
Disable telemetry |
--offline |
-o |
bool | False |
Disable online features |
--speak_messages |
-sp |
bool | False |
Read messages aloud (macOS) |
--safe_mode |
-safe |
string | off |
Code scanning: off, ask, auto |
--debug |
— | bool | False |
Developer debug mode |
--fast |
-f |
bool | — | Use gpt-4o-mini with concise mode |
--multi_line |
-ml |
bool | True |
Enable ``` multi-line input |
--local |
-l |
bool | — | Interactive local model setup |
--codestral |
— | bool | — | Codestral profile shortcut |
--assistant |
— | bool | — | Assistant profile shortcut |
--llama3 |
— | bool | — | Llama 3 profile shortcut |
--groq |
— | bool | — | Groq profile shortcut |
--vision |
-vi |
bool | — | Vision mode |
--os |
— | bool | — | OS control mode |
--reset_profile |
— | string | — | Reset a profile file to defaults |
--profiles |
— | bool | — | Open profiles directory |
--local_models |
— | bool | — | Open local models directory |
--conversations |
— | bool | — | List and resume conversations |
--server |
— | bool | — | Start server mode |
--version |
— | bool | — | Print version |
--contribute_conversation |
— | bool | False |
Share conversations for training |
--plain |
-pl |
bool | False |
Plain text output (no formatting) |
--stdin |
-s |
bool | — | Read from stdin, implies --plain |
Note
CLI flags override profile settings. The precedence order is: CLI flag > profile file > built-in default. The
--debug_modeflag is deprecated; use--verboseinstead.
OpenInterpreter Class Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
messages |
list | [] |
Conversation history (LMC format) |
offline |
bool | False |
Disable online features |
auto_run |
bool | False |
Skip code approval |
verbose |
bool | False |
Verbose logging |
debug |
bool | False |
Debug mode |
max_output |
int | 2800 |
Max chars for code output display |
safe_mode |
string | "off" |
Code scanning mode |
shrink_images |
bool | True |
Resize images sent to LLM |
loop |
bool | False |
Continue until task complete |
loop_message |
string | (built-in) | Message sent to LLM each loop iteration |
loop_breakers |
list | (4 phrases) | Phrases that break the loop |
disable_telemetry |
bool | False |
Disable PostHog telemetry |
multi_line |
bool | True |
Enable multi-line input |
conversation_history |
bool | True |
Save conversations to disk |
conversation_filename |
string | None |
Current conversation file name |
conversation_history_path |
string | OS-specific | Directory for conversation files |
os |
bool | False |
OS control mode |
speak_messages |
bool | False |
macOS TTS |
system_message |
string | (built-in) | Base system prompt |
custom_instructions |
string | "" |
Appended to system message |
user_message_template |
string | "{content}" |
Template for user messages |
code_output_template |
string | (built-in) | Template for code output messages |
empty_code_output_template |
string | (built-in) | Template when code produces no output |
code_output_sender |
string | "user" |
Role for code output messages |
contribute_conversation |
bool | False |
Share conversations for training |
plain_text_display |
bool | False |
Disable rich formatting |
highlight_active_line |
bool | True |
Highlight executing line |
LLM Sub-Object (interpreter.llm)
| Attribute | Type | Default | Description |
|---|---|---|---|
model |
string | — | LiteLLM model identifier |
temperature |
float | — | Sampling temperature |
api_key |
string | — | API key |
api_base |
string | — | Custom API endpoint |
api_version |
string | — | API version |
max_tokens |
int | — | Max output tokens |
max_budget |
float | — | Spending cap (USD) |
context_window |
int | — | Context window size |
supports_vision |
bool | — | Model accepts image inputs |
supports_functions |
bool | — | Model supports function calling |
Profile System
Profiles are stored in the OS-specific data directory under Open Interpreter/profiles/. The path can be opened with:
interpreter --profiles
YAML profiles set attributes directly:
# default.yaml
system_message: "You are a helpful assistant."
llm:
model: gpt-4o
temperature: 0.7
auto_run: false
Python profiles receive the interpreter object and can run arbitrary setup code:
# local.py
interpreter.llm.model = "ollama/llama3"
interpreter.llm.api_base = "http://localhost:11434"
interpreter.offline = True
Built-in profiles are in interpreter/terminal_interface/profiles/defaults/ and include configurations for: default.yaml, fast.yaml, vision.yaml, os.py, local.py, local-os.py, codestral.py, codestral-vision.py, codestral-os.py, llama3.py, llama3-vision.py, llama3-os.py, groq.py, assistant.py, e2b.py, obsidian.py, screenpipe.py, template_profile.py, and others.
Data Storage Locations
| Data | Path | Format |
|---|---|---|
| Conversations | ~/.local/share/Open Interpreter/conversations/ |
JSON |
| Profiles | ~/.local/share/Open Interpreter/profiles/ |
YAML/Python |
| Local models | ~/.local/share/Open Interpreter/models/ |
Llamafile binaries |
| Contribution cache | ~/.cache/open-interpreter/contribute.json |
JSON |
| Telemetry UUID | ~/.cache/open-interpreter/telemetry_user_id |
Plain text |
Note
Paths vary by OS. On macOS, the base is
~/Library/Application Support/Open Interpreter/. On Windows,%LOCALAPPDATA%\Open Interpreter\. Theget_storage_path()function ininterpreter/terminal_interface/utils/local_storage_path.pydetermines the actual path.
4. Deployment & Scaling
Server Mode Deployment
Start the server:
interpreter --server
The server binds to 127.0.0.1:8000 by default. Override with environment variables:
export INTERPRETER_HOST=0.0.0.0
export INTERPRETER_PORT=9000
interpreter --server
Warning
Setting
INTERPRETER_HOST=0.0.0.0exposes Open Interpreter to your entire local network. Always setINTERPRETER_API_KEYwhen binding to0.0.0.0.
Server Authentication
Set INTERPRETER_API_KEY to enable API key authentication:
export INTERPRETER_API_KEY=your-secret-key
Clients must include the key in the X-API-KEY header:
curl -H "X-API-KEY: your-secret-key" http://localhost:8000/heartbeat
The /heartbeat endpoint is always unauthenticated (for health checks).
WebSocket authentication uses a separate flow: clients send {"auth": "your-key"} as the first message. The server responds with {"auth": true} or {"auth": false}.
Docker Deployment
The repository includes a Dockerfile and an example Dockerfile in examples/:
FROM python:3.11-slim
RUN pip install open-interpreter
CMD ["interpreter", "--server"]
API Endpoints Reference
Core Server (async_core.py)
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/heartbeat |
No | Health check; returns {"status": "alive"} |
GET |
/ |
Yes | Test UI HTML page with WebSocket client |
POST |
/ |
Yes | Post LMC input payload |
POST |
/settings |
Yes | Update interpreter settings |
GET |
/settings/{setting} |
Yes | Get a specific setting value |
POST |
/openai/chat/completions |
Yes | OpenAI-compatible chat completions endpoint |
WebSocket |
/ |
Yes | Full-duplex LMC message streaming |
Insecure Routes (enabled when INTERPRETER_INSECURE_ROUTES=true)
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/run |
Yes | Execute code: {"language": "python", "code": "..."} |
POST |
/upload |
Yes | Upload a file to a specified path |
GET |
/download/{filename} |
Yes | Download a file |
Caution
The
/run,/upload, and/downloadendpoints allow arbitrary code execution and file system access. Only enableINTERPRETER_INSECURE_ROUTESin trusted, isolated environments.
OpenAI-Compatible Endpoint
POST /openai/chat/completions accepts standard OpenAI chat completion requests:
{
"model": "open-interpreter",
"messages": [{"role": "user", "content": "Hello"}],
"stream": true
}
Special control tokens in the content field:
| Token | Effect |
|---|---|
{STOP} |
Stop current response |
{CONTEXT_MODE_ON} |
Enable context accumulation mode |
{CONTEXT_MODE_OFF} |
Disable context mode |
{AUTO_RUN_ON} |
Enable auto-run |
{AUTO_RUN_OFF} |
Disable auto-run |
{START} |
Signal start of speech input (context mode) |
WebSocket Protocol (LMC Messages)
Messages are JSON objects in the LMC (Language Model Computer) format:
{"role": "user", "type": "message", "start": true}
{"role": "user", "type": "message", "content": "Hello"}
{"role": "user", "type": "message", "end": true}
Commands sent via WebSocket:
{"role": "user", "type": "command", "start": true}
{"role": "user", "type": "command", "content": "go"}
{"role": "user", "type": "command", "end": true}
The "go" command approves pending code execution. The "stop" command halts the current response.
Server responses follow the same format:
{"role": "assistant", "type": "message", "content": "I'll help..."}
{"role": "assistant", "type": "code", "format": "python", "content": "print('hello')"}
{"role": "computer", "type": "console", "format": "output", "content": "hello"}
{"role": "server", "type": "status", "content": "complete"}
{"role": "server", "type": "error", "content": "...traceback..."}
When INTERPRETER_REQUIRE_ACKNOWLEDGE=true, each output includes an "id" field and the client must respond with {"ack": "<id>"}.
Computer Use Server Mode
The interpreter/computer_use/loop.py module can also run as a standalone server:
python -m interpreter --os --server
This starts the computer_use module's FastAPI server with a single /openai/chat/completions endpoint that routes to the Anthropic computer use sampling loop.
5. Operations
Conversation History Management
Conversations are saved as JSON files in the conversations directory. Each file contains the full messages array.
List conversations:
interpreter --conversations
Programmatic access:
from interpreter.terminal_interface.utils.get_conversations import get_conversations
conversations = get_conversations()
Export conversation:
%jupyter # Export to Jupyter notebook
%markdown report # Export to report.md
Tip
Conversation files are named with a summary and date. Use
interpreter --conversationsto browse them interactively, or navigate directly to the storage directory.
Telemetry
Open Interpreter sends anonymous usage events to PostHog with the following data:
- Event name (e.g., session start)
- Open Interpreter version
- Anonymous UUID (generated once, stored in
~/.cache/open-interpreter/telemetry_user_id)
No conversation content, code, or personal information is transmitted.
Disable telemetry:
interpreter --disable_telemetry
# or
export DISABLE_TELEMETRY=true
Health Monitoring
The server exposes a /heartbeat endpoint:
curl http://localhost:8000/heartbeat
{"status": "alive"}
System Diagnostics
Use the %info magic command or programmatically:
from interpreter.core.utils.system_debug_info import system_info
system_info(interpreter)
This reports: Python version, pip version, Open Interpreter version, OS, CPU, RAM, model settings, vision/function-calling support, auto-run state, and current message history.
Note
The
%infocommand reveals all current interpreter settings including API base URLs. Use it for debugging but be cautious when sharing output publicly.
6. Performance
Token Usage and Cost Management
The %tokens magic command shows estimated token usage for the next request:
> %tokens
Tokens sent with next request as context: 1234 (Estimated Cost: $0.0123)
Cost estimation depends on LiteLLM's cost_per_token() function and may not be accurate for all providers.
Output Truncation
When code output exceeds max_output characters (default: 2800), it is truncated showing the first and last halves. The truncation message suggests strategies:
- Store results in variables:
result = command() - Summarize with AI:
computer.ai.summarize(result) - Search with Python:
result.find('text') - Use shell tools:
wc,grep,sed
Increase the limit with --max_output:
interpreter --max_output 10000
Context Window Optimization
For local models with limited RAM:
| RAM | Recommended context_window |
Recommended max_tokens |
|---|---|---|
| < 10 GB | 3000 | 1000 |
| 10-30 GB | 8000 | 1200 |
| 30+ GB | 16000+ | 4096 |
The code automatically sets these based on detected RAM when using --local.
7. Security
Code Execution Safety
Open Interpreter executes LLM-generated code directly on the host machine. This is inherently risky. The following safety mechanisms exist:
Approval prompt (default): Every code block requires user approval before execution. This is the primary safety mechanism.
Auto-run (-y): Bypasses the approval prompt entirely. Only use in supervised, disposable environments.
Safe mode (--safe_mode):
| Mode | Behavior |
|---|---|
off |
No code scanning (default) |
ask |
Scans code with semgrep before asking for approval |
auto |
Scans code with semgrep and auto-approves if clean |
Warning
Safe mode requires
semgrepto be installed (pip install semgrep). Without it, safe mode silently falls back to no scanning. If bothsafe_modeandauto_runare enabled,safe_modetakes precedence and disablesauto_run.
Code scanning implementation: The scan_code() function in interpreter/core/utils/scan_code.py writes the generated code to a temporary file, runs semgrep scan --config auto --quiet --error against it, and reports the result.
Server Security
API key authentication: Set INTERPRETER_API_KEY to require authentication on all endpoints (except /heartbeat).
WebSocket authentication: When INTERPRETER_REQUIRE_AUTH is not "False", WebSocket clients must authenticate with {"auth": "key"} before sending messages.
Auto-run protection: The server's /settings endpoint explicitly blocks setting auto_run via the API to prevent remote exploitation.
Insecure routes: The /run, /upload, and /download endpoints are disabled by default. They require INTERPRETER_INSECURE_ROUTES=true to enable.
Caution
Never expose the Open Interpreter server to the public internet. It provides direct code execution capabilities. If you must expose it, place it behind a reverse proxy with additional authentication and restrict to trusted IP ranges.
Telemetry Privacy
Telemetry sends only:
- Event name
- Package version
- Anonymous UUID
The PostHog API key is hardcoded in interpreter/core/utils/telemetry.py. No conversation content, code, or API keys are transmitted.
Contribution Data
When contribute_conversation=True or using model i, conversation data is sent to https://api.openinterpreter.com/v0/contribute/. This includes:
- Full conversation messages
- Open Interpreter version
- Optional user feedback
8. Developer Internals
Repository Structure
open-interpreter/
├── interpreter/ # Main Python package
│ ├── __init__.py # Entry point: OS mode routing, exports
│ ├── core/ # Core engine
│ │ ├── core.py # OpenInterpreter class
│ │ ├── respond.py # LLM↔Computer response loop
│ │ ├── render_message.py # Message rendering
│ │ ├── default_system_message.py # Built-in system prompt
│ │ ├── async_core.py # AsyncInterpreter + Server + API routes
│ │ ├── archived_server_1.py # Legacy server implementation (simple)
│ │ ├── archived_server_2.py # Legacy server implementation (WebSocket)
│ │ ├── llm/ # LLM layer
│ │ │ ├── llm.py # Llm class (LiteLLM wrapper)
│ │ │ ├── run_function_calling_llm.py
│ │ │ ├── run_text_llm.py
│ │ │ ├── run_tool_calling_llm.py
│ │ │ └── utils/
│ │ │ ├── convert_to_openai_messages.py # LMC → OpenAI format
│ │ │ ├── merge_deltas.py # Stream delta merging
│ │ │ └── parse_partial_json.py # Incremental JSON parser
│ │ ├── computer/ # Computer control layer
│ │ │ ├── computer.py # Computer class (aggregator)
│ │ │ ├── terminal/ # Code execution
│ │ │ │ ├── terminal.py
│ │ │ │ ├── base_language.py # Language plugin interface
│ │ │ │ └── languages/ # Python, JS, Shell, Ruby, R, Java, etc.
│ │ │ ├── keyboard/ # Keyboard control
│ │ │ ├── mouse/ # Mouse control
│ │ │ ├── display/ # Screen capture and OCR
│ │ │ ├── browser/ # Browser automation
│ │ │ ├── files/ # File operations
│ │ │ ├── clipboard/ # Clipboard access
│ │ │ ├── ai/ # AI helper (computer.ai.chat)
│ │ │ ├── calendar/ # Calendar access
│ │ │ ├── contacts/ # Contacts access
│ │ │ ├── mail/ # Email access
│ │ │ ├── sms/ # SMS access
│ │ │ ├── os/ # OS-level operations
│ │ │ ├── skills/ # Learned skills storage
│ │ │ ├── docs/ # Documentation helper
│ │ │ └── vision/ # Vision module
│ │ └── utils/
│ │ ├── lazy_import.py # Lazy module loading
│ │ ├── scan_code.py # semgrep code scanning
│ │ ├── system_debug_info.py # System diagnostics
│ │ ├── telemetry.py # PostHog telemetry
│ │ ├── temporary_file.py # Temp file management
│ │ └── truncate_output.py # Output truncation logic
│ ├── terminal_interface/ # CLI view layer
│ │ ├── start_terminal_interface.py # Argument parsing + startup
│ │ ├── terminal_interface.py # Main interactive loop
│ │ ├── magic_commands.py # %command handlers
│ │ ├── validate_llm_settings.py # Model/API validation
│ │ ├── conversation_navigator.py # Conversation browser
│ │ ├── local_setup.py # Local model setup wizard
│ │ ├── contributing_conversations.py # Data contribution flow
│ │ ├── render_past_conversation.py # Past conversation display
│ │ ├── components/ # Rich terminal blocks
│ │ │ ├── base_block.py
│ │ │ ├── code_block.py
│ │ │ └── message_block.py
│ │ ├── profiles/ # Profile system
│ │ │ ├── profiles.py # Load/save profiles
│ │ │ ├── historical_profiles.py
│ │ │ └── defaults/ # Built-in profiles
│ │ └── utils/ # Terminal utilities
│ │ ├── check_for_package.py
│ │ ├── check_for_update.py
│ │ ├── cli_input.py # Multi-line input handler
│ │ ├── count_tokens.py # Token counting + cost
│ │ ├── display_markdown_message.py
│ │ ├── display_output.py
│ │ ├── export_to_markdown.py
│ │ ├── find_image_path.py
│ │ ├── get_conversations.py
│ │ ├── in_jupyter_notebook.py
│ │ ├── local_storage_path.py
│ │ └── oi_dir.py
│ └── computer_use/ # Anthropic computer use
│ ├── loop.py # Computer use sampling loop + server
│ ├── unused_markdown.py # Markdown streaming parser (unused)
│ └── tools/
│ ├── base.py # ToolResult, BaseAnthropicTool
│ ├── bash.py # Bash tool
│ ├── computer.py # Computer tool (screenshots, clicks)
│ ├── edit.py # File edit tool
│ ├── collection.py # Tool collection manager
│ └── run.py # Run tool
├── installers/ # Platform-specific installers
├── examples/ # Jupyter notebooks and examples
├── tests/ # Test suite
├── docs/ # Documentation (Mintlify-based)
├── scripts/ # Utility scripts
├── pyproject.toml # Poetry project configuration
├── Dockerfile # Container build
└── LICENSE # AGPL license
Key Design Patterns
LMC Message Format: All internal communication uses Language Model Computer (LMC) messages — dictionaries with role (user, assistant, computer, server), type (message, code, console, image, command, confirmation, error, status), optional format (language name, output, active_line, base64), and content.
Streaming Architecture: The respond() generator yields LMC chunks one at a time. The terminal interface, server, and Python API all consume this same generator, making the output layer interchangeable.
Language Plugin System: Each executable language (Python, JavaScript, Shell, etc.) implements the BaseLanguage interface with run(code) (generator yielding LMC chunks), stop(), and terminate() methods. New languages can be added by creating a file in interpreter/core/computer/terminal/languages/.
Lazy Imports: The lazy_import() utility defers loading of optional packages (e.g., uvicorn, fastapi) until first use, keeping startup time fast when those features aren't needed.
Output Truncation: truncate_output() in interpreter/core/utils/truncate_output.py splits large outputs into first-half + last-half with a truncation notice, keeping max_output / 2 characters from each end.
Profile Precedence: Default values → Profile file → CLI arguments. CLI always wins.
Module Reference
interpreter/core/core.py — OpenInterpreter
The central class. Key methods:
__init__()— 40+ configurable parameters (see Configuration Reference above)chat(message, display, stream, blocking)— Main entry point. Returns messages list or generatorreset()— Clears messages and resets statedisplay_message(markdown)— Renders markdown to terminalget_oi_dir()— Returns the OI data directory path
The chat() method handles both interactive and programmatic modes. When stream=True, it returns a generator of LMC chunks. When display=True (default in terminal), output is rendered in real-time via Rich blocks.
interpreter/core/respond.py — Response Loop
respond(interpreter) is the core orchestration generator. It:
- Sends the message history to the LLM
- Yields each response chunk
- When code is encountered, yields a confirmation chunk
- On approval, executes code via
interpreter.computer.run() - Feeds output back to the LLM
- Handles the
loopmode re-prompting
interpreter/core/async_core.py — AsyncInterpreter & Server
AsyncInterpreter extends OpenInterpreter with:
- Thread-safe input/output via
janus.Queue - WebSocket message accumulation (
accumulate()) - Stop event handling for interruption
- Server instance (
self.server)
Server wraps a FastAPI app with:
- API key middleware (skipped for
/heartbeat) - All routes from
create_router() - Configurable host/port
interpreter/core/llm/utils/convert_to_openai_messages.py
Converts LMC message format to OpenAI API format. Handles text, code, images (base64 and path), and vision inputs. This is critical for compatibility with function-calling and tool-calling LLM APIs.
interpreter/computer_use/loop.py — Computer Use
Implements Anthropic's computer use beta API. The sampling_loop() async generator:
- Creates a
ToolCollectionwithComputerTool(and optionallyBashTool,EditTool) - Calls
client.beta.messages.create()with streaming - Processes tool use blocks, executes tools, feeds results back
- Continues until no tool calls remain
Supports providers: anthropic (direct), bedrock, vertex.
interpreter/terminal_interface/start_terminal_interface.py — CLI Entry Point
Defines all 40+ CLI arguments, parses them with argparse, applies profile shortcuts, validates LLM settings, and launches either:
interpreter.server.run()(server mode)conversation_navigator(interpreter)(conversations mode)interpreter.chat()(interactive mode)
The "ultra fast" i command pattern: if the first argument doesn't start with -, it's treated as a natural language command (interpreter make me a website), enabling one-shot execution.
Error Handling Patterns
LLM retry loop: AsyncInterpreter.respond() retries up to 5 times when the LLM produces no chunks, appending escalating prompts ("Hello? Answer please.", "Just say something, anything.").
Graceful keyboard interrupt: main() in start_terminal_interface.py catches KeyboardInterrupt, terminates computer processes, optionally asks for feedback, and submits conversation data if contributing.
Lazy import fallback: lazy_import(name, optional=True) returns None instead of raising ImportError for optional packages, enabling graceful degradation.
Testing
Tests are located in tests/:
| File | Purpose |
|---|---|
tests/test_interpreter.py |
Core interpreter functionality |
tests/core/test_async_core.py |
Server host/port configuration |
tests/core/computer/test_computer.py |
Computer module tests |
tests/core/computer/files/test_files.py |
File operations tests |
tests/config.test.yaml |
Test configuration |
Run tests:
poetry run pytest -s -x
The test suite is minimal relative to the codebase size. test_async_core.py tests server construction with default, explicit, and environment variable host/port configurations.
Code Style and Contributing
Formatting: Black (line length default) + isort, enforced via pre-commit hooks.
pip install pre-commit
pre-commit install
Manual formatting:
black .
isort .
Contributing workflow:
- Fork the repository
- Create a feature branch
- Install with Poetry:
poetry install - Run the fork:
poetry run interpreter - Run tests:
poetry run pytest -s -x - Submit a PR into
main
Optional extras for development:
poetry install -E local # For --local mode
poetry install -E os # For --os mode
poetry install -E local -E os # Both
License: AGPL for contributions after version 0.2.0 (MIT for earlier contributions).
9. Integration Points
LiteLLM Provider Support
Open Interpreter supports any LLM provider that LiteLLM supports. Model identifiers follow LiteLLM conventions:
| Provider | Model Format Example |
|---|---|
| OpenAI | gpt-4o, gpt-3.5-turbo |
| Anthropic | claude-3-5-sonnet-20240620 |
| Ollama | ollama/llama3 |
| Azure | azure/gpt-4 |
| AWS Bedrock | bedrock/anthropic.claude-3 |
| Google Vertex | vertex_ai/gemini-pro |
| Groq | groq/llama3-8b-8192 |
| Together AI | together_ai/... |
| Custom endpoint | openai/model-name + --api_base |
When --api_base is set and the model doesn't start with a recognized prefix (openai/, azure/, ollama, jan, local), the code automatically prepends openai/.
OpenAI-Compatible Server Integration
Other applications can connect to Open Interpreter's server as if it were an OpenAI API:
import openai
client = openai.OpenAI(
base_url="http://localhost:8000/openai",
api_key="your-interpreter-api-key"
)
response = client.chat.completions.create(
model="open-interpreter",
messages=[{"role": "user", "content": "List files in the current directory"}],
stream=True
)
E2B Sandbox Integration
The built-in e2b.py profile configures Open Interpreter to execute code in an E2B cloud sandbox instead of locally, providing isolation for untrusted workloads.
Docker / Containerized Execution
The repository's Dockerfile provides a basic containerized setup. For sandboxed code execution, community issue #1536 tracks implementing a dedicated sandbox, and #1717 proposes a Wasm-based code interpreter.
10. Troubleshooting
Server Fails to Start
Cause: Missing server dependencies.
Solution:
pip install "open-interpreter[server]"
WebSocket Connection Drops
Cause: Client not acknowledging messages when INTERPRETER_REQUIRE_ACKNOWLEDGE=true.
Solution: Ensure your WebSocket client sends {"ack": "<id>"} for every received message with an id field. The server retries up to 20 times before marking a message as unsent.
Tip
Set
INTERPRETER_REQUIRE_ACKNOWLEDGE=False(or leave it unset) for simpler integrations that don't need delivery guarantees.
Model Produces No Output
Cause: Incompatible model, wrong API base, or rate limiting.
Solution:
- Enable verbose mode:
interpreter --verbose - Check the model supports function calling:
--llm_supports_functions - Verify API connectivity:
curl $API_BASE/models - Try a known-working model:
interpreter --model gpt-4o
OS Mode Mouse/Keyboard Not Working
Cause: Missing accessibility permissions (macOS) or display server access (Linux).
Solution:
- macOS: Grant accessibility permissions to Terminal/iTerm in System Settings
- Linux: Ensure X11/Wayland display is accessible
- All: Move mouse to screen corner to verify the exit mechanism works
Warning
OS mode's emergency exit is triggered by moving the mouse to any screen corner. If this fails, close the terminal window or use
killto terminate the process.
11. Reference
LMC Message Types
| Role | Type | Format | Description |
|---|---|---|---|
user |
message |
— | User text input |
user |
image |
base64.{format}, path, description |
Image input |
user |
command |
— | Control command (go, stop) |
assistant |
message |
— | LLM text response |
assistant |
code |
Language name | Generated code |
computer |
console |
output |
Code execution output |
computer |
console |
active_line |
Currently executing line number |
computer |
image |
base64 |
Generated image |
server |
status |
— | Server status (complete) |
server |
error |
— | Error with traceback |
server |
completion |
— | Legacy completion signal |
Supported Languages
| Language | Class | File Extension | Aliases |
|---|---|---|---|
| Python | Python |
.py |
python, py |
| Shell | Shell |
.sh |
bash, sh, zsh |
| JavaScript | JavaScript |
.js |
javascript, js |
| HTML | HTML |
.html |
html |
| AppleScript | AppleScript |
.applescript |
applescript |
| R | R |
.r |
r |
| Ruby | Ruby |
.rb |
ruby |
| PowerShell | PowerShell |
.ps1 |
powershell |
| React | React |
.jsx |
react |
| Java | Java |
.java |
java |
| Jupyter | Jupyter |
.ipynb |
jupyter |
Default System Message
The built-in system message (in interpreter/core/default_system_message.py) instructs the LLM to:
- Write and execute code to complete tasks
- Try to accomplish goals in as few steps as possible
- Minimize the use of
print()in Python - Use the appropriate language for each task (shell for file operations, Python for data, etc.)
The message can be fully overridden with --system_message or extended with --custom_instructions.