Skip to content

open-interpreter

Open Interpreter (catalog agent open-interpreter) today is a terminal CLI that is a Rust fork of OpenAI Codex CLI: it keeps Codex's protocol and file formats and moves the home to its own directory, ~/.openinterpreter. This document leans on codex-cli.md for everything the fork shares and records only what was checked in the fork and what differs. The Python tool of 2023-2025 that carried the name left its own paths, described under Legacy Python SDK and CLI (0.x). The agent is parsed: transcripts are Codex rollouts, byte for byte, so the Codex parser (doubleagent/parsers/codex.py) reads them through its shared RolloutParser; the legacy tool's conversations/*.json files are collected but not parsed yet (issue 70).

Source and evidence

openinterpreter/openinterpreter (the old open-interpreter URL redirects there), Apache-2.0, open source, commit 2767e5f20d6927500b8f1938c773c61afb823245 (2026-10-02). All claims are from source. Paths below are relative to codex-rs/ unless they start with another top-level directory.

The current Open Interpreter is a Rust fork of OpenAI Codex CLI, not the Python tool of 2023-2025: "Open Interpreter is a fork of OpenAI's Codex" (README.md:46), and it keeps Codex crate names, protocol names and file names on purpose (FORK_BRANDING.md:3-6, 67-78). The layout under the home directory is therefore the Codex layout described in codex-cli.md, moved to a different directory. The current source contains no reference to the Python-era paths (platformdirs open-interpreter config, profiles/*.yaml, conversations/*.json); a grep of the tree for them finds nothing. Those paths are still on disk wherever the Python tool was used, so they were researched separately in the agent framework sweep for issue 64 (see frameworks.md) and are described under Legacy Python SDK and CLI (0.x).

Observed

  • No real install.

Source reviews

Collection

Per-user storage

Home resolution (utils/home-dir/src/lib.rs:5-36, 67-90): when the running product is Open Interpreter, INTERPRETER_HOME if set (must exist), else dirs::home_dir()/.openinterpreter. CODEX_HOME is deliberately ignored "so the two products stay isolated". No OS branching: ~/.openinterpreter on Linux and macOS, %USERPROFILE%\.openinterpreter on Windows. The product is chosen by codex-package.json variant: "open-interpreter" next to the binary, or an executable named interpreter* or i (product-info/src/lib.rs:180-218). The installers default to the same directory and, unlike the runtime, fall back to CODEX_HOME (scripts/install/install.sh:15-22, install.ps1:922-930).

Inside ~/.openinterpreter, the same names as Codex:

Executables are installed to ~/.local/bin and %LOCALAPPDATA%\Programs\Open Interpreter\bin (installers, lines cited above and install.ps1:941); the package itself lands in ~/.openinterpreter/packages/standalone.

Legacy Python SDK and CLI (0.x)

Checked at tag v0.4.2, commit 13061d2ce0ac35344f04c5285e795415cccf259d (2024-10-24), AGPL-3.0 at that tag. PyPI's last release, 0.4.3, has no git tag; its sdist was downloaded and its path calls (platformdirs.user_*, expanduser("~"), get_storage_path(...)) are identical to v0.4.2. The base directory is platformdirs.user_config_dir("open-interpreter") (oi_dir.py:3, local_storage_path.py:6-13; pin platformdirs = "^4.2.0", pyproject.toml:58), which is ~/.config/open-interpreter on Linux (platformdirs unix.py:49-51), ~/Library/Application Support/open-interpreter on macOS (macos.py:22-23, 40-42), and %LOCALAPPDATA%\open-interpreter\open-interpreter on Windows (the config directory is the local data directory, with the app name doubled as author; windows.py:32-44, 60-62). Under it:

  • conversations/<first words>__<Month_DD_YYYY_HH-MM-SS>.json: the full message list, a JSON array, of every chat from the CLI and from the SDK's interpreter.chat(), by default (conversation_history=True) (core.py:62-64, 261-290). This is not a Codex rollout, and the analyzer's Open Interpreter parser does not read it.
  • profiles/default.yaml and other profiles/*.yaml, .py or .json, created on first run; they may hold llm.api_key (profiles.py:19-20, 613-626, default.yaml:9).
  • skills/: agent-saved Python skills in OS mode (skills.py:26).
  • models/: downloaded .llamafile weights, gigabytes, only after the --local setup (local_setup.py:393-398, 51-63).
  • *.png at the root: temporary HTML render images (html_to_png_base64.py:21-29).

Outside the base directory, ~/.cache/open-interpreter/telemetry_user_id and contribute.json (expanduser, every OS) hold the telemetry UUID and the contribution opt-in (telemetry.py:24-29, contributing_conversations.py:14-16). Older layouts stay in place, because the migration copies and never deletes: user_config_dir("Open Interpreter") before 0.2.0 and user_config_dir("Open Interpreter Terminal") in 0.2.0, each with conversations/, profiles/ and config.yaml (profiles.py:682-686, 709-739, 756-765). The catalog covers all of these since collector 1.10.0 (.config/Open Interpreter* and its macOS and Windows equivalents); open-interpreter and Open Interpreter differ by hyphen and space, not only by case, so issue 29 does not apply. The legacy tool runs shell commands through a subprocess, with auto_run=False by default (shell.py:8-20, core.py:46). The unreleased development branch (1.0.0, commit fa06bfda18b70546baa85b9d314873e048f70c99) uses ~/.openinterpreter/default_profile.py (profiles.py:29-30), inside the current catalog entry; its api_key field (profiles.py:44) is not flagged, since that branch was never released to PyPI.

Standing grants

At ac1fcc8 the fork keeps Codex's code for these and for the scratch directories, described in Standing grants and approval records and Scratch directories in codex-cli.md.

rules/default.rules, the exec policy file Codex appends "approve and remember" and network rules to (codex-rs/core/src/exec_policy.rs:54-56), and config.toml project trust_level and tool approval_mode entries (codex-rs/core/src/config/mod.rs:2373, codex-rs/core/src/mcp_tool_call.rs:2291, 2334, 2369). Collected by the open-interpreter|.openinterpreter line.

Scratch directories

Thread worktrees in .openinterpreter/worktrees/<4 hex>/<repository name>, or under config.toml [desktop] git-worktree-root (codex-rs/worktree/src/settings.rs:12, 44). The default location is excluded (Exclusions); project discovery reads .openinterpreter/sessions and archived_sessions and, from collector 1.18.0, drops a cwd under <home>/.openinterpreter/worktrees (issue 222), so only a worktree under a configured git-worktree-root is discovered as a project. The .zcode/cli/artifacts spill directory is the agent's own output, under the catalog line.

Credentials

Exclusions

Same as Codex: packages/ (managed binaries), cache/, .tmp/, tmp/, plugins/cache (core-plugins/src/store.rs:26), skills/.system (skills/src/lib.rs:57), worktrees/ (worktree/src/settings.rs:44), visualizations/ (tui/src/inline_visualization.rs:92), .sandbox, .sandbox-bin, plus the fork's models-cache/. .zcode/cli/plugins/cache is only referenced as a display path for the emulated skill (harness_aliases.rs:2853-2858); nothing writes it. Keep .zcode/cli/artifacts: it holds full tool output. For the legacy Python tool, models/ in the base directory (llamafile weights).

Project-local files

Where the project path is recorded

As in Codex: session_meta first line of every rollout, payload.cwd (protocol/src/protocol.rs:3117-3141), and the threads table in state_5.sqlite. The existing Codex discovery (grep -ho '"cwd":"[^"]*"' over sessions/**/*.jsonl) applies unchanged with .openinterpreter in place of .codex; .jsonl.zst rollouts need zstd first.

A rollout cwd under .openinterpreter/worktrees (or a configured git-worktree-root) is a scratch directory rather than a project (Scratch directories), and discovery skips one under the default location; config.toml [projects."<path>"] tables name the projects the user trusted or distrusted.

Parsing

Transcript stores

What survives a delete

As in Codex (What survives a delete in codex-cli.md), thread/delete removes the thread's rollouts, its index lines and its rows in the SQLite stores, logs_2.sqlite included, and with them the session synced: Sentry feedback marker (codex-rs/state/src/runtime/threads.rs:1153, codex-rs/thread-store/src/local/delete_thread.rs:262). It leaves history.jsonl, one line per submitted prompt with its session id and time, and the import ledger external_agent_session_imports.json, which names the rollouts imported from Claude Code or Cursor. The memories files (off by default) and db-backups/ exist as in Codex (Memories and database backups); what a delete does to them is not stated in this document. No deletion marker is written. The analyzer reads history.jsonl, state_5.sqlite, thread_history_1.sqlite and the db-backups/ copies of state_5.sqlite as secondary sources, the memory rollout summaries as a source of their own and the import ledger to mark imported rollouts (Past use and secondary sources; see Secondary sources).

Record schema

Each line is RolloutLine: timestamp, optional ordinal, and the flattened item (history/src/lib.rs:277-284), serialised as {"type": <snake_case variant>, "payload": {...}} with an optional metadata on response_item (history/src/rollout_payload.rs:22-62). timestamp is UTC, YYYY-MM-DDThh:mm:ss.mmmZ (rollout/src/recorder.rs:2054-2059). Types: session_meta, response_item, inter_agent_communication, inter_agent_communication_metadata, compacted, turn_context, token_usage_record, world_state, retained_context, security_risk_score, event_msg, realtime_item.

  • session_meta payload (protocol/src/protocol.rs:3117-3154): session_id, id (thread), forked_from_id?, parent_thread_id?, timestamp, cwd, runtime_workspace_roots?, originator, cli_version, source, agent_nickname?, agent_role?, agent_path?, model_provider, base_instructions; plus git with commit_hash, branch, repository_url (protocol.rs:3222-3228, 3423-3437). originator defaults to codex_cli_rs in the fork too (login/src/auth/default_client.rs:42,64-68), so only the file's location tells Open Interpreter from Codex.
  • turn_context: turn_id, cwd, model, approval_policy, sandbox_policy, permission_profile, network, timezone, effort and more, the same field names as Codex's turn_context (protocol.rs:3287-3343). The emulated harness (claude-code, kimi-code, zcode and others) is a config.toml key (config/src/config_toml.rs:166-170) and is not recorded per turn.
  • response_item payload, tagged by type (protocol/src/models.rs:1009-1011): message (role, content blocks, phase?; 1020-1035), reasoning (summary, content?, encrypted_content; 1047-1059), local_shell_call (call_id, status, action; 1060-1072), function_call (name, namespace?, arguments JSON string, call_id; 1073-1092), function_call_output (call_id, name?, output; 1113-1132), custom_tool_call, custom_tool_call_output, tool_search_call, tool_search_output, web_search_call. The harness emulation renames tools (Bash, Read, Grep and so on in the claude-code harness, core/src/harness/claude_code.rs:1287), so name values are not the Codex set.
  • event_msg: UI events (task_started, task_complete, token_count, ...), as in Codex.

