Skip to content

codenotes666-blip/AI-Exchange-Client

Repository files navigation

AI Exchange Client

A local, Graph-backed mail client + cache + agent.

This repo is a single repo (monorepo) containing three apps:

  • sync-app/: builds/updates a local SQLite cache from Microsoft Graph (folders + date range + attachments)
  • agent-app/: intent→safe query templates over the local cache, plus sync now / sync status
  • web-server-app/: local 3-pane mail UI + chat grounded in the cache; shells out to agent-app
  • filesearch-app/: Windows-only filesystem search agent powered by Voidtools Everything SDK

Progress Monitor

Background scripts report live progress to a shared sync_status.json file. progress_monitor.py reads it every 2 seconds and shows an always-on-top desktop UI.

.\.venv\Scripts\python.exe .\progress_monitor.py

See MONITOR_ARCHITECTURE.md for the full architecture, the StatusWriter API, all registered task IDs, and the pattern for adding new tasks.

Secrets

Secrets live in a repo-root .env file (never committed). Each app sub-folder contains an identical env_loader.py that loads them into os.environ at startup. An age-encrypted .env.enc backup is safe to commit and restore on new machines via sops.

See SECRETS_ARCHITECTURE.md for the full loading chain, candidate file search order, encrypted backup workflow, and the pattern for adding env_loader.py to new apps.

Prereqs

  • Linux + system Python 3.10+
  • APT packages (no pip/venv assumed):
    • python3-msal
    • python3-requests
    • python3-yaml
    • Optional for PDF text extraction: poppler-utils (provides pdftotext)

Required environment variables

  • TENANT_ID
  • CLIENT_ID
  • CLIENT_SECRET
  • MAILBOX_UPN
  • OPENAI_API_KEY (needed for chat; optional for agent planning)

Preferred local source:

  • Store these in repo-local .env.
  • The app env loaders now check repo-local .env before older hidden-file locations.

Configure

  1. Copy the example config:
  • cp sync-app/config.example.yaml sync-app/config.yaml
  1. Edit sync-app/config.yaml:
  • Adjust sync.cache_range.start_date / end_date
  • Confirm sync.folders.names
  • Leave secrets as env-var references

Run

PowerShell-first quick start (Windows)

From repo root in pwsh:

  • Create config once if needed: Copy-Item sync-app/config.example.yaml sync-app/config.yaml
  • Put secrets in repo-local .env
  • Safe Graph verification: ./.venv/Scripts/python.exe ./sync-app/mailboxsync.py --config ./sync-app/config.yaml --sqlite "$env:TEMP\ai_exchange_mailboxsync_dry.sqlite" dry
  • Build/update cache: py -3 sync-app/mailboxsync.py --config sync-app/config.yaml sync
  • Agent search: py -3 agent-app/cache_agent_cli.py --config sync-app/config.yaml "pdfs from annie"
  • Agent sync controls:
    • py -3 agent-app/cache_agent_cli.py --config sync-app/config.yaml "sync now"
    • py -3 agent-app/cache_agent_cli.py --config sync-app/config.yaml "sync status"
  • Start mail web UI: ./web-server-app/restart_mail_web_server.ps1
  • Test Graph mail sending (standalone): .\.venv\Scripts\python.exe .\web-server-app\send_mail_cli.py new --to "you@example.com" --subject "test" --body "hello"
  • Start filesystem search server: ./filesearch-app/scripts/start_filesearch_server.ps1 -WaitForHealth -WaitTimeoutSec 10

Then open:

  • Mail UI: http://127.0.0.1:8001/
  • Filesearch UI: http://127.0.0.1:8712/

Build/update the cache

  • python3 sync-app/mailboxsync.py --config sync-app/config.yaml sync

Use the agent CLI

  • python3 agent-app/cache_agent_cli.py --config sync-app/config.yaml "pdfs from annie"
  • python3 agent-app/cache_agent_cli.py --config sync-app/config.yaml "sync now"
  • python3 agent-app/cache_agent_cli.py --config sync-app/config.yaml "sync status"

Start the web UI

  • cd web-server-app && bash restart_mail_web_server.sh

Then open:

  • http://127.0.0.1:8001/

Filesystem search (Windows only)

Everything uses a Windows DLL, so SDK calls must run in a Windows process.

Recommended workflow (WSL + Windows together):

  • Start the Windows server (from WSL, recommended): cd filesearch-app/scripts && ./wsl_start_server.sh --wait --wait-timeout 10
  • Use the HTML UI: http://127.0.0.1:8712/
  • Or call from WSL: python3 filesearch-app/filesearch_wsl_client.py --limit 20 "recent txt files"

UI notes (keyboard-first):

  • ArrowDown from query moves into results; ArrowUp from the first row returns to query.
  • Enter on a selected row opens an action menu (includes Copy Full Path → Windows clipboard).
  • Shift+Arrow supports multi-select; Copy copies all selected paths (newline-separated).

Content search (opt-in):

  • Content scanning is disabled unless you include the explicit marker content:.
  • Example: python3 filesearch-app/filesearch_wsl_client.py --limit 20 "ext:pdf content:insurance premiums"

Health/readiness:

  • http://127.0.0.1:8712/health (includes everything_db_loaded and openai_available)

OpenAI model:

  • Default model is gpt-5.2, but the UI allows switching models.

Agent notes / full runbook:

  • See filesearch-app/README.mdAgent runbook (do not reinvent) for exact commands, flags, endpoints, and test cases.
  • Large-result-set behavior and timeout tuning are documented there as well (see “everything query timed out”).

OpenAI key note:

  • If OPENAI_API_KEY is set in your WSL environment and you start via the WSL wrapper scripts, it is forwarded into the Windows server process automatically (via WSLENV environment passthrough).

EWS Archive Sync + Monitoring

The sync-app/archive_ews_sync.py script pulls the Exchange Online In-Place Archive directly via EWS (Microsoft Graph does not expose the archive mailbox). It writes into the same mail_cache.sqlite.

Requires the full_access_as_app Application permission granted in your Azure App Registration.

Key commands (from repo root in pwsh):

# One-shot sync (picks up from the oldest already-synced date and works backwards)
.\.venv\Scripts\python.exe .\sync-app\archive_ews_sync.py --config .\sync-app\config.yaml sync

# Unattended auto-restart loop (stops when target year is reached)
.\sync-app\scripts\run_archive_sync_loop.ps1 -TargetYear 2017

# Extract text from attachment blobs (run after sync is complete)
.\.venv\Scripts\python.exe .\sync-app\archive_ews_sync.py --config .\sync-app\config.yaml extract

# Combined terminal status report (process + DB stats)
.\.venv\Scripts\python.exe .\sync-app\archive_ews_sync.py --config .\sync-app\config.yaml status

Progress monitor — always-on-top desktop widget (bottom-right corner):

.\.venv\Scripts\pythonw.exe .\progress_monitor.py

Reads sync_status.json (written by status_writer.py) every 2 seconds. Any script can report progress by importing StatusWriter from status_writer.py.

Full details: sync-app/README.mdEWS Archive Sync and Progress Monitor sections.

Notes

  • The web server and the agent both default to sync-app/config.yaml.
  • The agent emits cache coverage warnings for date-based queries and can kick off a full sync.
  • Microsoft Graph access has been verified directly through mailboxsync.py dry in PowerShell.
  • The mail UI reply composer supports rich text editing (bold/italic/underline, lists, font controls), To/CC/BCC address fields that auto-populate on reply/reply-all/forward, per-email draft memory across message selections, and an amber tab indicator when a draft is present.
  • web-server-app/send_mail_cli.py is a standalone Graph mail send test tool (reply, reply-all, forward, new). Requires Mail.Send application permission with admin consent in Azure AD.

Secrets backup

  • Encrypted .env backup workflow is documented in SECRETS.md.
  • Plaintext .env stays local; commit .env.enc and .sops.yaml.
  • Windows age private key location: %APPDATA%\sops\age\keys.txt.

Clone

  • git clone <REPO_URL>

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors