Skip to content
eugene-plexusPublic

About

OpenAPI 3.1 contracts and architecture for Eugene Plexus, a self-hosted control plane for local LLM inference.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Eugene Plexus — specs

CI License: Apache 2.0 OpenAPI 3.1

OpenAPI 3.1 contracts for every cross-component interface in Eugene Plexus.

v0.1.0 is the first release of the local-inference control plane: early software that works, with rough edges and known limits. Start with the installation guide. Before updating an installation, make a checkpoint as the backup and recovery guide describes.

This is the single source of truth for how Eugene Plexus components talk to each other. The six active consumers (agent, control, gateway, inference-driver, library, and ui) depend on a pinned revision via codegen, never via direct import. Retired repos retain historical pins; they do not consume today's contracts. Components share schemas, not code.

What is Eugene Plexus?

A self-hosted control plane for local LLM inference.

It installs, updates and supervises inference engines, manages a model library on your own disk, holds per-model settings profiles, and exposes OpenAI-compatible and Anthropic Messages endpoints over eligible local and cloud backends. Its browser console manages authentication, routing and the machines in an installation. See the tested configurations and support boundaries before planning a shared deployment.

It is not an inference engine. We supervise upstream llama.cpp, and user-installed vLLM and MLX (on Apple silicon). We do not fork or replace the engines.

Eugene brings engine lifecycle, model files, application access and routing into one console. The intended workflow is:

  1. It installs, updates and restarts the engine for you. llama.cpp today, your own vLLM if you have one; it comes back after a crash and gets out of memory when idle.
  2. It tells you what fits before you download, and starts your settings there. Quant and context picked for this card, with the reason shown. Fit estimates guide a launch; they do not establish shared-service latency or replace testing on the target hardware.
  3. It finds and downloads models in the app, into your own folders, as plain files. Search a catalogue, read what a model is, pick a quant, download with resume and progress — landing in your existing GGUF directories, plainly named. No content-addressed cache, no hash mismatches. Delete us and you still have your models, correctly named, where you put them.
  4. One endpoint for your applications. OpenAI-compatible chat, tool calling, embeddings and streaming, plus an Anthropic Messages subset for Claude Code. See the supported features and limitations.
  5. Add the backends you already run and the subscriptions you already pay for. Connect local HTTP servers, supervised engines and supported CLI backends to one endpoint. Replicas are balanced with the prompt cache in mind: a conversation goes back to the copy that already holds it, a new one goes where there is room, and a llama.cpp server is never sent more than its memory holds (the research behind it). Failover uses eligible targets only when retry is safe; ambiguous work is not automatically replayed. See the failover rules and the API feature limits.
  6. Reach it from your other devices, safely. One switch, a real login with sessions, and client keys you can revoke — over a tailnet or your own LAN, not just localhost.
  7. It grows into a homelab. More machines from one console, a model library on the NAS, replicas across GPUs, one trust root that holds the install together.

