Skip to content

Configure development and production

Start with the generated files. They are complete alternatives, not layers that merge.

Generated development environment

schema = "vaani.environment.v1"
environment = "development"
revision = "1"
profile = "starter-default@1"
evaluation_profiles = ["starter-default@1"]
digest = "848749a4e1dabd438972f9ebe4e70b259d14151992e287af9a0d98b15c858875"

The Starter combines this environment with development-options@1.toml, a backend-owned allow-list of STT, LLM, and TTS targets. DevelopmentEvaluationCatalog.public_summary() reports each target's safe provider/model label, supported languages and voices, and whether its integration and credential are ready.

The browser selects one target for each role:

{
  "language": "en-IN",
  "selection": {
    "speech_recognition": "stt-deepgram-nova-3",
    "reasoning": "llm-ai-studio-gemini-3-5-flash",
    "speech_generation": "tts-smallest-lightning-v3-1-pro",
    "voice": "meher"
  }
}

The IDs must come from that exact backend response. The browser cannot add a provider, send arbitrary settings, or select a route whose package, credential, language, or voice is unavailable. The backend validates the selection again before dispatching it as private job metadata to the single worker.

Generated production environment

schema = "vaani.environment.v1"
environment = "production"
revision = "1"
profile = "starter-default@1"
production_deployment = "starter-production@1"
production_lock = "starter-production@1"
digest = "addc9699551fd60ee5d1ce92a712f8f73db9a524be2d22f052103a6b39bea405"

Production exposes no development route catalog. The named Production Deployment Profile and lock fix primary routes, ordered fallbacks, failure domains, resilience policy, preset, and environment identity. Production rejects profile selection, explicit null selection, and raw overrides.

Select one environment before backend or worker startup:

VAANI_ENVIRONMENT=development ./scripts/check
VAANI_ENVIRONMENT=production ./scripts/check

bootstrap_environment() accepts exactly development or production; it has no implicit default. The generated convenience scripts default local commands to development explicitly.

Presets are the simple configuration surface

A preset selects STT, LLM, TTS, languages, voices, streaming, VAD, endpointing, interruption, noise cancellation, standard tools, measurement, Judge slot, deadlines, and supported fallbacks. Use:

  • starter-default@1 for a multilingual Deepgram + Gemini 3 Flash Preview + SmallestAI browser bot;
  • basic-monolingual@1 for the smallest English/India compatibility bot;
  • birla-prod-v42@14 when you need its reviewed multilingual, production-compatible voice behavior.

The source default birla-prod-v42@14 is published in rc43. Historical rc42 installs remain paired with birla-prod-v42@13; pin that revision when reproducing the historical release.

The Birla @12 Judge authority includes redacted transcript, tool activity, and an allow-listed consumer evidence projection. Its Judge configuration must pass a bounded consumer_evidence= provider; published @6 remains immutable and does not enable that source.

Do not copy isolated settings between presets. Create and review a new preset revision when several bots need a different operational choice.

Safe overrides and secrets

In development, Assistant(overrides=...) accepts only a preset-declared language or voice before a call:

assistant = Assistant(
    name="Reception",
    preset="birla-prod-v42@14",
    prompt="Help the caller briefly.",
    overrides={"language": "hi-IN", "voice": "meher"},
)

Provider, model, temperature, speed, VAD, noise, deadline, and fallback are not Assistant overrides. Production-bound Assistants reject even the narrow raw overrides because the deployment lock already owns those choices.

TOML stores credential names, never values. Use .env locally and a secret manager in production. Keep prompts, customer data, transfer destinations, and credentials out of environment documents and locks.

Review a change

Create a new revision rather than editing an accepted document in place. Regenerate its digest and applicable production locks, review the diff, restart the worker, and place real browser and target-environment calls. Readiness means the local contract is usable; it does not mean providers, business APIs, or SIP were reached.

Exact fields and advanced deployment values are in the configuration reference.