Skip to content

ADR-001: Two AI providers behind configuration

Developers and the owner — read this before changing how the pipeline talks to AI vendors.

  • The pipeline never hard-codes one AI vendor: PRIMARY_AI_PROVIDER is tried first, FALLBACK_AI_PROVIDER second.
  • Models are environment variables too, so a model can be swapped without a deploy.
  • Status: accepted, partly realised. The fallback path exists and is tested with mocks, but no fallback key is configured, so in practice there is one provider.

An event is a fixed date with guests standing at the station. An outage, quota problem or account issue at a single AI vendor on that day would stop the product. The risk register lists “provider unavailable on the event day” as critical (RISKS.md, item 1) and account verification at the second vendor as a schedule risk (item 3).

  • Every image and vision call goes through bot/services/ai_pipeline.py, which resolves the provider and key from configuration.
  • Known providers are gemini and openai; an unknown name is a start-up error (bot/config.py).
  • A rate-limit answer is retried on the same provider with backoff; other failures move to the fallback provider. A switch raises an alert, throttled so an outage does not flood the admin chat.
  • A “no credits” answer (HTTP 402) is not retried — see ADR-011.
Alternative Why not
One provider, add the second later The switch would have to be built under pressure, on the event day.
An aggregator service in front of both One more dependency and account that can fail; no benefit at pilot scale.
  • Prompts and post-processing must stay provider-neutral; provider-specific options (resolution, aspect ratio) live inside the provider functions.
  • Cost accounting has separate price variables per provider and role.
  • With only one key present the service starts with a warning, not an error: running on one provider is an accepted fallback position. The OpenAI branches (images and vision) have never been exercised against the real API.

Last verified: 2026-11-13 against ai-sticker-pack@b715418 and ai-stickers-landing@e350ff5.