@dtelecom/agents-js 0.1.2 → 0.1.5

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,8 +1,8 @@
1
1
  import * as _dtelecom_server_sdk_node from '@dtelecom/server-sdk-node';
2
2
  import { Room, AudioSource, RemoteAudioTrack, AudioFrame } from '@dtelecom/server-sdk-node';
3
3
  import { EventEmitter } from 'events';
4
- import { A as AgentConfig, a as AgentStartOptions, M as Message, L as LLMPlugin, P as PipelineOptions, b as AgentState, S as STTStream, T as TranscriptionResult } from './types-EvtHMokR.mjs';
5
- export { c as AgentEvents, d as AudioOutput, D as DataMessageHandler, e as LLMChunk, f as MemoryConfig, g as PipelineEvents, R as RespondMode, h as STTPlugin, i as STTStreamOptions, j as TTSPlugin } from './types-EvtHMokR.mjs';
4
+ import { A as AgentConfig, a as AgentStartOptions, M as Message, L as LLMPlugin, P as PipelineOptions, b as AgentState, S as STTStream, T as TranscriptionResult } from './types-DWdkYmW8.mjs';
5
+ export { c as AgentEvents, d as AudioOutput, D as DataMessageHandler, e as LLMChunk, f as MemoryConfig, g as PipelineEvents, R as RespondMode, h as STTPlugin, i as STTStreamOptions, j as TTSPlugin } from './types-DWdkYmW8.mjs';
6
6
 
