@elyxndra/engine
v0.1.0
Published
Elyxndra engine layer: local model library, Hugging Face downloads, inference-engine supervision (MTPLX on Apple Silicon, llama.cpp everywhere) behind an OpenAI-compatible HTTP surface.
Maintainers
Readme
@elyxndra/engine
The engine half of Elyxndra's shared brain: local model library, Hugging Face downloads (resumable, queued, gated-repo aware), inference-engine supervision (MTPLX on Apple Silicon, llama.cpp everywhere, remote OpenAI-compatible servers), hardware-aware catalog, and a management HTTP surface with an OpenAI-compatible passthrough. Node 20+, no native addons.
npm install
npm test # vitest, offline (stub Hub + fake engine daemon)
npm run build
node dist/cli.js models | hardware | catalog
node dist/cli.js serve --port 8900 [--start <model>] # the daemon (standby if the port is taken)
node dist/cli.js service install|uninstall|status [--dry-run] # run it at login, per-userOne engine per machine
Every Elyxndra surface — the desktop app, an editor extension, the CLI — shares
one engine daemon on 127.0.0.1:8900. Whoever binds the port first hosts;
everyone else is a client; a stop from any of them is a stop for all, and the
stopped state says who (by: { reason, client }). Hosts get this policy
from one place:
import { EngineAttachment } from "@elyxndra/engine";
const engine = await EngineAttachment.open({ port: 8900, client: "desktop" });
engine.session; // EngineSession — LocalEngineSession (we host) or RemoteEngineSession (a client)
engine.on("session", (s) => {
/* the daemon we followed went away; we now host */
});Authentication
The daemon serves loopback only, and every request except GET /health (and
CORS preflights) must carry:
- the per-user secret —
x-elyxndra-token: <secret>orAuthorization: Bearer <secret>.engineSecret()reads (and on first use creates) it at<app data>/engine-secret, 0600 in a 0700 directory; a renderer gets it from its main process, never from disk itself; x-elyxndra-client: <name>(desktop,extension,cli— any short token). Besides attributing stops, this header is what forces a browser to send a CORS preflight, and preflights are answered only for origins on the host'sallowedOriginslist (exact match;Origin: nullnever passes).
GET /health stays open and reports auth: "sha256:<hex>" — the digest of
the daemon's secret — so a client can check it is talking to its daemon
before sending the secret anywhere:
import { EngineClient, engineSecret, secretDigest } from "@elyxndra/engine";
const token = engineSecret();
const client = new EngineClient({ client: "myapp", token });
if ((await client.health()).auth !== secretDigest(token)) throw new Error("not our daemon");EngineClient sends both headers on every call (SSE included — it uses a
fetch stream instead of EventSource whenever headers are configured), and
RemoteEngineSession.connect / EngineAttachment.open do the digest check
for you. The engine's own port is covered too: llama-server is launched with
an API key (LLAMA_ARG_API_KEY), so going around the daemon to 8902 needs a
bearer as well. That key is engineApiKey(secret) — derived from the per-user
secret, never the secret itself. The engine port is probed before anyone can
know who holds it, so a process squatting there learns a key that unlocks
nothing on the management API; every host that reads engine-secret derives
the same key and can adopt a llama-server another host started.
EngineSession is the surface the chat brain is written against, so the same
ChatApp works either side of the wire. Lower level, in-process:
import { createEngineRuntime, createEngineRouter } from "@elyxndra/engine";
const rt = await createEngineRuntime();
const handler = createEngineRouter(rt); // mount in the daemon's http server
// rt.manager.activate(model) / rt.store.search("qwen") / rt.downloads.start({...})See ../../docs/engine-port.md for the module map, the cross-platform
equivalents of every macOS-only call, and the endpoint table.
