Pernix

Your model. Your memory. Your machine.

A Python agent server you run yourself. It researches, schedules, remembers — and keeps working after you close the tab.

Run it
clone · install · run
$ git clone https://github.com/calvincs/Pernix.git && cd Pernix
$ python3 -m venv .venv && . .venv/bin/activate
$ pip install -r requirements.txt && python run.py
Morning brief 1 / 3

Qwen/Qwen3.8-27B ctx: 31% idle_ready

scripted replay of a real session

What ran while you slept.

The server keeps its own flight recorder. Here is one night of it, in order — the tab shut, the phone face-down, nobody watching.

  1. 23:14 you you close the tab
  2. 7h 48m · nobody watching
  3. 23:40 snooze dedup_sweep — 5 duplicate memory entries merged
  4. 01:00 snooze catchup_distill — 1 session reviewed · 4 saved, 2 deduped
  5. 03:00 canary nightly heartbeat — 2 / 2 passed
  6. 05:30 worker worker research-digest finished — parent auto-resumed
  7. 06:55 cron 0 7 * * 1-5 fired — session 8f2a1c3d
  8. 07:00 push “Brief ready” — sent to your phone
  9. lights on
  10. 07:02 you you open the tab

Every line is a real event type. None of it needed you awake.

Three things you keep.

I

The model

Local with Ollama, cloud via your own OpenRouter key, or both — mixed freely. A fast model scouts and plans. A capable one executes. A lighter one handles background work. Workers pick whichever model fits their task. The loop doesn't care which brain is inside: swap freely, your keys, your routing, your call.

II

The memory

Markdown files in data/memories/. Plain text, full-text indexed, tagged with source and type — yours forever. Stays put when you switch models. Stays put when a provider changes its terms. Not locked to any subscription, not sludge accumulating in a chat thread. Read, edit, or delete with any text editor — and the agent can correct or retire its own entries as it learns better.

III

The machine

No accounts. No cloud subscription. No usage telemetry. A Python server that binds to localhost until you say otherwise — then network mode with HTTPS and bearer-token auth. The harness is yours to inspect, fork, and rebuild.

What you're getting.

Pernix is one Python codebase that fits in your head. A FastAPI server, a state machine, a streaming agent loop, a memory store, a workspace. On top of it: a built-in PWA, a REST API, and a Swagger UI you can poke from any browser.

Run it on a dedicated VM, container, or spare Linux box. Open http://localhost:8090. Talk to it. Watch it think. Read the code that made it think that way.

  • stackPython 3.11+ · FastAPI · SQLite · SSE · Playwright
  • interfacesWeb PWA · REST · Server-Sent Events · MCP client
  • storageSQLite for sessions · Markdown for memory · filesystem workspace
  • licenseMIT
localhost:8090
The Pernix web UI: a request to compare Austin and Chicago weather, then three tool rows the agent actually ran — two Open-Meteo fetches at 611ms and 628ms and a file_write of weather-compare.md — and its summary underneath. The sidebar shows a coloured Research space above sessions bucketed into Today, Yesterday and This Week; the status bar carries the model chip, context use and an idle state.

A real 3.1 session, one take: asked to compare two cities' forecasts and save the result, the agent fetched both from Open-Meteo, wrote the file, and reported what it found — every tool call still open for inspection. Local Qwen3.8-27B.

The same session on a 390‑point phone: the sidebar becomes a drawer, the status bar collapses to a strip, and the tool rows and the answer stack full-width above the composer.

A toolbelt. Tools the agent reaches for.

Memory, visible

markdown on your disk
  • pernix.decisions.md6d
  • user.profile.md2h
  • pernix.lessons.md1d
  • pernix.tools.md4d

14 entries 9 · 5 merged overnight

Facts, decisions and lessons as plain Markdown in data/memories/ — full-text indexed, tagged with source and type, editable in any text editor. Recall hands the agent each entry with its file and its age, so an old belief is visibly old. The idle sweeps merge duplicates and retire what went stale.

