File size: 4,523 Bytes
5dbdf6e
 
 
 
 
 
 
c32bddc
 
 
 
 
 
 
5dbdf6e
 
 
 
 
 
 
 
 
b87bd2d
5dbdf6e
 
 
 
 
 
c32bddc
5dbdf6e
 
 
 
c32bddc
 
5dbdf6e
c32bddc
5dbdf6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c32bddc
 
5dbdf6e
c32bddc
 
 
 
 
 
 
 
 
 
5dbdf6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c32bddc
5dbdf6e
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"""Smoke-test every provider before building anything on top.

Run from project root:
  python -m backend.providers._smoke_test

Each test prints OK/FAIL and the response. Failures here will surface in the
build before they surface in the UI.

Stack A providers (post-2026-05-14, D-019):
  - Sarvam-M LLM β€” Indic translation (Hindi/Hinglish/vernacular)
  - Sarvam Bulbul TTS β€” voice synthesis
  - Sarvam Saarika STT β€” voice recognition
  - Local BGE embeddings (no network)
  - NVIDIA NIM brain β€” DeepSeek-V4-Pro
"""

from __future__ import annotations

import asyncio
import traceback

from backend.config import settings
from backend.providers.base import ChatMessage
from backend.providers.nvidia_nim_llm import get_brain_llm
from backend.providers.sarvam_llm import SarvamLLM
from backend.providers.sarvam_stt import SarvamSTT
from backend.providers.sarvam_tts import SarvamTTS


async def test_sarvam_llm():
    print("\n--- Sarvam-M LLM (Indic translation only) ---")
    try:
        client = SarvamLLM()
        result = await client.chat(
            messages=[
                ChatMessage(role="system", content="You are a translator. Translate to Hindi."),
                ChatMessage(role="user", content="The sum insured is the maximum amount your policy will pay."),
            ],
            max_tokens=120,
        )
        print(f"OK | model={result.model} | reply: {result.text[:200]}")
        print(f"   tokens prompt={result.prompt_tokens} completion={result.completion_tokens}")
        return True
    except Exception as e:
        print(f"FAIL | {type(e).__name__}: {e}")
        traceback.print_exc()
        return False


async def test_sarvam_tts():
    print("\n--- Sarvam Bulbul TTS ---")
    try:
        client = SarvamTTS()
        audio = await client.synthesize(
            text="Hello, I am your insurance advisor.",
            language_code="en-IN",
        )
        print(f"OK | got {len(audio)} bytes of audio")
        out = settings.CORPUS_DIR.parent / "_smoke_tts.wav"
        out.write_bytes(audio)
        print(f"   saved to {out.relative_to(settings.CORPUS_DIR.parent.parent)}")
        return True
    except Exception as e:
        print(f"FAIL | {type(e).__name__}: {e}")
        traceback.print_exc()
        return False


async def test_nim_brain():
    print("\n--- NIM DeepSeek-V4-Pro (THE brain β€” Stack A primary) ---")
    try:
        client = get_brain_llm()
        result = await client.chat(
            messages=[
                ChatMessage(role="system", content="You are a precise insurance advisor."),
                ChatMessage(role="user", content="Briefly: what does 'sum insured' mean in health insurance? Under 25 words."),
            ],
            max_tokens=120,
            temperature=0.2,
        )
        print(f"OK | model={result.model} | reply: {result.text[:200]}")
        return True
    except Exception as e:
        print(f"FAIL | {type(e).__name__}: {e}")
        traceback.print_exc()
        return False


async def test_sarvam_stt():
    """STT needs an audio file. We reuse the TTS output if it ran successfully."""
    print("\n--- Sarvam Saarika STT ---")
    try:
        audio_path = settings.CORPUS_DIR.parent / "_smoke_tts.wav"
        if not audio_path.exists():
            print("SKIP | no _smoke_tts.wav (TTS must run first)")
            return False
        audio_bytes = audio_path.read_bytes()
        client = SarvamSTT()
        result = await client.transcribe(
            audio_bytes=audio_bytes,
            audio_format="wav",
            language_code="en-IN",
        )
        print(f"OK | transcript: {result.text!r}")
        print(f"   language={result.language_code} confidence={result.confidence}")
        return True
    except Exception as e:
        print(f"FAIL | {type(e).__name__}: {e}")
        traceback.print_exc()
        return False


async def main():
    missing = settings.validate()
    if missing:
        print(f"WARN | missing keys: {missing}")

    results = {}
    results["nim_brain"] = await test_nim_brain()
    results["sarvam_llm"] = await test_sarvam_llm()
    results["sarvam_tts"] = await test_sarvam_tts()
    results["sarvam_stt"] = await test_sarvam_stt()  # depends on TTS output

    print("\n========== SUMMARY ==========")
    for name, ok in results.items():
        print(f"  {name:>20s}: {'OK' if ok else 'FAIL'}")
    print(f"\n{sum(results.values())}/{len(results)} providers healthy.")


if __name__ == "__main__":
    asyncio.run(main())