history.jsonl: {session_id, ts, text}, ts epoch seconds (message-history/src/lib.rs:62-66,128-131).

Joins and timestamps

Session to project: session_meta.payload.cwd, updated per turn by turn_context.payload.cwd. Tool call to result: call_id. Subagent to parent: session_meta.payload.parent_thread_id and forked_from_id. Imported chats: external_agent_session_imports.json records[] with source_path (the original ~/.claude/projects/... or ~/.cursor/... file), content_sha256, imported_thread_id (the rollout's thread id) and imported_at, source_modified_at (epoch) (external-agent-sessions/src/ledger.rs:18-30). A rollout whose thread id is in that ledger was written by /import (external-agent-sessions/src/export.rs:58-73), so its turns were authored in another agent and their record timestamps are import time.

Other stores

Same SQLite set as Codex (state_5.sqlite, logs_2.sqlite, thread_history_1.sqlite and others; state/src/sqlite.rs:29-34); the rollouts are the primary record. zstd for .jsonl.zst rollouts.

state_5.sqlite and thread_history_1.sqlite are parsed as secondary sources by the shared Codex reader (issue 122); their record shapes, joins and what they survive are in Other stores in codex-cli.md. The fork's threads migrations that the parser reads match Codex's (state/migrations/0001_threads.sql:1-19, 0007_threads_first_user_message.sql:1, 0025_thread_timestamps_millis.sql:1-2), and the thread history migrations stop at 0006 (state/thread_history_migrations/0006_thread_turn_ends.sql:1-3): there is no started_at_ms or completed_at_ms on thread_items, so created_at_ms, the item's start or the rollout line's time (thread-store/src/local/thread_history.rs:431-438), stamps every item row, and an agentMessage row precedes its rollout twin by the time the message took to stream.

Approval decisions in the logs

At ac1fcc8 the fork differs from Codex: the core logs a submission with its kind only, operation=exec_approval, never the decision (codex-rs/core/src/session/handlers.rs:421), so the op=ExecApproval rows the shared reader turns into permission decision: rows cannot occur; the app server's <- response: line with the decision is still logged (codex-rs/app-server/src/outgoing_message.rs:481), and the fork has no guardian_review_feedback table (its state migrations stop at 0055_thread_attachments.sql).

Memories and database backups

As in Codex, the memories files (memories/, off by default, codex-rs/features/src/lib.rs:1148-1150) and db-backups/ (codex-rs/state/src/runtime/recovery.rs:12) exist at ac1fcc8; both are collected.

Format versions

Tracks upstream Codex; no fork-specific version marker in the records. cli_version in session_meta is the fork's version. The record shapes are unchanged at ac1fcc8; turn_context still has network there (codex-rs/protocol/src/protocol.rs:3318), unlike Codex at the commit of the same day's review.

Secrets

Not in rollouts by design, but tool arguments and outputs can carry pasted keys. reasoning.encrypted_content is an opaque provider blob. The credential files (auth.json, credentials/kimi-code.json, .env) are listed in Credentials.

Parser plan

OpenInterpreterParser subclasses the shared RolloutParser, as CodexParser does, and reads .openinterpreter/sessions/ and .openinterpreter/archived_sessions/ rollouts, plain or .jsonl.zst, and .openinterpreter/history.jsonl with agent open-interpreter; the shared RolloutParser reads archived_sessions/ and .jsonl.zst for both agents.

Column Source
timestamp_utc line timestamp; history ts (s)
session_id session_meta.payload.id
project_path turn_context.payload.cwd, else session_meta.payload.cwd
git_branch session_meta.payload.git.branch
turn_type message by role; function_call, custom_tool_call, local_shell_call, web_search_call → tool_use; *_output → tool_result; reasoning → thinking; task_started/task_complete → system
model turn_context.payload.model
model row system model: <model> at the first turn_context that names one, model: <old> -> <new> at each change (the shared Codex reader)
permission mode row system permission mode: approval=<approval_policy> sandbox=<sandbox_policy> profile=<permission_profile> network=<network> at the first turn_context with any of them and permission mode: <old> -> <new> on every change, - for a missing field
tool_name, tool_use_id name, call_id
text message text, arguments/input/action.command, output

Permission rows

The permission mode row of the table carries the per-turn policy. There is no per-call decision row: the fork, like Codex, lists the approval request events among the transient events the rollout never stores (rollout/src/policy.rs:140-204).

The standing grants of rules/*.rules and config.toml (Standing grants) give one permission setting: row per rule statement and per standing key, from the shared reader, as in Codex (Permission rows in codex-cli.md); source-derived; not observed on any real install. The per-call decisions the fork logs, and its lack of a guardian_review_feedback table, are in Approval decisions in the logs.

Model rows

The model row of the table, from the shared Codex reader.

Past-use rows and secondary sources

The rollouts are the primary store; history.jsonl, state_5.sqlite and thread_history_1.sqlite are secondary sources, read as for Codex (Past use and secondary sources in codex-cli.md). Each record of the import ledger becomes a system row naming source_path. The memory rollout summaries, the db-backups/ copies of state_5.sqlite (Memories and database backups) and the thread_goal_updated events, which the fork persists in the rollout as Codex does (codex-rs/rollout/src/policy.rs:114), are read by the shared reader with Codex's roles and rows (Past-use rows in codex-cli.md); source-derived; not observed on any real install.

Sync, relay and origin rows

As for Codex (Sync, relay and origin in codex-cli.md), the fork records no session sync and has the same exits, unchanged: /feedback ("send logs to maintainers"; tui/src/slash_command.rs:93) still reports to OpenAI's Sentry project, not to an Open Interpreter one (feedback/src/lib.rs:56-57), attaches the thread's rollouts when the user agrees to upload logs (app-server/src/request_processors/feedback_processor.rs:200-215), is on by default (core/src/config/mod.rs:4403-4407) and logs feedback event uploaded to Sentry with the thread id (feedback/src/lib.rs:682-688) into .openinterpreter/logs_2.sqlite (state/src/sqlite.rs:29), the marker and the session synced: feedback report uploaded to Sentry, ... row Codex has, which the shared reader yields for the fork too (fixture only), removed by the fork's thread delete as in Codex (state/src/runtime/threads.rs:1153). codex cloud (here "Browse remote tasks"; cli/src/main.rs:239-241) still targets https://chatgpt.com/backend-api/ by default (core/src/config/mod.rs:4341-4343) and writes the same error.log line in its working directory (cloud-tasks-client/src/http.rs:377, 916); remote control keeps the remote_control_enrollments table (state/migrations/0024_remote_control_enrollments.sql:1-10); the thread store is local only (core/src/config/mod.rs:597-603). The fork adds no share, sync or upload feature of its own (searched sync, share, upload, cloud, remote in the crates absent upstream: acp-server, chat-wire-compat, external-agent-sessions, product-info, mcp-server, execpolicy-legacy).

The fork records no relay or origin.

Scratch directory rows

Worktrees under .openinterpreter/worktrees (Scratch directories), classed by the catalog rule; no row names them.

Deletion rows

No marker; as in Codex (What survives a delete).

Bad-line rows

The shared reader's rows: a thread_history_1.sqlite row with a bad item_json gives one row per record with the value in full (Bad lines in codex-cli.md).

Fixtures

  • .openinterpreter/sessions/2026/10/01/rollout-2026-10-01T12-00-00-0199a1b2-0000-7000-8000-000000000001.jsonl:
{"timestamp":"2026-10-01T10:00:00.000Z","type":"session_meta","payload":{"session_id":"0199a1b2-0000-7000-8000-000000000001","id":"0199a1b2-0000-7000-8000-000000000001","timestamp":"2026-10-01T10:00:00.000Z","cwd":"/home/alice/proj","originator":"codex_cli_rs","cli_version":"0.9.0","source":"cli","model_provider":"kimi-for-coding","git":{"branch":"main"}}}
{"timestamp":"2026-10-01T10:00:01.000Z","type":"turn_context","payload":{"turn_id":"t1","cwd":"/home/alice/proj","approval_policy":"on-request","sandbox_policy":{"type":"workspace-write"},"model":"kimi-k3"}}
{"timestamp":"2026-10-01T10:00:01.100Z","type":"response_item","payload":{"type":"message","role":"user","content":[{"type":"input_text","text":"list the files"}]}}
{"timestamp":"2026-10-01T10:00:03.000Z","type":"response_item","payload":{"type":"function_call","name":"Bash","arguments":"{\"command\":\"ls\"}","call_id":"call_1"}}
{"timestamp":"2026-10-01T10:00:04.000Z","type":"response_item","payload":{"type":"function_call_output","call_id":"call_1","output":"README.md"}}

The import ledger external_agent_session_imports.json:

  • {"records":[{"source_path":"/home/alice/.claude/projects/-home-alice-proj/5b1c.jsonl","content_sha256":"ab12...","imported_thread_id":"0199a1b2-0000-7000-8000-000000000002","imported_at":1759312800}]}

Source host rows

The agent records no source-host integration in a file the collector gathers (source at ac1fcc8, grepped for github, gitlab, bitbucket, oauth, installation, repositor and clone): as in Codex (Source host rows in codex-cli.md), codex cloud looks up a server-side environment by the local repository's GitHub origin (codex-rs/cloud-tasks/src/env_detect.rs:50-63) and the network proxy reads a GitHub token from the environment only (codex-rs/network-proxy/src/credential_broker/providers/github.rs:13-20).

Confidence

  • High: home resolution, CODEX_HOME being ignored, every file name in Per-user storage and Credentials (constants in the cited files, identical to upstream Codex), the Kimi credential file, the import ledger and its records key (no serde rename on the struct); the rollout line envelope, timestamp format, payload field names (shared structs) and input_text content blocks (protocol/src/models.rs:876-880).
  • High: the legacy Python tool's 0.4.x layout (source and the 0.4.3 sdist).
  • Medium: models-cache/ as an exclusion (written per provider by the app server, contents not inspected); .terminus-2 landing in the project (depends on whether the env vars reach the tool shell, not traced); pre-0.2 installs of the legacy tool on macOS, because platformdirs before 3.x put user_config_dir under ~/Library/Preferences and that history was not read, so a Library/Preferences/Open Interpreter* location is unverified and has no catalog line.
  • Not determined: whether device_id is sensitive (an identifier sent to Kimi, not a secret, flagged here for caution); whether the desktop or IDE surfaces of Open Interpreter exist and write elsewhere (none found in this repository); the exact tool names each emulated harness emits, which vary by harness module.