@livx.cc/agentx 0.95.3 → 0.95.4

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
@@ -1907,7 +1907,7 @@ var init_tools_shell = __esm({
1907
1907
 
1908
1908
  // cli/cli.ts
1909
1909
  import { createInterface } from "readline/promises";
1910
- import { existsSync as existsSync10, readFileSync as readFileSync7, appendFileSync, mkdirSync as mkdirSync11, writeFileSync as writeFileSync9, readdirSync as readdirSync4, statSync as statSync4, unlinkSync as unlinkSync5 } from "fs";
1910
+ import { existsSync as existsSync10, 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
1912
 
1913
1913
  // cli/clipboard.ts
@@ -6906,7 +6906,7 @@ var trunc = (s, n) => (s == null ? "" : String(s).length > n ? String(s).slice(0
6906
6906
  // cli/voice.ts
6907
6907
  init_logging();
6908
6908
  import { spawn as spawn2, spawnSync as spawnSync2 } from "child_process";
6909
- import { existsSync as existsSync4, mkdirSync as mkdirSync5, statSync as statSync3 } from "fs";
6909
+ import { existsSync as existsSync4, mkdirSync as mkdirSync5, readFileSync as readFileSync4, statSync as statSync3 } from "fs";
6910
6910
  import { homedir as homedir3 } from "os";
6911
6911
  import { dirname as dirname3, join as join6 } from "path";
6912
6912
  import { fileURLToPath } from "url";
@@ -7187,10 +7187,63 @@ var VoiceIO = class extends VoiceEngine {
7187
7187
  return !!(env.SONIOX_API_KEY && env.CARTESIA_API_KEY && env.CARTESIA_VOICE_ID);
7188
7188
  }
7189
7189
  };
7190
+ function fakeVoiceParts(uttFile) {
7191
+ let timer = null;
7192
+ let offset = 0;
7193
+ const stt = {
7194
+ usingAec: true,
7195
+ onPartial: (_) => {
7196
+ },
7197
+ onUtterance: (_, __) => {
7198
+ },
7199
+ onLevel: (_) => {
7200
+ },
7201
+ start() {
7202
+ timer = setInterval(() => {
7203
+ let buf;
7204
+ try {
7205
+ buf = readFileSync4(uttFile, "utf8");
7206
+ } catch {
7207
+ return;
7208
+ }
7209
+ if (buf.length <= offset) return;
7210
+ const fresh = buf.slice(offset);
7211
+ offset = buf.length;
7212
+ for (const line of fresh.split("\n")) {
7213
+ const t = line.trim();
7214
+ if (t) stt.onUtterance(t, Date.now());
7215
+ }
7216
+ }, 100);
7217
+ },
7218
+ reset() {
7219
+ },
7220
+ stop() {
7221
+ if (timer) {
7222
+ clearInterval(timer);
7223
+ timer = null;
7224
+ }
7225
+ }
7226
+ };
7227
+ const tts = { connect() {
7228
+ }, newContext() {
7229
+ }, speak() {
7230
+ }, end() {
7231
+ tts.onDone?.();
7232
+ }, cancel() {
7233
+ }, close() {
7234
+ }, onAudio: (_) => {
7235
+ }, onDone: () => {
7236
+ } };
7237
+ const player = { markTurn() {
7238
+ }, write() {
7239
+ }, drainMs: () => 0, playedMs: () => 0, kill() {
7240
+ } };
7241
+ return { stt, tts, player };
7242
+ }
7190
7243
 
7191
7244
  // cli/config.ts
7192
7245
  import { homedir as homedir4 } from "os";
7193
- import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
7246
+ import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
7194
7247
  import { join as join7 } from "path";
7195
7248
  import { pathToFileURL } from "url";
7196
7249
  var FILES = ["config.ts", "config.js", "config.mjs", "config.json"];
@@ -7212,7 +7265,7 @@ function loadSettings(dir) {
7212
7265
  const p = join7(dir, ".agent", "settings.json");
7213
7266
  if (!existsSync5(p)) return {};
7214
7267
  try {
7215
- const raw = JSON.parse(readFileSync4(p, "utf8"));
7268
+ const raw = JSON.parse(readFileSync5(p, "utf8"));
7216
7269
  const cfg = {};
7217
7270
  if (raw.mcpServers && typeof raw.mcpServers === "object") cfg.mcpServers = raw.mcpServers;
7218
7271
  if (raw.permissions && typeof raw.permissions === "object") cfg.permissions = raw.permissions;
@@ -7367,7 +7420,7 @@ function formatDiff(ops, opts = {}) {
7367
7420
  }
7368
7421
 
7369
7422
  // cli/session.ts
7370
- import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync4, readdirSync, renameSync, symlinkSync as symlinkSync2, unlinkSync, readlinkSync } from "fs";
7423
+ import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync4, readdirSync, renameSync, symlinkSync as symlinkSync2, unlinkSync, readlinkSync } from "fs";
7371
7424
  import { homedir as homedir5 } from "os";
7372
7425
  import { join as join8 } from "path";
7373
7426
  var log18 = forComponent("session");
@@ -7421,7 +7474,7 @@ var SessionStore = class {
7421
7474
  const path = join8(this.dir, `${id}.json`);
7422
7475
  if (!existsSync6(path)) return void 0;
7423
7476
  try {
7424
- return JSON.parse(readFileSync5(path, "utf8"));
7477
+ return JSON.parse(readFileSync6(path, "utf8"));
7425
7478
  } catch (e) {
7426
7479
  log18.debug(`unreadable session ${id} \u2014 ignoring`, e);
7427
7480
  return void 0;
@@ -7434,7 +7487,7 @@ var SessionStore = class {
7434
7487
  for (const f of readdirSync(this.dir)) {
7435
7488
  if (!f.endsWith(".json")) continue;
7436
7489
  try {
7437
- metas.push(JSON.parse(readFileSync5(join8(this.dir, f), "utf8")).meta);
7490
+ metas.push(JSON.parse(readFileSync6(join8(this.dir, f), "utf8")).meta);
7438
7491
  } catch (e) {
7439
7492
  log18.debug(`skipping unreadable session file ${f}`, e);
7440
7493
  }
@@ -7457,7 +7510,7 @@ function globalSessionLoad(idOrPrefix) {
7457
7510
  if (existsSync6(exact)) {
7458
7511
  try {
7459
7512
  const target = readlinkSync(exact);
7460
- return JSON.parse(readFileSync5(target, "utf8"));
7513
+ return JSON.parse(readFileSync6(target, "utf8"));
7461
7514
  } catch {
7462
7515
  return void 0;
7463
7516
  }
@@ -7468,7 +7521,7 @@ function globalSessionLoad(idOrPrefix) {
7468
7521
  const base = f.slice(0, -5);
7469
7522
  if (base.includes(idOrPrefix) || base.endsWith(idOrPrefix)) {
7470
7523
  const target = readlinkSync(join8(gd, f));
7471
- return JSON.parse(readFileSync5(target, "utf8"));
7524
+ return JSON.parse(readFileSync6(target, "utf8"));
7472
7525
  }
7473
7526
  }
7474
7527
  } catch {
@@ -7490,7 +7543,7 @@ function globalSessionList() {
7490
7543
  }
7491
7544
  continue;
7492
7545
  }
7493
- metas.push(JSON.parse(readFileSync5(target, "utf8")).meta);
7546
+ metas.push(JSON.parse(readFileSync6(target, "utf8")).meta);
7494
7547
  } catch {
7495
7548
  }
7496
7549
  }
@@ -8017,7 +8070,7 @@ function completePath(listDir, ref) {
8017
8070
  // cli/lineEditor.ts
8018
8071
  import { emitKeypressEvents } from "readline";
8019
8072
  import { spawnSync as spawnSync4 } from "child_process";
8020
- import { writeFileSync as writeFileSync7, readFileSync as readFileSync6, unlinkSync as unlinkSync2 } from "fs";
8073
+ import { writeFileSync as writeFileSync7, readFileSync as readFileSync7, unlinkSync as unlinkSync2 } from "fs";
8021
8074
  import { tmpdir as tmpdir2 } from "os";
8022
8075
  import { join as join11 } from "path";
8023
8076
 
@@ -9103,7 +9156,7 @@ function createLineEditor(out) {
9103
9156
  out.write("\x1B[?2004l");
9104
9157
  const r = spawnSync4(cmd, [...cargs, file], { stdio: "inherit" });
9105
9158
  if (r.status === 0) {
9106
- const text = readFileSync6(file, "utf8").replace(/\n$/, "");
9159
+ const text = readFileSync7(file, "utf8").replace(/\n$/, "");
9107
9160
  s.reset();
9108
9161
  if (text) s.insert(text);
9109
9162
  }
@@ -9876,7 +9929,7 @@ var err = (s) => process.stderr.write(s);
9876
9929
  var log22 = forComponent("cli");
9877
9930
  var VERSION = (() => {
9878
9931
  try {
9879
- return JSON.parse(readFileSync7(new URL("../package.json", import.meta.url), "utf8")).version ?? "?";
9932
+ return JSON.parse(readFileSync8(new URL("../package.json", import.meta.url), "utf8")).version ?? "?";
9880
9933
  } catch {
9881
9934
  return "?";
9882
9935
  }
@@ -10105,7 +10158,7 @@ function loadInstallEnv() {
10105
10158
  for (const name of [".env", ".env.local"]) {
10106
10159
  const file = join14(dir, name);
10107
10160
  if (!existsSync10(file)) continue;
10108
- for (const line of readFileSync7(file, "utf8").split("\n")) {
10161
+ for (const line of readFileSync8(file, "utf8").split("\n")) {
10109
10162
  const m = line.match(/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);
10110
10163
  if (!m || m[1] in process.env) continue;
10111
10164
  let val = m[2].trim();
@@ -10706,7 +10759,7 @@ function readImageParts(cwd, line) {
10706
10759
  if (!mime) continue;
10707
10760
  const abs = ref.startsWith("~/") ? untilde(ref) : resolve3(cwd, ref);
10708
10761
  try {
10709
- parts.push(imagePart(`data:${mime};base64,${readFileSync7(abs).toString("base64")}`));
10762
+ parts.push(imagePart(`data:${mime};base64,${readFileSync8(abs).toString("base64")}`));
10710
10763
  } catch {
10711
10764
  }
10712
10765
  }
@@ -10951,7 +11004,7 @@ function initInstructions(cwd) {
10951
11004
  function persistSetting(cwd, key, value) {
10952
11005
  const path = join14(cwd, ".agent", "settings.json");
10953
11006
  try {
10954
- const obj = existsSync10(path) ? JSON.parse(readFileSync7(path, "utf8")) : {};
11007
+ const obj = existsSync10(path) ? JSON.parse(readFileSync8(path, "utf8")) : {};
10955
11008
  if (obj[key] === value) return;
10956
11009
  obj[key] = value;
10957
11010
  mkdirSync11(dirname4(path), { recursive: true });
@@ -11108,6 +11161,7 @@ async function repl(args, ai, cfg, cwd) {
11108
11161
  notify(e) {
11109
11162
  if (voiceIO && (e.kind === "thinking_delta" || e.kind === "turn_start")) return;
11110
11163
  if (e.kind === "text_delta" && voiceIO) {
11164
+ spinner.stop();
11111
11165
  voiceIO.speakDelta(e.message);
11112
11166
  editorRef?.suspend();
11113
11167
  voiceEcho(e.message);
@@ -11195,7 +11249,7 @@ async function repl(args, ai, cfg, cwd) {
11195
11249
  quickLook: {
11196
11250
  branch: () => {
11197
11251
  try {
11198
- const head = readFileSync7(join14(cwd, ".git", "HEAD"), "utf8").trim();
11252
+ const head = readFileSync8(join14(cwd, ".git", "HEAD"), "utf8").trim();
11199
11253
  return head.startsWith("ref: refs/heads/") ? `branch: ${head.slice("ref: refs/heads/".length)}` : `detached HEAD at ${head.slice(0, 12)}`;
11200
11254
  } catch {
11201
11255
  return "not a git repository";
@@ -11430,7 +11484,7 @@ Added entries are loadable now via the Skill/SlashCommand tools; removed ones ar
11430
11484
  </system-reminder>`;
11431
11485
  };
11432
11486
  const histPath = join14(cwd, ".agent", "history");
11433
- const history = existsSync10(histPath) ? readFileSync7(histPath, "utf8").split("\n").filter(Boolean).reverse().slice(0, 500) : [];
11487
+ const history = existsSync10(histPath) ? readFileSync8(histPath, "utf8").split("\n").filter(Boolean).reverse().slice(0, 500) : [];
11434
11488
  const remember = (line) => {
11435
11489
  try {
11436
11490
  mkdirSync11(join14(cwd, ".agent"), { recursive: true });
@@ -12723,11 +12777,13 @@ ${out}
12723
12777
  err(dim(" (voice needs --duplex on a TTY)\n"));
12724
12778
  return false;
12725
12779
  }
12726
- if (!VoiceIO.available()) {
12780
+ if (!process.env.AGENTX_VOICE_FAKE && !VoiceIO.available()) {
12727
12781
  err(dim(" (voice I/O off \u2014 set SONIOX_API_KEY, CARTESIA_API_KEY, CARTESIA_VOICE_ID to talk)\n"));
12728
12782
  return false;
12729
12783
  }
12784
+ const fakeVoice = process.env.AGENTX_VOICE_FAKE ? fakeVoiceParts(process.env.AGENTX_VOICE_FAKE) : null;
12730
12785
  voiceIO = new VoiceIO({
12786
+ ...fakeVoice ?? {},
12731
12787
  // No ack phrase by default: a fixed "Mm-hm," every turn reads robotic, Haiku's TTFT doesn't
12732
12788
  // need masking (~0.7-1.2s full turns), and the conversational register already opens with a
12733
12789
  // natural reaction. The mechanism (+ echo-leak guard) stays for slower voice models.