@moolam/bindings-speech 1.0.0

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 (52) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +41 -0
  3. package/bin/speech-cert.mjs +11 -0
  4. package/certification/README.md +18 -0
  5. package/certification/device-profiles/mid-range-android.json +12 -0
  6. package/certification/profile.json +33 -0
  7. package/certification/prove-speech-cert.mjs +11 -0
  8. package/certification/reports/prove.green1.speech.cert.json +92 -0
  9. package/certification/reports/prove.seeded-red.speech.cert.json +70 -0
  10. package/certification/reports/speech.cert.json +92 -0
  11. package/certification/run-speech-cert.mjs +11 -0
  12. package/certification/schemas/speech.cert.report.schema.json +149 -0
  13. package/certification/voice-rtt.baseline.json +12 -0
  14. package/dist/edge_stt_harness.d.ts +86 -0
  15. package/dist/edge_stt_harness.d.ts.map +1 -0
  16. package/dist/edge_stt_harness.js +311 -0
  17. package/dist/edge_stt_harness.js.map +1 -0
  18. package/dist/index.d.ts +10 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +10 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/speech_certification.d.ts +149 -0
  23. package/dist/speech_certification.d.ts.map +1 -0
  24. package/dist/speech_certification.js +490 -0
  25. package/dist/speech_certification.js.map +1 -0
  26. package/dist/stt_binding.d.ts +148 -0
  27. package/dist/stt_binding.d.ts.map +1 -0
  28. package/dist/stt_binding.js +400 -0
  29. package/dist/stt_binding.js.map +1 -0
  30. package/dist/tts_binding.d.ts +187 -0
  31. package/dist/tts_binding.d.ts.map +1 -0
  32. package/dist/tts_binding.js +565 -0
  33. package/dist/tts_binding.js.map +1 -0
  34. package/dist/voice_rtt_proof.d.ts +112 -0
  35. package/dist/voice_rtt_proof.d.ts.map +1 -0
  36. package/dist/voice_rtt_proof.js +241 -0
  37. package/dist/voice_rtt_proof.js.map +1 -0
  38. package/dist/whisper_ffi.d.ts +44 -0
  39. package/dist/whisper_ffi.d.ts.map +1 -0
  40. package/dist/whisper_ffi.js +104 -0
  41. package/dist/whisper_ffi.js.map +1 -0
  42. package/fixtures/indic/audio/en-classroom.pcm +0 -0
  43. package/fixtures/indic/audio/hi-classroom-noise.pcm +0 -0
  44. package/fixtures/indic/audio/hi-en-codeswitch.pcm +0 -0
  45. package/fixtures/indic/audio/hi-greeting.pcm +0 -0
  46. package/fixtures/indic/audio/short-hi.pcm +0 -0
  47. package/fixtures/indic/audio/ta-greeting.pcm +0 -0
  48. package/fixtures/indic/catalog.json +75 -0
  49. package/fixtures/indic/supported-languages.json +8 -0
  50. package/fixtures/tts/tts-voices.model-card.json +41 -0
  51. package/fixtures/tts/voices.json +24 -0
  52. package/package.json +55 -0
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Local TTS behind SpeechInterface.synthesize.
3
+ *
4
+ * supportedLanguages lists only languages with loaded voice models.
5
+ * Unsupported BCP-47 codes route to the declared fallback language and
6
+ * surface `outcome: "fallback"` telemetry — never throw, never silent
7
+ * English substitution without that signal.
8
+ */
9
+ import type { AudioChunk, SpeechInterface, SpeechSynthesisOptions, TranscriptSegment } from "@moolam/contracts";
10
+ import type { SpeechConformanceHarness } from "@moolam/contract-conformance";
11
+ export declare const TTS_PACKAGE_ROOT: string;
12
+ export declare const DEFAULT_TTS_VOICES_MANIFEST: string;
13
+ /** Human+machine Indic TTS coverage card (language → voice + fallback policy). */
14
+ export declare const DEFAULT_TTS_MODEL_CARD: string;
15
+ export declare const LOCAL_TTS_ENGINE = "local-tts-v1";
16
+ export declare const TTS_SAMPLE_RATE_HZ = 16000;
17
+ export declare const TTS_STREAM_CHUNK_LIMIT = 64;
18
+ /** Max UTF-16 code units accepted per synthesize call (NFR / scalability). */
19
+ export declare const TTS_TEXT_CHAR_LIMIT = 4096;
20
+ /** PCM samples per streamed audio chunk (~40ms @ 16kHz). */
21
+ export declare const TTS_SAMPLES_PER_CHUNK = 640;
22
+ export type TtsVoiceCard = {
23
+ voiceId: string;
24
+ language: string;
25
+ sampleRateHz: number;
26
+ };
27
+ export type TtsVoicesManifest = {
28
+ schemaVersion: string;
29
+ engine: string;
30
+ fallbackLanguage: string;
31
+ voices: TtsVoiceCard[];
32
+ mixedScriptPolicy?: string;
33
+ description?: string;
34
+ };
35
+ export type TtsLanguageVoiceCoverageRow = {
36
+ language: string;
37
+ voiceId: string;
38
+ sampleRateHz: number;
39
+ script: string;
40
+ role: string;
41
+ };
42
+ export type TtsVoiceModelCard = {
43
+ schemaVersion: string;
44
+ engine: string;
45
+ locality: "on-device" | "self-hosted";
46
+ description: string;
47
+ fallbackLanguage: string;
48
+ fallbackPolicy: {
49
+ unsupportedBcp47: string;
50
+ emptyText: string;
51
+ mixedScript: string;
52
+ };
53
+ coverage: TtsLanguageVoiceCoverageRow[];
54
+ observability: {
55
+ event: string;
56
+ neverEmit: string;
57
+ requiredFields: string[];
58
+ };
59
+ voicesManifestRelpath: string;
60
+ };
61
+ export type LocalTtsTelemetryOp = "load" | "unload" | "synthesize" | "transcribe";
62
+ /** Metadata-only telemetry — never raw synthesis text bodies. */
63
+ export type LocalTtsTelemetryEvent = {
64
+ event: "bindings_speech.tts";
65
+ op: LocalTtsTelemetryOp;
66
+ outcome: "ok" | "error" | "fallback";
67
+ subjectId: string;
68
+ deviceId: string;
69
+ engine: typeof LOCAL_TTS_ENGINE;
70
+ languageCount?: number;
71
+ chunkCount?: number;
72
+ /** Effective BCP-47 after fallback resolution. */
73
+ effectiveLanguage?: string;
74
+ /** Requested BCP-47 (may differ when fallback fired). */
75
+ requestedLanguage?: string;
76
+ voiceId?: string;
77
+ usedFallback?: boolean;
78
+ failureClass?: "config" | "validation" | "not_loaded" | "native";
79
+ detail?: string;
80
+ };
81
+ export type LoadLocalTtsOptions = {
82
+ subjectId: string;
83
+ deviceId: string;
84
+ voicesManifestPath?: string;
85
+ onTelemetry?: (event: LocalTtsTelemetryEvent) => void;
86
+ backend?: LocalTtsNativeBackend;
87
+ };
88
+ export declare class LocalTtsError extends Error {
89
+ readonly failureClass: NonNullable<LocalTtsTelemetryEvent["failureClass"]>;
90
+ constructor(message: string, failureClass: NonNullable<LocalTtsTelemetryEvent["failureClass"]>);
91
+ }
92
+ export type LocalTtsNativeHandle = {
93
+ readonly id: string;
94
+ };
95
+ export type LocalTtsSynthesizeNativeParams = {
96
+ text: string;
97
+ language: string;
98
+ voiceId: string;
99
+ sampleRateHz: number;
100
+ speakingRate: number;
101
+ signal?: AbortSignal;
102
+ };
103
+ export type LocalTtsSynthesizeNativeResult = {
104
+ /** Streamed PCM chunks (s16le mono). */
105
+ chunks: Uint8Array[];
106
+ sampleRateHz: number;
107
+ };
108
+ export type LocalTtsNativeBackend = {
109
+ readonly kind: "in-process" | "native-addon";
110
+ load(modelId: string): Promise<LocalTtsNativeHandle>;
111
+ unload(handle: LocalTtsNativeHandle): Promise<void>;
112
+ synthesize(handle: LocalTtsNativeHandle, params: LocalTtsSynthesizeNativeParams): Promise<LocalTtsSynthesizeNativeResult>;
113
+ };
114
+ /**
115
+ * In-process local TTS stand-in: streams PCM chunks; mixed-script text
116
+ * does not crash. Production injects a real on-device TTS addon.
117
+ */
118
+ export declare function createInProcessLocalTtsBackend(): LocalTtsNativeBackend;
119
+ export declare function loadTtsVoicesManifest(manifestPath?: string): TtsVoicesManifest;
120
+ /** Languages actually backed by a loaded voice model (truthful declaration). */
121
+ export declare function languagesFromVoices(voices: readonly TtsVoiceCard[]): string[];
122
+ /**
123
+ * Load the TTS voice model card and require parity with the voices manifest
124
+ * (language set, voiceIds, fallbackLanguage). Coverage is never aspirational.
125
+ */
126
+ export declare function loadTtsVoiceModelCard(cardPath?: string, voicesManifestPath?: string): TtsVoiceModelCard;
127
+ /** Language → voiceId rows for README / hosts (order matches model card). */
128
+ export declare function languageVoiceCoverageTable(card?: TtsVoiceModelCard): ReadonlyArray<{
129
+ language: string;
130
+ voiceId: string;
131
+ role: string;
132
+ }>;
133
+ export declare function assertTtsModelCardMatchesVoices(card: TtsVoiceModelCard, manifest: TtsVoicesManifest): void;
134
+ export declare function resolveTtsVoice(args: {
135
+ voices: readonly TtsVoiceCard[];
136
+ fallbackLanguage: string;
137
+ requestedLanguage: string;
138
+ voiceId?: string;
139
+ }): {
140
+ voice: TtsVoiceCard;
141
+ effectiveLanguage: string;
142
+ usedFallback: boolean;
143
+ };
144
+ export declare class LocalTtsBinding implements SpeechInterface {
145
+ #private;
146
+ constructor(args: {
147
+ subjectId: string;
148
+ deviceId: string;
149
+ voices: readonly TtsVoiceCard[];
150
+ fallbackLanguage: string;
151
+ backend: LocalTtsNativeBackend;
152
+ handle: LocalTtsNativeHandle;
153
+ onTelemetry?: (event: LocalTtsTelemetryEvent) => void;
154
+ mixedScriptPolicy?: string;
155
+ });
156
+ get supportedLanguages(): string[];
157
+ get fallbackLanguage(): string;
158
+ get voices(): TtsVoiceCard[];
159
+ get subjectId(): string;
160
+ get deviceId(): string;
161
+ get engine(): typeof LOCAL_TTS_ENGINE;
162
+ get mixedScriptPolicy(): string | undefined;
163
+ unload(): Promise<void>;
164
+ /**
165
+ * STT stub so SpeechInterface is complete for CK-05.1 when using TTS-first
166
+ * hosts. Full STT is {@link WhisperCppSpeechBinding}.
167
+ */
168
+ transcribe(audio: AsyncIterable<AudioChunk>): AsyncIterable<TranscriptSegment>;
169
+ synthesize(text: string, options: SpeechSynthesisOptions): AsyncIterable<AudioChunk>;
170
+ }
171
+ /**
172
+ * Load local TTS: voices manifest → truthful supportedLanguages → FFI seam.
173
+ */
174
+ export declare function loadLocalTts(options: LoadLocalTtsOptions): Promise<LocalTtsBinding>;
175
+ export type CreateLocalTtsSpeechHarnessOptions = {
176
+ subjectId?: string;
177
+ deviceId?: string;
178
+ voicesManifestPath?: string;
179
+ onTelemetry?: (event: LocalTtsTelemetryEvent) => void;
180
+ backend?: LocalTtsNativeBackend;
181
+ };
182
+ /** Conformance factory for CK-05 against the local TTS binding. */
183
+ export declare function createLocalTtsSpeechHarnessFactory(options?: CreateLocalTtsSpeechHarnessOptions): (ctx?: {
184
+ subjectId?: string;
185
+ deviceId?: string;
186
+ }) => Promise<SpeechConformanceHarness>;
187
+ //# sourceMappingURL=tts_binding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tts_binding.d.ts","sourceRoot":"","sources":["../src/tts_binding.ts"],"names":[],"mappings":"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"}