Skip to content

Multi-Language Provider System Testing & Migration Guide ​

Table of Contents ​

  1. Pre-Migration Checklist
  2. Migration Procedure (Zero-Downtime)
  3. SuperAdmin UI Testing
  4. Customer Dashboard Testing
  5. Dispatch / Call Testing
  6. Rollback Plan

Pre-Migration Checklist ​

Before deploying the new code or running the migration:

  • [ ] Take a full MongoDB backup (mongodump or Atlas snapshot)
  • [ ] Confirm your .env has the correct MONGO_URI and DB_NAME for the target environment
  • [ ] Deploy the new backend code first (it's backward-compatible flat-field presets still work)
  • [ ] Confirm the app starts without errors and existing agents can still make calls

Migration Procedure ​

The migration is non-destructive and idempotent it only adds new data, never removes existing fields.

Why It Won't Break Production ​

  1. Flat fields remain untouched the migration adds language_combinations entries alongside (not replacing) existing flat provider fields
  2. PresetResolver falls back if an agent has no language set (all existing agents), the resolver uses flat fields exactly as before
  3. Voice tts_model is additive existing voices get a new field populated; existing code doesn't depend on it
  4. Idempotent running twice produces the same result (skips existing entries)

Step-by-Step ​

bash
# 1. Ensure backend is deployed with new code (backward-compatible)
# 2. Run migration in staging first
cd backend/client_backend
npx tsx src/scripts/migrate-language-combinations.ts

What the script does (3 phases):

PhaseActionImpact
1Populates tts_model on Voice documents that don't have itAdditive only new field
2Creates an initial language_combination entry from each preset's flat fieldsAdditive flat fields stay
3Seeds ProviderModel_Registry from distinct provider/model combosNew collection, no impact on existing

After running, check the summary output:

  • Voices updated / orphaned
  • Presets migrated / skipped
  • Registry entries seeded / already existing
  • Errors / warnings

Production Migration ​

bash
# In production, connect to the prod DB
MONGO_URI="mongodb+srv://..." DB_NAME="Oktivo-Prod" npx tsx src/scripts/migrate-language-combinations.ts

If anything fails, the script exits with code 1. Review warnings/errors in output. Re-running is safe.


SuperAdmin UI Testing ​

Step 1: Provider Registry Panel ​

Where: SuperAdmin Dashboard → Provider Registry (new section)

#TestExpected
1Navigate to Provider Registry pagePage loads, shows seeded entries from migration
2Filter by provider_type = "tts"Only TTS entries show
3Filter by language = "ar"Only entries with Arabic in supported_languages
4Create a new entry (e.g., TTS, "google", "wavenet-v2", languages: ["en-US", "ar"])Entry created, appears in list
5Try to create a duplicate (same type + provider + model)Error: "Duplicate entry exists" (409)
6Edit the entry change display_nameSaves correctly, other fields preserved
7Toggle is_active → OFFEntry shows inactive badge
8Try to delete an entry referenced by a presetError: "Cannot delete: referenced by X presets" (409)
9Delete an unreferenced entrySucceeds, entry removed from list
10Pagination: create 25+ entries, verify page navigationShows 20 per page, next/prev works

Step 2: Language Combination Editor (within Preset Editor) ​

Where: SuperAdmin → System Config → Edit a Preset

#TestExpected
1Open an existing preset (post-migration)See the initial language_combination that was created by migration
2Click "Add Language Combination"New empty row appears
3Select language_code "ar"Dropdowns filter to show only providers/models supporting Arabic
4Select LLM provider + modelOnly active registry entries appear
5Select TTS provider + modelOnly active entries with "ar" in supported_languages
6Select voiceOnly voices matching selected tts_provider + tts_model + "ar" language
7Try to add another entry with same language "ar"Inline error: "Duplicate language code: ar"
8Add a second entry with "fr-FR"Saves correctly, two entries shown
9Remove a language combinationEntry disappears, save succeeds
10Save preset with 21 entriesValidation error: "cannot exceed 20 entries"
11Save preset with a voice that doesn't match the TTS modelError: "Voice mismatches"
12Verify supported_languages field auto-derivesArray = union of all language_codes + default_tts_language

Step 3: Backward Compatibility ​

#TestExpected
1Save a preset with NO language_combinations (clear all)Saves successfully, flat fields remain
2Existing agents without language set still dispatchCall works exactly as before
3Save in old format from API (no language_combinations in payload)Accepted without error

Customer Dashboard Testing ​

Step 4: Agent Language Selection ​

Where: Customer Dashboard → Create/Edit Agent

#TestExpected
1Open agent tied to a preset with language_combinationsLanguage dropdown visible, populated with preset's supported_languages
2Open agent tied to a preset WITHOUT language_combinationsLanguage dropdown disabled or hidden
3Select "ar" from dropdownBackend resolves Arabic language_combination; displayed resolved providers update
4Select "en-US" from dropdownResolved providers switch to English stack
5Clear language selection (set to null)Agent uses flat preset defaults
6Try to select a language NOT in supported_languagesShould not appear in dropdown (filtered)
7Save agent with language "ar"Agent document persists language: "ar"
8Re-open agentLanguage dropdown shows "ar" selected, resolved providers shown correctly

Dispatch / Call Testing ​

Step 5: Language-Aware Calls ​

#TestExpected
1Make a test call with agent set to language "ar"Call dispatches with Arabic providers (check Agent Server logs)
2Check dispatch metadatallm_provider, tts_provider, stt_provider, tts_voice match the "ar" language_combination
3tts_language and stt_language in metadataBoth = "ar"
4Make a test call with agent set to language nullFalls back to flat preset providers
5Make a test call with agent whose language doesn't match any comboFalls back to flat fields, WARNING logged
6Make a web test call with language "ar"Same dispatch behavior as phone call

Step 6: Existing Agents (No Changes) ​

#TestExpected
1Test an existing agent that was never edited post-migrationCall works exactly as before (flat fallback)
2Check that language field is null on existing agentsConfirmed no behavior change
3Bulk test: run several existing agentsAll dispatch correctly without regression

Rollback Plan ​

If issues are found in production:

Quick Rollback (No Code Revert Needed) ​

The system is fully backward-compatible. If something goes wrong:

  1. Agents: Simply ensure language is null on affected agents they'll use flat fallback

    javascript
    // In MongoDB shell
    db.agents.updateMany({ language: { $ne: null } }, { $set: { language: null } })
  2. Presets: Language combinations are additive flat fields still work. Removing them is optional:

    javascript
    db.SystemConfig.updateMany({}, { $set: { "presets.$[].language_combinations": [] } })
  3. Registry: The ProviderModel_Registry collection can be dropped without impacting dispatch:

    javascript
    db.ProviderModel_Registry.drop()

Full Rollback (Code Revert) ​

  1. Revert to previous backend deployment
  2. Old code ignores language_combinations and language fields (they're just unused fields in MongoDB)
  3. No data loss migration only added fields, never removed

Quick Smoke Test Sequence (5 minutes) ​

After deployment + migration, run this minimal sequence to confirm nothing is broken:

  1. ✅ App starts without errors
  2. ✅ Make a test call with an existing agent (pre-migration, no language set) should work identically
  3. ✅ Open SuperAdmin → Provider Registry loads with seeded entries
  4. ✅ Open a preset editor → language_combinations section visible with migrated entry
  5. ✅ Create a new agent, select a language, make a test call → correct providers used
  6. ✅ Check dispatch logs for correct tts_language / stt_language

If all 6 pass, you're good to go.


Registry-First Workflow (Updated) ​

The system now enforces a strict workflow order:

1. Provider Registry  →  Register all LLM/TTS/STT provider+model combos
2. Preset             →  Create presets using registry dropdowns (no free-text)
3. Voice              →  Create voices tied to a specific provider + model
4. Agent              →  Assign preset + select language for dispatch

Key Changes from Original Design ​

AreaBeforeAfter
Preset provider/model fieldsFree-text inputsDropdowns from Provider Registry
Preset model fieldEditable stringSelect only from registered models for that provider
Language CombinationsManual entryAuto-populated on new preset (intersection of supported langs)
Default TTS/STT LanguageFree-textDropdown from available languages
Supported LanguagesManually typedAuto-derived from language_combinations (read-only)
Voice tts_modelNot requiredRequired dropdown from registered TTS models
Default Voice filterBy tts_provider onlyBy tts_provider + tts_model

Implications for SuperAdmins ​

  • Before creating a preset, ensure the desired LLM, TTS, and STT providers/models are all registered in Provider Registry
  • Before creating a voice, ensure the TTS provider + model are registered
  • When adding a new AI model (e.g., new OpenAI model), first add it to Provider Registry with its supported languages, then it becomes available in preset dropdowns

Auto Language Combination Logic ​

When creating a new preset:

  1. Select LLM provider + model
  2. Select TTS provider + model
  3. Select STT provider + model
  4. On save, the system computes the intersection of supported_languages across all three registry entries
  5. One language_combination entry is auto-created per intersecting language, using the preset's flat provider settings
  6. supported_languages is auto-derived from those entries

Example: If LLM supports [en, ar, fr], TTS supports [en, ar, hi], STT supports [en, ar], the intersection is [en, ar] → two language_combinations are auto-created.

Last updated: