README.md
Language Markdown7.6 KB177 lines
# CortexA native desktop client for language models that shows what every replycosts. Tauri v2 (a Rust shell) and React, on DeepInfra's hosted models or anymodel server you run yourself.## Quick startNeeds Rust (stable) and Node 22. On Linux, also the WebKitGTK developmentlibraries that `.github/workflows/ci.yml` installs.```bashnpm cinpx vite build # first: the Rust build embeds the built interfacecargo test --workspace # core logic, the provider against the stand-in, whole turnsnpm test # Vitest: formatting, markdown safety, the store, the app rendersnpm run typecheck # tscnpm run test:ui # Playwright: the interface in Chromium, on sample datanpm run tauri dev # the app, with hot reload```The end-to-end run drives the real app over WebDriver on Linux. It needs`webkit2gtk-driver`, `xvfb`, `dbus-x11` and `cargo install tauri-driver`, and adebug build with the `e2e` feature first:```bashnpx tauri build --debug --no-bundle --features e2escripts/e2e-linux.sh```CI also checks formatting and lints:```bashcargo fmt --all --checkcargo clippy --workspace --all-targets -- -D warningsnpm run format:check # Prettier over src/ and e2e/```## Why it existsHosted chat apps charge a flat monthly fee whether you ask one question or athousand. Paying per token through an inference provider is usually farcheaper, but only if you can see what you are spending. Cortex puts the priceof every reply in front of you: tokens in and out and the dollar cost undereach answer, a running total per conversation, the month so far against abudget, and an estimate of what a prompt will cost before you send it.## How it is builtThe logic lives in `crates/cortex-core`, a plain Rust library: the providerclient and its streaming parser, pricing and cost, SQLite storage withfull-text search, attachments and export. `src-tauri` holds the commands, thewindows, the tray and the shortcut. The React interface talks to it throughone typed interface, whose TypeScript types are generated from the Ruststructs. More in [docs/architecture.md](docs/architecture.md).```crates/cortex-core/ providers, streaming, pricing, cost, storage, exportcrates/standin/ the test stand-in for DeepInfra and local serverssrc-tauri/ the desktop shell: commands, windows, tray, shortcutsrc/ the React interface (main window and quick prompt)e2e/ Playwright (interface) and WebDriver (real app) testsdocs/ architecture, cost accounting, the Mac checklist```## What it does- **Streaming chat** with any chat model on DeepInfra, or on a local server(Ollama, LM Studio, llama.cpp: anything OpenAI-compatible). Stop a reply atany point; what arrived is kept.- **A cost meter everywhere.** Live per-model prices from DeepInfra, storedwith each reply so history never changes. Estimates are labeled "est.".Local models cost nothing. See [how cost is counted](docs/cost-accounting.md).- **A model picker with prices:** search, filter by vision, reasoning,favorites or local, and see input and output price per million tokens andthe context size before you choose.- **A quick prompt.** Cmd+Shift+Space anywhere opens a small frosted promptover whatever you are doing. Ask, read, press Esc. Cmd+Enter moves theconversation into the main window.- **Presets:** saved system prompts (with an optional model and temperature),applied to a chat in one click.- **Search** across every chat (full-text, as you type).- **Export to an Obsidian vault:** a conversation as Markdown withfrontmatter (models, tokens, cost), images copied beside it.- **Images and files:** paste or drop an image for a vision model (it isdownscaled first, since vision models bill by size), or a text file to readas context.- **macOS window materials:** frosted panels over native vibrancy, light anddark, with a choice of material and panel tint, and a solid mode for whentransparency gets in the way.- **Menu bar:** this month's spend, a new chat or the quick prompt, fromanywhere.## Screenshots*Screenshots are the interface on its built-in sample data (every chat in themis invented), shown over the backdrop the page paints when there is no nativevibrancy. On a Mac the panels sit on the frosted desktop instead.*## Privacy- Chats, attachments and settings live in one SQLite file on your computer.- API keys live in the macOS Keychain, never in the database or a file. Theinterface can set or remove a key but never read one back. A key is checkedwith the provider before it is stored, so a mistyped one is caught at once.- The only network traffic is to the provider you chose, from the Rust side.The webview itself cannot reach the network (its content security policyallows none).- No telemetry, no accounts, no update pings. With a local model, nothingleaves the machine at all.## InstallBuild from source: after the Quick start, `npm run tauri build` makes arelease build (the `.app` and a `.dmg` on macOS). The build is ad-hoc signed,not notarized, so macOS asks once: open System Settings, Privacy & Security,and choose "Open Anyway". Then:1. Settings, DeepInfra: paste your API key (from deepinfra.com, Dashboard, API Keys).2. Optionally add a local server under Local servers (Ollama is`http://localhost:11434/v1`).3. Set a monthly budget if you want the warnings.`npm run dev` serves the interface alone in a browser, on sample data.## TestsThe Rust tests run every provider path against `crates/standin`, a smallOpenAI-compatible server whose behavior is picked by model id: streaming withusage, no usage, cached tokens, reasoning, images, errors before and during astream, and a slow reply for testing Stop (which checks that the server seesthe connection close). The Playwright run covers two window sizes in boththemes, the main flows, and an axe check for contrast and labels. Theend-to-end run starts the actual Tauri binary under a virtual display, pointsit at the stand-in, and sends a message, stops one, searches, and exports anote.What needs a real key and a Mac (live prices, DeepInfra's usage reporting,vibrancy, the Keychain, the global shortcut) is a five-minute checklist in[docs/verify-on-mac.md](docs/verify-on-mac.md).## Keyboard| Keys | Does ||---|---|| Cmd+Shift+Space | Quick prompt, from anywhere (changeable) || Cmd+N | New chat || Cmd+K | Search chats || Cmd+, | Settings || Enter / Shift+Enter | Send / new line || Esc | Stop the reply; close a panel || Cmd+Enter (quick prompt) | Continue in the main window |## Limitations- No tool calling or agents: Cortex is for talking to a model, on purpose.- macOS is the target. Linux builds and is tested (without vibrancy); Windowsis not built.- The quick prompt may not appear over full-screen apps on macOS.- Token estimates for local servers are approximate, and marked as such.- Prices come from DeepInfra's public model list, which is an extension to theOpenAI format rather than a documented contract; the dated offline copy isthe fallback.## LicenseMIT.