@livx.cc/agentx 0.97.3 → 0.97.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.js CHANGED
@@ -4651,6 +4651,26 @@ init_logging();
4651
4651
  // src/voice/spokenSplitter.ts
4652
4652
  var OPEN = "<spoken>";
4653
4653
  var CLOSE = "</spoken>";
4654
+ var SentenceCoalescer = class _SentenceCoalescer {
4655
+ buf = "";
4656
+ static isEnd(c) {
4657
+ return c === "\n" || c === "." || c === "!" || c === "?" || c === "\u2026";
4658
+ }
4659
+ feed(delta) {
4660
+ if (delta) this.buf += delta;
4661
+ let cut = -1;
4662
+ for (let i = 0; i < this.buf.length; i++) if (_SentenceCoalescer.isEnd(this.buf[i])) cut = i;
4663
+ if (cut < 0) return "";
4664
+ const ready = this.buf.slice(0, cut + 1).trim();
4665
+ this.buf = this.buf.slice(cut + 1);
4666
+ return ready;
4667
+ }
4668
+ flush() {
4669
+ const s = this.buf.trim();
4670
+ this.buf = "";
4671
+ return s;
4672
+ }
4673
+ };
4654
4674
  var SpokenSplitter = class {
4655
4675
  buf = "";
4656
4676
  inSpoken = false;
@@ -5090,13 +5110,19 @@ ${recent}` : brief) + verify + deliverContract;
5090
5110
  const speak = (seg) => {
5091
5111
  if (seg) o.host?.notify?.({ kind: "speak_utterance", message: seg });
5092
5112
  };
5113
+ const coalescer = new SentenceCoalescer();
5114
+ const feedSpoken = (s) => {
5115
+ const ready = coalescer.feed(s);
5116
+ if (ready) speak(ready);
5117
+ };
5118
+ const flushSpoken = () => speak(coalescer.flush());
5093
5119
  const askBridge = o.askRelay ? { ask: relayAsk } : o.host?.ask ? { ask: (q) => o.host.ask(q) } : {};
5094
5120
  const workerHost = {
5095
5121
  ...askBridge,
5096
5122
  notify: (ev) => {
5097
5123
  if (ev?.kind === "text_delta" && typeof ev.message === "string") {
5098
5124
  const { spoken, detail } = splitter.feed(ev.message);
5099
- speak(spoken);
5125
+ feedSpoken(spoken);
5100
5126
  if (detail.trim()) pushTail(detail.trim());
5101
5127
  return;
5102
5128
  }
@@ -5119,7 +5145,13 @@ ${recent}` : brief) + verify + deliverContract;
5119
5145
  signal: controller.signal
5120
5146
  // shared with the checker so a cancel tears down both
5121
5147
  };
5122
- const promise = new Agent(agentOpts).run(briefText).then((res) => this.maybeVerify(id, brief, res, tier, agentOpts, askBridge)).then((res) => this.onWorkerSettled(id, res)).catch((err) => this.onWorkerFailed(id, err));
5148
+ const promise = new Agent(agentOpts).run(briefText).then((res) => {
5149
+ const { spoken, detail } = splitter.flush();
5150
+ feedSpoken(spoken);
5151
+ if (detail.trim()) pushTail(detail.trim());
5152
+ flushSpoken();
5153
+ return res;
5154
+ }).then((res) => this.maybeVerify(id, brief, res, tier, agentOpts, askBridge)).then((res) => this.onWorkerSettled(id, res)).catch((err) => this.onWorkerFailed(id, err));
5123
5155
  this.tasks.set(id, { id, label, status: "running", controller, promise, tail, brief, followUp, splitter });
5124
5156
  if (this.tasks.size > this.options.maxTaskRecords)
5125
5157
  for (const [tid, rec] of this.tasks) {