@livx.cc/agentx 0.96.11 → 0.96.13

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
@@ -1909,6 +1909,7 @@ var init_tools_shell = __esm({
1909
1909
  import { createInterface } from "readline/promises";
1910
1910
  import { existsSync as existsSync9, readFileSync as readFileSync8, appendFileSync, mkdirSync as mkdirSync11, writeFileSync as writeFileSync9, readdirSync as readdirSync4, statSync as statSync4, unlinkSync as unlinkSync5 } from "fs";
1911
1911
  import { homedir as homedir9, tmpdir as tmpdir3 } from "os";
1912
+ import { spawnSync as spawnSync6 } from "child_process";
1912
1913
 
1913
1914
  // cli/clipboard.ts
1914
1915
  import { execFileSync } from "child_process";
@@ -7146,6 +7147,12 @@ function resolveAecBinary() {
7146
7147
  }
7147
7148
  return bin;
7148
7149
  }
7150
+ function aecUnavailableHint() {
7151
+ if (process.env.MIC_AEC === "0" || process.platform !== "darwin") return null;
7152
+ if (resolveAecBinary()) return null;
7153
+ if (spawnSync2("which", ["swiftc"]).status !== 0) return "install Xcode CLI tools (`xcode-select --install`) for echo cancellation";
7154
+ return null;
7155
+ }
7149
7156
  var NodeMicSource = class {
7150
7157
  aec;
7151
7158
  bin;
@@ -10087,6 +10094,10 @@ async function checkForUpdate(current) {
10087
10094
  if (cM > lM || cM === lM && cm > lm || cM === lM && cm === lm && cp >= lp) return null;
10088
10095
  return `Update available: ${current} \u2192 ${latest}. Run \`bun add -g @livx.cc/agentx\` to update.`;
10089
10096
  }
10097
+ function installUpdate() {
10098
+ const r = spawnSync6("bun", ["add", "-g", "@livx.cc/agentx"], { stdio: "inherit" });
10099
+ return (r.status ?? 1) === 0;
10100
+ }
10090
10101
  var spinner = /* @__PURE__ */ (() => {
10091
10102
  const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
10092
10103
  let timer;
@@ -10831,6 +10842,12 @@ function makeAskResolver(cwd) {
10831
10842
  }
10832
10843
  };
10833
10844
  }
10845
+ function hasBrowserMcp(cfg, extraTools) {
10846
+ const isBrowser = (s) => /browser/i.test(s);
10847
+ if (Object.entries(cfg.mcpServers ?? {}).some(([n, c]) => isBrowser(n) && !c?.disabled)) return true;
10848
+ return extraTools.some((t) => t.name.startsWith("mcp__") && isBrowser(t.name.slice(5).split("__")[0]));
10849
+ }
10850
+ var BROWSER_MAX_CONTEXT_TOKENS = 12e4;
10834
10851
  function optsFor(args, ai, cfg = {}, extraTools = []) {
10835
10852
  const perm = resolvePermMode(args, canPrompt);
10836
10853
  if (perm.notice) err(dim(` \u26A0 ${perm.notice}
@@ -10869,7 +10886,9 @@ function optsFor(args, ai, cfg = {}, extraTools = []) {
10869
10886
  maxRepeats: cfg.maxRepeats,
10870
10887
  maxToolCalls: cfg.maxToolCalls,
10871
10888
  keepToolOutputs: cfg.keepToolOutputs,
10872
- maxContextTokens: cfg.maxContextTokens,
10889
+ // Token-aware backstop: explicit config wins; else auto-enable for browser MCP runs (huge DOM/screenshot
10890
+ // results otherwise accumulate past the maxTokens budget kill-switch mid-browse). Off for normal sessions.
10891
+ maxContextTokens: cfg.maxContextTokens ?? (hasBrowserMcp(cfg, extraTools) ? BROWSER_MAX_CONTEXT_TOKENS : void 0),
10873
10892
  learnFromMistakes: cfg.learnFromMistakes,
10874
10893
  // Forwarded to cursor/* delegations for environment parity (chat-model providers ignore it).
10875
10894
  // Raw config (pre-OAuth): unresolved-oauth http servers are skipped by the cursor mapper.
@@ -10890,7 +10909,11 @@ async function makeAgent(args, ai, cfg, extraTools = []) {
10890
10909
  else if (args.shell === false) err(dim(" \u2296 --no-shell: VFS bash only (no real /bin/sh)\n"));
10891
10910
  if (args.harden && !virtual) err(dim(` \u26E8 hardened shell: writes confined to cwd+tmp${args.hardenNet ? "" : ", network blocked"} (sandbox-exec/bwrap)
10892
10911
  `));
10893
- const agent = await buildAgent(optsFor(args, ai, cfg, extraTools));
10912
+ const opts = optsFor(args, ai, cfg, extraTools);
10913
+ if (opts.maxContextTokens === BROWSER_MAX_CONTEXT_TOKENS && cfg.maxContextTokens == null)
10914
+ err(dim(` \u229E browser MCP detected \u2014 auto-capping sent context at ~${BROWSER_MAX_CONTEXT_TOKENS / 1e3}k tok (set maxContextTokens in config to override)
10915
+ `));
10916
+ const agent = await buildAgent(opts);
10894
10917
  const display = displayHooks(agent.options.fs, { flush: agent.options.host?.flushText });
10895
10918
  agent.options.hooks = cfg.hooks ? composeHooks(display, hooksFromConfig(cfg.hooks)) : display;
10896
10919
  return agent;
@@ -11972,8 +11995,8 @@ ${task}`;
11972
11995
  const wasRaw = process.stdin.isTTY && process.stdin.isRaw;
11973
11996
  if (wasRaw) process.stdin.setRawMode(false);
11974
11997
  try {
11975
- const { spawnSync: spawnSync6 } = await import("child_process");
11976
- const r = spawnSync6("less", ["-R"], { input: text, stdio: ["pipe", "inherit", "inherit"] });
11998
+ const { spawnSync: spawnSync7 } = await import("child_process");
11999
+ const r = spawnSync7("less", ["-R"], { input: text, stdio: ["pipe", "inherit", "inherit"] });
11977
12000
  if (r.error) err(text);
11978
12001
  } finally {
11979
12002
  if (wasRaw) process.stdin.setRawMode(true);
@@ -12369,8 +12392,8 @@ ${task}`;
12369
12392
  const wasRaw = process.stdin.isTTY && process.stdin.isRaw;
12370
12393
  if (wasRaw) process.stdin.setRawMode(false);
12371
12394
  try {
12372
- const { spawnSync: spawnSync6 } = await import("child_process");
12373
- spawnSync6(ed, [idx], { stdio: "inherit" });
12395
+ const { spawnSync: spawnSync7 } = await import("child_process");
12396
+ spawnSync7(ed, [idx], { stdio: "inherit" });
12374
12397
  } finally {
12375
12398
  if (wasRaw) process.stdin.setRawMode(true);
12376
12399
  }
@@ -12799,11 +12822,14 @@ ${task}`;
12799
12822
  run: async () => {
12800
12823
  err(dim(" checking\u2026\n"));
12801
12824
  const msg = await checkForUpdate(VERSION).catch(() => null);
12802
- if (msg) {
12803
- err(yellow(` ${msg}
12825
+ if (!msg) {
12826
+ err(green(" \u2713 up to date\n"));
12827
+ return;
12828
+ }
12829
+ err(yellow(` ${msg.replace(/Run .+$/, "Installing\u2026")}
12804
12830
  `));
12805
- err(dim(" run the command above to update, then restart.\n"));
12806
- } else err(green(" \u2713 up to date\n"));
12831
+ if (installUpdate()) err(green(" \u2713 updated \u2014 restart agentx to use the new version\n"));
12832
+ else err(red(" \u2717 update failed \u2014 run `bun add -g @livx.cc/agentx` manually\n"));
12807
12833
  }
12808
12834
  },
12809
12835
  exit: { desc: "quit", run: () => true },
@@ -13048,6 +13074,11 @@ ${out}
13048
13074
  const inNote = inDev ? `, in: ${inDev.name}` : "";
13049
13075
  err(dim(` \u{1F3A4} voice on (${voiceIO.usingAec ? "echo-cancelled" : "heuristic echo \u2014 headphones recommended"}${inNote}) \u2014 just talk; speak over it to interrupt; say "voice off" to stop
13050
13076
  `));
13077
+ if (!voiceIO.usingAec) {
13078
+ const hint = aecUnavailableHint();
13079
+ if (hint) err(yellow(` \u26A0 no echo cancellation \u2014 ${hint}
13080
+ `));
13081
+ }
13051
13082
  if (inDev?.virtual) err(yellow(` \u26A0 default input "${inDev.name}" looks like a virtual device \u2014 if it can't hear you, switch your Mac input to a real mic
13052
13083
  `));
13053
13084
  if (greet) {
@@ -13302,9 +13333,7 @@ async function main() {
13302
13333
  return;
13303
13334
  }
13304
13335
  console.log(msg.replace(/Run .+$/, "Installing\u2026"));
13305
- const { spawnSync: spawnSync6 } = await import("child_process");
13306
- const r = spawnSync6("bun", ["add", "-g", "@livx.cc/agentx"], { stdio: "inherit" });
13307
- process.exit(r.status ?? 1);
13336
+ process.exit(installUpdate() ? 0 : 1);
13308
13337
  }
13309
13338
  if (args.debug) process.env.DEBUG ||= "*";
13310
13339
  if (args.print && !args.task && !process.stdin.isTTY) args.task = (await readAllStdin()).trim();