@livx.cc/agentx 0.99.119 → 0.99.121
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 +1 -1
- package/dist/cli.js +55 -14
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +55 -14
- package/dist/index.js.map +1 -1
- package/dist/{secondChannel-DepBV0Zv.d.ts → secondChannel-D33Wvruo.d.ts} +8 -1
- package/package.json +2 -2
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-
|
|
2
|
+
import { o as RouterState, H as Hooks, p as RunResult, R as ReasoningEffort, C as ChannelMode, A as Agent } from './secondChannel-D33Wvruo.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
|
@@ -10027,8 +10027,17 @@ function isPhatic(text, bank) {
|
|
|
10027
10027
|
return !!q2 && (t === q2 || t.startsWith(q2 + " "));
|
|
10028
10028
|
});
|
|
10029
10029
|
}
|
|
10030
|
+
var CLOSER = new Set("ok okay k cool great nice perfect awesome amazing lovely excellent alright fine good thanks thank thx you so much very a lot bye goodbye cheers later see ya night got it i that that's thats is it's its all for now sounds understood noted makes sense oh ah wow right then just \u05EA\u05D5\u05D3\u05D4 \u05E8\u05D1\u05D4 \u05E1\u05D1\u05D1\u05D4 \u05D0\u05D5\u05E7\u05D9\u05D9 \u05D0\u05D5\u05E7\u05D9 \u05D1\u05E1\u05D3\u05E8 \u05D9\u05D5\u05E4\u05D9 \u05D0\u05D7\u05DC\u05D4 \u05DE\u05E2\u05D5\u05DC\u05D4 \u05DE\u05E6\u05D5\u05D9\u05DF \u05DE\u05D2\u05E0\u05D9\u05D1 \u05E0\u05D4\u05D3\u05E8 \u05D1\u05D9\u05D9 \u05DC\u05D4\u05EA\u05E8\u05D0\u05D5\u05EA \u05D8\u05D5\u05D1 \u05D6\u05D4\u05D5 \u05D6\u05D4 \u05D4\u05DB\u05DC \u05D1\u05D9\u05E0\u05EA\u05D9\u05D9\u05DD \u05D4\u05D1\u05E0\u05EA\u05D9 \u05DE\u05DE\u05E9 \u05DC\u05DA \u05D0\u05D6".split(" "));
|
|
10031
|
+
function turnIntent(text) {
|
|
10032
|
+
const t = text.trim();
|
|
10033
|
+
if (/\?[\s"')\]]*$/.test(t)) return "ask";
|
|
10034
|
+
const w = norm3(t).split(" ").filter(Boolean);
|
|
10035
|
+
const asks = requestOpener(t) && !/^ת/.test(lead(t)[0] ?? "") || pendingQuestion(t);
|
|
10036
|
+
if (w.length && w.length <= 8 && w.every((x) => CLOSER.has(x)) && !asks) return "closer";
|
|
10037
|
+
return asks || requestOpener(t) ? "ask" : "say";
|
|
10038
|
+
}
|
|
10030
10039
|
var SKIP = new Set("um uh uhm erm hmm mm oh ok okay so no yes yeah yep well hey hi and but right alright actually like now then wait hang on me speaker \u05D0\u05D5\u05E7\u05D9\u05D9 \u05D8\u05D5\u05D1 \u05D0\u05D6 \u05DC\u05D0 \u05DB\u05DF \u05E8\u05D2\u05E2 \u05D0\u05D4 \u05D0\u05DE \u05D9\u05D0\u05DC\u05DC\u05D4 \u05D5".split(" "));
|
|
10031
|
-
var ASK = "what whats how why where when who which whose is are was were do does did can could would will should shall have has may isnt arent dont doesnt didnt cant wont check open show tell find search look send run go lets please take give make write explain select focus order try compare list use set activate highlight outline capture start stop read play call book create add remove delete put type click close switch help get summarize translate mark keep remind schedule \u05DE\u05D4 \u05D0\u05D9\u05DA \u05DC\u05DE\u05D4 \u05D0\u05D9\u05E4\u05D4 \u05DE\u05EA\u05D9 \u05DE\u05D9 \u05D4\u05D0\u05DD \u05DB\u05DE\u05D4 \u05EA\u05DF \u05EA\u05E0\u05D9 \u05EA\u05D2\u05D9\u05D3 \u05EA\u05D2\u05D9\u05D3\u05D9 \u05D1\u05D5\u05D0 \u05D1\u05D5\u05D0\u05D9".split(" ");
|
|
10040
|
+
var ASK = "what whats how why where when who which whose is are was were do does did can could would will should shall have has may isnt arent dont doesnt didnt cant wont check open show tell find search look send run go lets please take give make write explain select focus order try compare list use set activate highlight outline capture start stop read play call book create add remove delete put type click close switch help get name recommend suggest summarize translate mark keep remind schedule \u05DE\u05D4 \u05D0\u05D9\u05DA \u05DC\u05DE\u05D4 \u05D0\u05D9\u05E4\u05D4 \u05DE\u05EA\u05D9 \u05DE\u05D9 \u05D4\u05D0\u05DD \u05DB\u05DE\u05D4 \u05EA\u05DF \u05EA\u05E0\u05D9 \u05EA\u05D2\u05D9\u05D3 \u05EA\u05D2\u05D9\u05D3\u05D9 \u05D1\u05D5\u05D0 \u05D1\u05D5\u05D0\u05D9".split(" ");
|
|
10032
10041
|
var WANT = /^(i (want|need|would like|d like|wanna)|אני (רוצה|צריך|צריכה|מבקש|מבקשת))(\s|$)/u;
|
|
10033
10042
|
var lead = (text) => {
|
|
10034
10043
|
const w = text.toLowerCase().replace(/[^\p{L}\p{N}\s]+/gu, "").split(/\s+/).filter(Boolean);
|
|
@@ -13164,6 +13173,9 @@ var SecondChannelOptions = class {
|
|
|
13164
13173
|
/** Duplex v3 (§3 first sound): a bridge skips the decider (the veto stays for backchannels/fillers) and speaks a
|
|
13165
13174
|
* canned line at once; a generated one is started at dispatch and used only if it already landed. */
|
|
13166
13175
|
instantBridge = false;
|
|
13176
|
+
/** Duplex v3 §3 late bridge: a turn that expects an answer (not a closer) and got no bridge yet gets one canned bridge
|
|
13177
|
+
* this long after the user's last word if channel-1 is still silent — the short turns the 0ms rule skips ("Hi"). 0 = off. */
|
|
13178
|
+
lateBridgeMs = 0;
|
|
13167
13179
|
/** No new interim for this long → a pause (hosts may also call onPause). */
|
|
13168
13180
|
fillerPauseMs = 700;
|
|
13169
13181
|
fillerMinWords = 4;
|
|
@@ -13227,6 +13239,11 @@ var SecondChannel = class {
|
|
|
13227
13239
|
pauseTimer = null;
|
|
13228
13240
|
bcTimer = null;
|
|
13229
13241
|
bridgeTimer = null;
|
|
13242
|
+
lateTimer = null;
|
|
13243
|
+
late = false;
|
|
13244
|
+
// the bridge moment being considered is the late one (no length rule)
|
|
13245
|
+
lastWordAgo = 0;
|
|
13246
|
+
// the dispatched turn: ms since the user's last word (anchors lateBridgeMs)
|
|
13230
13247
|
lastAt = -Infinity;
|
|
13231
13248
|
lastKind = null;
|
|
13232
13249
|
live = null;
|
|
@@ -13345,9 +13362,11 @@ var SecondChannel = class {
|
|
|
13345
13362
|
if (s === this.main) return;
|
|
13346
13363
|
this.main = s;
|
|
13347
13364
|
if (s === "first_audio" || s === "speaking") this.live = null;
|
|
13348
|
-
if (s !== "queued" && s !== "thinking"
|
|
13349
|
-
|
|
13350
|
-
|
|
13365
|
+
if (s !== "queued" && s !== "thinking") {
|
|
13366
|
+
for (const k of ["bridgeTimer", "lateTimer"]) if (this[k]) {
|
|
13367
|
+
clearTimeout(this[k]);
|
|
13368
|
+
this[k] = null;
|
|
13369
|
+
}
|
|
13351
13370
|
}
|
|
13352
13371
|
if (s === "idle") {
|
|
13353
13372
|
this.heard = "";
|
|
@@ -13368,7 +13387,7 @@ var SecondChannel = class {
|
|
|
13368
13387
|
this.userSpeaking = false;
|
|
13369
13388
|
this.bridged = false;
|
|
13370
13389
|
if (this.lastKind === "bridge") this.lastKind = null;
|
|
13371
|
-
for (const k of ["pauseTimer", "bcTimer", "bridgeTimer"]) {
|
|
13390
|
+
for (const k of ["pauseTimer", "bcTimer", "bridgeTimer", "lateTimer"]) {
|
|
13372
13391
|
if (this[k]) clearTimeout(this[k]);
|
|
13373
13392
|
this[k] = null;
|
|
13374
13393
|
}
|
|
@@ -13379,11 +13398,21 @@ var SecondChannel = class {
|
|
|
13379
13398
|
void this.consider("working");
|
|
13380
13399
|
}, wait);
|
|
13381
13400
|
else void this.consider("working");
|
|
13401
|
+
const late = this.o.lateBridgeMs - this.lastWordAgo;
|
|
13402
|
+
if (this.o.lateBridgeMs > 0) this.lateTimer = setTimeout(() => {
|
|
13403
|
+
this.lateTimer = null;
|
|
13404
|
+
if (this.bridged || this.busy || turnIntent(this.heard) === "closer" || this.blocked("bridge")) return;
|
|
13405
|
+
this.late = true;
|
|
13406
|
+
void this.consider("working").finally(() => {
|
|
13407
|
+
this.late = false;
|
|
13408
|
+
});
|
|
13409
|
+
}, Math.max(late, wait + 1));
|
|
13382
13410
|
}
|
|
13383
13411
|
}
|
|
13384
13412
|
/** The user's final line was dispatched to the main agent (its words are the bridge's micro-context). */
|
|
13385
|
-
onUserTurn(text) {
|
|
13413
|
+
onUserTurn(text, lastWordAgoMs = 0) {
|
|
13386
13414
|
this.heard = text.trim();
|
|
13415
|
+
this.lastWordAgo = Math.max(0, lastWordAgoMs);
|
|
13387
13416
|
this.floorWords = this.carried + words3(this.heard).length;
|
|
13388
13417
|
this.lastUser = this.heard;
|
|
13389
13418
|
this.detect(this.heard);
|
|
@@ -13451,12 +13480,19 @@ var SecondChannel = class {
|
|
|
13451
13480
|
}
|
|
13452
13481
|
/** Why this turn gets no bridge by rule ('' = it may) — language, a quick/phatic turn, or blocked(). */
|
|
13453
13482
|
bridgeBlock() {
|
|
13454
|
-
const w = words3(this.heard);
|
|
13483
|
+
const w = words3(this.heard), intent = turnIntent(this.heard);
|
|
13455
13484
|
if (!this.lang) return "language unknown";
|
|
13456
|
-
if (
|
|
13457
|
-
if (
|
|
13485
|
+
if (intent === "closer") return "no answer due";
|
|
13486
|
+
if (this.late) return this.blocked("bridge");
|
|
13487
|
+
const why = intent === "ask" ? w.length <= 6 && isPhatic(this.heard, this.bank) ? "phatic" : "" : this.shortTurn(w.length);
|
|
13488
|
+
if (why) return this.o.lateBridgeMs > 0 ? `${why} (late bridge armed)` : why;
|
|
13458
13489
|
return this.blocked("bridge");
|
|
13459
13490
|
}
|
|
13491
|
+
shortTurn(n) {
|
|
13492
|
+
if (n <= 3 || n <= 6 && isPhatic(this.heard, this.bank)) return n <= 3 ? "quick turn" : "phatic";
|
|
13493
|
+
if (n < this.o.bridgeMinWords) return `under ${this.o.bridgeMinWords} words`;
|
|
13494
|
+
return "";
|
|
13495
|
+
}
|
|
13460
13496
|
bcTimes = [];
|
|
13461
13497
|
capped() {
|
|
13462
13498
|
if (!this.o.maxPerWindow) return false;
|
|
@@ -13468,8 +13504,9 @@ var SecondChannel = class {
|
|
|
13468
13504
|
rule(trigger, pauseMs = 0, breath = false, cue = null) {
|
|
13469
13505
|
const w = words3(this.heard);
|
|
13470
13506
|
if (!this.lang) return "silence";
|
|
13507
|
+
if (trigger === "working") return this.bridgeBlock() ? "silence" : "bridge";
|
|
13471
13508
|
if (w.length <= 3 || w.length <= 6 && isPhatic(this.heard, this.bank)) return "silence";
|
|
13472
|
-
const k = trigger === "interim" ? this.backchannelMoment(w.length, breath) && (!this.o.anticipate || !this.plan || !silentTurn(this.plan) && (!!cue || !this.o.cueOnly && this.plan.density !== "low")) ? "backchannel" : null : trigger === "pause" ? pauseMs >= this.o.fillerPauseMs && w.length >= this.o.fillerMinWords ? "filler" : null :
|
|
13509
|
+
const k = trigger === "interim" ? this.backchannelMoment(w.length, breath) && (!this.o.anticipate || !this.plan || !silentTurn(this.plan) && (!!cue || !this.o.cueOnly && this.plan.density !== "low")) ? "backchannel" : null : trigger === "pause" ? pauseMs >= this.o.fillerPauseMs && w.length >= this.o.fillerMinWords ? "filler" : null : null;
|
|
13473
13510
|
return k && this.allowed(k) ? k : "silence";
|
|
13474
13511
|
}
|
|
13475
13512
|
/** Plan (or, with `heard`, revise) the backchannels of the user's turn — async, never on the hot path. */
|
|
@@ -13736,8 +13773,11 @@ var VoiceCall = class {
|
|
|
13736
13773
|
aec: o.aec,
|
|
13737
13774
|
// v3 §3: first sound <1.2s p50 from the last word — the endpoint takes ~0.6s and the bridge's TTS ~0.2s, so the bridge
|
|
13738
13775
|
// goes 300ms after the turn if MAIN is still silent (it always is that early: warm MAIN's first token is ≥1s), no veto
|
|
13776
|
+
// A short question gets that bridge too (by intent, not length); any other turn expecting an answer that got none
|
|
13777
|
+
// gets a late one at 1.3s from the last word while MAIN is still silent (API first byte runs 1-8s); a closer, none.
|
|
13739
13778
|
bridgeDelayMs: 300,
|
|
13740
13779
|
instantBridge: true,
|
|
13780
|
+
lateBridgeMs: 1300,
|
|
13741
13781
|
...this.lang ? { lang: this.lang } : {},
|
|
13742
13782
|
...o.channel,
|
|
13743
13783
|
// the ledger: a turn's bridge moment that stayed silent, and why (its wait then has no first sound until MAIN speaks)
|
|
@@ -13961,7 +14001,7 @@ var VoiceCall = class {
|
|
|
13961
14001
|
if (this.cur) this.close(this.cur, t.replaces === this.cur.id ? "replaced" : void 0);
|
|
13962
14002
|
this.follow(t.text);
|
|
13963
14003
|
this.clearProgress();
|
|
13964
|
-
this.cur = { id: t.id, text: t.text, at, finalAt, lastWord, running: true, streamed: false, sounded: false, worded: false, done: false, marks: { sent: now4 }, closed: false };
|
|
14004
|
+
this.cur = { id: t.id, text: t.text, at, finalAt, lastWord, running: true, streamed: false, sounded: false, worded: false, done: false, marks: { sent: now4 }, closed: false, due: turnIntent(t.text) !== "closer" };
|
|
13965
14005
|
const early = this.earlyHeard;
|
|
13966
14006
|
this.earlyHeard = null;
|
|
13967
14007
|
if (early && early.at >= at) {
|
|
@@ -13971,7 +14011,7 @@ var VoiceCall = class {
|
|
|
13971
14011
|
this.progress.turn();
|
|
13972
14012
|
this.o.onMetric({ name: "turn", id: t.id, kind: t.kind, text: t.text });
|
|
13973
14013
|
this.o.sendTurn(t.text, { id: t.id, ...t.replaces ? { replaces: t.replaces } : {} });
|
|
13974
|
-
if (t.kind === "new") this.fill.onUserTurn(t.text);
|
|
14014
|
+
if (t.kind === "new") this.fill.onUserTurn(t.text, now4 - at);
|
|
13975
14015
|
}
|
|
13976
14016
|
onDrop(text, why) {
|
|
13977
14017
|
if (!this.gate.holding) {
|
|
@@ -14010,7 +14050,7 @@ var VoiceCall = class {
|
|
|
14010
14050
|
sounded(c, by, at = this.o.now()) {
|
|
14011
14051
|
if (c.sounded) return;
|
|
14012
14052
|
c.sounded = true;
|
|
14013
|
-
this.o.onMetric({ name: "first_sound", id: c.id, ms: Math.round(at - c.at), by });
|
|
14053
|
+
this.o.onMetric(c.due ? { name: "first_sound", id: c.id, ms: Math.round(at - c.at), by } : { name: "first_sound", id: c.id, by, kind: "no answer due" });
|
|
14014
14054
|
}
|
|
14015
14055
|
/** The turn is over (answered + audible, replaced, the next turn, the call's end): its timeline, once. A turn whose MAIN
|
|
14016
14056
|
* never became audible still reports first_word — with no ms and why (cut / replaced / silent) — so every turn has one. */
|
|
@@ -14030,7 +14070,8 @@ var VoiceCall = class {
|
|
|
14030
14070
|
mainText: rel(m.mainText),
|
|
14031
14071
|
mainAudio: rel(m.mainAudio),
|
|
14032
14072
|
lastWord: c.lastWord,
|
|
14033
|
-
end: c.end
|
|
14073
|
+
end: c.end,
|
|
14074
|
+
...c.due ? {} : { due: false }
|
|
14034
14075
|
};
|
|
14035
14076
|
for (const k of Object.keys(tl)) if (tl[k] === void 0) delete tl[k];
|
|
14036
14077
|
this.o.onMetric({ name: "timeline", id: c.id, text: c.text, timeline: tl });
|