remember · recall · deep_recall · update_memory · forget

Workers

parallel sub‑agents

Inside a turn the agent fans work out to sub-agents, each in its own session on whichever model fits — a vision specialist beside a code model beside a researcher. Flat by design: workers don't spawn workers. The parent parks in awaiting_workers and resumes itself when they land.

spawn_worker · await_workers · message_worker

Autonomy

a finish line, not a step graph
goal budgeted
gate pytest -q exit 0
beat round boundary

A goal is intent that outlives a turn — budgeted in tokens, time and continuations, auto-resumed when a turn hits its ceiling. A gate is a shell check the model cannot talk its way past: it passes on the exit code or not at all. Heartbeats steer running work without interrupting it.

goal_create · add_gate · set_heartbeat · evaluate

Cron

a standing order
0 7 * * 1-5

each run opens its own session — Cron: morning-brief

Put a standing prompt on a schedule and the brief is built before you wake, the digest writes itself, the watchdog never sleeps. When a run needs you, it pings your phone through the PWA or a webhook.

schedule_job · test_job · list_scheduled_jobs

MCP

other people's tools

mcp_<server>_<tool>

External Model Context Protocol servers — on the box or across the network — register as ordinary Pernix tools. The same scout curation, the same dangerous-tool gate, the same per-tool health metrics as the built-ins.

mcp_add_server · mcp_list_servers · data/mcp_servers.json

Runs on your hardware

nothing leaves unless you send it
your machine server model memory workspace OpenRouter Tavily optional · your key

One Python process on a box you own. The model can be local with Ollama, the memory is files on your disk, the workspace is a directory you can cd into. No accounts, no telemetry, no hosted control plane — it binds to localhost until you say otherwise. The two dashed lines are the only ones that leave, and only if you put a key in .env.

python run.py · localhost:8090 · .env

also in the box

  • search_web
  • browse_web
  • http_get
  • repl
  • job_start
  • view_image
  • spaces
  • skills
  • reflect & retry
  • self-written tools
  • a model per role
  • images · audio · pdf
  • PWA + web push
  • voice input
  • light theme
  • screen-reader floor
  • session search
  • tool safety gate
  • RLM
  • reliability ledger
  • dreams
  • canary suite
  • adaptive policy
  • archive & storage

In the app

One turn spawning two parallel workers, awaiting them, and merging their results.
session › transcript — fan out, await, merge
Six memory files the agent has written across sessions, with entry counts and timestamps.
Explorer › Knowledge — six files, twenty entries
A file the agent wrote, rendered in the Explorer’s workspace browser.
Explorer › Files — a file the agent wrote, rendered

How a turn thinks itself out.

Every message you send rolls through five phases. Each one runs on a model suited to its job — fast for planning, capable for acting, light for verifying.

  1. 01

    Session

    Your message lands on a persistent thread — text, images, audio, PDFs. Append-only. Resumable. Restart-proof.

    queue
  2. 02

    Scout

    A small fast model in a fresh context plans the approach — recalls what you've told it before, picks tools, loads only the relevant skills.

    fast model
  3. 03

    Agent Loop

    The main model executes. Streams tokens, calls tools, reads results, calls more tools — until done. If the cloud rate-limits, it falls back to your local model mid-loop.

    main model
  4. 04

    Reflect

    A quality gate verifies intent was met. Returns pass, retry, or escalate. Up to two retries before surfacing.

    verify
  5. 05

    Post‑hooks

    Auto-titling, memory distillation, worker cleanup. The cleanup runs in the background after you've already seen the answer.

    background
event log hover a phase to sample its events

Compaction trims old turns when context fills past 75%. The originals stay in the database — only the prompt view changes.

