Skip to main content

exocortex-symphony

An unofficial build of OpenAI Symphony, packaged for pip. It is not affiliated with or endorsed by OpenAI.

The build is upstream Symphony at the commit recorded in BUILD.json (upstream_commit) with plane-adapter.patch applied. The patch adds a Plane tracker adapter and two agent tools, so that Symphony can use a self-hosted Plane fork as its tracker. Both files ship inside the package, next to the executables.

The package exists so that a machine with only a PyPI mirror can install Symphony. It carries one self-contained executable per platform, built with Burrito. Each executable includes Erlang/OTP, so the machine does not need Erlang, Elixir or mise.

Platforms

platform executable status
macOS, Apple silicon bin/symphony_macos_arm64 macOS 14 or later; built and run here, natively
macOS, Intel bin/symphony_macos_x86_64 macOS 14 or later; built and run here, under Rosetta
Linux, x86_64 bin/symphony_linux_x86_64 built, never run
Linux, arm64 bin/symphony_linux_arm64 built, never run

All four are in one wheel (py3-none-any). The package picks the one that matches sys.platform and platform.machine(). On any other platform the commands exit with an error that names the platform.

  • macOS: the executables need macOS 14 (Sonoma) or later, because the Erlang runtime they carry is built for macOS 14. They were run on this build machine (Apple silicon): the arm64 executable natively, the x86_64 executable under Rosetta. Neither has been run on an Intel Mac.
  • Linux: the executables were cross-built on macOS and have never been run, on Linux or anywhere else. Treat them as untested.

What Symphony needs at run time

  • The Codex CLI on PATH, logged in (codex login status).
  • git.
  • For a WORKFLOW rendered by exocortex-project, the Plane API key in PLANE_API_KEY.

Hand-off to Plane: the attached diff

The Plane adapter gives the agent a plane_attach_diff tool, which attaches the work item's change to the work item as a .patch file. The patch is the workspace's current content against the fork point of the base branch (origin/main by default): committed changes, uncommitted edits and new files that are not ignored, whether or not the agent could commit. Real Codex runs in a sandbox that forbids writes to .git, so its git commit fails; the patch still carries the change. Symphony builds it in a temporary git index and leaves the repository's own index, HEAD, refs and files untouched. The same content gives the same attachment; changed content gives a new one.

Symphony also attaches the diff itself at the hand-off, so the agent does not have to remember the tool. When the agent's plane_api call moves its own work item to Human Review (a PATCH whose body sets state to that state's id; another name can be set as tracker.provider.review_state), Symphony first attaches the patch with the default arguments, then sends the state change as the agent wrote it. Content the agent already attached is not uploaded again. The attach never blocks the hand-off: the call's result carries auto_attach (attached, already_attached, no_changes or error), and the Symphony log has one line Plane hand-off auto_attach outcome=<outcome> ... issue_identifier=<key> per hand-off. Calling plane_attach_diff earlier stays optional, for another base branch or file name.

Known limits with real Codex

  • Codex installed only through the editor extension is not on PATH, so Symphony cannot start it and exocortex-project's doctor reports it missing. The extension carries the executable at ~/.vscode/extensions/openai.chatgpt-*/bin/<platform>/codex (for example bin/macos-aarch64/ on Apple silicon). Put that directory on PATH in the shell that starts Symphony, or install the Codex CLI.
  • The WORKFLOW rendered by exocortex-project 0.1.0 hardcodes the model gpt-5.5 and the reasoning effort xhigh in codex.command. symphony workflow has no option for either; to choose another model or effort, edit the two --config values in codex.command by hand after rendering.
  • Pull-request workflows (--pr-host github) need git writes: a branch, commits and a push. The default Codex sandbox (workspace-write) denies writes to .git, so those steps fail. The --pr-host none workflow does not need them, because the change reaches Plane as the attached patch.

Commands

  • exocortex-symphony [args...] replaces itself with the Symphony executable for this platform and passes every argument through unchanged. python -m exocortex_symphony does the same.
  • exocortex-symphony-home prints <data dir>/exocortex-symphony/<package version>/ and creates it if needed. The data dir is $XDG_DATA_HOME, or ~/.local/share when that is unset. The directory holds bin/symphony, a symbolic link to the packaged executable (a copy where links cannot be made). Export it as SYMPHONY_DIR for exocortex-project 0.1.0.

If site-packages is read-only and the executable has lost its execute bit, it is copied into that same directory (bin/symphony_<target>) and run from there.

Use with exocortex-project 0.1.0

pip install exocortex-project exocortex-symphony
export SYMPHONY_DIR="$(exocortex-symphony-home)"
exocortex-project symphony workflow --project <IDENT> [--pr-host github|none]

symphony workflow writes WORKFLOW.md at the repository root. Start Symphony from there:

