@lokutor/sdk 1.2.3 → 1.4.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.
package/dist/index.d.mts CHANGED
@@ -1,54 +1,87 @@
1
1
  /**
2
2
  * Available voice styles for the Lokutor AI Agent
3
3
  */
4
+ /**
5
+ * Built-in voices.
6
+ *
7
+ * Versa 2.0 names each voice for the language its reference speaker was recorded in: `EN_*` are
8
+ * English speakers, `ESCA_*` Spanish/Catalan. That is a guide to how a voice sounds, not a
9
+ * restriction — the model is zero-shot, so any voice can speak any supported language.
10
+ *
11
+ * The bare `F1`–`M5` values are the Versa 1.x names. They still work: the server maps them onto
12
+ * the matching Versa 2.0 voice, keeping the language family of the call. Prefer the explicit names
13
+ * in new code.
14
+ *
15
+ * This enum is a convenience, not the full set — a cloned voice's id (`clone_…`) is also a valid
16
+ * `voice`, which is why the config fields accept any string.
17
+ */
4
18
  declare enum VoiceStyle {
19
+ EN_F1 = "en_f1",
20
+ EN_F2 = "en_f2",
21
+ EN_F3 = "en_f3",
22
+ EN_F4 = "en_f4",
23
+ EN_F5 = "en_f5",
24
+ EN_M1 = "en_m1",
25
+ EN_M2 = "en_m2",
26
+ EN_M3 = "en_m3",
27
+ EN_M4 = "en_m4",
28
+ EN_M5 = "en_m5",
29
+ ESCA_F1 = "esca_f1",
30
+ ESCA_F2 = "esca_f2",
31
+ ESCA_F3 = "esca_f3",
32
+ ESCA_F4 = "esca_f4",
33
+ ESCA_F5 = "esca_f5",
34
+ ESCA_M1 = "esca_m1",
35
+ ESCA_M2 = "esca_m2",
36
+ ESCA_M3 = "esca_m3",
37
+ ESCA_M4 = "esca_m4",
38
+ ESCA_M5 = "esca_m5",
39
+ /** @deprecated Versa 1.x name, mapped server-side. Use EN_F1 / ESCA_F1. */
5
40
  F1 = "F1",
41
+ /** @deprecated Versa 1.x name, mapped server-side. */
6
42
  F2 = "F2",
43
+ /** @deprecated Versa 1.x name, mapped server-side. */
7
44
  F3 = "F3",
45
+ /** @deprecated Versa 1.x name, mapped server-side. */
8
46
  F4 = "F4",
47
+ /** @deprecated Versa 1.x name, mapped server-side. */
9
48
  F5 = "F5",
49
+ /** @deprecated Versa 1.x name, mapped server-side. */
10
50
  M1 = "M1",
51
+ /** @deprecated Versa 1.x name, mapped server-side. */
11
52
  M2 = "M2",
53
+ /** @deprecated Versa 1.x name, mapped server-side. */
12
54
  M3 = "M3",
55
+ /** @deprecated Versa 1.x name, mapped server-side. */
13
56
  M4 = "M4",
57
+ /** @deprecated Versa 1.x name, mapped server-side. */
14
58
  M5 = "M5"
15
59
  }
16
60
  /**
17
- * Supported languages for speech and text
61
+ * A voice id: one of {@link VoiceStyle}, or any id the API serves — including a cloned voice's
62
+ * `clone_…`. Typed to keep autocomplete on the enum while still accepting a runtime id.
63
+ */
64
+ type VoiceId = VoiceStyle | (string & {});
65
+ /**
66
+ * Languages Lokutor supports.
67
+ *
68
+ * Nine, as of the Versa 2.0 rollout. The previous list carried 32 entries — Japanese, Chinese,
69
+ * Arabic, Russian and more — that no shipped model was trained to speak, and omitted Catalan,
70
+ * Galician and Basque, which it speaks well. Every one of these except English has a trained
71
+ * language token in the model; English is its unmarked base case.
72
+ *
73
+ * `GET /languages` serves the live list; prefer it over hardcoding if you support user choice.
18
74
  */
19
75
  declare enum Language {
20
76
  ENGLISH = "en",
21
77
  SPANISH = "es",
78
+ CATALAN = "ca",
79
+ GALICIAN = "gl",
80
+ BASQUE = "eu",
81
+ PORTUGUESE = "pt",
22
82
  FRENCH = "fr",
23
- GERMAN = "de",
24
83
  ITALIAN = "it",
25
- PORTUGUESE = "pt",
26
- JAPANESE = "ja",
27
- KOREAN = "ko",
28
- CHINESE = "zh",
29
- ARABIC = "ar",
30
- BULGARIAN = "bg",
31
- CROATIAN = "hr",
32
- CZECH = "cs",
33
- DANISH = "da",
34
- DUTCH = "nl",
35
- ESTONIAN = "et",
36
- FINNISH = "fi",
37
- GREEK = "el",
38
- HINDI = "hi",
39
- HUNGARIAN = "hu",
40
- INDONESIAN = "id",
41
- LATVIAN = "lv",
42
- LITHUANIAN = "lt",
43
- POLISH = "pl",
44
- ROMANIAN = "ro",
45
- RUSSIAN = "ru",
46
- SLOVAK = "sk",
47
- SLOVENIAN = "sl",
48
- SWEDISH = "sv",
49
- TURKISH = "tr",
50
- UKRAINIAN = "uk",
51
- VIETNAMESE = "vi"
84
+ GERMAN = "de"
52
85
  }
