@dtelecom/agents-js 0.3.0 → 0.3.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.
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-Di_jxIgs.mjs';
5
- export { c as AgentEvents, d as AudioOutput, D as DataMessageHandler, e as LLMChatOptions, f as LLMChunk, g as MemoryConfig, h as PipelineEvents, R as RespondMode, i as STTPlugin, j as STTStreamOptions, k as TTSPlugin, l as ToolCallResult, m as ToolDefinition } from './types-Di_jxIgs.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-BJylZd8Q.mjs';
5
+ export { c as AgentEvents, d as AudioOutput, D as DataMessageHandler, e as LLMChatOptions, f as LLMChunk, g as MemoryConfig, h as PipelineEvents, R as RespondMode, i as STTPlugin, j as STTStreamOptions, k as TTSPlugin, l as ToolCallResult, m as ToolDefinition } from './types-BJylZd8Q.mjs';
6
6
 
7
7
  declare class VoiceAgent extends EventEmitter {
8
8
  private readonly config;
@@ -125,6 +125,7 @@ declare class Pipeline extends EventEmitter {
125
125
  private readonly _warmupPromise;
126
126
  private readonly _ttsWarmupPromise;
127
127
  private readonly _llmWarmupPromise;
128
+ private readonly _audioReadyPromise;
128
129
  get processing(): boolean;
129
130
  get running(): boolean;
130
131
  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-Di_jxIgs.js';
5
- export { c as AgentEvents, d as AudioOutput, D as DataMessageHandler, e as LLMChatOptions, f as LLMChunk, g as MemoryConfig, h as PipelineEvents, R as RespondMode, i as STTPlugin, j as STTStreamOptions, k as TTSPlugin, l as ToolCallResult, m as ToolDefinition } from './types-Di_jxIgs.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-BJylZd8Q.js';
5
+ export { c as AgentEvents, d as AudioOutput, D as DataMessageHandler, e as LLMChatOptions, f as LLMChunk, g as MemoryConfig, h as PipelineEvents, R as RespondMode, i as STTPlugin, j as STTStreamOptions, k as TTSPlugin, l as ToolCallResult, m as ToolDefinition } from './types-BJylZd8Q.js';
6
6
 
7
7
  declare class VoiceAgent extends EventEmitter {
8
8
  private readonly config;
@@ -125,6 +125,7 @@ declare class Pipeline extends EventEmitter {
125
125
  private readonly _warmupPromise;
126
126
  private readonly _ttsWarmupPromise;
127
127
  private readonly _llmWarmupPromise;
128
+ private readonly _audioReadyPromise;
128
129
  get processing(): boolean;
129
130
  get running(): boolean;
130
131
  get agentState(): AgentState;
package/dist/index.js CHANGED
@@ -682,11 +682,21 @@ var AudioOutput = class {
682
682
  _responding = false;
683
683
  _stopped = false;
684
684
  silenceInterval = null;
685
+ /** Resolves when the RTP transport is ready and initial silence has been sent. */
686
+ whenReady;
687
+ _resolveReady;
685
688
  /** When set, raw PCM from TTS is saved to this directory as WAV files for debugging. */
686
689
  dumpDir = null;
687
690
  dumpCounter = 0;
688
691
  constructor(source) {
689
692
  this.source = source;
693
+ if (source.ready) {
694
+ this.whenReady = Promise.resolve();
695
+ } else {
696
+ this.whenReady = new Promise((resolve) => {
697
+ this._resolveReady = resolve;
698
+ });
699
+ }
690
700
  }
691
701
  get playing() {
692
702
  return this._playing;
@@ -714,8 +724,11 @@ var AudioOutput = class {
714
724
  startSilence() {
715
725
  if (this.silenceInterval) return;
716
726
  const startKeepalive = () => {
717
- log3.debug("Transport ready \u2014 sending initial silence + starting 3s keepalive");
718
- this.sendSilenceFrame();
727
+ log3.debug("Transport ready \u2014 sending initial silence burst + starting 3s keepalive");
728
+ for (let i = 0; i < 15; i++) {
729
+ this.sendSilenceFrame();
730
+ }
731
+ this._resolveReady?.();
719
732
  this.silenceInterval = setInterval(() => {
720
733
  if (!this._playing && !this._responding && !this._stopped) {
721
734
  this.sendSilenceFrame();
@@ -1254,12 +1267,14 @@ var Pipeline = class extends import_events.EventEmitter {
1254
1267
  this._llmWarmupPromise = this.llm.warmup ? this.llm.warmup(options.instructions).catch((err) => {
1255
1268
  log7.warn("LLM warmup failed (non-fatal):", err);
1256
1269
  }) : Promise.resolve();
1257
- this._warmupPromise = Promise.all([this._ttsWarmupPromise, this._llmWarmupPromise]).then(() => {
1270
+ this._audioReadyPromise = this.audioOutput.whenReady;
1271
+ this._warmupPromise = Promise.all([this._ttsWarmupPromise, this._llmWarmupPromise, this._audioReadyPromise]).then(() => {
1258
1272
  });
1259
1273
  }
1260
1274
  _warmupPromise;
1261
1275
  _ttsWarmupPromise;
1262
1276
  _llmWarmupPromise;
1277
+ _audioReadyPromise;
1263
1278
  get processing() {
1264
1279
  return this._processing;
1265
1280
  }
@@ -1417,6 +1432,7 @@ var Pipeline = class extends import_events.EventEmitter {
1417
1432
  wake();
1418
1433
  };
1419
1434
  const MAX_LLM_RETRIES = 2;
1435
+ let toolCallEmitted = false;
1420
1436
  const producer = async () => {
1421
1437
  const defaultLang = this.tts?.defaultLanguage;
1422
1438
  for (let attempt = 0; attempt <= MAX_LLM_RETRIES; attempt++) {
@@ -1466,6 +1482,7 @@ var Pipeline = class extends import_events.EventEmitter {
1466
1482
  }
1467
1483
  } else if (chunk.type === "tool_call" && chunk.toolCall) {
1468
1484
  log7.info(`Tool call: ${chunk.toolCall.name}(${chunk.toolCall.arguments})`);
1485
+ toolCallEmitted = true;
1469
1486
  this.emit("toolCall", chunk.toolCall);
1470
1487
  }
1471
1488
  }
@@ -1478,7 +1495,7 @@ var Pipeline = class extends import_events.EventEmitter {
1478
1495
  if (remaining) {
1479
1496
  pushSentence(remaining);
1480
1497
  }
1481
- if (fullResponse.trim()) {
1498
+ if (fullResponse.trim() || toolCallEmitted) {
1482
1499
  break;
1483
1500
  }
1484
1501
  log7.warn(`LLM produced no output (attempt ${attempt + 1}/${MAX_LLM_RETRIES + 1})`);
@@ -1590,7 +1607,7 @@ var Pipeline = class extends import_events.EventEmitter {
1590
1607
  return;
1591
1608
  }
1592
1609
  this._processing = true;
1593
- await this._ttsWarmupPromise;
1610
+ await Promise.all([this._ttsWarmupPromise, this._audioReadyPromise]);
1594
1611
  log7.info(`say(): "${text.slice(0, 60)}"`);
1595
1612
  try {
1596
1613
  const signal = this.bargeIn.startCycle();