# AgentLaunch — Full Technical Specification > Ship your AI SaaS in days. FastAPI + Next.js with token billing built in. ## 1. Overview & Architecture Philosophy Most AI boilerplates are monolithic JavaScript/TypeScript templates. However, the machine learning and AI ecosystem (LangChain, LlamaIndex, DSPy, PyTorch, Hugging Face, NumPy) is anchored in Python. JavaScript AI libraries frequently lag behind, lack tensor computing capabilities, and struggle with memory-efficient local model weights. AgentLaunch resolves this dichotomy through clean architectural decoupling: - **Presentation & Web Experience**: Next.js 15 App Router running on Vercel with Server-Side Rendering (SSR), React Server Components (RSC), and edge-optimized routing. - **AI Execution Engine**: Python 3.12+ FastAPI backend container running on high-throughput infrastructure (Railway, Fly.io, Render, Modal, AWS ECS) with async I/O and Pydantic v2 validation. - **State & Vector Persistence**: PostgreSQL 16 hosted via Supabase with the pgvector extension, utilizing Row-Level Security (RLS) to enforce strict multi-tenant isolation at the database layer. - **Monetization Layer**: Automated token metering integrated with Stripe Meter Events API (`POST /v1/billing/meter_events`), enabling precise usage-based billing without adding latency to streaming responses. --- ## 2. Technical Stack Breakdown ### Backend - **Python**: 3.12+ - **Framework**: FastAPI (Pydantic v2 schemas, strict type annotations, async handlers) - **Dependency & Package Manager**: uv (Astral) with deterministic `uv.lock` - **Database ORM**: SQLAlchemy 2.0 (asyncio) + asyncpg driver - **Vector Search**: PostgreSQL 16 `pgvector` with HNSW cosine distance indexing - **Security**: python-jose (`jwt`), HTTPBearer authentication, cryptographic Supabase JWKS / JWT signature validation - **Deployment**: Multi-stage production Dockerfiles with non-root security context ### Frontend - **Framework**: Next.js 15 (App Router, Server Actions, React 19) - **Styling**: Tailwind CSS v4, Lucide React icons, Framer Motion animations - **Package Manager**: pnpm with `pnpm-lock.yaml` - **Analytics**: Privacy-friendly Plausible Analytics (cookieless, GDPR compliant) - **State & Streaming**: Custom React hooks (`use-agent-stream.ts`) consuming `EventSource` / fetch SSE streams ### Database & Auth - **Provider**: Supabase (PostgreSQL 16) - **Extensions**: `vector` (pgvector 1536-dimensional embeddings) - **Authentication**: Supabase Auth (Email/Password, Magic Link, OAuth) - **Authorization**: Row-Level Security (RLS) policies binding queries to `auth.uid()` --- ## 3. Core Architectural Implementations ### A. Zero-Trust Supabase JWT Bridge (`auth.py`) FastAPI verifies the incoming Supabase JWT cryptographically on every protected endpoint. It does not trust client parameters or mutable metadata: ```python import logging from fastapi import Depends, HTTPException, status from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from jose import jwt, JWTError from api.core.config import settings from api.db.session import get_db_session from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select from api.models.user import User logger = logging.getLogger(__name__) security = HTTPBearer() async def get_current_user( credentials: HTTPAuthorizationCredentials = Depends(security), db: AsyncSession = Depends(get_db_session) ) -> dict: """ Zero-Trust JWT verification dependency. Validates cryptographic Supabase signature. Never trusts client-supplied identity. Fetches verified stripe_customer_id directly from the database (NOT user_metadata). """ token = credentials.credentials try: payload = jwt.decode( token, settings.SUPABASE_JWT_SECRET, algorithms=["HS256"], audience="authenticated" ) user_id: str = payload.get("sub") if not user_id: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid or expired token" ) query = select(User.stripe_customer_id).where(User.id == user_id) result = await db.execute(query) stripe_customer_id = result.scalar_one_or_none() return { "id": user_id, "email": payload.get("email"), "role": payload.get("role", "authenticated"), "stripe_customer_id": stripe_customer_id } except JWTError as e: logger.error(f"JWT verification failed for request: {str(e)}") raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="Invalid or expired token" ) ``` ### B. Server-Sent Events (SSE) Streaming with Guaranteed Metering (`agent.py`) Token billing calculations are guaranteed to run upon stream completion or mid-stream client disconnection via `try...finally`: ```python from fastapi import APIRouter, Depends from fastapi.responses import StreamingResponse from api.core.auth import get_current_user from api.schemas.agent import AgentPromptRequest from api.services.llm import stream_langchain_agent from api.services.stripe_billing import log_token_usage router = APIRouter(prefix="/v1/agent", tags=["AI Workflows"]) @router.post("/stream") async def stream_agent_execution( payload: AgentPromptRequest, user: dict = Depends(get_current_user) ) -> StreamingResponse: """ Server-Sent Events (SSE) generator. Guarantees Stripe metered token sync in try...finally even upon disconnect. """ async def sse_generator(): total_tokens = 0 try: async for chunk in stream_langchain_agent(payload.prompt, user["id"]): total_tokens += chunk.token_count yield f"data: {chunk.json()}\n\n" finally: if total_tokens > 0 and user.get("stripe_customer_id"): await log_token_usage( customer_id=user["stripe_customer_id"], token_count=total_tokens, event_name="ai_tokens_consumed" ) return StreamingResponse(sse_generator(), media_type="text/event-stream") ``` ### C. Multi-Tenant pgvector RAG with Row-Level Security (`init_vector_rag.sql`) Multi-tenant isolation is enforced inside Postgres itself rather than relying on application code: ```sql create extension if not exists vector; create table document_chunks ( id uuid primary key default gen_random_uuid(), user_id uuid references auth.users(id) on delete cascade not null, source_file text not null, content text not null, embedding vector(1536), created_at timestamptz default now() ); alter table document_chunks enable row level security; create policy "Users can only access their own vector chunks" on document_chunks for all using (auth.uid() = user_id); create index on document_chunks using hnsw (embedding vector_cosine_ops) with (m = 16, ef_construction = 64); ``` --- ## 4. API Specification & Endpoints | Method | Endpoint | Description | Auth Required | |---|---|---|---| | `POST` | `/v1/agent/stream` | Real-time SSE token stream from LangChain/DSPy | Bearer JWT | | `POST` | `/v1/rag/query` | Semantic vector similarity query with RLS filter | Bearer JWT | | `POST` | `/v1/rag/ingest` | Parse and chunk documents into pgvector table | Bearer JWT | | `POST` | `/v1/billing/meter_events` | Stripe metered billing event synchronizer | Bearer JWT / Internal | | `GET` | `/v1/health` | Service health check and database connectivity | None | --- ## 5. Commercial Licensing - **Solo Builder ($99 early-bird / $149 regular)**: Perpetual license for 1 developer. Deploy unlimited commercial products or client SaaS deliverables. Zero royalties. - **Team License ($199 early-bird / $299 regular)**: Perpetual license for up to 5 developers. Private team GitHub invites, production Docker deployment manifests, and agency client deployment rights. - **Prohibited**: You may not redistribute or resell the raw boilerplate source code as a competing template, starter kit, or UI library. --- ## 6. Official Resources & References - Website: https://agentlaunch.pysaas.dev - Terms of Service: https://agentlaunch.pysaas.dev/terms - Privacy Policy: https://agentlaunch.pysaas.dev/privacy - License: https://agentlaunch.pysaas.dev/license - LLMs Short Summary: https://agentlaunch.pysaas.dev/llms.txt - Author: Yogesh (Solo Builder, AI & Full-Stack Tooling) - Support: support@pysaas.dev