@dtelecom/agents-js 0.2.0 → 0.2.1

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.
@@ -403,9 +403,198 @@ var OpenRouterLLM = class {
403
403
  }
404
404
  };
405
405
 
406
+ // src/providers/openai-llm.ts
407
+ var log3 = createLogger("OpenAILLM");
408
+ var OPENAI_URL = "https://api.openai.com/v1/chat/completions";
409
+ var OpenAILLM = class {
410
+ apiKey;
411
+ model;
412
+ maxTokens;
413
+ temperature;
414
+ responseFormat;
415
+ constructor(options) {
416
+ if (!options.apiKey) {
417
+ throw new Error("OpenAILLM requires an apiKey");
418
+ }
419
+ this.apiKey = options.apiKey;
420
+ this.model = options.model;
421
+ this.maxTokens = options.maxTokens ?? 512;
422
+ this.temperature = options.temperature ?? 0.7;
423
+ this.responseFormat = options.responseFormat;
424
+ }
425
+ /**
426
+ * Warm up the LLM by sending the system prompt and a short message.
427
+ * Primes the HTTP/TLS connection and model loading on the provider side.
428
+ */
429
+ async warmup(systemPrompt) {
430
+ log3.info("Warming up LLM connection...");
431
+ const start = performance.now();
432
+ const messages = [
433
+ { role: "system", content: systemPrompt },
434
+ { role: "user", content: "Hello" }
435
+ ];
436
+ try {
437
+ const gen = this.chat(messages);
438
+ for await (const chunk of gen) {
439
+ if (chunk.type === "done") break;
440
+ }
441
+ log3.info(`LLM warmup complete in ${(performance.now() - start).toFixed(0)}ms`);
442
+ } catch (err) {
443
+ log3.warn("LLM warmup failed (non-fatal):", err);
444
+ }
445
+ }
446
+ async *chat(messages, signal, options) {
447
+ const body = {
448
+ model: this.model,
449
+ messages,
450
+ max_tokens: this.maxTokens,
451
+ temperature: this.temperature,
452
+ stream: true,
453
+ stream_options: { include_usage: true }
454
+ };
455
+ if (this.responseFormat && !options?.plainText) {
456
+ body.response_format = this.responseFormat;
457
+ }
458
+ log3.debug(`LLM request: model=${this.model}, messages=${messages.length}`);
459
+ const response = await fetch(OPENAI_URL, {
460
+ method: "POST",
461
+ headers: {
462
+ "Content-Type": "application/json",
463
+ "Authorization": `Bearer ${this.apiKey}`
464
+ },
465
+ body: JSON.stringify(body),
466
+ signal
467
+ });
468
+ if (!response.ok) {
469
+ const errorText = await response.text();
470
+ throw new Error(`OpenAI API error ${response.status}: ${errorText}`);
471
+ }
472
+ if (!response.body) {
473
+ throw new Error("OpenAI response has no body");
474
+ }
475
+ const reader = response.body.getReader();
476
+ const decoder = new TextDecoder();
477
+ let buffer = "";
478
+ const structured = !!this.responseFormat && !options?.plainText;
479
+ let jsonBuffer = "";
480
+ let segmentsYielded = false;
481
+ let lastUsage;
482
+ let inSegmentsArray = false;
483
+ let objectStart = -1;
484
+ let braceDepth = 0;
485
+ let scanIndex = 0;
486
+ let inString = false;
487
+ let escaped = false;
488
+ function extractSegments(buf) {
489
+ const results = [];
490
+ for (let i = scanIndex; i < buf.length; i++) {
491
+ const ch = buf[i];
492
+ if (escaped) {
493
+ escaped = false;
494
+ continue;
495
+ }
496
+ if (ch === "\\" && inString) {
497
+ escaped = true;
498
+ continue;
499
+ }
500
+ if (ch === '"') {
501
+ inString = !inString;
502
+ continue;
503
+ }
504
+ if (inString) continue;
505
+ if (!inSegmentsArray) {
506
+ if (ch === "[") {
507
+ const before = buf.slice(0, i).trimEnd();
508
+ if (before.endsWith(":") && buf.slice(0, i).includes('"segments"')) {
509
+ inSegmentsArray = true;
510
+ }
511
+ }
512
+ continue;
513
+ }
514
+ if (ch === "{") {
515
+ if (braceDepth === 0) objectStart = i;
516
+ braceDepth++;
517
+ } else if (ch === "}") {
518
+ braceDepth--;
519
+ if (braceDepth === 0 && objectStart >= 0) {
520
+ const objStr = buf.slice(objectStart, i + 1);
521
+ try {
522
+ const seg = JSON.parse(objStr);
523
+ if (seg.lang && seg.text) {
524
+ results.push({ lang: seg.lang, text: seg.text });
525
+ }
526
+ } catch {
527
+ }
528
+ objectStart = -1;
529
+ }
530
+ } else if (ch === "]" && braceDepth === 0) {
531
+ inSegmentsArray = false;
532
+ }
533
+ }
534
+ scanIndex = buf.length;
535
+ return results;
536
+ }
537
+ try {
538
+ while (true) {
539
+ if (signal?.aborted) break;
540
+ const { done, value } = await reader.read();
541
+ if (done) break;
542
+ buffer += decoder.decode(value, { stream: true });
543
+ const lines = buffer.split("\n");
544
+ buffer = lines.pop() ?? "";
545
+ for (const line of lines) {
546
+ const trimmed = line.trim();
547
+ if (!trimmed || !trimmed.startsWith("data: ")) continue;
548
+ const data = trimmed.slice(6);
549
+ if (data === "[DONE]") break;
550
+ try {
551
+ const parsed = JSON.parse(data);
552
+ const choice = parsed.choices?.[0];
553
+ if (!choice) {
554
+ if (parsed.usage) {
555
+ lastUsage = {
556
+ promptTokens: parsed.usage.prompt_tokens,
557
+ completionTokens: parsed.usage.completion_tokens
558
+ };
559
+ }
560
+ continue;
561
+ }
562
+ const delta = choice.delta;
563
+ if (delta?.content) {
564
+ if (structured) {
565
+ jsonBuffer += delta.content;
566
+ const segments = extractSegments(jsonBuffer);
567
+ for (const seg of segments) {
568
+ yield { type: "segment", segment: seg };
569
+ segmentsYielded = true;
570
+ }
571
+ } else {
572
+ yield { type: "token", token: delta.content };
573
+ }
574
+ }
575
+ if (parsed.usage) {
576
+ lastUsage = {
577
+ promptTokens: parsed.usage.prompt_tokens,
578
+ completionTokens: parsed.usage.completion_tokens
579
+ };
580
+ }
581
+ } catch {
582
+ }
583
+ }
584
+ }
585
+ } finally {
586
+ reader.releaseLock();
587
+ }
588
+ if (structured && !segmentsYielded && jsonBuffer.length > 0) {
589
+ log3.warn(`LLM returned no segments. Raw JSON: "${jsonBuffer.slice(0, 300)}"`);
590
+ }
591
+ yield { type: "done", ...lastUsage ? { usage: lastUsage } : {} };
592
+ }
593
+ };
594
+
406
595
  // src/providers/cartesia-tts.ts
