[ 'api_key' => env('OPENROUTER_API_KEY'), 'base_url' => env('OPENROUTER_BASE_URL', 'https://openrouter.ai/api/v1'), 'timeout' => (int) env('OPENROUTER_TIMEOUT', 30), 'app_name' => env('APP_NAME', 'City10'), 'app_url' => env('APP_URL', 'http://localhost:16980'), ], /* |-------------------------------------------------------------------------- | Allow-listed Free Models |-------------------------------------------------------------------------- | | Only the free models listed below may be selected for AI agents. | Administrators cannot register agents with models outside this list, | which keeps operating costs at zero and enforces the platform policy. | */ 'allowed_models' => [ 'poolside/laguna-m.1:free', 'cohere/north-mini-code:free', 'deepseek/deepseek-v4-flash-0731:free', 'qwen/qwen3.8-27b:free', 'nvidia/nemotron-3-ultra-550b-a55b:free', 'nvidia/nemotron-3-super-120b-a12b:free', 'google/gemma-4-31b-it:free', 'google/gemma-4-26b-a4b-it:free', 'openai/gpt-oss-20b:free', 'nvidia/nemotron-nano-12b-v2-vl:free', 'nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free', 'nvidia/nemotron-3-nano-30b-a3b:free', 'nvidia/nemotron-nano-9b-v2:free', 'poolside/laguna-xs-2.1:free', 'inclusionai/ling-3.0-flash-vl:free', 'qwen/qwen3.7-flash:free', // Verified working free chat models (live probe of the OpenRouter // catalogue). Safe defaults for per-character assignment. 'deepseek/deepseek-v4-flash-0731', 'nvidia/nemotron-3.5-lightning:free', 'liquid/lfm-2.5-2.6b:free', 'openrouter/free', // Owner-approved exception: paid but near-zero cost // (1.4e-7/1k tokens), verified live on 2026-11-01. 'xiaomi/mimo-v2.6-flash', ], /* |-------------------------------------------------------------------------- | Per-Character Model Pool (AI_MODELS) |-------------------------------------------------------------------------- | | Comma-separated allow-listed models distributed deterministically | across characters (each character keeps a stable own model). Falls | back to AI_DEFAULT_MODEL when empty. | */ 'models' => array_values(array_filter(array_map( 'trim', explode(',', (string) env('AI_MODELS', '')) ))), /* |-------------------------------------------------------------------------- | Per-Character Model Map (AI_CHARACTER_MODELS) |-------------------------------------------------------------------------- | | Explicit "id or name = model" overrides from the environment, e.g. | "Maria=liquid/lfm-2.5-2.6b:free,7=openrouter/free". Takes priority | over the pool; entries outside the allow-list are ignored. | */ 'character_models' => $parseCharacterModels((string) env('AI_CHARACTER_MODELS', '')), /* |-------------------------------------------------------------------------- | Air Traffic Control Model (AI_ATC_MODEL) |-------------------------------------------------------------------------- | | Default model used by the airport control tower agent for movement | clearances (takeoff authorizations). Must stay inside allowed_models. | */ 'atc_model' => env('AI_ATC_MODEL', 'poolside/laguna-xs-2.1:free'), /* |-------------------------------------------------------------------------- | Fallback Model (AI_FALLBACK_MODEL) |-------------------------------------------------------------------------- | | Tried whenever the preferred model of a call fails (chain fallback). | Owner-approved paid model with near-zero cost; must stay inside | allowed_models. | */ 'fallback_model' => env('AI_FALLBACK_MODEL', 'xiaomi/mimo-v2.6-flash'), /* |-------------------------------------------------------------------------- | Default Model |-------------------------------------------------------------------------- | | Model assigned to newly created agents when none is specified. | */ 'default_model' => env('AI_DEFAULT_MODEL', 'deepseek/deepseek-v4-flash-0731'), /* |-------------------------------------------------------------------------- | Agent Decision Cadence (seconds) |-------------------------------------------------------------------------- | | Minimum interval between two reasoning calls for the same agent, | protecting the upstream API from excessive usage. | */ 'think_interval' => (int) env('AI_THINK_INTERVAL', 60), ];