Found by @Joilence during review of #36. Pre-existing on main, unrelated to that PR's packaging work.
The bug
src/tts/engines/sarvam.ts destructures the default export:
({ default: SarvamAI } = await import('sarvamai'));
// ...
const client = new SarvamAI({ apiSubscriptionKey: this.resolveApiKey() });
sarvamai@1.1.8 has no default export, and SarvamAI is a namespace object, not a constructor. The client class is exported as SarvamAIClient:
$ node --input-type=module -e "const m = await import('sarvamai'); \
console.log('default:', typeof m.default); \
console.log('SarvamAI:', typeof m.SarvamAI); \
console.log('SarvamAIClient:', typeof m.SarvamAIClient)"
default: undefined
SarvamAI: object
SarvamAIClient: function
So new SarvamAI(...) throws SarvamAI is not a constructor for every user who has the package correctly installed. The engine has never worked.
Why it went unnoticed
The try/catch around the import only wraps the import() itself, and reports any failure as "requires the 'sarvamai' package". The new call is outside it, so the actual failure is a bare TypeError at a line that looks unrelated to the import. Nothing in the suite covers it — sarvamai isn't installed on main, so there's no test that could have caught it.
Fix
Destructure the named export instead:
const { SarvamAIClient } = await import('sarvamai');
const client = new SarvamAIClient({ apiSubscriptionKey: this.resolveApiKey() });
Not yet verified
Whether the convert() call underneath is also wrong — that needs a live Sarvam API key to exercise. The constructor fix is necessary but may not be sufficient.
Once #36 lands, sarvamai becomes a devDependency and is mockable, so this should ship with a test asserting the client is constructed and convert() receives the expected payload — the same shape as tests/tts/mlx-audio.test.ts.
Found by @Joilence during review of #36. Pre-existing on
main, unrelated to that PR's packaging work.The bug
src/tts/engines/sarvam.tsdestructures the default export:sarvamai@1.1.8has no default export, andSarvamAIis a namespace object, not a constructor. The client class is exported asSarvamAIClient:So
new SarvamAI(...)throwsSarvamAI is not a constructorfor every user who has the package correctly installed. The engine has never worked.Why it went unnoticed
The
try/catcharound the import only wraps theimport()itself, and reports any failure as "requires the 'sarvamai' package". Thenewcall is outside it, so the actual failure is a bareTypeErrorat a line that looks unrelated to the import. Nothing in the suite covers it —sarvamaiisn't installed onmain, so there's no test that could have caught it.Fix
Destructure the named export instead:
Not yet verified
Whether the
convert()call underneath is also wrong — that needs a live Sarvam API key to exercise. The constructor fix is necessary but may not be sufficient.Once #36 lands,
sarvamaibecomes a devDependency and is mockable, so this should ship with a test asserting the client is constructed andconvert()receives the expected payload — the same shape astests/tts/mlx-audio.test.ts.