Snooze runs between turns. While the agent is idle, it works a ladder of maintenance to completion — dedupes memory, distills your profile, mines finished sessions for lessons, archives post-mortems, and (when enabled) dreams. The moment you send a new message, Snooze cancels mid-stride and resumes next idle — your work always wins.

Recovery assumes the worst. Kill the server mid-turn and restart it: interrupted sessions are swept to safety at boot, parents parked on workers are recovered, and clients replay any events they missed by sequence number. Nothing pretends it didn't happen.

Ten states. One session at a time.

Every session is in exactly one state, and every edge is a (state, reason) pair in an exhaustive table — anything not in the table is rejected. Transitions are logged, replayed to the UI in real time, and recovered after a crash. Hover or tap a state to see its real exits; left alone, the diagram walks an actual turn.

Edges drawn from the table in sessions/state_v2.py. Two housekeeping reasons are omitted for legibility. reaper-unstick returns six states to idle_ready — scouting, processing, pause_requested, paused, awaiting_user, awaiting_workers; cancel-timeout covers those six plus compacting, finalizing and cancelling. Both are explicit rows in the table, not a generic force.

localhost:8090 · State timeline
Five turns as phase-segmented lanes; the selected turn shows the scout’s plan and its chosen tools.
The same machine inside the app: five turns as phase bars, the fifth opened to its plan.

An open API. Tinker freely.

The web UI is one client. There are many. Pernix is built on FastAPI, which means every endpoint the UI calls is also yours to call — from a script, a cron job, another service, your terminal.

Open localhost:8090/docs while the server runs and you get a live Swagger UI: every endpoint, every schema, every response model — try-it-able right from the browser. /redoc if you prefer ReDoc. The fastest way to learn the system is to poke it.

  • streamingServer-Sent Events on /api/sessions/{id}/events for tokens, tool calls, state transitions.
  • resumableSequence-numbered replay on reconnect — clients never miss an event.
  • scriptableThe same API the PWA uses. Build CLIs, integrations, custom UIs.
  • discoverableOpenAPI 3 schema at /openapi.json. Generate clients in any language.
localhost:8090/docs OAS 3.1
Pernix API v3.1.0
GET /api/sessions List all sessions
POST /api/chat Send a message · events via SSE
curl http://localhost:8090/api/chat \
  -H "Content-Type: application/json" \
  -d '{"session_id": "abc123",
       "message": "summarize the auth branch"}'
GET /api/sessions/{id}/events SSE stream · tokens, tools, state
+ 157 more endpoints · openapi.json

Three markdown files, no black boxes.

Pernix's behavior beyond raw model output is shaped by plain text on disk. SOUL.md defines who it is. RULES.md defines how it acts. SESSIONS.md injects deployment-specific context — the user's timezone and key facts, the domains this installation is allowed to act in, per-domain permission levels, and active long-running intents the agent is tracking. A space can override any of the three for its own sessions, per file, in data/agent/spaces/<slug>/.

It's the opposite of a black box. The personality, the operational guardrails, the project conventions — all editable, all auditable, all yours. Open them in any text editor. The agent picks up the change on its next turn.

  • Want it more terse? Edit a paragraph in SOUL.md.
  • Need a project guardrail? Add a line to RULES.md.
  • Want to constrain what domains the agent acts in? Set permission levels in SESSIONS.md.
  • Switching context entirely? Swap the whole file out.
# Identity

You are Pernix — a capable, focused AI assistant.
You help with complex tasks, think carefully before acting,
and communicate clearly.

## Core Traits

- Pragmatic: Prefer working solutions over perfect ones.
  Ship, then iterate.
- Direct: Minimal preamble. Get to the point.
  No filler phrases.
- Curious: Enjoy understanding systems deeply
  before changing them.
- Careful: Confirm intent before irreversible
  actions. Measure twice, cut once.

## Communication Style

- Concise by default — expand when the topic demands it.
- No sycophancy. No "great question!"
- When referencing code, include file paths and line
  numbers so the user can navigate directly.