This order and this wording were adopted on 2026-09-18 (docs/design/release-roadmap.md decision #2). The design documents number the same ideas differently and deliberately — they keep the numbers older documents cite, so #4 there is still the schema-driven config UI, which has not gone anywhere: it is now how line 2 prefills a profile rather than something worth leading with. docs/design/local-inference-control-plane.md §2 holds both lists side by side.

Client credentials and revocation: client-key management. Real local-model setup: Claude Code and Open WebUI.

Full design: docs/design/local-inference-control-plane.md. Current order of work: audience roadmap.

Current status

2026-10-02: v0.1.0 is the first release; see the installation instructions and the release checks. The six alphas before it remain available. The support matrix distinguishes measured, simulated, pending and unsupported configurations, and the release notes list the physical checks and the moderated sessions still owed.

Historical snapshot — 2026-09-17

The following snapshot predates R1-R8 and the alpha; its defect and publication statuses are historical, not the current pickup list. Their implementation records are in the previous roadmap.

As of 2026-09-17, this is a pre-1.0 control plane under active development, and not yet releasable — deliberately. Milestones M0 through M11 are built, each with a re-runnable acceptance script rather than a claim, and so are ten further slices since (the resource-tree UI, Library folders, the hobbyist onboarding plan, Issues, a node-local model copy). Installers, a developer bootstrap and a control-plane container image exist; the container image is published to GHCR as :edge, and nothing else is published — no GitHub Release, nothing on PyPI or npm.

An adversarial code review on 2026-09-17 found 38 anchored defects plus an architectural note, 11 of them rated High for a public first release. Eight are being fixed before any public link and five more before the first hostile review; the order is docs/design/release-roadmap.md. Until they land, do not expose this to a network you do not control — the login rate limiter can be driven from a request header when the browser reaches it through our own proxy, which is a pre-authentication defect. (A second one needs an operator token first: a crafted single-file download spec can write outside your model folders.)

  • Live-verified on real hardware: llama.cpp and vLLM supervision, model scanning and profiles, catalogue search and resumable downloads, replica balancing, priority-tier failover, idle unload, wake on demand, memory admission, retained per-request metrics, tool calling end to end, embeddings, real token streaming, and a node keeping its own copy of the models it runs (21 s to serving against 266 s over SMB).
  • Multi-host is proven on two real machines (Windows + WSL2 Ubuntu, across NAT and a host firewall): non-loopback binds, derived advertise addresses, a cross-host completion, an idle unload decided on one host and executed on the other, and a full signing-key rotation. A NAS-hosted library serving a 27B to a GPU node is the live install. Not proven: two replicas of one model on two machines — the gateway keys runtimes by bare name, so that case cross-wires today (roadmap R1.6).
  • Hardware-aware quant guidance is built and is not yet trustworthy. Two code paths compute a fit and only one carries the per-layer KV arithmetic, so the number the one-click Run path writes into a profile can be far smaller than the one the recommendation card showed (roadmap R1.3). A Windows machine with an AMD or Intel GPU is currently detected as having no GPU at all and is given a CPU-only engine build (roadmap R2.3).
  • The browser path is verified, as of M9: Playwright drives first run, login, restart-on-login and the topology-resolved proxy against a live install; scripts/hobbyist-acceptance.sh counts real clicks from a clean guest to a first token on Windows and WSL2.
  • Still unverified: a signing-key rotation with a genuinely offline node, a partitioned-but-alive old control root, two-GPU placement, macOS on bare-metal hardware, and concurrent users against one runtime. macOS and MLX are verified on GitHub's (virtual) Macs (A4, 2026-09-30: the installer, launchd, MLX and llama.cpp on Metal); MLX is no longer experimental. Clock skew is no longer unverified — it took a worker out of the live install on 2026-09-15, and every component now tolerates five minutes of it.
  • Provider compatibility is a subset. Anthropic /v1/messages is implemented for text/tool clients, with explicit limitations. Images are planned in A4; Responses API parity is not promised. See API compatibility.
  • Known gaps: rolling engine upgrades; a mixed-version engine fleet is possible and nothing detects it; no structured model-slot editor; one control-root screen (/nodes). The ~116 ms of control-plane overhead measured at M8 is explained — a fresh HTTPS client per request, parsing a CA bundle on the event loop — and is the first fix on the roadmap.

Records: the node-local copy · Library folders · the hobbyist click budget · Issues · M7 on two hosts · M4 vLLM · M8 metrics. Deploying over a tailnet: docs/deployment/tailnet.md · in a container: docs/deployment/container.md.

Layout

openapi/
  gateway.yaml              the OpenAI-compatible front door; routing + failover
  inference-driver.yaml     the uniform surface over one backend (N instances)
  library.yaml              the operator's model directories, scanned + profiled;
                            catalogue search, downloads, quant guidance
  agent.yaml                per-host supervision, engine lifecycle, enrollment
  control.yaml              trust root, node registry, replicated control state
  components/
    common.yaml             shared schemas (messages, errors, config protocol, auth)

Shape

Two layers, never collapsed: a routing gateway above N per-backend inference-driver instances.

Component Repo Port Job
node agent agent 8079 One per host. Supervises components and engines; owns adapters, admission, local topology and logs; currently serves UI assets
control root control 8083 Install trust root, node registry, union topology, single-writer replicated log and warm standbys. Spawns nothing
gateway gateway 8080 One OpenAI-compatible endpoint. Model → driver resolution, load balancing, priority-list failover. No backend knowledge.
inference-driver inference-driver 8081 One instance per backend. Owns provider choice, model id, secrets and health; generation parameters come from the gateway
library library 8082 The operator's own model directories: recursive scan (GGUF + safetensors), metadata, per-model launch profiles; catalogue search, resumable downloads, quant table, hardware fit scoring
ui ui 3000 dev / 8079 served Config editor, runtime dashboard, library browser, discovery, chat playground, logs
specs this repo — Contracts; consumers codegen from a pinned SHA

The layering matters and is not an accident of history. A driver belongs next to its engine, so it can run on a remote GPU host while the gateway reaches it over the tailnet — that is the whole multi-host story. Two replicas of one model on two GPUs need N independently-configured backends with something above them. And claude_code_cli / codex_cli are subprocess backends with no endpoint to proxy to, so a driver has to be able to sit in the request path regardless.

Components vs. runtimes

The agent supervises two different kinds of process and keeps them in separate collections, because they share only their supervision mechanics:

Component (/v1/components) Runtime (/v1/runtimes)
What it is a Eugene Plexus process a third-party engine binary
How it starts <python> -m <module> argv built by an engine adapter
Readiness the shared /healthz engine-specific probe
Config the standard config trio curated engine flag surface
Auth receives the trust bundle's path + a token for its own machine, never a key; the control root owns its auth gets none; fronted by a driver

ComponentKind contains exactly gateway, inference-driver, library, and control. The agent and UI are processes but are not members of that enum. Ports above are defaults, not fixed assignments for every instance.

Engine knowledge splits the same way, with no shared library: how to start an engine (argv, readiness, curated flags) lives in the supervisor; how to talk to one (wire protocol) lives in the driver.

Using these schemas

Python (Pydantic v2 models)

pip install datamodel-code-generator
datamodel-codegen \
  --input openapi/gateway.yaml \
  --input-file-type openapi \
  --output-model-type pydantic_v2.BaseModel \
  --output gen/gateway_models.py

Python (typed async client)

pip install openapi-python-client
openapi-python-client generate --path openapi/gateway.yaml

TypeScript (types)

npm install -D openapi-typescript
npx openapi-typescript openapi/gateway.yaml -o gen/gateway.ts

We deliberately avoid the Java-based openapi-generator — verbose output, opinionated templates you fight, heavyweight install.

Consumers pin a specs SHA in their own SPECS_REF file and regenerate from GitHub at that SHA, so a change here never breaks a consumer until it chooses to bump.

Installing it

One command on any machine, from nothing — no Python needed first, because uv brings its own:

curl -fsSL https://raw.githubusercontent.com/eugene-plexus/specs/main/scripts/install.sh | sh
irm https://raw.githubusercontent.com/eugene-plexus/specs/main/scripts/install.ps1 | iex

On Apple Silicon, the POSIX installer and developer bootstrap request native arm64 Python, including from a Rosetta terminal. An existing Intel environment is preserved and rejected with recovery instructions. The bootstrap's --python option still accepts an explicit interpreter override. Architecture selection has simulated regression coverage; installation and Metal inference on a physical Mac remain unverified.

Both install into a single prefix they own, register startup, start Eugene and print its URL. Windows uses a service by default and asks for administrator access; -NoService selects a logon task. Mac uses a per-user LaunchAgent. A worker joins an existing installation with --join <control-root-url> --token <jwt>.

The current development installers also save an offline removal utility: Windows Settings ? Apps ? Installed apps ? Eugene Plexus ? Uninstall, or Remove Eugene Plexus in the Mac user's Applications folder. Removal shows sizes and offers separate choices for deleting settings/app data and managed downloads. By default it deletes the software while preserving those files and all original model folders. A retained cleanup receipt lets you change the choices later, even after Python has been removed.

--uninstall / -Uninstall remains available. See the Windows and Mac removal guide for exact commands, retained-file locations and how to handle a partial cleanup. These improvements ship after v0.1.0; published installer assets are unchanged.

Packages are fetched from pinned GitHub archives. The support matrix distinguishes runner checks from physical-machine verification, including the remaining Mac and Windows checks.

Or in a container, for the control plane

The control plane runs on an ordinary VM or NAS while the GPU machines stay on bare metal and join it over the network:

docker compose -f docker/compose.yaml up -d --build

One service, not four: the container runs a node agent that supervises the control root, gateway and library, exactly as it does on a host. There is no GPU and no engine in the image, deliberately. docs/deployment/container.md has the without-Compose commands (UnRAID, Synology, plain Docker), the port table, and what is verified so far.

Setting up a dev environment

Eugene Plexus is a polyrepo targeting Python 3.12 — every component pins requires-python = ">=3.12", ruff target-version = "py312", and mypy python_version = "3.12", and CI runs on 3.12. Develop on 3.12 so local matches CI.

One command does the whole polyrepo — it needs only git, because uv brings its own Python and every repo is public:

git clone https://github.com/eugene-plexus/specs
sh specs/scripts/bootstrap.sh     # Windows: powershell specs/scripts/bootstrap.ps1

It clones all eight repos as siblings, gives each Python repo a 3.12 virtualenv with [dev] and pre-commit hooks, sets up ui and website with npm, builds the UI export, and installs every component into the agent's virtualenv — which is the step that matters, because the supervisor spawns children with its own interpreter. Pass --root DIR / -Root DIR to build it somewhere else. Node is optional; without it the two Node repos are skipped and the dev agent serves no browser half.

The rest of this section describes what that automates. Committed generated files already match each consumer's pin; regenerate when changing the pin or verifying freshness.

The step worth understanding, because it is the one people skip when setting up by hand: both bootstrap scripts install every component into the agent's venv as well as its own. That is not redundancy. The agent supervises children by spawning them with its own sys.executable, so a component missing from the agent's environment cannot be started by it at all — and on a first boot the agent checks with find_spec and declines to declare what it cannot import, leaving a working supervisor with nothing to supervise.

Since the UI became a Python package, the same applies to it: without eugene-plexus-ui in the agent's venv you get the API and a "no web UI installed" page. The scripts install it editable, so npm run build:python in ui is immediately visible to a running agent.

Afterwards there is nothing else to run. Start the agent and it declares and spawns the control root, gateway and library itself; the browser UI is for setting a passphrase and pointing the library at your models.

VS Code Tasks (Windows)

.vscode/tasks.json is shared in Git; other editor settings and local task state remain ignored. The tasks use Windows PowerShell 5.1, scripts/dev-tasks.ps1 and scripts/dev-seed.ps1, which share scripts/dev-common.ps1:

  • Start launches Agent and UI Dev concurrently, and on a first boot that is the whole of getting a control plane running: the agent declares and spawns the control root, gateway and library itself. The agent runs from the dev install directory, not from a source checkout: everything it persists (agent.yaml, node.yaml, logs/, companion driver configs) lands beside its config file. Defaults to .dev-install beside the repo checkouts; EUGENE_PLEXUS_DEV_INSTALL overrides it.
  • Finish Install (optional) is the unattended equivalent of the first-run UI, for a dev loop or CI that should not need a browser: it sets the operator passphrase on the agent and control root, points the library at a model directory, marks first run complete and declares one llama.cpp runtime. It does this over the same endpoints the UI uses; there is no privileged path. Nothing requires it. It is idempotent, waits for the agent rather than failing if run first, and reads the passphrase from EUGENE_PLEXUS_DEV_PASSPHRASE or a private SecureString prompt - never from disk or a command line, and there is no recovery path for it by design. -Model / -Binary override the paths; -SkipRuntime stops after configuration. Without a llama-server binary the install is still configured and the runtime is skipped with a reason.
  • UI Dev runs the installed Next.js executable on port 3000 and fails if it is occupied. EUGENE_PLEXUS_DEV_UI_PORT overrides the port for launch and checks.
  • Health Check reads /v1/components and /v1/runtimes from the agent, probes every discovered component URL, and checks the UI. Degraded/safe-mode services, crashed runtimes, missing topology and network/auth failures return exit code 1. A stopped runtime does not fail the check — idle unload is policy working — and neither does one that is still loading, which is a snapshot of something in progress. Companion drivers are probed whether or not their engine is loaded: per the agent contract a companion deliberately keeps running while its runtime is stopped, which is what lets the gateway keep listing an on-demand model, so a dead one has to surface rather than be skipped.
  • Stop All is a force-stop fallback: it stops only the Agent/UI launcher trees recorded by these tasks, including their supervised descendants. It verifies PID, creation time and launcher command; it never selects listeners by port. Use Ctrl+C in the task terminals for normal shutdown. Legacy launches, detached orphans and other workspaces are deliberately not targeted.

Default agent address: http://127.0.0.1:8079. EUGENE_PLEXUS_AGENT_BIND_PORT also updates the UI/check defaults; an explicit AGENT_URL overrides their target. GATEWAY_URL remains the UI's gateway bootstrap override. Set bootstrap environment variables before launching VS Code so tasks inherit them; topology and model settings still belong in the application config UI.

Health Check accepts EUGENE_PLEXUS_DEV_TOKEN from the environment or prompts privately for an operator token on HTTP 401. Obtain the token through the normal login flow. It is not stored in task arguments or files, printed, or sent to discovered health endpoints. Do not put tokens in tracked task definitions. The check covers one agent's topology, not the install-wide control view.

Run the focused tests with Windows PowerShell (Pester 3.4.0 and Node.js):

Import-Module Pester -RequiredVersion 3.4.0
Invoke-Pester -Script ./scripts/dev-tasks.Tests.ps1 -EnableExit

The tests use mocks and temporary synthetic processes, not your running stack.

Conventions

  • camelCase field names throughout — with one deliberate exception. The gateway's /v1/chat/completions and /v1/models use snake_case and OpenAI's error envelope, because "OpenAI-compatible" is worth nothing unless an unmodified OpenAI SDK can point its base_url at us and work. House style does not get to break every client.
  • RFC 7807 problem+json for errors everywhere else.
  • SSE for one-way streams, framed exactly as OpenAI frames them on the compatible surface.
  • Every component implements the same config trio — GET /v1/config, GET /v1/config/schema, PATCH /v1/config — with rich UI metadata, so one generic editor manages all of them. This started as an internal convention; it is now a product feature.

Architectural commitments

These are settled. Don't relitigate them in PRs without a strong reason.

  • Never ship an inference engine. Wrap upstream, track it, don't fork it.
  • The user's model files stay in user-chosen directories. No content-addressed cache. Non-negotiable.
  • Two layers: a routing gateway above N per-backend drivers. Never collapsed.
  • OpenAPI 3.1 for everything. HTTP+JSON for control, SSE for one-way streams, WebSocket+JSON for bidirectional. gRPC/Protobuf deferred until a concrete hot-path need emerges.
  • Polyrepo, no shared core library. Components share schemas (this repo), not code.
  • Apache 2.0 — permissive adoption with an explicit patent grant.
  • Open-core. Core stays Apache 2.0 forever. Future commercial add-ons live in physically separate repos under commercial license.
  • DCO, no CLA. See CONTRIBUTING.md.
  • Eugene's own per-node keys authenticate components to each other on any network. Machines on one private network (a LAN, or a mesh the owner runs) talk directly; a machine outside reaches the root only over a node-only route that carries signed node traffic and nothing else (Job Sites, docs/design/remote-nodes.md). No cloud service is required in the path. The control root owns install-wide trust; enrolled agents distribute credentials to their children, and user-facing endpoints enforce bearer auth.

History

Eugene Plexus began in May 2026 as a consciousness framework wrapping commercial LLMs, then grew a from-scratch LLM training platform in June 2026. Both were retired as of 2026-09-08. The code still exists and worked; it is archived, not deleted. If you find consciousness or training concepts in old commits or tags, they are historical — main is the control plane.

The organization contains 15 repositories: seven active, one deferred, and seven retired. connector is deferred; memory, identity, coordinator, trainer, data, eval, and inference are retired. None is GitHub-archived: status labels describe project scope, not read-only repository settings. cluster is not an existing repository. Historical pins and documentation are retained.

The name is a legacy of that era and was kept deliberately, which is why this README does the work a descriptive name would have done for free.

Versioning

  • This repo follows SemVer. 0.x means breaking changes can land on minor bumps; pin exactly until 1.0.
  • Each OpenAPI document carries its own info.version. The repo tag is the umbrella version.
  • Breaking schema changes require a major (or pre-1.0 minor) bump and a migration note in the changelog.
  • Cross-component release notes live in CHANGELOG.md.

License

Apache 2.0 — see LICENSE.

About

OpenAPI 3.1 contracts and architecture for Eugene Plexus, a self-hosted control plane for local LLM inference.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages