From 431fbf4ef077be00c2186ee7fe560f9dc86b8b92 Mon Sep 17 00:00:00 2001 From: Jan Librowski Date: Fri, 17 Jul 2026 11:51:49 +0200 Subject: [PATCH 1/3] fix(deploy): pass OPENROUTER_API_KEY to the backend service The adapt endpoint runs its LLM call in the backend, not the worker, and answered 501 adapt_disabled on every request because only the worker received the key. Executions kept working, which masked it. --- deploy/ai-studio/docker-compose.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deploy/ai-studio/docker-compose.yml b/deploy/ai-studio/docker-compose.yml index b891cea66..42fe11ee6 100644 --- a/deploy/ai-studio/docker-compose.yml +++ b/deploy/ai-studio/docker-compose.yml @@ -82,6 +82,9 @@ services: TRUST_PROXY: 'true' RATE_LIMIT_EXECUTE_PER_MINUTE: ${RATE_LIMIT_EXECUTE_PER_MINUTE:-10} RATE_LIMIT_EXECUTE_PER_DAY: ${RATE_LIMIT_EXECUTE_PER_DAY:-50} + # the backend calls the LLM itself for /api/visualize/adapt + OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:?set OPENROUTER_API_KEY in deploy/ai-studio/.env} + AI_MODEL: ${AI_MODEL:-mistralai/mistral-small-3.2-24b-instruct} depends_on: app-db: condition: service_healthy From 48c340cb3adf4211d364acefffe26dc60bb9b7b0 Mon Sep 17 00:00:00 2001 From: Jan Librowski Date: Fri, 17 Jul 2026 12:13:52 +0200 Subject: [PATCH 2/3] fix(deploy): wire TAVILY_API_KEY into the worker service The worker reads TAVILY_API_KEY to enable the AI Agent's web search tool, but the deploy compose never passed it, so web search was silently disabled on deployments: agents with the toggle on ran without the tool. Optional - an empty value keeps it off. --- deploy/ai-studio/.env.example | 7 ++++++- deploy/ai-studio/docker-compose.yml | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/deploy/ai-studio/.env.example b/deploy/ai-studio/.env.example index b80d85932..6d250ca1d 100644 --- a/deploy/ai-studio/.env.example +++ b/deploy/ai-studio/.env.example @@ -9,10 +9,15 @@ OPENROUTER_API_KEY= # --- LLM -------------------------------------------------------------------- -# WB-229 demo model. Cheap, EU-hosted, solid tool calling. +# Demo model. Cheap, EU-hosted, solid tool calling. # ~$0.075/M input + $0.20/M output => ~$0.0004 per 3-call template run. AI_MODEL=mistralai/mistral-small-3.2-24b-instruct +# Tavily web search (optional). Enables the AI Agent's "Web search" tool - +# free key at https://tavily.com (~1000 searches/month). Leave empty to +# disable: agents with web search toggled on still run, just without the tool. +TAVILY_API_KEY= + # --- abuse gate (per-IP, execute route) --------------------------------------- RATE_LIMIT_EXECUTE_PER_MINUTE=10 diff --git a/deploy/ai-studio/docker-compose.yml b/deploy/ai-studio/docker-compose.yml index 42fe11ee6..5eed67bf7 100644 --- a/deploy/ai-studio/docker-compose.yml +++ b/deploy/ai-studio/docker-compose.yml @@ -114,6 +114,8 @@ services: TEMPORAL_ADDRESS: temporal:7233 OPENROUTER_API_KEY: ${OPENROUTER_API_KEY:?set OPENROUTER_API_KEY in deploy/ai-studio/.env} AI_MODEL: ${AI_MODEL:-mistralai/mistral-small-3.2-24b-instruct} + # optional - empty disables the AI Agent's web search tool + TAVILY_API_KEY: ${TAVILY_API_KEY:-} depends_on: app-db: condition: service_healthy From dddf90ac81ad25ccfdda398fe1b627f78f697985 Mon Sep 17 00:00:00 2001 From: Jan Librowski Date: Fri, 17 Jul 2026 12:13:53 +0200 Subject: [PATCH 3/3] fix: unify the AI_MODEL default on the demo model Backend and worker code defaulted to google/gemini-2.5-flash-lite while the deploy stack defaults to mistralai/mistral-small-3.2-24b-instruct, so an unset AI_MODEL meant different models depending on where the process ran. One default everywhere now - the deployed demo already runs this model, so production behavior does not change. --- apps/backend/.env.example | 2 +- apps/backend/src/env.ts | 2 +- apps/execution-worker/.env.example | 2 +- apps/execution-worker/src/env.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/backend/.env.example b/apps/backend/.env.example index 8c7df3951..d639840f1 100644 --- a/apps/backend/.env.example +++ b/apps/backend/.env.example @@ -19,4 +19,4 @@ TURNSTILE_SECRET_KEY= # Optional: leave empty to disable AI adapt (the endpoint returns 501). The # execution worker keeps its own key for running workflows. OPENROUTER_API_KEY= -AI_MODEL=google/gemini-2.5-flash-lite +AI_MODEL=mistralai/mistral-small-3.2-24b-instruct diff --git a/apps/backend/src/env.ts b/apps/backend/src/env.ts index cc2e7543e..278e18aa8 100644 --- a/apps/backend/src/env.ts +++ b/apps/backend/src/env.ts @@ -20,5 +20,5 @@ export const env = { TURNSTILE_SECRET_KEY: process.env['TURNSTILE_SECRET_KEY'] ?? null, // Null = the "AI adapt" endpoint is disabled (returns 501). The worker keeps its own key. OPENROUTER_API_KEY: process.env['OPENROUTER_API_KEY'] ?? null, - AI_MODEL: envOr('AI_MODEL', 'google/gemini-2.5-flash-lite'), + AI_MODEL: envOr('AI_MODEL', 'mistralai/mistral-small-3.2-24b-instruct'), }; diff --git a/apps/execution-worker/.env.example b/apps/execution-worker/.env.example index 4a2aaf531..94e2ecd4c 100644 --- a/apps/execution-worker/.env.example +++ b/apps/execution-worker/.env.example @@ -3,7 +3,7 @@ TEMPORAL_ADDRESS=127.0.0.1:7233 # OpenRouter — any model OPENROUTER_API_KEY=sk-or-... -AI_MODEL=google/gemini-2.5-flash-lite +AI_MODEL=mistralai/mistral-small-3.2-24b-instruct # Tavily web search (optional). Enables the AI Agent's "Web search" tool. Get a # free key at https://tavily.com (free tier ~1000 searches/month). Leave empty diff --git a/apps/execution-worker/src/env.ts b/apps/execution-worker/src/env.ts index c86338aa9..5bbd6a61a 100644 --- a/apps/execution-worker/src/env.ts +++ b/apps/execution-worker/src/env.ts @@ -18,7 +18,7 @@ export const env = { TEMPORAL_ADDRESS: envOr('TEMPORAL_ADDRESS', '127.0.0.1:7233'), OPENROUTER_API_KEY: requireEnv('OPENROUTER_API_KEY'), // Cheap, fast default for the public demo; quality-per-cost over frontier capability. - AI_MODEL: envOr('AI_MODEL', 'google/gemini-2.5-flash-lite'), + AI_MODEL: envOr('AI_MODEL', 'mistralai/mistral-small-3.2-24b-instruct'), // Optional. Enables the AI Agent's web-search tool; agents run without it when unset. TAVILY_API_KEY: process.env['TAVILY_API_KEY'], };