Frontend
Next.js 16 web application for building and managing agents, tools, apps, and knowledge, including its auth layer, configuration, telemetry, and the docs site
Updated 2026-11-03
Verified 2026-11-03
The Frontend is the Cosmos web application. Builders and organization admins use it to create and test agents, tools, apps, skills, prompts, and knowledge bases, and to manage users, providers, models, and observability. The source lives in the cosmos-frontend-v4 repository, which the platform Compose files build as the frontend service on port 3000.
Why It Matters
The Frontend stores no domain data of its own. Everything it shows comes from the backend services, so most Frontend incidents trace back to session or token state in the auth routes, a wrong service URL in the environment, or a missing cosmos-docs directory for the docs site, rather than to page logic.
Architecture At A Glance
- Framework: Next.js 16 with the App Router and Turbopack in development, React 19, and strict TypeScript.
- UI: Material UI v7 with a custom theme, plus Base UI primitives, MUI X charts, date pickers and tree views, Nivo charts, and Cytoscape for graph views.
- State and data: Redux Toolkit with RTK Query slices under
src/network/. - Layers:
src/domain/(backend contracts),src/network/(RTK Query endpoints, base query, reauthentication),src/auth/(auth engine, guards, permission map),src/services/andsrc/infrastructure/(repository providers and HTTP adapters),src/config/(feature flags, environment loader), andsrc/store/. - Voice: browser voice testing uses the Pipecat client libraries with the small WebRTC transport.
| Route area | Purpose |
|---|---|
src/app/(private)/user/ | Builder workspace: agents, apps, tools, skills, prompts, documents (knowledge), evaluations, quality, responsible AI, model garden, observability, metrics, costing, users, organizations, and account settings |
src/app/(private)/admin/ | Platform administration: organizations, users, permissions, providers, connectors, features, model garden, and costing |
src/app/(private)/workspaces/, src/app/(private)/o/[orgId]/ | Workspace and organization-scoped entry points |
src/app/resetpassword/ | Anonymous password reset and verification |
src/app/api/auth/ | Auth routes for login, logout, refresh, MFA verify and resend, and SSO callback |
src/app/api/client-config/ | Runtime client configuration (telemetry connection string) |
src/app/docs/, src/app/api/docs/ | Cosmos documentation site and its content and search APIs (see Documentation Site) |
A root proxy.ts (Next.js middleware) runs on every route except static assets and implements maintenance mode. COSMOS_FRONTEND_MAINTENANCE_MODE turns it on or off for the Frontend; when that variable is unset, the shared MAINTENANCE_MODE flag applies. While it is on, every request except /health and /healthz receives a 503 maintenance response with a Retry-After header (default 300 seconds). MAINTENANCE_TITLE, MAINTENANCE_MESSAGE, MAINTENANCE_UNTIL, MAINTENANCE_CONTACT, and MAINTENANCE_PRODUCT_NAME customize the message.
Authentication
The browser never talks to User Service directly for token-issuing calls. Login goes through backend-for-frontend routes under src/app/api/auth/:
| Route | Behavior |
|---|---|
POST /api/auth/login/ | Forwards credentials to User Service /api/v1/users/login/. An MFA challenge (401 with error: "mfa_required") passes through to the browser unchanged. |
POST /api/auth/mfa/verify/, POST /api/auth/mfa/resend/ | Complete or resend the MFA challenge. |
POST /api/auth/sso-callback/ | Completes single sign-on. |
POST /api/auth/refresh/ | Reads the refresh session cookie and exchanges it at User Service /api/v1/users/refresh-token/ in body token mode. A rotated refresh token replaces the cookie. |
POST /api/auth/logout/ | Ends the session and clears the cookie. |
The refresh token is kept in the cosmos_frontend_refresh cookie (httpOnly, SameSite=Lax). Only the access token and its public metadata reach browser code. A failed refresh does not delete the cookie, because another tab or request may have rotated it at the same time.
Server-side auth routes resolve User Service through USER_SERVICE_URL first and fall back to NEXT_PUBLIC_USER_SERVICE_URL or the gateway host variables. Inside a container, USER_SERVICE_URL must be the in-network address, because localhost there is the frontend container itself.
After login, route and component access is controlled by the guards and permission map in src/auth/. Most API calls carry Authorization: Bearer <token> and X-Org-Id, and project-scoped calls also send the active project header.
Configuration
Next.js inlines NEXT_PUBLIC_* variables at build time. npm run build:<env> runs scripts/build-with-env-runner.js with the matching env file. Targets are dev, azure, gcp, uat, and develop, each with a :local variant. The Docker build chooses the script from the HYPERSCALER and ENVIRONMENT build arguments, or from BUILD_SCRIPT_OVERRIDE.
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_BASE_PATH | Base path and asset prefix for the app (empty in local dev) |
NEXT_PUBLIC_USER_SERVICE_URL | Browser-side User Service URL |
USER_SERVICE_URL | Server-side User Service URL for the auth routes |
NEXT_PUBLIC_CONFIGURATOR_SERVICE_URL, NEXT_PUBLIC_TOOLS_SERVICE_URL, NEXT_PUBLIC_ADK_SERVICE_URL, NEXT_PUBLIC_CHAT_SERVICE_URL, NEXT_PUBLIC_STORAGE_SERVICE_URL, NEXT_PUBLIC_KB_SERVICE_URL, NEXT_PUBLIC_OBSERVER_SERVICE_URL, NEXT_PUBLIC_RAGFLOW_SERVICE_URL | Per-service public URLs used by browser calls |
NEXT_PUBLIC_VOICE_WEBRTC_SERVICE_URL, NEXT_PUBLIC_VOICE_WEBSOCKET_HOST, NEXT_PUBLIC_VOICE_TWILIO_SERVICE_URL | Voice service endpoints |
NEXT_PUBLIC_WEBRTC_ICE_SERVERS | ICE server list for browser WebRTC voice sessions |
NEXT_PUBLIC_COSMOS_GATEWAY_HOST and related _BROWSER, _SSR, and _WEBSOCKET_HOST variants | Gateway-style host fallback when per-service URLs are not set |
NEXT_PUBLIC_MODELGARDEN_SERVICE_URL, NEXT_PUBLIC_KB_RAG_SERVICE_URL | Model Garden and knowledge retrieval endpoints |
NEXT_PUBLIC_DOCUMENTATION_URL | Documentation link target |
NEXT_PUBLIC_FEATURE_CONNECTORS | Feature flag for connectors |
APPINSIGHTSCONNECTIONSTRING | Runtime Application Insights connection string (see Telemetry) |
In local development the Compose file sets each NEXT_PUBLIC_*_SERVICE_URL to the host-mapped port (for example http://localhost:8100 for Configurator) and sets USER_SERVICE_URL=http://user-web:8000. Deployed environments use each service's public URL directly; there is no shared gateway in front of the services.
Telemetry
Browser telemetry uses Azure Application Insights. On load, the app fetches GET /api/client-config/. This route reads APPINSIGHTSCONNECTIONSTRING from the server environment on every request, so a deployed pod can supply it from its secret store without a rebuild. When the value is empty, which is the case outside Azure and in local development, telemetry stays off and nothing is sent.
When telemetry is on:
- Every item is tagged with the cloud role
frontend. - Page views are tracked automatically on route changes, and duplicate App Router navigations are dropped.
- Query strings and fragments are removed from page, URL, and dependency fields, because they can carry reset tokens, search terms, or IDs.
- Click analytics names elements by
data-ai-nameordata-testidbefore falling back to other attributes. - Correlation headers are added only for Cosmos API hosts, so browser calls join the server-side traces for the same transaction. Third-party hosts, such as direct blob uploads, are excluded.
- The authenticated user context is an opaque user ID, never an email, name, or token.
NEXT_PUBLIC_APPINSIGHTS_DISABLE_COOKIES=truedisables telemetry cookies.
Documentation Site
The Frontend serves this documentation at /docs/, rendered from the cosmos-docs/ directory.
- Docs root:
DOCS_ROOTis used when it points at an existing directory. Otherwise the docs root iscosmos-docsunder the process working directory (/app/cosmos-docsin the container). This fallback covers the difference between host paths and container paths. - Routes:
/docs/and/docs/<path>render pages,/docs/health/shows a freshness report for public pages, and/docs/assets/<path>serves files fromcosmos-docs/assets/. Asset paths that resolve outside the assets directory, including traversal and symlink tricks, are rejected. - Access: the
operationsandcontributingsections, and any page whoseaudienceisinternalwithoutexternal, are internal. Internal pages are not prerendered with content and are left out of the search index. They load only through the authenticated content API under/api/docs/content/, behind a sign-in gate. - Search: a lunr index of public pages is served from
/api/docs/search-index. - Freshness: pages are fresh when
last_verifiedis within 30 days, aging within 60 days, stale beyond that, and unknown when the date is missing. - Diagrams: draw.io files referenced from markdown images, for example
, render as diagrams.
How docs get into the image
The Dockerfile has a docs-git stage that sparse-clones the cosmos-docs directory from the platform repository. Build arguments control it:
| Build argument | Default | Purpose |
|---|---|---|
DOCS_REPO_URL | platform repository | Repository to clone |
DOCS_BRANCH | master | Branch to clone |
GITHUB_ACCESS_TOKEN | empty | Explicit token for the private repository; takes precedence |
GITHUB_TOKEN | empty | Fallback token, such as the one CI injects |
DOCS_CACHE_BUST | empty | Change this value to force a fresh clone |
The clone step does not fail the build. If the repository cannot be reached, the image builds without docs and /docs/ has no content. The runner stage copies cosmos-docs into /app/cosmos-docs. In local development, Compose passes the workspace cosmos-docs directory in as the docs build context and also mounts it read-only at /app/cosmos-docs, so edits show up without a rebuild.
Testing Workspace
Agent and app testing runs through the Chat WebSocket using the versioned ADK v2 test protocol:
- Create New Session prepares an unsaved, in-memory test draft. The session is created only when the first message or image is sent. That first frame carries the org, project, agent or app version, selected tools and knowledge graphs, and the chosen provider, model, and temperature.
- After a disconnect, the client never replays a start or a query. Continuing a session sends
resume_session: truewith the session ID and a new message. - Saved test sessions load from a server-owned test snapshot and paginated visible messages. Raw ADK events are never requested for test sessions.
- The Tool Calls inspector shows only redacted tool start and complete metadata. Historical traces come from Observer, scoped to the session's organization and project.
- Saved responses that have a server message ID support thumbs-up and thumbs-down feedback and show follow-up question chips. Evaluate starts a quality run for a saved session when the agent version has an Analyzer attached.
Integration Points
| Service | Integration |
|---|---|
| User Service | Login, MFA, SSO, token refresh (through the auth routes), users, organizations, roles, and permissions |
| Configurator | CRUD for agents, apps, tools, skills, prompts, guardrails, providers, and knowledge bases |
| Chat | Testing workspace WebSocket |
| ADK | Test sessions, snapshots, feedback, suggestions, and evaluation |
| Tools Server | Tool testing and connectors |
| Storage | File and collection uploads |
| Observer | Observability dashboards and test session traces |
| Voice | Browser voice testing over WebRTC |
| RAGflow | Knowledge retrieval |
Development
npm install
npm run dev # Turbopack
npm run dev:webpack # Webpack fallback
npm run dev:metrics # Report the slowest route compilations
npm run lint
npm run typecheck
The dev server keeps its Turbopack cache between runs and precompiles common workspace routes after startup. It clears .next automatically when the directory grows past 5 GB. Set NEXT_DEV_PREWARM=false to skip prewarming, or NEXT_DEV_CACHE_LIMIT_GB=<size> to change the limit. Unit tests use Vitest, and browser tests use Playwright.
In the platform workspace, start the Frontend with ./manage.sh dev start (it is a default service) and open http://localhost:3000. See Deploying Locally.
Troubleshooting
- Login fails with a connection error from
/api/auth/login/:USER_SERVICE_URLpoints atlocalhostinside the container. Set it to the in-network User Service address and run./manage.sh dev restart frontend. - Environment changes are not picked up:
NEXT_PUBLIC_*values are inlined at build time. Use./manage.sh dev restart frontendin dev, and rebuild the image for deployed targets. /docs/has no content: check that docs exist in the container (docker exec cosmos-dev-frontend ls /app/cosmos-docs/) and thatDOCS_ROOTdoes not point at a missing path. For deployed images, check the build log for a skipped docs clone and confirm that a token was supplied.- No telemetry in Application Insights: confirm that
GET /api/client-config/returns a non-emptyappInsightsConnectionStringfor that environment. - Every page returns 503: maintenance mode is on. Check
MAINTENANCE_MODEandCOSMOS_FRONTEND_MAINTENANCE_MODE.