mirror of
https://github.com/THU-MAIC/OpenMAIC.git
synced 2026-10-28 16:35:27 +08:00
Google shuts down veo-3.1-generate-preview, veo-3.1-fast-generate-preview and veo-3.1-lite-generate-preview on 2026-10-22. They were the last models of the built-in Veo video provider (Veo 3.0 and 2.0 went in #1939), and the Veo adapter does not speak the API of Google's replacement, gemini-omni-1.1-flash. A catalog entry that cannot generate is worse than an absent one, so the provider is removed as Sora was: its catalog entry, type-union member, adapter, UI name and icon, VIDEO_VEO_* mapping, docs rows and tests. OpenRouter Video keeps google/veo-3.1, which OpenRouter serves from Vertex AI and is not part of this shutdown. Configurations written for earlier versions keep working. RETIRED_PRESETS names the removed preset: an openmaic.yml provider with preset: veo no longer stops the server, the slots that named such a provider (in the file or in workspace settings) follow their parents again, and startup notices ask to remove the provider and any VIDEO_VEO_* variables. Referencing the provider directly fails with the reason instead of "unknown preset". Supporting gemini-omni-1.1-flash is tracked in #1940. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
802 lines
36 KiB
Bash
802 lines
36 KiB
Bash
# =============================================================================
|
|
# OpenMAIC Environment Variables
|
|
# Copy this file to .env.local and fill in the values you need.
|
|
# DATABASE_URL is required, except under docker-compose.yml, which sets it for
|
|
# the bundled PostgreSQL (see "Persistence" below). Everything else is optional.
|
|
#
|
|
# Models are configured in openmaic.yml (copy openmaic.example.yml), which
|
|
# references the keys below as ${VAR}, or in the model settings of the web app.
|
|
# The provider variables in this file, server-providers.yml, DEFAULT_MODEL and
|
|
# MODEL_FALLBACK are the legacy configuration: they still work while there is
|
|
# no openmaic.yml and are deprecated. See the Configuration docs.
|
|
# =============================================================================
|
|
|
|
# --- Model configuration file ------------------------------------------------
|
|
# Path of the model configuration. Default: openmaic.yml in the directory the
|
|
# server starts in (the repository root; /app in the Docker image). When set,
|
|
# the file must exist. Read at startup; restart after changing it.
|
|
# OPENMAIC_CONFIG=openmaic.yml
|
|
|
|
# --- Instance secret ---------------------------------------------------------
|
|
# Encrypts provider keys saved in the web settings. When unset, one is created
|
|
# on first start in data/instance-secret.key (the Docker data volume). Keep it
|
|
# with the database: saved keys cannot be read without it. Set it explicitly
|
|
# when running more than one instance, when data/ does not survive a restart,
|
|
# or on a read-only filesystem, e.g. from `openssl rand -base64 32`. The server
|
|
# warns at startup when stored keys were sealed under a different secret.
|
|
# Instances that share a database also share one persistent data directory
|
|
# (data/, /app/data in the image): uploaded materials are stored there.
|
|
# OPENMAIC_SECRET_KEY=
|
|
|
|
# --- LLM Providers -----------------------------------------------------------
|
|
# Server-managed credentials authorize only the explicit *_MODELS list and deployment
|
|
# default/fallback or slot model references for that capability. Catalogue models are
|
|
# not implicitly authorized. Set *_MODELS for each provider, then restart the server.
|
|
# Users bringing their own credentials and keyless local providers are unaffected.
|
|
# A provider without a key is unrestricted: do not use one for a gateway that adds its
|
|
# own upstream credential; give the gateway a key and a *_MODELS list instead.
|
|
# Format: {PROVIDER}_API_KEY, {PROVIDER}_BASE_URL (optional), {PROVIDER}_MODELS (required for server-managed model selection, comma-separated)
|
|
# Legacy: without openmaic.yml these configure providers directly. With
|
|
# openmaic.yml they no longer configure providers on their own: reference them
|
|
# from the file as ${VAR} (for example apiKey: ${OPENAI_API_KEY}). The TTS,
|
|
# ASR, image, video, PDF and web search variables below work the same way.
|
|
|
|
OPENAI_API_KEY=
|
|
OPENAI_BASE_URL=
|
|
OPENAI_MODELS=
|
|
# For relays whose non-streaming Chat Completions response is incompatible.
|
|
# Forces custom OpenAI base URLs to use Chat Completions and buffers SSE responses.
|
|
# Has no effect on the official OpenAI base URL. Disabled by default.
|
|
# OPENAI_COMPAT_USE_STREAMING_CHAT=true
|
|
|
|
# Azure uses deployment names as model IDs.
|
|
AZURE_OPENAI_API_KEY=
|
|
AZURE_OPENAI_BASE_URL=https://YOUR-RESOURCE.openai.azure.com/openai
|
|
AZURE_OPENAI_MODELS=
|
|
|
|
ATLASCLOUD_API_KEY=
|
|
ATLASCLOUD_BASE_URL=https://api.atlascloud.ai/v1
|
|
# Example: qwen/qwen3.5-flash,deepseek-ai/deepseek-v4-pro
|
|
ATLASCLOUD_MODELS=
|
|
|
|
ANTHROPIC_API_KEY=
|
|
ANTHROPIC_BASE_URL=
|
|
ANTHROPIC_MODELS=
|
|
|
|
GOOGLE_API_KEY=
|
|
GOOGLE_BASE_URL=
|
|
GOOGLE_MODELS=
|
|
|
|
DEEPSEEK_API_KEY=
|
|
DEEPSEEK_BASE_URL=
|
|
# Example: deepseek-v4-pro,deepseek-flash
|
|
DEEPSEEK_MODELS=
|
|
# Chat and opted-in search share DEEPSEEK_API_KEY and DEEPSEEK_BASE_URL.
|
|
# Explicit webSearch slots or server-providers.yml web-search.deepseek also opt in.
|
|
# false force-disables DeepSeek search even for an explicit slot.
|
|
WEB_SEARCH_DEEPSEEK_ENABLED=
|
|
|
|
QWEN_API_KEY=
|
|
QWEN_BASE_URL=
|
|
QWEN_MODELS=
|
|
|
|
# Kimi chat and opted-in web search share these runtime credentials.
|
|
# Default: https://api.moonshot.cn/v1; international: https://api.moonshot.ai/v1.
|
|
# Coding Plan keys require https://api.kimi.com/coding/v1 (or api.kimi.ai/coding/v1).
|
|
KIMI_API_KEY=
|
|
KIMI_BASE_URL=
|
|
# Chat model pins; search has no model selector.
|
|
KIMI_MODELS=
|
|
# Optional runtime search opt-in; unset/false never activates search from chat credentials.
|
|
# Explicit webSearch slots or server-providers.yml web-search.kimi also opt in.
|
|
# false force-disables Kimi search even for an explicit slot.
|
|
WEB_SEARCH_KIMI_ENABLED=
|
|
|
|
MINIMAX_API_KEY=
|
|
# MiniMax Anthropic-compatible endpoint for the built-in Anthropic SDK integration
|
|
MINIMAX_BASE_URL=https://api.minimaxi.com/anthropic/v1
|
|
# Example: MiniMax-M2.7-highspeed,MiniMax-M2.7,MiniMax-M2.5-highspeed,MiniMax-M2.5
|
|
MINIMAX_MODELS=
|
|
|
|
GLM_API_KEY=
|
|
GLM_BASE_URL=
|
|
GLM_MODELS=
|
|
|
|
SILICONFLOW_API_KEY=
|
|
SILICONFLOW_BASE_URL=
|
|
SILICONFLOW_MODELS=
|
|
|
|
DOUBAO_API_KEY=
|
|
DOUBAO_BASE_URL=
|
|
DOUBAO_MODELS=
|
|
|
|
OPENROUTER_API_KEY=
|
|
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
|
|
# Example: deepseek/deepseek-v4-pro,deepseek/deepseek-v4-flash
|
|
OPENROUTER_MODELS=
|
|
|
|
GROK_API_KEY=
|
|
GROK_BASE_URL=
|
|
# Example: grok-4.6,grok-4.5
|
|
GROK_MODELS=
|
|
|
|
TENCENT_API_KEY=
|
|
# Tencent TokenHub OpenAI-compatible endpoint. Hy3 is a model ID, not an env prefix.
|
|
# TENCENT_HUNYUAN_* is also accepted as an alias.
|
|
TENCENT_BASE_URL=https://tokenhub.tencentmaas.com/v1
|
|
# Example: hy3
|
|
TENCENT_MODELS=
|
|
|
|
XIAOMI_API_KEY=
|
|
# MIMO_* is also accepted as an alias. Use tp-... keys only with Token Plan URLs.
|
|
XIAOMI_BASE_URL=https://api.xiaomimimo.com/v1
|
|
# Token Plan regional examples:
|
|
# XIAOMI_BASE_URL=https://token-plan-cn.xiaomimimo.com/v1
|
|
# XIAOMI_BASE_URL=https://token-plan-sgp.xiaomimimo.com/v1
|
|
# XIAOMI_BASE_URL=https://token-plan-ams.xiaomimimo.com/v1
|
|
# Example: mimo-v2.6-pro,mimo-v2.6-flash,mimo-v2.5-pro,mimo-v2.5
|
|
XIAOMI_MODELS=
|
|
|
|
TOKENDANCE_API_KEY=
|
|
# OpenAI-compatible gateway. The same key also works for the image, video, TTS
|
|
# and web-search routes on this host (see the README quick example).
|
|
TOKENDANCE_BASE_URL=https://tokendance.space/gateway/v1
|
|
# Example: deepseek-v4.1-flash,deepseek-v4-pro,glm-5.3,kimi-k3,qwen3.8-max
|
|
TOKENDANCE_MODELS=
|
|
|
|
# --- Ollama (Local Models) ---------------------------------------------------
|
|
# No API key needed. Configure BASE_URL here (server-side) so it bypasses SSRF
|
|
# protection automatically. Client-supplied localhost URLs are blocked in production.
|
|
# OLLAMA_BASE_URL=http://localhost:11434/v1
|
|
# OLLAMA_MODELS=llama3.3,llama3.2,qwen2.5,mistral,gemma3
|
|
|
|
# Lemonade local server (OpenAI-compatible, no API key required)
|
|
# LEMONADE_BASE_URL=http://localhost:13305/v1
|
|
# LEMONADE_MODELS=Qwen3-0.6B-GGUF,Llama-3.2-1B-Instruct-Hybrid,Qwen2.5-VL-7B-Instruct
|
|
|
|
# Amazon Bedrock LLMs (no OpenAI-style API key required)
|
|
# Set BEDROCK_REGION to enable Bedrock server-side provider config.
|
|
# AWS credentials are resolved from the standard AWS environment / credential chain.
|
|
# BEDROCK_REGION=us-east-1
|
|
# BEDROCK_MODELS=us.anthropic.claude-sonnet-5,us.anthropic.claude-opus-4-8
|
|
# Optional bearer-token authentication or custom Bedrock-compatible endpoint.
|
|
# AWS_BEARER_TOKEN_BEDROCK=
|
|
# BEDROCK_API_KEY=
|
|
# BEDROCK_BASE_URL=
|
|
# DEFAULT_MODEL=bedrock:us.anthropic.claude-sonnet-5
|
|
|
|
# --- TTS (Text-to-Speech) ----------------------------------------------------
|
|
|
|
TTS_OPENAI_API_KEY=
|
|
TTS_OPENAI_MODELS=
|
|
TTS_OPENAI_BASE_URL=
|
|
|
|
TTS_AZURE_API_KEY=
|
|
TTS_AZURE_MODELS=
|
|
TTS_AZURE_BASE_URL=
|
|
|
|
TTS_GLM_API_KEY=
|
|
TTS_GLM_MODELS=
|
|
TTS_GLM_BASE_URL=
|
|
|
|
TTS_QWEN_API_KEY=
|
|
TTS_QWEN_MODELS=
|
|
TTS_QWEN_BASE_URL=
|
|
# List the voice-clone target in TTS_QWEN_MODELS when using cloned voices.
|
|
# Qwen voice cloning reuses TTS_QWEN_API_KEY. Override the target model if needed.
|
|
# TTS_QWEN_VOICE_CLONE_MODEL=qwen3-tts-vc-2026-01-22
|
|
|
|
TTS_DOUBAO_API_KEY=
|
|
TTS_DOUBAO_MODELS=
|
|
TTS_DOUBAO_BASE_URL=
|
|
|
|
TTS_MINIMAX_API_KEY=
|
|
TTS_MINIMAX_MODELS=
|
|
# MiniMax TTS endpoint (speech-2.8 / 2.6 / 02 / 01 series)
|
|
TTS_MINIMAX_BASE_URL=https://api.minimaxi.com
|
|
TTS_ELEVENLABS_API_KEY=
|
|
TTS_ELEVENLABS_MODELS=
|
|
TTS_ELEVENLABS_BASE_URL=
|
|
|
|
# Google Gemini TTS (Interactions API). Reuse an AI Studio / Gemini API key.
|
|
TTS_GOOGLE_API_KEY=
|
|
TTS_GOOGLE_MODELS=
|
|
TTS_GOOGLE_BASE_URL=
|
|
|
|
# VoxCPM2 TTS (local, OpenAI-compatible; API key is optional)
|
|
# TTS_VOXCPM_API_KEY=
|
|
# TTS_VOXCPM_MODELS=
|
|
# TTS_VOXCPM_BASE_URL=http://localhost:8000/v1
|
|
|
|
# Lemonade TTS (local, no API key required)
|
|
# TTS_LEMONADE_BASE_URL=http://localhost:13305/v1
|
|
|
|
# Operators can force-disable any built-in TTS provider. Examples:
|
|
# TTS_OPENAI_ENABLED=false
|
|
# TTS_BROWSER_NATIVE_ENABLED=false
|
|
|
|
# --- ASR (Automatic Speech Recognition) --------------------------------------
|
|
|
|
ASR_OPENAI_API_KEY=
|
|
ASR_OPENAI_MODELS=
|
|
ASR_OPENAI_BASE_URL=
|
|
|
|
ASR_QWEN_API_KEY=
|
|
ASR_QWEN_MODELS=
|
|
ASR_QWEN_BASE_URL=
|
|
|
|
ASR_AZURE_API_KEY=
|
|
ASR_AZURE_MODELS=
|
|
ASR_AZURE_BASE_URL=https://{region}.api.cognitive.microsoft.com
|
|
|
|
# FunASR (local, WAV input only, no API key required)
|
|
# ASR_FUNASR_BASE_URL=http://localhost:8000/v1
|
|
|
|
# Lemonade ASR (local, WAV input only, no API key required)
|
|
# ASR_LEMONADE_BASE_URL=http://localhost:13305/v1
|
|
|
|
# Operators can force-disable any built-in ASR provider. Examples:
|
|
# ASR_OPENAI_ENABLED=false
|
|
# ASR_BROWSER_NATIVE_ENABLED=false
|
|
|
|
# Optional local audio/video material extraction uses the first enabled server
|
|
# ASR provider above. It also requires the system `ffmpeg` and `ffprobe`
|
|
# executables on PATH; no bundled binary or npm dependency is installed.
|
|
# Without both executables, OpenMAIC skips the local extractor and uses a
|
|
# configured AliDocMind cloud extractor when available. With neither path
|
|
# enabled, media materials fail cleanly with setup guidance.
|
|
|
|
# --- PDF Processing -----------------------------------------------------------
|
|
|
|
PDF_UNPDF_API_KEY=
|
|
PDF_UNPDF_BASE_URL=
|
|
|
|
PDF_MINERU_API_KEY=
|
|
PDF_MINERU_BASE_URL=
|
|
# Optional. Defaults to "pipeline"; use "hybrid-auto-engine" only when your MinerU
|
|
# service has the required GPU/device configuration.
|
|
PDF_MINERU_BACKEND=
|
|
|
|
PDF_MINERU_CLOUD_API_KEY=
|
|
PDF_MINERU_CLOUD_BASE_URL=https://mineru.net/api/v4
|
|
# Self-hosted MinerU never falls back to MinerU Cloud implicitly: a request that
|
|
# selects self-hosted MinerU without a configured base URL fails loudly. Set this
|
|
# to "true" to explicitly opt in to MinerU Cloud as a fallback (documents then
|
|
# leave your infrastructure). Default: off.
|
|
ALLOW_MINERU_CLOUD_FALLBACK=
|
|
|
|
# AliDocMind uses an Alibaba Cloud AccessKey pair instead of a single API key.
|
|
ALIDOCMIND_ACCESS_KEY_ID=
|
|
ALIDOCMIND_ACCESS_KEY_SECRET=
|
|
ALIDOCMIND_BASE_URL=
|
|
|
|
# --- Image Generation ---------------------------------------------------------
|
|
|
|
IMAGE_OPENAI_API_KEY=
|
|
IMAGE_OPENAI_MODELS=
|
|
IMAGE_OPENAI_BASE_URL=https://api.openai.com/v1
|
|
|
|
IMAGE_SEEDREAM_API_KEY=
|
|
IMAGE_SEEDREAM_MODELS=
|
|
IMAGE_SEEDREAM_BASE_URL=
|
|
|
|
IMAGE_QWEN_IMAGE_API_KEY=
|
|
IMAGE_QWEN_IMAGE_MODELS=
|
|
IMAGE_QWEN_IMAGE_BASE_URL=
|
|
|
|
IMAGE_NANO_BANANA_API_KEY=
|
|
IMAGE_NANO_BANANA_MODELS=
|
|
IMAGE_NANO_BANANA_BASE_URL=
|
|
|
|
IMAGE_MINIMAX_API_KEY=
|
|
IMAGE_MINIMAX_MODELS=
|
|
# Example models: image-01, image-01-live
|
|
IMAGE_MINIMAX_BASE_URL=https://api.minimaxi.com
|
|
|
|
IMAGE_GROK_API_KEY=
|
|
IMAGE_GROK_MODELS=
|
|
IMAGE_GROK_BASE_URL=
|
|
|
|
IMAGE_GLM_API_KEY=
|
|
IMAGE_GLM_MODELS=
|
|
# Example models: cogview-3-flash, cogview-4
|
|
IMAGE_GLM_BASE_URL=https://open.bigmodel.cn/api/paas/v4
|
|
|
|
# OpenRouter image generation. Optional; read at runtime. One key reaches every
|
|
# image model OpenRouter hosts (FLUX, Seedream, GPT Image, Gemini, Qwen Image,
|
|
# Recraft, Krea, ...). The model list in Settings is fetched live from
|
|
# GET /images/models. List the authorized ids in IMAGE_OPENROUTER_MODELS. Base URL defaults to
|
|
# https://openrouter.ai/api/v1 when left blank.
|
|
IMAGE_OPENROUTER_API_KEY=
|
|
IMAGE_OPENROUTER_MODELS=
|
|
IMAGE_OPENROUTER_BASE_URL=
|
|
|
|
# Lemonade image generation (local, no API key required)
|
|
# IMAGE_LEMONADE_BASE_URL=http://localhost:13305/v1
|
|
|
|
# Operators can force-disable any built-in image provider, including the
|
|
# client-only ComfyUI provider (it has no credential env). Examples:
|
|
# IMAGE_OPENAI_ENABLED=false
|
|
# IMAGE_COMFYUI_ENABLED=false
|
|
|
|
# --- Video Generation ---------------------------------------------------------
|
|
|
|
VIDEO_SEEDANCE_API_KEY=
|
|
VIDEO_SEEDANCE_MODELS=
|
|
VIDEO_SEEDANCE_BASE_URL=
|
|
|
|
VIDEO_KLING_API_KEY=
|
|
VIDEO_KLING_MODELS=
|
|
VIDEO_KLING_BASE_URL=
|
|
|
|
VIDEO_SORA_API_KEY=
|
|
VIDEO_SORA_BASE_URL=
|
|
|
|
VIDEO_MINIMAX_API_KEY=
|
|
VIDEO_MINIMAX_MODELS=
|
|
# Example models: MiniMax-Hailuo-2.3, MiniMax-Hailuo-2.3-Fast, MiniMax-Hailuo-02
|
|
VIDEO_MINIMAX_BASE_URL=https://api.minimaxi.com
|
|
|
|
VIDEO_GROK_API_KEY=
|
|
VIDEO_GROK_MODELS=
|
|
VIDEO_GROK_BASE_URL=
|
|
|
|
VIDEO_HAPPYHORSE_API_KEY=
|
|
VIDEO_HAPPYHORSE_MODELS=
|
|
VIDEO_HAPPYHORSE_BASE_URL=https://dashscope.aliyuncs.com
|
|
|
|
# OpenRouter video generation. Optional; read at runtime. One key reaches every
|
|
# video model OpenRouter hosts (Veo, Kling, Runway, Seedance, Hailuo, Wan,
|
|
# Sora, Grok Imagine, ...). The model list in Settings is fetched live from
|
|
# GET /videos/models. List the authorized ids in VIDEO_OPENROUTER_MODELS. Base URL defaults to
|
|
# https://openrouter.ai/api/v1 when left blank.
|
|
VIDEO_OPENROUTER_API_KEY=
|
|
VIDEO_OPENROUTER_MODELS=
|
|
VIDEO_OPENROUTER_BASE_URL=
|
|
|
|
# Operators can force-disable any built-in video provider. Examples:
|
|
# VIDEO_GROK_ENABLED=false
|
|
# VIDEO_KLING_ENABLED=false
|
|
|
|
# --- Web Search ---------------------------------------------------------------
|
|
# Note: Grok (xAI) web search is available via chat completions + search tools,
|
|
# not as a standalone search API. Use Grok LLM provider with search_parameters
|
|
# in chat requests. See: https://docs.x.ai/docs/guides/tools/search-tools
|
|
|
|
TAVILY_API_KEY=
|
|
TAVILY_BASE_URL=
|
|
EXA_API_KEY=
|
|
EXA_BASE_URL=https://api.exa.ai
|
|
FIRECRAWL_API_KEY=
|
|
FIRECRAWL_BASE_URL=https://api.firecrawl.dev
|
|
BOCHA_API_KEY=
|
|
BOCHA_BASE_URL=https://api.bocha.cn
|
|
BRAVE_API_KEY=
|
|
BRAVE_BASE_URL=
|
|
BAIDU_API_KEY=
|
|
BAIDU_BASE_URL=https://qianfan.baidubce.com
|
|
# Self-hosted SearXNG instance (no API key required)
|
|
SEARXNG_BASE_URL=
|
|
# Dedicated MiniMax web-search vars avoid conflicting with the LLM MINIMAX_* endpoint.
|
|
WEB_SEARCH_MINIMAX_API_KEY=
|
|
WEB_SEARCH_MINIMAX_BASE_URL=https://api.minimaxi.com
|
|
# Dedicated Doubao web-search vars avoid conflicting with the Doubao LLM provider.
|
|
WEB_SEARCH_DOUBAO_API_KEY=
|
|
WEB_SEARCH_DOUBAO_BASE_URL=https://open.feedcoopapi.com
|
|
# Claude (Anthropic) native web search. Dedicated vars avoid conflicting with
|
|
# ANTHROPIC_* LLM provider vars. Set WEB_SEARCH_CLAUDE_MODELS to authorize the
|
|
# search models server-side (first entry is the default), e.g. claude-sonnet-5.
|
|
WEB_SEARCH_CLAUDE_API_KEY=
|
|
WEB_SEARCH_CLAUDE_BASE_URL=https://api.anthropic.com/v1
|
|
WEB_SEARCH_CLAUDE_MODELS=
|
|
|
|
# Operators can force-disable any built-in web search provider. Examples:
|
|
# TAVILY_ENABLED=false
|
|
# EXA_ENABLED=false
|
|
# WEB_SEARCH_DOUBAO_ENABLED=false
|
|
# SEARXNG_ENABLED=false
|
|
|
|
# Server-only, default-OFF selector for the Native Child execution harness.
|
|
# OPENMAIC_ENABLE_PI_NATIVE_CHILD_RUNTIME=true
|
|
# Server-only, default-OFF Native Spotlight capability; does not select the runtime.
|
|
# OPENMAIC_ENABLE_PI_NATIVE_CHILD_SPOTLIGHT=true
|
|
|
|
# --- Feature Flags -----------------------------------------------------------
|
|
|
|
# Boolean feature flags accept "true" or "1". NEXT_PUBLIC_* values are compiled
|
|
# into the browser bundle at build time, so changing them requires a rebuild.
|
|
|
|
# Enable the Pro workbench entry (the workbench also requires the agent
|
|
# runtime to be configured server-side; see the Agent Runtime section).
|
|
# Implies the MAIC Editor gate below — Pro mode always ships with the editor.
|
|
# NEXT_PUBLIC_PRO_WORKBENCH_ENABLED=true
|
|
|
|
# Master gate for the MAIC Editor Pro-mode entry point. Implied by
|
|
# NEXT_PUBLIC_PRO_WORKBENCH_ENABLED; set it alone to enable the classroom
|
|
# editor on a deployment without the workbench.
|
|
# NEXT_PUBLIC_MAIC_EDITOR_ENABLED=true
|
|
|
|
# Select @openmaic/editor inside Pro mode. This does not enable Pro mode by itself.
|
|
# NEXT_PUBLIC_MAIC_EDITOR_RENDERER_ENABLED=true
|
|
|
|
# Use @openmaic/renderer for the classroom playback canvas.
|
|
# NEXT_PUBLIC_MAIC_PLAYBACK_RENDERER_ENABLED=true
|
|
|
|
# The old director-graph classroom chat has been removed. Classroom chat uses Pi
|
|
# and requires a Classroom model with tool calling. Remove NEXT_PUBLIC_PI_CHAT_ENABLED.
|
|
# Production builds accept only unset, empty string, 'true', or '1' (exact match);
|
|
# all other values fail with migration guidance.
|
|
# Docker Compose's service env_file supplies runtime values, not build args.
|
|
|
|
# Enable the unified PPT/Interactive courseware-reference entry in Pi playback.
|
|
# Pi chat and editor element references remain independent from this default-off build-time gate.
|
|
# Changing a NEXT_PUBLIC_* value requires rebuilding the application.
|
|
# NEXT_PUBLIC_COURSEWARE_REFERENCE_ENABLED=true
|
|
|
|
# Enable the server-side vocational task-engine generation path.
|
|
# OPENMAIC_ENABLE_VOCATIONAL=true
|
|
|
|
# Show the experimental vocational task-engine control in the client.
|
|
# NEXT_PUBLIC_SHOW_VOCATIONAL_TEST_UI=true
|
|
|
|
# Show the video export and PPTX import entry points.
|
|
# NEXT_PUBLIC_ENABLE_VIDEO_EXPORT=true
|
|
# NEXT_PUBLIC_ENABLE_PPTX_IMPORT=true
|
|
|
|
# Informational destination shown on exported Quiz/PBL cover cards. Unset or
|
|
# blank defaults to open.maic.chat; set to "off" to omit it.
|
|
# NEXT_PUBLIC_VIDEO_EXPORT_CTA_DESTINATION=open.maic.chat
|
|
|
|
# --- Agent Runtime (experimental) ---------------------------------------------
|
|
|
|
# Server-only gate for durable background agent sessions: the /api/agent
|
|
# session and owner-event control-plane routes plus the in-process session
|
|
# runner. Default OFF — while disabled, every /api/agent/sessions* and
|
|
# /api/agent/owner-events route answers 404. Truthy values are "true" or "1";
|
|
# anything else (including unset) is treated as disabled.
|
|
# OPENMAIC_AGENT_RUNTIME_ENABLED=true
|
|
|
|
# The runtime uses the PostgreSQL connection (DATABASE_URL) from the
|
|
# "Persistence" section below, which every deployment configures.
|
|
|
|
# The agent runs on the `agent` slot of the model configuration (openmaic.yml,
|
|
# or the model settings): a model that supports tool calling. Optional fields
|
|
# on the slot: api ("openai-completions", the default, or "openai-responses"),
|
|
# contextWindow (pins the window compaction assumes below the catalogue value),
|
|
# and thinking, which must never set effort (the tool-using driver cannot
|
|
# combine reasoning_effort with function tools on this transport). A
|
|
# deployment configured only through DEFAULT_MODEL has the agent turned off.
|
|
|
|
# Runner tuning. Defaults are shown; only relevant once the runtime is enabled.
|
|
# OPENMAIC_AGENT_RUNTIME_SCAN_INTERVAL_MS=1000
|
|
# OPENMAIC_AGENT_RUNTIME_HEARTBEAT_MS=2000
|
|
# OPENMAIC_AGENT_RUNTIME_LEASE_TTL_MS=10000
|
|
# OPENMAIC_AGENT_RUNTIME_MAX_CONCURRENT=2
|
|
# OPENMAIC_AGENT_RUNTIME_MAX_ATTEMPTS=5
|
|
|
|
# Global per-tool-call execution bound for every agent run (ms). A tool call
|
|
# that neither resolves nor rejects within the budget is aborted and settles as
|
|
# an error tool-result the agent can retry or proceed from; the session does
|
|
# not die. Default 600000 (10 minutes). Tools with known longer budgets (media
|
|
# synthesis, material extraction) carry their own explicit bounds in code.
|
|
# OPENMAIC_AGENT_TOOL_TIMEOUT_MS=600000
|
|
|
|
# Conversation compaction is reserved and OFF by default. The reusable
|
|
# compaction runtime is not implemented yet — it lands in a later slice of
|
|
# work — and until then the runner runs without context transformation, so
|
|
# these knobs are inert placeholders.
|
|
# OPENMAIC_AGENT_COMPACTION_ENABLED=true
|
|
# OPENMAIC_AGENT_COMPACTION_RESERVE_TOKENS=0
|
|
# OPENMAIC_AGENT_COMPACTION_KEEP_RECENT_TOKENS=0
|
|
|
|
# Session prompts and follow-up messages are capped server-side at a fixed
|
|
# 100,000 characters; this limit is a constant and is not configurable.
|
|
|
|
# --- Generation runs ----------------------------------------------------------
|
|
|
|
# Course generation runs on the server: a run is a PostgreSQL record that a
|
|
# worker in every server process executes, step by step, and another process
|
|
# takes over from its last checkpoint if one dies. The worker always runs (it
|
|
# does not depend on OPENMAIC_AGENT_RUNTIME_ENABLED) and needs a process that
|
|
# outlives requests, so serverless hosts are not supported. It shares the lease
|
|
# timing of the agent runtime (OPENMAIC_AGENT_RUNTIME_SCAN_INTERVAL_MS,
|
|
# _HEARTBEAT_MS, _LEASE_TTL_MS and _MAX_ATTEMPTS above). Defaults are shown;
|
|
# values must be positive integers.
|
|
#
|
|
# Runs one owner may have in progress at once (a run waiting for its outline to
|
|
# be confirmed, or paused at a failed step, does not count). Over the limit,
|
|
# starting, confirming or retrying a run answers 429 ACTIVE_RUN_LIMIT.
|
|
# OPENMAIC_MAX_ACTIVE_RUNS_PER_OWNER=2
|
|
# Runs one owner may have waiting for outline confirmation at once.
|
|
# OPENMAIC_MAX_WAITING_RUNS_PER_OWNER=10
|
|
# Runs one server process executes at once.
|
|
# OPENMAIC_GENERATION_RUN_MAX_CONCURRENT=4
|
|
# Uploaded materials one server process extracts at once in the background
|
|
# (each is parsed or transcribed right after its upload, before generation).
|
|
# OPENMAIC_MATERIAL_EXTRACTION_CONCURRENCY=2
|
|
# One owner's extractions running at once across every server process, so one
|
|
# owner's uploads cannot hold every worker while others wait.
|
|
# OPENMAIC_MATERIAL_EXTRACTION_PER_OWNER=2
|
|
# The largest stored extraction result (text and images) of one material, in
|
|
# MB; a larger one fails with EXTRACTION_RESULT_TOO_LARGE. Results count
|
|
# against the owner's material byte quota.
|
|
# OPENMAIC_MATERIAL_EXTRACTION_MAX_RESULT_MB=100
|
|
# Hours an uploaded material that no generation run or agent session uses is
|
|
# kept after it was last read (an open composer reads its materials back) before
|
|
# it is deleted.
|
|
# OPENMAIC_UNUSED_MATERIAL_TTL_HOURS=24
|
|
# Run event streams (one run's events, or the owner's run changes) one owner may
|
|
# hold open on one process.
|
|
# OPENMAIC_GENERATION_RUN_STREAMS_PER_OWNER=16
|
|
# Hours a finished run keeps its full event log before it is compacted to its
|
|
# final snapshot.
|
|
# OPENMAIC_GENERATION_RUN_RETENTION_HOURS=24
|
|
|
|
# --- Proxy (optional) --------------------------------------------------------
|
|
|
|
# HTTP_PROXY=
|
|
# HTTPS_PROXY=
|
|
# Comma-separated hosts that bypass the proxy. Supports domain suffixes and *.
|
|
# NO_PROXY=localhost,127.0.0.1,.internal.example.com
|
|
|
|
# --- Misc ---------------------------------------------------------------------
|
|
|
|
# Default model (deprecated: prefer openmaic.yml). Without openmaic.yml it
|
|
# becomes the default of every chat slot (the `llm` root), below the models a
|
|
# workspace picks in the settings; the agent stays off. There is no hardcoded
|
|
# vendor fallback: a call with no model configured fails.
|
|
# Example: openai:gpt-5.5, minimax:MiniMax-M2.7-highspeed,
|
|
# bedrock:us.anthropic.claude-sonnet-5
|
|
DEFAULT_MODEL=
|
|
|
|
# Per-stage models are slots in openmaic.yml (course.outline,
|
|
# course.content.slide, classroom, agent, ...). MODEL_ROUTES is no longer read:
|
|
# a server that still sets it without openmaic.yml refuses to start. The agent
|
|
# runtime's former "maic-agent-driver" route is now the `agent` slot (with its
|
|
# `api` and `contextWindow`).
|
|
|
|
# Retry model (deprecated: prefer a slot's `fallback` in openmaic.yml). When a
|
|
# generation call fails with a retryable failure (SDK-classified transient
|
|
# error, timeout, network error, quota 429, capacity 503) or returns empty
|
|
# output, the shared callLLM layer retries ONCE on the slot's fallback model.
|
|
# Content-safety rejections and other 4xx failures never fall back. Without
|
|
# openmaic.yml, MODEL_FALLBACK becomes the fallback of DEFAULT_MODEL.
|
|
# MODEL_FALLBACK=
|
|
|
|
# LOG_LEVEL=info
|
|
# LOG_FORMAT=pretty
|
|
# LLM_THINKING_DISABLED=false
|
|
|
|
# Opt-in parallel scene-content generation (#572). 0/unset = serial (default).
|
|
# A value > 1 fetches scene content concurrently (capped at 10); actions + TTS
|
|
# stay serial. Leave off if your API key has a low per-key concurrency quota.
|
|
# PARALLEL_SCENE_CONCURRENCY=3
|
|
|
|
# --- Local/Self-hosted Deployment ---------------------------------------------
|
|
# Set to "true" to allow private/local network URLs. That covers private
|
|
# (RFC1918), loopback, link-local and CGNAT (100.64.0.0/10, used by Tailscale
|
|
# and similar overlay networks) targets. Required for self-hosted models like
|
|
# Ollama. Do NOT enable on public deployments.
|
|
# The known cloud instance-metadata and credential endpoints (169.254.169.254,
|
|
# 169.254.170.2, 169.254.170.23, 100.100.100.200, 168.63.129.16, 192.0.0.192,
|
|
# fd00:ec2::254, fd00:ec2::23, metadata.google.internal) are blocked with or
|
|
# without this flag, as are IANA reserved, multicast and broadcast ranges. That
|
|
# is a fixed address list, not a general link-local block, and under the flag a
|
|
# hostname whose DNS lookup fails, times out or returns no answer is still
|
|
# allowed through.
|
|
# ALLOW_LOCAL_NETWORKS=true
|
|
|
|
# Build-time, space-separated CSP frame-ancestor sources in addition to 'self'.
|
|
# Configure only origins you trust to embed OpenMAIC, then rebuild the app. The
|
|
# Docker and Compose builds also accept this value as a build argument.
|
|
# ALLOWED_FRAME_ANCESTORS=https://partner.example.com
|
|
|
|
# Optional MP4 render service (issue #866). When set, the in-app "Export Video"
|
|
# menu offers one-click MP4 rendering; when unset, it degrades to downloading a
|
|
# project ZIP for local CLI rendering. Point this at the isolated render-service
|
|
# container (see render-service/ and the "video-export" docker-compose profile).
|
|
# This is operator-supplied trusted config: the app forwards uploads to it
|
|
# without the SSRF guard, so a private/compose-network target works WITHOUT
|
|
# setting ALLOW_LOCAL_NETWORKS.
|
|
# RENDER_SERVICE_URL=http://render-service:9000
|
|
|
|
# Optional runtime setting for render-service-only preview concurrency, independent
|
|
# of video exports. Defaults to 1; maximum 2 for standard, 1 for low-memory.
|
|
# Values above the resource profile's limit fail startup.
|
|
# Each executing preview launches its own browser alongside the export, so
|
|
# provision additional memory before raising this value. Passed through by Compose.
|
|
# RENDER_PREVIEW_MAX_CONCURRENCY=1
|
|
|
|
# Render-service-only opt-in for bounded local chunk execution. These variables
|
|
# are read at runtime by the isolated render-service container; the public HTTP
|
|
# API is unchanged. Defaults keep the existing in-process renderer.
|
|
# RENDER_CHUNK_EXECUTION=false
|
|
# RENDER_CHUNK_COUNT=1
|
|
# RENDER_CHUNK_WORKERS=1
|
|
# RENDER_MAX_PARALLEL_CHUNKS=1
|
|
# RENDER_CHUNK_SIZE_FRAMES=0
|
|
# RENDER_TARGET_CHUNK_FRAMES=0
|
|
|
|
# Honor x-forwarded-for / x-real-ip when deriving client identity for both
|
|
# render-service admission and access-code verification throttling.
|
|
# Enable only behind a trusted reverse proxy that overwrites these headers.
|
|
# TRUST_PROXY_HEADERS=true
|
|
|
|
# --- Persistence (PostgreSQL, required) ---------------------------------------
|
|
|
|
# Courses, chat history, learner progress and generated media are stored in
|
|
# PostgreSQL through the embedded /api/persistence endpoint. The server refuses
|
|
# to start without DATABASE_URL. Requests are attributed to the owner the owner
|
|
# identity seam resolves (by default the anonymous owner cookie); there is no
|
|
# separate persistence credential.
|
|
#
|
|
# Local development: `pnpm db:up` starts a separate development PostgreSQL
|
|
# (its own Compose project, container and volume, see docker-compose.db.yml)
|
|
# on 127.0.0.1 (port OPENMAIC_DB_PORT, default 5432); then uncomment this line.
|
|
# `pnpm db:down` stops it again (the data volume is kept).
|
|
# DATABASE_URL=postgres://openmaic:openmaic-dev@127.0.0.1:5432/openmaic
|
|
#
|
|
# Under docker-compose.yml, the default points at the bundled PostgreSQL (from
|
|
# PERSISTENCE_POSTGRES_PASSWORD, which must then be letters and digits); a value
|
|
# set here overrides it. Other deployments (the Docker image on its own, or
|
|
# `pnpm start`) point this at a PostgreSQL database they run themselves.
|
|
|
|
# Logical bytes of live assets each owner may hold (default 10 GiB; 0 opts
|
|
# out). Per owner, not per deployment: with anonymous-cookie owners a cleared
|
|
# cookie is a new owner with a fresh quota.
|
|
# ASSET_QUOTA_BYTES=
|
|
|
|
# The anonymous owner cookie and the ACCESS_CODE cookie carry the `Secure` flag
|
|
# in production builds. Over plain HTTP other than localhost no browser stores
|
|
# them, so every request is a new owner and the access code is asked again.
|
|
# Safari refuses to store `Secure` cookies served over plain http://localhost
|
|
# (unlike Chromium/Firefox, it does not special-case localhost), so every
|
|
# request mints a fresh anonymous owner and owner-scoped document writes fail
|
|
# with 403. Deployments that serve plain HTTP (no TLS) opt out with the exact
|
|
# value 0 — any other spelling (false, no) leaves `Secure` on:
|
|
# COOKIE_SECURE=0
|
|
# Only do this on a trusted network or locally: without `Secure` the cookie
|
|
# travels in the clear and can be replayed by anyone on-path.
|
|
|
|
# Single-tenant deployments: resolve every request to this fixed owner id
|
|
# instead of a per-browser anonymous cookie. One team behind one ACCESS_CODE
|
|
# then shares one course library — a second browser no longer sees an empty
|
|
# list, and `publish` becomes usable (it refuses anonymous owners, since
|
|
# publishing a cookie partition is not something the product allows).
|
|
# Unset, every browser keeps its own partition and this block changes nothing.
|
|
#
|
|
# This answers WHO owns a course; DATABASE_URL above answers WHERE one lives.
|
|
# Without this setting (or OWNER_SINGLE_USER), a second browser is a different
|
|
# anonymous owner and sees an empty list.
|
|
#
|
|
# ACCESS_CODE is required: without one the middleware lets every request
|
|
# through, so a single shared owner would expose one readable, editable and
|
|
# publishable course library to anyone who can reach the deployment. Setting
|
|
# this without an access code fails startup. Everyone holding the access code
|
|
# then sees, edits and can publish the same courses, with no per-person
|
|
# attribution — which is what SECURITY.md already says ACCESS_CODE is, and not
|
|
# user authentication. 1-128 characters of [A-Za-z0-9._-]; the reserved `anon:`
|
|
# prefix is rejected, and a malformed value fails startup rather than being
|
|
# ignored.
|
|
# PERSISTENCE_SHARED_OWNER_ID=
|
|
|
|
# Personal installations: resolve every request to one fixed owner for a
|
|
# single person, who may publish. On by default under Docker Compose (see
|
|
# docker-compose.defaults.env); unset elsewhere. "true"/"1" or "false"/"0";
|
|
# anything else fails startup. Excludes PERSISTENCE_SHARED_OWNER_ID above:
|
|
# setting both fails startup.
|
|
# OWNER_SINGLE_USER=true
|
|
#
|
|
# The owner id (default "local"), same format as PERSISTENCE_SHARED_OWNER_ID.
|
|
# Setting it while OWNER_SINGLE_USER is off fails startup.
|
|
# OWNER_SINGLE_USER_ID=local
|
|
#
|
|
# Exposure: every request becomes the owner of the whole library. The mode runs
|
|
# with or without ACCESS_CODE; without one, anyone who can reach the server
|
|
# shares, edits and can delete the single library, so the server logs a
|
|
# prominent startup warning. Keep it on 127.0.0.1 or a private network
|
|
# (docker-compose.yml publishes on 127.0.0.1 by default; OPENMAIC_PUBLISH_ADDRESS
|
|
# changes that), or set ACCESS_CODE below.
|
|
#
|
|
# A browser that used the deployment anonymously before keeps its anonymous
|
|
# cookie; single-user mode can claim that earlier work into the single owner
|
|
# with POST /api/identity/claim. OWNER_CLAIM_TRIGGER=auto below would claim on
|
|
# every visiting browser's first request, irreversibly merging the libraries of
|
|
# everyone who used the deployment anonymously; set it only knowingly.
|
|
# The owner id is permanent: changing OWNER_SINGLE_USER_ID (or switching from
|
|
# PERSISTENCE_SHARED_OWNER_ID) strands the previous owner's library.
|
|
|
|
# Real accounts (your own sessions, API keys, or an identity gateway such as
|
|
# oauth2-proxy or Cloudflare Access) are not configured here: a host registers
|
|
# owner auth methods in instrumentation.ts. See "Owner identity" in README.md,
|
|
# which includes a recipe for verifying a gateway-signed JWT. When a host
|
|
# registers methods and still wants the shared owner above, it includes
|
|
# sharedTeamAuthMethod() last; setting PERSISTENCE_SHARED_OWNER_ID beside a
|
|
# registration that leaves it out fails startup.
|
|
|
|
# Store asset bytes in S3 instead of PostgreSQL. Region, endpoint, and credentials
|
|
# are resolved through the standard AWS SDK environment / credential chain.
|
|
# ASSET_S3_BUCKET=
|
|
|
|
# Use endpoint/bucket/key addressing for S3-compatible stores such as MinIO and
|
|
# Ceph. These stores commonly require path-style requests when configured
|
|
# through AWS_ENDPOINT_URL_S3. Accepts "true" or "1"; leave unset for Amazon S3.
|
|
# AWS_S3_FORCE_PATH_STYLE=1
|
|
|
|
# Opt into indirect asset byte egress: answer asset byte GETs with a short-lived
|
|
# signed S3 URL (a 302, or a JSON descriptor for the packaged client) instead of
|
|
# the bytes. Unset or "direct" keeps direct egress (the safe default). Requires
|
|
# the object store's CORS to admit this app's origin and expose Content-Type, and
|
|
# the signing identity to hold s3:ListBucket on the bucket so a missing key
|
|
# answers 404 NoSuchKey rather than 403.
|
|
# ASSET_BYTE_EGRESS=redirect
|
|
|
|
# Claiming anonymous work on sign-in (see README "Claiming anonymous work").
|
|
# explicit (default): the app calls POST /api/identity/claim; auto: the first
|
|
# request that carries both an account and an anonymous owner claims it.
|
|
# OWNER_CLAIM_TRIGGER=explicit
|
|
|
|
# The page response of a browser's first load mints the anonymous owner cookie
|
|
# (default on), so the page's first API requests do not each mint an owner.
|
|
# Set it to false only when registered owner auth methods set
|
|
# anonymousFallback: false (startup warns when they do and this is on); hosts
|
|
# that keep anonymous visitors need it, and skip it per request in
|
|
# middleware.ts for requests their methods authenticate.
|
|
# "true", "1", "false" or "0"; anything else fails startup.
|
|
# OWNER_ANONYMOUS_PREMINT=true
|
|
|
|
# How long an owner-scoped write (default 30000) and a claim (default 5000) wait
|
|
# for the owner's identity lock before answering 503 OWNER_BUSY with
|
|
# Retry-After. Positive integers in milliseconds, checked at startup.
|
|
# OWNER_WRITE_LOCK_WAIT_MS=30000
|
|
# OWNER_CLAIM_LOCK_WAIT_MS=5000
|
|
|
|
# The asset collector is enabled by default.
|
|
# ASSET_COLLECTION_ENABLED=true
|
|
# ASSET_COLLECTION_INTERVAL_MS=900000
|
|
# ASSET_COLLECTION_GRACE_MS=3600000
|
|
|
|
# Directory of the file-backed classroom store of earlier versions. Defaults to
|
|
# <cwd>/data/classrooms. Classrooms generated through /api/generate-classroom
|
|
# are now saved in PostgreSQL (courses) and the asset pool (media, narration);
|
|
# at startup the server imports the <id>.json classrooms it finds here, once,
|
|
# retrying in the background until it completes, and logs a summary. They go to
|
|
# the shared team owner or the single user when one is configured; otherwise to
|
|
# a dedicated owner no visitor resolves to, so each classroom keeps opening
|
|
# read-only from its old link and appears in no visitor's library (export it as
|
|
# a ZIP and import it to own a copy). An id another course already holds is
|
|
# skipped. Keep this directory in place: the import leaves the files where they
|
|
# are, imported classrooms may still reference files in it, and agent-run
|
|
# courses serve narration and material media from it. The old
|
|
# <cwd>/data/classroom-jobs directory is no longer read.
|
|
# OPENMAIC_CLASSROOMS_DIR=/var/lib/openmaic/classrooms
|
|
|
|
# How long an allocated asset stays pending -- stored, but not yet named by any
|
|
# document -- before the collector expires it. A client stores bytes first and
|
|
# writes the id into the document afterwards, so this window has to outlive a
|
|
# whole generation pass plus a write-back that is waiting for its slide to be
|
|
# built; the default is one day for that reason. A value that is not a positive
|
|
# integer stops the server from starting.
|
|
# ASSET_PENDING_TTL_MS=86400000
|
|
|
|
# --- Access Control -----------------------------------------------------------
|
|
# Set a password to restrict site access. When set, users must enter this code
|
|
# before using the app. Leave empty or remove to disable access control
|
|
# (fail-open: middleware lets every request through with no credential).
|
|
# Read at runtime. When unset, the server logs a one-time startup warning (in
|
|
# single-user mode, the single-user warning, which names ACCESS_CODE, instead);
|
|
# GET /api/health reports accessCodeConfigured: false. Set this before exposing
|
|
# the server to a network. The warning does not prevent local zero-config use.
|
|
# Use a long random value (at least 16 characters from a random generator):
|
|
# this code is the only secret guarding the deployment. The code is remembered
|
|
# in a signed token stored in an HTTP-only cookie for 7 days; the lifetime is
|
|
# enforced server-side, so visitors re-verify after it expires.
|
|
# ACCESS_CODE=your-secret-code
|
|
#
|
|
# Verification is rate limited only when TRUST_PROXY_HEADERS=true (see above):
|
|
# behind a trusted reverse proxy that overwrites x-forwarded-for / x-real-ip,
|
|
# each client is limited to 10 attempts per 60 seconds, and a trusted client's
|
|
# successful verification clears its own counter. Without a trusted proxy the
|
|
# app cannot attribute a request to a client, so there is no throttle; rely on
|
|
# the length and randomness of the code instead.
|