Skip to content

Support installing FrontierAgent once and launching from any project - #41

Draft
matyasstoch wants to merge 1 commit into
ApodexAI:mainfrom
matyasstoch:feature/global-install-launch
Draft

Support installing FrontierAgent once and launching from any project#41
matyasstoch wants to merge 1 commit into
ApodexAI:mainfrom
matyasstoch:feature/global-install-launch

Conversation

@matyasstoch

@matyasstoch matyasstoch commented Sep 9, 2026

Copy link
Copy Markdown

Problem

A wheel built from this repository installs with uv tool install, but the first launch outside a checkout fails twice. Profile loading stops with Provider registry not found: .../site-packages/config/providers.yaml, because the registry lives at the repository root and is resolved relative to the package. Once that is fixed, read_file fails inside its helper, which is piped to python3 -: a tool install only puts the console scripts on PATH, so python3 resolves to the system interpreter (3.9 on macOS).

Result

After uv tool install --python 3.12 git+https://github.com/ApodexAI/FrontierAgent.git, frontier-agent runs inside any project and the existing TUI opens against that directory, with run records under <project>/.apodex/. The checkout workflow, the macOS Docker preference with native fallback, the Linux native default, the apodex alias, and the BYOK policy (no login command, no credential entry or display) are unchanged.

Changes

  1. Packaged provider registry. config/providers.yaml is force-included in the wheel as frontier_agent/infra/providers.yaml. The loader prefers the checkout file and falls back to the packaged copy.
  2. Correct Python environment in native mode. prepare_native_runtime places the CLI interpreter's bin directory ahead of the inherited PATH unless it already leads it, so read_file, download_file, and python3 inside bash use the environment the CLI was installed with.
  3. User env file with defined precedence. An optional $XDG_CONFIG_HOME/apodex/env (default ~/.config/apodex/env, override APODEX_ENV_FILE) supplies defaults. Precedence, highest first: CLI options, exported environment, .env in the launch directory or an ancestor (unchanged), the user file. The file is read literally without ${VAR} expansion, and notes name variables and paths only.
  4. Credential and endpoint guard. A <PREFIX>_API_KEY and <PREFIX>_BASE_URL pair defined together in the user file is applied together. If a higher source sets one half to a different value, the other half is withheld and the reason is printed once.
  5. Docker outside a checkout. Building apodex:local needs a source tree, which a wheel lacks. The launcher uses an image that is already present, builds from APODEX_BUILD_CONTEXT, or pulls an explicit APODEX_IMAGE. With none of those it fails with setup guidance listing those options and --native, preserving the existing Docker preference. Resolved runtime variables cross into the container as docker run -e NAME, never as values on a command line.

A new docs/install/global-install.md covers installation, PATH troubleshooting, the user file, the one-time Docker step, and updating.

Tests

Precedence and the pair guard, secret-free output, --cwd and --model semantics, the packaged registry, Docker build-context and forwarding, native PATH selection against a decoy python3, and a built wheel installed with uv tool and launched from unrelated projects against a local stub endpoint. Docker integration is covered by tests and mocks only; no container was started.

Validation

Check Result
uv run pytest -q 1766 passed, 3 skipped, 1 failed: tests/test_network_tools.py::test_redirect_hops_are_validated_not_followed_blindly needs DNS, unavailable in the sandbox used here
apodex/tests/test_global_install.py 7 passed against the built wheel
ruff check on the CI paths passes
ruff check . whole tree 12 findings in tests/ and docker/, identical to main
tools/import_smoke.py passes with the eval extras
pyright 1 error, identical to main: gradio unresolved without the hf-space extra
tools/preflight.py fails on main and here: the default pipeline id is imported as a module path, and the underscore form reaches a missing create_llm. Addressed in #37

A wheel built from this repository installs with `uv tool install`, but the
first launch outside a checkout failed twice. Profile loading could not find
`config/providers.yaml`, which lives at the repository root and is resolved
relative to the package. After that, the first `read_file` call ran its helper
under the system `python3` (3.9 on macOS) because a tool install only exposes
the console scripts on PATH.

Packaging and runtime:
- Ship `config/providers.yaml` inside the wheel as
  `frontier_agent/infra/providers.yaml`; the loader prefers the checkout copy
  and falls back to the packaged one.
- Native mode places the CLI interpreter's bin directory ahead of the inherited
  PATH so `read_file`, `download_file`, and `python3` inside `bash` use the
  environment the CLI was installed with. A PATH that already leads with it is
  left unchanged.

Configuration:
- Add an optional user env file at `$XDG_CONFIG_HOME/apodex/env` (default
  `~/.config/apodex/env`, override with `APODEX_ENV_FILE`). Precedence is CLI
  options, exported environment, the launch directory's `.env` and ancestors,
  then the user file. The file is read literally, blank values are ignored, and
  notes never include values.
- A `<PREFIX>_API_KEY` / `<PREFIX>_BASE_URL` pair defined together in the user
  file is applied together. If a higher source fixes one half to a different
  value, the other half is withheld and the reason is printed once.

Docker:
- Building `apodex:local` needs a source checkout. Outside one, the launcher
  uses an image that is already present, builds from `APODEX_BUILD_CONTEXT`,
  or pulls an explicit `APODEX_IMAGE`; with none of those it stops and lists
  the options together with `--native` rather than dropping the boundary.
- Forward resolved runtime variables into the container as `-e NAME`, so an
  exported value reaches the container without appearing on the command line.

The macOS Docker preference, the Linux native default, and the BYOK policy
(no login command, no credential entry or display in the TUI) are unchanged.

Docs: a new `docs/install/global-install.md` covers installation, PATH
troubleshooting, the user file and its precedence, the one-time Docker step,
and updating. Existing checkout instructions remain supported.

Tests cover env precedence and the pair guard, secret-free output, `--cwd`
semantics, the packaged registry, Docker build-context and forwarding
behaviour, native PATH selection, and a built wheel installed with `uv tool`
and launched from unrelated directories against a local stub endpoint.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant