@livx.cc/agentx 0.99.107 → 0.99.108

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/cli.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- import { o as RouterState, H as Hooks, p as RunResult, R as ReasoningEffort, C as ChannelMode, A as Agent } from './secondChannel-BYW5qPAJ.js';
2
+ import { o as RouterState, H as Hooks, p as RunResult, R as ReasoningEffort, C as ChannelMode, A as Agent } from './secondChannel-3IPP3Qgh.js';
3
3
  import { IFilesystem } from '@livx.cc/wcli/core';
4
4
  import { M as Message, U as UserQuestion, H as HostBridge, c as ContentPart, o as MessageContent } from './tools-DZHZIyxh.js';
5
5
 
package/dist/cli.js CHANGED
@@ -13022,6 +13022,9 @@ var SecondChannelOptions = class {
13022
13022
  /** A bridge waits this long after the user's turn is dispatched, and plays only if channel-1 has said nothing yet
13023
13023
  * (a fast reply/ack needs no bridge — one before it reads as the agent starting a different sentence). 0 = at once. */
13024
13024
  bridgeDelayMs = 1200;
13025
+ /** Duplex v3 (§3 first sound): a bridge skips the decider (the veto stays for backchannels/fillers) and speaks a
13026
+ * canned line at once; a generated one is started at dispatch and used only if it already landed. */
13027
+ instantBridge = false;
13025
13028
  /** No new interim for this long → a pause (hosts may also call onPause). */
13026
13029
  fillerPauseMs = 700;
13027
13030
  fillerMinWords = 4;
@@ -13093,6 +13096,8 @@ var SecondChannel = class {
13093
13096
  // the line the last barge actually cut (spoke())
13094
13097
  bridged = false;
13095
13098
  // one bridge per main turn
13099
+ bridgeDraft = null;
13100
+ // a bridge generated ahead, used only if ready in time
13096
13101
  recent = [];
13097
13102
  picks = /* @__PURE__ */ new Map();
13098
13103
  inflight = null;
@@ -13228,6 +13233,7 @@ var SecondChannel = class {
13228
13233
  if (this[k]) clearTimeout(this[k]);
13229
13234
  this[k] = null;
13230
13235
  }
13236
+ if (this.o.instantBridge) this.prefetchBridge();
13231
13237
  const wait = Math.max(this.o.bridgeDelayMs, this.o.minGapMs - (this.o.now() - this.lastAt));
13232
13238
  if (wait > 0) this.bridgeTimer = setTimeout(() => {
13233
13239
  this.bridgeTimer = null;
@@ -13360,7 +13366,7 @@ var SecondChannel = class {
13360
13366
  try {
13361
13367
  let kind = rule;
13362
13368
  let choice;
13363
- if (this.o.decide && !cue) {
13369
+ if (this.o.decide && !cue && !(rule === "bridge" && this.o.instantBridge)) {
13364
13370
  const ac = new AbortController();
13365
13371
  const d = await withBudget(this.o.decide(this.tail(), { ...this.state(pauseMs), rule }, ac.signal), this.o.decisionBudgetMs, "channel decision", ac);
13366
13372
  choice = d?.choice;
@@ -13394,7 +13400,24 @@ var SecondChannel = class {
13394
13400
  call_ms: Math.round(now4 - this.startedAt)
13395
13401
  };
13396
13402
  }
13403
+ /** Start writing this turn's bridge now, so it may be ready by bridgeDelayMs. The bridge never waits for it. */
13404
+ prefetchBridge() {
13405
+ this.bridgeDraft = null;
13406
+ if (!this.o.generate || !this.o.generateFor.includes("bridge") || !this.lang || !this.heard) return;
13407
+ const gen = this.gen, ac = new AbortController();
13408
+ const ctx = { kind: "bridge", heard: this.tail(), state: this.main, avoid: [...this.recent], lang: this.lang };
13409
+ void withBudget(this.o.generate(ctx, ac.signal), Math.max(this.o.generateBudgetMs, this.o.bridgeDelayMs), "bridge generate", ac).then((raw) => {
13410
+ const text = cleanLine(raw ?? "", ctx.lang);
13411
+ if (text && gen === this.gen) this.bridgeDraft = { gen, text };
13412
+ }).catch((e) => log27.debug(`bridge prefetch failed: ${e?.message ?? e}`));
13413
+ }
13397
13414
  async line(kind, react = true) {
13415
+ if (kind === "bridge" && this.o.instantBridge) {
13416
+ const d = this.bridgeDraft?.gen === this.gen ? this.bridgeDraft.text : "";
13417
+ this.bridgeDraft = null;
13418
+ if (d && !this.recent.some((r) => norm3(r) === norm3(d))) return d;
13419
+ return this.pick(kind);
13420
+ }
13398
13421
  if (this.o.generate && this.o.generateFor.includes(kind) && (kind !== "backchannel" || react)) {
13399
13422
  const ac = new AbortController();
13400
13423
  const ctx = { kind, heard: this.tail(), state: this.main, avoid: [...this.recent], lang: this.lang, ...kind === "backchannel" && this.o.reactionGapMs ? { react: true } : {} };
@@ -13544,6 +13567,9 @@ var VoiceCall = class {
13544
13567
  } : {},
13545
13568
  mode: o.mode,
13546
13569
  aec: o.aec,
13570
+ bridgeDelayMs: 700,
13571
+ instantBridge: true,
13572
+ // v3 §3: first sound <1.2s p50 — a bridge at 700ms if MAIN is still silent, no veto, no wait
13547
13573
  ...this.lang ? { lang: this.lang } : {},
13548
13574
  ...o.channel,
13549
13575
  speak: (text, kind) => this.say(text, kind),