PLANE_API_KEY="$(cat ~/.config/exocortex-project/token)" exocortex-symphony \
  --i-understand-that-this-will-be-running-without-the-usual-guardrails --port 4100 WORKFLOW.md

This package replaces step 5 of exocortex-project 0.1.0's SETUP.md (git clone of the Symphony fork, mise, mix build). The rest of that step still applies: render the WORKFLOW with exocortex-project symphony workflow, then run exocortex-project symphony check and doctor.

Known false result: with this package, exocortex-project symphony check and doctor (0.1.0) report that the Symphony executable has no Plane adapter. That check reads the executable as an escript archive and does not understand the Burrito format. The adapter is present. The check that matters is the one that runs symphony --help and expects Usage: symphony, and it passes.

First run

On its first run, each executable unpacks its payload (Erlang runtime and the Symphony release) into a per-user directory and reuses that directory on later runs:

  • macOS: ~/Library/Application Support/.burrito/symphony_erts-<erts>_<version>/
  • Linux: $XDG_DATA_HOME/.burrito/ or ~/.local/share/.burrito/, same directory name. The Linux executables also write a musl runtime to /tmp/libc-musl-<hash>.so.

For this build the directory name is symphony_erts-16.4_0.0.3-exo.3. SYMPHONY_INSTALL_DIR moves the unpack location to $SYMPHONY_INSTALL_DIR/.burrito/. Burrito's own maintenance commands pass through: exocortex-symphony maintenance directory prints the directory, and exocortex-symphony maintenance uninstall removes it after asking.

Symphony's version string carries the -exo.N suffix because Burrito keys the unpack directory on the ERTS version and the app version only. A rebuilt executable with an unchanged version would run the payload unpacked by the previous build.

Build

The executables are not in git. scripts/build-binaries.sh builds them from a clean checkout of the Symphony fork (SYMPHONY_SRC, default ~/projects/symphony; not SYMPHONY_DIR, which is the directory exocortex-project runs bin/symphony from) and writes the executables, BUILD.json, plane-adapter.patch (git diff <upstream commit>..<fork commit>), LICENSE.symphony and NOTICE.symphony into src/exocortex_symphony/. It needs mise with Erlang/Elixir as the fork's elixir/mise.toml pins them and zig@0.15.2. It removes the fork's release directory (elixir/_build/prod/rel/symphony) first, so no application directory from an earlier version is packed, and runs the builds with TMPDIR set to a directory of its own that it removes afterwards, because Burrito leaves about 750 MB of temporary files per full build.

SYMPHONY_SRC=~/projects/symphony scripts/build-binaries.sh
uv run pytest && uv run ruff check .
EXOCORTEX_SYMPHONY_REQUIRE_BINARIES=1 uv build

With EXOCORTEX_SYMPHONY_REQUIRE_BINARIES=1, the build fails when an executable or BUILD.json is missing. Without it, the package builds without them (for development). build_info() returns BUILD.json, which records the upstream repository and commit, the fork commit, the Symphony, ERTS and OTP versions, and each executable's size and sha256.

Licenses

  • The Python launcher in this package: AGPL-3.0-only, like the repository it comes from. The text ships as LICENSE.
  • The bundled Symphony executables and plane-adapter.patch: Apache-2.0. Symphony's license and notice ship as LICENSE.symphony and NOTICE.symphony. The executables also contain Erlang/OTP and Elixir (Apache-2.0) and Symphony's Hex dependencies under their own licenses.

All three files are the package's license files (license-files), so installers place them in the .dist-info/licenses/ directory; LICENSE.symphony and NOTICE.symphony also sit next to the executables.

Metadata

Release files for exocortex-symphony 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for exocortex-symphony 0.1.0
File Size Uploaded
exocortex_symphony-0.1.0.tar.gz 56.0 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for exocortex-symphony 0.1.0
File Interpreter ABI Platform
exocortex_symphony-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 112.0 MB

Release files / exocortex_symphony-0.1.0.tar.gz

Download URL exocortex_symphony-0.1.0.tar.gz
Size 56.0 MB
Tags Source
SHA-256 checksum
How to use checksums
f9e07292688751b63866be1a507eca7c76f21fb8081ed17cf4b3ad5df2bee8d5
BLAKE2b-256 checksum
How to use checksums
ff718da5eb3d07f3829d64fc6bdcf0b3450b7e21977e22ffd9c699dcb7b28517
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / exocortex_symphony-0.1.0-py3-none-any.whl

Download URL exocortex_symphony-0.1.0-py3-none-any.whl
Size 56.0 MB
Tags Python 3
SHA-256 checksum
How to use checksums
26306afc28372cd747eb5a58597209d49a307d32bbfcd3ccc434fbe01e8fcbd3
BLAKE2b-256 checksum
How to use checksums
c367d35edbf1ebb9a0a4e1e81266dcd055dd112b5858aefc6921f8776a63724e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page