data/agent/SOUL.md · data/agent/RULES.md · data/agent/SESSIONS.md · data/skills/*/SKILL.md

Just minutes from clone to chat.

Install Ollama, pull a recent model, clone the repo, run the server. Pernix is well-tested with the latest Qwen 3 series on Ollama, and with current frontier models on OpenRouter. Use whatever's current — agentic workloads benefit from newer models with stronger tool-calling and reasoning.

  1. 01

    Install the prerequisites

    Python 3.11+. Ollama if you want local models — pull a current Qwen 3 release. An OpenRouter key or any OpenAI-compatible server (vLLM, LM Studio) works too; Ollama is optional.

  2. 02

    Clone & install

    Standard Python: clone, venv, pip install -r requirements.txt. Optional: copy .env.example for OpenRouter or Tavily keys.

  3. 03

    Run it

    python run.py. Open localhost:8090. Pick a model in Settings. Say hello — and open /docs in another tab to watch the API.

  4. 04

    Make it yours

    Edit SOUL.md. Write a skill. Set a goal behind a gate. Schedule it on cron. Read the code in core/ — it fits in your head.

~/pernix
$ git clone https://github.com/calvincs/Pernix.git
$ cd pernix
$ python3 -m venv .venv && source .venv/bin/activate
$ pip install -r requirements.txt
$ playwright install chromium  # browser for browse_web
$ cp .env.example .env  # add API keys if you have any
$ ollama pull <your-current-qwen3>  # or any modern frontier model
$ python run.py
  Pernix → http://127.0.0.1:8090 

# the UI lives at /, swagger at /docs, redoc at /redoc

New in v3.1.0.

Everything since v3.0.0 under one tag — one week of field campaigns on the reference box, one commit per finding. The full story is in the changelog; upgrade notes in the upgrade guide.

A tool for integrations and recurring work.

Pernix is under active development. Knowing what it's for, and what it isn't, saves you the wrong expectation.

It is for…

  • Vertical work loops. Build a loop tied to one job and keep running it. Email triage, incident response, research digests, meeting-to-action pipelines, voice-memo-to-notes, weekly operations summaries. The product isn't an agent — it's the loop you build around a recurring job.
  • A headless agent substrate. A FastAPI server with full REST coverage. Wire it into other systems, drive it from scripts, build a custom client, run it as the brain behind a calendar agent or research bot. The web UI is one front-end among many possible.
  • Recurring work. Skills + cron + memory. The morning brief, the weekly digest, the watchdog, the recurring research crawl — running reliably whether you're watching or not, with a push notification to your phone when something needs you.
  • An agent in your pocket. The web UI installs as a PWA. Send it a task from your phone over the LAN, drop a photo, an audio file, or a PDF on it, and check back when the agent pings you. Network mode is HTTPS with token auth — your house, your rules.
  • Model-independent pipelines. Build once with a local model, swap to a frontier API when the task demands it, fall back automatically when it rate-limits. The loop keeps running — you decide the routing.
  • Tinkering & learning. One Python codebase, every layer auditable. A working harness to read, fork, and rebuild your own ideas on top of.

It isn't…

  • A coding harness. Use Claude Code, Opencode, Codex, Cursor, or any IDE-integrated agent for serious software work. Pernix is built for a different job.
  • A commercial product. An independent open-source project, built for daily use by its author and shipped as-is under MIT.
  • Production software. It executes shell commands and writes files on the host machine — that is what makes it useful, and what makes it dangerous on the wrong box. Run it in a dedicated VM, container, or spare machine, and never expose network mode to the public internet.
  • Finished. Each release brings new ideas; read the upgrade notes when you pull.

Alpha software. Here be dragons. Sharp edges. Occasional tears. Bugs included at no extra charge — fire extinguisher sold separately.

Fork it. Read it. Make it yours.

Pernix is a working tool, built for daily use and shared openly — use it, learn from it, build on it.