Deployment configuration
September 21, 2026 · View on GitHub
Vercel project: 0xbuns/typesafe-ai-playground.
Production: https://typesafe-ai-playground.vercel.app.
Set TYPESAFE_API_KEY as a sensitive server-only production environment variable.
Never use NEXT_PUBLIC_TYPESAFE_API_KEY. The app exposes a shared-key demo, so its
request limits belong at the edge, before serverless instances scale out.
The production Vercel Firewall uses these project-level, per-IP limits:
| Endpoint | Fixed-window limit |
|---|---|
/api/run | 60 requests per 60 seconds |
/api/meme-image | 12 requests per 60 seconds |
/api/pull-request | 6 requests per 60 seconds |
/api/solve | 20 requests per 60 seconds |
The LangChain endpoint /api/langchain-route is limited to 30 requests per 60 seconds per IP.
To reproduce on a new linked project:
vercel firewall overview
vercel firewall diff
vercel firewall rules add 'Limit shared Jev API usage' \
--condition '{"type":"path","op":"eq","value":"/api/run"}' \
--action rate_limit --rate-limit-requests 60 --rate-limit-window 60 \
--rate-limit-keys ip --yes
vercel firewall rules add 'Limit meme image downloads' \
--condition '{"type":"path","op":"eq","value":"/api/meme-image"}' \
--action rate_limit --rate-limit-requests 12 --rate-limit-window 60 \
--rate-limit-keys ip --yes
vercel firewall rules add 'Limit public PR lookups' \
--condition '{"type":"path","op":"eq","value":"/api/pull-request"}' \
--action rate_limit --rate-limit-requests 6 --rate-limit-window 60 \
--rate-limit-keys ip --yes
vercel firewall rules add 'Limit exact solver checks' \
--condition '{"type":"path","op":"eq","value":"/api/solve"}' \
--action rate_limit --rate-limit-requests 20 --rate-limit-window 60 \
--rate-limit-keys ip --yes
vercel firewall rules add 'Limit LangChain routing invocations' \
--condition '{"type":"path","op":"eq","value":"/api/langchain-route"}' \
--action rate_limit --rate-limit-requests 30 --rate-limit-window 60 \
--rate-limit-keys ip --yes
vercel firewall diff
vercel firewall publish --yes
Review existing rules and unpublished changes first; do not create duplicates or publish unrelated changes. These are persistent edge limits, not an in-memory counter that resets on cold starts. They do not authenticate users or establish a global budget across IPs. Configure spending limits on your provider key for that. Local development does not pass through the Vercel Firewall.
Browser-run routes on your own server
/api/local-browser, /api/native-browser, /api/pc-build and /api/clean-room
launch Chromium on the server through uv (browser-use pinned in
lib/localBrowser.ts). They accept same-origin requests from whichever host serves
the app, so a self-hosted server with uv and Chromium can run the browser agent,
native browser and clean-room workspaces. Requests whose Origin names another
host, and sec-fetch-site: cross-site fetches, are refused; forwarded headers are
ignored. The comparison is by host, not scheme, so a TLS-terminating proxy works.
Vercel serverless functions cannot spawn Chromium, so those routes refuse with an
explanation when VERCEL is set. On a self-hosted deployment the existing bounds
still apply: three concurrent browser sessions, three starts per minute, and the
shared-key controls above. Anyone who can reach the app can start a run, so put
the deployment behind your own access control before exposing it publicly.
/api/meme-image also restricts schemes, destinations, redirects, downloaded bytes,
and decoded pixels. It resolves each destination, rejects private/reserved IPs,
and pins the actual TLS connection to the validated address. No TypeSafe key or
browser cookies are forwarded to image hosts.
Each workspace has a statically generated 1200 × 630 opengraph-image route. lib/social.ts supplies per-page titles, descriptions, canonical paths and matching Twitter metadata; lib/social-image.tsx renders the shared pink/sky-blue TypeSafe design with locally stored reference artwork. When adding a page, add its registry entry, call pageMetadata, and add a small opengraph-image.tsx entry point. public/og.png remains the README artwork.
The SMT endpoint uses the Node.js z3-solver WASM package. next.config.ts externalizes it and traces the WASM/runtime files into /api/solve; do not move it to the Edge runtime. Queue, input, timeout and solver-resource limits are also enforced locally.