| 2 | |
2 | |
| 3 | **One interface. Every model. Bring your own keys.** — https://www.polyllm.io |
3 | **One interface. Every model. Bring your own keys.** — https://www.polyllm.io |
| 4 | |
4 | |
| 5 | −PolyLLM is a universal control center for AI models: connect your own OpenAI, Anthropic, Google Gemini, xAI, Mistral, DeepSeek, Kimi (Moonshot), OpenRouter and Cerebras API keys, |
5 | +PolyLLM is a mobile-first, multi-model AI workspace — an "AI operating system" rather than a chat box: connect your own |
| 6 | −discover the models your keys can reach, configure each one with only the parameters it supports, chat with real |
6 | +OpenAI, Anthropic, Google Gemini, xAI, Mistral, DeepSeek, Kimi (Moonshot), OpenRouter and Cerebras API keys (plus any |
| 7 | −token-by-token streaming, compare up to four models side by side in the Arena, and track tokens, latency and estimated |
7 | +OpenAI-compatible endpoint such as Ollama, LM Studio, vLLM, llama.cpp or MLX), discover the models your keys can reach, |
| 8 | −cost. Keys are encrypted at rest (AES-256-GCM, HKDF-derived data key, AAD-bound to the user) and only decrypted on the |
8 | +configure each one with only the parameters it supports, chat with real token-by-token streaming, let the transparent |
| |
9 | +**Smart Router (AUTO)** recommend a model, compare 2–4 models inline or in the **Arena** (blind mode, votes per criterion, |
| |
10 | +personal scoreboard), organise work in **Projects** with a prompt library (`{{variables}}`) and a reusable file library, |
| |
11 | +search everything (`model:claude project:research after:2026-08-01`), share/export conversations, and track tokens, |
| |
12 | +latency, cost, projections and savings opportunities in **Usage**. Installable as a PWA; designed first for 375–430 px |
| |
13 | +phones (bottom navigation, bottom sheets, swipe gestures, keyboard-safe composer), then tablet and desktop. Keys are encrypted at rest (AES-256-GCM, HKDF-derived data key, AAD-bound to the user) and only decrypted on the |
| 9 | server immediately before a provider request. |
14 | server immediately before a provider request. |
| 10 | |
15 | |
| 11 | ## Stack |
16 | ## Stack |
| 19 | src/lib/ai/core provider-neutral contract: PolyModel, UnifiedChatRequest, UnifiedStreamEvent, errors, retry, pricing, normalization |
24 | src/lib/ai/core provider-neutral contract: PolyModel, UnifiedChatRequest, UnifiedStreamEvent, errors, retry, pricing, normalization |
| 20 | src/lib/ai/providers adapters (openai, anthropic, gemini, xai, mistral, deepseek, kimi, openrouter, cerebras) + catalogs — provider quirks live ONLY here |
25 | src/lib/ai/providers adapters (openai, anthropic, gemini, xai, mistral, deepseek, kimi, openrouter, cerebras) + catalogs — provider quirks live ONLY here |
| 21 | src/lib/ai/registry model registry: live listing → catalog merge → Postgres; scheduled + manual sync |
26 | src/lib/ai/registry model registry: live listing → catalog merge → Postgres; scheduled + manual sync |
| 22 | −src/lib/chat turn orchestration (edit/regenerate/continue/branch), built-in tools loop, SSE |
27 | +src/lib/chat turn orchestration (edit/regenerate/continue/branch/adopt, ephemeral temporary chats), built-in tools loop, SSE |
| |
28 | +src/lib/arena sessions, streaming per model, votes/criteria, winner & scoreboard math, exports, public shares |
| |
29 | +src/lib/projects|library|prompts workspaces, reusable files (token estimates), prompt templates with variables |
| |
30 | +src/lib/search full-text search (Postgres FTS + filter query language) · src/lib/export conversation exports (md/txt/json/html→print) |
| |
31 | +src/lib/endpoints custom OpenAI-compatible endpoints (encrypted keys/headers, discovery, SSRF guard) · src/lib/usage analytics & savings |
| |
32 | +src/lib/models model intelligence: badges, lifecycle, intent search, compare slugs, parameter groups · src/lib/client router & token estimators |
| 23 | src/lib/providers encrypted key storage & validation |
33 | src/lib/providers encrypted key storage & validation |
| 24 | −src/components ui kit · app shell · chat · arena · settings · marketing |
34 | +src/db schema.ts (core) + schema-workspace.ts (1.0 tables) · drizzle/ migrations |
| 25 | −docs/ provider-research (per provider, dated), provider-test-matrix (generated), deployment-cluster, final-audit, UI brief |
35 | +src/components ui kit (sheet, segmented, …) · app shell (bottom nav, drawer) · chat · models · arena · projects · library · prompts · search · share · usage · providers · settings · marketing |
| 26 | −scripts/ sync-models, provider-matrix (real-API tests) |
36 | +docs/ UPGRADE-PLAN (1.0 contract) + upgrade-notes/ (per area) · provider-research · provider-test-matrix · deployment-cluster · UI brief |
| 27 | −e2e/, tests/ Playwright workflows, vitest unit tests |
37 | +scripts/ sync-models, provider-matrix (real-API tests), brand-assets (favicons / PWA icons / OG image) |
| |
38 | +e2e/, tests/, qa/ Playwright workflows, vitest unit + integration tests, responsive QA sweeps (`qa/responsive-qa.mjs`, `qa/flows.mjs`) |
| 28 | ``` |
39 | ``` |
| 29 | |
40 | |
| 30 | ## Development |
41 | ## Development |
| 38 | EMAIL_DRY_RUN=1 EMAIL_DRY_RUN_PRINT=1 pnpm dev && pnpm test:e2e # full browser workflow (links read from the dev log) |
49 | EMAIL_DRY_RUN=1 EMAIL_DRY_RUN_PRINT=1 pnpm dev && pnpm test:e2e # full browser workflow (links read from the dev log) |
| 39 | ``` |
50 | ``` |
| 40 | |
51 | |
| |
52 | +## Responsive QA |
| |
53 | +```bash |
| |
54 | +pnpm dev # single dev server on :3000 |
| |
55 | +QA_EMAIL=… QA_PASSWORD=… node qa/responsive-qa.mjs # 17 screens × 375/390/393/430/tablet/desktop → qa/out/ + report.json |
| |
56 | +node qa/flows.mjs --width=390 [--send] # drawer, model picker, composer, chat, Arena swipe, search, palette, sheets |
| |
57 | +``` |
| |
58 | + |
| 41 | ## Deployment |
59 | ## Deployment |
| 42 | −Runs on the private MacLustr cluster behind ngrok — see `docs/deployment-cluster.md`. |
60 | +Runs on the private MacLustr cluster behind the MacLustr Tunnel (WireGuard + Caddy on BHS64) — see `docs/deployment-cluster.md`. |
| |
61 | +Built and hosted by Simon-Pierre Boucher on [MacLustr](https://www.maclustr.io) · contact@spboucher.ai |
| 43 | |
62 | |
| 44 | ## Security notes |
63 | ## Security notes |
| 45 | No provider key ever reaches the browser, logs or analytics (structured logger redacts key-shaped strings and sensitive |
64 | No provider key ever reaches the browser, logs or analytics (structured logger redacts key-shaped strings and sensitive |