407
596
  import WebSocket2 from "ws";
408
- var log3 = createLogger("CartesiaTTS");
597
+ var log4 = createLogger("CartesiaTTS");
409
598
  var CARTESIA_WS_BASE = "wss://api.cartesia.ai/tts/websocket";
410
599
  var DEFAULT_API_VERSION = "2024-06-10";
411
600
  var DEFAULT_MODEL = "sonic-3";
@@ -444,7 +633,7 @@ var CartesiaTTS = class {
444
633
  /** Close the WebSocket connection to allow clean process exit. */
445
634
  close() {
446
635
  if (this.ws) {
447
- log3.debug("Closing Cartesia WebSocket");
636
+ log4.debug("Closing Cartesia WebSocket");
448
637
  this.ws.close();
449
638
  this.ws = null;
450
639
  }
@@ -453,17 +642,17 @@ var CartesiaTTS = class {
453
642
  }
454
643
  /** Pre-connect the WebSocket so first synthesize() doesn't pay connection cost. */
455
644
  async warmup() {
456
- log3.info("Warming up TTS connection...");
645
+ log4.info("Warming up TTS connection...");
457
646
  const start = performance.now();
458
647
  try {
459
648
  await this.ensureConnection();
460
- log3.info(`TTS warmup complete in ${(performance.now() - start).toFixed(0)}ms`);
649
+ log4.info(`TTS warmup complete in ${(performance.now() - start).toFixed(0)}ms`);
461
650
  } catch (err) {
462
- log3.warn("TTS warmup failed (non-fatal):", err);
651
+ log4.warn("TTS warmup failed (non-fatal):", err);
463
652
  }
464
653
  }
465
654
  async *synthesize(text, signal) {
466
- log3.debug(`Synthesizing: "${text.slice(0, 60)}"`);
655
+ log4.debug(`Synthesizing: "${text.slice(0, 60)}"`);
467
656
  await this.ensureConnection();
468
657
  if (!this.ws || this.ws.readyState !== WebSocket2.OPEN) {
469
658
  throw new Error("Cartesia WebSocket not connected");
@@ -534,12 +723,12 @@ var CartesiaTTS = class {
534
723
  if (this.connectPromise) return this.connectPromise;
535
724
  this.connectPromise = new Promise((resolve, reject) => {
536
725
  const url = `${CARTESIA_WS_BASE}?api_key=${this.apiKey}&cartesia_version=${this.apiVersion}`;
537
- log3.debug("Connecting to Cartesia...");
726
+ log4.debug("Connecting to Cartesia...");
538
727
  this.ws = new WebSocket2(url);
539
728
  this.ws.on("open", () => {
540
729
  this._connected = true;
541
730
  this.connectPromise = null;
542
- log3.info("Cartesia WebSocket connected");
731
+ log4.info("Cartesia WebSocket connected");
543
732
  resolve();
544
733
  });
545
734
  this.ws.on("message", (data) => {
@@ -547,12 +736,12 @@ var CartesiaTTS = class {
547
736
  const msg = JSON.parse(data.toString());
548
737
  this.handleMessage(msg);
549
738
  } catch (err) {
550
- log3.error("Failed to parse Cartesia message:", err);
739
+ log4.error("Failed to parse Cartesia message:", err);
551
740
  }
552
741
  });
553
742
  this.ws.on("error", (err) => {
554
743
  const error = err instanceof Error ? err : new Error(String(err));
555
- log3.error("Cartesia WebSocket error:", error);
744
+ log4.error("Cartesia WebSocket error:", error);
556
745
  for (const ctx of this.contexts.values()) {
557
746
  ctx.error = error;
558
747
  ctx.wake?.();
@@ -562,7 +751,7 @@ var CartesiaTTS = class {
562
751
  reject(error);
563
752
  });
564
753
  this.ws.on("close", (code, reason) => {
565
- log3.debug(`Cartesia WebSocket closed: ${code} ${reason.toString()}`);
754
+ log4.debug(`Cartesia WebSocket closed: ${code} ${reason.toString()}`);
566
755
  this._connected = false;
567
756
  this.connectPromise = null;
568
757
  for (const ctx of this.contexts.values()) {
@@ -587,12 +776,12 @@ var CartesiaTTS = class {
587
776
  ctx.wake?.();
588
777
  }
589
778
  } else if (type === "done") {
590
- log3.debug(`Cartesia synthesis done for ${contextId} (${ctx.chunks.length} chunks pending)`);
779
+ log4.debug(`Cartesia synthesis done for ${contextId} (${ctx.chunks.length} chunks pending)`);
591
780
  ctx.done = true;
592
781
  ctx.wake?.();
593
782
  } else if (type === "error") {
594
783
  const errorMsg = msg.error ?? "Unknown Cartesia error";
595
- log3.error(`Cartesia error for ${contextId}: ${errorMsg}`);
784
+ log4.error(`Cartesia error for ${contextId}: ${errorMsg}`);
596
785
  ctx.error = new Error(`Cartesia TTS error: ${errorMsg}`);
597
786
  ctx.wake?.();
598
787
  }
@@ -601,7 +790,7 @@ var CartesiaTTS = class {
601
790
 
602
791
  // src/providers/deepgram-tts.ts
603
792
  import WebSocket3 from "ws";
604
- var log4 = createLogger("DeepgramTTS");
793
+ var log5 = createLogger("DeepgramTTS");
605
794
  var DEEPGRAM_WS_BASE = "wss://api.deepgram.com/v1/speak";
606
795
  var DEFAULT_SAMPLE_RATE2 = 48e3;
607
796
  function parseLangSegments(text, defaultLang) {
@@ -698,7 +887,7 @@ var DeepgramTTS = class {
698
887
  /** Close all WebSocket connections to allow clean process exit. */
699
888
  close() {
700
889
  for (const [lang, ws] of this.connections) {
701
- log4.debug(`Closing WebSocket for [${lang}]`);
890
+ log5.debug(`Closing WebSocket for [${lang}]`);
702
891
  ws.close();
703
892
  }
704
893
  this.connections.clear();
@@ -707,13 +896,13 @@ var DeepgramTTS = class {
707
896
  }
708
897
  /** Pre-connect all language WebSocket connections. */
709
898
  async warmup() {
710
- log4.info("Warming up TTS connections...");
899
+ log5.info("Warming up TTS connections...");
711
900
  const start = performance.now();
712
901
  try {
713
902
  await Promise.all(Object.keys(this.models).map((lang) => this.ensureConnection(lang)));
714
- log4.info(`TTS warmup complete in ${(performance.now() - start).toFixed(0)}ms`);
903
+ log5.info(`TTS warmup complete in ${(performance.now() - start).toFixed(0)}ms`);
715
904
  } catch (err) {
716
- log4.warn("TTS warmup failed (non-fatal):", err);
905
+ log5.warn("TTS warmup failed (non-fatal):", err);
717
906
  }
718
907
  }
719
908
  /** Strip SSML lang tags from text for display/events. */
@@ -746,7 +935,7 @@ var DeepgramTTS = class {
746
935
  }
747
936
  }
748
937
  async *synthesizeSegment(lang, text, signal) {
749
- log4.debug(`Synthesizing [${lang}]: "${text.slice(0, 60)}"`);
938
+ log5.debug(`Synthesizing [${lang}]: "${text.slice(0, 60)}"`);
750
939
  await this.ensureConnection(lang);
751
940
  const ws = this.connections.get(lang);
752
941
  if (!ws || ws.readyState !== WebSocket3.OPEN) {
@@ -804,7 +993,7 @@ var DeepgramTTS = class {
804
993
  }
805
994
  const promise = new Promise((resolve, reject) => {
806
995
  const url = `${DEEPGRAM_WS_BASE}?model=${encodeURIComponent(model)}&encoding=linear16&sample_rate=${this.sampleRate}`;
807
- log4.debug(`Connecting to Deepgram for [${lang}]: ${model}`);
996
+ log5.debug(`Connecting to Deepgram for [${lang}]: ${model}`);
808
997
  const ws = new WebSocket3(url, {
809
998
  headers: {
810
999
  Authorization: `Token ${this.apiKey}`
@@ -813,7 +1002,7 @@ var DeepgramTTS = class {
813
1002
  ws.on("open", () => {
814
1003
  this.connections.set(lang, ws);
815
1004
  this.connectPromises.delete(lang);
816
- log4.info(`Deepgram WebSocket connected for [${lang}] (${model})`);
1005
+ log5.info(`Deepgram WebSocket connected for [${lang}] (${model})`);
817
1006
  resolve();
818
1007
  });
819
1008
  ws.on("message", (data, isBinary) => {
@@ -830,16 +1019,16 @@ var DeepgramTTS = class {
830
1019
  state.flushed = true;
831
1020
  state.wake?.();
832
1021
  } else if (msg.type === "Warning" || msg.type === "Error") {
833
- log4.warn(`Deepgram [${lang}] ${msg.type}: ${msg.description || msg.message || JSON.stringify(msg)}`);
1022
+ log5.warn(`Deepgram [${lang}] ${msg.type}: ${msg.description || msg.message || JSON.stringify(msg)}`);
834
1023
  }
835
1024
  } catch {
836
- log4.warn(`Failed to parse Deepgram message for [${lang}]`);
1025
+ log5.warn(`Failed to parse Deepgram message for [${lang}]`);
837
1026
  }
838
1027
  }
839
1028
  });
840
1029
  ws.on("error", (err) => {
841
1030
  const error = err instanceof Error ? err : new Error(String(err));
842
- log4.error(`Deepgram WebSocket error [${lang}]:`, error);
1031
+ log5.error(`Deepgram WebSocket error [${lang}]:`, error);
843
1032
  const state = this.flushStates.get(lang);
844
1033
  if (state) {
845
1034
  state.error = error;
@@ -850,7 +1039,7 @@ var DeepgramTTS = class {
850
1039
  reject(error);
851
1040
  });
852
1041
  ws.on("close", (code, reason) => {
853
- log4.debug(`Deepgram WebSocket closed [${lang}]: ${code} ${reason.toString()}`);
1042
+ log5.debug(`Deepgram WebSocket closed [${lang}]: ${code} ${reason.toString()}`);
854
1043
  this.connections.delete(lang);
855
1044
  this.connectPromises.delete(lang);
856
1045
  const state = this.flushStates.get(lang);
@@ -867,7 +1056,7 @@ var DeepgramTTS = class {
867
1056
 
868
1057
  // src/providers/dtelecom-stt.ts
869
1058
  import WebSocket4 from "ws";
870
- var log5 = createLogger("DtelecomSTT");
1059
+ var log6 = createLogger("DtelecomSTT");
871
1060
  var KEEPALIVE_INTERVAL_MS2 = 5e3;
872
1061
  var DtelecomSTT = class {
873
1062
  options;
@@ -926,7 +1115,7 @@ var DtelecomSTTStream = class extends BaseSTTStream {
926
1115
  }
927
1116
  if (this.ws?.readyState === WebSocket4.OPEN) {
928
1117
  this.ws.send(JSON.stringify(config));
929
- log5.info(`Reconfiguring STT: language=${language}${options?.forceWhisper ? ", model=whisper" : ""}`);
1118
+ log6.info(`Reconfiguring STT: language=${language}${options?.forceWhisper ? ", model=whisper" : ""}`);
930
1119
  }
931
1120
  }
932
1121
  async close() {
@@ -939,15 +1128,15 @@ var DtelecomSTTStream = class extends BaseSTTStream {
939
1128
  this.ws.close();
940
1129
  this.ws = null;
941
1130
  }
942
- log5.debug("DtelecomSTT stream closed");
1131
+ log6.debug("DtelecomSTT stream closed");
943
1132
  }
944
1133
  connect() {
945
1134
  const url = this.serverUrl.replace(/\/$/, "") + "/v1/stream";
946
1135
  const wsUrl = url.replace("https://", "wss://").replace("http://", "ws://");
947
- log5.debug(`Connecting to dTelecom STT: ${wsUrl}`);
1136
+ log6.debug(`Connecting to dTelecom STT: ${wsUrl}`);
948
1137
  this.ws = new WebSocket4(wsUrl);
949
1138
  this.ws.on("open", () => {
950
- log5.info("dTelecom STT WebSocket connected");
1139
+ log6.info("dTelecom STT WebSocket connected");
951
1140
  const config = {
952
1141
  type: "config",
953
1142
  language: this.language,
@@ -964,19 +1153,19 @@ var DtelecomSTTStream = class extends BaseSTTStream {
964
1153
  const msg = JSON.parse(data.toString());
965
1154
  this.handleMessage(msg);
966
1155
  } catch (err) {
967
- log5.error("Failed to parse dTelecom STT message:", err);
1156
+ log6.error("Failed to parse dTelecom STT message:", err);
968
1157
  }
969
1158
  });
970
1159
  this.ws.on("error", (err) => {
971
- log5.error("dTelecom STT WebSocket error:", err);
1160
+ log6.error("dTelecom STT WebSocket error:", err);
972
1161
  this.emit("error", err instanceof Error ? err : new Error(String(err)));
973
1162
  });
974
1163
  this.ws.on("close", (code, reason) => {
975
- log5.debug(`dTelecom STT WebSocket closed: ${code} ${reason.toString()}`);
1164
+ log6.debug(`dTelecom STT WebSocket closed: ${code} ${reason.toString()}`);
976
1165
  this._ready = false;
977
1166
  this.stopKeepAlive();
978
1167
  if (!this._closed) {
979
- log5.info("dTelecom STT connection lost, reconnecting in 1s...");
1168
+ log6.info("dTelecom STT connection lost, reconnecting in 1s...");
980
1169
  setTimeout(() => {
981
1170
  if (!this._closed) this.connect();
982
1171
  }, 1e3);
@@ -995,14 +1184,14 @@ var DtelecomSTTStream = class extends BaseSTTStream {
995
1184
  } else if (type === "error") {
996
1185
  const errData = msg.error;
997
1186
  const errorMsg = msg.message || (typeof errData === "string" ? errData : JSON.stringify(errData)) || "Unknown STT error";
998
- log5.error(`dTelecom STT error: ${errorMsg}`);
1187
+ log6.error(`dTelecom STT error: ${errorMsg}`);
999
1188
  this.emit("error", new Error(errorMsg));
1000
1189
  }
1001
1190
  }
1002
1191
  handleReady(msg) {
1003
1192
  const clientId = msg.client_id;
1004
1193
  const lang = msg.language;
1005
- log5.info(`dTelecom STT ready: client_id=${clientId}, language=${lang}`);
1194
+ log6.info(`dTelecom STT ready: client_id=${clientId}, language=${lang}`);
1006
1195
  this._ready = true;
1007
1196
  for (const buf of this.pendingAudio) {
1008
1197
  if (this.ws?.readyState === WebSocket4.OPEN) {
@@ -1019,7 +1208,7 @@ var DtelecomSTTStream = class extends BaseSTTStream {
1019
1208
  const latencyMs = msg.latency_ms;
1020
1209
  if (!text) return;
1021
1210
  if (isFinal && latencyMs !== void 0) {
1022
- log5.info(`stt_final: ${latencyMs.toFixed(0)}ms "${text.slice(0, 50)}"`);
1211
+ log6.info(`stt_final: ${latencyMs.toFixed(0)}ms "${text.slice(0, 50)}"`);
1023
1212
  }
1024
1213
  this.emit("transcription", {
1025
1214
  text,
@@ -1030,7 +1219,7 @@ var DtelecomSTTStream = class extends BaseSTTStream {
1030
1219
  }
1031
1220
  handleVadEvent(msg) {
1032
1221
  const event = msg.event;
1033
- log5.debug(`VAD event: ${event}`);
1222
+ log6.debug(`VAD event: ${event}`);
1034
1223
  if (event === "speech_start") {
1035
1224
  this.emit("transcription", {
1036
1225
  text: "",
@@ -1056,7 +1245,7 @@ var DtelecomSTTStream = class extends BaseSTTStream {
1056
1245
 
1057
1246
  // src/providers/dtelecom-tts.ts
1058
1247
  import WebSocket5 from "ws";
1059
- var log6 = createLogger("DtelecomTTS");
1248
+ var log7 = createLogger("DtelecomTTS");
1060
1249
  var DtelecomTTS = class {
1061
1250
  serverUrl;
1062
1251
  sessionKey;
@@ -1088,19 +1277,19 @@ var DtelecomTTS = class {
1088
1277
  }
1089
1278
  /** Pre-connect WebSocket to TTS server. */
1090
1279
  async warmup() {
1091
- log6.info("Warming up TTS connection...");
1280
+ log7.info("Warming up TTS connection...");
1092
1281
  const start = performance.now();
1093
1282
  try {
1094
1283
  await this.ensureConnection();
1095
- log6.info(`TTS warmup complete in ${(performance.now() - start).toFixed(0)}ms`);
1284
+ log7.info(`TTS warmup complete in ${(performance.now() - start).toFixed(0)}ms`);
1096
1285
  } catch (err) {
1097
- log6.warn("TTS warmup failed (non-fatal):", err);
1286
+ log7.warn("TTS warmup failed (non-fatal):", err);
1098
1287
  }
1099
1288
  }
1100
1289
  /** Close WebSocket connection. */
1101
1290
  close() {
1102
1291
  if (this.ws) {
1103
- log6.debug("Closing TTS WebSocket");
1292
+ log7.debug("Closing TTS WebSocket");
1104
1293
  this.ws.close();
1105
1294
  this.ws = null;
1106
1295
  }
@@ -1162,7 +1351,7 @@ var DtelecomTTS = class {
1162
1351
  msg.lang_code = voiceConfig.langCode;
1163
1352
  msg.speed = this.speed;
1164
1353
  }
1165
- log6.info(`TTS send [${lang}]: voice=${voiceConfig?.voice ?? "default"} lang_code=${voiceConfig?.langCode ?? "default"} "${text.slice(0, 60)}"`);
1354
+ log7.info(`TTS send [${lang}]: voice=${voiceConfig?.voice ?? "default"} lang_code=${voiceConfig?.langCode ?? "default"} "${text.slice(0, 60)}"`);
1166
1355
  ws.send(JSON.stringify(msg));
1167
1356
  try {
1168
1357
  while (true) {
@@ -1195,7 +1384,7 @@ var DtelecomTTS = class {
1195
1384
  this.connectPromise = new Promise((resolve, reject) => {
1196
1385
  const url = this.serverUrl.replace(/\/$/, "") + "/v1/stream";
1197
1386
  const wsUrl = url.replace("https://", "wss://").replace("http://", "ws://");
1198
- log6.debug(`Connecting to dTelecom TTS: ${wsUrl}`);
1387
+ log7.debug(`Connecting to dTelecom TTS: ${wsUrl}`);
1199
1388
  const ws = new WebSocket5(wsUrl);
1200
1389
  ws.on("open", () => {
1201
1390
  this.ws = ws;
@@ -1212,7 +1401,7 @@ var DtelecomTTS = class {
1212
1401
  };
1213
1402
  }
1214
1403
  ws.send(JSON.stringify(msg));
1215
- log6.info("dTelecom TTS WebSocket connected");
1404
+ log7.info("dTelecom TTS WebSocket connected");
1216
1405
  resolve();
1217
1406
  });
1218
1407
  ws.on("message", (data, isBinary) => {
@@ -1233,21 +1422,21 @@ var DtelecomTTS = class {
1233
1422
  state.done = true;
1234
1423
  state.wake?.();
1235
1424
  } else if (msg.type === "generating") {
1236
- log6.debug(`TTS generating: "${msg.text?.slice(0, 40)}"`);
1425
+ log7.debug(`TTS generating: "${msg.text?.slice(0, 40)}"`);
1237
1426
  } else if (msg.type === "error") {
1238
1427
  const errorMsg = msg.message || "Unknown TTS error";
1239
- log6.error(`dTelecom TTS error: ${errorMsg}`);
1428
+ log7.error(`dTelecom TTS error: ${errorMsg}`);
1240
1429
  state.error = new Error(errorMsg);
1241
1430
  state.wake?.();
1242
1431
  }
1243
1432
  } catch {
1244
- log6.warn("Failed to parse dTelecom TTS message");
1433
+ log7.warn("Failed to parse dTelecom TTS message");
1245
1434
  }
1246
1435
  }
1247
1436
  });
1248
1437
  ws.on("error", (err) => {
1249
1438
  const error = err instanceof Error ? err : new Error(String(err));
1250
- log6.error("dTelecom TTS WebSocket error:", error);
1439
+ log7.error("dTelecom TTS WebSocket error:", error);
1251
1440
  const state = this.flushState;
1252
1441
  if (state) {
1253
1442
  state.error = error;
@@ -1258,7 +1447,7 @@ var DtelecomTTS = class {
1258
1447
  reject(error);
1259
1448
  });
1260
1449
  ws.on("close", (code, reason) => {
1261
- log6.debug(`dTelecom TTS WebSocket closed: ${code} ${reason.toString()}`);
1450
+ log7.debug(`dTelecom TTS WebSocket closed: ${code} ${reason.toString()}`);
1262
1451
  this.ws = null;
1263
1452
  this.connectPromise = null;
1264
1453
  const state = this.flushState;
@@ -1277,6 +1466,7 @@ export {
1277
1466
  DeepgramTTS,
1278
1467
  DtelecomSTT,
1279
1468
  DtelecomTTS,
1469
+ OpenAILLM,
1280
1470
  OpenRouterLLM
1281
1471
  };
1282
1472
  //# sourceMappingURL=index.mjs.map