@livx.cc/agentx 0.99.87 → 0.99.91

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();
@@ -16907,6 +16921,7 @@ var VERSION = (() => {
16907
16921
  })();
16908
16922
  async function checkForUpdate(current) {
16909
16923
  if (current === "?") return null;
16924
+ if (existsSync9(new URL("../.git", import.meta.url))) return null;
16910
16925
  const res = await fetch("https://registry.npmjs.org/@livx.cc/agentx/latest", {
16911
16926
  signal: AbortSignal.timeout(3e3)
16912
16927
  });
@@ -17215,6 +17230,7 @@ function resolveModelOrNewest(model) {
17215
17230
  return fallback;
17216
17231
  }
17217
17232
  var ENV_KEY_ALIASES = { google: ["GEMINI_API_KEY"] };
17233
+ var fileEnvNames = /* @__PURE__ */ new Set();
17218
17234
  function loadEnvFile(file) {
17219
17235
  if (!existsSync9(file)) return;
17220
17236
  for (const line of readFileSync10(file, "utf8").split("\n")) {
@@ -17224,6 +17240,7 @@ function loadEnvFile(file) {
17224
17240
  if (val.startsWith('"') && val.endsWith('"') || val.startsWith("'") && val.endsWith("'")) val = val.slice(1, -1);
17225
17241
  else val = val.replace(/\s+#.*$/, "").trim();
17226
17242
  process.env[m[1]] = val;
17243
+ fileEnvNames.add(m[1]);
17227
17244
  }
17228
17245
  }
17229
17246
  function loadInstallEnv() {
@@ -17234,12 +17251,17 @@ function loadInstallEnv() {
17234
17251
  loadEnvFile(join16(homedir10(), ".agent", name));
17235
17252
  }
17236
17253
  }
17254
+ function paraVaultToken() {
17255
+ if (process.platform !== "darwin") return void 0;
17256
+ const r = Bun.spawnSync(["/usr/bin/security", "find-generic-password", "-s", "Para Settings", "-a", "VAULT_TOKEN", "-w"], { stdout: "pipe", stderr: "pipe" });
17257
+ return r.exitCode === 0 ? r.stdout.toString().trim() || void 0 : void 0;
17258
+ }
17237
17259
  async function loadBodifySecrets() {
17238
- const apiKey = process.env.BODIFY_API_KEY, appId = process.env.BODIFY_APP_ID;
17239
- if (!apiKey || !appId) return;
17260
+ const apiKey = process.env.BODIFY_API_KEY || paraVaultToken(), appId = process.env.BODIFY_APP_ID || "para-browser";
17261
+ if (!apiKey) return;
17240
17262
  const base = process.env.BODIFY_URL || "https://bodify.bod.ee";
17241
17263
  try {
17242
- const res = await fetch(`${base}/api/apps/${encodeURIComponent(appId)}/env`, {
17264
+ const res = await fetch(`${base}/api/apps/${encodeURIComponent(appId)}/env?environment=${encodeURIComponent(process.env.BODIFY_ENV || "prod")}`, {
17243
17265
  headers: { Authorization: `Bearer ${apiKey}` },
17244
17266
  signal: AbortSignal.timeout(5e3)
17245
17267
  });
@@ -17250,7 +17272,7 @@ async function loadBodifySecrets() {
17250
17272
  const { values } = await res.json();
17251
17273
  if (!values) return;
17252
17274
  for (const [k, v] of Object.entries(values)) {
17253
- if (!(k in process.env)) process.env[k] = v;
17275
+ if (!(k in process.env) || fileEnvNames.has(k)) process.env[k] = v;
17254
17276
  }
17255
17277
  } catch (e) {
17256
17278
  console.error(` bodify secrets: ${e.message ?? e}`);
@@ -19137,7 +19159,7 @@ ${task}`;
19137
19159
  `));
19138
19160
  const keys = ["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "GOOGLE_API_KEY", "GROQ_API_KEY"].filter((k) => process.env[k]);
19139
19161
  keys.length ? ok(`provider keys: ${keys.join(", ")}`) : bad("no provider keys set (ANTHROPIC_API_KEY / OPENAI_API_KEY / GOOGLE_API_KEY / GROQ_API_KEY)");
19140
- 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)");
19162
+ 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)");
19141
19163
  {
19142
19164
  const has = hasCommand;
19143
19165
  if (!VoiceIO.available()) warn("voice: keys missing (SONIOX_API_KEY / CARTESIA_API_KEY / CARTESIA_VOICE_ID) \u2014 voice disabled");
@@ -20610,7 +20632,10 @@ function duplexError(e, reflexModel) {
20610
20632
  const code = e?.statusCode;
20611
20633
  return code && !msg.includes(String(code)) ? `${msg} (${code})` : msg;
20612
20634
  }
20613
- var leakDecider = () => process.env.TYPESAFE_AI_KEY ? new DecideClient({ apiKey: process.env.TYPESAFE_AI_KEY }) : void 0;
20635
+ var leakDecider = () => {
20636
+ const o = voiceDeciderOptions();
20637
+ return o ? new DecideClient(o) : void 0;
20638
+ };
20614
20639
  function makeSecondChannel(ai, reflexModel, opts) {
20615
20640
  const decider = leakDecider();
20616
20641
  const instinct = decider ? new Instinct({ decider }) : void 0;