@livx.cc/agentx 0.99.88 → 0.99.90

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.js CHANGED
@@ -9217,6 +9217,11 @@ configureLogging((name) => {
9217
9217
  // src/voice/instinct.ts
9218
9218
  init_logging();
9219
9219
  var log19 = forComponent("Instinct");
9220
+ function voiceDeciderOptions(env = process.env) {
9221
+ if (env.TYPESAFE_AI_KEY) return { apiKey: env.TYPESAFE_AI_KEY };
9222
+ if (env.GROQ_API_KEY) return { provider: "llm", model: "groq/openai/gpt-oss-120b", apiKey: env.GROQ_API_KEY };
9223
+ return void 0;
9224
+ }
9220
9225
  var InstinctOptions = class {
9221
9226
  decider;
9222
9227
  /** Partial unchanged this long (a micro-pause) → consult. */
@@ -9609,7 +9614,7 @@ var SUSPECT = [
9609
9614
  /\bwe(?: have|'ve)\b|\bwe (?:already )?(?:responded|replied|dispatched|used|called|did|gave|said|asked)\b/i,
9610
9615
  /\bno (?:further|more|other)\b/i,
9611
9616
  /\[\s*task\b|\bt\d+\b|\bwait(?:ing)? for (?:the )?(?:events?|results?|task)\b/i,
9612
- /\w\s*\{\s*"|\bwhat:\s*"/,
9617
+ /[\p{L}\p{N}.!?…]\s*\{\s*"|\bwhat:\s*"/u,
9613
9618
  /\b(?:last|previous) (?:response|reply|message|turn)\b|\bthe (?:conversation|transcript|context)\b/i
9614
9619
  ];
9615
9620
  var STRICT = [
@@ -9626,6 +9631,12 @@ var STRICT = [
9626
9631
  // its own protocol: using its tools, tool-call syntax, task events
9627
9632
  new RegExp(String.raw`(?:\b[Ww]e(?: need to| should| must| have to| will|'ll)|\b[Ll]et'?s|^[Ss]hould|^[Nn]ow we should) (?:call|use|do|dispatch(?: to)?|invoke) (?:the )?${TOOL}\b`),
9628
9633
  new RegExp(String.raw`\b(?:[Ww]e (?:called|dispatched)|responded with) ${TOOL}\b|\b${TOOL}\s*\{|\bwhat:\s*"|\b${TOOL} (?:tool )?(?:brief|call|args?|arguments)\b`),
9634
+ // telegraphic self-instruction naming its own tool ("Use Act with brief to search npm.", "Then dispatch Act.") and
9635
+ // tool-call arguments glued onto the text ("One sentence ack.{"brief":…}" — harmony lost the call's recipient;
9636
+ // agentx sessions 20260713-124250, 20261012-225902). A JSON block printed for the listener follows whitespace.
9637
+ // "Use <Tool>" only in the planning shape (with/to/punctuation next) — "Use Act two of the play…" is speech.
9638
+ new RegExp(String.raw`^(?:Use|Call|Invoke) ${TOOL}(?= with\b| to\b|\s*[.,;:]|\s*$)|^(?:(?:Then|Now|So) )?[Dd]ispatch(?: to)? (?:the )?${TOOL}\b`),
9639
+ /[\p{L}\p{N}.!?…]\{\s*"\w+"\s*:/u,
9629
9640
  /\bwait(?:ing)? for (?:the )?(?:events?|t\d+)\b|\bt\d+ (?:completed|failed)\b|\[\s*task\b/i
9630
9641
  ];
9631
9642
  var SENTENCE_END = new RegExp(`[.!?\u2026]+["')\\]]*(?:\\s|(?=\\p{Lu}|\\[))`, "gu");
@@ -13405,7 +13416,8 @@ var SCRIPTS = [
13405
13416
  [new RegExp("\\p{Script=Latin}", "gu"), "latin"]
13406
13417
  ];
13407
13418
  var STOP3 = Object.fromEntries(Object.entries({
13408
- en: "hi hello hey yes thanks let see check one sec just give right well look the and is are you i it to of that what this was have with for not but my me",
13419
+ en: "hi hello hey yes no a thanks let see check one sec just give right well look the and is are you i it to of that what this was have with for not but my me",
13420
+ // 'a'/'no' are English too: without them 'thanks a lot', 'long time no see' failed fitsLanguage('en')
13409
13421
  es: "hola s\xED gracias bueno a me te lo se le del al el la los las que es y de en un una por para con no pero mi yo qu\xE9 est\xE1",
13410
13422
  fr: "bonjour salut oui merci le la les est et de des un une que je tu il pas pour avec mais mon qui",
13411
13423
  de: "hallo ja danke der die das und ist ich du nicht ein eine mit zu was aber mein wie auch",
@@ -13540,12 +13552,14 @@ var ChannelBanks = class {
13540
13552
  if (e.code !== "ENOENT") log29.warn(`bank cache ${f} unreadable \u2014 regenerating: ${e.message}`);
13541
13553
  return null;
13542
13554
  });
13543
- const valid = cached && validateBank(cached.bank, lang, 1);
13555
+ const valid = cached && validateBank(cached.bank, lang, 0);
13556
+ const complete = !!valid && BANK_KEYS.every((k) => valid[k].length);
13544
13557
  if (valid) {
13558
+ for (const k of BANK_KEYS) if (!valid[k].length) valid[k] = [...this.o.fallback[lang]?.[k] ?? []];
13545
13559
  this.banks.set(lang, valid);
13546
- log29.debug(`bank ${lang}: cache hit (${BANK_KEYS.map((k) => valid[k].length).join("/")})`);
13560
+ log29.debug(`bank ${lang}: cache hit (${BANK_KEYS.map((k) => valid[k].length).join("/")})${complete ? "" : " \u2014 missing kinds, refreshing"}`);
13547
13561
  }
13548
- if (valid && this.o.now() - cached.at < this.o.refreshMs) return;
13562
+ if (complete && this.o.now() - cached.at < this.o.refreshMs) return;
13549
13563
  await this.generate(lang, valid);
13550
13564
  }
13551
13565
  async generate(lang, have) {
@@ -13562,7 +13576,7 @@ var ChannelBanks = class {
13562
13576
  bank[k] = [...fresh[k], ...have?.[k] ?? []].filter((x) => !seen.has(norm2(x)) && seen.add(norm2(x))).slice(0, this.o.maxPerKind);
13563
13577
  }
13564
13578
  this.banks.set(lang, bank);
13565
- log29.info(`bank ${lang}: ${have ? "refreshed" : "generated"} (${BANK_KEYS.map((k) => bank[k].length).join("/")}) in ${Math.round(this.o.now() - t0)}ms`);
13579
+ log29.debug(`bank ${lang}: ${have ? "refreshed" : "generated"} (${BANK_KEYS.map((k) => bank[k].length).join("/")}) in ${Math.round(this.o.now() - t0)}ms`);
13566
13580
  const f = this.file(lang);
13567
13581
  if (f) await mkdir(this.o.cacheDir, { recursive: true }).then(() => writeFile(f, JSON.stringify({ at: this.o.now(), bank }))).catch((e) => log29.warn(`bank cache write ${f} failed: ${e.message}`));
13568
13582
  } catch (e) {
@@ -13678,7 +13692,7 @@ var SecondChannel = class {
13678
13692
  if (host) this.pinned = true;
13679
13693
  const lang = primaryLang(tag);
13680
13694
  if (!lang || lang === this.lang) return;
13681
- log30.info(`language ${this.lang} \u2192 ${lang}`);
13695
+ log30.debug(`language ${this.lang} \u2192 ${lang}`);
13682
13696
  this.lang = lang;
13683
13697
  this.recent = [];
13684
13698
  this.picks.clear();
@@ -17236,12 +17250,17 @@ function loadInstallEnv() {
17236
17250
  loadEnvFile(join16(homedir10(), ".agent", name));
17237
17251
  }
17238
17252
  }
17253
+ function paraVaultToken() {
17254
+ if (process.platform !== "darwin") return void 0;
17255
+ const r = Bun.spawnSync(["/usr/bin/security", "find-generic-password", "-s", "Para Settings", "-a", "VAULT_TOKEN", "-w"], { stdout: "pipe", stderr: "pipe" });
17256
+ return r.exitCode === 0 ? r.stdout.toString().trim() || void 0 : void 0;
17257
+ }
17239
17258
  async function loadBodifySecrets() {
17240
- const apiKey = process.env.BODIFY_API_KEY, appId = process.env.BODIFY_APP_ID;
17241
- if (!apiKey || !appId) return;
17259
+ const apiKey = process.env.BODIFY_API_KEY || paraVaultToken(), appId = process.env.BODIFY_APP_ID || "para-browser";
17260
+ if (!apiKey) return;
17242
17261
  const base = process.env.BODIFY_URL || "https://bodify.bod.ee";
17243
17262
  try {
17244
- const res = await fetch(`${base}/api/apps/${encodeURIComponent(appId)}/env`, {
17263
+ const res = await fetch(`${base}/api/apps/${encodeURIComponent(appId)}/env?environment=${encodeURIComponent(process.env.BODIFY_ENV || "prod")}`, {
17245
17264
  headers: { Authorization: `Bearer ${apiKey}` },
17246
17265
  signal: AbortSignal.timeout(5e3)
17247
17266
  });
@@ -19139,7 +19158,7 @@ ${task}`;
19139
19158
  `));
19140
19159
  const keys = ["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "GOOGLE_API_KEY", "GROQ_API_KEY"].filter((k) => process.env[k]);
19141
19160
  keys.length ? ok(`provider keys: ${keys.join(", ")}`) : bad("no provider keys set (ANTHROPIC_API_KEY / OPENAI_API_KEY / GOOGLE_API_KEY / GROQ_API_KEY)");
19142
- process.env.BODIFY_API_KEY && process.env.BODIFY_APP_ID ? ok(`bodify secrets: ${process.env.BODIFY_APP_ID}`) : warn("bodify secrets: not configured (set BODIFY_API_KEY + BODIFY_APP_ID)");
19161
+ process.env.BODIFY_API_KEY || paraVaultToken() ? ok(`bodify secrets: ${process.env.BODIFY_APP_ID || "para-browser"}`) : warn("bodify secrets: no vault token (connect the vault in Para Settings \u25B8 Keys, or set BODIFY_API_KEY)");
19143
19162
  {
19144
19163
  const has = hasCommand;
19145
19164
  if (!VoiceIO.available()) warn("voice: keys missing (SONIOX_API_KEY / CARTESIA_API_KEY / CARTESIA_VOICE_ID) \u2014 voice disabled");
@@ -20612,7 +20631,10 @@ function duplexError(e, reflexModel) {
20612
20631
  const code = e?.statusCode;
20613
20632
  return code && !msg.includes(String(code)) ? `${msg} (${code})` : msg;
20614
20633
  }
20615
- var leakDecider = () => process.env.TYPESAFE_AI_KEY ? new DecideClient({ apiKey: process.env.TYPESAFE_AI_KEY }) : void 0;
20634
+ var leakDecider = () => {
20635
+ const o = voiceDeciderOptions();
20636
+ return o ? new DecideClient(o) : void 0;
20637
+ };
20616
20638
  function makeSecondChannel(ai, reflexModel, opts) {
20617
20639
  const decider = leakDecider();
20618
20640
  const instinct = decider ? new Instinct({ decider }) : void 0;