7
7
  declare class VoiceAgent extends EventEmitter {
8
8
  private readonly config;
@@ -111,6 +111,9 @@ declare class Pipeline extends EventEmitter {
111
111
  /** Queued turn while current one is still processing */
112
112
  private pendingTurn;
113
113
  constructor(options: PipelineOptions);
114
+ /** One-shot warmup — safe to call from constructor, resolves when both LLM and TTS are ready. */
115
+ private _warmupPromise;
116
+ private warmup;
114
117
  get processing(): boolean;
115
118
  get running(): boolean;
116
119
  get agentState(): AgentState;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as _dtelecom_server_sdk_node from '@dtelecom/server-sdk-node';
2
2
  import { Room, AudioSource, RemoteAudioTrack, AudioFrame } from '@dtelecom/server-sdk-node';
3
3
  import { EventEmitter } from 'events';
4
- import { A as AgentConfig, a as AgentStartOptions, M as Message, L as LLMPlugin, P as PipelineOptions, b as AgentState, S as STTStream, T as TranscriptionResult } from './types-EvtHMokR.js';
5
- export { c as AgentEvents, d as AudioOutput, D as DataMessageHandler, e as LLMChunk, f as MemoryConfig, g as PipelineEvents, R as RespondMode, h as STTPlugin, i as STTStreamOptions, j as TTSPlugin } from './types-EvtHMokR.js';
4
+ import { A as AgentConfig, a as AgentStartOptions, M as Message, L as LLMPlugin, P as PipelineOptions, b as AgentState, S as STTStream, T as TranscriptionResult } from './types-DWdkYmW8.js';
5
+ export { c as AgentEvents, d as AudioOutput, D as DataMessageHandler, e as LLMChunk, f as MemoryConfig, g as PipelineEvents, R as RespondMode, h as STTPlugin, i as STTStreamOptions, j as TTSPlugin } from './types-DWdkYmW8.js';
6
6
 
7
7
  declare class VoiceAgent extends EventEmitter {
8
8
  private readonly config;
@@ -111,6 +111,9 @@ declare class Pipeline extends EventEmitter {
111
111
  /** Queued turn while current one is still processing */
112
112
  private pendingTurn;
113
113
  constructor(options: PipelineOptions);
114
+ /** One-shot warmup — safe to call from constructor, resolves when both LLM and TTS are ready. */
115
+ private _warmupPromise;
116
+ private warmup;
114
117
  get processing(): boolean;
115
118
  get running(): boolean;
116
119
  get agentState(): AgentState;
package/dist/index.js CHANGED
@@ -698,17 +698,33 @@ var AudioOutput = class {
698
698
  * Start sparse silence keepalive to prevent the SFU from dropping the track.
699
699
  * With Opus DTX enabled, the encoder handles silence natively — we only need
700
700
  * an occasional packet to keep the SSRC alive.
701
+ *
702
+ * Waits for the RTP transport to be ready before sending — no frames are
703
+ * wasted before DTLS is connected.
701
704
  */
702
705
  startSilence() {
703
706
  if (this.silenceInterval) return;
704
- log3.debug("Starting silence keepalive (sparse, 3s interval)");
705
- this.silenceInterval = setInterval(() => {
706
- if (!this._playing && !this._responding && !this._stopped) {
707
- const f = new import_server_sdk_node2.AudioFrame(SILENCE, SAMPLE_RATE, CHANNELS, SAMPLES_PER_FRAME);
708
- this.source.captureFrame(f).catch(() => {
709
- });
710
- }
711
- }, 3e3);
707
+ const startKeepalive = () => {
708
+ log3.debug("Transport ready \u2014 sending initial silence + starting 3s keepalive");
709
+ this.sendSilenceFrame();
710
+ this.silenceInterval = setInterval(() => {
711
+ if (!this._playing && !this._responding && !this._stopped) {
712
+ this.sendSilenceFrame();
713
+ }
714
+ }, 3e3);
715
+ };
716
+ if (this.source.ready) {
717
+ startKeepalive();
718
+ } else {
719
+ log3.debug("Waiting for transport before starting silence keepalive...");
720
+ this.source.onReady = () => startKeepalive();
721
+ }
722
+ }
723
+ sendSilenceFrame() {
724
+ const frame = new import_server_sdk_node2.AudioFrame(SILENCE, SAMPLE_RATE, CHANNELS, SAMPLES_PER_FRAME);
725
+ this.source.captureFrame(frame).catch((err) => {
726
+ log3.warn("Failed to send silence frame:", err);
727
+ });
712
728
  }
713
729
  /**
714
730
  * Write a PCM16 buffer to the audio output.
@@ -1173,16 +1189,27 @@ var Pipeline = class extends import_events.EventEmitter {
1173
1189
  this.splitter.reset();
1174
1190
  this.setAgentState("idle");
1175
1191
  };
1192
+ this._warmupPromise = this.warmup(options.instructions);
1193
+ }
1194
+ /** One-shot warmup — safe to call from constructor, resolves when both LLM and TTS are ready. */
1195
+ _warmupPromise;
1196
+ async warmup(instructions) {
1197
+ const tasks = [];
1176
1198
  if (this.llm.warmup) {
1177
- this.llm.warmup(options.instructions).catch((err) => {
1178
- log7.warn("LLM warmup failed:", err);
1179
- });
1199
+ tasks.push(
1200
+ this.llm.warmup(instructions).catch((err) => {
1201
+ log7.warn("LLM warmup failed:", err);
1202
+ })
1203
+ );
1180
1204
  }
1181
1205
  if (this.tts?.warmup) {
1182
- this.tts.warmup().catch((err) => {
1183
- log7.warn("TTS warmup failed:", err);
1184
- });
1206
+ tasks.push(
1207
+ this.tts.warmup().catch((err) => {
1208
+ log7.warn("TTS warmup failed:", err);
1209
+ })
1210
+ );
1185
1211
  }
1212
+ await Promise.all(tasks);
1186
1213
  }
1187
1214
  get processing() {
1188
1215
  return this._processing;
@@ -1289,6 +1316,7 @@ var Pipeline = class extends import_events.EventEmitter {
1289
1316
  return;
1290
1317
  }
1291
1318
  this._processing = true;
1319
+ await this._warmupPromise;
1292
1320
  const tSpeechEnd = this.lastFinalAt;
1293
1321
  const sttDuration = this.lastSttDuration;
1294
1322
  let tLlmFirstToken = 0;
@@ -1442,6 +1470,7 @@ var Pipeline = class extends import_events.EventEmitter {
1442
1470
  return;
1443
1471
  }
1444
1472
  this._processing = true;
1473
+ await this._warmupPromise;
1445
1474
  log7.info(`say(): "${text.slice(0, 60)}"`);
1446
1475
  try {
1447
1476
  const signal = this.bargeIn.startCycle();