mattrguerra/cortexmainPrivate on GitHub, published here in full

README.md

Language Markdown7.6 KB177 lines

README.md

  1. # Cortex
  2. A native desktop client for language models that shows what every reply
  3. costs. Tauri v2 (a Rust shell) and React, on DeepInfra's hosted models or any
  4. model server you run yourself.
  5. ![Cortex in light mode: a sidebar of chats with the cost of each, and a conversation about a backup script with the tokens and cost under the reply](docs/screenshots/main-light.png)
  6. ## Quick start
  7. Needs Rust (stable) and Node 22. On Linux, also the WebKitGTK development
  8. libraries that `.github/workflows/ci.yml` installs.
  9. ```bash
  10. npm ci
  11. npx vite build # first: the Rust build embeds the built interface
  12. cargo test --workspace # core logic, the provider against the stand-in, whole turns
  13. npm test # Vitest: formatting, markdown safety, the store, the app renders
  14. npm run typecheck # tsc
  15. npm run test:ui # Playwright: the interface in Chromium, on sample data
  16. npm run tauri dev # the app, with hot reload
  17. ```
  18. The end-to-end run drives the real app over WebDriver on Linux. It needs
  19. `webkit2gtk-driver`, `xvfb`, `dbus-x11` and `cargo install tauri-driver`, and a
  20. debug build with the `e2e` feature first:
  21. ```bash
  22. npx tauri build --debug --no-bundle --features e2e
  23. scripts/e2e-linux.sh
  24. ```
  25. CI also checks formatting and lints:
  26. ```bash
  27. cargo fmt --all --check
  28. cargo clippy --workspace --all-targets -- -D warnings
  29. npm run format:check # Prettier over src/ and e2e/
  30. ```
  31. ## Why it exists
  32. Hosted chat apps charge a flat monthly fee whether you ask one question or a
  33. thousand. Paying per token through an inference provider is usually far
  34. cheaper, but only if you can see what you are spending. Cortex puts the price
  35. of every reply in front of you: tokens in and out and the dollar cost under
  36. each answer, a running total per conversation, the month so far against a
  37. budget, and an estimate of what a prompt will cost before you send it.
  38. ## How it is built
  39. The logic lives in `crates/cortex-core`, a plain Rust library: the provider
  40. client and its streaming parser, pricing and cost, SQLite storage with
  41. full-text search, attachments and export. `src-tauri` holds the commands, the
  42. windows, the tray and the shortcut. The React interface talks to it through
  43. one typed interface, whose TypeScript types are generated from the Rust
  44. structs. More in [docs/architecture.md](docs/architecture.md).
  45. ```
  46. crates/cortex-core/ providers, streaming, pricing, cost, storage, export
  47. crates/standin/ the test stand-in for DeepInfra and local servers
  48. src-tauri/ the desktop shell: commands, windows, tray, shortcut
  49. src/ the React interface (main window and quick prompt)
  50. e2e/ Playwright (interface) and WebDriver (real app) tests
  51. docs/ architecture, cost accounting, the Mac checklist
  52. ```
  53. ## What it does
  54. - **Streaming chat** with any chat model on DeepInfra, or on a local server
  55. (Ollama, LM Studio, llama.cpp: anything OpenAI-compatible). Stop a reply at
  56. any point; what arrived is kept.
  57. - **A cost meter everywhere.** Live per-model prices from DeepInfra, stored
  58. with each reply so history never changes. Estimates are labeled "est.".
  59. Local models cost nothing. See [how cost is counted](docs/cost-accounting.md).
  60. - **A model picker with prices:** search, filter by vision, reasoning,
  61. favorites or local, and see input and output price per million tokens and
  62. the context size before you choose.
  63. - **A quick prompt.** Cmd+Shift+Space anywhere opens a small frosted prompt
  64. over whatever you are doing. Ask, read, press Esc. Cmd+Enter moves the
  65. conversation into the main window.
  66. - **Presets:** saved system prompts (with an optional model and temperature),
  67. applied to a chat in one click.
  68. - **Search** across every chat (full-text, as you type).
  69. - **Export to an Obsidian vault:** a conversation as Markdown with
  70. frontmatter (models, tokens, cost), images copied beside it.
  71. - **Images and files:** paste or drop an image for a vision model (it is
  72. downscaled first, since vision models bill by size), or a text file to read
  73. as context.
  74. - **macOS window materials:** frosted panels over native vibrancy, light and
  75. dark, with a choice of material and panel tint, and a solid mode for when
  76. transparency gets in the way.
  77. - **Menu bar:** this month's spend, a new chat or the quick prompt, from
  78. anywhere.
  79. ## Screenshots
  80. ![Cortex in dark mode, reading a chart of two pricing plans with a vision model](docs/screenshots/main-dark.png)
  81. ![The model picker: every chat model with its input and output price per million tokens and its context size](docs/screenshots/model-picker.png)
  82. ![Usage: spend this month by model and by day](docs/screenshots/usage.png)
  83. ![The quick prompt with an answer and its cost](docs/screenshots/quick-prompt.png)
  84. *Screenshots are the interface on its built-in sample data (every chat in them
  85. is invented), shown over the backdrop the page paints when there is no native
  86. vibrancy. On a Mac the panels sit on the frosted desktop instead.*
  87. ## Privacy
  88. - Chats, attachments and settings live in one SQLite file on your computer.
  89. - API keys live in the macOS Keychain, never in the database or a file. The
  90. interface can set or remove a key but never read one back. A key is checked
  91. with the provider before it is stored, so a mistyped one is caught at once.
  92. - The only network traffic is to the provider you chose, from the Rust side.
  93. The webview itself cannot reach the network (its content security policy
  94. allows none).
  95. - No telemetry, no accounts, no update pings. With a local model, nothing
  96. leaves the machine at all.
  97. ## Install
  98. Build from source: after the Quick start, `npm run tauri build` makes a
  99. release build (the `.app` and a `.dmg` on macOS). The build is ad-hoc signed,
  100. not notarized, so macOS asks once: open System Settings, Privacy & Security,
  101. and choose "Open Anyway". Then:
  102. 1. Settings, DeepInfra: paste your API key (from deepinfra.com, Dashboard, API Keys).
  103. 2. Optionally add a local server under Local servers (Ollama is
  104. `http://localhost:11434/v1`).
  105. 3. Set a monthly budget if you want the warnings.
  106. `npm run dev` serves the interface alone in a browser, on sample data.
  107. ## Tests
  108. The Rust tests run every provider path against `crates/standin`, a small
  109. OpenAI-compatible server whose behavior is picked by model id: streaming with
  110. usage, no usage, cached tokens, reasoning, images, errors before and during a
  111. stream, and a slow reply for testing Stop (which checks that the server sees
  112. the connection close). The Playwright run covers two window sizes in both
  113. themes, the main flows, and an axe check for contrast and labels. The
  114. end-to-end run starts the actual Tauri binary under a virtual display, points
  115. it at the stand-in, and sends a message, stops one, searches, and exports a
  116. note.
  117. What needs a real key and a Mac (live prices, DeepInfra's usage reporting,
  118. vibrancy, the Keychain, the global shortcut) is a five-minute checklist in
  119. [docs/verify-on-mac.md](docs/verify-on-mac.md).
  120. ## Keyboard
  121. | Keys | Does |
  122. |---|---|
  123. | Cmd+Shift+Space | Quick prompt, from anywhere (changeable) |
  124. | Cmd+N | New chat |
  125. | Cmd+K | Search chats |
  126. | Cmd+, | Settings |
  127. | Enter / Shift+Enter | Send / new line |
  128. | Esc | Stop the reply; close a panel |
  129. | Cmd+Enter (quick prompt) | Continue in the main window |
  130. ## Limitations
  131. - No tool calling or agents: Cortex is for talking to a model, on purpose.
  132. - macOS is the target. Linux builds and is tested (without vibrancy); Windows
  133. is not built.
  134. - The quick prompt may not appear over full-screen apps on macOS.
  135. - Token estimates for local servers are approximate, and marked as such.
  136. - Prices come from DeepInfra's public model list, which is an extension to the
  137. OpenAI format rather than a documented contract; the dated offline copy is
  138. the fallback.
  139. ## License
  140. MIT.