@startsimpli/llm 0.4.29 → 0.4.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +76 -5
  2. package/bin/startsimpli-speech.js +22 -0
  3. package/package.json +10 -3
  4. package/src/__tests__/fixtures/captions-golden.json +1881 -0
  5. package/src/__tests__/fixtures/eleven-v3-tagged-alignment.json +1 -0
  6. package/src/__tests__/fixtures/voices-golden.json +614 -0
  7. package/src/__tests__/refine.test.ts +193 -0
  8. package/src/__tests__/speech-captions-cli.test.ts +37 -0
  9. package/src/__tests__/speech-captions.test.ts +136 -0
  10. package/src/__tests__/speech-cli.test.ts +67 -0
  11. package/src/__tests__/speech-synthesize.test.ts +277 -0
  12. package/src/__tests__/speech-voices-cli.test.ts +45 -0
  13. package/src/__tests__/speech-voices.test.ts +109 -0
  14. package/src/index.ts +3 -0
  15. package/src/refine/errors.ts +23 -0
  16. package/src/refine/gates.ts +55 -0
  17. package/src/refine/index.ts +11 -0
  18. package/src/refine/llm-step.ts +35 -0
  19. package/src/refine/refine.ts +81 -0
  20. package/src/refine/types.ts +54 -0
  21. package/src/speech/alignment.ts +48 -0
  22. package/src/speech/bin.ts +12 -0
  23. package/src/speech/captions/cues.ts +108 -0
  24. package/src/speech/captions/formats.ts +33 -0
  25. package/src/speech/captions/index.ts +6 -0
  26. package/src/speech/captions/types.ts +18 -0
  27. package/src/speech/captions/words.ts +91 -0
  28. package/src/speech/captions-cli.ts +50 -0
  29. package/src/speech/cli.ts +140 -0
  30. package/src/speech/http.ts +11 -4
  31. package/src/speech/index.ts +8 -2
  32. package/src/speech/interface.ts +7 -5
  33. package/src/speech/providers/elevenlabs-models.ts +34 -0
  34. package/src/speech/providers/elevenlabs-tts.ts +88 -0
  35. package/src/speech/providers/elevenlabs.ts +23 -5
  36. package/src/speech/providers/mock.ts +23 -3
  37. package/src/speech/providers/openai.ts +34 -3
  38. package/src/speech/repr.ts +14 -0
  39. package/src/speech/service.ts +25 -14
  40. package/src/speech/types.ts +55 -1
  41. package/src/speech/voices/cast-voices.json +127 -0
  42. package/src/speech/voices/cast-voices.ts +169 -0
  43. package/src/speech/voices/emotion.ts +51 -0
  44. package/src/speech/voices/errors.ts +14 -0
  45. package/src/speech/voices/index.ts +12 -0
  46. package/src/speech/voices/schema.ts +53 -0
  47. package/src/speech/voices/tags.ts +11 -0
  48. package/src/speech/voices-cli.ts +43 -0
