Sign in

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

frontend
frontendnextjsreacttypescriptmuiredux

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/ and src/infrastructure/ (repository providers and HTTP adapters), src/config/ (feature flags, environment loader), and src/store/.
  • Voice: browser voice testing uses the Pipecat client libraries with the small WebRTC transport.
Route areaPurpose
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/:

RouteBehavior
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.

VariablePurpose
NEXT_PUBLIC_BASE_PATHBase path and asset prefix for the app (empty in local dev)
NEXT_PUBLIC_USER_SERVICE_URLBrowser-side User Service URL
USER_SERVICE_URLServer-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_URLPer-service public URLs used by browser calls
NEXT_PUBLIC_VOICE_WEBRTC_SERVICE_URL, NEXT_PUBLIC_VOICE_WEBSOCKET_HOST, NEXT_PUBLIC_VOICE_TWILIO_SERVICE_URLVoice service endpoints
NEXT_PUBLIC_WEBRTC_ICE_SERVERSICE server list for browser WebRTC voice sessions
NEXT_PUBLIC_COSMOS_GATEWAY_HOST and related _BROWSER, _SSR, and _WEBSOCKET_HOST variantsGateway-style host fallback when per-service URLs are not set
NEXT_PUBLIC_MODELGARDEN_SERVICE_URL, NEXT_PUBLIC_KB_RAG_SERVICE_URLModel Garden and knowledge retrieval endpoints
NEXT_PUBLIC_DOCUMENTATION_URLDocumentation link target
NEXT_PUBLIC_FEATURE_CONNECTORSFeature flag for connectors
APPINSIGHTSCONNECTIONSTRINGRuntime 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-name or data-testid before 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=true disables telemetry cookies.

Documentation Site

The Frontend serves this documentation at /docs/, rendered from the cosmos-docs/ directory.

  • Docs root: DOCS_ROOT is used when it points at an existing directory. Otherwise the docs root is cosmos-docs under the process working directory (/app/cosmos-docs in 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 from cosmos-docs/assets/. Asset paths that resolve outside the assets directory, including traversal and symlink tricks, are rejected.
  • Access: the operations and contributing sections, and any page whose audience is internal without external, 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_verified is 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 ![Runtime](../assets/diagrams/cosmos-runtime.drawio), 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 argumentDefaultPurpose
DOCS_REPO_URLplatform repositoryRepository to clone
DOCS_BRANCHmasterBranch to clone
GITHUB_ACCESS_TOKENemptyExplicit token for the private repository; takes precedence
GITHUB_TOKENemptyFallback token, such as the one CI injects
DOCS_CACHE_BUSTemptyChange 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: true with 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

ServiceIntegration
User ServiceLogin, MFA, SSO, token refresh (through the auth routes), users, organizations, roles, and permissions
ConfiguratorCRUD for agents, apps, tools, skills, prompts, guardrails, providers, and knowledge bases
ChatTesting workspace WebSocket
ADKTest sessions, snapshots, feedback, suggestions, and evaluation
Tools ServerTool testing and connectors
StorageFile and collection uploads
ObserverObservability dashboards and test session traces
VoiceBrowser voice testing over WebRTC
RAGflowKnowledge retrieval

Development

bash
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_URL points at localhost inside 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 frontend in 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 that DOCS_ROOT does 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-empty appInsightsConnectionString for that environment.
  • Every page returns 503: maintenance mode is on. Check MAINTENANCE_MODE and COSMOS_FRONTEND_MAINTENANCE_MODE.