@lokutor/sdk 1.1.0 → 1.1.2
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/README.md +2 -0
- package/dist/index.d.mts +18 -4
- package/dist/index.d.ts +18 -4
- package/dist/index.js +40 -8
- package/dist/index.mjs +40 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Lokutor JavaScript SDK
|
|
2
2
|
|
|
3
|
+

|
|
4
|
+
|
|
3
5
|
[](https://www.npmjs.com/package/@lokutor/sdk)
|
|
4
6
|
[](https://opensource.org/licenses/MIT)
|
|
5
7
|
|
package/dist/index.d.mts
CHANGED
|
@@ -28,6 +28,7 @@ declare enum Language {
|
|
|
28
28
|
*/
|
|
29
29
|
declare const AUDIO_CONFIG: {
|
|
30
30
|
SAMPLE_RATE: number;
|
|
31
|
+
SPEAKER_SAMPLE_RATE: number;
|
|
31
32
|
CHANNELS: number;
|
|
32
33
|
CHUNK_DURATION_MS: number;
|
|
33
34
|
readonly CHUNK_SIZE: number;
|
|
@@ -44,7 +45,6 @@ declare const DEFAULT_URLS: {
|
|
|
44
45
|
*/
|
|
45
46
|
interface LokutorConfig {
|
|
46
47
|
apiKey: string;
|
|
47
|
-
serverUrl?: string;
|
|
48
48
|
onTranscription?: (text: string) => void;
|
|
49
49
|
onResponse?: (text: string) => void;
|
|
50
50
|
onAudio?: (data: Uint8Array) => void;
|
|
@@ -71,7 +71,6 @@ interface SynthesizeOptions {
|
|
|
71
71
|
declare class VoiceAgentClient {
|
|
72
72
|
private ws;
|
|
73
73
|
private apiKey;
|
|
74
|
-
private serverUrl;
|
|
75
74
|
prompt: string;
|
|
76
75
|
voice: VoiceStyle;
|
|
77
76
|
language: Language;
|
|
@@ -81,6 +80,7 @@ declare class VoiceAgentClient {
|
|
|
81
80
|
private onStatus?;
|
|
82
81
|
private onError?;
|
|
83
82
|
private isConnected;
|
|
83
|
+
private messages;
|
|
84
84
|
constructor(config: LokutorConfig & {
|
|
85
85
|
prompt: string;
|
|
86
86
|
voice?: VoiceStyle;
|
|
@@ -114,16 +114,30 @@ declare class VoiceAgentClient {
|
|
|
114
114
|
* Disconnect from the server
|
|
115
115
|
*/
|
|
116
116
|
disconnect(): void;
|
|
117
|
+
/**
|
|
118
|
+
* Update the system prompt mid-conversation
|
|
119
|
+
*/
|
|
120
|
+
updatePrompt(newPrompt: string): void;
|
|
121
|
+
/**
|
|
122
|
+
* Get full conversation transcript
|
|
123
|
+
*/
|
|
124
|
+
getTranscript(): Array<{
|
|
125
|
+
role: 'user' | 'agent';
|
|
126
|
+
text: string;
|
|
127
|
+
timestamp: number;
|
|
128
|
+
}>;
|
|
129
|
+
/**
|
|
130
|
+
* Get conversation as formatted text
|
|
131
|
+
*/
|
|
132
|
+
getTranscriptText(): string;
|
|
117
133
|
}
|
|
118
134
|
/**
|
|
119
135
|
* Client for standalone Text-to-Speech synthesis
|
|
120
136
|
*/
|
|
121
137
|
declare class TTSClient {
|
|
122
138
|
private apiKey;
|
|
123
|
-
private serverUrl;
|
|
124
139
|
constructor(config: {
|
|
125
140
|
apiKey: string;
|
|
126
|
-
serverUrl?: string;
|
|
127
141
|
});
|
|
128
142
|
/**
|
|
129
143
|
* Synthesize text to speech
|
package/dist/index.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ declare enum Language {
|
|
|
28
28
|
*/
|
|
29
29
|
declare const AUDIO_CONFIG: {
|
|
30
30
|
SAMPLE_RATE: number;
|
|
31
|
+
SPEAKER_SAMPLE_RATE: number;
|
|
31
32
|
CHANNELS: number;
|
|
32
33
|
CHUNK_DURATION_MS: number;
|
|
33
34
|
readonly CHUNK_SIZE: number;
|
|
@@ -44,7 +45,6 @@ declare const DEFAULT_URLS: {
|
|
|
44
45
|
*/
|
|
45
46
|
interface LokutorConfig {
|
|
46
47
|
apiKey: string;
|
|
47
|
-
serverUrl?: string;
|
|
48
48
|
onTranscription?: (text: string) => void;
|
|
49
49
|
onResponse?: (text: string) => void;
|
|
50
50
|
onAudio?: (data: Uint8Array) => void;
|
|
@@ -71,7 +71,6 @@ interface SynthesizeOptions {
|
|
|
71
71
|
declare class VoiceAgentClient {
|
|
72
72
|
private ws;
|
|
73
73
|
private apiKey;
|
|
74
|
-
private serverUrl;
|
|
75
74
|
prompt: string;
|
|
76
75
|
voice: VoiceStyle;
|
|
77
76
|
language: Language;
|
|
@@ -81,6 +80,7 @@ declare class VoiceAgentClient {
|
|
|
81
80
|
private onStatus?;
|
|
82
81
|
private onError?;
|
|
83
82
|
private isConnected;
|
|
83
|
+
private messages;
|
|
84
84
|
constructor(config: LokutorConfig & {
|
|
85
85
|
prompt: string;
|
|
86
86
|
voice?: VoiceStyle;
|
|
@@ -114,16 +114,30 @@ declare class VoiceAgentClient {
|
|
|
114
114
|
* Disconnect from the server
|
|
115
115
|
*/
|
|
116
116
|
disconnect(): void;
|
|
117
|
+
/**
|
|
118
|
+
* Update the system prompt mid-conversation
|
|
119
|
+
*/
|
|
120
|
+
updatePrompt(newPrompt: string): void;
|
|
121
|
+
/**
|
|
122
|
+
* Get full conversation transcript
|
|
123
|
+
*/
|
|
124
|
+
getTranscript(): Array<{
|
|
125
|
+
role: 'user' | 'agent';
|
|
126
|
+
text: string;
|
|
127
|
+
timestamp: number;
|
|
128
|
+
}>;
|
|
129
|
+
/**
|
|
130
|
+
* Get conversation as formatted text
|
|
131
|
+
*/
|
|
132
|
+
getTranscriptText(): string;
|
|
117
133
|
}
|
|
118
134
|
/**
|
|
119
135
|
* Client for standalone Text-to-Speech synthesis
|
|
120
136
|
*/
|
|
121
137
|
declare class TTSClient {
|
|
122
138
|
private apiKey;
|
|
123
|
-
private serverUrl;
|
|
124
139
|
constructor(config: {
|
|
125
140
|
apiKey: string;
|
|
126
|
-
serverUrl?: string;
|
|
127
141
|
});
|
|
128
142
|
/**
|
|
129
143
|
* Synthesize text to speech
|
package/dist/index.js
CHANGED
|
@@ -54,7 +54,8 @@ var Language = /* @__PURE__ */ ((Language2) => {
|
|
|
54
54
|
return Language2;
|
|
55
55
|
})(Language || {});
|
|
56
56
|
var AUDIO_CONFIG = {
|
|
57
|
-
SAMPLE_RATE:
|
|
57
|
+
SAMPLE_RATE: 16e3,
|
|
58
|
+
SPEAKER_SAMPLE_RATE: 44100,
|
|
58
59
|
CHANNELS: 1,
|
|
59
60
|
CHUNK_DURATION_MS: 20,
|
|
60
61
|
get CHUNK_SIZE() {
|
|
@@ -78,7 +79,6 @@ function base64ToUint8Array(base64) {
|
|
|
78
79
|
var VoiceAgentClient = class {
|
|
79
80
|
ws = null;
|
|
80
81
|
apiKey;
|
|
81
|
-
serverUrl;
|
|
82
82
|
prompt;
|
|
83
83
|
voice;
|
|
84
84
|
language;
|
|
@@ -89,9 +89,9 @@ var VoiceAgentClient = class {
|
|
|
89
89
|
onStatus;
|
|
90
90
|
onError;
|
|
91
91
|
isConnected = false;
|
|
92
|
+
messages = [];
|
|
92
93
|
constructor(config) {
|
|
93
94
|
this.apiKey = config.apiKey;
|
|
94
|
-
this.serverUrl = config.serverUrl || DEFAULT_URLS.VOICE_AGENT;
|
|
95
95
|
this.prompt = config.prompt;
|
|
96
96
|
this.voice = config.voice || "F1" /* F1 */;
|
|
97
97
|
this.language = config.language || "en" /* ENGLISH */;
|
|
@@ -107,12 +107,12 @@ var VoiceAgentClient = class {
|
|
|
107
107
|
async connect() {
|
|
108
108
|
return new Promise((resolve, reject) => {
|
|
109
109
|
try {
|
|
110
|
-
let url =
|
|
110
|
+
let url = DEFAULT_URLS.VOICE_AGENT;
|
|
111
111
|
if (this.apiKey) {
|
|
112
112
|
const separator = url.includes("?") ? "&" : "?";
|
|
113
113
|
url += `${separator}api_key=${this.apiKey}`;
|
|
114
114
|
}
|
|
115
|
-
console.log(`\u{1F517} Connecting to ${
|
|
115
|
+
console.log(`\u{1F517} Connecting to ${DEFAULT_URLS.VOICE_AGENT}...`);
|
|
116
116
|
this.ws = new WebSocket(url);
|
|
117
117
|
this.ws.binaryType = "arraybuffer";
|
|
118
118
|
this.ws.onopen = () => {
|
|
@@ -182,6 +182,12 @@ var VoiceAgentClient = class {
|
|
|
182
182
|
}
|
|
183
183
|
break;
|
|
184
184
|
case "transcript":
|
|
185
|
+
const role = msg.role === "user" ? "user" : "agent";
|
|
186
|
+
this.messages.push({
|
|
187
|
+
role,
|
|
188
|
+
text: msg.data,
|
|
189
|
+
timestamp: Date.now()
|
|
190
|
+
});
|
|
185
191
|
if (msg.role === "user") {
|
|
186
192
|
if (this.onTranscription) this.onTranscription(msg.data);
|
|
187
193
|
console.log(`\u{1F4AC} You: ${msg.data}`);
|
|
@@ -227,13 +233,39 @@ var VoiceAgentClient = class {
|
|
|
227
233
|
this.ws = null;
|
|
228
234
|
}
|
|
229
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* Update the system prompt mid-conversation
|
|
238
|
+
*/
|
|
239
|
+
updatePrompt(newPrompt) {
|
|
240
|
+
this.prompt = newPrompt;
|
|
241
|
+
if (this.ws && this.isConnected) {
|
|
242
|
+
try {
|
|
243
|
+
this.ws.send(JSON.stringify({ type: "prompt", data: newPrompt }));
|
|
244
|
+
console.log(`\u2699\uFE0F Updated prompt: ${newPrompt.substring(0, 50)}...`);
|
|
245
|
+
} catch (error) {
|
|
246
|
+
console.error("Error updating prompt:", error);
|
|
247
|
+
}
|
|
248
|
+
} else {
|
|
249
|
+
console.warn("Not connected - prompt will be updated on next connection");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Get full conversation transcript
|
|
254
|
+
*/
|
|
255
|
+
getTranscript() {
|
|
256
|
+
return this.messages.slice();
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Get conversation as formatted text
|
|
260
|
+
*/
|
|
261
|
+
getTranscriptText() {
|
|
262
|
+
return this.messages.map((msg) => `${msg.role === "user" ? "You" : "Agent"}: ${msg.text}`).join("\n");
|
|
263
|
+
}
|
|
230
264
|
};
|
|
231
265
|
var TTSClient = class {
|
|
232
266
|
apiKey;
|
|
233
|
-
serverUrl;
|
|
234
267
|
constructor(config) {
|
|
235
268
|
this.apiKey = config.apiKey;
|
|
236
|
-
this.serverUrl = config.serverUrl || DEFAULT_URLS.TTS;
|
|
237
269
|
}
|
|
238
270
|
/**
|
|
239
271
|
* Synthesize text to speech
|
|
@@ -244,7 +276,7 @@ var TTSClient = class {
|
|
|
244
276
|
synthesize(options) {
|
|
245
277
|
return new Promise((resolve, reject) => {
|
|
246
278
|
try {
|
|
247
|
-
let url =
|
|
279
|
+
let url = DEFAULT_URLS.TTS;
|
|
248
280
|
if (this.apiKey) {
|
|
249
281
|
const separator = url.includes("?") ? "&" : "?";
|
|
250
282
|
url += `${separator}api_key=${this.apiKey}`;
|
package/dist/index.mjs
CHANGED
|
@@ -21,7 +21,8 @@ var Language = /* @__PURE__ */ ((Language2) => {
|
|
|
21
21
|
return Language2;
|
|
22
22
|
})(Language || {});
|
|
23
23
|
var AUDIO_CONFIG = {
|
|
24
|
-
SAMPLE_RATE:
|
|
24
|
+
SAMPLE_RATE: 16e3,
|
|
25
|
+
SPEAKER_SAMPLE_RATE: 44100,
|
|
25
26
|
CHANNELS: 1,
|
|
26
27
|
CHUNK_DURATION_MS: 20,
|
|
27
28
|
get CHUNK_SIZE() {
|
|
@@ -45,7 +46,6 @@ function base64ToUint8Array(base64) {
|
|
|
45
46
|
var VoiceAgentClient = class {
|
|
46
47
|
ws = null;
|
|
47
48
|
apiKey;
|
|
48
|
-
serverUrl;
|
|
49
49
|
prompt;
|
|
50
50
|
voice;
|
|
51
51
|
language;
|
|
@@ -56,9 +56,9 @@ var VoiceAgentClient = class {
|
|
|
56
56
|
onStatus;
|
|
57
57
|
onError;
|
|
58
58
|
isConnected = false;
|
|
59
|
+
messages = [];
|
|
59
60
|
constructor(config) {
|
|
60
61
|
this.apiKey = config.apiKey;
|
|
61
|
-
this.serverUrl = config.serverUrl || DEFAULT_URLS.VOICE_AGENT;
|
|
62
62
|
this.prompt = config.prompt;
|
|
63
63
|
this.voice = config.voice || "F1" /* F1 */;
|
|
64
64
|
this.language = config.language || "en" /* ENGLISH */;
|
|
@@ -74,12 +74,12 @@ var VoiceAgentClient = class {
|
|
|
74
74
|
async connect() {
|
|
75
75
|
return new Promise((resolve, reject) => {
|
|
76
76
|
try {
|
|
77
|
-
let url =
|
|
77
|
+
let url = DEFAULT_URLS.VOICE_AGENT;
|
|
78
78
|
if (this.apiKey) {
|
|
79
79
|
const separator = url.includes("?") ? "&" : "?";
|
|
80
80
|
url += `${separator}api_key=${this.apiKey}`;
|
|
81
81
|
}
|
|
82
|
-
console.log(`\u{1F517} Connecting to ${
|
|
82
|
+
console.log(`\u{1F517} Connecting to ${DEFAULT_URLS.VOICE_AGENT}...`);
|
|
83
83
|
this.ws = new WebSocket(url);
|
|
84
84
|
this.ws.binaryType = "arraybuffer";
|
|
85
85
|
this.ws.onopen = () => {
|
|
@@ -149,6 +149,12 @@ var VoiceAgentClient = class {
|
|
|
149
149
|
}
|
|
150
150
|
break;
|
|
151
151
|
case "transcript":
|
|
152
|
+
const role = msg.role === "user" ? "user" : "agent";
|
|
153
|
+
this.messages.push({
|
|
154
|
+
role,
|
|
155
|
+
text: msg.data,
|
|
156
|
+
timestamp: Date.now()
|
|
157
|
+
});
|
|
152
158
|
if (msg.role === "user") {
|
|
153
159
|
if (this.onTranscription) this.onTranscription(msg.data);
|
|
154
160
|
console.log(`\u{1F4AC} You: ${msg.data}`);
|
|
@@ -194,13 +200,39 @@ var VoiceAgentClient = class {
|
|
|
194
200
|
this.ws = null;
|
|
195
201
|
}
|
|
196
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Update the system prompt mid-conversation
|
|
205
|
+
*/
|
|
206
|
+
updatePrompt(newPrompt) {
|
|
207
|
+
this.prompt = newPrompt;
|
|
208
|
+
if (this.ws && this.isConnected) {
|
|
209
|
+
try {
|
|
210
|
+
this.ws.send(JSON.stringify({ type: "prompt", data: newPrompt }));
|
|
211
|
+
console.log(`\u2699\uFE0F Updated prompt: ${newPrompt.substring(0, 50)}...`);
|
|
212
|
+
} catch (error) {
|
|
213
|
+
console.error("Error updating prompt:", error);
|
|
214
|
+
}
|
|
215
|
+
} else {
|
|
216
|
+
console.warn("Not connected - prompt will be updated on next connection");
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Get full conversation transcript
|
|
221
|
+
*/
|
|
222
|
+
getTranscript() {
|
|
223
|
+
return this.messages.slice();
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Get conversation as formatted text
|
|
227
|
+
*/
|
|
228
|
+
getTranscriptText() {
|
|
229
|
+
return this.messages.map((msg) => `${msg.role === "user" ? "You" : "Agent"}: ${msg.text}`).join("\n");
|
|
230
|
+
}
|
|
197
231
|
};
|
|
198
232
|
var TTSClient = class {
|
|
199
233
|
apiKey;
|
|
200
|
-
serverUrl;
|
|
201
234
|
constructor(config) {
|
|
202
235
|
this.apiKey = config.apiKey;
|
|
203
|
-
this.serverUrl = config.serverUrl || DEFAULT_URLS.TTS;
|
|
204
236
|
}
|
|
205
237
|
/**
|
|
206
238
|
* Synthesize text to speech
|
|
@@ -211,7 +243,7 @@ var TTSClient = class {
|
|
|
211
243
|
synthesize(options) {
|
|
212
244
|
return new Promise((resolve, reject) => {
|
|
213
245
|
try {
|
|
214
|
-
let url =
|
|
246
|
+
let url = DEFAULT_URLS.TTS;
|
|
215
247
|
if (this.apiKey) {
|
|
216
248
|
const separator = url.includes("?") ? "&" : "?";
|
|
217
249
|
url += `${separator}api_key=${this.apiKey}`;
|