@livx.cc/agentx 0.99.113 → 0.99.115

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 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-CJMY5EbL.js';
2
+ import { o as RouterState, H as Hooks, p as RunResult, R as ReasoningEffort, C as ChannelMode, A as Agent } from './secondChannel-BCEr_QyM.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
 
@@ -140,6 +140,8 @@ interface Args {
140
140
  help: boolean;
141
141
  version: boolean;
142
142
  keepAlive?: boolean;
143
+ lean?: boolean;
144
+ voiceGender?: 'female' | 'male';
143
145
  duplex: boolean;
144
146
  duplexV2?: boolean;
145
147
  call?: boolean;
package/dist/cli.js CHANGED
@@ -10136,6 +10136,9 @@ var KIND_HINT = {
10136
10136
  bridge: `neutral one-moment cues while the answer is prepared (like "let me see\u2026", "one sec\u2026") \u2014 never the start of a statement or opinion ("the thing is", "well actually", "here's the deal")`,
10137
10137
  phatic: 'greetings, thanks and yes/no openers a person starts a turn with (like "hi", "thanks", "how are you")'
10138
10138
  };
10139
+ function personaHint(gender) {
10140
+ return gender === "female" ? 'You are a woman: when you refer to yourself, use feminine grammatical forms (e.g. Hebrew "\u05D1\u05D5\u05D3\u05E7\u05EA", not "\u05D1\u05D5\u05D3\u05E7").' : gender === "male" ? 'You are a man: when you refer to yourself, use masculine grammatical forms (e.g. Hebrew "\u05D1\u05D5\u05D3\u05E7", not "\u05D1\u05D5\u05D3\u05E7\u05EA").' : 'Your gender is unknown: never refer to yourself in a gendered form (in Hebrew use plural "\u05D1\u05D5\u05D3\u05E7\u05D9\u05DD" or no verb at all, never "\u05D1\u05D5\u05D3\u05E7"/"\u05D1\u05D5\u05D3\u05E7\u05EA").';
10141
+ }
10139
10142
  function fastBankGenerator(ai, model, perKind = 12) {
10140
10143
  return async (lang, avoid, signal) => {
10141
10144
  const name = languageName(lang);
@@ -12834,14 +12837,19 @@ init_logging();
12834
12837
  var log25 = forComponent("Progress");
12835
12838
  var HE_RESULT_CLAIM = /(?:^|\s)(?:מצאתי|סיימתי|בוצע|הנה|אין)(?=\s|$|[.,!…])/u;
12836
12839
  var TOPICS = [
12840
+ [/toolsearch|^mcp__.*__(list_commands|call_info)$/, null],
12841
+ // tool plumbing — no line (and no generated one)
12837
12842
  [/kanban|board|card|\bkb\b|list_cards/, "board"],
12838
12843
  [/mail|gmail|inbox/, "mail"],
12839
12844
  [/calendar|event|schedule/, "calendar"],
12840
12845
  [/memory|recall|remember/, "memory"],
12841
- [/web_?search|websearch|fetch|browse|url|page|tab|browser/, "web"],
12846
+ [/web_?search|search_web|google/, "websearch"],
12847
+ [/fetch|read_page|get_page|page_text|navigate|url|history/, "page"],
12848
+ [/click|type|press_key|scroll|screenshot|tab|browser|highlight|point|wait_for|upload/, "browser"],
12842
12849
  [/grep|glob|search|find|lookup|quicklook/, "search"],
12850
+ [/^(agent|task)$|subagent|delegate/, "delegate"],
12843
12851
  [/edit|write|patch|create|update|save|delete|move/, "write"],
12844
- [/shell|bash|exec|run|command|terminal/, "run"],
12852
+ [/shell|bash|exec|run|command|terminal|eval/, "run"],
12845
12853
  [/read|open|view|cat|look|get|list|ls/, "read"]
12846
12854
  ];
12847
12855
  var PROGRESS_TEMPLATES = {
@@ -12850,27 +12858,62 @@ var PROGRESS_TEMPLATES = {
12850
12858
  mail: ["checking the mail\u2026", "going through the inbox\u2026"],
12851
12859
  calendar: ["checking the calendar\u2026", "looking at the schedule\u2026"],
12852
12860
  memory: ["checking my notes\u2026", "looking back\u2026"],
12853
- web: ["reading the page\u2026", "looking it up online\u2026"],
12861
+ websearch: ["searching\u2026", "searching the web\u2026"],
12862
+ page: ["reading the page\u2026", "going through the page\u2026"],
12863
+ browser: ["working in the browser\u2026", "on the page now\u2026"],
12854
12864
  search: ["searching\u2026", "still looking\u2026"],
12865
+ delegate: ["working on it\u2026", "still on it\u2026"],
12855
12866
  write: ["making the change\u2026", "writing it down\u2026"],
12856
12867
  run: ["running it\u2026", "still running\u2026"],
12857
12868
  read: ["reading it\u2026", "going through it\u2026"]
12858
12869
  },
12859
12870
  he: {
12860
- // plural present: gender-neutral for a voice of either gender
12861
12871
  board: ["\u05D1\u05D5\u05D3\u05E7\u05D9\u05DD \u05D1\u05DC\u05D5\u05D7\u2026", "\u05DE\u05E1\u05EA\u05DB\u05DC\u05D9\u05DD \u05E2\u05DC \u05D4\u05DB\u05E8\u05D8\u05D9\u05E1\u05D9\u05DD\u2026"],
12862
12872
  mail: ["\u05D1\u05D5\u05D3\u05E7\u05D9\u05DD \u05D0\u05EA \u05D4\u05DE\u05D9\u05D9\u05DC\u2026", "\u05E2\u05D5\u05D1\u05E8\u05D9\u05DD \u05E2\u05DC \u05D4\u05D3\u05D5\u05D0\u05E8\u2026"],
12863
12873
  calendar: ["\u05D1\u05D5\u05D3\u05E7\u05D9\u05DD \u05D1\u05D9\u05D5\u05DE\u05DF\u2026", "\u05DE\u05E1\u05EA\u05DB\u05DC\u05D9\u05DD \u05D1\u05DC\u05D5\u05F4\u05D6\u2026"],
12864
12874
  memory: ["\u05D1\u05D5\u05D3\u05E7\u05D9\u05DD \u05D1\u05E8\u05E9\u05D9\u05DE\u05D5\u05EA\u2026", "\u05DE\u05D7\u05E4\u05E9\u05D9\u05DD \u05D1\u05D6\u05D9\u05DB\u05E8\u05D5\u05DF\u2026"],
12865
- web: ["\u05E7\u05D5\u05E8\u05D0\u05D9\u05DD \u05D0\u05EA \u05D4\u05D3\u05E3\u2026", "\u05DE\u05D7\u05E4\u05E9\u05D9\u05DD \u05D1\u05E8\u05E9\u05EA\u2026"],
12875
+ websearch: ["\u05DE\u05D7\u05E4\u05E9\u05D9\u05DD\u2026", "\u05DE\u05D7\u05E4\u05E9\u05D9\u05DD \u05D1\u05E8\u05E9\u05EA\u2026"],
12876
+ page: ["\u05E7\u05D5\u05E8\u05D0\u05D9\u05DD \u05D0\u05EA \u05D4\u05D3\u05E3\u2026", "\u05E2\u05D5\u05D1\u05E8\u05D9\u05DD \u05E2\u05DC \u05D4\u05D3\u05E3\u2026"],
12877
+ browser: ["\u05E2\u05D5\u05D1\u05D3\u05D9\u05DD \u05D1\u05D3\u05E4\u05D3\u05E4\u05DF\u2026", "\u05E2\u05DC \u05D4\u05D3\u05E3 \u05E2\u05DB\u05E9\u05D9\u05D5\u2026"],
12866
12878
  search: ["\u05DE\u05D7\u05E4\u05E9\u05D9\u05DD\u2026", "\u05E2\u05D3\u05D9\u05D9\u05DF \u05DE\u05D7\u05E4\u05E9\u05D9\u05DD\u2026"],
12879
+ delegate: ["\u05E2\u05D5\u05D1\u05D3\u05D9\u05DD \u05E2\u05DC \u05D6\u05D4\u2026", "\u05E2\u05D3\u05D9\u05D9\u05DF \u05E2\u05DC \u05D6\u05D4\u2026"],
12867
12880
  write: ["\u05DE\u05D1\u05E6\u05E2\u05D9\u05DD \u05D0\u05EA \u05D4\u05E9\u05D9\u05E0\u05D5\u05D9\u2026", "\u05DB\u05D5\u05EA\u05D1\u05D9\u05DD \u05D0\u05EA \u05D6\u05D4\u2026"],
12868
12881
  run: ["\u05DE\u05E8\u05D9\u05E6\u05D9\u05DD\u2026", "\u05E2\u05D3\u05D9\u05D9\u05DF \u05E8\u05E5\u2026"],
12869
12882
  read: ["\u05E7\u05D5\u05E8\u05D0\u05D9\u05DD\u2026", "\u05E2\u05D5\u05D1\u05E8\u05D9\u05DD \u05E2\u05DC \u05D6\u05D4\u2026"]
12883
+ },
12884
+ "he-f": {
12885
+ board: ["\u05D1\u05D5\u05D3\u05E7\u05EA \u05D1\u05DC\u05D5\u05D7\u2026", "\u05DE\u05E1\u05EA\u05DB\u05DC\u05EA \u05E2\u05DC \u05D4\u05DB\u05E8\u05D8\u05D9\u05E1\u05D9\u05DD\u2026"],
12886
+ mail: ["\u05D1\u05D5\u05D3\u05E7\u05EA \u05D0\u05EA \u05D4\u05DE\u05D9\u05D9\u05DC\u2026", "\u05E2\u05D5\u05D1\u05E8\u05EA \u05E2\u05DC \u05D4\u05D3\u05D5\u05D0\u05E8\u2026"],
12887
+ calendar: ["\u05D1\u05D5\u05D3\u05E7\u05EA \u05D1\u05D9\u05D5\u05DE\u05DF\u2026", "\u05DE\u05E1\u05EA\u05DB\u05DC\u05EA \u05D1\u05DC\u05D5\u05F4\u05D6\u2026"],
12888
+ memory: ["\u05D1\u05D5\u05D3\u05E7\u05EA \u05D1\u05E8\u05E9\u05D9\u05DE\u05D5\u05EA\u2026", "\u05DE\u05D7\u05E4\u05E9\u05EA \u05D1\u05D6\u05D9\u05DB\u05E8\u05D5\u05DF\u2026"],
12889
+ websearch: ["\u05DE\u05D7\u05E4\u05E9\u05EA\u2026", "\u05DE\u05D7\u05E4\u05E9\u05EA \u05D1\u05E8\u05E9\u05EA\u2026"],
12890
+ page: ["\u05E7\u05D5\u05E8\u05D0\u05EA \u05D0\u05EA \u05D4\u05D3\u05E3\u2026", "\u05E2\u05D5\u05D1\u05E8\u05EA \u05E2\u05DC \u05D4\u05D3\u05E3\u2026"],
12891
+ browser: ["\u05E2\u05D5\u05D1\u05D3\u05EA \u05D1\u05D3\u05E4\u05D3\u05E4\u05DF\u2026", "\u05E2\u05DC \u05D4\u05D3\u05E3 \u05E2\u05DB\u05E9\u05D9\u05D5\u2026"],
12892
+ search: ["\u05DE\u05D7\u05E4\u05E9\u05EA\u2026", "\u05E2\u05D3\u05D9\u05D9\u05DF \u05DE\u05D7\u05E4\u05E9\u05EA\u2026"],
12893
+ delegate: ["\u05E2\u05D5\u05D1\u05D3\u05EA \u05E2\u05DC \u05D6\u05D4\u2026", "\u05E2\u05D3\u05D9\u05D9\u05DF \u05E2\u05DC \u05D6\u05D4\u2026"],
12894
+ write: ["\u05DE\u05D1\u05E6\u05E2\u05EA \u05D0\u05EA \u05D4\u05E9\u05D9\u05E0\u05D5\u05D9\u2026", "\u05DB\u05D5\u05EA\u05D1\u05EA \u05D0\u05EA \u05D6\u05D4\u2026"],
12895
+ run: ["\u05DE\u05E8\u05D9\u05E6\u05D4\u2026", "\u05E2\u05D3\u05D9\u05D9\u05DF \u05E8\u05E5\u2026"],
12896
+ read: ["\u05E7\u05D5\u05E8\u05D0\u05EA\u2026", "\u05E2\u05D5\u05D1\u05E8\u05EA \u05E2\u05DC \u05D6\u05D4\u2026"]
12897
+ },
12898
+ "he-m": {
12899
+ board: ["\u05D1\u05D5\u05D3\u05E7 \u05D1\u05DC\u05D5\u05D7\u2026", "\u05DE\u05E1\u05EA\u05DB\u05DC \u05E2\u05DC \u05D4\u05DB\u05E8\u05D8\u05D9\u05E1\u05D9\u05DD\u2026"],
12900
+ mail: ["\u05D1\u05D5\u05D3\u05E7 \u05D0\u05EA \u05D4\u05DE\u05D9\u05D9\u05DC\u2026", "\u05E2\u05D5\u05D1\u05E8 \u05E2\u05DC \u05D4\u05D3\u05D5\u05D0\u05E8\u2026"],
12901
+ calendar: ["\u05D1\u05D5\u05D3\u05E7 \u05D1\u05D9\u05D5\u05DE\u05DF\u2026", "\u05DE\u05E1\u05EA\u05DB\u05DC \u05D1\u05DC\u05D5\u05F4\u05D6\u2026"],
12902
+ memory: ["\u05D1\u05D5\u05D3\u05E7 \u05D1\u05E8\u05E9\u05D9\u05DE\u05D5\u05EA\u2026", "\u05DE\u05D7\u05E4\u05E9 \u05D1\u05D6\u05D9\u05DB\u05E8\u05D5\u05DF\u2026"],
12903
+ websearch: ["\u05DE\u05D7\u05E4\u05E9\u2026", "\u05DE\u05D7\u05E4\u05E9 \u05D1\u05E8\u05E9\u05EA\u2026"],
12904
+ page: ["\u05E7\u05D5\u05E8\u05D0 \u05D0\u05EA \u05D4\u05D3\u05E3\u2026", "\u05E2\u05D5\u05D1\u05E8 \u05E2\u05DC \u05D4\u05D3\u05E3\u2026"],
12905
+ browser: ["\u05E2\u05D5\u05D1\u05D3 \u05D1\u05D3\u05E4\u05D3\u05E4\u05DF\u2026", "\u05E2\u05DC \u05D4\u05D3\u05E3 \u05E2\u05DB\u05E9\u05D9\u05D5\u2026"],
12906
+ search: ["\u05DE\u05D7\u05E4\u05E9\u2026", "\u05E2\u05D3\u05D9\u05D9\u05DF \u05DE\u05D7\u05E4\u05E9\u2026"],
12907
+ delegate: ["\u05E2\u05D5\u05D1\u05D3 \u05E2\u05DC \u05D6\u05D4\u2026", "\u05E2\u05D3\u05D9\u05D9\u05DF \u05E2\u05DC \u05D6\u05D4\u2026"],
12908
+ write: ["\u05DE\u05D1\u05E6\u05E2 \u05D0\u05EA \u05D4\u05E9\u05D9\u05E0\u05D5\u05D9\u2026", "\u05DB\u05D5\u05EA\u05D1 \u05D0\u05EA \u05D6\u05D4\u2026"],
12909
+ run: ["\u05DE\u05E8\u05D9\u05E5\u2026", "\u05E2\u05D3\u05D9\u05D9\u05DF \u05E8\u05E5\u2026"],
12910
+ read: ["\u05E7\u05D5\u05E8\u05D0\u2026", "\u05E2\u05D5\u05D1\u05E8 \u05E2\u05DC \u05D6\u05D4\u2026"]
12870
12911
  }
12871
12912
  };
12872
12913
  var ProgressOptions = class {
12873
12914
  templates = PROGRESS_TEMPLATES;
12915
+ /** The voice's gender: picks the gendered table (`${lang}-f`/`-m`) when one exists. */
12916
+ gender = "";
12874
12917
  /** Fast-model fallback for a tool with no template (fastProgressGenerator). Absent → silence. */
12875
12918
  generate;
12876
12919
  generateBudgetMs = 800;
@@ -12919,8 +12962,11 @@ var Progress = class {
12919
12962
  async line(tool, args, lang) {
12920
12963
  if (this.streamed) return "";
12921
12964
  const name = tool.toLowerCase();
12922
- const topic = TOPICS.find(([re]) => re.test(name))?.[1];
12923
- const pool = topic ? this.o.templates[lang]?.[topic] ?? [] : [];
12965
+ const hit = TOPICS.find(([re]) => re.test(name));
12966
+ if (hit && hit[1] === null) return "";
12967
+ const topic = hit?.[1];
12968
+ const g = this.o.gender ? this.o.templates[`${lang}-${this.o.gender[0]}`] : void 0;
12969
+ const pool = topic ? (g ?? this.o.templates[lang])?.[topic] ?? [] : [];
12924
12970
  const fresh = pool.find((l2) => !this.said.has(norm3(l2)));
12925
12971
  if (fresh) return fresh;
12926
12972
  if (!this.o.generate) return "";
@@ -12941,9 +12987,9 @@ var Progress = class {
12941
12987
  return l;
12942
12988
  }
12943
12989
  };
12944
- function fastProgressGenerator(ai, model) {
12990
+ function fastProgressGenerator(ai, model, gender) {
12945
12991
  return async (tool, hint, lang, signal) => {
12946
- const prompt = `An assistant on a live voice call is running the tool "${tool}"${hint ? ` (about: "${hint}")` : ""}. Write ONE spoken line of 2-5 words, in ${languageName(lang)}, saying what it is doing right now (like "checking the board\u2026"). Never state a result or a finding. Output only the line.`;
12992
+ const prompt = `An assistant on a live voice call is running the tool "${tool}"${hint ? ` (about: "${hint}")` : ""}. Write ONE spoken line of 2-5 words, in ${languageName(lang)}, saying what it is doing right now (like "checking the board\u2026"). Never state a result or a finding. ${personaHint(gender)} Output only the line.`;
12947
12993
  const reasoning = /gpt-oss/.test(model) ? { providerOptions: { reasoning_effort: "low" } } : {};
12948
12994
  const r = await ai.chat({ model, messages: [{ role: "user", content: prompt }], stream: false, signal, maxTokens: 150, ...reasoning });
12949
12995
  return r.content ?? "";
@@ -13588,14 +13634,14 @@ var KIND_HINT2 = {
13588
13634
  bridge: 'a neutral one-moment cue while the answer is prepared ("let me see\u2026", "one sec\u2026") \u2014 never the start of a statement or opinion ("the thing is", "well actually")'
13589
13635
  };
13590
13636
  var REACT_HINT = 'a short reaction to their LAST words instead: feeling ("oh no", "ha, nice", "ugh"), surprise ("wait, really?", "huh"), a light laugh if they joke or laugh ("ha!"), or an echo of their key word ("the deploy?") \u2014 still never asks for an answer or takes the turn; if nothing there deserves a reaction, a plain "mm-hm"';
13591
- function fastLineGenerator(ai, model) {
13637
+ function fastLineGenerator(ai, model, gender) {
13592
13638
  return async (c, signal) => {
13593
13639
  const prompt = `You voice the tiny side-sounds of a live spoken conversation. Write ONE line of 1-5 words: ${KIND_HINT2[c.kind]}.
13594
13640
  ` + (c.react ? `Here the line may be ${REACT_HINT}.
13595
13641
  ` : "") + `The user just said: "${c.heard}"
13596
13642
  The assistant is: ${c.state}.
13597
13643
  ` + (c.avoid.length ? `Do not reuse any of: ${c.avoid.map((a) => `"${a}"`).join(", ")}.
13598
- ` : "") + `React to their actual words, casually, in ${languageName(c.lang)}. Output only the line.`;
13644
+ ` : "") + `React to their actual words, casually, in ${languageName(c.lang)}. ${personaHint(gender)} Output only the line.`;
13599
13645
  const reasoning = /gpt-oss/.test(model) ? { providerOptions: { reasoning_effort: "low" } } : {};
13600
13646
  const r = await ai.chat({ model, messages: [{ role: "user", content: prompt }], stream: false, signal, maxTokens: 150, ...reasoning });
13601
13647
  return r.content ?? "";
@@ -13633,6 +13679,8 @@ var VoiceCallOptions = class {
13633
13679
  bankCacheDir;
13634
13680
  /** The host STT's language (BCP-47) — the starting language; each turn's own words still decide. */
13635
13681
  lang;
13682
+ /** The voice's gender: generated fill/progress lines speak of themselves in it (Hebrew templates too). '' = neutral. */
13683
+ gender = "";
13636
13684
  aec = false;
13637
13685
  mode = "normal";
13638
13686
  gate = {};
@@ -13656,7 +13704,7 @@ var VoiceCall = class {
13656
13704
  ...ai ? {
13657
13705
  banks: new ChannelBanks({ generate: fastBankGenerator(ai, o.fastModel), ...o.bankCacheDir ? { cacheDir: o.bankCacheDir } : {} }),
13658
13706
  decide: channelDecide(ai),
13659
- generate: fastLineGenerator(ai, o.fastModel)
13707
+ generate: fastLineGenerator(ai, o.fastModel, o.gender)
13660
13708
  } : {},
13661
13709
  mode: o.mode,
13662
13710
  aec: o.aec,
@@ -13670,7 +13718,7 @@ var VoiceCall = class {
13670
13718
  cancel: () => o.cancel(),
13671
13719
  now: o.now
13672
13720
  });
13673
- this.progress = new Progress({ ...ai ? { generate: fastProgressGenerator(ai, o.fastModel) } : {}, now: o.now, ...o.progress });
13721
+ this.progress = new Progress({ ...ai ? { generate: fastProgressGenerator(ai, o.fastModel, o.gender) } : {}, gender: o.gender, now: o.now, ...o.progress });
13674
13722
  this.judge = new OverlapJudge({ ...ai ? { model: overlapModelFor(ai) } : {}, now: o.now });
13675
13723
  this.gate = new TurnGate({
13676
13724
  now: o.now,
@@ -14791,7 +14839,7 @@ Reference files in them by their mount path (the left side).`;
14791
14839
  // turns, amortising the ~2s Agent.create + h2 handshake. Keyed per agentx launch.
14792
14840
  ...(() => {
14793
14841
  const po = providerOptionsFor(o.model, cwd, o.mcpServers, o.hostMcpServers);
14794
- return po ? { providerOptions: po } : {};
14842
+ return po ? { providerOptions: o.lean && isClaudeCode ? { ...po, settingSources: [] } : po } : {};
14795
14843
  })(),
14796
14844
  ...(() => {
14797
14845
  const now4 = /* @__PURE__ */ new Date();
@@ -14853,12 +14901,11 @@ Windows paths: file tools accept ${cwd} style paths and the same path written ${
14853
14901
  // Subagent transcript traces, origin-anchored under .agent/traces (disk mode only — sandbox/db modes
14854
14902
  // must never write the real disk). Lets an interrupted/failed child leave a readable trail + pointer.
14855
14903
  ...!virtual ? { traceDir: `${cwd}/.agent/traces` } : {},
14856
- skillsDir: dots("skills"),
14857
- commandsDir: dots("commands"),
14904
+ ...o.lean ? {} : { skillsDir: dots("skills"), commandsDir: dots("commands") },
14858
14905
  memoryDir,
14859
14906
  memoryUserDir,
14860
14907
  agentsDir: dot("agents"),
14861
- instructionFiles: o.instructionFiles ?? ["AGENTS.md", "CLAUDE.md"],
14908
+ instructionFiles: o.lean ? false : o.instructionFiles ?? ["AGENTS.md", "CLAUDE.md"],
14862
14909
  // Only override the Agent's safety defaults when explicitly configured.
14863
14910
  ...o.maxTokens != null ? { maxTokens: o.maxTokens } : {},
14864
14911
  ...o.timeoutMs != null ? { timeoutMs: o.timeoutMs } : {},
@@ -18771,14 +18818,19 @@ function parseArgs(argv) {
18771
18818
  } else if (x === "--call") {
18772
18819
  a.call = true;
18773
18820
  a.duplex = true;
18774
- } else if (x === "--keep-alive") a.keepAlive = true;
18821
+ } else if (x === "--lean") a.lean = true;
18822
+ else if (x === "--keep-alive") a.keepAlive = true;
18775
18823
  else if (x === "--channel-only") a.channelOnly = true;
18776
18824
  else if (x === "--channel-mode") a.channelMode = parseChannelMode(val(++i, x));
18777
18825
  else if (x === "--conversational" || x === "--convo" || x === "--voice") {
18778
18826
  a.voice = true;
18779
18827
  a.duplex = true;
18780
18828
  } else if (x === "--voice-model") a.voiceModel = val(++i, x);
18781
- else if (x === "--think-model") a.thinkModel = val(++i, x);
18829
+ else if (x === "--voice-gender") {
18830
+ const g = val(++i, x);
18831
+ if (g !== "female" && g !== "male") throw new Error("--voice-gender is female or male");
18832
+ a.voiceGender = g;
18833
+ } else if (x === "--think-model") a.thinkModel = val(++i, x);
18782
18834
  else if (x === "--no-think") a.thinkModel = false;
18783
18835
  else if (x === "--allowedTools" || x === "--allowed-tools") a.allowedTools = val(++i, x).split(",").map((s) => s.trim()).filter(Boolean);
18784
18836
  else if (x === "--disallowedTools" || x === "--disallowed-tools") a.disallowedTools = val(++i, x).split(",").map((s) => s.trim()).filter(Boolean);
@@ -18884,6 +18936,8 @@ Flags:
18884
18936
  impulsive reactions, human pacing (implies --duplex; aliases: --convo, --voice)
18885
18937
  with SONIOX_API_KEY + CARTESIA_API_KEY(+VOICE_ID) set: real voice I/O \u2014 mic in,
18886
18938
  spoken replies out (echo-cancelled; speak over it to interrupt)
18939
+ --voice-gender <female|male> with --call/--channel-only: the voice's gender \u2014 fill and progress lines speak of
18940
+ themselves in it (Hebrew and other gendered languages); unset = gender-neutral wording
18887
18941
  --voice-model <id> with --duplex: the fast voice model (default groq/openai/gpt-oss-120b)
18888
18942
  --think-model <id> with --duplex: the premium deep-reasoning model (default: the newest anthropic Opus)
18889
18943
  --no-think with --duplex: disable the Think tier (Act handles everything)
@@ -18904,6 +18958,9 @@ Flags:
18904
18958
  results/reminders; note: persistent background) \u2014 never stored as the user's words
18905
18959
  with -p: the first {"type":"user","text"} line is the prompt; later ones STEER the running turn
18906
18960
  (unconsumed steers come back as the result's \`unsteered\`)
18961
+ --lean a lean prompt (a voice call's turn \u2014 time to first word): no skill, slash-command or
18962
+ AGENTS.md/CLAUDE.md catalogs; claude-code/* runs isolated from settings files (no CLAUDE.md,
18963
+ skills, plugins or settings MCP servers) \u2014 the host's MCP servers (--mcp-config/.agent) stay
18907
18964
  --keep-alive with -p --input-format stream-json: stay up after a turn \u2014 each {"type":"user"} line while idle
18908
18965
  is the NEXT turn (warm: same session, model connection and MCP servers), one {type:result}
18909
18966
  per turn; it boots (and warms a claude-code/* session) before the first line arrives;
@@ -19685,6 +19742,7 @@ function optsFor(args, ai, cfg = {}, extraTools = []) {
19685
19742
  // Forwarded to cursor/* delegations for environment parity (chat-model providers ignore it).
19686
19743
  // Raw config (pre-OAuth): unresolved-oauth http servers are skipped by the cursor mapper.
19687
19744
  mcpServers: cfg.mcpServers,
19745
+ lean: args.lean,
19688
19746
  // Gates + powers default-on WebSearchAnthropic. Same precedence as the main client (env wins).
19689
19747
  anthropicKey: apiKeysFromEnv().anthropic ?? cfg.apiKeys?.anthropic,
19690
19748
  anthropicWebSearch: cfg.anthropicWebSearch
@@ -20397,7 +20455,8 @@ async function repl(args, ai, cfg, cwd) {
20397
20455
  ai,
20398
20456
  fastModel: args.voiceModel ?? process.env.AGENTX_CHANNEL_MODEL ?? new VoiceCallOptions().fastModel,
20399
20457
  mode: args.channelMode,
20400
- channel: channelOptions(ai, args.voiceModel ?? process.env.AGENTX_CHANNEL_MODEL ?? new VoiceCallOptions().fastModel),
20458
+ channel: channelOptions(ai, args.voiceModel ?? process.env.AGENTX_CHANNEL_MODEL ?? new VoiceCallOptions().fastModel, args.voiceGender),
20459
+ gender: args.voiceGender ?? "",
20401
20460
  show: (t, kind) => {
20402
20461
  err("\r\x1B[0J" + dim(` \u21B3 ${kind === "progress" ? "\u22EF " : ""}${t}
20403
20462
  `));
@@ -22498,7 +22557,7 @@ var leakDecider = () => voiceDecider();
22498
22557
  function makeSecondChannel(ai, reflexModel, mode = "normal", opts) {
22499
22558
  return new SecondChannel({ ...channelOptions(ai, process.env.AGENTX_CHANNEL_MODEL || reflexModel), mode, ...opts });
22500
22559
  }
22501
- function channelOptions(ai, model) {
22560
+ function channelOptions(ai, model, gender) {
22502
22561
  const decider = leakDecider();
22503
22562
  const instinct = decider ? new Instinct({ decider }) : void 0;
22504
22563
  const planner = new BackchannelPlanner(ai, { model });
@@ -22506,7 +22565,7 @@ function channelOptions(ai, model) {
22506
22565
  // Banks in the user's language: generated once per language, cached + topped up across sessions (~/.agent/cache).
22507
22566
  banks: new ChannelBanks({ generate: fastBankGenerator(ai, model), cacheDir: join16(homedir10(), ".agent", "cache", "channel-banks") }),
22508
22567
  decide: channelDecide(ai, instinct),
22509
- generate: fastLineGenerator(ai, model),
22568
+ generate: fastLineGenerator(ai, model, gender),
22510
22569
  // Anticipated backchannels: on in chatty mode (its preset), else off until the offline replay proves them (tests/voice-bc-anticipate-eval.ts)
22511
22570
  plan: (c, s) => planner.plan(c, s),
22512
22571
  ...process.env.AGENTX_CHANNEL_ANTICIPATE === "1" ? { anticipate: true } : {},
@@ -22642,7 +22701,8 @@ async function channelServe(args, ai, cfg) {
22642
22701
  const call = new VoiceCall({
22643
22702
  fastModel: model,
22644
22703
  mode: args.channelMode,
22645
- channel: channelOptions(ai, process.env.AGENTX_CHANNEL_MODEL || model),
22704
+ gender: args.voiceGender ?? "",
22705
+ channel: channelOptions(ai, process.env.AGENTX_CHANNEL_MODEL || model, args.voiceGender),
22646
22706
  speak: () => true,
22647
22707
  // the host plays {type:'channel'} lines (shown via show)
22648
22708
  show: (text, kind) => out({ type: "channel", kind, text }),