Commit Graph
110 Commits
Author SHA1 Message Date
Andrew ParkandGitHub 28e913f706 fix(agents): bind built-in tools, live tool-call UI, Markdown streaming (#255) 2026-04-17 11:01:50 -07:00
Andrew ParkandGitHub 48c23d87df perf: replace agents polling with WebSocket, fix workbox prod mode (#254) 2026-04-17 11:00:50 -07:00
f339c1c2d6 feat: memory UI, settings, and API fixes (#247)
* refactor: merge desktop/ into frontend/, eliminate duplicate Tauri scaffolding

The project had two overlapping directories: desktop/ (Tauri Rust backend +
stale React components) and frontend/ (real React app + dead Tauri stub).
This consolidates everything under frontend/:

- Move desktop/src-tauri/ → frontend/src-tauri/ (the real 1,720-line Rust
  backend with Ollama sidecar, backend lifecycle, cloud keys, overlay, etc.)
- Preserve 9 old desktop React components in frontend/src/components/Desktop/
  (excluded from TS build — APIs have drifted, kept for future integration)
- Delete the old frontend/src-tauri/ stub (246 lines, never compiled)
- Delete desktop/ entirely
- Fix tauri.conf.json frontendDist path (../../frontend/dist → ../dist)
- Update CI workflow, bump script, .gitignore, and docs paths
- Rename setup/ → Setup/ for consistent PascalCase component directories

* feat: add memory UI, settings, and fix memory API routes

- Add Memory tab to Data Sources page with stats, search, index path,
  and manual store functionality
- Add Memory section to Settings page with backend picker, context
  injection toggle, and parameter sliders (top_k, min_score, max_tokens)
- Add memory API functions to frontend (getMemoryStats, searchMemory,
  storeMemory, indexMemoryPath, getMemoryConfig)
- Fix backend /v1/memory/* routes to use app-level memory backend
  instead of creating fresh SQLiteMemory instances per request
- Add GET /v1/memory/config and POST /v1/memory/index endpoints
- Gracefully handle missing Rust backend (return defaults instead of 500)
- Fix nested scroll in Agents Interact tab (use viewport-relative height)

* fix: memory API routes, dialog plugin, and UI polish

- Fix memory API: use backend.retrieve() not .search(), .count() not
  .stats() to match actual SQLiteMemory interface
- Handle None backend gracefully in index endpoint (503 instead of crash)
- Expand ~ in index path (expanduser + resolve)
- Install @tauri-apps/plugin-dialog for native folder picker in Tauri
- Browse button only shows in Tauri (browser can't get absolute paths)
- Redesign Memory tab: proper cards, color-coded search scores, two-column
  layout for index/store, loading spinners, accent gradient on stats card

---------

Co-authored-by: Jon Saad-Falcon <41205309+jonsaadfalcon@users.noreply.github.com>
2026-04-14 09:53:14 -07:00
Andrew ParkandGitHub 54d79ef235 feat: add Apple Contacts connector (macOS AddressBook) (#248)
* feat: add Apple Contacts connector (macOS AddressBook)

Reads directly from ~/Library/Application Support/AddressBook/AddressBook-v22.abcddb
in read-only mode. Extracts names, phone numbers, emails, postal addresses, URLs,
social profiles, and notes for each contact. Requires Full Disk Access like
iMessage and Apple Notes connectors.

- New connector: src/openjarvis/connectors/apple_contacts.py
- Registered in connectors/__init__.py
- Added frontend catalog entry (PIM category) and icon mapping
- MCP tools: contacts_search, contacts_get_contact

* test: add comprehensive tests for Apple Contacts connector

15 tests covering: is_connected (exists/missing), sync yields all real
contacts (skips system rows), extracts all field types (phone, email,
address, URL, social, notes), cleans Apple label markup, org-only
contacts, minimal contacts, since filter, sync_status tracking,
structured metadata, disconnect, mcp_tools, registry, empty DB,
missing DB. Uses fake SQLite database — no real Contacts DB needed.

* fix: scan iCloud/Exchange source databases for all contacts

The main AddressBook database only contains locally-created contacts.
Synced contacts (iCloud, Exchange, etc.) live under
Sources/<UUID>/AddressBook-v22.abcddb. Now scans all source databases
and deduplicates by ZUNIQUEID across sources.

Adds tests for multi-source scanning and cross-source deduplication.
2026-04-14 09:49:08 -07:00
Andrew ParkandGitHub 55662fc426 refactor: merge desktop/ into frontend/, eliminate duplicate Tauri scaffolding (#246)
The project had two overlapping directories: desktop/ (Tauri Rust backend +
stale React components) and frontend/ (real React app + dead Tauri stub).
This consolidates everything under frontend/:

- Move desktop/src-tauri/ → frontend/src-tauri/ (the real 1,720-line Rust
  backend with Ollama sidecar, backend lifecycle, cloud keys, overlay, etc.)
- Preserve 9 old desktop React components in frontend/src/components/Desktop/
  (excluded from TS build — APIs have drifted, kept for future integration)
- Delete the old frontend/src-tauri/ stub (246 lines, never compiled)
- Delete desktop/ entirely
- Fix tauri.conf.json frontendDist path (../../frontend/dist → ../dist)
- Update CI workflow, bump script, .gitignore, and docs paths
- Rename setup/ → Setup/ for consistent PascalCase component directories
2026-04-14 09:48:12 -07:00
Tanvir BhathalandGitHub 9c15b25f90 [FEAT] New Interaction Interface UI (#237) 2026-04-13 14:23:15 -07:00
Jon Saad-FalconandGitHub a009646071 feat: Morning Digest with Voice Mode + unified OAuth + Apple connectors (#174) 2026-04-03 11:05:41 -07:00
mrTSB 2feaa10d97 fix local 2026-04-01 22:13:00 -07:00
3ea727fc43 fix: match template instruction keys to server template IDs (underscores)
Server returns template IDs with underscores (code_reviewer, research_monitor)
but TEMPLATE_INSTRUCTIONS used hyphens. Added both formats + prompts for
personal_deep_research and inbox_triager templates.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:24:36 -07:00
608ed7531c feat: add Models, API Keys, and Web Search sections to Settings
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:24:36 -07:00
370be96565 feat: add document import via paste text or file upload
Adds a new Upload / Paste data source that lets users paste text or upload
documents (.txt, .md, .pdf, .docx, .csv) directly into the knowledge base.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:24:36 -07:00
1100057b90 fix: improve Gmail connect instructions and add troubleshooting
Clarify that Gmail uses App Passwords (not OAuth login popup), emphasize
2-Step Verification prerequisite, and add a collapsible troubleshooting
section for common issues. Also improve the error message when Gmail
auth fails to specifically mention App Password requirements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:24:36 -07:00
beb5c0fb6c feat: reorder agent tabs (Interact first), add strategy tooltips
Move the Interact tab to the first position in agent detail view and
default to it when opening an agent. Add "(optional)" hint to Advanced
Settings and add (?) tooltips to Memory Extraction, Observation
Compression, Retrieval Strategy, and Task Decomposition labels.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:24:36 -07:00
aaab50ffcf feat: add pre-filled instruction prompts to agent templates
Add TEMPLATE_INSTRUCTIONS map with sensible defaults for daily-briefing,
research-monitor, code-reviewer, and meeting-prep templates so users get
a starting prompt when selecting a template. Show a warning hint when the
instruction contains [bracketed placeholders] that need to be replaced.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:24:36 -07:00
5c1990b7ae feat: add daily/weekly/hourly schedule presets for agents
Replace the manual/interval/cron schedule picker with friendlier presets
(Daily, Weekly, Every N hours, Custom cron) that generate the correct
cron expressions or interval values behind the scenes. Update
formatSchedule() to render human-readable labels like "Daily at 9:00 AM"
and "Weekly on Mon, Wed, Fri at 9:00 AM".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:24:36 -07:00
579ff50256 feat: add chat/edit/delete buttons and model status to agent cards
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:24:36 -07:00
dc2a2edbcd fix: data source connect flow UX, obsidian/gcalendar sync bugs, agent timeout
- Frontend: add progress stages (Connecting → Authenticating → Connected →
  Syncing) with spinner and progress bar to the data source connect flow.
  Previously sources would silently stay "Not connected" after setup.
  Show error message on failure instead of swallowing exceptions.

- Obsidian connector: use timezone-aware datetime (tz=timezone.utc) in
  fromtimestamp() to fix "can't compare offset-naive and offset-aware
  datetimes" crash during incremental sync.

- Google Calendar connector: catch HTTPStatusError when listing events
  for individual calendars (e.g. US Holidays returning 404) so one
  inaccessible calendar doesn't crash the entire sync.

- Agent SSE timeout: increase progress queue timeout from 120s to 600s
  so complex multi-hop deep research queries aren't killed mid-execution
  on slower local models.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 21:24:36 -07:00
mrTSB f8c37fe85e make cloud models on desktop app work 2026-04-01 21:22:25 -07:00
Jon Saad-FalconandClaude Opus 4.6 a57813fcfa feat: overhaul install + setup UX for data sources, messaging, and desktop app
- Skip SetupWizard on launch, go straight to Chat page
- Add Data Sources page with sidebar nav (separate tabs for data sources + messaging channels)
- Add "Connect your data" banner + quick-action buttons on Chat empty state
- Add hint on deep research agent pointing to Data Sources + Messaging tabs
- Consistent naming: "Data Sources" and "Messaging Channels" everywhere
- Fix Apple Notes / iMessage setup (remove broken system prefs link)
- Fix Slack data source: auto-join public channels, rate limit retry, is_member filter
- Add channels:join scope to all Slack manifests + docs
- Fix Gmail: use gmail_imap connector (IMAP + app password), increase limit to 5000
- Fix sync endpoint: run in background thread, return immediately
- Show sync progress with progress bar, error messages, Sync Now / Re-sync / Retry buttons
- Add triggerSync() API + SyncStatusDisplay component
- Rewrite all connector setup instructions with precise click-by-click steps
- Notion: share all pages at once via top-level page sharing
- Obsidian: show how to find vault path via Obsidian UI or Finder
- SendBlue: add link to API Credentials page, add ngrok webhook step
- Slack messaging: add Copy button for JSON manifest
- Add OpenJarvis Slack icon asset
- Shorten deep research template description
- Fix desktop app port (8222 → 8000 to match server default)
- Disable auto-updater for local dev builds
- Register Slack, Outlook, GCalendar connectors in __init__.py
- Auto-create default agent when setting up messaging channels

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 22:44:59 -07:00
Jon Saad-FalconandClaude Opus 4.6 bc31cce732 feat: simplify Messaging tab to iMessage/SMS (SendBlue) + Slack only
Removed WhatsApp (Baileys blocked by WhatsApp servers) and Twilio SMS
(SendBlue handles SMS as fallback automatically). Updated Slack setup
instructions with the App Manifest JSON for one-step configuration.

Three channels: iMessage + SMS (SendBlue), Slack (Socket Mode)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 17:17:51 -07:00
Jon Saad-FalconandClaude Opus 4.6 9825daa334 feat: complete SendBlue integration — auto-restore, CLI, health check, docs
- Register sendblue in channels/__init__.py so ChannelRegistry works
- Auto-restore SendBlue bindings on server startup from database,
  re-creating ChannelBridge + DeepResearchAgent so webhooks survive
  server restarts
- Add sendblue to CLI channel_cmd.py (_get_channel, help text) and
  SystemBuilder._resolve_channel() for config.toml support
- Health check endpoint GET /v1/channels/sendblue/health returns
  channel_connected, bridge_wired, ready status
- Frontend: SendBlueWizard checks health on mount, shows
  "Disconnected" badge with "Reconnect" button when bridge is dead
- Docs: CLI usage, server restart behavior, ngrok re-registration,
  troubleshooting table, health check endpoint

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:33:12 -07:00
Jon Saad-FalconandClaude Opus 4.6 bfcc90866c fix: make Slack App Token required, fix CLI prompt label
App Token (xapp-) is required for Socket Mode DMs, not optional.
Removed xoxe- from CLI prompt since session tokens don't work.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:21:04 -07:00
Jon Saad-FalconandClaude Opus 4.6 6e57379018 fix: handle SendBlue free tier (shared line) in setup wizard
When /api/lines returns no numbers (free/shared line tier), the wizard
now shows a manual input with instructions to copy the phone number
from the "Send from" field in the SendBlue dashboard, instead of
showing an error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 21:40:57 -07:00
Jon Saad-FalconandClaude Opus 4.6 0508056903 fix: correct SendBlue signup URL to dashboard.sendblue.com/company-signup
The old sendblue.co/getblue URL causes ERR_TOO_MANY_REDIRECTS.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 21:22:13 -07:00
Jon Saad-FalconandClaude Opus 4.6 1adab5d849 feat: SendBlue guided wizard with auto-verify, auto-register, test msg
Backend:
- POST /v1/channels/sendblue/verify — validates API keys, auto-fetches
  assigned phone numbers from SendBlue GET /api/lines
- POST /v1/channels/sendblue/register-webhook — auto-registers the
  /webhooks/sendblue callback URL with SendBlue
- POST /v1/channels/sendblue/test — sends a test iMessage to verify setup

Frontend:
- SendBlueWizard component with multi-step guided flow:
  Step 1: "Open SendBlue signup" button (opens in new tab)
  Step 2: Paste API Key + Secret → "Verify & Find Number" auto-fetches
  Step 3: Shows discovered phone number → "Activate Phone Number"
  Step 4: Success state with "Send Test" button
- Active state shows agent's number + test message sender
- Generic channels (Slack, WhatsApp, SMS, local iMessage) listed below

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 21:18:02 -07:00
Jon Saad-FalconandClaude Opus 4.6 7fd247be7e feat: wire Slack Socket Mode listener to channel bind/unbind
When user connects Slack in the Messaging tab, the backend now creates
a SlackChannel with Socket Mode, registers a handler that routes incoming
DMs to DeepResearchAgent, and starts listening. Unbinding disconnects
the Socket Mode client.

Requires slack-sdk installed and both bot_token (xoxb-) + app_token (xapp-).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 20:44:55 -07:00
Jon Saad-FalconandClaude Opus 4.6 e5477e89fe fix: preserve telemetry metadata when polling refreshes messages
The 2-second polling interval was replacing local messages (with _usage,
_telemetry) with server messages (without those fields). Now stores
metadata in a ref and merges it back when polling refreshes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 20:06:14 -07:00
Jon Saad-FalconandClaude Opus 4.6 e9fe9be035 feat: add full telemetry footer to agent Interact responses
Shows engine, model, tokens, speed, latency, tool calls — matching
the Chat tab's XRayFooter UX. Click to expand detailed view.
Backend streams usage + telemetry in final SSE chunk.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 19:54:22 -07:00
Jon Saad-Falcon df129790f9 Merge branch 'feat/deep-research-setup' 2026-03-27 19:46:55 -07:00
Jon Saad-FalconandClaude Opus 4.6 f69c400896 fix: resolve stuck thinking bubble and add response metadata footer in InteractTab
The progress indicator now only shows when waitingForResponse or sending
is true, preventing it from persisting after the response arrives due to
stale isAgentWorking/hasPending checks. Agent response bubbles now display
elapsed time, tool call count, and a copy button in an XRay-style footer.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 19:35:16 -07:00
Jon Saad-FalconandClaude Opus 4.6 c079197c4e fix: improve Interact tab UX and add real-time activity logging
- Replace "Run Now" button with "Chat ready" hint when on the Interact
  tab so users know they can just type a message without pressing Run.
- Add learning log entries in generate_deep_research() for query start,
  tool calls, tool results, query completion, and errors so interactive
  queries are visible in the Logs tab.
- Rewrite LogsTab to poll every 5 seconds, merge execution traces with
  learning log entries into a unified timeline sorted by timestamp.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:26:57 -07:00
Jon Saad-FalconandClaude Opus 4.6 de91fe6ecf feat: add real-time streaming and tool progress to InteractTab
Refactor sendAgentMessage to accept onProgress/onContentDelta/onDone
callbacks so the InteractTab can show content as it arrives word by
word, display tool-call progress labels (e.g. "Querying data with
SQL"), and render an elapsed-time footer. The backend now streams
tool_progress SSE events from DeepResearchAgent before the final
content, matching the Chat tab's polished streaming UX.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:17:10 -07:00
Jon Saad-FalconandClaude Opus 4.6 bd22eeae1e fix: show 'Researching your data...' indicator while agent processes query
Added waitingForResponse state that stays true during the entire stream
consumption. Shows a pulsing indicator with descriptive text so the user
knows the agent is working (searching, analyzing, writing report).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:06:22 -07:00
Jon Saad-FalconandClaude Opus 4.6 7f7cf5ccd9 fix: show agent response in chat bubble + auto-ingest after connector connect
1. InteractTab now displays the streamed agent response as a bubble
   immediately after it finishes (was being discarded)
2. Connecting a source auto-triggers background ingest into KnowledgeStore
   so Google Drive data appears with chunk counts immediately

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:00:14 -07:00
Jon Saad-FalconandClaude Opus 4.6 9f204e8368 fix: poll connector status after OAuth connect, auto-refresh every 10s
The Google OAuth flow runs in a background thread. The frontend now polls
every 3s after connecting to detect when the token arrives, and auto-refreshes
every 10s to catch background completions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:51:54 -07:00
Jon Saad-Falcon 490870a25c fix: show user message bubble immediately before waiting for agent response 2026-03-27 17:42:37 -07:00
Jon Saad-FalconandClaude Opus 4.6 b38d5565b0 fix: send stream:true for agent messages so backend actually runs the LLM
The Interact tab was sending messages without stream:true, so the backend
just stored them as pending without running the agent. Now consumes the
SSE stream and displays the full response.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:12:38 -07:00
Jon Saad-Falcon fcc146b050 fix: split Google OAuth into separate Client ID and Client Secret fields 2026-03-27 16:51:53 -07:00
Jon Saad-FalconandClaude Opus 4.6 8d9eed6533 feat: add Reconnect button to connected sources, show warning for 0-data sources
Connected sources now show a "Reconnect" button that expands the inline setup
flow to re-enter credentials. Sources with 0 chunks show "Connected — no data
synced yet" in amber instead of "0 items" in green.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:30:01 -07:00
Jon Saad-FalconandClaude Opus 4.6 6c9ede1756 fix: merge Gmail IMAP into single "Gmail" channel entry
Remove duplicate gmail OAuth entry, rename gmail_imap to gmail in frontend
so it matches the backend connector ID that has the actual data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:21:36 -07:00
Jon Saad-FalconandClaude Opus 4.6 175a13492f fix: improve Channels tab UX — larger fonts, per-source labels, detailed setup instructions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:00:05 -07:00
Jon Saad-FalconandClaude Opus 4.6 ae73eca91a feat: replace Channels tab with data sources + add Messaging tab
Rewrite ChannelsTab to show connector data sources (Gmail, Slack, Notion,
etc.) with chunk counts, connected/not-connected states, and inline setup
with step-by-step instructions. Add new MessagingTab for phone/platform
messaging (iMessage, Slack, WhatsApp, SMS). Update DETAIL_TABS to include
both tabs with Database and Wifi icons respectively.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 15:40:50 -07:00
Jon Saad-FalconandClaude Sonnet 4.6 af53d51e58 feat: add StepByStepPanel with per-connector setup instructions
Adds StepByStepPanel component to SourceConnectFlow that renders numbered
setup steps with optional links and input fields for each connector. Wires
it as the primary panel for any connector with steps defined, with existing
OAuth/Local/Filesystem panels as fallbacks. Also updates connectors.ts to
use ConnectorMeta (with SetupStep/inputFields) as the canonical type and
exports SourceCard as a backward-compatible alias.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 15:07:03 -07:00
Jon Saad-FalconandClaude Sonnet 4.6 639c641618 feat: add per-connector setup instructions and input fields to SOURCE_CATALOG
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 15:05:55 -07:00
Jon Saad-FalconandClaude Sonnet 4.6 5aa5cd8c9e feat: add Channels tab to agent detail view with connect/disconnect UI
Adds iMessage, Slack, WhatsApp, and SMS (Twilio) channel binding UI to
the agent detail view, with expandable connect forms and active/disconnect states.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 15:04:12 -07:00
Jon Saad-FalconandClaude Opus 4.6 c36695a399 fix: parallel section titles — Agent Statistics, Local Utilization, Dollars Saved vs.
Remove "Cloud Savings for Agent" card title. Add "Agent Statistics"
as section title over the usage metrics, aligned with "Local
Utilization" and "Dollars Saved vs." — all three sections now have
matching uppercase labels at the same vertical position.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:46:37 -07:00
Jon Saad-FalconandClaude Opus 4.6 4cbe29c027 fix: section titles "Local Utilization" and "Dollars Saved vs."
Three grouped sections inside the savings card, separated by
vertical dividers: usage metrics | Local Utilization (compute,
energy) | Dollars Saved vs. (GPT-5.3, Claude, Gemini). Section
titles are small uppercase labels above each group.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:39:58 -07:00
Jon Saad-FalconandClaude Opus 4.6 c013bc82f0 fix: add "SAVED vs." label before cloud provider cost comparisons
Vertical "SAVED vs." label between the divider and provider costs
makes it clear the dollar amounts represent money avoided by
running locally instead of using cloud APIs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:32:12 -07:00
Jon Saad-FalconandClaude Opus 4.6 22fa74bc36 fix: unified savings card with dividers, large values, clean layout
Single card with "Cloud Savings for Agent" header. All metrics
(queries, tokens, compute, energy, dollar savings) in one flex row
with vertical dividers separating usage | compute+energy | costs.
Large bold values above small labels. Consistent typography.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:24:43 -07:00
Jon Saad-FalconandClaude Opus 4.6 54d5a4a4c0 fix: single row for stats + savings, value above label, consistent style
All bubbles (Total Queries, Input Tokens, Output Tokens, Compute,
Energy, and per-provider dollar savings) now sit in one flex row
under "Cloud Savings for Agent". Each bubble has the value (bold)
above the label, with consistent styling. Green for savings values.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 14:20:05 -07:00