53
86
  /**
54
87
  * Audio configuration constants
@@ -87,7 +120,7 @@ interface LokutorConfig {
87
120
  */
88
121
  interface SynthesizeOptions {
89
122
  text: string;
90
- voice?: VoiceStyle;
123
+ voice?: VoiceId;
91
124
  language?: Language;
92
125
  speed?: number;
93
126
  steps?: number;
@@ -163,7 +196,7 @@ interface BrowserAudioOptions {
163
196
  */
164
197
  interface VoiceAgentOptions {
165
198
  prompt?: string;
166
- voice?: VoiceStyle;
199
+ voice?: VoiceId;
167
200
  language?: Language;
168
201
  serverUrl?: string;
169
202
  visemes?: boolean;
@@ -302,7 +335,7 @@ declare class VoiceAgentClient {
302
335
  private apiKey;
303
336
  private agentId;
304
337
  prompt: string;
305
- voice: VoiceStyle;
338
+ voice: VoiceId;
306
339
  language: Language;
307
340
  tools: ToolDefinition[];
308
341
  private onTranscription?;
@@ -330,7 +363,7 @@ declare class VoiceAgentClient {
330
363
  private serverUrl;
331
364
  constructor(config: LokutorConfig & {
332
365
  prompt: string;
333
- voice?: VoiceStyle;
366
+ voice?: VoiceId;
334
367
  language?: Language;
335
368
  visemes?: boolean;
336
369
  onVisemes?: (visemes: Viseme[]) => void;
@@ -436,7 +469,7 @@ declare class VoiceAgentClient {
436
469
  /**
437
470
  * Change the voice style mid-conversation
438
471
  */
439
- updateVoice(voice: VoiceStyle): void;
472
+ updateVoice(voice: VoiceId): void;
440
473
  /**
441
474
  * Change the language mid-conversation
442
475
  */
@@ -478,7 +511,7 @@ declare class TTSClient {
478
511
  */
479
512
  synthesize(options: {
480
513
  text: string;
481
- voice?: VoiceStyle;
514
+ voice?: VoiceId;
482
515
  language?: Language;
483
516
  speed?: number;
484
517
  steps?: number;
@@ -869,4 +902,4 @@ declare class ConversationalPanel {
869
902
  private playErrorTone;
870
903
  }
871
904
 
872
- export { AUDIO_CONFIG, type AnalyserConfig, type AudioManager, type BrowserAudioConfig, BrowserAudioManager, type BrowserAudioOptions, ConversationalPanel, type ConversationalPanelConfig, DEFAULT_URLS, type ErrorCode, type HealthStatus, Language, type LanguageInfo, type LokutorConfig, LokutorError, type ModelInfo, NodeAudioManager, STTClient, type ServerConfig, type ServerStatus, SpeechToTextClient, type SpeechToTextOptions, StreamResampler, type SynthesizeOptions, TTSClient, type ToolCall, type ToolDefinition, type TranscribeOptions, type TranscribeResult, type TranscribeSegment, type Viseme, VoiceAgentClient, type VoiceAgentOptions, type VoiceInfo, VoiceStyle, applyLowPassFilter, bytesToPcm16, calculateRMS, float32ToPcm16, isRetryable, normalizeAudio, pcm16ToBytes, pcm16ToFloat32, resample, resampleWithAntiAliasing, simpleConversation, simpleTTS, simpleTranscribe };
905
+ export { AUDIO_CONFIG, type AnalyserConfig, type AudioManager, type BrowserAudioConfig, BrowserAudioManager, type BrowserAudioOptions, ConversationalPanel, type ConversationalPanelConfig, DEFAULT_URLS, type ErrorCode, type HealthStatus, Language, type LanguageInfo, type LokutorConfig, LokutorError, type ModelInfo, NodeAudioManager, STTClient, type ServerConfig, type ServerStatus, SpeechToTextClient, type SpeechToTextOptions, StreamResampler, type SynthesizeOptions, TTSClient, type ToolCall, type ToolDefinition, type TranscribeOptions, type TranscribeResult, type TranscribeSegment, type Viseme, VoiceAgentClient, type VoiceAgentOptions, type VoiceId, type VoiceInfo, VoiceStyle, applyLowPassFilter, bytesToPcm16, calculateRMS, float32ToPcm16, isRetryable, normalizeAudio, pcm16ToBytes, pcm16ToFloat32, resample, resampleWithAntiAliasing, simpleConversation, simpleTTS, simpleTranscribe };
package/dist/index.d.ts CHANGED
@@ -1,54 +1,87 @@
1
1
  /**
2
2
  * Available voice styles for the Lokutor AI Agent
3
3
  */
4
+ /**
5
+ * Built-in voices.
6
+ *
7
+ * Versa 2.0 names each voice for the language its reference speaker was recorded in: `EN_*` are
8
+ * English speakers, `ESCA_*` Spanish/Catalan. That is a guide to how a voice sounds, not a
9
+ * restriction — the model is zero-shot, so any voice can speak any supported language.
10
+ *
11
+ * The bare `F1`–`M5` values are the Versa 1.x names. They still work: the server maps them onto
12
+ * the matching Versa 2.0 voice, keeping the language family of the call. Prefer the explicit names
13
+ * in new code.
14
+ *
15
+ * This enum is a convenience, not the full set — a cloned voice's id (`clone_…`) is also a valid
16
+ * `voice`, which is why the config fields accept any string.
17
+ */
4
18
  declare enum VoiceStyle {
19
+ EN_F1 = "en_f1",
20
+ EN_F2 = "en_f2",
21
+ EN_F3 = "en_f3",
22
+ EN_F4 = "en_f4",
23
+ EN_F5 = "en_f5",
24
+ EN_M1 = "en_m1",
25
+ EN_M2 = "en_m2",
26
+ EN_M3 = "en_m3",
27
+ EN_M4 = "en_m4",
28
+ EN_M5 = "en_m5",
29
+ ESCA_F1 = "esca_f1",
30
+ ESCA_F2 = "esca_f2",
31
+ ESCA_F3 = "esca_f3",
32
+ ESCA_F4 = "esca_f4",
33
+ ESCA_F5 = "esca_f5",
34
+ ESCA_M1 = "esca_m1",
35
+ ESCA_M2 = "esca_m2",
36
+ ESCA_M3 = "esca_m3",
37
+ ESCA_M4 = "esca_m4",
38
+ ESCA_M5 = "esca_m5",
39
+ /** @deprecated Versa 1.x name, mapped server-side. Use EN_F1 / ESCA_F1. */
5
40
  F1 = "F1",
41
+ /** @deprecated Versa 1.x name, mapped server-side. */
6
42
  F2 = "F2",
43
+ /** @deprecated Versa 1.x name, mapped server-side. */
7
44
  F3 = "F3",
45
+ /** @deprecated Versa 1.x name, mapped server-side. */
8
46
  F4 = "F4",
47
+ /** @deprecated Versa 1.x name, mapped server-side. */
9
48
  F5 = "F5",
49
+ /** @deprecated Versa 1.x name, mapped server-side. */
10
50
  M1 = "M1",
51
+ /** @deprecated Versa 1.x name, mapped server-side. */
11
52
  M2 = "M2",
53
+ /** @deprecated Versa 1.x name, mapped server-side. */
12
54
  M3 = "M3",
55
+ /** @deprecated Versa 1.x name, mapped server-side. */
13
56
  M4 = "M4",
57
+ /** @deprecated Versa 1.x name, mapped server-side. */
14
58
  M5 = "M5"
15
59
  }
16
60
  /**
17
- * Supported languages for speech and text
61
+ * A voice id: one of {@link VoiceStyle}, or any id the API serves — including a cloned voice's
62
+ * `clone_…`. Typed to keep autocomplete on the enum while still accepting a runtime id.
63
+ */
64
+ type VoiceId = VoiceStyle | (string & {});
65
+ /**
66
+ * Languages Lokutor supports.
67
+ *
68
+ * Nine, as of the Versa 2.0 rollout. The previous list carried 32 entries — Japanese, Chinese,
69
+ * Arabic, Russian and more — that no shipped model was trained to speak, and omitted Catalan,
70
+ * Galician and Basque, which it speaks well. Every one of these except English has a trained
71
+ * language token in the model; English is its unmarked base case.
72
+ *
73
+ * `GET /languages` serves the live list; prefer it over hardcoding if you support user choice.
18
74
  */
19
75
  declare enum Language {
20
76
  ENGLISH = "en",
21
77
  SPANISH = "es",
78
+ CATALAN = "ca",
79
+ GALICIAN = "gl",
80
+ BASQUE = "eu",
81
+ PORTUGUESE = "pt",
22
82
  FRENCH = "fr",
23
- GERMAN = "de",
24
83
  ITALIAN = "it",
25
- PORTUGUESE = "pt",
26
- JAPANESE = "ja",
27
- KOREAN = "ko",
28
- CHINESE = "zh",
29
- ARABIC = "ar",
30
- BULGARIAN = "bg",
31
- CROATIAN = "hr",
32
- CZECH = "cs",
33
- DANISH = "da",
34
- DUTCH = "nl",
35
- ESTONIAN = "et",
36
- FINNISH = "fi",
37
- GREEK = "el",
38
- HINDI = "hi",
39
- HUNGARIAN = "hu",
40
- INDONESIAN = "id",
41
- LATVIAN = "lv",
42
- LITHUANIAN = "lt",
43
- POLISH = "pl",
44
- ROMANIAN = "ro",
45
- RUSSIAN = "ru",
46
- SLOVAK = "sk",
47
- SLOVENIAN = "sl",
48
- SWEDISH = "sv",
49
- TURKISH = "tr",
50
- UKRAINIAN = "uk",
51
- VIETNAMESE = "vi"
84
+ GERMAN = "de"
52
85
  }
53
86
  /**
54
87
  * Audio configuration constants
@@ -87,7 +120,7 @@ interface LokutorConfig {
87
120
  */
88
121
  interface SynthesizeOptions {
89
122
  text: string;
90
- voice?: VoiceStyle;
123
+ voice?: VoiceId;
91
124
  language?: Language;
92
125
  speed?: number;
93
126
  steps?: number;
@@ -163,7 +196,7 @@ interface BrowserAudioOptions {
163
196
  */
164
197
  interface VoiceAgentOptions {
165
198
  prompt?: string;
166
- voice?: VoiceStyle;
199
+ voice?: VoiceId;
167
200
  language?: Language;
168
201
  serverUrl?: string;
169
202
  visemes?: boolean;
@@ -302,7 +335,7 @@ declare class VoiceAgentClient {
302
335
  private apiKey;
303
336
  private agentId;
304
337
  prompt: string;
305
- voice: VoiceStyle;
338
+ voice: VoiceId;
306
339
  language: Language;
307
340
  tools: ToolDefinition[];
308
341
  private onTranscription?;
@@ -330,7 +363,7 @@ declare class VoiceAgentClient {
330
363
  private serverUrl;
331
364
  constructor(config: LokutorConfig & {
332
365
  prompt: string;
333
- voice?: VoiceStyle;
366
+ voice?: VoiceId;
334
367
  language?: Language;
335
368
  visemes?: boolean;
336
369
  onVisemes?: (visemes: Viseme[]) => void;
@@ -436,7 +469,7 @@ declare class VoiceAgentClient {
436
469
  /**
437
470
  * Change the voice style mid-conversation
438
471
  */
439
- updateVoice(voice: VoiceStyle): void;
472
+ updateVoice(voice: VoiceId): void;
440
473
  /**
441
474
  * Change the language mid-conversation
442
475
  */
@@ -478,7 +511,7 @@ declare class TTSClient {
478
511
  */
479
512
  synthesize(options: {
480
513
  text: string;
481
- voice?: VoiceStyle;
514
+ voice?: VoiceId;
482
515
  language?: Language;
483
516
  speed?: number;
484
517
  steps?: number;
@@ -869,4 +902,4 @@ declare class ConversationalPanel {
869
902
  private playErrorTone;
870
903
  }
871
904
 
872
- export { AUDIO_CONFIG, type AnalyserConfig, type AudioManager, type BrowserAudioConfig, BrowserAudioManager, type BrowserAudioOptions, ConversationalPanel, type ConversationalPanelConfig, DEFAULT_URLS, type ErrorCode, type HealthStatus, Language, type LanguageInfo, type LokutorConfig, LokutorError, type ModelInfo, NodeAudioManager, STTClient, type ServerConfig, type ServerStatus, SpeechToTextClient, type SpeechToTextOptions, StreamResampler, type SynthesizeOptions, TTSClient, type ToolCall, type ToolDefinition, type TranscribeOptions, type TranscribeResult, type TranscribeSegment, type Viseme, VoiceAgentClient, type VoiceAgentOptions, type VoiceInfo, VoiceStyle, applyLowPassFilter, bytesToPcm16, calculateRMS, float32ToPcm16, isRetryable, normalizeAudio, pcm16ToBytes, pcm16ToFloat32, resample, resampleWithAntiAliasing, simpleConversation, simpleTTS, simpleTranscribe };
905
+ export { AUDIO_CONFIG, type AnalyserConfig, type AudioManager, type BrowserAudioConfig, BrowserAudioManager, type BrowserAudioOptions, ConversationalPanel, type ConversationalPanelConfig, DEFAULT_URLS, type ErrorCode, type HealthStatus, Language, type LanguageInfo, type LokutorConfig, LokutorError, type ModelInfo, NodeAudioManager, STTClient, type ServerConfig, type ServerStatus, SpeechToTextClient, type SpeechToTextOptions, StreamResampler, type SynthesizeOptions, TTSClient, type ToolCall, type ToolDefinition, type TranscribeOptions, type TranscribeResult, type TranscribeSegment, type Viseme, VoiceAgentClient, type VoiceAgentOptions, type VoiceId, type VoiceInfo, VoiceStyle, applyLowPassFilter, bytesToPcm16, calculateRMS, float32ToPcm16, isRetryable, normalizeAudio, pcm16ToBytes, pcm16ToFloat32, resample, resampleWithAntiAliasing, simpleConversation, simpleTTS, simpleTranscribe };
package/dist/index.js CHANGED
@@ -51,6 +51,26 @@ module.exports = __toCommonJS(index_exports);
51
51
 
52
52
  // src/types.ts
53
53
  var VoiceStyle = /* @__PURE__ */ ((VoiceStyle2) => {
54
+ VoiceStyle2["EN_F1"] = "en_f1";
55
+ VoiceStyle2["EN_F2"] = "en_f2";
56
+ VoiceStyle2["EN_F3"] = "en_f3";
57
+ VoiceStyle2["EN_F4"] = "en_f4";
58
+ VoiceStyle2["EN_F5"] = "en_f5";
59
+ VoiceStyle2["EN_M1"] = "en_m1";
60
+ VoiceStyle2["EN_M2"] = "en_m2";
61
+ VoiceStyle2["EN_M3"] = "en_m3";
62
+ VoiceStyle2["EN_M4"] = "en_m4";
63
+ VoiceStyle2["EN_M5"] = "en_m5";
64
+ VoiceStyle2["ESCA_F1"] = "esca_f1";
65
+ VoiceStyle2["ESCA_F2"] = "esca_f2";
66
+ VoiceStyle2["ESCA_F3"] = "esca_f3";
67
+ VoiceStyle2["ESCA_F4"] = "esca_f4";
68
+ VoiceStyle2["ESCA_F5"] = "esca_f5";
69
+ VoiceStyle2["ESCA_M1"] = "esca_m1";
70
+ VoiceStyle2["ESCA_M2"] = "esca_m2";
71
+ VoiceStyle2["ESCA_M3"] = "esca_m3";
72
+ VoiceStyle2["ESCA_M4"] = "esca_m4";
73
+ VoiceStyle2["ESCA_M5"] = "esca_m5";
54
74
  VoiceStyle2["F1"] = "F1";
55
75
  VoiceStyle2["F2"] = "F2";
56
76
  VoiceStyle2["F3"] = "F3";
@@ -66,36 +86,13 @@ var VoiceStyle = /* @__PURE__ */ ((VoiceStyle2) => {
66
86
  var Language = /* @__PURE__ */ ((Language2) => {
67
87
  Language2["ENGLISH"] = "en";
68
88
  Language2["SPANISH"] = "es";
89
+ Language2["CATALAN"] = "ca";
90
+ Language2["GALICIAN"] = "gl";
91
+ Language2["BASQUE"] = "eu";
92
+ Language2["PORTUGUESE"] = "pt";
69
93
  Language2["FRENCH"] = "fr";
70
- Language2["GERMAN"] = "de";
71
94
  Language2["ITALIAN"] = "it";
72
- Language2["PORTUGUESE"] = "pt";
73
- Language2["JAPANESE"] = "ja";
74
- Language2["KOREAN"] = "ko";
75
- Language2["CHINESE"] = "zh";
76
- Language2["ARABIC"] = "ar";
77
- Language2["BULGARIAN"] = "bg";
78
- Language2["CROATIAN"] = "hr";
79
- Language2["CZECH"] = "cs";
80
- Language2["DANISH"] = "da";
81
- Language2["DUTCH"] = "nl";
82
- Language2["ESTONIAN"] = "et";
83
- Language2["FINNISH"] = "fi";
84
- Language2["GREEK"] = "el";
85
- Language2["HINDI"] = "hi";
86
- Language2["HUNGARIAN"] = "hu";
87
- Language2["INDONESIAN"] = "id";
88
- Language2["LATVIAN"] = "lv";
89
- Language2["LITHUANIAN"] = "lt";
90
- Language2["POLISH"] = "pl";
91
- Language2["ROMANIAN"] = "ro";
92
- Language2["RUSSIAN"] = "ru";
93
- Language2["SLOVAK"] = "sk";
94
- Language2["SLOVENIAN"] = "sl";
95
- Language2["SWEDISH"] = "sv";
96
- Language2["TURKISH"] = "tr";
97
- Language2["UKRAINIAN"] = "uk";
98
- Language2["VIETNAMESE"] = "vi";
95
+ Language2["GERMAN"] = "de";
99
96
  return Language2;
100
97
  })(Language || {});
101
98
  var AUDIO_CONFIG = {
@@ -1688,14 +1685,18 @@ var PANEL_CSS = (
1688
1685
  .cv-curtain .cv-curtain-bg {
1689
1686
  position: absolute;
1690
1687
  inset: 0;
1691
- background: url('/background_gradient.jpeg') center / cover no-repeat;
1692
- z-index: -1;
1688
+ background: var(--cv-accent);
1689
+ z-index: -2;
1693
1690
  }
1694
1691
  .cv-curtain .cv-curtain-overlay {
1695
1692
  position: absolute;
1696
1693
  inset: 0;
1697
- background: var(--cv-accent);
1698
- opacity: 0.35;
1694
+ /* Fractal-noise grain, tinted white and blended in soft-light -- the same treatment the rest
1695
+ of the product uses for a textured accent fill, so the curtain reads as the agent's own
1696
+ color instead of a flat tint over a stock photo. */
1697
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.95' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
1698
+ background-size: 160px 160px;
1699
+ background-blend-mode: soft-light;
1699
1700
  z-index: -1;
1700
1701
  }
1701
1702
  .cv-curtain.is-up { transform: translateY(-100%); }
@@ -1778,17 +1779,6 @@ var PANEL_CSS = (
1778
1779
  z-index: 10;
1779
1780
  transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1);
1780
1781
  }
1781
- .cv-is-speaking .cv-visualizer-wrap {
1782
- animation: cv-pulse 2.5s infinite ease-in-out;
1783
- }
1784
- .cv-is-thinking .cv-visualizer-wrap {
1785
- opacity: 0.5;
1786
- transform: translate(-50%, -50%) scale(0.9);
1787
- }
1788
- @keyframes cv-pulse {
1789
- 0%, 100% { transform: translate(-50%, -50%) scale(1); }
1790
- 50% { transform: translate(-50%, -50%) scale(1.05); }
1791
- }
1792
1782
  .cv-canvas {
1793
1783
  width: 100% !important;
1794
1784
  height: 100% !important;
package/dist/index.mjs CHANGED
@@ -1,5 +1,25 @@
1
1
  // src/types.ts
2
2
  var VoiceStyle = /* @__PURE__ */ ((VoiceStyle2) => {
3
+ VoiceStyle2["EN_F1"] = "en_f1";
4
+ VoiceStyle2["EN_F2"] = "en_f2";
5
+ VoiceStyle2["EN_F3"] = "en_f3";
6
+ VoiceStyle2["EN_F4"] = "en_f4";
7
+ VoiceStyle2["EN_F5"] = "en_f5";
8
+ VoiceStyle2["EN_M1"] = "en_m1";
9
+ VoiceStyle2["EN_M2"] = "en_m2";
10
+ VoiceStyle2["EN_M3"] = "en_m3";
11
+ VoiceStyle2["EN_M4"] = "en_m4";
12
+ VoiceStyle2["EN_M5"] = "en_m5";
13
+ VoiceStyle2["ESCA_F1"] = "esca_f1";
14
+ VoiceStyle2["ESCA_F2"] = "esca_f2";
15
+ VoiceStyle2["ESCA_F3"] = "esca_f3";
16
+ VoiceStyle2["ESCA_F4"] = "esca_f4";
17
+ VoiceStyle2["ESCA_F5"] = "esca_f5";
18
+ VoiceStyle2["ESCA_M1"] = "esca_m1";
19
+ VoiceStyle2["ESCA_M2"] = "esca_m2";
20
+ VoiceStyle2["ESCA_M3"] = "esca_m3";
21
+ VoiceStyle2["ESCA_M4"] = "esca_m4";
22
+ VoiceStyle2["ESCA_M5"] = "esca_m5";
3
23
  VoiceStyle2["F1"] = "F1";
4
24
  VoiceStyle2["F2"] = "F2";
5
25
  VoiceStyle2["F3"] = "F3";
@@ -15,36 +35,13 @@ var VoiceStyle = /* @__PURE__ */ ((VoiceStyle2) => {
15
35
  var Language = /* @__PURE__ */ ((Language2) => {
16
36
  Language2["ENGLISH"] = "en";
17
37
  Language2["SPANISH"] = "es";
38
+ Language2["CATALAN"] = "ca";
39
+ Language2["GALICIAN"] = "gl";
40
+ Language2["BASQUE"] = "eu";
41
+ Language2["PORTUGUESE"] = "pt";
18
42
  Language2["FRENCH"] = "fr";
19
- Language2["GERMAN"] = "de";
20
43
  Language2["ITALIAN"] = "it";
21
- Language2["PORTUGUESE"] = "pt";
22
- Language2["JAPANESE"] = "ja";
23
- Language2["KOREAN"] = "ko";
24
- Language2["CHINESE"] = "zh";
25
- Language2["ARABIC"] = "ar";
26
- Language2["BULGARIAN"] = "bg";
27
- Language2["CROATIAN"] = "hr";
28
- Language2["CZECH"] = "cs";
29
- Language2["DANISH"] = "da";
30
- Language2["DUTCH"] = "nl";
31
- Language2["ESTONIAN"] = "et";
32
- Language2["FINNISH"] = "fi";
33
- Language2["GREEK"] = "el";
34
- Language2["HINDI"] = "hi";
35
- Language2["HUNGARIAN"] = "hu";
36
- Language2["INDONESIAN"] = "id";
37
- Language2["LATVIAN"] = "lv";
38
- Language2["LITHUANIAN"] = "lt";
39
- Language2["POLISH"] = "pl";
40
- Language2["ROMANIAN"] = "ro";
41
- Language2["RUSSIAN"] = "ru";
42
- Language2["SLOVAK"] = "sk";
43
- Language2["SLOVENIAN"] = "sl";
44
- Language2["SWEDISH"] = "sv";
45
- Language2["TURKISH"] = "tr";
46
- Language2["UKRAINIAN"] = "uk";
47
- Language2["VIETNAMESE"] = "vi";
44
+ Language2["GERMAN"] = "de";
48
45
  return Language2;
49
46
  })(Language || {});
50
47
  var AUDIO_CONFIG = {
@@ -1637,14 +1634,18 @@ var PANEL_CSS = (
1637
1634
  .cv-curtain .cv-curtain-bg {
1638
1635
  position: absolute;
1639
1636
  inset: 0;
1640
- background: url('/background_gradient.jpeg') center / cover no-repeat;
1641
- z-index: -1;
1637
+ background: var(--cv-accent);
1638
+ z-index: -2;
1642
1639
  }
1643
1640
  .cv-curtain .cv-curtain-overlay {
1644
1641
  position: absolute;
1645
1642
  inset: 0;
1646
- background: var(--cv-accent);
1647
- opacity: 0.35;
1643
+ /* Fractal-noise grain, tinted white and blended in soft-light -- the same treatment the rest
1644
+ of the product uses for a textured accent fill, so the curtain reads as the agent's own
1645
+ color instead of a flat tint over a stock photo. */
1646
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.95' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
1647
+ background-size: 160px 160px;
1648
+ background-blend-mode: soft-light;
1648
1649
  z-index: -1;
1649
1650
  }
1650
1651
  .cv-curtain.is-up { transform: translateY(-100%); }
@@ -1727,17 +1728,6 @@ var PANEL_CSS = (
1727
1728
  z-index: 10;
1728
1729
  transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1);
1729
1730
  }
1730
- .cv-is-speaking .cv-visualizer-wrap {
1731
- animation: cv-pulse 2.5s infinite ease-in-out;
1732
- }
1733
- .cv-is-thinking .cv-visualizer-wrap {
1734
- opacity: 0.5;
1735
- transform: translate(-50%, -50%) scale(0.9);
1736
- }
1737
- @keyframes cv-pulse {
1738
- 0%, 100% { transform: translate(-50%, -50%) scale(1); }
1739
- 50% { transform: translate(-50%, -50%) scale(1.05); }
1740
- }
1741
1731
  .cv-canvas {
1742
1732
  width: 100% !important;
1743
1733
  height: 100% !important;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lokutor/sdk",
3
- "version": "1.2.3",
3
+ "version": "1.4.0",
4
4
  "description": "JavaScript/TypeScript SDK for Lokutor Real-time Voice AI",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
package/src/client.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  VoiceStyle,
3
+ VoiceId,
3
4
  Language,
4
5
  DEFAULT_URLS,
5
6
  LokutorConfig,
@@ -159,7 +160,7 @@ export class VoiceAgentClient {
159
160
  private apiKey: string;
160
161
  private agentId: string = "";
161
162
  public prompt: string;
162
- public voice: VoiceStyle;
163
+ public voice: VoiceId;
163
164
  public language: Language;
164
165
  public tools: ToolDefinition[] = [];
165
166
 
@@ -197,7 +198,7 @@ export class VoiceAgentClient {
197
198
 
198
199
  constructor(config: LokutorConfig & {
199
200
  prompt: string,
200
- voice?: VoiceStyle,
201
+ voice?: VoiceId,
201
202
  language?: Language,
202
203
  visemes?: boolean,
203
204
  onVisemes?: (visemes: Viseme[]) => void,
@@ -208,6 +209,9 @@ export class VoiceAgentClient {
208
209
  this.apiKey = config.apiKey;
209
210
  this.agentId = config.agentId || "";
210
211
  this.prompt = config.prompt;
212
+ // Default stays the Versa 1.x name on purpose: the server resolves F1 to the voice of the
213
+ // call's own language family (esca_f1 for Spanish, en_f1 for English), which adapts better
214
+ // than pinning one explicit voice here would.
211
215
  this.voice = config.voice || VoiceStyle.F1;
212
216
  this.language = config.language || Language.ENGLISH;
213
217
  this.serverUrl = config.serverUrl || DEFAULT_URLS.VOICE_AGENT;
@@ -767,7 +771,7 @@ export class VoiceAgentClient {
767
771
  /**
768
772
  * Change the voice style mid-conversation
769
773
  */
770
- public updateVoice(voice: VoiceStyle) {
774
+ public updateVoice(voice: VoiceId) {
771
775
  this.voice = voice;
772
776
  if (this.ws && this.ws.readyState === WebSocket.OPEN && this.isConnected) {
773
777
  this.ws.send(JSON.stringify({ type: 'voice', data: voice }));
@@ -853,7 +857,7 @@ export class TTSClient {
853
857
  */
854
858
  public synthesize(options: {
855
859
  text: string;
856
- voice?: VoiceStyle;
860
+ voice?: VoiceId;
857
861
  language?: Language;
858
862
  speed?: number;
859
863
  steps?: number;
@@ -30,14 +30,18 @@ const PANEL_CSS = /*css*/ `
30
30
  .cv-curtain .cv-curtain-bg {
31
31
  position: absolute;
32
32
  inset: 0;
33
- background: url('/background_gradient.jpeg') center / cover no-repeat;
34
- z-index: -1;
33
+ background: var(--cv-accent);
34
+ z-index: -2;
35
35
  }
36
36
  .cv-curtain .cv-curtain-overlay {
37
37
  position: absolute;
38
38
  inset: 0;
39
- background: var(--cv-accent);
40
- opacity: 0.35;
39
+ /* Fractal-noise grain, tinted white and blended in soft-light -- the same treatment the rest
40
+ of the product uses for a textured accent fill, so the curtain reads as the agent's own
41
+ color instead of a flat tint over a stock photo. */
42
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.95' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
43
+ background-size: 160px 160px;
44
+ background-blend-mode: soft-light;
41
45
  z-index: -1;
42
46
  }
43
47
  .cv-curtain.is-up { transform: translateY(-100%); }
@@ -120,17 +124,6 @@ const PANEL_CSS = /*css*/ `
120
124
  z-index: 10;
121
125
  transition: all 0.5s cubic-bezier(0.16, 1, 0.3, 1);
122
126
  }
123
- .cv-is-speaking .cv-visualizer-wrap {
124
- animation: cv-pulse 2.5s infinite ease-in-out;
125
- }
126
- .cv-is-thinking .cv-visualizer-wrap {
127
- opacity: 0.5;
128
- transform: translate(-50%, -50%) scale(0.9);
129
- }
130
- @keyframes cv-pulse {
131
- 0%, 100% { transform: translate(-50%, -50%) scale(1); }
132
- 50% { transform: translate(-50%, -50%) scale(1.05); }
133
- }
134
127
  .cv-canvas {
135
128
  width: 100% !important;
136
129
  height: 100% !important;
package/src/types.ts CHANGED
@@ -1,58 +1,93 @@
1
1
  /**
2
2
  * Available voice styles for the Lokutor AI Agent
3
3
  */
4
+ /**
5
+ * Built-in voices.
6
+ *
7
+ * Versa 2.0 names each voice for the language its reference speaker was recorded in: `EN_*` are
8
+ * English speakers, `ESCA_*` Spanish/Catalan. That is a guide to how a voice sounds, not a
9
+ * restriction — the model is zero-shot, so any voice can speak any supported language.
10
+ *
11
+ * The bare `F1`–`M5` values are the Versa 1.x names. They still work: the server maps them onto
12
+ * the matching Versa 2.0 voice, keeping the language family of the call. Prefer the explicit names
13
+ * in new code.
14
+ *
15
+ * This enum is a convenience, not the full set — a cloned voice's id (`clone_…`) is also a valid
16
+ * `voice`, which is why the config fields accept any string.
17
+ */
4
18
  export enum VoiceStyle {
5
- // Female voices
19
+ // English reference speakers
20
+ EN_F1 = "en_f1",
21
+ EN_F2 = "en_f2",
22
+ EN_F3 = "en_f3",
23
+ EN_F4 = "en_f4",
24
+ EN_F5 = "en_f5",
25
+ EN_M1 = "en_m1",
26
+ EN_M2 = "en_m2",
27
+ EN_M3 = "en_m3",
28
+ EN_M4 = "en_m4",
29
+ EN_M5 = "en_m5",
30
+
31
+ // Spanish / Catalan reference speakers
32
+ ESCA_F1 = "esca_f1",
33
+ ESCA_F2 = "esca_f2",
34
+ ESCA_F3 = "esca_f3",
35
+ ESCA_F4 = "esca_f4",
36
+ ESCA_F5 = "esca_f5",
37
+ ESCA_M1 = "esca_m1",
38
+ ESCA_M2 = "esca_m2",
39
+ ESCA_M3 = "esca_m3",
40
+ ESCA_M4 = "esca_m4",
41
+ ESCA_M5 = "esca_m5",
42
+
43
+ /** @deprecated Versa 1.x name, mapped server-side. Use EN_F1 / ESCA_F1. */
6
44
  F1 = "F1",
45
+ /** @deprecated Versa 1.x name, mapped server-side. */
7
46
  F2 = "F2",
47
+ /** @deprecated Versa 1.x name, mapped server-side. */
8
48
  F3 = "F3",
49
+ /** @deprecated Versa 1.x name, mapped server-side. */
9
50
  F4 = "F4",
51
+ /** @deprecated Versa 1.x name, mapped server-side. */
10
52
  F5 = "F5",
11
-
12
- // Male voices
53
+ /** @deprecated Versa 1.x name, mapped server-side. */
13
54
  M1 = "M1",
55
+ /** @deprecated Versa 1.x name, mapped server-side. */
14
56
  M2 = "M2",
57
+ /** @deprecated Versa 1.x name, mapped server-side. */
15
58
  M3 = "M3",
59
+ /** @deprecated Versa 1.x name, mapped server-side. */
16
60
  M4 = "M4",
61
+ /** @deprecated Versa 1.x name, mapped server-side. */
17
62
  M5 = "M5",
18
63
  }
19
64
 
20
65
  /**
21
- * Supported languages for speech and text
66
+ * A voice id: one of {@link VoiceStyle}, or any id the API serves — including a cloned voice's
67
+ * `clone_…`. Typed to keep autocomplete on the enum while still accepting a runtime id.
68
+ */
69
+ export type VoiceId = VoiceStyle | (string & {});
70
+
71
+ /**
72
+ * Languages Lokutor supports.
73
+ *
74
+ * Nine, as of the Versa 2.0 rollout. The previous list carried 32 entries — Japanese, Chinese,
75
+ * Arabic, Russian and more — that no shipped model was trained to speak, and omitted Catalan,
76
+ * Galician and Basque, which it speaks well. Every one of these except English has a trained
77
+ * language token in the model; English is its unmarked base case.
78
+ *
79
+ * `GET /languages` serves the live list; prefer it over hardcoding if you support user choice.
22
80
  */
23
81
  export enum Language {
24
82
  ENGLISH = "en",
25
83
  SPANISH = "es",
84
+ CATALAN = "ca",
85
+ GALICIAN = "gl",
86
+ BASQUE = "eu",
87
+ PORTUGUESE = "pt",
26
88
  FRENCH = "fr",
27
- GERMAN = "de",
28
89
  ITALIAN = "it",
29
- PORTUGUESE = "pt",
30
- JAPANESE = "ja",
31
- KOREAN = "ko",
32
- CHINESE = "zh",
33
- ARABIC = "ar",
34
- BULGARIAN = "bg",
35
- CROATIAN = "hr",
36
- CZECH = "cs",
37
- DANISH = "da",
38
- DUTCH = "nl",
39
- ESTONIAN = "et",
40
- FINNISH = "fi",
41
- GREEK = "el",
42
- HINDI = "hi",
43
- HUNGARIAN = "hu",
44
- INDONESIAN = "id",
45
- LATVIAN = "lv",
46
- LITHUANIAN = "lt",
47
- POLISH = "pl",
48
- ROMANIAN = "ro",
49
- RUSSIAN = "ru",
50
- SLOVAK = "sk",
51
- SLOVENIAN = "sl",
52
- SWEDISH = "sv",
53
- TURKISH = "tr",
54
- UKRAINIAN = "uk",
55
- VIETNAMESE = "vi",
90
+ GERMAN = "de",
56
91
  }
57
92
 
58
93
  /**
@@ -97,7 +132,7 @@ export interface LokutorConfig {
97
132
  */
98
133
  export interface SynthesizeOptions {
99
134
  text: string;
100
- voice?: VoiceStyle;
135
+ voice?: VoiceId;
101
136
  language?: Language;
102
137
  speed?: number;
103
138
  steps?: number;
@@ -179,7 +214,7 @@ export interface BrowserAudioOptions {
179
214
  */
180
215
  export interface VoiceAgentOptions {
181
216
  prompt?: string;
182
- voice?: VoiceStyle;
217
+ voice?: VoiceId;
183
218
  language?: Language;
184
219
  serverUrl?: string;
185
220
  visemes?: boolean;