agent.libx.js 0.92.4 → 0.92.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/cli/cli.ts CHANGED
@@ -986,7 +986,8 @@ async function repl(args: Args, ai: ChatLike, cfg: Partial<AgentConfig>, cwd: st
986
986
  // the line editor for raw stdin). Auto-deny with a narratable reason — the worker adapts or reports
987
987
  // back and the voice narrates it. Allow/deny rules (config, --allowedTools, --yes) apply as-is.
988
988
  const duplexAsk = async (call: ToolUse): Promise<{ decision: 'allow' | 'deny' }> => {
989
- err(yellow(` ⊘ worker asked to run ${call.name} — auto-denied (no interactive approval in duplex; use --yes or --allowedTools)\n`));
989
+ err('\r\x1b[0J' + yellow(` ⊘ worker asked to run ${call.name} — auto-denied (no interactive approval in duplex; use --yes or --allowedTools)\n`));
990
+ editorRef?.redrawNow(); // background event at a live prompt — repaint below the notice
990
991
  return { decision: 'deny' };
991
992
  };
992
993
  if (duplex) {
@@ -1039,6 +1040,15 @@ async function repl(args: Args, ai: ChatLike, cfg: Partial<AgentConfig>, cwd: st
1039
1040
  editorRef?.redrawNow();
1040
1041
  return;
1041
1042
  }
1043
+ // Remaining task_* events (started/progress/cancelled/error) land ASYNC at a live prompt —
1044
+ // same treatment as task_done: clear the prompt line, print, repaint (bare err() leaves
1045
+ // residue glued to 'agentx › '). task_done returned above; everything else falls through.
1046
+ if (typeof e.kind === 'string' && e.kind.startsWith('task_')) {
1047
+ spinner.stop();
1048
+ err('\r\x1b[0J' + dim(` · ${e.message}\n`));
1049
+ editorRef?.redrawNow();
1050
+ return;
1051
+ }
1042
1052
  base.notify!(e); // makeHost always provides notify (the HostBridge type just marks it optional)
1043
1053
  },
1044
1054
  };
package/dist/cli.js CHANGED
@@ -3978,9 +3978,20 @@ var VoiceEngine = class {
3978
3978
  echoActive() {
3979
3979
  return this.speaking || now() < this.echoUntil;
3980
3980
  }
3981
+ /** Genuine user speech vs our own bleed (AEC tier): novel words must DOMINATE, not merely exist.
3982
+ * Degraded AEC + an STT mis-hearing manufactures a single novel word out of pure echo (a name or
3983
+ * rare word in our own reply comes back transcribed slightly differently — 1 novel / N words).
3984
+ * A real interjection is mostly novel ("stop", "wait what") — short utterances pass on ratio,
3985
+ * longer ones on count. */
3986
+ genuine(text) {
3987
+ const total = this.words(text).length;
3988
+ const novel = this.novelWords(text).length;
3989
+ if (!novel) return false;
3990
+ return novel >= 2 || novel / Math.max(1, total) > 0.5;
3991
+ }
3981
3992
  handlePartial(text) {
3982
3993
  if (this.speaking) {
3983
- const barge = this.novelWords(text).length >= (this.usingAec ? 1 : this.suspectUntil ? 1 : 2);
3994
+ const barge = this.usingAec ? this.genuine(text) : this.novelWords(text).length >= (this.suspectUntil ? 1 : 2);
3984
3995
  if (barge) {
3985
3996
  const phase = this.ctxOpen ? "speaking" : "drain";
3986
3997
  this.interrupt();
@@ -3994,10 +4005,10 @@ var VoiceEngine = class {
3994
4005
  this.pendingTimer = null;
3995
4006
  }
3996
4007
  }
3997
- if (!this.echoActive() || this.novelWords(text).length >= 1) this.options.onPartial(text);
4008
+ if (!this.echoActive() || (this.usingAec ? this.genuine(text) : this.novelWords(text).length >= 1)) this.options.onPartial(text);
3998
4009
  }
3999
4010
  handleUtterance(text) {
4000
- if (this.echoActive() && this.novelWords(text).length < (this.usingAec ? 1 : 2)) {
4011
+ if (this.echoActive() && (this.usingAec ? !this.genuine(text) : this.novelWords(text).length < 2)) {
4001
4012
  this.stt.reset();
4002
4013
  return;
4003
4014
  }
@@ -7710,8 +7721,9 @@ async function repl(args, ai, cfg, cwd) {
7710
7721
  let duplexAccount = () => {
7711
7722
  };
7712
7723
  const duplexAsk = async (call) => {
7713
- err(yellow(` \u2298 worker asked to run ${call.name} \u2014 auto-denied (no interactive approval in duplex; use --yes or --allowedTools)
7724
+ err("\r\x1B[0J" + yellow(` \u2298 worker asked to run ${call.name} \u2014 auto-denied (no interactive approval in duplex; use --yes or --allowedTools)
7714
7725
  `));
7726
+ editorRef?.redrawNow();
7715
7727
  return { decision: "deny" };
7716
7728
  };
7717
7729
  if (duplex) {
@@ -7752,6 +7764,13 @@ async function repl(args, ai, cfg, cwd) {
7752
7764
  editorRef?.redrawNow();
7753
7765
  return;
7754
7766
  }
7767
+ if (typeof e.kind === "string" && e.kind.startsWith("task_")) {
7768
+ spinner.stop();
7769
+ err("\r\x1B[0J" + dim(` \xB7 ${e.message}
7770
+ `));
7771
+ editorRef?.redrawNow();
7772
+ return;
7773
+ }
7755
7774
  base.notify(e);
7756
7775
  }
7757
7776
  };