Modern Architecture • Agentic Multi-Agent Search • Configurable Providers • Open-Source
TripSage AI is a travel planning platform that combines the power of modern AI agents with rich AI SDK v7 tools and all-in-one travel services.
- AI Gateway + BYOK Routing: Vercel AI Gateway for app-owned OpenAI profiles, direct user BYOK for OpenAI/OpenRouter/Anthropic/xAI, and encrypted key storage
- Agentic Tool Orchestration: 15+ production-ready tools via AI SDK v7 with Zod validation for flights (Duffel), accommodations, weather, maps, planning, and memory
- Hybrid RAG Pipeline: Vector similarity search with Supabase pgvector + keyword fusion, with Together.ai and Mixedbread reranking for retrieval accuracy
- Structured Outputs: Schema-first LLM responses with
generateText+Output.objectfor deterministic parsing and type-safe validation - Streaming Intelligence: Real-time SSE streaming with interleaved tool calls and generative UI components
- Supabase PostgreSQL + pgvector: Managed database with HNSW indexes for semantic search, embeddings storage, and vector similarity queries
- Supabase Auth & Vault: Server-side authentication with SSR clients (
@supabase/ssr), encrypted BYOK secrets in Vault with RLS-gated access - Supabase Realtime: Private channels with Row Level Security for multi-user collaboration, presence tracking, and broadcast events
- Supabase Storage: File uploads with signed URL access, metadata persistence, and server-enforced access control
- Upstash Redis: Serverless HTTP Redis for caching, sliding-window rate limiting, and deduplication keys
- Upstash QStash: Webhook-driven background jobs with signature verification, Redis idempotency gates, and batch processing (memory sync, async tasks)
- Vercel Runtime Architecture: Next.js 16 route handlers, Vercel CLI prebuilt promotion, and deployment through Vercel's global network
- React Compiler: Automatic memoization to reduce avoidable client rerenders
- Zero-Trust Architecture: BYOK keys never touch client; server-only routes with
"server-only"imports and dynamic execution - Row Level Security: Supabase RLS policies enforce per-user data isolation; security-definer RPCs guard Vault access
- Rate Limiting: Upstash Ratelimit with tiered budgets (40 req/min streaming, 20 req/min validation) per user/IP
- OpenTelemetry: Distributed tracing with PII redaction, span instrumentation, and Trace Drains for observability without data leakage
- Tool Approval Flows: Sensitive operations (bookings, payments) pause streaming and require explicit user consent
- Next.js 16 + React 19: App Router with RSC-first architecture, Server Components by default, React Compiler enabled
- TypeScript 6: Strict mode with end-to-end type safety, Zod schemas as single source of truth
- AI SDK v7 Native: Provider V4 resolution, stateless streaming, tool calling, and structured outputs
- Node.js 24.x (see
.nvmrc) with pnpm 11.x (seepackage.json#packageManager) - PostgreSQL 15+ (or Supabase account)
- Upstash Redis for caching (via Vercel integration)
# Clone the repository
git clone https://github.com/BjornMelin/tripsage-ai.git
cd tripsage-ai
# Activate the project-pinned pnpm and install dependencies
corepack enable
corepack install
pnpm install
cp .env.local.example .env.local # Configure environment
# Start development server (includes API routes)
pnpm dev # Next.js app + API routes (port 3000)# Frontend access
open http://localhost:3000Single-runtime, server-first stack optimized for Vercel's Node.js runtime:
- Backend & UI: Next.js 16 App Router (React 19), AI SDK v7 route handlers, and React Compiler
- AI Routing: Vercel AI Gateway for app-owned OpenAI profiles with opt-in team fallback, plus BYOK support via Supabase Vault
- Database & Auth: Supabase PostgreSQL with pgvector (HNSW indexes), SSR clients (
@supabase/ssr), Realtime channels, Storage buckets - Cache & Rate Limiting: Upstash Redis (HTTP) for serverless caching and Upstash Ratelimit for sliding-window throttling
- Background Jobs: Upstash QStash for webhook-driven async tasks with idempotency guarantees
- Observability: OpenTelemetry with Vercel Trace Drains, span instrumentation, and PII redaction
# Frontend / API (single app at root)
corepack enable
corepack install
pnpm install
pnpm dev # Next.js dev server (includes API routes)
pnpm type-check
pnpm biome:fix # Format/lint (CI enforces clean diffs)
pnpm test # Vitest
pnpm exec playwright install chromium # one-time browser install (fresh machine)
pnpm test:e2e:chromium # Playwright (Chromium-only; recommended local default)
pnpm test:e2e # Playwright (all configured browsers)
# Supabase tooling (optional)
make supa.link PROJECT_REF=...
make supa.db.pushIf pnpm is not already on your PATH, run corepack enable once to install the pnpm shim, or use corepack pnpm ... for one-off commands. The canonical package-manager version lives in package.json#packageManager; corepack install downloads that exact version for this project. Use pnpm ci in CI/CD for clean, frozen installs. pnpm-specific supply-chain settings such as minimumReleaseAge, allowBuilds, trustPolicy, and blockExoticSubdeps live in pnpm-workspace.yaml.
Server-side tracing is registered via src/instrumentation.ts using @vercel/otel. Client-side tracing is initialized via TelemetryProvider (mounted from src/app/layout.tsx) and exports browser spans with OTLP/HTTP.
Local tracing (Collector + Jaeger):
docker compose up -d otel-collector jaeger
open http://localhost:16686Enable browser tracing (optional):
# Either is accepted (client normalizes to `/v1/traces`)
NEXT_PUBLIC_OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
# or
NEXT_PUBLIC_OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces
# (also accepted)
NEXT_PUBLIC_OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318/v1/traces/To disable browser tracing in production, leave NEXT_PUBLIC_OTEL_EXPORTER_OTLP_ENDPOINT unset.
Run pnpm biome:fix before committing. CI runs pnpm biome:fix and then checks for a clean working tree with git diff --exit-code, so any formatting changes produced locally will fail CI if not committed.
tripsage-ai/
├── src/ # Next.js 16 + AI SDK v7 source code
├── public/ # Static assets
├── e2e/ # Playwright E2E tests
├── supabase/ # Supabase migrations/config
├── docker/ # OTEL/Jaeger compose
├── .github/ # CI/CD
├── package.json # Node.js dependencies
└── Makefile # Supabase ops shortcuts
- Server-first: Route Handlers own AI calls. Core
streamTextroutes useconvertToModelMessages(),toUIMessageStream(), andcreateUIMessageStreamResponse().ToolLoopAgentendpoints returncreateAgentUIStreamResponse()throughcreateAgentRoute(). Validate inputs with Zod v4. - Auth/DB:
@supabase/ssronly; no auth-helpers. - Cache/jobs: Upstash HTTP clients only (
Redis.fromEnv, QStash SDK). - Logging: OTEL exporters; no
console.login server code. - Tests: Vitest/Playwright only (no pytest/ruff/uv).
Production deploys use the Vercel CLI workflow in docs/runbooks/deployment-vercel.md:
pnpm deploy:check-env
vercel pull --yes --environment=production
vercel build --prod
vercel deploy --prebuilt --prod --skip-domain --archive=tgz --yes
pnpm deploy:smoke -- --url "$DEPLOYMENT_URL"
vercel promote "$DEPLOYMENT_URL" --yes --timeout=5mDocker compose files in docker/ are local observability/dev helpers, not the
production deploy authority.
scripts/verify-production-env.mjs is the deploy-time source of truth. It
validates core app origins, Supabase SSR/Vault, Upstash Redis/QStash, security
secrets, BYOK health checks, feature-aware Stripe, Resend, and Amadeus groups,
and AI demo provider readiness.
For local setup, start from .env.local.example. For production, run
pnpm deploy:check-env before vercel build.
GET /api/health # Public runtime health
POST /api/chat # AI SDK v7 UI message stream
POST /api/flights/search # Flight search
GET /api/trips/suggestions # AI-powered trip suggestions
POST /api/keys/validate # BYOK provider validation
GET /api/health/byok # Operator-only BYOK health probeThe authoritative route catalog is docs/api/api-reference.md. Trip CRUD, collaboration, and itinerary mutations use Server Actions rather than internal REST routes.
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY!)
// authorize realtime with access token via RealtimeAuthProvider in app
const channel = supabase.channel(`user:${userId}`, { config: { private: true } })
channel.on('broadcast', { event: 'chat:message' }, ({ payload }) => console.log(payload))
channel.subscribe()We welcome contributions! See the Development Guide for the full workflow, code standards, and testing details.
TripSage AI includes performance-oriented runtime building blocks:
- Caching: Upstash Redis HTTP caching and request deduplication
- Vector Search: Supabase pgvector with HNSW indexes for semantic retrieval
- Streaming: Real-time SSE with AI SDK v7, interleaved tool calls, and progressive UI rendering
- Background Processing: Upstash QStash handles signed async jobs for memory sync and batch operations
See performance validation for reproducible measurement and claim requirements.
Zero-trust architecture with defense-in-depth security:
- BYOK Architecture: User API keys encrypted in Supabase Vault, accessed only via SECURITY DEFINER RPCs with PostgREST JWT claims validation—keys never reach client
- Row Level Security: Supabase RLS policies enforce per-user data isolation; all tables protected by default
- Rate Limiting: Upstash Ratelimit with sliding-window counters, tiered budgets (40 req/min streaming, 20 req/min validation) per user/IP
- Server-Only Secrets: BYOK routes import
"server-only"and run withdynamic = "force-dynamic"to ensure secrets processed per-request - PII Redaction: OpenTelemetry spans automatically redact sensitive data; structured logging with correlation IDs
- Tool Approval Gates: Critical operations (bookings, payments) pause streaming and require explicit user consent
- Dependency Security: Dependabot provides automated vulnerability scanning; CI runs
pnpm deps:auditandpnpm audit --audit-level high, withpnpm auditavailable for local/manual checks
# Security verification (ensure no hardcoded secrets)
git grep -i "fallback-secret\|development-only" . # Should return empty
# Dependency audit
pnpm audit
# Run security-focused tests
pnpm test --grep security- Provider validation:
/api/keys/validateverifies BYOK provider keys server-side without exposing secret material. - Operator health:
/api/health/byokusesBYOK_HEALTHCHECK_KEYand reports provider readiness without returning Vault values. - Deploy smoke:
pnpm deploy:smoke -- --url "$DEPLOYMENT_URL"checks health, security headers, auth guards, BYOK health when configured, and QStash-protected jobs before promotion.
- Health Checks: Endpoint monitoring with health checks
- Logging: Structured logging with correlation IDs
- Metrics: Custom business metrics and performance tracking
- Error Tracking: Detailed error reporting and alerting
This project is licensed under the MIT License - see the LICENSE file for details.
Built by Bjorn Melin as an exploration of AI-driven travel planning.