agent.libx.js 0.94.23 → 0.94.25

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
@@ -89,7 +89,7 @@ Beyond file tools, the runtime ships the higher-altitude pieces too — each an
89
89
  - **Streaming** (`stream: true` → `text_delta` via `HostBridge.notify`) and **context compaction** (`compaction: { maxMessages }` → edge-safe summarize-and-boundary). Defaults preserve the original non-stream, drop-oldest behavior.
90
90
  - **Multi-turn + project context** — `Agent.send()` continues a conversation across turns (vs `run()`, which starts fresh); **project instructions** (`instructionFiles`: `AGENTS.md`/`CLAUDE.md` at the FS root) inject into the system prompt.
91
91
  - **DuplexAgent** (`src/duplex.ts`) — voice-optimized three-tier engine (reflex/act/think): a fast reflex agent streams instant replies and self-selects escalation — `Act` for standard tool work (Sonnet-class), `Think` for deep reasoning (Opus-class, configurable, default on). Results are pushed back and re-voiced by the reflex (turn mutex, coalesced completions, `TaskStatus`/`CancelTask`). See [`mind/10`](./mind/10-duplex.md).
92
- - **Scheduler** (`src/scheduler.ts`) — in-process scheduled tasks: one-off (`{at}`), interval (`{everyMs}`), cron (`{cron}`). Four agent tools (`ScheduleTask`/`ScheduleList`/`ScheduleCancel`/`Wakeup`). Fires while the session is alive; persisted in session JSON, re-armed on `--resume`. See [`mind/12`](./mind/12-scheduler.md).
92
+ - **Scheduler** (`src/scheduler.ts` + `cli/osScheduler.ts`) — one-off (`{at}`), interval (`{everyMs}`), cron (`{cron}`) via `ScheduleTask`/`ScheduleList`/`ScheduleCancel`/`Wakeup`. In-session jobs fire while the session is alive (persisted, re-armed on `--resume`); far one-offs (or `backend:'os'`) register with the OS scheduler (launchd / crontab / at) and **survive quitting** — the fired job headless-resumes the session (`agentx -p … --resume <id> --yes`). The `PushNotification` tool (osascript / notify-send) alerts the user out-of-band; `Read` on a `.pdf` returns extracted text (poppler's pdftotext, disk mode). See [`mind/12`](./mind/12-scheduler.md).
93
93
  - **Budget kill-switches** — always-on per-run guards (`maxTokens`/`timeoutMs`/`maxRepeats`/`maxToolCalls`/`signal` → `finishReason` `budget`/`timeout`/`loop`/`max_tool_calls`/`aborted`) protect the API spend against runaway loops. The *enforceable* billing cap is server-side in the web key-proxy: a VFS-backed budget config (`/.agent/budget.json`, USD-metered, hot-reloaded, $100/wk default) a browser client can't bypass. See [`web/`](./web) and [`mind/06`](./mind/06-agent-features.md).
94
94
 
95
95
  ## The `agentx` CLI
@@ -106,14 +106,14 @@ agentx --resume <id> "…" # resume a specific session
106
106
  - **Filesystem + Shell** — by default the CLI has **full real-filesystem access like Claude Code** (root `/` is the machine root, the launch dir is the working dir, absolute host paths and above-cwd reach both work) with a **real `/bin/sh`** (`Shell` tool) so the agent can run git, bun, node, curl, and any installed binary. Secrets (`.env`, `.ssh`, keys, `.git`) stay hidden by the jail; env secrets are scrubbed from the child shell. `--sandbox` instead operates over an in-memory copy of the working dir with a VFS-only `bash` — the real disk is never touched. `--boddb <dir>` runs over a **persistent database workspace** (a bod-db store at `<dir>` — `meta.db` tree + `files/` bytes) that survives across runs while the real disk stays untouched; DB-native by default, or add `--seed` to hydrate it from cwd on the first run. `--no-shell` forces the VFS bash in disk mode. `--harden` OS-sandboxes the real shell (macOS `sandbox-exec` / Linux `bwrap`): writes confined to cwd+tmp, outbound network blocked (`--harden-net` keeps network); commands fail closed when no wrapper exists. (`/sandbox` shows the active mode.)
107
107
  - **Sessions** — every conversation persists to `./.agent/sessions/<id>.json`; `--continue`/`--resume` (and `/sessions`, `/resume`) pick it back up, *with memory across turns* — a REPL turn sees the previous one. A global symlink index at `~/.agent/sessions/` enables cross-project lookup: `--resume 090715-myproject` resolves from any directory, and `/sessions all` lists every project's sessions in one picker.
108
108
  - **Diffs** — every `Edit`/`Write`/`MultiEdit` renders a colorized `+/-` diff (TTY-gated; plain when piped).
109
- - **Slash commands** — `/help /tools /model /compact /memory /clear /sessions /resume /commands /init`; `/compact <focus>` preserves matching lines from the folded span; `/memory` opens the memory index in `$EDITOR`; user-defined `./.agent/commands/<name>.md` are invokable directly as `/<name>` (the same registry the model's `SlashCommand` tool uses). Skills/commands created **mid-session** are picked up automatically each turn (delivered as a cache-friendly `<system-reminder>` delta, like Claude Code) and the `Skill`/`SlashCommand` tools rescan on a name miss; `/reload` forces a full catalog + system-prompt rebuild.
109
+ - **Slash commands** — `/help /tools /model /compact /copy /diff /memory /clear /sessions /resume /commands /init`; `/compact <focus>` preserves matching lines from the folded span; `/copy [code]` puts the last reply (or its last code block) on the OS clipboard; `/diff` shows everything the session changed (oldest checkpoint → now); `/memory` opens the memory index in `$EDITOR`; user-defined `./.agent/commands/<name>.md` are invokable directly as `/<name>` (the same registry the model's `SlashCommand` tool uses). Skills/commands created **mid-session** are picked up automatically each turn (delivered as a cache-friendly `<system-reminder>` delta, like Claude Code) and the `Skill`/`SlashCommand` tools rescan on a name miss; `/reload` forces a full catalog + system-prompt rebuild.
110
110
  - **Live chrome** — the thinking spinner shows elapsed seconds + `esc to interrupt`; the terminal tab title tracks the session topic; a bell rings when a long (>10s) turn finishes in a backgrounded tab; the footer warns at 80%/90% context pressure and auto-trims announce themselves.
111
111
  - **`/transcript [n]`** — the full session transcript including complete tool-result bodies (the past-turn equivalent of Ctrl-O live verbose), paged through `less`; **`/doctor`** — one-shot environment sanity check (keys, model pricing, config, session-store writability, memory, MCP mounts).
112
112
  - **Syntax-highlighted code fences** — ```` ```ts ```` (and js/py/sh/go/rust/…) blocks render with keywords bold, strings green, numbers cyan, comments dim; unknown languages keep the plain cyan body. **TodoWrite plans** pin a compact `☑ 2/5 · current step` line into the idle footer.
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`; `~/` expands to the home directory); 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; quote paths with spaces as `@"…"` — drag-dropped files, e.g. macOS screenshots, quote themselves automatically); 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.
@@ -1,5 +1,5 @@
1
1
  import { IFilesystem } from '@livx.cc/wcli/core';
2
- import { M as Message, H as HostBridge, A as AgentTool, C as ChatLike, e as MessageContent } from './tools-9AUK6SG2.js';
2
+ import { M as Message, H as HostBridge, A as AgentTool, C as ChatLike, e as MessageContent } from './tools-DtpN8Agv.js';
3
3
 
4
4
  /**
5
5
  * Hooks — deterministic interception points around tool execution, run by the
@@ -285,6 +285,8 @@ declare class AgentOptions {
285
285
  permissions?: PermissionPolicy;
286
286
  /** Opt-in syntax guardrail: refuse to persist a syntactically-broken code-file write/edit. Default off. */
287
287
  lintOnWrite?: boolean;
288
+ /** Optional PDF text extraction for Read on .pdf files (node hosts wire pdftotext); absent => Read explains. */
289
+ pdfText?: (path: string) => Promise<string>;
288
290
  /** Opt-in: after a write-class tool runs, run `command` over the VFS and append any failure to the tool result.
289
291
  * `tools` defaults to ['Write','Edit','MultiEdit','ApplyEdits']. */
290
292
  autoTest?: {
@@ -326,7 +328,10 @@ declare class Agent {
326
328
  * from `options` — apply mid-conversation changes to `planMode`/`permissions`/`model` etc. (prepare()
327
329
  * is otherwise memoized per conversation). */
328
330
  reprepare(): void;
329
- /** Inject tools into a running agent (e.g. dynamically mounted MCP servers). Takes effect on the next turn. */
331
+ /** Tools injected via addTools(); kept separate from options.tools so prepare() rebuilds don't drop them. */
332
+ private injectedTools;
333
+ /** Inject tools into a running agent (e.g. dynamically mounted MCP servers). Takes effect on the next turn
334
+ * and survives prepare() rebuilds (reprepare(), new conversations). */
330
335
  addTools(tools: AgentTool[]): void;
331
336
  /** Remove tools by name from a running agent. Returns the count removed. */
332
337
  removeTools(names: Set<string> | string[]): number;
package/dist/cli.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
- import { h as RunResult, R as ReasoningEffort } from './Agent-DmsB5hzp.js';
2
+ import { h as RunResult, R as ReasoningEffort } from './Agent-BA-rueWn.js';
3
3
  import { IFilesystem } from '@livx.cc/wcli/core';
4
- import { M as Message, c as ContentPart } from './tools-9AUK6SG2.js';
4
+ import { M as Message, c as ContentPart } from './tools-DtpN8Agv.js';
5
5
 
6
6
  /**
7
7
  * On-disk session store for the CLI: each conversation is one JSON file at
@@ -175,6 +175,10 @@ declare function resolvePermMode(args: {
175
175
  ask?: boolean;
176
176
  outputFormat?: string;
177
177
  }, interactiveCapable: boolean): PermMode;
178
+ /** Extract `@ref` mentions: bare `@path` (no spaces) or quoted `@"path with spaces"` — the quoted
179
+ * form is what lets a drag-dropped macOS screenshot ("Screenshot 2026-06-11 at ….png") attach at all.
180
+ * Bare refs get trailing sentence punctuation stripped (e.g. "@a.ts." / "@a.ts?"). */
181
+ declare function mentionRefs(line: string): string[];
178
182
  /** Read `@image.png` mentions from `line` as base64 image content parts (real files under cwd; binary,
179
183
  * so read via node fs — the VFS readFile is utf8). Unreadable/missing images are skipped silently
180
184
  * (expandMentions reports the missing @ref separately). */
@@ -218,4 +222,4 @@ declare function jsonResult(res: RunResult, session: SessionData): {
218
222
  */
219
223
  declare function readMultiline(readLine: (continuing: boolean) => Promise<string | null>): Promise<string | null>;
220
224
 
221
- export { type PermMode, appendMemoryNote, cacheMultipliers, condenseReplay, costOf, estimateTranscriptTokens, expandMentions, exportMarkdown, fmtUsd, formatHistory, formatStatus, formatTranscriptFull, jsonResult, mcpMentionResolver, parseArgs, pastePathClassifier, readImageParts, readMultiline, resolvePermMode, runShellLine, setMcpMentionResolver };
225
+ export { type PermMode, appendMemoryNote, cacheMultipliers, condenseReplay, costOf, estimateTranscriptTokens, expandMentions, exportMarkdown, fmtUsd, formatHistory, formatStatus, formatTranscriptFull, jsonResult, mcpMentionResolver, mentionRefs, parseArgs, pastePathClassifier, readImageParts, readMultiline, resolvePermMode, runShellLine, setMcpMentionResolver };