agent.libx.js 0.94.14 → 0.94.15

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/README.md CHANGED
@@ -113,7 +113,7 @@ agentx --resume <id> "…" # resume a specific session
113
113
  - **`/agents`** — list subagent types from `./.agent/agents` (description, model, tool scope); `/agents new <name>` scaffolds a frontmatter'd definition for the `Task` tool's `agentType`. **`!<partial>` + menu** completes from past `!` shell commands. **`@server:uri`** mentions inline an MCP resource body into the prompt. Transient network drops mid-step retry automatically (2 attempts, backoff) instead of failing the turn.
114
114
  - **Project instructions** — `./AGENTS.md` (or `CLAUDE.md`) auto-loads into every run; `/init` scaffolds one.
115
115
  - **Any provider** — set `ANTHROPIC_API_KEY` / `OPENAI_API_KEY` / `GOOGLE_API_KEY` / `GROQ_API_KEY`; choose with `-m provider/model`.
116
- - **@-file mentions & headless JSON** — reference files inline in a prompt with `@path` (e.g. `explain @src/Agent.ts`); script with `-p --output-format json` to get one machine-readable result object on stdout (activity stays on stderr).
116
+ - **@-file mentions & headless JSON** — reference files inline in a prompt with `@path` (e.g. `explain @src/Agent.ts`; `~/` expands to the home directory); script with `-p --output-format json` to get one machine-readable result object on stdout (activity stays on stderr).
117
117
  - **Tab-completion** — `Tab` completes `/<command>` names and `@<path>` file/dir references (descends subdirs, dotfiles hidden unless typed) straight from the working tree.
118
118
  - **Duplex mode** — `agentx --duplex` runs the full standard REPL (slash commands, sessions, postures, rewind, MCP) with the three-tier engine driving turns: a fast voice model (`--voice-model`, default `groq/openai/gpt-oss-120b`) answers every line instantly and delegates real work to background workers built with the same wiring as a normal run (fs mode, permissions, MCP); worker activity shows as dim chrome and results are re-voiced when ready. Switch any tier live with `/model` (opens a reflex/act/think picker), or the `/voice-model` · `/think-model` shortcuts. `/tasks` lists background tasks, inspects a task's live output tail, and cancels a running one from a picker (Esc mid-turn cancels the foreground turn; Esc again at the idle prompt cancels running workers).
119
119
  - **MCP servers** — declare `mcpServers: { name: { command, args } | { url } }` in config and they're auto-mounted at startup (in parallel, with an optional `mountTimeoutMs` deadline so one slow/dead server never blocks the rest): the client does the JSON-RPC handshake (stdio or HTTP) + `tools/list`, and the discovered tools appear as `mcp__<name>__<tool>` in `/tools` (inspect with `/mcp`). A bad server is logged and skipped, never blocking the agent. For large tool sets, **deferred mode** (`makeMcpToolSearch` / `mountMcpDeferred`) exposes just two bounded tools (`ToolSearch` + `McpCall`) instead of N defs — dodging the provider tool-cap and improving selection accuracy. **`mountMcpCatalog`** goes further: a cached, hash-keyed catalog + lazy connect means a turn that uses no MCP tool opens **zero** connections, and one that uses a tool connects exactly that server — latency scales with tools-used, not servers-configured. A down server is **negative-cached** (`failureCooldownMs`) so it never re-floors a later turn at the deadline. For zero turn-path latency even on a cold process, call **`warmMcpCatalog`** at boot + on a timer (off-turn discovery) and mount with **`{ discover: 'cache-only' }`** — the turn then never synchronously connects: it serves the warmed catalog and discovers any miss in the background.
package/dist/cli.js CHANGED
@@ -9319,8 +9319,9 @@ function readImageParts(cwd, line) {
9319
9319
  for (const ref of refs) {
9320
9320
  const mime = IMG_EXT[extname(ref).toLowerCase()];
9321
9321
  if (!mime) continue;
9322
+ const abs = ref.startsWith("~/") ? join9(homedir6(), ref.slice(2)) : resolve3(cwd, ref);
9322
9323
  try {
9323
- parts.push(imagePart(`data:${mime};base64,${readFileSync5(resolve3(cwd, ref)).toString("base64")}`));
9324
+ parts.push(imagePart(`data:${mime};base64,${readFileSync5(abs).toString("base64")}`));
9324
9325
  } catch {
9325
9326
  }
9326
9327
  }
@@ -9366,10 +9367,11 @@ ${body}`);
9366
9367
  continue;
9367
9368
  }
9368
9369
  }
9370
+ const path = ref.startsWith("~/") ? join9(homedir6(), ref.slice(2)) : ref;
9369
9371
  try {
9370
- if (await fs.exists(ref)) {
9372
+ if (await fs.exists(path)) {
9371
9373
  blocks.push(`--- @${ref} ---
9372
- ${await fs.readFile(ref)}`);
9374
+ ${await fs.readFile(path)}`);
9373
9375
  loaded.push(ref);
9374
9376
  } else missing.push(ref);
9375
9377
  } catch {