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'sdoctorreports it missing. The extension carries the executable at~/.vscode/extensions/openai.chatgpt-*/bin/<platform>/codex(for examplebin/macos-aarch64/on Apple silicon). Put that directory onPATHin the shell that starts Symphony, or install the Codex CLI. - The WORKFLOW rendered by exocortex-project 0.1.0 hardcodes the model
gpt-5.5and the reasoning effortxhighincodex.command.symphony workflowhas no option for either; to choose another model or effort, edit the two--configvalues incodex.commandby 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 noneworkflow 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_symphonydoes the same.exocortex-symphony-homeprints<data dir>/exocortex-symphony/<package version>/and creates it if needed. The data dir is$XDG_DATA_HOME, or~/.local/sharewhen that is unset. The directory holdsbin/symphony, a symbolic link to the packaged executable (a copy where links cannot be made). Export it asSYMPHONY_DIRfor 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 asLICENSE.symphonyandNOTICE.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)
| File | Size | Uploaded | |
|---|---|---|---|
| exocortex_symphony-0.1.0.tar.gz | 56.0 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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}
|