Commit Graph
411 Commits
Author SHA1 Message Date
Jon Saad-FalconandClaude Sonnet 4.6 677ece6fb3 feat: tag engines with is_cloud and tools with is_local for boundary scanning
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 20:26:26 -07:00
Jon Saad-FalconandClaude Opus 4.6 7c1f983891 feat: BoundaryGuard module — scan/redact/block at device exit points
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 20:24:07 -07:00
Jon Saad-FalconandClaude Opus 4.6 63a32d20d6 feat: secure server defaults — loopback binding, redact mode, rate limiting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 20:00:49 -07:00
Jon Saad-FalconandClaude Opus 4.6 44c52edfcd docs: security hardening implementation plan — 15 tasks with TDD
Detailed plan covering network exposure, boundary guard, webhook
validation, file permissions, log sanitization, credential scoping,
CORS hardening, and security profiles. Each task has failing tests
first, then implementation, then verification.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 19:26:59 -07:00
Jon Saad-FalconandClaude Opus 4.6 e842976d96 docs: security hardening design spec — layered boundary enforcement
Approved design for comprehensive security hardening covering network
exposure defaults, boundary guard scanning, webhook fail-closed validation,
file permissions, credential handling, log sanitization, and security profiles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 18:29:51 -07:00
Jon Saad-FalconandClaude Opus 4.6 6233ae1aa1 feat: Slack daemon as subprocess for reliable Socket Mode
Replaces the flaky inline bolt_app creation with a proper subprocess
daemon (slack_daemon.py). The daemon persists independently of the
HTTP request lifecycle, solving the Socket Mode connection dropping.

Features: thread replies, progress updates, message queue, Slack
formatting, PID file for lifecycle management.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:57:49 -07:00
Jon Saad-FalconandClaude Opus 4.6 9a6b1c1623 feat: reply in thread for Slack messages to reduce DM clutter
All bot replies (acknowledgment, progress updates, final response)
now use thread_ts to reply in the thread of the user's message.
Keeps the DM conversation clean — one thread per question.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:12:36 -07:00
Jon Saad-FalconandClaude Opus 4.6 590e8b90a3 feat: convert markdown to Slack formatting instead of stripping it
Converts: ## Header → *Header* (bold), **bold** → *bold*,
*italic* → _italic_, ~~strike~~ → ~strike~, [text](url) → <url|text>.
Removes LaTeX and HTML. System prompt updated to use simple markdown
since it gets auto-converted per platform.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:06:57 -07:00
Jon Saad-FalconandClaude Opus 4.6 d3c7c59c8d fix: improve SendBlue UX — queue tracking, periodic reminders, SMS formatting
1. Ack message: "Message received! Working on it now..."
2. Queue awareness: if another message arrives while processing,
   "Message received! Message X in queue, will respond ASAP"
3. Periodic reminders every 60s: "Still working! Will reply ASAP"
4. Response formatting: _format_for_sms() strips markdown headers,
   bold/italic, code blocks, LaTeX, image syntax, collapses blanks
5. System prompt: instructs agent to use plain text, short paragraphs,
   simple dashes — no markdown/LaTeX that breaks in iMessage/SMS

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 15:06:01 -07:00
Jon Saad-FalconandClaude Opus 4.6 2ef6615184 feat: improve Slack messaging UX — progress updates, queue, clean formatting
1. Initial: "Message received! Working on it now..."
2. Every 60s while processing: "Still working! Will reply ASAP"
3. New message while busy: "Message received! Message X in queue of Y"
4. Responses stripped of markdown (headers, bold, code blocks) for
   clean Slack display
5. System prompt updated to prefer plain text over complex markdown

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:59:03 -07:00
Jon Saad-FalconandClaude Opus 4.6 1252531551 test: add 26 tests for SendBlue channel and webhook
tests/channels/test_sendblue.py (18 tests):
- Init from params and env vars, no-credentials error state
- Connect/disconnect lifecycle
- Send: success, from_number inclusion, API error, network error,
  no-credentials, event emission
- Webhook handler: incoming triggers handlers, outbound ignored,
  empty content ignored, event emission, handler crash safety
- Properties: from_number, list_channels

tests/server/test_sendblue_webhook.py (8 tests):
- Webhook: incoming 200, outbound ignored, empty ignored, missing
  from_number ignored, secret validation (reject + accept), no bridge
- Health: ready=true when wired, ready=false when not

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:42:43 -07:00
Jon Saad-FalconandClaude Opus 4.6 1add224599 test: add 59 tests for system prompt, Slack messaging, and connector health
- test_deep_research_prompt.py (8 tests): date injection, time, day of week,
  dynamic generation, response types, tool descriptions, /no_think, Jarvis name
- test_slack_messaging.py (7 tests): connect with/without tokens, error state,
  disconnect, handler registration, send without token
- test_connector_health.py (44 tests): all 11 connectors instantiate, have
  required methods, report not-connected without creds, have metadata.
  Plus KnowledgeStore data presence checks.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:35:58 -07:00
Jon Saad-FalconandClaude Opus 4.6 7fd685f53a feat: inject current date/time into system prompt dynamically
The model now knows today's date and time. _build_system_prompt()
generates a fresh prompt with "Today is Saturday, March 28, 2026.
The current time is 02:28 PM." on every agent.run() call.

Fixes: model was hallucinating "January 29, 2025" for date queries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 14:29:54 -07:00
Jon Saad-FalconandClaude Opus 4.6 77a1c596b7 feat: expand system prompt with 12 adaptive query types
Jarvis now handles: casual, quick lookup, people lookup, daily/weekly
digest, meeting prep/debrief, task/follow-up finder, contact analysis
(neglected contacts, frequency), document finder, email triage,
cross-source synthesis, deep research, and about-self queries.

