lock family docs GitHub

lea · Teams of agents

Other providers: Codex, Ollama, vLLM

An agent runs on a provider: claude (Claude Code, the default), codex (OpenAI's Codex CLI, in the image) or an OpenAI-compatible endpoint of your own, run through Codex (Ollama, vLLM, any server with the Responses API).

  • LEA_PROVIDER and LEA_MODEL in ~/.config/lea/lea.conf are the default provider and model (an agent started without one: the deck's n, a lead's agents_spawn).
  • lea new -p codex -m gpt-5.1-codex, the deck's N (then the provider's digit), or a lead's agents_spawn with profile and model start an agent on another one; providers_list tells an agent which exist. The deck shows each agent's provider and model.
  • Codex keeps its own login per projects directory, like Claude Code: run codex login (or /login) in the first Codex agent. It runs with its own sandbox (workspace-write) and asks for anything else in its pane; lea's MCP tools reach it, and its turn's end makes it idle in the deck. lea does not see Codex's permission dialogs (the deck shows the agent working) and does not wake an idle Codex agent when a message arrives: it reads its inbox with msg_inbox or waits with msg_wait.

Endpoints go in ~/.config/lea/providers (LEA_PROVIDERS), one per line (config/providers.example):

# <name>  <base URL>                          [key=<key file>]             [model=<default model>]
ollama    http://192.168.1.10:11434/v1                                     model=qwen3-coder:30b
vllm      https://vllm.example.com/v1         key=/home/me/.config/lea/keys/vllm
  • An endpoint's API key never reaches the agents. The file names a key file, not a key: it must be yours, mode 600 (or 400), a regular file with a single hard link, and outside every directory lea mounts into the agents' container (the projects directory, lea's data, ~/.claude, ~/.codex; real paths are compared). Nor may it sit in a Docker volume lea mounts there, such as the nested engine's storage (<prefix>-podman-<id>, under Docker's own data directory): every agent reads it. lea mounts it into the proxy container only, where lea-keyproxy adds it to the agents' requests; an agent reaches the endpoint at http://lea-proxy:4400/<name> and sees neither the key nor the upstream. The key is read at each request: to rotate it, rewrite the file in place (cat new-key > file); a file replaced by a new one (mv, most editors) is seen once the proxy restarts, which the next lea does. Every agent of every lea container can use a configured endpoint (none can read its key); the proxy's egress network (your host, other containers there) cannot.
  • lea-keyproxy sends every request through the proxy's own egress rules: an endpoint on your network (an Ollama on your LAN, or on this machine at its Docker bridge address) must be listed in LEA_INTERNAL_HOSTS with its port, as any internal host; nothing is open by default, and loopback, localhost and link-local addresses are refused. A key goes over HTTPS only, except to a host you listed there. A public endpoint's domain must be in the egress allowlist too (LEA_EGRESS_ALLOW: default,<its domain>). The forwarder answers the agents' networks only, never the proxy's egress network (your host, other containers there).
  • Codex needs the endpoint to serve the Responses API (/v1/responses): Ollama 0.13.3 or later, a recent vLLM.
  • A change of the providers file restarts the proxy at the next lea.