Changelog

What we've shipped, in reverse chronological order.

No roadmap promises, no marketing copy — just the concrete increments that have landed on main. Dates use ISO format.

  1. ·Wave 2: dark mode, i18n, runtime + release infra, ~200 new tests

    Six parallel agent packs: dark mode + command palette + i18n, product feature polish, per-tenant runtime settings, desktop + mobile release CI, axe-core sweeps, and off-site backup + staging tooling.

    • Dark mode across the app (Tailwind darkMode: "class", cookie + localStorage + prefers-color-scheme), toast notifications, proper 404 and 500 pages, dynamic favicons.
    • Hand-rolled en/hi internationalisation with a language switcher on the settings page, plus a Cmd+K command palette with fuzzy matching over the in-app actions.
    • Chat session delete and rename, audit log CSV export (admin-only streaming, 100k row cap), six new enquiry filter parameters, and a schema migration that actually populates payload and resolved_by_user_id on approvals.
    • Per-tenant agent runtime settings: model override, system prompt suffix, rate limits per minute / hour, daily token budget, default currency. Cost tracker writes every turn to session_costs and enforces the daily budget.
    • GET / PATCH /api/tenant-settings admin-only, plus a trial-balance report and tool result cache (read-only allowlist, tenant-scoped, 5-minute default TTL).
    • .github/workflows/desktop-release.yml (Tauri build matrix for macOS, Linux, Windows with PR dry-run) and mobile-release.yml (EAS build + OTA update).
    • Passport OCR scaffold in the mobile app with a real ICAO 9303 MRZ parser (and a stubbed capture path until a provider is picked). First vitest suite wired into apps/mobile.
    • Accessibility sweep with @axe-core/playwright across 19 pages (surfaced 8 pre-existing colour-contrast violations as a UX backlog), an opt-in real-Postgres integration fixture, Locust load scenarios, and a getting-started walkthrough plus per-driver setup pages.
    • Off-site Postgres backups via an rclone wrapper (AWS S3, Backblaze B2, Cloudflare R2, Wasabi, MinIO, DigitalOcean Spaces), a staging environment bootstrap script with systemd unit templates, and a secret rotation CLI for the JWT / DB / Redis / metrics / KMS secrets.
  2. ·Wave 1: team onboarding, auth hardening, observability, agent-to-ledger, ~100 new tests

    Five parallel packs that unblock real team usage and close the loop between the agent runtime and the ledger.

    • Tenant invites with roles, accept-invite flow, and an /app/settings page for admins to manage members.
    • PATCH /api/auth/profile, a password reset flow (Redis token, log-to-stdout email stub), and three new public pages: /app/forgot-password, /app/reset-password, and /app/accept-invite.
    • Password strength validator with a 58-entry blocklist, TOTP 2FA with pyotp and a /auth/sign-in-totp second-factor endpoint, plus an API key table with scoped vy_-prefixed keys.
    • GitHub Actions CI (pytest + vitest + Playwright + marketing build), automated Postgres backups via a systemd timer with a 30-day retention, and a runbook documenting 17 deploy gotchas from previous sessions.
    • Sentry integration across the API, web app, and marketing site with PII-scrubbing before_send hooks and a tenant-tagging middleware, plus a Prometheus /internal/metrics endpoint gated to localhost or a shared token.
    • Mobile sidebar drawer (hidden below 768px with a hamburger overlay), enquiries filter bar now responsive, four loading.tsx skeletons for the main list pages.
    • Audit log viewer with admin-only RBAC, an approvals-to-audit hook so granted and rejected decisions land in the trail, and a passenger resolver that mints UUIDv7 identifiers correctly.
    • draft_invoice tool for the accounting agent (approval-gated, auto-numbering per tenant, Decimal-only math), the /reports/trial-balance endpoint, and a demo tenant seeder that populates five enquiries, three invoices, three bills, five ledger accounts, three balanced journal entries, and five audit events — idempotent via a marker row.
  3. ·Demo account and chat path fixes

    A public demo login and three fixes to the chat path that were biting browser-side SDK consumers.

    • Demo account [email protected] exposed on the sign-in page with a “Use demo credentials” pre-fill link.
    • Fixed SDK consumers (web, mobile, desktop) to pass an /api-prefixed base URL so the browser-side SDK reaches FastAPI through nginx.
    • Fixed createSession to post an empty body (the API derives tenant and actor from the bearer JWT).
  4. ·Approvals inbox and enquiry lifecycle

    A finance-side approvals inbox and a first-class enquiry object with a full lifecycle.

    • New /api/approvals and /app/approvals — list pending tool-call approvals, approve or reject from a finance inbox, 15-minute TTL, cross-tenant 404.
    • New enquiries table and full CRUD: /api/enquiries and UI at /app/enquiries (list, filter, search, create, detail, edit, promote-to-chat).
    • Status lifecycle new → quoted → booked with cancelled as a terminal state.
    • Migration 0006_enquiries.
  5. ·Real-data reports

    Receivables and payables reports now query real ledger tables instead of fixture data.

    • invoices, bills, ledger_accounts, journal_entries tables added (migration 0005_invoices_ledger).
    • build_journal_entry helper enforces debit == credit in code, not via DB triggers.
    • /reports/receivables and /reports/payables now query real data with 0-30 / 31-60 / 61-90 / 90+ aging buckets.
  6. ·Eight bug fixes from the error-path test pass

    A focused sweep of error-path regressions found during an explicit failure-mode test run.

    • Tool output schema validation with retry-once on schema mismatch.
    • Anthropic RateLimitError / APIConnectionError retry with exponential backoff (Retry-After honored).
    • Sign-in gates on email_verified with distinguishable 401 codes (email_not_verified vs invalid_credentials).
    • Amadeus JSON decode errors mapped to typed driver errors (no raw exceptions through the boundary).
    • BSP India HAF parser airline allow-list (164 IATA carriers) plus a regex pre-check.
    • VFS MFA / 2FA / OTP signals routed to PermanentError (was being miscategorized as auth failure).
    • pending_approvals.expires_at and status="expired" enum value with lazy sweep.
    • resolve_approval(actor_tenant_id) cross-tenant guard.
  7. ·Hotels domain

    A hotels_holidays agent, a canonical hotel data model, and a real-HTTP TBO driver for search and re-pricing.

    • New hotels_holidays agent with approval-gated booking.
    • New canonical hotel models: HotelRoom, HotelRate, HotelProperty, HotelSearchResult, and a BoardBasis enum.
    • New TBO driver — search and price re-check wired with real HTTP; booking is stubbed pending sandbox credentials.
    • Migration 0003_passengers plus StoragePassengerResolver end-to-end.
    • Postgres session stores wired by default when VOYAGENT_DB_URL is set.
  8. ·In-house auth replaces Clerk everywhere

    Auth is now owned end-to-end in the platform — password hashing, JWTs, refresh-token rotation, and a Redis-backed denylist.

    • Argon2id password hashing.
    • HS256 JWT access tokens (1h) plus opaque refresh tokens (30d, single-use rotation).
    • httpOnly cookies on web (voyagent_at), SecureStore on mobile and desktop.
    • Redis-backed JWT jti denylist for revocation.
    • Email verification flow stubbed (/send-verification-email, /verify-email); real delivery is pending a provider decision.
    • Migrations 0002_inhouse_auth.
  9. ·Native deployment

    Docker Compose retired in favor of systemd-supervised native processes on a single host.

    • Migrated off Docker Compose to systemd-supervised processes.
    • Three units: voyagent-api (uvicorn :8010), voyagent-web (next start :3011), and voyagent-marketing (next start :3012).
    • Native Postgres 16 (shared host instance) and native Redis 7.
    • Single-host nginx plus certbot for TLS.
    • Removed Clerk, Temporal, and Docker from docs and configs.
  10. ·Foundations

    The baseline platform the entries above build on — canonical model, driver contracts, agent loop, and multi-tenant isolation.

    • In-process agent loop with prompt caching (Anthropic SDK).
    • Three domain agents: ticketing_visa, accounting, and hotels_holidays.
    • Canonical Pydantic v2 data model: flights, hotels, visa, finance, lifecycle.
    • Five driver skeletons: Amadeus, TBO, Tally, BSP India, and VFS — all conforming to typed driver contracts.
    • Real-time chat with SSE streaming and approval-gated tool calls.
    • Multi-tenant isolation enforced at every storage query.
    • Tests: roughly 750 Python (pytest) and 47 TypeScript (vitest).

For a deeper roadmap see IMPLEMENTATION-PLAN.md. For architecture decisions see docs/DECISIONS.md.

Ready to retire the 15-tool workflow?

Voyagent is in early access. We onboard a small number of agencies each month with white-glove setup of drivers, data, and approval workflows.