Upgrade pattern for an existing Next.js App Router frontend that adds an Agentuity backend runtime for AI routes.
- Two-runtime architecture:
- Next.js frontend runtime (
localhost:3000) - Agentuity backend runtime (
localhost:3500)
- Next.js frontend runtime (
- Dev startup gate:
wait-onchecks backend health (/api/health) before Next.js boots - Translate workflow using plain
fetch():POST /api/translate,GET /api/translate/history, andDELETE /api/translate/history
- Eval wiring on the translate agent:
adversarialpreset evallanguage-matchcustom eval
- Local proxy mode and cross-origin
baseUrlmode
- Next.js rewrites: https://nextjs.org/docs/app/api-reference/config/next-config-js/rewrites
- Next.js
'use client': https://nextjs.org/docs/app/api-reference/directives/use-client
nextjs/
├── app/ # Next.js frontend
│ ├── components/TranslateDemo.tsx # Translate + history UI (plain fetch)
│ ├── layout.tsx
│ └── page.tsx
├── agentuity/ # Agentuity backend
│ ├── src/agent/translate/agent.ts # Translate agent
│ ├── src/agent/translate/eval.ts # Evals (adversarial + language-match)
│ ├── src/agent/translate/state.ts # History state schema
│ └── src/api/index.ts # /api/translate* routes
├── next.config.ts # /api/* rewrite to Agentuity backend
└── tsconfig.json
Run from the project root (existing-apps/nextjs), not from inside agentuity/. The root dev script starts both the frontend and backend together:
cd existing-apps/nextjs
bun install
bun run build:agent
bun run devbun run dev starts both runtimes concurrently, and the web process uses wait-on to check http://127.0.0.1:3500/api/health before launching Next.js. Running bun run dev inside agentuity/ starts only the backend, which serves the API and workbench but not the frontend page.
- Frontend: http://localhost:3000
- Backend: http://localhost:3500
- Workbench: http://localhost:3500/workbench
If the project is not registered with Agentuity Cloud, translation calls require provider keys:
OPENAI_API_KEYfor translate agent callsGROQ_API_KEYfor eval model calls
Without credentials, the backend still starts and history endpoints work, but POST /api/translate returns 500.
- If Next.js warns about workspace root detection, keep
outputFileTracingRootinnext.config.tspointed to the monorepo root. - Local default mode uses rewrite proxying in development:
/api/:path* -> http://localhost:3500/api/:path*. - To override proxy target, set
AGENTUITY_PROXY_TARGET(for examplehttps://backend.example.com). - Cross-origin mode skips the rewrite and uses
NEXT_PUBLIC_AGENTUITY_BASE_URLas thefetch()base URL. - In local-only mode without provider credentials,
POST /api/translatecan return500; history endpoints still work. - If backend startup is delayed,
wait-onwaits up to 30 seconds before failing with a timeout error. - If you see a
DEP0060warning while using Next.js rewrites/proxy in dev, treat it as a known transitive dev-time warning unless request routing is actually failing.
The client component uses plain fetch() to call the Agentuity backend:
POST /api/translatewith JSON body{ text, toLanguage, model }GET /api/translate/historyDELETE /api/translate/history
No wrapper library or provider component is needed. The NEXT_PUBLIC_AGENTUITY_BASE_URL env variable sets the base URL for cross-origin mode; in local proxy mode it defaults to empty (same origin).
Run this after changing backend routes, schemas, or frontend route calls:
cd existing-apps/nextjs
bun run build:agent
bun run testbuild:agentbuilds the Agentuity backend.testis a practical check (build:agent && typecheck), not a separate test framework setup.
This example runs two separate runtimes when deployed.
- Preferred: host-level proxy/rewrite
- Route frontend
/api/*traffic to the Agentuity backend. - Equivalent to local
next.config.tsrewrite behavior, but configured at your host/load balancer.
- Fallback: explicit backend base URL from the frontend
- Set frontend env:
NEXT_PUBLIC_AGENTUITY_BASE_URL=https://your-agentuity-backend.example.com - The
fetch()calls inTranslateDemoprepend this as the base URL. - Enable cross-origin backend access with:
AGENTUITY_CORS_ALLOWED_ORIGINS=https://your-frontend.example.com
By default, the Agentuity runtime reflects any origin for CORS. For tighter control, add a cors option to createApp() (e.g., cors: { sameOrigin: true } or cors: { origin: ['https://your-frontend.example.com'] }).