agent.libx.js 0.93.2 → 0.93.6

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.ts CHANGED
@@ -876,6 +876,7 @@ declare class VoiceEngine {
876
876
  private pausedAt;
877
877
  private lastOverlapPartial;
878
878
  private resumeTimer;
879
+ private turnStartAt;
879
880
  constructor(options?: Partial<VoiceEngineOptions>);
880
881
  start(): Promise<void>;
881
882
  get usingAec(): boolean;
@@ -942,6 +943,7 @@ declare class SonioxSTT {
942
943
  private lastChangeAt;
943
944
  private lastCombined;
944
945
  private endpointTimer;
946
+ private firstTokenAt;
945
947
  constructor(options?: Partial<SonioxSTTOptions>);
946
948
  get usingAec(): boolean;
947
949
  private connectWs;
package/dist/index.js CHANGED
@@ -2896,9 +2896,17 @@ var Agent = class _Agent {
2896
2896
  let res;
2897
2897
  const sent = this.trimContext();
2898
2898
  const frag = reasoningToChatFragment(o.model, o.reasoning);
2899
+ const isCursorWithTools = o.model.startsWith("cursor/") && wireTools.length > 0;
2900
+ const cursorPo = isCursorWithTools ? {
2901
+ toolExecutor: async (name, args) => {
2902
+ const tc = { id: `cursor-${Date.now()}`, type: "function", function: { name, arguments: JSON.stringify(args) } };
2903
+ const raw = await this.dispatch(tc);
2904
+ return typeof raw === "string" ? raw : raw.text;
2905
+ }
2906
+ } : void 0;
2899
2907
  const reasonOpts = {
2900
2908
  ...frag,
2901
- ...o.providerOptions ? { providerOptions: { ...frag.providerOptions, ...o.providerOptions } } : {}
2909
+ ...o.providerOptions || cursorPo ? { providerOptions: { ...frag.providerOptions, ...o.providerOptions, ...cursorPo } } : {}
2902
2910
  };
2903
2911
  try {
2904
2912
  if (useStream) {
@@ -3601,7 +3609,7 @@ var DuplexAgentOptions = class {
3601
3609
  ai;
3602
3610
  /** The WORKER's filesystem. If omitted the worker keeps Agent's jailed-disk-at-cwd default. */
3603
3611
  fs;
3604
- voiceModel = "anthropic/claude-haiku-4-5";
3612
+ voiceModel = "groq/openai/gpt-oss-20b";
3605
3613
  workerModel = "anthropic/claude-sonnet-4-6";
3606
3614
  /** Escape hatches merged over the derived per-agent options. */
3607
3615
  voiceOptions;
@@ -4198,6 +4206,8 @@ var VoiceEngine = class {
4198
4206
  lastOverlapPartial = "";
4199
4207
  // change-detection: only NEW partial text counts as activity
4200
4208
  resumeTimer = null;
4209
+ turnStartAt = 0;
4210
+ // timestamp when the current turn began (for TTFT logging)
4201
4211
  constructor(options) {
4202
4212
  this.options = { ...new VoiceEngineOptions(), ...options };
4203
4213
  const o = this.options;
@@ -4258,6 +4268,7 @@ var VoiceEngine = class {
4258
4268
  this.spokeDeltas = true;
4259
4269
  this.ackAt = now();
4260
4270
  }
4271
+ this.turnStartAt = now();
4261
4272
  this.setState("thinking");
4262
4273
  }
4263
4274
  speakDelta(text) {
@@ -4266,6 +4277,7 @@ var VoiceEngine = class {
4266
4277
  this.reply += text;
4267
4278
  for (const w of this.words(this.reply)) this.echoWords.add(w);
4268
4279
  this.tts.speak(text, true);
4280
+ if (!this.spokeDeltas && this.turnStartAt) log8.info(`ttft: ${Math.round(now() - this.turnStartAt)}ms`);
4269
4281
  this.spokeDeltas = true;
4270
4282
  this.setState("speaking");
4271
4283
  }
@@ -4286,6 +4298,7 @@ var VoiceEngine = class {
4286
4298
  }
4287
4299
  this.drainTimer = null;
4288
4300
  this.speaking = false;
4301
+ if (this.turnStartAt) log8.info(`turn: ${Math.round(now() - this.turnStartAt)}ms (incl. playback)`);
4289
4302
  this.echoUntil = now() + 2500;
4290
4303
  if (!this.usingAec) this.stt.reset();
4291
4304
  this.setState("listening");
@@ -4322,7 +4335,7 @@ var VoiceEngine = class {
4322
4335
  this.ctxOpen = false;
4323
4336
  this.interrupted = true;
4324
4337
  this.suspectUntil = 0;
4325
- this.echoUntil = now() + 2500;
4338
+ this.echoUntil = now() + Math.max(2500, this.player.drainMs() + 3e3);
4326
4339
  this.tts.cancel();
4327
4340
  this.player.kill();
4328
4341
  if (!this.usingAec) this.stt.reset();
@@ -4517,6 +4530,8 @@ var SonioxSTT = class {
4517
4530
  lastChangeAt = 0;
4518
4531
  lastCombined = "";
4519
4532
  endpointTimer = null;
4533
+ firstTokenAt = 0;
4534
+ // first speech token in current utterance
4520
4535
  constructor(options) {
4521
4536
  this.options = { ...new SonioxSTTOptions(), ...options };
4522
4537
  }
@@ -4556,6 +4571,7 @@ var SonioxSTT = class {
4556
4571
  this.endpointTimer = setInterval(() => {
4557
4572
  const combined = (this.finalText + this.partialText).trim();
4558
4573
  if (!combined || now2() - this.lastChangeAt < this.options.silenceEndpointMs) return;
4574
+ if (this.firstTokenAt) log9.info(`stt: ${Math.round(now2() - this.firstTokenAt)}ms first-token\u2192silence-endpoint, "${combined.slice(0, 60)}"`);
4559
4575
  this.reset();
4560
4576
  this.onUtterance(combined, now2());
4561
4577
  }, 120);
@@ -4583,10 +4599,12 @@ var SonioxSTT = class {
4583
4599
  if (combined !== this.lastCombined) {
4584
4600
  this.lastCombined = combined;
4585
4601
  this.lastChangeAt = now2();
4602
+ if (!this.firstTokenAt && combined.trim()) this.firstTokenAt = now2();
4586
4603
  }
4587
4604
  this.onPartial(combined);
4588
4605
  if (endpoint && this.finalText.trim()) {
4589
4606
  const utterance = this.finalText.trim();
4607
+ if (this.firstTokenAt) log9.info(`stt: ${Math.round(now2() - this.firstTokenAt)}ms first-token\u2192endpoint, "${utterance.slice(0, 60)}"`);
4590
4608
  this.reset();
4591
4609
  this.onUtterance(utterance, now2());
4592
4610
  }
@@ -4595,6 +4613,7 @@ var SonioxSTT = class {
4595
4613
  this.finalText = "";
4596
4614
  this.partialText = "";
4597
4615
  this.lastCombined = "";
4616
+ this.firstTokenAt = 0;
4598
4617
  }
4599
4618
  stop() {
4600
4619
  this.stopped = true;