@@ -0,0 +1 @@
1
+ {"text": "[excited] Most people use Claude Code li", "model": "eleven_v3", "alignment": {"characters": ["[", "e", "x", "c", "i", "t", "e", "d", "]", " ", "M", "o", "s", "t", " ", "p", "e", "o", "p", "l", "e", " ", "u", "s", "e", " ", "C", "l", "a", "u", "d", "e", " ", "C", "o", "d", "e", " ", "l", "i"], "character_start_times_seconds": [0.0, 0.048, 0.064, 0.08, 0.096, 0.108, 0.12, 0.132, 0.144, 0.192, 0.202, 0.211, 0.221, 0.23, 0.24, 0.297, 0.354, 0.411, 0.469, 0.526, 0.583, 0.64, 0.72, 0.8, 0.88, 0.96, 1.017, 1.074, 1.131, 1.189, 1.246, 1.303, 1.36, 1.44, 1.52, 1.6, 1.68, 1.76, 1.84, 1.92], "character_end_times_seconds": [0.048, 0.064, 0.08, 0.096, 0.108, 0.12, 0.132, 0.144, 0.192, 0.202, 0.211, 0.221, 0.23, 0.24, 0.297, 0.354, 0.411, 0.469, 0.526, 0.583, 0.64, 0.72, 0.8, 0.88, 0.96, 1.017, 1.074, 1.131, 1.189, 1.246, 1.303, 1.36, 1.44, 1.52, 1.6, 1.68, 1.76, 1.84, 1.92, 2.0]}}
@@ -0,0 +1,614 @@
1
+ [
2
+ {
3
+ "expected": {
4
+ "voices": {
5
+ "leo": {
6
+ "language": null,
7
+ "model": "eleven_v3",
8
+ "role": "engineer",
9
+ "settings": {
10
+ "stability": 0.5
11
+ },
12
+ "voice_id": "jSuBIjxMKhqIfb0wCK1F"
13
+ },
14
+ "maya": {
15
+ "language": null,
16
+ "model": "eleven_v3",
17
+ "role": "presenter",
18
+ "settings": {
19
+ "stability": 0.35
20
+ },
21
+ "voice_id": "rdEyNni8e60Jlx1RsV9N"
22
+ }
23
+ },
24
+ "warnings": []
25
+ },
26
+ "name": "saved-timeline aliases fall to the pool in order",
27
+ "request": {
28
+ "cast": [
29
+ {
30
+ "character": "presenter",
31
+ "id": "maya",
32
+ "voice": "maya"
33
+ },
34
+ {
35
+ "character": "engineer",
36
+ "id": "leo",
37
+ "voice": "leo"
38
+ }
39
+ ]
40
+ }
41
+ },
42
+ {
43
+ "expected": {
44
+ "voices": {
45
+ "a": {
46
+ "language": null,
47
+ "model": "eleven_v3",
48
+ "role": "manager",
49
+ "settings": {
50
+ "stability": 0.5
51
+ },
52
+ "voice_id": "FrS6cKLB1wg4WYgPa9GW"
53
+ },
54
+ "b": {
55
+ "language": null,
56
+ "model": "eleven_v3",
57
+ "role": null,
58
+ "settings": {},
59
+ "voice_id": "AbCdEfGhIjKlMnOpQrSt"
60
+ }
61
+ },
62
+ "warnings": []
63
+ },
64
+ "name": "library id and real voice id",
65
+ "request": {
66
+ "cast": [
67
+ {
68
+ "id": "a",
69
+ "voice": "manager"
70
+ },
71
+ {
72
+ "id": "b",
73
+ "voice": "AbCdEfGhIjKlMnOpQrSt"
74
+ }
75
+ ]
76
+ }
77
+ },
78
+ {
79
+ "expected": {
80
+ "voices": {
81
+ "a": {
82
+ "language": null,
83
+ "model": "eleven_v3",
84
+ "role": "clone_1",
85
+ "settings": {
86
+ "stability": 0.5
87
+ },
88
+ "voice_id": "WBpAa2ue6cyOek99incw"
89
+ },
90
+ "b": {
91
+ "language": null,
92
+ "model": "eleven_v3",
93
+ "role": "presenter",
94
+ "settings": {
95
+ "stability": 0.35
96
+ },
97
+ "voice_id": "rdEyNni8e60Jlx1RsV9N"
98
+ },
99
+ "c": {
100
+ "language": null,
101
+ "model": "eleven_v3",
102
+ "role": "engineer",
103
+ "settings": {
104
+ "stability": 0.5
105
+ },
106
+ "voice_id": "jSuBIjxMKhqIfb0wCK1F"
107
+ }
108
+ },
109
+ "warnings": []
110
+ },
111
+ "name": "explicit voices do not use pool places",
112
+ "request": {
113
+ "cast": [
114
+ {
115
+ "id": "a",
116
+ "voice": "clone_1"
117
+ },
118
+ {
119
+ "id": "b"
120
+ },
121
+ {
122
+ "id": "c",
123
+ "voice": "x"
124
+ }
125
+ ]
126
+ }
127
+ },
128
+ {
129
+ "expected": {
130
+ "voices": {
131
+ "leo": {
132
+ "language": null,
133
+ "model": "eleven_multilingual_v2",
134
+ "role": "engineer",
135
+ "settings": {
136
+ "similarity_boost": 0.8,
137
+ "speed": 1.0,
138
+ "stability": 0.5,
139
+ "style": 0.2
140
+ },
141
+ "voice_id": "jSuBIjxMKhqIfb0wCK1F"
142
+ },
143
+ "maya": {
144
+ "language": null,
145
+ "model": "eleven_multilingual_v2",
146
+ "role": "presenter",
147
+ "settings": {
148
+ "similarity_boost": 0.75,
149
+ "speed": 1.0,
150
+ "stability": 0.35,
151
+ "style": 0.5
152
+ },
153
+ "voice_id": "rdEyNni8e60Jlx1RsV9N"
154
+ }
155
+ },
156
+ "warnings": []
157
+ },
158
+ "name": "model override",
159
+ "request": {
160
+ "cast": [
161
+ {
162
+ "character": "presenter",
163
+ "id": "maya",
164
+ "voice": "maya"
165
+ },
166
+ {
167
+ "character": "engineer",
168
+ "id": "leo",
169
+ "voice": "leo"
170
+ }
171
+ ],
172
+ "model": "eleven_multilingual_v2"
173
+ }
174
+ },
175
+ {
176
+ "expected": {
177
+ "voices": {
178
+ "m": {
179
+ "language": "es",
180
+ "model": "eleven_multilingual_v2",
181
+ "role": "presenter",
182
+ "settings": {
183
+ "similarity_boost": 0.75,
184
+ "speed": 1.0,
185
+ "stability": 0.35,
186
+ "style": 0.5
187
+ },
188
+ "voice_id": "AAAAAAAAAAAAAAAAAAAA"
189
+ },
190
+ "n": {
191
+ "language": "es",
192
+ "model": "eleven_multilingual_v2",
193
+ "role": "engineer",
194
+ "settings": {
195
+ "similarity_boost": 0.8,
196
+ "speed": 1.0,
197
+ "stability": 0.5,
198
+ "style": 0.2
199
+ },
200
+ "voice_id": "jSuBIjxMKhqIfb0wCK1F"
201
+ }
202
+ },
203
+ "warnings": []
204
+ },
205
+ "name": "language picks model and voice",
206
+ "request": {
207
+ "cast": [
208
+ {
209
+ "id": "m",
210
+ "voice": "presenter"
211
+ },
212
+ {
213
+ "id": "n",
214
+ "voice": "engineer"
215
+ }
216
+ ],
217
+ "language": "es",
218
+ "libraryPatch": {
219
+ "languages": {
220
+ "en": {
221
+ "default": true
222
+ },
223
+ "es": {
224
+ "model": "eleven_multilingual_v2",
225
+ "rhubarb_recognizer": "phonetic",
226
+ "roles": {
227
+ "presenter": {
228
+ "voice_id": "AAAAAAAAAAAAAAAAAAAA"
229
+ }
230
+ }
231
+ },
232
+ "fr": {
233
+ "model": "eleven_multilingual_v2",
234
+ "rhubarb_recognizer": "phonetic"
235
+ }
236
+ }
237
+ }
238
+ }
239
+ },
240
+ {
241
+ "expected": {
242
+ "voices": {
243
+ "m": {
244
+ "language": "es",
245
+ "model": "eleven_multilingual_v2",
246
+ "role": "presenter",
247
+ "settings": {
248
+ "similarity_boost": 0.75,
249
+ "speed": 1.0,
250
+ "stability": 0.35,
251
+ "style": 0.5
252
+ },
253
+ "voice_id": "AAAAAAAAAAAAAAAAAAAA"
254
+ }
255
+ },
256
+ "warnings": []
257
+ },
258
+ "name": "region falls back to base language",
259
+ "request": {
260
+ "cast": [
261
+ {
262
+ "id": "m",
263
+ "voice": "presenter"
264
+ }
265
+ ],
266
+ "language": "es-MX",
267
+ "libraryPatch": {
268
+ "languages": {
269
+ "en": {
270
+ "default": true
271
+ },
272
+ "es": {
273
+ "model": "eleven_multilingual_v2",
274
+ "rhubarb_recognizer": "phonetic",
275
+ "roles": {
276
+ "presenter": {
277
+ "voice_id": "AAAAAAAAAAAAAAAAAAAA"
278
+ }
279
+ }
280
+ },
281
+ "fr": {
282
+ "model": "eleven_multilingual_v2",
283
+ "rhubarb_recognizer": "phonetic"
284
+ }
285
+ }
286
+ }
287
+ }
288
+ },
289
+ {
290
+ "expected": {
291
+ "voices": {
292
+ "leo": {
293
+ "language": null,
294
+ "model": "eleven_v3",
295
+ "role": "engineer",
296
+ "settings": {
297
+ "stability": 0.5
298
+ },
299
+ "voice_id": "jSuBIjxMKhqIfb0wCK1F"
300
+ },
301
+ "maya": {
302
+ "language": null,
303
+ "model": "eleven_v3",
304
+ "role": "presenter",
305
+ "settings": {
306
+ "stability": 0.35
307
+ },
308
+ "voice_id": "rdEyNni8e60Jlx1RsV9N"
309
+ }
310
+ },
311
+ "warnings": []
312
+ },
313
+ "name": "default language is the unchanged path",
314
+ "request": {
315
+ "cast": [
316
+ {
317
+ "character": "presenter",
318
+ "id": "maya",
319
+ "voice": "maya"
320
+ },
321
+ {
322
+ "character": "engineer",
323
+ "id": "leo",
324
+ "voice": "leo"
325
+ }
326
+ ],
327
+ "language": "en-GB"
328
+ }
329
+ },
330
+ {
331
+ "expected": {
332
+ "voices": {
333
+ "m": {
334
+ "language": "es",
335
+ "model": "eleven_v3",
336
+ "role": "presenter",
337
+ "settings": {
338
+ "stability": 0.35
339
+ },
340
+ "voice_id": "AAAAAAAAAAAAAAAAAAAA"
341
+ }
342
+ },
343
+ "warnings": []
344
+ },
345
+ "name": "explicit model beats the language model",
346
+ "request": {
347
+ "cast": [
348
+ {
349
+ "id": "m",
350
+ "voice": "presenter"
351
+ }
352
+ ],
353
+ "language": "es",
354
+ "libraryPatch": {
355
+ "languages": {
356
+ "en": {
357
+ "default": true
358
+ },
359
+ "es": {
360
+ "model": "eleven_multilingual_v2",
361
+ "rhubarb_recognizer": "phonetic",
362
+ "roles": {
363
+ "presenter": {
364
+ "voice_id": "AAAAAAAAAAAAAAAAAAAA"
365
+ }
366
+ }
367
+ },
368
+ "fr": {
369
+ "model": "eleven_multilingual_v2",
370
+ "rhubarb_recognizer": "phonetic"
371
+ }
372
+ }
373
+ },
374
+ "model": "eleven_v3"
375
+ }
376
+ },
377
+ {
378
+ "expected": {
379
+ "error": {
380
+ "kind": "not_resolvable",
381
+ "message": "language 'xx' is not in the cast voice file; known: ['de', 'en', 'es', 'fr', 'it', 'ja', 'pt']"
382
+ },
383
+ "warnings": []
384
+ },
385
+ "name": "unknown language",
386
+ "request": {
387
+ "cast": [
388
+ {
389
+ "character": "presenter",
390
+ "id": "maya",
391
+ "voice": "maya"
392
+ },
393
+ {
394
+ "character": "engineer",
395
+ "id": "leo",
396
+ "voice": "leo"
397
+ }
398
+ ],
399
+ "language": "xx"
400
+ }
401
+ },
402
+ {
403
+ "expected": {
404
+ "error": {
405
+ "kind": "unfilled",
406
+ "message": "voice slot 'open_slot_1' is empty: INPUT bspike-448.15.22.10: pick or design this voice (the sidekick's). Set voice_id and settings.<model> here."
407
+ },
408
+ "warnings": []
409
+ },
410
+ "name": "unfilled slot",
411
+ "request": {
412
+ "cast": [
413
+ {
414
+ "id": "s",
415
+ "voice": "open_slot_1"
416
+ }
417
+ ]
418
+ }
419
+ },
420
+ {
421
+ "expected": {
422
+ "error": {
423
+ "kind": "not_resolvable",
424
+ "message": "voice 21m00Tcm4TlvDq8ikWAM is retired: Rachel: dead on the v1 pool (402)"
425
+ },
426
+ "warnings": []
427
+ },
428
+ "name": "retired id",
429
+ "request": {
430
+ "cast": [
431
+ {
432
+ "id": "x",
433
+ "voice": "21m00Tcm4TlvDq8ikWAM"
434
+ }
435
+ ]
436
+ }
437
+ },
438
+ {
439
+ "expected": {
440
+ "error": {
441
+ "kind": "not_resolvable",
442
+ "message": "unknown model 'eleven_nonexistent'; known: ['eleven_flash_v2_5', 'eleven_multilingual_v2', 'eleven_v3', 'eleven_v3_conversational', 'eleven_v4', 'eleven_v4_turbo']"
443
+ },
444
+ "warnings": []
445
+ },
446
+ "name": "unknown model",
447
+ "request": {
448
+ "cast": [
449
+ {
450
+ "id": "x",
451
+ "voice": "presenter"
452
+ }
453
+ ],
454
+ "model": "eleven_nonexistent"
455
+ }
456
+ },
457
+ {
458
+ "expected": {
459
+ "error": {
460
+ "kind": "not_resolvable",
461
+ "message": "cast members 'a' and 'b' resolve to the same voice rdEyNni8e60Jlx1RsV9N"
462
+ },
463
+ "warnings": []
464
+ },
465
+ "name": "two members on one voice",
466
+ "request": {
467
+ "cast": [
468
+ {
469
+ "id": "a",
470
+ "voice": "presenter"
471
+ },
472
+ {
473
+ "id": "b",
474
+ "voice": "presenter"
475
+ }
476
+ ]
477
+ }
478
+ },
479
+ {
480
+ "expected": {
481
+ "error": {
482
+ "kind": "not_resolvable",
483
+ "message": "cast member 'z': no voice reference (None) and no pool place; library: ['ai_assistant', 'clone_1', 'customer', 'engineer', 'manager', 'open_slot_1', 'presenter', 'santa']"
484
+ },
485
+ "warnings": []
486
+ },
487
+ "name": "no voice and empty pool",
488
+ "request": {
489
+ "cast": [
490
+ {
491
+ "id": "z"
492
+ }
493
+ ],
494
+ "libraryPatch": {
495
+ "default_pool": []
496
+ }
497
+ }
498
+ },
499
+ {
500
+ "expected": {
501
+ "voices": {
502
+ "x": {
503
+ "language": null,
504
+ "model": "eleven_v3",
505
+ "role": null,
506
+ "settings": {},
507
+ "voice_id": "cgSgspJ2msm6clMCkdW9"
508
+ }
509
+ },
510
+ "warnings": [
511
+ "voice cgSgspJ2msm6clMCkdW9 (Jessica) is a Default voice that expires 2026-12-31"
512
+ ]
513
+ },
514
+ "name": "expiring warns before the deadline",
515
+ "request": {
516
+ "cast": [
517
+ {
518
+ "id": "x",
519
+ "voice": "cgSgspJ2msm6clMCkdW9"
520
+ }
521
+ ],
522
+ "today": "2026-11-02"
523
+ }
524
+ },
525
+ {
526
+ "expected": {
527
+ "error": {
528
+ "kind": "not_resolvable",
529
+ "message": "voice cgSgspJ2msm6clMCkdW9 (Jessica) is a Default voice that expires 2026-12-31"
530
+ },
531
+ "warnings": []
532
+ },
533
+ "name": "expiring errors on the deadline",
534
+ "request": {
535
+ "cast": [
536
+ {
537
+ "id": "x",
538
+ "voice": "cgSgspJ2msm6clMCkdW9"
539
+ }
540
+ ],
541
+ "today": "2026-12-31"
542
+ }
543
+ },
544
+ {
545
+ "expected": {
546
+ "voices": {
547
+ "x": {
548
+ "language": null,
549
+ "model": "eleven_v3",
550
+ "role": null,
551
+ "settings": {},
552
+ "voice_id": "cgSgspJ2msm6clMCkdW9"
553
+ }
554
+ },
555
+ "warnings": []
556
+ },
557
+ "name": "expiring allow is silent after the deadline",
558
+ "request": {
559
+ "cast": [
560
+ {
561
+ "id": "x",
562
+ "voice": "cgSgspJ2msm6clMCkdW9"
563
+ }
564
+ ],
565
+ "expiring": "allow",
566
+ "today": "2027-06-01"
567
+ }
568
+ },
569
+ {
570
+ "expected": {
571
+ "error": {
572
+ "kind": "not_resolvable",
573
+ "message": "voice cgSgspJ2msm6clMCkdW9 (Jessica) is a Default voice that expires 2026-12-31"
574
+ },
575
+ "warnings": []
576
+ },
577
+ "name": "expiring error policy errors before the deadline",
578
+ "request": {
579
+ "cast": [
580
+ {
581
+ "id": "x",
582
+ "voice": "cgSgspJ2msm6clMCkdW9"
583
+ }
584
+ ],
585
+ "expiring": "error",
586
+ "today": "2026-01-01"
587
+ }
588
+ },
589
+ {
590
+ "expected": {
591
+ "error": {
592
+ "kind": "not_resolvable",
593
+ "message": "cast members 'x' and 'y' resolve to the same voice cgSgspJ2msm6clMCkdW9"
594
+ },
595
+ "warnings": [
596
+ "voice cgSgspJ2msm6clMCkdW9 (Jessica) is a Default voice that expires 2026-12-31"
597
+ ]
598
+ },
599
+ "name": "expiring voice shared by two members warns then fails on the duplicate",
600
+ "request": {
601
+ "cast": [
602
+ {
603
+ "id": "x",
604
+ "voice": "cgSgspJ2msm6clMCkdW9"
605
+ },
606
+ {
607
+ "id": "y",
608
+ "voice": "cgSgspJ2msm6clMCkdW9"
609
+ }
610
+ ],
611
+ "today": "2026-11-02"
612
+ }
613
+ }
614
+ ]