Cortex is a local-first AI workspace for Windows. It runs models on the machine
-- either through Ollama or by loading a local .gguf file with its own managed
llama.cpp runtime -- keeps conversations and memory in local storage, and
presents the React/TypeScript interface inside a Python-owned pywebview/WebView2
window. The normal launcher owns the backend, native window, and any development
frontend process; Cortex does not open the user's installed browser.
The interface is deliberately small: a chat library, a focused transcript, a composer with a local model picker, and settings for model, memory, appearance, and execution controls.
Every response carries its own footer -- timestamp, token count, and tokens per second -- with copy, regenerate, and fork controls that appear on hover.
Reasoning and sources stay out of the answer body until asked for, each as its own disclosure beneath the response:
Cortex lists models installed through Ollama alongside any .gguf files in the
local models folder, each with the parameter size, quantization, and context
length read from the model itself. A GGUF can be fetched by Hugging Face repo id
or direct URL, then selected from the same picker as everything else:
Generation defaults live in one place, and the chat model doubles as the title model so there is only one choice to make:
Temperature, top-p, top-k, repeat penalty, and context window can also be overridden for a single conversation from the composer, without disturbing these standing defaults.
Ctrl/Cmd+K opens a command palette that reaches new chat, settings, theme,
model switching, and recent conversations without leaving the keyboard:
The whole workspace follows the system theme, or can be pinned light or dark:
The application in these images is the real build. The conversations, library, memories, and staged tasks are a fixed demo workspace defined in
tools/screenshots/showcase_server.py-- no model is contacted during a capture, so the images regenerate byte for byte with./tools/screenshots/showcase.ps1.
- Local chat. Stream responses from a local model with Markdown, syntax-highlighted fenced code, reasoning details, sources, code-block copy controls, retry/regenerate, and forked threads. Long transcripts render in a virtualized list so scroll performance stays smooth regardless of history length.
- Two local runtimes. Use models installed through Ollama, or point Cortex at
a folder of
.gguffiles and it serves them through its own managed llama.cpp runtime -- no separate install. Thellama-serverbinary is fetched once, verified against a pinned SHA-256, and cached. GPU backend selection isauto(try Vulkan, fall back to CPU),vulkan, orcpu. - Bring your own GGUF. Download a model into the local folder by direct URL
or Hugging Face repo, then select it from the same picker as everything else.
Local files appear as
gguf:<filename>. - Composer model control. Inspect the local inventory, switch models without leaving the composer, refresh the inventory, and stage local image or text attachments.
- Per-chat generation parameters. Temperature, top-p, top-k, repeat penalty, and context window default to the values in Settings but can be overridden for a single conversation from the composer, without changing the standing default. Each response shows its token count and tokens/sec once generation finishes.
- Prompt control. Standing system instructions apply to every turn, with no length cap. A local model can also be run raw: Bypass Cortex's default system prompt leaves the built-in identity and safety instructions out of the request entirely. It is off by default and takes a deliberate opt-in.
- Model details. The Models panel shows each installed model's parameter size, quantization, and context length alongside its name, read from Ollama's existing model-detail response.
- Keyboard-first navigation. A command palette (Ctrl/Cmd+K) reaches new
chat, settings, theme, model switching, and recent chats;
?opens a shortcuts reference. The sidebar also supports searching chats by title. - Durable context. Threads live in SQLite; permanent memories use atomic local JSON storage. Existing JSON chat history and Windows settings are read additively during migration without rewriting the legacy source.
- Bounded local tools. Explicit arithmetic can use the deterministic scratch calculator. User-selected PNG/JPEG/WebP transforms run as fixed recipes in a short-lived worker.
- Approval-gated Python. A local model may propose a task in a small,
restricted subset of Python (no imports, no
def/class/while, no method or attribute calls -- assignment, bounded loops, comprehensions, and a fixed builtin list), and the backend validates it, records the source digest and requested capabilities, and waits for one-time user approval. The task tray shows pending approval, progress, output, errors, cancellation, and revoke state. Ordinary assistant text and fenced code are never executed. - Optional response translation. A configured local model can translate each response into a target language, off by default and set independently of the chat model.
- Native local runtime. The API binds to loopback, the native handoff uses an expiring session token, and the embedded WebView uses a private Cortex-owned profile.
When a model proposes a task, the transcript states what it wants and the exact access it is asking for, and the task parks in the tray until the user decides. Nothing runs in the meantime:
The tray names the requested host access, flags broad access as a high-risk choice for that run, and lets the generated source be inspected before anything executes. A finished task keeps its captured output alongside it:
Code execution is a separate capability from scratch computation:
- The local model emits a structured request containing Python source, a plain- language intent, and the exact filesystem, process, and network capabilities it wants.
- Cortex validates and persists a pending job. A model response, Markdown block, or malformed request cannot start a worker.
- The user chooses Allow once or Deny. Permissions are not carried into the next run.
- An isolated, short-lived worker applies source, time, memory, output, and
child-process limits. Host operations go through the brokered
cortexAPI; environment variables, credentials, and application secrets are not inherited. - The task tray records the lifecycle and renders structured output. Stop, cancellation, timeout, denial, and revoke invalidate the grant.
Broad filesystem, process, or network access is a clearly labeled high-risk choice for that run. It is never silently enabled or persisted. If the required worker boundary cannot be established, Cortex fails closed and ordinary chat remains available.
main.py
+-- supervised FastAPI backend (Python)
| +-- versioned loopback API, session auth, SSE jobs
| +-- SQLite conversations/settings and local memory repositories
| +-- model and generation services (Ollama + managed llama.cpp)
| `-- scratch, image, attachment, and code execution lifecycles
+-- native pywebview / WebView2 window
`-- supervised Vite server (development mode only)
frontend/ React + Vite + TypeScript application
backend/cortex_backend/ API, repositories, services, and worker boundaries
contracts/ generated TypeScript API contracts
assets/ externalized model prompt assets
packaging/ Windows PyInstaller build and WebView2 bootstrapper
tools/ contract generation, qualification spikes, screenshots
tests/ Python API, lifecycle, worker, and migration tests
The supported source runtime is Windows. User data stays under
%APPDATA%\ChatLLM\ChatLLM-Assistant unless an explicit --data-dir is supplied.
Semantic vector storage is intentionally dormant until retrieval is integrated
end to end; Cortex does not pull an embedding model at startup.
- Windows 10 or later
- Python 3.10 or later
- At least one local model, from either runtime:
- Ollama installed and running at
http://127.0.0.1:11434, or - a
.gguffile in the local models folder, served by the managed llama.cpp runtime (no Ollama required)
- Ollama installed and running at
- Node.js 22+ and npm for frontend development or source builds
Get a model, create a virtual environment, and launch the native desktop application:
ollama pull qwen3:8b
python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install -r requirements.txt
python main.pyIf you would rather not run Ollama, skip the first line and instead drop a
.gguf file into the local models folder shown under Settings -> System, or
download one from there by URL or Hugging Face repo. Cortex serves it with its
own llama.cpp runtime.
The first launch checks the local model inventory. Choose a model from the setup screen or later from the composer picker. If neither runtime has a usable model, Cortex still opens and explains the connection state; generation becomes available once a model is present and the inventory is refreshed.
Useful launcher options:
python main.py --dev # supervise Vite while developing the UI
python main.py --headless --port 8765 # backend only, for diagnostics/automation
python main.py --data-dir PATH # use an isolated local profile
python main.py --skip-build-check # reuse the existing frontend/dist bundle
python main.py --build-frontend # build the frontend and exit--no-browser is retained as a deprecated alias for --headless. The Ollama
endpoint can be intentionally changed for a trusted local network setup with
CORTEX_OLLAMA_HOST; the default remains loopback.
The local check script covers the fast gates CI runs, from the repository root.
For contributor setup, install requirements-dev.txt as described in
CONTRIBUTING.md so the local Ruff version matches CI:
./scripts/check.ps1 # fast gates, including security/watchdog qualification
./scripts/check.ps1 -Tier full # adds compileall, Playwright, and the bundle buildFor coding-agent work, read the repository-level agent operating contract first. The local coding-agent harness standard records the researched target architecture and release gates. Cortex's current product boundary is still bounded local execution; the standard does not imply that arbitrary workspace or shell authority is enabled.
To run them automatically before every push:
git config core.hooksPath .githooksUse npm.cmd on Windows when PowerShell execution policy blocks the npm.ps1
shim. API contract artifacts are generated with:
python tools/generate_contracts.py --writeThe README screenshots are regenerated from a fixed demo workspace, so they stay
in step with the UI without hand-editing images. showcase.ps1 writes the full
showcase set (to the Desktop by default, or -OutDir); the images used above are
a curated subset copied into .github/images/:
npm.cmd run build --prefix frontend
./tools/screenshots/showcase.ps1Build the one-folder package with:
powershell -ExecutionPolicy Bypass -File packaging/build_windows.ps1The result is written to dist/Cortex/Cortex.exe. The package contains the
frontend, prompt assets, Python runtime, pywebview bridge, and the signed
Evergreen WebView2 bootstrapper. A packaged launch does not require Node.js, a
global Python installation, or an installed browser.
Cortex keeps the API on loopback and requires an expiring authenticated native
window session. The embedded view uses a private profile and does not inherit
browser cookies, history, extensions, or profiles. Prompts, responses, memories,
and raw model output are excluded from diagnostic logs. Ollama remains local
unless CORTEX_OLLAMA_HOST is intentionally configured otherwise.
The code-execution worker is a bounded containment boundary, not a claim of arbitrary operating-system isolation. Review the exact source and capabilities before approving a run. See SECURITY.md for reporting guidance.
- Agent operating contract
- Local coding-agent harness standard
(background research and target design, not policy -- see
AGENTS.md) - What's next
- Attachment boundary
- Execution architecture records
- Archived planning documents
- Contributing guide
- Change log
- Security policy
Cortex is distributed under the terms in LICENSE.







