Env vars¶
Status: Current | Last reviewed: 2026-10-20
Master env-var reference. Per-service vars live in each service's doc; this page is the cross-service catalog.
Local dev env loading¶
Every .devcontainer/scripts/start-*.sh launcher, health-check.sh, and the watchdogs load .devcontainer/scripts/lib-env.sh. The loader reads root .env.local when present, then fills safe local defaults for common service URLs and ports. Manual launches should use the same loader:
bash .devcontainer/scripts/with-env.sh --summary
bash .devcontainer/scripts/with-env.sh npm --prefix apps/ai-manager run dev
with-env.sh --summary prints the effective env with secrets redacted. validate-env.sh is run by wake-up.sh and can be run directly before a rebuild; it enforces required local secrets and, on DEV_ENV=ec2, checks the city public URLs for Janus, TURN, surface-app, payment-vault, code-server, and MCP, the non-charging payment gates, and minimum secret lengths. scripts/ec2-dev/city-update.sh <city> --step env backs up and reconciles those city-specific .env.local values before --step rebuild.
For AI/manual restarts, prefer either overmind restart <service> or the service launcher under .devcontainer/scripts/. If you need to run a framework command directly, wrap it with with-env.sh so it sees the same .env.local and derived defaults as Overmind.
Ari Assistant and Poppy¶
The separate Assistant app owns
ASSISTANT_DATABASE_URL, ASSISTANT_ENCRYPTION_KEY, ASSISTANT_PUBLIC_URL,
ASSISTANT_STUDIO_URL, ASSISTANT_MODEL, ASSISTANT_MODEL_SOURCE and
ASSISTANT_PRIVATE_ORIGINS. Its default model path uses the tenant integration
in Studio; Studio limits model IDs with ASSISTANT_MODEL_ALLOWLIST.
The Poppy Company gateway owns
POPPY_DATABASE_URL, POPPY_NONCE_KEY, POPPY_DOMAIN_SUFFIX and
POPPY_ALLOWED_CLIENT_ORIGINS. Studio also needs the Poppy database connection
and domain suffix for its tenant-scoped publication API. Provisioners write
private local files; keep these credentials out of Git.
Global¶
| Var | Used by | Purpose |
|---|---|---|
TRUESERVE_DEV_MODE |
every service in Vanguard | dev flips path resolution to host processes; unset means cluster |
MASTER_ENCRYPTION_KEY |
ai-manager, ai-orchestrator, agent-host, async-agent, catalog-builder, config-sync-service, teams-agent-gateway | AES-256-GCM key for integrations, tools, tool_secrets, and Teams bot secrets. See secret-storage.md |
DATABASE_URL |
every service that hits Postgres | Postgres connection string |
POSTGRES_SSL_MODE |
services that compose a Postgres URL from POSTGRES_* vars |
Postgres TLS mode. Use require, verify-ca, or verify-full for managed cloud Postgres; local/Kind usually uses disable |
REDIS_URL |
every service that hits Redis | Redis connection string |
COLLAB_REDIS_URL |
collab-gateway | Optional separate Redis for collab DB 4 |
RABBITMQ_URL / BROKER_URL |
async-agent, event-publisher | AMQP URL. Use amqps:// for managed RabbitMQ; in-cluster RabbitMQ can stay amqp:// when mesh mTLS is enabled |
TSF_EVENT_TRANSPORT |
surface-app, ai-manager (server runtime, read per request) | Browser event-stream transport: sse (default) or ws. Set ws where a network middlebox buffers SSE (some *.trueserve.ai cities) — the flag reaches the browser through existing session/resolve/ticket payloads and clients switch to the same-origin /ws/* WebSocket endpoints (ingress-routed to conversation-api / async-agent). Runtime env on purpose: NEXT_PUBLIC_EVENT_TRANSPORT is baked at build time, so it survives only as a dev-only lowest-precedence override in the surface-app in-tree SDK. See conversation-api |
ClearConnect PSP¶
CLEARCONNECT_CONFIG_FILE names the private runtime JSON file for the
standalone PSP demo. The launcher defaults
to .local-data/clearconnect/config.json; manual backend commands must point to
it explicitly. This app uses its own database and clears inherited city
credentials before launching its API and connector. Do not put provider secrets
in VITE_* variables.
CLEARCONNECT_HOST_APP_DIR optionally overrides the host source directory used
by the nginx installer; the Vanguard default is
/home/admin/trueserve-framework/apps/clearconnect.
Standalone multimodal Google authentication¶
These optional edge-mode settings enable GECX invocation of the private Cloud Run sandbox. They do not grant operator or browser session access.
| Variable | Default | Purpose |
|---|---|---|
MULTIMODAL_GOOGLE_SERVICE_ACCOUNTS |
Empty, disabled | Comma-separated exact Google service-account emails allowed to call MCP |
MULTIMODAL_GOOGLE_ID_TOKEN_AUDIENCES |
Empty | Additional exact Google ID-token audiences, including the canonical Cloud Run URL aliases |
MULTIMODAL_PUBLIC_URL |
Empty | Service origin used for MCP Host validation, OAuth issuer and Google token audience validation |
The service also accepts the configured origin's /mcp URL as an audience.
Google signature, issuer, expiry and verified email are checked independently
of Cloud Run ingress.
Director rendering¶
Director rendering in ai-manager accepts two optional runtime settings:
DIRECTOR_RENDER_ORIGIN selects the same-instance app origin (default
http://127.0.0.1:${PORT or 3001}), and DIRECTOR_CHROMIUM_PATH selects an
installed browser executable. Neither is user input. See Director.
Auth and identity¶
| Var | Used by | Purpose |
|---|---|---|
OIDC_ISSUER |
ai-manager, surface-app | Authentik issuer URL |
OIDC_CLIENT_ID |
ai-manager | OAuth client id |
OIDC_CLIENT_SECRET |
ai-manager | OAuth client secret |
AUTHENTIK_BASE_URL |
ai-manager | Authentik admin API base URL for the Platform Admin console (user/tenant/group write-back). Defaults to SSO_BASE_URL |
AUTHENTIK_API_TOKEN / AUTHENTIK_API_TOKEN_FILE |
ai-manager | Authentik admin API token (inline, or a file path — default secret/AuthentikToken.txt, walked up from the app cwd). Required for the Platform Admin console to create users and manage tenant:<slug>:<role> / trueserve-platform-admin groups. Create it in Authentik → Directory → Tokens & App Passwords for an admin user |
APP_URL / NEXT_PUBLIC_APP_URL |
ai-manager | Browser-facing ai-manager origin. OAuth callback/start, enrollment redirects, post-login redirects, and generated public URLs prefer this over forwarded host headers |
AI_MANAGER_ALLOWED_REDIRECT_HOSTS |
ai-manager | Comma-separated fallback host allowlist for OAuth/enrollment redirects and generated public URLs when APP_URL is unset. PUBLIC_FQDN also derives ai-manager.<domain> and emulator.<domain> |
EXTERNAL_AI_MANAGER_URL / EXTERNAL_SURFACE_APP_URL |
ai-manager | Public deployment URLs surfaced to external systems (API-token connection info, embed snippet generation). Embed snippets resolve these first, then derive https://<service>.<PUBLIC_FQDN>, then fall back to the request host — so generated snippets never carry a localhost dev URL |
COLLAB_SERVICE_TOKEN |
collab-gateway, ai-manager | Shared token for service-to-service collab verification |
SURFACE_INTERNAL_HMAC_SECRET |
surface-app, ai-manager, conversation-api, teams-agent-gateway | Shared HMAC secret for internal conversation-api calls |
EMBED_COOKIE_CROSS_ORIGIN |
surface-app | Forces SameSite=None; Secure for the sfa_session embed cookie. /api/session/exchange also applies those attributes automatically for HTTPS browser-facing requests. |
WHISKER_GATEWAY_TOKEN_SECRET |
ai-manager, ai-orchestrator | Shared HMAC secret for short-lived live-debug WebSocket gateway tokens |
CUSTOMER_AUTH_OTP_PEPPER |
conversation-api | HMAC pepper for Customer Authentication OTP code hashes. Missing pepper refuses OTP issuance (an unkeyed digest of a six-digit code is reversible). Rotating it invalidates all outstanding codes |
CUSTOMER_AUTH_RP_ID |
conversation-api | WebAuthn Relying Party ID override for Customer Authentication passkeys. Accepted only as a registrable suffix of the surface-app host; default is the surface-app hostname |
PAYMENT_VAULT_PUBLIC_URL |
ai-manager | Platform-default public base URL of payment-vault, which serves the hosted-fields payment iframe. A tenant may override it per tenant (tenant_settings['payments'].vault_public_url) when it needs the frame served from its own PCI-scoped hostname; unset and unoverridden means Payments is unavailable (vault_not_configured) |
TRUESERVE_USER_ID |
code-server pod | Bound user id presented as x-on-behalf-of |
TRUESERVE_TENANT_ID |
code-server pod | Bound tenant id presented as x-on-behalf-of-tenant |
TRUESERVE_USER_NAME |
code-server pod | Display name for presence |
CODE_SERVER_VERIFY_TOKEN |
ai-manager, code-server auth-proxy | Optional shared token for /api/auth/code-server-verify. When set on ai-manager, the auth-proxy must send the same value via X-Code-Server-Verify-Token; configure code-server chart authProxy.verifyTokenSecret |
Object storage¶
| Var | Used by | Purpose |
|---|---|---|
STORAGE_PROVIDER |
every service that hits object storage | s3 (default) | gcs | local |
STORAGE_BUCKET_RECORDINGS / STORAGE_BUCKET_CATALOGS / STORAGE_BUCKET_ASSETS / STORAGE_BUCKET_SCALE_TESTING |
per store role used | No default — a service using an unset role bucket fails loudly rather than writing to a wrong bucket |
STORAGE_REGION |
same | Required (s3/gcs) — always passed explicitly to the client |
STORAGE_ENDPOINT |
same | Empty = AWS S3; https://storage.googleapis.com for GCS S3-interop; http://localhost:9000 for the CI MinIO |
STORAGE_FORCE_PATH_STYLE |
same | true for any custom endpoint (MinIO, GCS) |
STORAGE_ACCESS_KEY / STORAGE_SECRET_KEY / STORAGE_SESSION_TOKEN |
same | OPTIONAL by design — absent selects the SDK default credential chain (IRSA). Never make these required |
STORAGE_KEY_PREFIX |
same | Prepended to every key; separates shared-local-bucket users (dev machines, kind) |
LOCAL_STORAGE_PATH |
STORAGE_PROVIDER=local |
Base directory for the filesystem provider |
WORKFLOW_DATASET_LOCAL_DIR |
async-agent | Local fallback directory for workflow dataset pages when S3/MinIO credentials are absent. Defaults to /tmp/trueserve-workflow-datasets |
All object storage rides the shared seam (object-storage.md); the retired MINIO_* / S3_* aliases are CI-gated out (scripts/storage/check-retired-storage-vocabulary.sh). Tenant archive sinks may still provide destination credentials through integrations — those config blobs keep their legacy alias keys as data compatibility.
Service-to-service URLs¶
| Var | Set by | Purpose |
|---|---|---|
ASYNC_AGENT_URL |
ai-orchestrator | async-agent endpoint, e.g. localhost:8000 |
CONVERSATION_API_GRPC_ENDPOINT |
ai-orchestrator | conversation-api gRPC, localhost:1234 |
CONVERSATION_API_URL |
surface-app, teams-agent-gateway | conversation-api HTTP/SSE URL; local surface-app commonly uses :8080, while in-cluster gateway deployments use the conversation-api Service URL |
EMBED_CORS_VALIDATION_ENABLED |
conversation-api | Enables origin-validation middleware backed by ai-manager's active allowed origins. Defaults on; set false only for isolated local development |
EMBED_ALLOW_LOCALHOST |
conversation-api | Allows localhost origins when origin validation is enabled. Defaults false; local/Kind overlays set true explicitly |
ALLOWED_ORIGINS_REGEX |
conversation-api | CORS response allowlist regex for direct browser/partner calls. Origin validation still gates route execution when enabled |
SURFACE_APP_BASE_URL |
conversation-api, ai-orchestrator | Preferred browser-facing surface-app base URL for multimodal share links. On conversation-api it MUST be the external HTTPS URL (or unset) in any non-localhost env — it is both the customer link base and an allow-list entry, and every configured entry is normalized (HTTPS-required) when the allow-list is built, so a non-HTTPS value here (e.g. the internal subchart default http://surface-app:3001) throws "must be HTTPS" and 400s every multimodal-SMS request, even one carrying the correct external URL. The KMS subchart default is http://surface-app:3001, so the values-kms-*.yaml conversation-api block pins the external HTTPS value explicitly |
NEXT_PUBLIC_SURFACE_APP_URL |
ai-manager, conversation-api, ai-orchestrator | Browser-facing local/dev surface-app URL; used for multimodal links when SURFACE_APP_BASE_URL is unset. In ai-manager it is baked into the client bundle at build time (--build-arg, see the Dockerfile) — a runtime helm value has no effect on the browser. When unset, ai-manager's Preview iframe derives surface-app from window.location, rewriting the ai-manager host (ai-manager.<domain> in Vanguard, studio.<domain> in KMS dev/qa/prod) to surface-app.<domain> — see lib/surface-app-url.ts |
SURFACE_APP_URL |
ai-orchestrator, conversation-api | Server/deployed surface-app URL; also accepted by conversation-api's multimodal link allow-list |
NEXT_PUBLIC_COLLAB_WS_URL |
ai-manager | collab-gateway WS URL, ws://localhost:3510 |
WHISKER_PUBLIC_WS_URL |
ai-manager | Optional browser-facing Whisker gateway base. Gateway/cluster deployments usually use wss://ai-manager.<domain>/whisker-ws; vanguard local uses wss://code.<domain>/whisker-ws; empty means same-origin /whisker-ws. |
TEAMS_AGENT_GATEWAY_PUBLIC_URL |
ai-manager | Public HTTPS base URL used to render Microsoft Teams Bot Framework messaging endpoints |
AGENT_HOST_MCP_URL |
ai-orchestrator | MCP endpoint; agent-host-mcp:8003 rewrites to localhost:8003 in Vanguard |
ARI_CONTROLLER_URL |
async-agent, ai-orchestrator, agent-host | ari-controller HTTP base, http://localhost:3000 in dev. 3000 is the controller's HTTP_PORT default and its chart service.targetPort, and the in-cluster host is ari-controller-node — the Service name is hardcoded in that subchart's service.yaml, so http://ari-controller:3000 resolves to nothing. The orchestrator's consult client also reads ARI_CONTROLLER_HTTP_URL (this variable wins); both defaulted to :8080 until 2026-08-12, which is why every consult call failed to connect. See start-conversation-node.md |
ARI_CONTROLLER_INTERNAL_TOKEN |
ari-controller, async-agent, ai-orchestrator, agent-host | Bearer on ari-controller's internal routes (/consult/*, /outbound-call, /session-end, /dtmf-out/*). Same value on both sides; ari-controller also accepts ARI_INTERNAL_SERVICE_TOKEN / INTERNAL_SERVICE_TOKEN in that precedence order and requires ≥32 bytes outside dev. Unset on the controller ⇒ every mutating route answers 503; mismatched or absent on the caller ⇒ 401. There is no anonymous path — so a caller that sends no header at all fails identically to a wrong one, and the model reports it as a refused transfer (see warm-handoff.md). In K8s it comes from the trueserve-media-secrets Secret and must be listed in each service's secretEnv in every per-env values file (Helm replaces that list wholesale) |
ANTIGRAVITY_RUNNER_URL |
ai-orchestrator | Internal HTTP URL for the sandboxed Google Antigravity runner. Local default http://localhost:8011; cluster default http://antigravity-runner:8011 |
WORKSPACE_AGENT_RUNNER_URL |
ai-orchestrator | Internal HTTP URL for the sandboxed Assistant Agent runner used by Codex and Claude Code. Local default http://localhost:8012; cluster default http://workspace-agent-runner:8012 |
CONVERSATION_API_PUBLIC_URL |
conversation-api, ai-manager | Explicit public base used as the url in served/previewed A2A Agent Cards ({base}/agents/{id}). When unset, both services fall back to https://conversation-api.${PUBLIC_FQDN}, then (conversation-api) X-Forwarded-*. Must be a fully-qualified domain — external A2A callers fetch it. See conversation-api.md |
PUBLIC_FQDN |
conversation-api, ai-manager | Deployment domain (e.g. vanguard.dev.trueserve.deloitte.com); used to derive the A2A Agent Card url as https://conversation-api.<PUBLIC_FQDN> when CONVERSATION_API_PUBLIC_URL is unset |
When global.security.transportEncryption.enabled=true, internal service URLs generally remain http://... and gRPC endpoint vars remain host:port. Istio sidecars provide pod-to-pod encryption; do not switch internal app URLs to https:// unless the destination application itself is configured to serve TLS.
Knowledge tools¶
Knowledge has no environment variables. It is configured per tenant in
ai-manager under Settings → Tenant Settings → Knowledge (tenant admins only),
stored in tenant_settings key knowledge as {enabled, base_url,
api_token_enc} with the API token AES-256-GCM encrypted under
MASTER_ENCRYPTION_KEY. ai-manager, ai-orchestrator, and async-agent all read
that per session/build — there is no env fallback, so an unconfigured tenant sees
no Knowledge tool type. The retired vars were
NEXT_PUBLIC_FEATURE_KNOWLEDGE_TOOLS, FEATURE_KNOWLEDGE_TOOLS,
KNOWLEDGE_SOURCES_API_BASE_URL, KNOWLEDGE_SOURCES_API_TOKEN, MCP_API_KEY,
and KNOWLEDGE_SOURCES_API_TOKEN_FILE; migrate an existing env-configured
environment with npx tsx apps/ai-manager/scripts/backfill-knowledge-settings.ts.
See knowledge tools.
A2A (Agent2Agent)¶
| Var | Used by | Purpose |
|---|---|---|
A2A_TURN_TIMEOUT_SEC |
conversation-api | Max seconds the A2A message/send bridge waits for an agent turn before returning collected text. Default 45 |
Salesforce Service Cloud Voice (connect-scv-translator)¶
| Var | Used by | Purpose |
|---|---|---|
TELEPHONY_PROVIDER |
connect-scv-translator | Which telephony provider to drive: Connect, Genesys, or demo. Overridable per request with an x-telephony-provider header |
ORCHESTRATOR_GRPC_ENDPOINT |
connect-scv-translator | ai-orchestrator gRPC for Live Translation, e.g. localhost:50051 |
SCV_TRANSLATION_AGENT_ID |
connect-scv-translator | Lowest-precedence default translation agent, served to the softphone by GET /api/translator-config. Must be a published speech_to_speech/translation pipeline id. Outranked by the panel's Translation Agent ID and the Call Center XML reqTranslationAgentId; all three blank means translation refuses to start |
SCV_TRANSLATION_PREFIX |
connect-scv-translator | Label prefixing the translated message in a Salesforce transcript. SCRT2's messages body has ONE text field, so an utterance in two languages is posted as two messages — the original, then the translation prefixed with this. Default [Translation]; set to an empty value for an unlabelled second message (not the same as unset) |
SCV_TRANSCRIPT_TRANSLATION_ONLY |
connect-scv-translator | true sends only the translation, dropping the original. Default false — a Salesforce transcript records what was actually said, and the translation is our annotation of it |
SCV_SERVICE_TOKEN |
connect-scv-translator | Service token accepted at /ws/orchestrator WebSocket upgrade |
SCV_BROWSER_SESSION_SECRET |
connect-scv-translator | HMAC secret for browser WS session tickets. Auto-generated per boot in Vanguard |
SCV_ALLOWED_ORIGINS |
connect-scv-translator | Comma-separated origins allowed to mint SCV browser sessions and open SCV WebSockets. Blank means same-origin only |
SCV_TRANSLATOR_CLIENT_PORT / SCV_TRANSLATOR_SERVER_PORT |
connect-scv-translator | Vanguard ports. Defaults 8101 (webpack-dev-server) and 3031 (Express). Not 8094 — that is mkdocs-developer |
SF_SCRT_INSTANCE_URL, ORG_ID, CALL_CENTER_NAME |
connect-scv-translator | Salesforce SCRT2 fallbacks. Normally unset — SCV posts all three at runtime to /api/configureTenantInfo, and SF_SCRT_INSTANCE_URL is only read under IS_LOCAL_CONFIG=true. There is no SCRT_BASE_URL (it was documented but never read) |
SCRT_PRIVATE_KEY / SCRT_PRIVATE_KEY_FILE |
connect-scv-translator | RS256 key signing the SCRT2 Bearer — inline PEM (\n escapes accepted) or a path; falls back to server/private.key. Its public half must be the certificate the Call Center was created with. Missing ⇒ every transcript / voiceCall write fails while calls and translation keep working |
SCV_TRANSLATION_ACTIVE_ATTRIBUTE |
connect-scv-translator | Connect contact attribute marked while translation runs, so the transcript gate knows to drop Contact Lens's parallel segments. Default TrueServeTranslationActive — must match the gate lambda's TRANSLATION_ACTIVE_ATTRIBUTE, and a mismatch silently restores duplicate transcripts |
SCV_TRANSCRIPT_ANALYSIS_BUCKET |
connect-scv-translator | S3 bucket for the Contact-Lens-shaped post-call analysis document a translated call publishes at call end — normally the Connect instance's own storage bucket. Unset disables publication entirely — the shipped default. Needs s3:PutObject |
SCV_TRANSCRIPT_ANALYSIS_PREFIX |
connect-scv-translator | Key prefix for that document. Default Translations/Voice, deliberately not Connect's Analysis/Voice: the key is {prefix}/{YYYY}/{MM}/{DD}/{contactId}_translated_{ISO8601Z}.json, so both the prefix and the filename infix differ from real Contact Lens output while the date/timestamp convention matches |
SCV_TRANSCRIPT_ANALYSIS_REGION |
connect-scv-translator | Region of that bucket. Falls back to AWS_REGION. Its own fact: the process, the Connect instance, and the bucket can all sit in different regions, and PutObject to the wrong one fails PermanentRedirect, losing the document |
AWS_CONNECT_INSTANCE_ID |
connect-scv-translator | Connect instance for contact-attribute writes (falls back to AWS_CONNECT_INSTANCE_ARN, then CONNECT_INSTANCE_ID); also stamped into the analysis document's CustomerMetadata.InstanceId |
CONNECT_REGION |
connect-scv-translator | The instance's region — configures the CCP embed and the server-side control-plane client (contact attributes). Falls back to AWS_CONNECT_REGION, then AWS_REGION. A process running elsewhere sends UpdateContactAttributes to a region where the contact doesn't exist, and because that write is best-effort the only symptom is duplicate transcripts |
The browser-aws / browser-direct demo translation modes additionally read COGNITO_*, AWS_REGION, DEEPGRAM_API_KEY, OPENAI_API_KEY, ELEVENLABS_API_KEY, and GOOGLE_APPLICATION_CREDENTIALS. The production orchestrator-grpc path needs none of them — vendor credentials stay server-side in ai-orchestrator. See connect-scv-translator.
scv-transcript-gate lambda¶
Deployed into the customer's AWS account, not Vanguard. Its auth is deliberately separate from the connector's — different integration, different credentials.
| Var | Purpose |
|---|---|
DOWNSTREAM_FUNCTION_ARN |
Salesforce's untouched Contact Lens consumer, re-invoked for allowed records (required) |
CONNECT_INSTANCE_ID |
Connect instance the contact attribute is read from (required) |
TRANSLATION_ACTIVE_ATTRIBUTE |
Attribute name. Default TrueServeTranslationActive; must match the connector's SCV_TRANSLATION_ACTIVE_ATTRIBUTE |
ATTRIBUTE_CACHE_TTL_SECONDS |
Per-contact decision cache. Default 30 |
MAX_DOWNSTREAM_BATCH |
Records per downstream invoke. Default 5 — not a tuning knob: the multiorg consumer bails out and processes nothing when handed more than 5 |
DRY_RUN |
true logs decisions and forwards everything. Use it to validate before disabling the CloudFormation event-source mapping |
See scv-transcript-gate.
Krisp VIVA and Voice Translation¶
Voice isolation runs by default for every voice agent. The image packages both isolation variants plus the optional VAD/turn/IP models; Agent Studio can turn isolation off per node or opt into the other Krisp features independently. The SDK uses one process-global license and requires HTTPS egress to sdkapi.krisp.ai and analytics.krisp.ai.
| Var | Used by | Purpose |
|---|---|---|
KRISP_VIVA_DEFAULT_ENABLED |
ai-orchestrator | Default true. Enables isolation for voice agents with no explicit setting. Set false only as an operational rollback; explicit Krisp selections still apply |
KRISP_VIVA_API_KEY |
ai-orchestrator | Process-global Krisp UAR license key. Required for the default-on runtime; inject from a Kubernetes Secret, never the image |
KRISP_VIVA_API_KEY_FILE |
Vanguard launcher | Local-only path to the ignored key file. Defaults to secret/KrispApiKey.txt; the launcher reads it into KRISP_VIVA_API_KEY without printing it |
KRISP_VIVA_FILTER_TELEPHONY_MODEL_PATH |
ai-orchestrator | Isolation model for pipeline audio ≤16 kHz. Image default: krisp-viva-vi-tel-v2.1.kef |
KRISP_VIVA_FILTER_WIDEBAND_MODEL_PATH |
ai-orchestrator | Isolation model for pipeline audio >16 kHz. Image default: krisp-viva-vi-pro-v1.kef |
KRISP_VIVA_FILTER_MODEL_PATH |
ai-orchestrator | Optional compatibility override that forces one isolation model at every sample rate |
KRISP_VIVA_TURN_MODEL_PATH |
ai-orchestrator | Turn detection model path for Krisp VIVA turn analyzer |
KRISP_VIVA_IP_MODEL_PATH |
ai-orchestrator | Interruption prediction model path for Krisp VIVA user-start strategy. The supplied IP v1.1 model is English-only |
KRISP_VT_API_KEY |
ai-orchestrator, ai-manager discovery | Server-side key used to mint short-lived Voice Translation session tokens and discover languages. Encrypted Krisp integration profiles take precedence; local dev defaults this to the ignored VIVA key |
The image installs krisp_voice_translation==1.0.0 beside
krisp_audio==1.11.0. Do not install the native RTC
krisp_audio==1.8.0 archive into ai-orchestrator because it owns the same
Python package name. A future native RTC fallback must be an isolated service.
SCV Krisp browser RTC¶
| Var | Used by | Purpose |
|---|---|---|
SCV_KRISP_RTC_ENABLED |
connect-scv-translator | Master kill switch; default true |
SCV_KRISP_RTC_ROLLOUT_PERCENTAGE |
connect-scv-translator | Deterministic agent-hash rollout from 0 to 100; default 100 |
SCV_KRISP_OUTBOUND_NC_DEFAULT / SCV_KRISP_INBOUND_NC_DEFAULT |
connect-scv-translator | Organization NC defaults; both default true |
SCV_KRISP_OUTBOUND_BVC_DEFAULT |
connect-scv-translator | Organization outbound BVC auto default; default true |
SCV_KRISP_OUTBOUND_ACCENT_DEFAULT / SCV_KRISP_INBOUND_ACCENT_DEFAULT |
connect-scv-translator | Accent Conversion defaults; both default false |
SCV_KRISP_ALLOW_OUTBOUND_NC_OVERRIDE / SCV_KRISP_ALLOW_OUTBOUND_BVC_OVERRIDE / SCV_KRISP_ALLOW_OUTBOUND_ACCENT_OVERRIDE |
connect-scv-translator | Allow the matching agent-microphone override; default true |
SCV_KRISP_ALLOW_INBOUND_NC_OVERRIDE / SCV_KRISP_ALLOW_INBOUND_ACCENT_OVERRIDE |
connect-scv-translator | Allow the matching customer-audio override; default true |
KRISP_RTC_ASSET_DIR |
connect-scv-translator | Optional extracted browser asset root; defaults to runtime/krisp |
KRISP_VIVA_VAD_MODEL_PATH |
ai-orchestrator | Voice activity detection model path for vad_provider=krisp_viva |
KRISP_VIVA_SOURCE_DIR / KRISP_VIVA_RUNTIME_DIR |
Vanguard setup | Vendor archive input and generated runtime output. Defaults: repository krisp/ and ignored .local-data/krisp/ |
Google Antigravity runner¶
| Var | Used by | Purpose |
|---|---|---|
ANTIGRAVITY_RUNNER_PORT |
antigravity-runner | Local HTTP port. Default 8011 |
ANTIGRAVITY_RUNNER_FAKE |
antigravity-runner | Local/test mode that streams deterministic fake Antigravity events without requiring the preview SDK wheel or Google credentials |
ANTIGRAVITY_RUNNER_USE_DOCKER |
antigravity-runner | Local real-SDK launcher mode. Default true so the preview SDK runs in the Docker image with a compatible glibc |
ANTIGRAVITY_RUNNER_DOCKER_CONFIG |
local antigravity-runner launcher | Optional Docker configuration directory for public image builds only, matching the workspace runner option. |
ANTIGRAVITY_RUNNER_WORKSPACE_DIR |
antigravity-runner | Parent directory for per-chat ephemeral workspaces |
ANTIGRAVITY_RUNNER_EGRESS_PROXY |
antigravity-runner | Optional forward proxy for sandbox egress allowlisting |
Workspace Assistant Agent runner¶
| Var | Used by | Purpose |
|---|---|---|
WORKSPACE_AGENT_RUNNER_PORT |
workspace-agent-runner | Local HTTP port. Default 8012 |
WORKSPACE_AGENT_RUNNER_FAKE |
workspace-agent-runner | Local/test mode that streams deterministic fake Codex/Claude events without requiring either CLI |
WORKSPACE_AGENT_RUNNER_USE_DOCKER |
workspace-agent-runner | Local launcher mode. Defaults to true so the runner uses its Python 3.13 Docker image with bundled Codex and Claude Code CLIs |
WORKSPACE_AGENT_RUNNER_WORKSPACE_DIR |
workspace-agent-runner | Parent directory for per-turn ephemeral workspaces |
WORKSPACE_AGENT_RUNNER_CODEX_BIN |
workspace-agent-runner | Codex CLI binary name/path |
WORKSPACE_AGENT_RUNNER_CLAUDE_BIN |
workspace-agent-runner | Claude Code CLI binary name/path |
CODEX_API_KEY / OPENAI_API_KEY |
workspace-agent-runner | Codex CLI credentials when not supplied by the Assistant Agent stage |
ANTHROPIC_API_KEY |
workspace-agent-runner | Native Anthropic Claude Code credentials when not supplied by the Assistant Agent stage |
AWS_BEARER_TOKEN_BEDROCK |
ai-orchestrator, workspace-agent-runner | Optional Bedrock bearer-token fallback when no selected tenant integration supplies bedrock_api_key |
AZURE_OPENAI_API_KEY |
ai-orchestrator, async-agent | Optional Azure OpenAI key fallback; tenant Microsoft integrations normally supply openai_api_key |
AZURE_OPENAI_ENDPOINT |
ai-orchestrator, async-agent | Optional Azure resource-endpoint fallback; normally stored on the tenant Microsoft integration |
AZURE_OPENAI_API_VERSION |
ai-orchestrator, async-agent | Optional Azure API-version override; service defaults apply when unset |
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN / AWS_REGION |
workspace-agent-runner | AWS credential-chain fallback for Claude Code on Bedrock |
GOOGLE_APPLICATION_CREDENTIALS / ANTHROPIC_VERTEX_PROJECT_ID / CLOUD_ML_REGION |
workspace-agent-runner | Google Vertex fallback for Claude Code when no selected Google integration supplies them |
Code export¶
| Var | Used by | Purpose |
|---|---|---|
ENABLE_STRANDS_EXPORT / NEXT_PUBLIC_ENABLE_STRANDS_EXPORT |
ai-manager | Enable the Strands agent code-package export (format=strands + editor menu item). Default off — see docs/04-processes/agent-code-export.md |
ENABLE_CODE_EXPORT / NEXT_PUBLIC_ENABLE_CODE_EXPORT |
ai-manager | Enable the Genkit + ADK agent exports and the LangGraph workflow export (format=genkit\|adk\|langgraph + menu items). Default off — see agent-code-export.md + workflow-code-export.md |
Generate with AI¶
| Var | Used by | Purpose |
|---|---|---|
NEXT_PUBLIC_FEATURE_AI_GENERATION |
ai-manager | Deployment flag for "Generate with AI" (default off). Tenant setting + active runner integration are also required — see docs/04-processes/ai-generation.md |
FEATURE_CONVERSATIONAL_DESIGN |
ai-manager | Runtime-only, default off. Shows the live Design with AI workspace, with direct /studio routes gated too. Local deployments opt in through .env.local; restart ai-manager after changes. Starting a design also requires AI-generation flags, an enabled tenant AI connection, designer migrations and workspace-agent-runner. Only dev:prototype exports use scripted responses. See Studio rollout. |
WORKSPACE_AGENT_RUNNER_DOCKER_CONFIG |
local workspace-agent-runner launcher | Optional Docker configuration directory for image builds only. Use the absolute .devcontainer/docker-public path when a host credential helper prevents pulling public build dependencies. |
GENERATION_AI_MANAGER_URL |
ai-manager | Base URL workspace-agent-runner uses to reach ai-manager (generation MCP + runner-event callbacks). Containerized runner: http://host.docker.internal:3001; host mode: http://localhost:3001. Falls back to AI_MANAGER_INTERNAL_URL |
GENERATION_WALL_MS |
workspace-agent-runner | Per-generation-run wall clock. Default 1800000 (30 min) |
GENERATION_CONCURRENCY |
workspace-agent-runner | Concurrent generation-run cap. Default 2 |
GENERATION_DOCS_DIR |
workspace-agent-runner | Path to the built generation-docs bundle (shared/generation-docs/dist) seeded into each workspace |
GENERATION_WORKSPACE_TTL_SECONDS |
workspace-agent-runner | TTL for awaiting-answers generation workspaces. Default 86400 (24 h) |
GENERATION_MODEL_BEDROCK / GENERATION_SMALL_MODEL_BEDROCK |
ai-manager | Override the generator CLI's main/small model when the runner integration is AWS Bedrock. Defaults: global.anthropic.claude-opus-4-8 / global.anthropic.claude-haiku-4-5-20251001-v1:0 |
GENERATION_MODEL_ANTHROPIC / GENERATION_SMALL_MODEL_ANTHROPIC |
ai-manager | Same, for a native Anthropic integration. Defaults: claude-opus-4-8 / claude-haiku-4-5-20251001 |
GENERATION_MODEL_VERTEX / GENERATION_SMALL_MODEL_VERTEX |
ai-manager | Same, for a Google Vertex integration. Defaults: claude-opus-4-8@20251101 / claude-haiku-4-5@20251001 |
GENERATION_MODEL_OPENAI / GENERATION_SMALL_MODEL_OPENAI |
ai-manager | OpenAI authoring model / Activity Log summary and public-research model. Defaults: gpt-6-astra / gpt-4.1-mini. The selected OpenAI integration supplies the API key and base URL; these do not change generated agent runtime models. See OpenAI authoring. |
GENERATION_REASONING_EFFORT_OPENAI |
ai-manager | OpenAI authoring reasoning effort, default low for the benchmark-selected Astra setup. Applies to new generation/Studio/editor sessions. Explicit per-job experiment settings override it; existing managed sessions retain their saved settings. |
GENERATION_LIBRARY_TOKEN_FILE |
ai-manager | Optional private file containing the TrueServe Library token (raw token or Bearer prefix). Used only by the server to read https://gallery.trueserve.deloitte.com/api/mcp; never sent to the model or runner. Missing configuration disables Library research without blocking local discovery. |
GENERATION_LIBRARY_READ_TOOLS |
ai-manager | Comma-separated reviewed read operations for a Library server without read-only annotations. Current Gallery: search_gallery,get_content. Write names and destructive annotations remain rejected. |
AUDIT_LOG_SUMMARY_PROMPT |
ai-manager | Optional deployment-wide prompt override for Activity Log change summaries. Used only when AI Generation / Editor Assistant availability is true; tenant JSON override also works via tenant_settings key audit_log_summary with {"prompt": "..."} |
ASSISTANT_TURN_WALL_MS |
ai-manager + workspace-agent-runner | Editor/designer per-turn wall clock, including Build draft. Default 1800000 (30 min). Set identically on both services; the designer lease and internal stream idle timeout allow an extra minute. |
ASSISTANT_CONCURRENCY |
workspace-agent-runner | Concurrent assistant-turn cap. Default 2 |
ASSISTANT_WORKSPACE_TTL_SECONDS |
workspace-agent-runner | Idle TTL for assistant workspaces (runner-side; the DB session outlives it — a swept workspace recovers transparently). Default 86400 (24 h) |
ASSISTANT_SESSION_TTL_DAYS |
ai-manager | Editor-assistant session TTL (sliding, bumped per turn). Default 7 |
ASSISTANT_SESSION_SWEEPER |
ai-manager | Set 0 to disable the hourly expired-session sweep |
MANAGEMENT_A2A_TASK_SWEEPER |
ai-manager | Set 0 to disable hourly deletion of expired seven-day A2A tasks and ordered replay events |
Service authentication¶
| Var | Used by | Purpose |
|---|---|---|
ASYNC_AGENT_API_TOKEN |
ai-manager, ai-orchestrator, conversation-api, agent-host | Tenant-scoped tsf_ API token used for server-to-server calls into async-agent, and as agent-host's local/dev fallback when CONVERSATION_API_TOKEN is unset. On conversation-api it is what makes real SMS possible at all — both link senders (Customer Authentication and the multimodal A2UI handshake) call async-agent's POST /api/v1/sms/send, and their caller is the orchestrator's HMAC-stamped request, which carries no bearer to forward; without this token both refuse with an error naming it. Common local workflow/tool/config paths need workflows:manage, tools:manage, configuration:manage, and agents:manage. Must be minted per environment; do not use a committed placeholder |
ASYNC_AGENT_CORS_ALLOWED_ORIGINS |
async-agent | Comma-separated browser origins allowed on credentialed async-agent HTTP routes. Defaults to localhost dev origins; do not use wildcard credentialed CORS |
CONVERSATION_API_TOKEN |
agent-host | Tenant-scoped tsf_ bearer for agent-host calls into conversation-api routes that require require_api_token, including inject_message_to_conversation → /conversations/{id}/inject. Falls back to ASYNC_AGENT_API_TOKEN when unset; inject_message_to_voice is a deprecated MCP alias |
MCP_ALLOW_QUERY_TOKEN_AUTH |
agent-host | Compatibility flag for MCP clients that cannot set auth headers. Default false; prefer Authorization: Bearer tsf_* because query-string tokens are commonly logged |
Payments (PCI)¶
payment-vault is the only component that ever sees a card number. See payment-vault and Payments (PCI).
There is no deployment-wide payments feature flag: the capability is gated per tenant (the payments tenant_settings key, an active payments integration, and a resolvable vault URL), and the Helm subchart is gated separately by payment-vault.enabled.
Read by payment-vault:
| Var | Used by | Purpose |
|---|---|---|
PAYMENT_VAULT_HOST / PAYMENT_VAULT_PORT |
payment-vault | Listen address. Defaults 0.0.0.0 / 3530 |
PAYMENT_VAULT_PUBLIC_URL |
payment-vault, ai-manager | Browser-facing origin the hosted-fields frame URL is built from. Empty means no frame is offered — a legitimate voice-DTMF-only deployment, not a misconfiguration (the session still opens and frame_url comes back empty). A tenant's vault_public_url setting overrides this platform default |
PAYMENT_VAULT_INTERNAL_TOKEN |
payment-vault, conversation-api | Bearer for the vault's /internal/* routes. Without a strong token the vault refuses every internal request — "not configured" resolves to closed, and the lifespan logs an error because the only upstream symptom is a 401. INTERNAL_SERVICE_TOKEN is accepted as a fallback. Generate with openssl rand -hex 32 |
PAYMENT_VAULT_FRAME_TOKEN_SECRET |
payment-vault | Signs the short-lived token in the frame URL. Separate from the internal token because it travels in a URL a browser holds, so the two rotate on different schedules. Unset means the frame cannot be minted, never minted unsigned |
PAYMENT_VAULT_ALLOWED_FRAME_ANCESTORS |
payment-vault | Comma-separated origins for the frame page's CSP frame-ancestors. Empty renders 'none', the right default for a page whose only purpose is to be framed by exactly one known origin |
PAYMENT_VAULT_SESSION_TTL_SECONDS |
payment-vault | How long a capture session may live. Default 300. A security control, not a UX knob — it bounds how long a PAN can be held if every other mechanism fails, so being generous to a slow caller widens exactly that window |
PAYMENT_VAULT_MAX_LIVE_SESSIONS |
payment-vault | Concurrent capture cap. Default 500. Bounds memory and, more to the point, how much cardholder data one compromised process can hold at once |
PAYMENT_VAULT_SWEEP_INTERVAL_SECONDS |
payment-vault | TTL sweeper period. Default 15 |
DATABASE_URL |
payment-vault | Should name a restricted, SELECT-only role. The vault reads integrations/integration_secrets and writes nothing; tsf_app (BYPASSRLS) works and is worse for no benefit |
MASTER_ENCRYPTION_KEY |
payment-vault | Decrypts the provider credential. Note the AES key is the SHA-256 digest of this value, matching ai-manager's Node implementation — see secret storage |
PAYMENT_VAULT_CREDENTIAL_CACHE_SECONDS |
payment-vault | Credential cache TTL. Default 60, so a rotation lands within a minute with no restart |
PAYMENT_VAULT_PROVIDER_TIMEOUT_SECONDS |
payment-vault | Per-provider-call timeout. Default 20. Never "wait forever" |
PAYMENT_VAULT_ADAPTER |
payment-vault | auto (resolve from the integration row's provider) or fake (in-process test double). Default auto. The Vanguard start script defaults it to fake locally because dev has no Stripe credentials |
PAYMENT_VAULT_ALLOW_FAKE_PROVIDER |
payment-vault | Second gate the fake needs — PAYMENT_VAULT_ADAPTER=fake alone is refused. Default false, and the chart keeps it false so a stray adapter setting in a deployed environment cannot quietly stop charging anybody |
LOG_LEVEL |
payment-vault | Default INFO. Every record passes through log_guard.py regardless of level |
Read by conversation-api and ai-orchestrator — the same three vars, two callers, two different legs. conversation-api opens, finalizes and cancels sessions and asks for refunds and status; ai-orchestrator's PaymentModeController streams the captured keypad fields in. That second leg goes straight to the vault and never through conversation-api, whose PaymentVaultClient deliberately has no set_field/finalize so a PAN can never transit that process. Set them in both or in neither: with either value missing the controller refuses to begin a capture (and logs why) rather than opening one with nowhere to put the digits.
| Var | Used by | Purpose |
|---|---|---|
PAYMENT_VAULT_URL |
conversation-api, ai-orchestrator | Base URL of the vault. Unset is a supported state: capture paths answer 503 payments_not_configured while status and audit reads (pure SQL) keep working |
PAYMENT_VAULT_INTERNAL_TOKEN |
conversation-api, ai-orchestrator | Bearer for the vault's internal API. Set but with no token ⇒ payments are refused, and the caller logs it. INTERNAL_SERVICE_TOKEN is accepted as a fallback in both |
PAYMENT_VAULT_TLS_VERIFY |
conversation-api, ai-orchestrator | Default true. Turn off only for a vault behind a self-signed cert in local dev — this is the leg that carries a card number |
Microsoft Teams custom agents¶
| Var | Used by | Purpose |
|---|---|---|
NEXT_PUBLIC_FEATURE_TEAMS / FEATURE_TEAMS |
ai-manager, teams-agent-gateway | Enables Microsoft Teams custom-agent exposure (default off). NEXT_PUBLIC_FEATURE_TEAMS shows the agent Settings panel at build time; FEATURE_TEAMS gates ai-manager Teams API routes and Teams gateway callbacks at runtime |
TEAMS_AGENT_GATEWAY_PORT |
teams-agent-gateway | HTTP port for Bot Framework callbacks. Local default 3521 to avoid the local multimodal-service port; the Helm chart sets 3520 explicitly |
TEAMS_ASSISTANT_TIMEOUT_MS |
teams-agent-gateway | Max milliseconds to wait for final assistant text before sending the deterministic fallback. Default 45000 |
TEAMS_GATEWAY_SKIP_BOT_AUTH |
teams-agent-gateway | Local-only bypass for Bot Framework bearer validation. Do not set in shared dev or production |
UI feature flags¶
| Var | Used by | Purpose |
|---|---|---|
NEXT_PUBLIC_FEATURE_AVATAR |
ai-manager | Shows the Avatar settings card (voice agents) and the tester's avatar-view toggle (default off). A saved settings.avatar config keeps working at runtime; only the UI affordance hides |
NEXT_PUBLIC_FEATURE_REAL_SMS_TESTING |
ai-manager | Shows SMS mode in full-screen Agent Preview (default off). The flag is baked at build time. When a tester enables the mode, Preview requires an ANI and sends all capability texts through real_sms to that number while retaining browser-emulated audio |
NEXT_PUBLIC_FEATURE_PLATFORM_ADMIN / FEATURE_PLATFORM_ADMIN |
ai-manager | Platform Admin console (super-admin only) — tenants, users, memberships/roles, platform super-admins, from the profile dropdown. Default on (it replaces the previously always-on platform-admin tenant management). NEXT_PUBLIC_* gates the /admin nav + pages at build time; FEATURE_* gates the /api/admin/* routes at runtime. Set both false as a kill-switch. See ai-manager |
Tuning¶
| Var | Set by | Purpose |
|---|---|---|
AI_ORCHESTRATOR_WARM_SMART_TURN |
ai-orchestrator | Pre-load the local smart-turn ONNX model at boot (background, after the gRPC port is SERVING) so the first cascaded STT→LLM→TTS call doesn't pay the ~12 s cold import. Default on; set 0 to revert to lazy load. See universal-pipeline-builder.md |
Telemetry¶
Everything is generic OTLP (endpoint + protocol + headers) split into two
streams: infra (HTTP/API/worker spans) on OTEL_EXPORTER_OTLP_* and AI
(LLM/STT/TTS/S2S/session spans) on OTEL_AI_EXPORTER_OTLP_*. When the AI
endpoint is unset, AI spans fall back to the infra destination. Phoenix and
LangFuse are plain OTLP destinations — recipes in
observability.md.
| Var | Used by | Purpose |
|---|---|---|
ENABLE_TRACING / ENABLE_OTEL |
ai-orchestrator, async-agent | Enable OpenTelemetry. Setting OTEL_EXPORTER_OTLP_ENDPOINT or OTEL_AI_EXPORTER_OTLP_ENDPOINT also enables tracing unless OTEL_SDK_DISABLED=true |
OTEL_BATCH_EXPORT |
ai-orchestrator, async-agent | Batch span export off realtime model/audio and HTTP request paths. Defaults to true; set false only for targeted synchronous-export debugging. |
OTEL_EXPORTER_OTLP_ENDPOINT / _TRACES_ENDPOINT |
ai-orchestrator, async-agent, ai-manager | Infra-stream OTLP destination |
OTEL_EXPORTER_OTLP_PROTOCOL |
ai-orchestrator, async-agent | grpc or http/protobuf (infra stream) |
OTEL_EXPORTER_OTLP_HEADERS |
ai-orchestrator, async-agent | Infra-stream auth headers such as Authorization=Bearer ... |
OTEL_AI_EXPORTER_OTLP_ENDPOINT |
ai-orchestrator, async-agent, ai-manager | AI-stream OTLP destination (LangFuse/Phoenix/collector). Unset = AI spans go to the infra destination |
OTEL_AI_EXPORTER_OTLP_PROTOCOL |
ai-orchestrator, async-agent, ai-manager | grpc or http/protobuf (AI stream; default http/protobuf) |
OTEL_AI_EXPORTER_OTLP_HEADERS |
ai-orchestrator, async-agent, ai-manager | AI-stream auth headers, e.g. LangFuse Authorization=Basic <base64(pk:sk)> |
OTEL_AI_PROJECT_NAME |
ai-orchestrator, async-agent, ai-manager | Sets openinference.project.name resource attribute (default conversations) |
OTEL_AI_TENANT_PROJECT_TEMPLATE |
ai-orchestrator, async-agent | Optional, e.g. conversations-{tenant_id} — rewrites the project name per span at the system AI destination so tenants land in separate projects |
OTEL_AI_EXPORTER_ENABLED |
ai-orchestrator, async-agent, ai-manager | Default true; false drops the AI stream at system level (tenant destinations unaffected) |
TENANT_TELEMETRY_ENABLED |
ai-orchestrator, async-agent | Default true; false disables DB-driven per-tenant AI-span routing |
TENANT_TELEMETRY_CACHE_TTL |
ai-orchestrator, async-agent | Tenant telemetry config cache TTL in seconds (default 60) — the "takes effect within" window |
OTEL_RESOURCE_ATTRIBUTES |
ai-orchestrator, async-agent | Standard resource attributes |
AI_MANAGER_ENABLE_OTEL |
ai-manager | Master gate for ai-manager tracing (dual-stream: its LLM/usage spans route to the AI destination, Next.js request spans to infra). |
CONVERSATION_API_ENABLE_OTEL |
conversation-api | Debug-only conversation-api tracing. Leave unset for conversation telemetry; enabling it exports REST/SSE request spans. |
Removed (startup ERROR if set): OTEL_BACKEND, PHOENIX_COLLECTOR_ENDPOINT,
PHOENIX_PROJECT_NAME, PHOENIX_PROTOCOL, ARIZE_PHOENIX_PROJECT,
LANGFUSE_HOST, LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY. Migration:
Phoenix → OTEL_AI_EXPORTER_OTLP_ENDPOINT + OTEL_AI_EXPORTER_OTLP_PROTOCOL=grpc
+ OTEL_AI_PROJECT_NAME; LangFuse → endpoint <host>/api/public/otel +
OTEL_AI_EXPORTER_OTLP_HEADERS=Authorization=Basic <base64(pk:sk)>.
ai-orchestrator enriches conversation spans from the selected agent config,
including agent.*, pipeline.*, llm.provider, llm.model_name,
gen_ai.system, and gen_ai.request.model. Hosted model ARNs are normalized
to the underlying model family and preserve the hosting layer as
llm.host_provider. ai-orchestrator also emits service-level usage spans for
LLM, STT, TTS, translation, realtime/S2S, and utility processors, plus direct
token-bearing spans for custom OpenAI/Gemini/Vertex/Bedrock processor calls
such as LLM translation, form filling, transcript enhancement, suggestions,
and subagents. These spans include token, character, audio-duration, and
transcript-count dimensions when available. Token-bearing spans include both gen_ai.usage.* and
input_tokens/output_tokens/prompt_tokens/completion_tokens aliases for
Phoenix cost rollups. async-agent adds the same provider/model conventions to
workflow LLM node spans and concrete LangChain LLM-call spans. LLM request
spans include span.type=llm_request, success, duration_ms, flattened
token counts, cache token counts, and finish reasons when available.
All AI spans additionally carry tenant.id and telemetry.stream=ai — the
keys used for stream classification, collector-side routing, per-tenant
project stamping, and tenant-level telemetry routing (see
observability.md).
Vanguard-specific¶
| Var | Purpose |
|---|---|
TSF_CATALOG_WORKSPACES |
Host path mounted into code-server |
PUBLIC_IP |
rtpengine GA dual-interface |
LAN_IP |
rtpengine GA dual-interface |
City EC2 required public env¶
City boxes must set these in .env.local because code updates do not touch gitignored env files. city-update.sh <city> --step env is the source of truth and writes the values shown here.
| Var | Required value pattern |
|---|---|
DEV_ENV |
ec2 |
PUBLIC_FQDN / PUBLIC_HOSTNAME |
<city>.trueserve.ai |
PUBLIC_IP, HOST_IP, LOCAL_IP, ASTERISK_LAN_IP |
EC2 public or private IPs for media/nginx templates |
GENESYS_BYOC_FQDN |
Per-city Genesys BYOC trunk FQDN |
JANUS_WS_URL / NEXT_PUBLIC_JANUS_WS_URL |
wss://janus.<city>.trueserve.ai/ws |
TURN_SERVER / NEXT_PUBLIC_TURN_SERVER |
turn.<city>.trueserve.ai |
TURN_PORT / TURN_TYPE |
3478 / tcp |
FORCE_TURN_ONLY / NEXT_PUBLIC_FORCE_TURN_ONLY |
true |
ALLOW_STATIC_TURN_CREDENTIALS |
true for local dev Node servers |
NEXT_PUBLIC_SURFACE_APP_URL, SURFACE_APP_URL, SURFACE_APP_BASE_URL |
https://surface-app.<city>.trueserve.ai |
CONVERSATION_API_PUBLIC_URL |
https://conversation-api.<city>.trueserve.ai |
CES_MCP_BASE_URL / AGENT_HOST_MCP_PUBLIC_URL |
https://tools.<city>.trueserve.ai/mcp |
CODE_SERVER_URL |
https://code.<city>.trueserve.ai |
WHISKER_PUBLIC_WS_URL |
wss://code.<city>.trueserve.ai/whisker-ws |
See also¶
- Secret storage
- Secrets management
- Cloud-managed swap
.devcontainer/env.local.template— full Vanguard env template
Optional Scene and Analytics agents¶
| Var | Used by | Purpose |
|---|---|---|
FEATURE_SCENE_AGENTS |
ai-manager | Runtime-only opt-in for Scene creation, filters, saved agents, Director pages/APIs and exports. Defaults off; also requires the parent Agents feature |
FEATURE_ANALYTICS_AGENTS |
ai-manager, Analytics worker | Runtime-only opt-in for Analytics creation, filters, saved agents, editor/API routes and preparation. Defaults off; also requires the parent Agents feature |
NEXT_PUBLIC_FEATURE_ANALYTICS_AGENTS |
Legacy only | Ignored. Set the runtime flag in each destination environment; a build-time value cannot enable Analytics |
ANALYTICS_WORKER_CONCURRENCY |
Analytics worker | Concurrent leased jobs, 1–16; default 4, Vanguard testing uses 16 |
ANALYTICS_PYTHON |
Analytics worker | Python executable with shared PII/transcription/provider dependencies; dev launcher defaults to apps/async-agent/.venv/bin/python |
The server passes both optional-agent flags to Studio, so runtime configuration
controls the UI and API together. Restart the affected process after changing a
flag; no frontend rebuild is required. Checked-in examples keep both false.
Vanguard's local opt-ins belong only in its gitignored .env.local.
Sources use the normal assets-store and managed encryption settings. Provider credentials resolve from the tenant's integrations. See Analytics preparation and migration.
Agent evaluation¶
SIMULATION_WORKER_ROLE, SIMULATION_WORKER_CONCURRENCY,
SIMULATION_WORKER_AUDIO_CONCURRENCY, SIMULATION_GLOBAL_ACTIVE,
SIMULATION_ORCHESTRATOR_ADDRESSES, SIMULATION_CALLER_MODEL,
SIMULATION_JUDGE_MODEL, SIMULATION_TTS_MODEL, SIMULATION_TTS_VOICE and
SIMULATION_AUTHOR_MODEL configure the durable Performance workers.
ORCHESTRATOR_MAX_SESSIONS and ORCHESTRATOR_DRAIN_FILE control runtime admission.
See worker operation and defaults.
Local orchestrator readiness¶
Overmind defaults AI_ORCHESTRATOR_HTTP_PORT to 8099 and derives
ORCHESTRATOR_HTTP_URL=http://localhost:${AI_ORCHESTRATOR_HTTP_PORT} unless
explicitly configured. AI Manager uses this URL for real agent readiness checks.
Its application-level fallback is the cluster URL http://ai-orchestrator:8080,
which is unsuitable for local host processes. Restart AI Manager after changing
this value; preserve the configured ORCHESTRATOR_HTTP_API_KEY where required.
Knowledge Management pilot¶
FEATURE_KNOWLEDGE_AGENTS defaults to false. Set it on Studio and the
Knowledge worker to enable native preparation, retrieval, evaluation and
publication. It is server-only and runtime checked. The worker uses the same
database, encryption and asset-storage settings as Studio. See
Knowledge Management.
KNOWLEDGE_WORKER_CONCURRENCY defaults to 2 and accepts integers from 1
to 4. Each slot owns a leased framework job; refresh scheduling runs
independently. Native RAGFlow extraction has its own concurrency settings.
Restart the knowledge worker to apply a slot-count change.