- Ollama engine: capture eval_count and prompt_eval_count from the
streaming final chunk (includes thinking/reasoning tokens).
- Routes: include usage data in the SSE finish chunk so the frontend
gets accurate token counts even in streaming mode.
- X-Ray footer: show estimated thinking tokens when completion_tokens
significantly exceeds visible output (e.g. "1695 generated · 11 prompt
· ~1680 thinking").
- Tauri commands: save_cloud_key writes keys to ~/.openjarvis/cloud-keys.env
(chmod 600), get_cloud_key_status reports which providers are configured.
- Server spawn: reads cloud-keys.env and injects keys as env vars into
the jarvis serve process, so CloudEngine picks them up automatically.
- Frontend: Cloud Models tab saves keys through Tauri invoke (desktop)
in addition to localStorage (web), so keys persist across restarts.
- Flow: user enters key in Cloud tab → saved to disk → next server
start picks it up → cloud models appear in the model list.
1. Cloud Models tab: third tab in Cmd+K palette with API key management
for OpenAI, Anthropic, Google, and OpenRouter. Keys stored in
localStorage (never sent externally). Top-3 models per provider
shown when key is configured. Connected status indicator.
2. New chat button: skip creating a new chat if the current one is
empty (no messages). Prevents stacking empty conversations.
3. Tab label: "Installed" renamed to "Installed Models (N)" for clarity.
1. Desktop icon: bake rounded corners into the PNG/ICNS/ICO so the icon
looks consistent on Desktop and in Applications.
2. SetupScreen: truncate long status text with ellipsis, word-break
error messages so they don't overflow the block.
3. Model switching: create a new chat session when changing models,
preventing stale context errors with the new model.
4. X-Ray footer: show input/output token counts in the collapsed
summary (e.g. "42 in · 128 out") alongside engine, model, latency.
* feat(ui): update design tokens — system-ui font, warmer palette, accent triad
- Remove Merriweather serif font, switch to system-ui font stack
- Warmer dark mode neutrals (#161618 bg instead of #09090b)
- Add amber/purple accent tokens for signature color triad
- Update borders to rgba for softer feel
- Tighter line-height (1.5) and letter-spacing (-0.01em)
- Update PWA theme_color to match new palette
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(ui): frosted glass sidebar with backdrop-blur
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(ui): initialize shadcn/ui with button, dialog, input, select, tooltip, sonner
Set up shadcn/ui (v4) for Tailwind CSS v4 with CSS-first config. Added
path aliases (@/) to tsconfig.json and vite.config.ts. Installed six
components (button, dialog, input, select, tooltip, sonner) and wired
Sonner's <Toaster> into App.tsx for toast notifications. Removed the
next-themes dependency since this is a Vite/React project, not Next.js.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(ui): disable create agent when unavailable, replace errors with toasts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(ui): add System Pulse bar and health check banner
- 3px gradient bar at top reflecting system state (idle/inferencing/agent)
- Health check banner when backend is unreachable
- Pulse colors: blue (inference), purple (agents), dim blue (idle)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* feat(ui): add X-Ray message footers with collapsible telemetry
- MessageTelemetry type on ChatMessage (engine, model, speed, TTFT, timing)
- Capture timing data during SSE streaming in InputArea
- XRayFooter component: collapsed one-liner + expandable trace grid
- Integrated into MessageBubble, replacing old token count display
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(ui): resolve shadcn/ui CSS token conflicts with design system
- Namespace shadcn @theme inline variables (--color-cn-*) to avoid
overriding project's --color-border, --color-accent, --radius-* tokens
- Remove @apply border-border, bg-background, text-foreground, font-sans
that conflicted with our explicit CSS custom properties
- Remove dead Geist font import (we use system-ui)
- Remove ---break--- comment artifacts from shadcn CLI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace confirm() dialog (blocked by Tauri webview) with a
double-click confirmation pattern: first click turns the button
red with "Click again to confirm", second click clears data.
Resets after 3 seconds if not confirmed.
- Boot sequence: Phase 2 now pulls ALL Qwen3.5 models that fit in RAM
before the server starts. SetupScreen blocks until every model is
downloaded, showing per-model progress. No more background Phase 4.
- Default model: third-largest fitting model (qwen3.5:9b on 64GB).
- Download button: added pull_ollama_model and delete_ollama_model Tauri
commands. Frontend uses Tauri invoke in desktop mode, fixing the
"Load failed!" CORS/timeout issue with fetch().
* feat: model catalogue with download/delete and auto-pull Qwen3.5
- Desktop boot: start server immediately with fallback model (qwen3:0.6b),
then pull preferred model (qwen3.5:4b) and remaining Qwen3.5 variants
that fit in RAM in the background. No more broken "Select model" state.
- Backend: add POST /v1/models/pull and DELETE /v1/models/{name} endpoints
so the frontend can trigger model downloads and deletions via Ollama.
- Frontend: redesign CommandPalette (Cmd+K) with two tabs — "Installed"
shows pulled models with select/delete, "Download Models" shows a
catalogue of popular models plus a custom model input field.
- Fix ollama_has_model() to use exact tag matching instead of prefix
matching, preventing false positives.
* fix: streaming, model switching, second-largest default, and tests
- Streaming: use direct engine streaming for non-tool requests so tokens
arrive in real-time instead of being batched by the agent bridge.
Add error handling to _handle_stream so engine errors surface as
content chunks instead of silent failures.
- Model selection: pick the second-largest Qwen3.5 model that fits
(leaves headroom for OS/apps) instead of the absolute largest.
- Model switching: abort in-flight stream when the user changes models
mid-generation, preventing stale-model errors. Improve error messages
in catch blocks.
- Tests: add tests/server/test_model_management.py with 11 tests
covering model pull/delete endpoints, streaming error resilience,
direct-engine streaming bypass, and model listing. All 100 server
tests pass.
Detect system RAM at startup and automatically pull all Qwen3.5 model
variants (0.8b through 122b) that can run on the user's machine. The
smallest model is pulled first so the app is usable immediately, then
remaining models download in the background. The server starts with the
largest fitting model as default.
Also fixes ollama_has_model() to use exact tag matching instead of
prefix matching, which previously caused false positives (e.g. qwen3:0.6b
matching qwen3.5 queries).
Three issues fixed:
1. The desktop-latest release accumulated stale artifacts across builds
because tauri-action adds new files without removing old ones. Users
could download an outdated DMG. Added a clean-release job that wipes
all existing assets before the build matrix runs.
2. The frontend hardcoded DESKTOP_API to port 8000 but the Tauri backend
starts the server on port 8222. Added a get_api_base Tauri command so
the frontend fetches the port from the Rust backend at startup,
keeping JARVIS_PORT as the single source of truth.
3. frontend/package.json version was 1.0.0 while desktop and pyproject
are 0.1.0, causing duplicate artifact names in the release.
getBase() reads settings.apiUrl from localStorage so the API URL
configured in the Settings page is actually used by api.ts and sse.ts.
Previously hardcoded to localhost:8000, causing "Failed to get response"
when the backend ran on a different port.
Co-authored-by: robbym-dev <robbym-dev@users.noreply.github.com>
Two minor frontend bugs:
- App.tsx: browser app hardcoded energy_wh_saved and flops_saved to 0
when submitting to the leaderboard instead of computing them from
per_provider data (desktop app was already correct)
- GetStartedPage.tsx: CodeBlock code props used JSX string attributes
(code="...\n...") which render \n literally; switched to JS
expressions (code={"...\n..."}) so newlines render correctly
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>