Commit Graph
132 Commits
Author SHA1 Message Date
6240c59ca3 Update cost-comparison models: GPT-5.6 Sol, Claude Fable 5 (#634)
Refresh the cost-comparison / savings surfaces to current frontier cloud
pricing (per 1M tokens):

- OpenAI:    GPT-5.3 ($2/$10)        -> GPT-5.6 Sol ($5/$30)
- Anthropic: Claude Opus 4.6 ($5/$25) -> Claude Fable 5 ($10/$50)
- Google:    Gemini 3.1 Pro ($2/$12)  -> unchanged

Internal provider keys are renamed in lockstep (gpt-5.3 -> gpt-5.6-sol,
claude-opus-4.6 -> claude-fable-5) across the canonical CLOUD_PRICING
dict, the two server-rendered HTML pages, and the frontend color/label
maps so backend, dashboard, and UI stay consistent. Energy/FLOPs
metadata is carried over unchanged. Model catalog and eval configs are
untouched (real model/benchmark entries, not the cost comparison).

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 14:48:22 -07:00
215ab76e5f docs: point the Project Site link to openjarvis.stanford.edu (#628)
The project's canonical site moved from the Scaling Intelligence Lab blog
(scalingintelligence.stanford.edu/blogs/openjarvis/) to
https://openjarvis.stanford.edu/. Update every reference to that URL:

- README: the "Project" badge and the "Project Site" link
- docs/index.md: the research write-up link
- desktop Settings: the "Project site" link (SettingsPage.tsx)
- the Twitter-bot operator prompt

The bare Scaling Intelligence Lab homepage links (the lab itself, not the
project site) are intentionally left unchanged, as are the github.io
documentation and installer URLs.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 13:27:32 -07:00
904133cb25 fix(research): respect configured engine for Deep Research (#616)
Fixes #575. Web Deep Research was hardcoded to OllamaEngine + DEFAULT_PLANNER_MODEL, ignoring the user's configured/active engine and model. Resolve the planner from [deep_research] override -> live app chat engine + selected model -> config defaults -> legacy Ollama, pass the chat picker's model from the frontend into /api/research, record the actual planner engine in telemetry, and refuse to silently fall back to a different engine (raise an actionable error instead). Adds config support and focused tests for resolution and the route. Related: #576 (duplicate).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 13:46:18 -07:00
e7c46c1985 fix(frontend): make Supabase anon key optional to unblock PyPI publishing (#589)
PyPI publishing had been broken since v1.0.3.dev851: #587 made VITE_SUPABASE_ANON_KEY a hard build-time requirement, but no such secret exists, so the frontend build aborted every publish run before the PyPI upload. Decouple package buildability from the leaderboard credential: a missing anon key now disables the savings leaderboard at runtime instead of failing the build, and auto-enables when the secret is provided. Verified: npm run build with the key unset succeeds; tsc + vitest pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 13:15:06 -07:00
8d33cb58fa Fix secure cloud key storage and Supabase key config (#587)
Route desktop cloud-key saves/status through the OS credential store (keyring with per-platform native backends: apple-native / windows-native / sync-secret-service), migrate the legacy plaintext ~/.openjarvis/cloud-keys.env into it, remove browser localStorage persistence of provider keys, and push key updates to the running server via /v1/cloud/reload (legacy env-file fallback retained). Remove hardcoded Supabase anon JWTs from frontend/docs source and make VITE_SUPABASE_ANON_KEY a required build var. Adds libdbus-1-dev to the Linux desktop build and a CI build var. Closes #220.

NOTE (post-merge follow-ups, not covered by CI): add the VITE_SUPABASE_ANON_KEY repo secret with the rotated key (release/docs builds otherwise use a placeholder), rotate the previously-committed Supabase anon key, and run a desktop save->restart->read smoke test to confirm keychain persistence.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 16:11:32 -07:00
Elliot SluskyandGitHub d4eb6308b1 Fix desktop speech dependency setup (#574) 2026-06-20 17:08:24 -07:00
f9d1bc8c27 fix(connectors): complete Google OAuth and register Drive in Data Sources (fixes #512) (#548)
Pasting a Google Client ID / Secret never completed OAuth: Drive (and its
Google siblings) accepted the credentials, showed no error, opened no browser,
and never appeared in Data Sources. Root cause is three coupled defects, all
reproduced at the unit level against main with a FastAPI TestClient (no Google
creds, network-free):

(A/B) POST /connect routed a `client_id:client_secret` pair into the
  connector's handle_callback, which spawned a daemon thread that popped a
  browser and ran its own localhost:8789 callback server. That thread fails
  silently in the bundled desktop context (`except Exception: pass`), so the
  connector never gained an access_token; /connect returned status "pending"
  and the UI's 20x2s poll timed out with no error.
  Fix: in POST /connect, an OAuth `client_id:client_secret` pair now persists
  the client credentials to every Google credential file and returns an
  `oauth_required` directive pointing at the in-process server flow, instead of
  the silent background thread. The Google connectors' handle_callback no longer
  spawns the browser thread for the pair case — it only persists the creds; the
  server's /oauth/start -> /oauth/callback owns the consent round-trip.

(C) The would-be-correct server flow was itself broken: under
  `from __future__ import annotations` plus a `Request` import local to the
  router factory, FastAPI could not resolve the stringized `request: Request`
  annotation. /oauth/start returned HTTP 422 (request mis-bound as a query
  param) and /oauth/callback injected None -> AttributeError on
  `request.base_url`. Fix: import `Request` at module scope and make the
  callback's `request` a required injected dependency.

A malformed/blank client pair now raises HTTP 400 with the provider setup URL
instead of a perpetual silent "pending" (REVIEW.md silent-failure discipline).

Frontend: DataSourcesPage now opens the server OAuth window when /connect
returns `oauth_required`, then polls until connected; connect errors surface the
backend detail; the Drive setup steps document the "Web application" OAuth
client + server-callback redirect URI the in-process flow requires.

Tests (run on the main venv, hermetic — no ~/.openjarvis pollution):
- test_oauth_flow.py: the three handle_callback tests now assert NO browser is
  opened and only client creds are persisted (was: assert background flow ran).
- test_connectors_router_oauth.py (new): reproduces + fixes all three defects via
  TestClient with mocked token exchange; parametrized over gdrive/gcalendar/
  gcontacts/gmail/google_tasks to prove the shared OAuth path is fixed for every
  sibling and that a single consent writes the access_token to all six Google
  credential files and flips is_connected() to True.
Full tests/connectors suite: 355 passed.

Relationship to PR #510: #510 rewrites all of these files (account-scoped
retrieval) but still carries all three defects. This fix is intentionally scoped
to the OAuth path and does not modify oauth.py, to minimize collision. A
maintainer can either merge this and rebase #510 on top, or port these changes
into #510. See PR body for details.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 19:55:22 -07:00
7ba334b5f0 fix(gui): inject bearer token into streaming chat/research routes (#499)
Ensures that the desktop GUI correctly sends the Authorization header
when an API key is configured. This resolves the 'Failed to get response'
bug on Windows systems with enabled authentication.

Ref: #266

Co-authored-by: sanjayravit <sanjay@example.com>
2026-06-14 17:32:43 -07:00
bc9fa6b3c8 fix(memory): surface clear error when openjarvis_rust missing instead of silent no-op (#527)
Memory tools degraded silently and misleadingly when the mandatory
`openjarvis_rust` extension was absent from the *serving* venv:

- `POST /v1/memory/store` returned HTTP 200 `{"status":"stored","note":
  "no backend available"}` and stored nothing (silent data loss).
- `POST /v1/memory/index` returned a generic "No memory backend available",
  and the desktop frontend discarded the server `detail` and threw a blanket
  "Failed to index path", blaming the path instead of the real cause.
- `GET /v1/memory/config` reported `backend_type: sqlite` even though no
  backend could be constructed.

Root cause: `SQLiteMemory.__init__` calls `get_rust_module()` (which raises
ImportError by design — the Rust ext is mandatory, no Python fallback), and
`_get_memory_backend` swallowed that ImportError and returned `None`,
conflating "native extension missing" (a hard install error) with "memory
intentionally disabled" (benign). A chunking floor also silently dropped whole
short documents, and the installer never verified the extension imported from
the serving venv before writing its success marker.

Fix (no fake Python fallback — the Rust ext stays mandatory by design):

- Add `MemoryBackendUnavailable` + `RUST_MISSING_HINT` in tools/storage/_stubs.
  `SQLiteMemory.__init__` translates the bridge ImportError into this clear,
  actionable error ("run `uv run maturin develop ...`").
- `_get_memory_backend` distinguishes the two cases: a missing native ext
  raises HTTP 503 with the actionable hint; a benign unconfigured backend
  still returns `None` (graceful path preserved for search/stats).
- `/store` now returns 503 instead of a 200 silent no-op.
- `/config` reports `available: false` + `detail` instead of falsely claiming
  a healthy `backend_type`.
- `/index` adds a `note` when `chunks_indexed == 0` so "indexed" never
  silently means "stored nothing".
- chunk_text no longer drops an entire short document below `min_chunk_size`
  (the floor only discards tiny *trailing* fragments now).
- Frontend `storeMemory`/`indexMemoryPath` surface the server `detail` instead
  of blanket strings; `MemoryConfig` gains optional `available`/`detail`.
  (Left the pre-existing `backend` vs `backend_type` mismatch untouched.)
- build-extension.sh verifies `import openjarvis_rust` succeeds in the serving
  venv before writing the `extension-built` marker.

Regression tests: tests/server/test_api_routes.py::TestMemoryRustMissing mocks
`get_rust_module` to raise ImportError and asserts /store (503, not 200 no-op),
/index (actionable detail, not "Failed to index path"), and /config
(available:false) all surface the clear error; tests/memory/test_chunking.py
asserts short-only docs are kept while tiny trailing fragments are still
filtered.

Fixes #502

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 13:25:10 -07:00
4b4fd587b2 fix(frontend): send local API key as Bearer on /v1 + /api requests (#471)
When `jarvis serve` runs with an API key configured, AuthMiddleware 401s
every /v1 and /api request that lacks a Bearer token. The frontend never
sent one, so telemetry, managed-agents, savings, etc. all failed (#266).

- Add getApiKey() (reads settings.apiKey, with optional
  VITE_OPENJARVIS_API_KEY build-time override) and authHeaders() to
  api.ts, plus an apiFetch() wrapper that prepends getBase() and injects
  the Bearer header on every local-server call. Route all /v1 + /api
  fetches through it so none can omit auth.
- Add `apiKey` to the Settings model (store.ts) and a password field in
  Settings → Connection so users can enter it.

Keyless local servers are unaffected: with no key, no Authorization
header is sent (byte-for-byte unchanged). The Supabase savings path keeps
its own anon key — not conflated with the local key.

Bootstraps vitest (no prior frontend test runner) + a `test` script, and
adds api.auth.test.ts covering getApiKey/authHeaders. Verified: tsc
--noEmit clean, vitest 6/6, vite build succeeds.

Deferred (not in scope): WebSocket auth (browsers can't set WS headers)
and Tauri auto-injecting a generated key.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 13:25:14 -07:00
Jon Saad-FalconandGitHub 21f1becb4d feat(desktop): single default model + custom OpenAI-compatible endpoints (#453) 2026-05-30 19:34:51 -07:00
Andrew ParkandGitHub 48dcb40be4 fix(desktop): surface backend error frames in Deep Research stream (#428) 2026-05-29 09:48:59 -07:00
Robby ManihaniandGitHub 26285e56fa fix(agents): wire continuous-agent Interact tab end-to-end + CLI workflow polish (#425) 2026-05-28 12:07:03 -07:00
Andrew ParkandGitHub c6448f7cf2 fix(desktop): preselect model in onboarding so first chat doesn't 400 (#427) 2026-05-28 11:19:52 -07:00
Tanvir BhathalandGitHub 0702f2793c (bug): telemetry fixes (#421) 2026-05-27 09:36:26 -07:00
Tanvir BhathalandGitHub c84f1fddee feat: proactive agent approval bell with approve/deny UI (#370) 2026-05-22 17:38:48 -07:00
Robby ManihaniandGitHub 855ed51780 feat: Deep Research Slack integration (#365) 2026-05-20 12:02:05 -07:00
Tanvir BhathalandGitHub a58d6b6c48 Auto Update (#358) 2026-05-19 11:57:10 -07:00
Jon Saad-FalconandGitHub fea8d3e872 release: v1.0.1 (#357) 2026-05-18 20:19:37 -07:00
Robby ManihaniandGitHub 9af0dfe336 feat: Deep Research — personal deep research over Gmail with hybrid retrieval and agentic synthesis (#354) 2026-05-18 17:46:12 -07:00
Tanvir BhathalandGitHub 7081be7bd3 [FEAT] Telemetry (#351) 2026-05-17 13:07:05 -07:00
Andrew ParkandGitHub 64d0f7ab02 feat(frontend): cleaner UI pass — consistent layout, tokens, skeleton loading (#258) 2026-04-17 12:33:29 -07:00
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