Tested: "neglected contacts" → 1 SQL call, 27s, real results.
"casual greeting" → 0 tools, 6s. Model adapts automatically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 10:07:36 -07:00
Jon Saad-FalconandClaude Opus 4.6 994671fcdf feat: adaptive system prompt — Jarvis responds naturally to different query types
Replaces the rigid deep-research-only prompt with an adaptive one that
classifies queries into 4 types:
1. Casual/conversational — friendly reply, no tools
2. Quick data lookup — one tool call, short answer
3. Deep research — multi-hop, cited report
4. About self — describe capabilities

Tested: casual gets 0 tool calls (6s), quick lookup gets 1 SQL call (17s),
self-description gets 0 calls (17s). Deep research still works as before.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:37:20 -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 87ad86bcb1 docs: add SendBlue iMessage/SMS channel setup guide
- Full setup walkthrough: SendBlue account, API keys, ngrok tunnel,
  webhook registration
- Documents the browser UI wizard flow (Messaging tab)
- Free tier notes: shared line, verified contacts, 10 contact limit
- Programmatic setup via Python
- Webhook behavior: instant ack, 45s delay notice, full response
- Constructor parameters and TOML config reference
- Added SendBlue to the supported channels table

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:17:09 -07:00
Jon Saad-FalconandClaude Opus 4.6 6e33d5bbfa feat: instant iMessage ack + delay notice for SendBlue channel
When a text arrives via SendBlue:
1. Immediately sends "Message received! Researching your data now..."
2. If the agent takes >45s, sends "Still working — complex query..."
3. Then sends the full research response

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:15:06 -07:00
Jon Saad-FalconandClaude Opus 4.6 bf28877fec docs: comprehensive Slack setup guide with Socket Mode, App Manifest, and troubleshooting
Covers both data connector (read messages) and messaging channel (DM the agent).
Includes the full App Manifest JSON, required scopes table, and all the gotchas
we discovered (Request URL, reinstall requirement, App Token vs Bot Token, etc.).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:12:36 -07:00
Jon Saad-FalconandClaude Opus 4.6 b808f47410 fix: create ChannelBridge + DeepResearchAgent when binding SendBlue
- When binding a SendBlue channel and no ChannelBridge exists, create
  one with a DeepResearchAgent wired to the knowledge store
- Fix _build_deep_research_tools scoping issue via self-import
- Fix model name resolution to fall back to app.state.model

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:12:06 -07:00
Jon Saad-FalconandClaude Opus 4.6 d123964ca7 feat: use slack-bolt for Slack Socket Mode — receives DMs and responds with DeepResearch
Replaced raw slack-sdk SocketModeClient with slack-bolt App which
properly handles event subscriptions, self-event filtering, and
message routing. Bot says "Message received! Researching now..."
then runs DeepResearchAgent and replies with the research result.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 21:50:08 -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 a3f355034f fix: learning log entries now write correctly, clean up debug logging
Learning log entries (query_start, tool_call, tool_result, query_complete)
now persist to SQLite and appear in the Logs tab. Fixed result.output->content
attribute name and removed debug print statements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 19:27:42 -07:00
Jon Saad-Falcon 7a6be1d45e debug: add logging for learning log writes 2026-03-27 19:22:16 -07:00
Jon Saad-Falcon 4c8b4e17e6 fix: correct store_agent_response args, fix result.output->content, add log warnings 2026-03-27 19:20:50 -07:00
Jon Saad-FalconandClaude Opus 4.6 d2df7d083e feat: real-time tool progress + live logs for DeepResearch agent
- InteractTab shows streaming content word-by-word with tool progress
- LogsTab polls every 5s, shows learning log entries with color-coded badges
- Backend emits tool_progress SSE events during agent execution
- Learning log entries written for query_start, tool_call, tool_result, query_complete
- "Run Now" replaced with "Chat ready" indicator on Interact tab

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 18:31:23 -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-FalconandClaude Opus 4.6 28d4cc7454 fix: run DeepResearchAgent with tools for managed agent streaming
The streaming endpoint was calling engine.stream_full() directly without
tools, so the agent responded as a generic chatbot. Now detects
deep_research agent type and runs the full DeepResearchAgent.run() loop
with knowledge_search, knowledge_sql, scan_chunks, and think tools,
then streams the result as SSE.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:45:32 -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-Falcon 8549324d28 fix: check port availability before starting OAuth callback server 2026-03-27 17:39:59 -07:00
Jon Saad-FalconandClaude Opus 4.6 53a20fde30 fix: run Google OAuth flow in background thread to prevent server freeze
The OAuth callback server blocks with handle_request(). Running it in a
daemon thread prevents it from freezing the FastAPI event loop.
Also accept system_prompt kwarg in DeepResearchAgent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:24:46 -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-FalconandClaude Opus 4.6 bec38ebc1d docs: add Channels & Connectors troubleshooting guide
Covers setup instructions and troubleshooting for all 12 connectors:
Gmail, Google Drive, Calendar, Contacts, Slack, Notion, Granola,
Apple Notes, iMessage, Outlook, Obsidian, Dropbox.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 17:01:17 -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 62b98d903b feat: add proper Google OAuth flow with localhost callback server
Add exchange_google_token() and run_oauth_flow() to oauth.py for the
full authorization code exchange. Update gdrive, gcalendar, and
gcontacts connectors to trigger the browser-based OAuth flow when a
client_id:client_secret pair is provided, prefer access_token over raw
token, and require an actual access_token for is_connected(). auth_url()
now returns the Cloud Console credentials page when no client_id is
stored.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:45:03 -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