@lokutor/sdk 1.1.15 → 1.1.19

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.
package/dist/index.d.mts CHANGED
@@ -28,7 +28,9 @@ declare enum Language {
28
28
  */
29
29
  declare const AUDIO_CONFIG: {
30
30
  SAMPLE_RATE: number;
31
+ SAMPLE_RATE_INPUT: number;
31
32
  SPEAKER_SAMPLE_RATE: number;
33
+ SAMPLE_RATE_OUTPUT: number;
32
34
  CHANNELS: number;
33
35
  CHUNK_DURATION_MS: number;
34
36
  readonly CHUNK_SIZE: number;
@@ -83,18 +85,68 @@ interface VoiceAgentOptions {
83
85
  language?: Language;
84
86
  serverUrl?: string;
85
87
  visemes?: boolean;
86
- onTranscription?: (text: string, isUser: boolean) => void;
88
+ onTranscription?: (text: string) => void;
87
89
  onVisemes?: (visemes: Viseme[]) => void;
88
90
  onStatusChange?: (status: string) => void;
89
- onError?: (err: any) => void;
91
+ onError?: (err: LokutorError) => void;
92
+ }
93
+ /**
94
+ * REST API response types for discovery endpoints.
95
+ */
96
+ interface VoiceInfo {
97
+ id: string;
98
+ gender?: string;
99
+ languages?: string[];
100
+ }
101
+ interface LanguageInfo {
102
+ code: string;
103
+ name: string;
104
+ }
105
+ interface ModelInfo {
106
+ name: string;
107
+ description?: string;
108
+ default?: boolean;
109
+ }
110
+ interface ServerConfig {
111
+ max_text_length: number;
112
+ min_speed: number;
113
+ max_speed: number;
114
+ min_steps: number;
115
+ max_steps: number;
116
+ sample_rate: number;
117
+ channels: number;
118
+ }
119
+ interface ServerStatus {
120
+ status: string;
121
+ timestamp: string;
122
+ version: string;
123
+ runtime: string;
124
+ inference: string;
125
+ uptime_seconds: number;
126
+ goroutines: number;
127
+ mem_alloc_bytes: number;
128
+ active_connections: number;
129
+ failed_requests: number;
130
+ ready: boolean;
131
+ }
132
+ interface HealthStatus {
133
+ status: string;
134
+ timestamp: string;
135
+ version: string;
136
+ runtime: string;
137
+ inference: string;
138
+ load: number;
90
139
  }
91
140
  /**
92
141
  * Viseme data for lip-sync animation
93
142
  * Format: {"v": index, "c": character, "t": timestamp}
94
143
  */
95
144
  interface Viseme {
145
+ /** Text-position index (which input character the model is attending to), not a stable viseme ID */
96
146
  v: number;
147
+ /** Character/phoneme being spoken (reduced set: a,e,i,o,u,m,p,b,f,v,t,d,s,z,l,n,r,k,g,sil) */
97
148
  c: string;
149
+ /** Offset in seconds from the start of the audio stream */
98
150
  t: number;
99
151
  }
100
152
  /**
@@ -119,7 +171,45 @@ interface ToolCall {
119
171
  name: string;
120
172
  arguments: string;
121
173
  }
174
+ /**
175
+ * Error code enum matching the backend API error catalog
176
+ */
177
+ type ErrorCode = 'auth.missing_key' | 'auth.invalid_key' | 'auth.rate_limited' | 'auth.time_limited' | 'validation.invalid_voice' | 'validation.invalid_language' | 'validation.text_too_long' | 'validation.speed_out_of_range' | 'validation.steps_out_of_range' | 'validation.invalid_request_format' | 'tts.synthesis_failed' | 'tts.voice_unavailable' | 'tts.model_not_found' | 'tts.session_limit_reached' | 'stt.not_configured' | 'stt.stream_create_failed' | 'stt.language_not_supported' | 'agent.session_failed' | 'agent.provider_error' | 'internal.error' | 'internal.timeout' | 'internal.cancelled' | 'ws.close';
178
+ /**
179
+ * Typed error class for all Lokutor SDK errors.
180
+ * Includes the backend error code, human-readable message,
181
+ * optional detail, and whether the operation is retryable.
182
+ */
183
+ declare class LokutorError extends Error {
184
+ readonly code: ErrorCode;
185
+ readonly detail?: string;
186
+ readonly retryable: boolean;
187
+ readonly original?: unknown;
188
+ constructor(code: ErrorCode, message: string, opts?: {
189
+ detail?: string;
190
+ retryable?: boolean;
191
+ original?: unknown;
192
+ });
193
+ }
194
+ /**
195
+ * Returns true if the given error is a retryable LokutorError.
196
+ */
197
+ declare function isRetryable(error: unknown): boolean;
122
198
 
199
+ /**
200
+ * Interface for audio hardware management (Browser/Node parity)
201
+ */
202
+ interface AudioManager {
203
+ init(): Promise<void>;
204
+ startMicrophone(onAudioInput: (pcm16Data: Uint8Array) => void): Promise<void>;
205
+ stopMicrophone(): void;
206
+ playAudio(pcm16Data: Uint8Array): void;
207
+ stopPlayback(): void;
208
+ cleanup(): void;
209
+ isMicMuted(): boolean;
210
+ setMuted(muted: boolean): void;
211
+ getAmplitude(): number;
212
+ }
123
213
  /**
124
214
  * Main client for Lokutor Voice Agent SDK
125
215
  *
@@ -145,10 +235,12 @@ declare class VoiceAgentClient {
145
235
  private audioManager;
146
236
  private enableAudio;
147
237
  private currentGeneration;
238
+ private listeners;
148
239
  private isUserDisconnect;
149
240
  private reconnecting;
150
241
  private reconnectAttempts;
151
242
  private maxReconnectAttempts;
243
+ private serverUrl;
152
244
  constructor(config: LokutorConfig & {
153
245
  prompt: string;
154
246
  voice?: VoiceStyle;
@@ -157,11 +249,20 @@ declare class VoiceAgentClient {
157
249
  onVisemes?: (visemes: Viseme[]) => void;
158
250
  enableAudio?: boolean;
159
251
  tools?: ToolDefinition[];
252
+ serverUrl?: string;
160
253
  });
161
254
  /**
162
255
  * Connect to the Lokutor Voice Agent server
256
+ * @param customAudioManager Optional replacement for the default audio hardware handler
163
257
  */
164
- connect(): Promise<boolean>;
258
+ connect(customAudioManager?: AudioManager): Promise<boolean>;
259
+ /**
260
+ * The "Golden Path" - Starts a managed session with hardware handled automatically.
261
+ * This is the recommended way to start a conversation in browser environments.
262
+ */
263
+ startManaged(config?: {
264
+ audioManager?: AudioManager;
265
+ }): Promise<this>;
165
266
  /**
166
267
  * Send initial configuration to the server
167
268
  */
@@ -179,7 +280,13 @@ declare class VoiceAgentClient {
179
280
  * Handle incoming text messages (metadata/transcriptions)
180
281
  */
181
282
  private handleTextMessage;
182
- private audioListeners;
283
+ /**
284
+ * Register an event listener (for Python parity)
285
+ */
286
+ on(event: string, callback: Function): this;
287
+ /**
288
+ * Internal emitter for all events
289
+ */
183
290
  private emit;
184
291
  onAudio(callback: (data: Uint8Array) => void): void;
185
292
  onVisemes(callback: (visemes: Viseme[]) => void): void;
@@ -187,6 +294,15 @@ declare class VoiceAgentClient {
187
294
  * Disconnect from the server
188
295
  */
189
296
  disconnect(): void;
297
+ /**
298
+ * Returns true if the client is currently connected.
299
+ */
300
+ get connected(): boolean;
301
+ /**
302
+ * Returns the current generation counter.
303
+ * Useful for correlating audio/viseme chunks with utterances.
304
+ */
305
+ get generation(): number;
190
306
  /**
191
307
  * Toggles the microphone mute state (if managed by client)
192
308
  * returns the new mute state
@@ -196,6 +312,36 @@ declare class VoiceAgentClient {
196
312
  * Gets the microphone volume amplitude 0-1 (if managed by client)
197
313
  */
198
314
  getAmplitude(): number;
315
+ /**
316
+ * Fetch available voice styles from the server.
317
+ * No authentication required.
318
+ */
319
+ static fetchVoices(baseUrl?: string): Promise<VoiceInfo[]>;
320
+ /**
321
+ * Fetch supported languages from the server.
322
+ * No authentication required.
323
+ */
324
+ static fetchLanguages(baseUrl?: string): Promise<LanguageInfo[]>;
325
+ /**
326
+ * Fetch loaded TTS model versions from the server.
327
+ * No authentication required.
328
+ */
329
+ static fetchModels(baseUrl?: string): Promise<ModelInfo[]>;
330
+ /**
331
+ * Fetch server configuration (limits and defaults).
332
+ * No authentication required.
333
+ */
334
+ static fetchConfig(baseUrl?: string): Promise<ServerConfig>;
335
+ /**
336
+ * Fetch rich runtime status from the server.
337
+ * No authentication required.
338
+ */
339
+ static fetchStatus(baseUrl?: string): Promise<ServerStatus>;
340
+ /**
341
+ * Fetch health/liveness status from the server.
342
+ * No authentication required.
343
+ */
344
+ static fetchHealth(baseUrl?: string): Promise<HealthStatus>;
199
345
  /**
200
346
  * Update the system prompt mid-conversation
201
347
  */
@@ -236,6 +382,7 @@ declare class TTSClient {
236
382
  visemes?: boolean;
237
383
  onAudio?: (data: Uint8Array) => void;
238
384
  onVisemes?: (visemes: any[]) => void;
385
+ onTTFB?: (ms: number) => void;
239
386
  onError?: (error: any) => void;
240
387
  }): Promise<void>;
241
388
  }
@@ -443,4 +590,4 @@ declare class BrowserAudioManager {
443
590
  isRecording(): boolean;
444
591
  }
445
592
 
446
- export { AUDIO_CONFIG, type AnalyserConfig, type BrowserAudioConfig, BrowserAudioManager, type BrowserAudioOptions, DEFAULT_URLS, Language, type LokutorConfig, StreamResampler, type SynthesizeOptions, TTSClient, type ToolCall, type ToolDefinition, type Viseme, VoiceAgentClient, type VoiceAgentOptions, VoiceStyle, applyLowPassFilter, bytesToPcm16, calculateRMS, float32ToPcm16, normalizeAudio, pcm16ToBytes, pcm16ToFloat32, resample, resampleWithAntiAliasing, simpleConversation, simpleTTS };
593
+ export { AUDIO_CONFIG, type AnalyserConfig, type AudioManager, type BrowserAudioConfig, BrowserAudioManager, type BrowserAudioOptions, DEFAULT_URLS, type ErrorCode, type HealthStatus, Language, type LanguageInfo, type LokutorConfig, LokutorError, type ModelInfo, type ServerConfig, type ServerStatus, StreamResampler, type SynthesizeOptions, TTSClient, type ToolCall, type ToolDefinition, type Viseme, VoiceAgentClient, type VoiceAgentOptions, type VoiceInfo, VoiceStyle, applyLowPassFilter, bytesToPcm16, calculateRMS, float32ToPcm16, isRetryable, normalizeAudio, pcm16ToBytes, pcm16ToFloat32, resample, resampleWithAntiAliasing, simpleConversation, simpleTTS };
package/dist/index.d.ts CHANGED
@@ -28,7 +28,9 @@ declare enum Language {
28
28
  */
29
29
  declare const AUDIO_CONFIG: {
30
30
  SAMPLE_RATE: number;
31
+ SAMPLE_RATE_INPUT: number;
31
32
  SPEAKER_SAMPLE_RATE: number;
33
+ SAMPLE_RATE_OUTPUT: number;
32
34
  CHANNELS: number;
33
35
  CHUNK_DURATION_MS: number;
34
36
  readonly CHUNK_SIZE: number;
@@ -83,18 +85,68 @@ interface VoiceAgentOptions {
83
85
  language?: Language;
84
86
  serverUrl?: string;
85
87
  visemes?: boolean;
86
- onTranscription?: (text: string, isUser: boolean) => void;
88
+ onTranscription?: (text: string) => void;
87
89
  onVisemes?: (visemes: Viseme[]) => void;
88
90
  onStatusChange?: (status: string) => void;
89
- onError?: (err: any) => void;
91
+ onError?: (err: LokutorError) => void;
92
+ }
93
+ /**
94
+ * REST API response types for discovery endpoints.
95
+ */
96
+ interface VoiceInfo {
97
+ id: string;
98
+ gender?: string;
99
+ languages?: string[];
100
+ }
101
+ interface LanguageInfo {
102
+ code: string;
103
+ name: string;
104
+ }
105
+ interface ModelInfo {
106
+ name: string;
107
+ description?: string;
108
+ default?: boolean;
109
+ }
110
+ interface ServerConfig {
111
+ max_text_length: number;
112
+ min_speed: number;
113
+ max_speed: number;
114
+ min_steps: number;
115
+ max_steps: number;
116
+ sample_rate: number;
117
+ channels: number;
118
+ }
119
+ interface ServerStatus {
120
+ status: string;
121
+ timestamp: string;
122
+ version: string;
123
+ runtime: string;
124
+ inference: string;
125
+ uptime_seconds: number;
126
+ goroutines: number;
127
+ mem_alloc_bytes: number;
128
+ active_connections: number;
129
+ failed_requests: number;
130
+ ready: boolean;
131
+ }
132
+ interface HealthStatus {
133
+ status: string;
134
+ timestamp: string;
135
+ version: string;
136
+ runtime: string;
137
+ inference: string;
138
+ load: number;
90
139
  }
91
140
  /**
92
141
  * Viseme data for lip-sync animation
93
142
  * Format: {"v": index, "c": character, "t": timestamp}
94
143
  */
95
144
  interface Viseme {
145
+ /** Text-position index (which input character the model is attending to), not a stable viseme ID */
96
146
  v: number;
147
+ /** Character/phoneme being spoken (reduced set: a,e,i,o,u,m,p,b,f,v,t,d,s,z,l,n,r,k,g,sil) */
97
148
  c: string;
149
+ /** Offset in seconds from the start of the audio stream */
98
150
  t: number;
99
151
  }
100
152
  /**
@@ -119,7 +171,45 @@ interface ToolCall {
119
171
  name: string;
120
172
  arguments: string;
121
173
  }
174
+ /**
175
+ * Error code enum matching the backend API error catalog
176
+ */
177
+ type ErrorCode = 'auth.missing_key' | 'auth.invalid_key' | 'auth.rate_limited' | 'auth.time_limited' | 'validation.invalid_voice' | 'validation.invalid_language' | 'validation.text_too_long' | 'validation.speed_out_of_range' | 'validation.steps_out_of_range' | 'validation.invalid_request_format' | 'tts.synthesis_failed' | 'tts.voice_unavailable' | 'tts.model_not_found' | 'tts.session_limit_reached' | 'stt.not_configured' | 'stt.stream_create_failed' | 'stt.language_not_supported' | 'agent.session_failed' | 'agent.provider_error' | 'internal.error' | 'internal.timeout' | 'internal.cancelled' | 'ws.close';
178
+ /**
179
+ * Typed error class for all Lokutor SDK errors.
180
+ * Includes the backend error code, human-readable message,
181
+ * optional detail, and whether the operation is retryable.
182
+ */
183
+ declare class LokutorError extends Error {
184
+ readonly code: ErrorCode;
185
+ readonly detail?: string;
186
+ readonly retryable: boolean;
187
+ readonly original?: unknown;
188
+ constructor(code: ErrorCode, message: string, opts?: {
189
+ detail?: string;
190
+ retryable?: boolean;
191
+ original?: unknown;
192
+ });
193
+ }
194
+ /**
195
+ * Returns true if the given error is a retryable LokutorError.
196
+ */
197
+ declare function isRetryable(error: unknown): boolean;
122
198
 
199
+ /**
200
+ * Interface for audio hardware management (Browser/Node parity)
201
+ */
202
+ interface AudioManager {
203
+ init(): Promise<void>;
204
+ startMicrophone(onAudioInput: (pcm16Data: Uint8Array) => void): Promise<void>;
205
+ stopMicrophone(): void;
206
+ playAudio(pcm16Data: Uint8Array): void;
207
+ stopPlayback(): void;
208
+ cleanup(): void;
209
+ isMicMuted(): boolean;
210
+ setMuted(muted: boolean): void;
211
+ getAmplitude(): number;
212
+ }
123
213
  /**
124
214
  * Main client for Lokutor Voice Agent SDK
125
215
  *
@@ -145,10 +235,12 @@ declare class VoiceAgentClient {
145
235
  private audioManager;
146
236
  private enableAudio;
147
237
  private currentGeneration;
238
+ private listeners;
148
239
  private isUserDisconnect;
149
240
  private reconnecting;
150
241
  private reconnectAttempts;
151
242
  private maxReconnectAttempts;
243
+ private serverUrl;
152
244
  constructor(config: LokutorConfig & {
153
245
  prompt: string;
154
246
  voice?: VoiceStyle;
@@ -157,11 +249,20 @@ declare class VoiceAgentClient {
157
249
  onVisemes?: (visemes: Viseme[]) => void;
158
250
  enableAudio?: boolean;
159
251
  tools?: ToolDefinition[];
252
+ serverUrl?: string;
160
253
  });
161
254
  /**
162
255
  * Connect to the Lokutor Voice Agent server
256
+ * @param customAudioManager Optional replacement for the default audio hardware handler
163
257
  */
164
- connect(): Promise<boolean>;
258
+ connect(customAudioManager?: AudioManager): Promise<boolean>;
259
+ /**
260
+ * The "Golden Path" - Starts a managed session with hardware handled automatically.
261
+ * This is the recommended way to start a conversation in browser environments.
262
+ */
263
+ startManaged(config?: {
264
+ audioManager?: AudioManager;
265
+ }): Promise<this>;
165
266
  /**
166
267
  * Send initial configuration to the server
167
268
  */
@@ -179,7 +280,13 @@ declare class VoiceAgentClient {
179
280
  * Handle incoming text messages (metadata/transcriptions)
180
281
  */
181
282
  private handleTextMessage;
182
- private audioListeners;
283
+ /**
284
+ * Register an event listener (for Python parity)
285
+ */
286
+ on(event: string, callback: Function): this;
287
+ /**
288
+ * Internal emitter for all events
289
+ */
183
290
  private emit;
184
291
  onAudio(callback: (data: Uint8Array) => void): void;
185
292
  onVisemes(callback: (visemes: Viseme[]) => void): void;
@@ -187,6 +294,15 @@ declare class VoiceAgentClient {
187
294
  * Disconnect from the server
188
295
  */
189
296
  disconnect(): void;
297
+ /**
298
+ * Returns true if the client is currently connected.
299
+ */
300
+ get connected(): boolean;
301
+ /**
302
+ * Returns the current generation counter.
303
+ * Useful for correlating audio/viseme chunks with utterances.
304
+ */
305
+ get generation(): number;
190
306
  /**
191
307
  * Toggles the microphone mute state (if managed by client)
192
308
  * returns the new mute state
@@ -196,6 +312,36 @@ declare class VoiceAgentClient {
196
312
  * Gets the microphone volume amplitude 0-1 (if managed by client)
197
313
  */
198
314
  getAmplitude(): number;
315
+ /**
316
+ * Fetch available voice styles from the server.
317
+ * No authentication required.
318
+ */
319
+ static fetchVoices(baseUrl?: string): Promise<VoiceInfo[]>;
320
+ /**
321
+ * Fetch supported languages from the server.
322
+ * No authentication required.
323
+ */
324
+ static fetchLanguages(baseUrl?: string): Promise<LanguageInfo[]>;
325
+ /**
326
+ * Fetch loaded TTS model versions from the server.
327
+ * No authentication required.
328
+ */
329
+ static fetchModels(baseUrl?: string): Promise<ModelInfo[]>;
330
+ /**
331
+ * Fetch server configuration (limits and defaults).
332
+ * No authentication required.
333
+ */
334
+ static fetchConfig(baseUrl?: string): Promise<ServerConfig>;
335
+ /**
336
+ * Fetch rich runtime status from the server.
337
+ * No authentication required.
338
+ */
339
+ static fetchStatus(baseUrl?: string): Promise<ServerStatus>;
340
+ /**
341
+ * Fetch health/liveness status from the server.
342
+ * No authentication required.
343
+ */
344
+ static fetchHealth(baseUrl?: string): Promise<HealthStatus>;
199
345
  /**
200
346
  * Update the system prompt mid-conversation
201
347
  */
@@ -236,6 +382,7 @@ declare class TTSClient {
236
382
  visemes?: boolean;
237
383
  onAudio?: (data: Uint8Array) => void;
238
384
  onVisemes?: (visemes: any[]) => void;
385
+ onTTFB?: (ms: number) => void;
239
386
  onError?: (error: any) => void;
240
387
  }): Promise<void>;
241
388
  }
@@ -443,4 +590,4 @@ declare class BrowserAudioManager {
443
590
  isRecording(): boolean;
444
591
  }
445
592
 
446
- export { AUDIO_CONFIG, type AnalyserConfig, type BrowserAudioConfig, BrowserAudioManager, type BrowserAudioOptions, DEFAULT_URLS, Language, type LokutorConfig, StreamResampler, type SynthesizeOptions, TTSClient, type ToolCall, type ToolDefinition, type Viseme, VoiceAgentClient, type VoiceAgentOptions, VoiceStyle, applyLowPassFilter, bytesToPcm16, calculateRMS, float32ToPcm16, normalizeAudio, pcm16ToBytes, pcm16ToFloat32, resample, resampleWithAntiAliasing, simpleConversation, simpleTTS };
593
+ export { AUDIO_CONFIG, type AnalyserConfig, type AudioManager, type BrowserAudioConfig, BrowserAudioManager, type BrowserAudioOptions, DEFAULT_URLS, type ErrorCode, type HealthStatus, Language, type LanguageInfo, type LokutorConfig, LokutorError, type ModelInfo, type ServerConfig, type ServerStatus, StreamResampler, type SynthesizeOptions, TTSClient, type ToolCall, type ToolDefinition, type Viseme, VoiceAgentClient, type VoiceAgentOptions, type VoiceInfo, VoiceStyle, applyLowPassFilter, bytesToPcm16, calculateRMS, float32ToPcm16, isRetryable, normalizeAudio, pcm16ToBytes, pcm16ToFloat32, resample, resampleWithAntiAliasing, simpleConversation, simpleTTS };