# Copy this file to .env and fill in your values. # ───────────────────────────────────────────────────────────────────────────── # Frontend (Vite) — client-visible # ───────────────────────────────────────────────────────────────────────────── # For both `npm run dev` and `docker compose up`, the Ion token is baked into # the Vite client bundle at build time (VITE_* prefix). Under docker compose # it's passed as a build arg (compose.yaml → frontend build args), so changing # it requires a rebuild. Either way it's intentionally client-visible — scope # it in the Ion console to restrict allowed assets and HTTP referrers. # Cesium Ion access token — get one free at https://ion.cesium.com VITE_CESIUM_ION_ACCESS_TOKEN= # Cesium ion API server the token above was issued by. Only needed if your token comes from a # non-production ion server (e.g. an internal/staging ion environment) — leave unset for a normal # ion.cesium.com token. Setting the wrong (or no) server for a non-production token causes every # asset request to fail with 401 Unauthorized against the default production server. You can find # the correct value by decoding your token's JWT payload and reading its "iss" claim. # VITE_CESIUM_ION_SERVER_URL=https://your-ion-server.example.com # Base URL the frontend calls for the chat API. The chat endpoint is this base # joined with /api/chat. Point it at the backend host (must match the backend's # PUBLIC_URL and be permitted by its ALLOWED_ORIGIN/CORS list). Baked in at # build time; under docker compose it's built as "" so the app calls relative # /api/chat, which nginx proxies to the backend. # Default: http://localhost:3001 VITE_API_BASE_URL=http://localhost:3001 # Frontend OpenTelemetry log export (build-time Vite env vars). # Enables OTLP log export from browser-side packages (frontend + codegen sandbox logger adapter). # Default: false VITE_TELEMETRY_ENABLED=false # Base OTLP endpoint (the app appends /v1/logs). Example: https://otel-gateway.example.com VITE_OTEL_EXPORTER_OTLP_ENDPOINT= # Optional explicit logs endpoint (overrides VITE_OTEL_EXPORTER_OTLP_ENDPOINT + /v1/logs). VITE_OTEL_EXPORTER_OTLP_LOGS_ENDPOINT= # Optional comma-separated OTLP headers: key=value,key2=value2 (for vendor auth/project routing). VITE_OTEL_EXPORTER_OTLP_HEADERS= # Optional service identity overrides for frontend telemetry resource attributes. VITE_OTEL_SERVICE_NAME=cesiumjs-ai-starter-app-frontend VITE_OTEL_SERVICE_NAMESPACE=cesium-ai # Optional extra OTEL resource attributes: key=value,key2=value2 VITE_OTEL_RESOURCE_ATTRIBUTES= # Minimum severity (debug/info/warn/error/silent) for this app's browser-side loggers (console + # OTLP export alike) VITE_OTEL_LOG_LEVEL= # Comma-separated exact HTTP(S) origins that generated Cesium code may load assets from. # Empty/unset denies guest-provided network URLs. Paths are not allowed here. # VITE_SANDBOX_ALLOWED_NETWORK_ORIGINS=https://assets.example.com,https://maps.example.com # ───────────────────────────────────────────────────────────────────────────── # Backend (Node API) — server-side only, NEVER prefix these with VITE_ # ───────────────────────────────────────────────────────────────────────────── # Base URL the backend is reachable at (e.g. https://api.example.com). The # listening port is derived from this URL. # Default: http://localhost:3001 PUBLIC_URL=http://localhost:3001 # Which LLM provider the agent loop uses: openai | anthropic | google # Default: openai AI_PROVIDER=openai # Provider API keys. Only the key for the selected AI_PROVIDER is required. # Leave the rest blank. Leaving all of them blank runs the app as a plain # static viewer — /api/chat returns NOT_CONFIGURED and the chat panel shows # an inline message instead of failing silently. OPENAI_API_KEY= ANTHROPIC_API_KEY= GOOGLE_GENERATIVE_AI_API_KEY= # Optional model override. When unset, a sensible default is chosen per provider # (openai: gpt-4.1, anthropic: claude-opus-4-8, google: gemini-2.5-pro). AI_MODEL= # Optional custom base URL for an OpenAI-compatible proxy / gateway / self-hosted # endpoint. Leave blank to use the provider's default. AI_BASE_URL= # In-process rate limit: max requests per minute per IP for /api/chat. # Default: 20. Set to a higher value or disable via your gateway if you have one. RATE_LIMIT_RPM=20 # Max number of BM25-matched cesiumjs-skills domains inlined as grounding context in the # executeCesiumCode tool's code-generation prompt. Higher values give the model more reference # material per request (more tokens, potentially better coverage for intents spanning domains); # lower values keep prompts small and scoped. Default: 1. CODEGEN_MAX_SKILLS=1 # Max regeneration attempts if a generated executeCesiumCode snippet fails static AST # verification (each retry feeds the previous attempt's violations back to the model as extra # prompt context). Higher values give the model more chances to recover from a bad generation # (more latency/cost per request) before the tool call returns an error. Default: 3. CODEGEN_MAX_ATTEMPTS=3 # Hard cap on generated executeCesiumCode source size in characters, enforced by the static AST # verifier before parsing. Default: 4000. CODEGEN_MAX_CODE_LENGTH=4000 # Hard cap on generated executeCesiumCode line count, enforced by the static AST verifier before # parsing. Default: 100. CODEGEN_MAX_CODE_LINES=100 # Optional comma-separated free-identifier allowlist enforced by the static AST verifier. When # blank/unset, no allowlist restriction is applied (any identifier not otherwise banned — see # BANNED_GLOBALS — is permitted). Example: CODEGEN_ALLOWED_SYMBOLS=viewer,Cartesian3,Cartographic CODEGEN_ALLOWED_SYMBOLS= # Optional extra instructions appended to the executeCesiumCode generation prompt's output rules # (e.g. app-specific constraints or house style preferences). Blank/unset appends nothing. This is # app/operator-supplied text only — never plumb raw end-user chat input into this value, since it # feeds directly into the codegen model's prompt. CODEGEN_EXTRA_INSTRUCTIONS= # CORS allow-list: comma-separated origins permitted to call the backend. # Default: http://localhost:5173 (the Vite dev server) ALLOWED_ORIGIN=http://localhost:5173 # Per-tool-call timeout for MCP tools (ms). Default: 30000. MCP_TOOL_TIMEOUT_MS=30000 # Signs the session-ID cookie used to key any auto-detected, auth-required # MCP server's connections. Only meaningful when at least one such server is # detected. Required when session-scoped MCP connections are enabled. Generate # a long random value for each environment; never commit the populated value. SESSION_SECRET= # OpenTelemetry log + trace export for backend + server-side packages (mcp-tools adapter # included). Traces cover the agent loop's GenAI spans (invoke_agent/chat/execute_tool, emitted # via @ai-sdk/otel) for every streamText call in packages/server's runAgent. # true | false (default: false) TELEMETRY_ENABLED=false # Base OTLP endpoint (the app appends /v1/logs or /v1/traces). Example: https://otel-gateway.example.com OTEL_EXPORTER_OTLP_ENDPOINT= # Optional explicit logs endpoint (overrides OTEL_EXPORTER_OTLP_ENDPOINT + /v1/logs). OTEL_EXPORTER_OTLP_LOGS_ENDPOINT= # Optional explicit traces endpoint (overrides OTEL_EXPORTER_OTLP_ENDPOINT + /v1/traces). OTEL_EXPORTER_OTLP_TRACES_ENDPOINT= # Optional comma-separated OTLP headers: key=value,key2=value2 (for vendor auth/project routing). OTEL_EXPORTER_OTLP_HEADERS= # Service identity for backend telemetry resource attributes. OTEL_SERVICE_NAME=cesiumjs-ai-starter-app-backend OTEL_SERVICE_NAMESPACE=cesium-ai # Optional extra OTEL resource attributes: key=value,key2=value2 OTEL_RESOURCE_ATTRIBUTES= # Backend telemetry log threshold (debug/info/warn/error/silent). Default: info OTEL_LOG_LEVEL=info