@livx.cc/agentx 0.99.121 → 0.99.123

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.
@@ -1,4 +1,4 @@
1
- import { A as AgentTool } from './tools-DZHZIyxh.js';
1
+ import { A as AgentTool } from './tools-DwfeF8VQ.js';
2
2
 
3
3
  /**
4
4
  * MCP bridge — adapt a Model Context Protocol tool list into the agent's AgentTool[],
@@ -1,5 +1,5 @@
1
- import { e as McpToolSearchOptions, f as McpToolSpec } from './mcp-CUo-9LUe.js';
2
- import { A as AgentTool } from './tools-DZHZIyxh.js';
1
+ import { e as McpToolSearchOptions, f as McpToolSpec } from './mcp-DZhcLur2.js';
2
+ import { A as AgentTool } from './tools-DwfeF8VQ.js';
3
3
  import '@livx.cc/wcli/core';
4
4
 
5
5
  /** Hard cap for `tools/call`. NOT the 30s protocol timeout: a tool call is real work (an image render, a crawl)
@@ -1,5 +1,5 @@
1
1
  import { IFilesystem } from '@livx.cc/wcli/core';
2
- import { M as Message, o as MessageContent, H as HostBridge, A as AgentTool, C as ChatLike, k as JobRegistry, U as UserQuestion } from './tools-DZHZIyxh.js';
2
+ import { M as Message, o as MessageContent, H as HostBridge, A as AgentTool, C as ChatLike, k as JobRegistry, U as UserQuestion } from './tools-DwfeF8VQ.js';
3
3
 
4
4
  /**
5
5
  * `--model auto`: per-turn model routing. A classifier (Jev by default — injected, so a regex or
@@ -260,6 +260,106 @@ declare function planMode(opts?: {
260
260
  /** Run several Hooks as one: preToolUse stops at the first block; post/stop all fire. */
261
261
  declare function composeHooks(...list: (Hooks | undefined)[]): Hooks;
262
262
 
263
+ /**
264
+ * Two-model modes (ported from Blank #258/#272) — generic, host-agnostic.
265
+ *
266
+ * DELEGATE `[planner->worker]` — the (premium) agent model PLANS, a cheaper worker model WRITES.
267
+ * The planner keeps every read tool plus `Task`/`TaskBatch`, but may not write: a nudge in the prompt
268
+ * was not enough (Opus, told to delegate, wrote the whole app itself 8 runs of 8). So the rule is
269
+ * enforced at EXECUTION. Workers inherit this exact toolbelt (children get the parent's tools), so the
270
+ * one thing that tells a planner call from a worker call is the calling agent's own model, which the
271
+ * Agent puts on `ToolContext.model`. That is why delegate mode refuses to start when the models are equal.
272
+ *
273
+ * ADVISOR `[worker<-advisor]` — the inverse. The cheap model drives with every tool; `Advise` makes a
274
+ * few short calls to the premium model that see only the request, an optional host snapshot and the
275
+ * question — never the system prompt or the conversation (Anthropic's advisor tool / Aider's architect).
276
+ * A prompt rule was not enough here either (Haiku, told to consult, wrote everything with 0 calls), so
277
+ * the first write waits for one consult.
278
+ *
279
+ * Both modes run the second model through the agent's shared `ai`; `meterWorkers` sums every call on
280
+ * a model other than the agent's own, which the Agent reports as `RunResult.workerUsage`.
281
+ */
282
+
283
+ /** Tools that change files — refused for the planner, gated for an advised worker. */
284
+ declare const WRITE_TOOLS: Set<string>;
285
+ /** The planner also loses the shells: either one can write files. */
286
+ declare const PLANNER_BLOCKED: Set<string>;
287
+ /** Does the planner lose this tool? By the tool's own `writes` flag first — it survives a host rename (shraga-ee's
288
+ * `Shell` → `Bash`) — then by name, case-insensitively (`Bash`, a host's own `write`). */
289
+ declare const plannerBlocks: (t: {
290
+ name: string;
291
+ writes?: boolean;
292
+ }) => boolean;
293
+ declare const PLANNER_REFUSAL = "Refused: you are the planner and do not write files. Delegate the change with Task/TaskBatch (model set to the worker) and give the worker a full spec.";
294
+ declare const PLAN_FIRST = "Refused: check your plan with `Advise` before the first write (files, data shape, the hard parts). Then write.";
295
+ /** A build may consult at most this many times by default: plan + review + one spare. */
296
+ declare const ADVISE_LIMIT = 3;
297
+ type ModeTool = {
298
+ name: string;
299
+ run: (...a: any[]) => any;
300
+ };
301
+ /** The worker model when delegate mode can run for this planner, else undefined (why: in the log). */
302
+ declare function delegateWorkerFor(planner: string, worker?: string | false | null): string | undefined;
303
+ /** The advisor model when advisor mode can run for this worker, else undefined. */
304
+ declare function advisorFor(worker: string, advisor?: string | false | null): string | undefined;
305
+ /** Refuse the planner's file-changing tools; a worker (any other `ctx.model`) runs them as usual. */
306
+ declare function delegateTools<T extends ModeTool>(tools: T[], planner: string): T[];
307
+ /** Appended to the PLANNER's system prompt only (workers inherit the host's base prompt). */
308
+ declare function delegatePrompt(worker: string): string;
309
+ /** Appended to the advised worker's system prompt. */
310
+ declare function advisorPrompt(advisor: string): string;
311
+ interface AdvisorSetup {
312
+ ai: ChatLike;
313
+ advisor: string;
314
+ /** The user's request as the advisor should read it (the current turn's text). */
315
+ request: () => string;
316
+ /** Host-supplied state the advisor reads NOW (mid-run): files, a diff, a summary. Capped. Default: none. */
317
+ snapshot?: () => string | Promise<string>;
318
+ limit?: number;
319
+ }
320
+ /** The `Advise` tool, plus `gate` for the file tools: the first write waits for one consult
321
+ * (a failed consult counts — it never blocks the work). */
322
+ type Advisor = {
323
+ tool: ModeTool & {
324
+ description: string;
325
+ parameters: Record<string, unknown>;
326
+ };
327
+ gate: <T extends ModeTool>(tools: T[]) => T[];
328
+ used: () => number;
329
+ };
330
+ declare function makeAdvisor(o: AdvisorSetup): Advisor;
331
+ type ChatUsage = {
332
+ promptTokens: number;
333
+ completionTokens: number;
334
+ totalTokens: number;
335
+ cacheCreationTokens?: number;
336
+ cacheReadTokens?: number;
337
+ };
338
+ /** Meter the second model's calls: every call on the shared `ai` that names a model other than `main`
339
+ * (workers, the advisor). Streams count their LAST usage chunk, as the agent loop does. `model()` is
340
+ * the provider's resolved id of the last such call (captured right after it, before `main` overwrites it). */
341
+ declare function meterWorkers<T extends ChatLike>(ai: T, main: string): {
342
+ ai: T;
343
+ usage: () => ChatUsage | undefined;
344
+ model: () => string | undefined;
345
+ reset: () => void;
346
+ };
347
+ /** Claude Code's NATIVE file-changing tools (its own loop runs them; agentx's tool wrappers never see the call). */
348
+ declare const CC_WRITE_TOOLS: string[];
349
+ /**
350
+ * The same two modes for a claude-code/* agent. Claude Code runs its OWN tool loop, so `delegateTools`/`gate`
351
+ * (which wrap agentx tools) never fire there — Opus wrote with its native Write and had no worker tool.
352
+ * - planner: native writes, Bash and native Task/Agent are `disallowedTools` (the SDK strips them); agentx's
353
+ * Task/TaskBatch reach it over the in-process bridge (ccBridge.ts), so it delegates to workers on the worker model.
354
+ * - advised worker: `Advise` goes over the bridge; a PreToolUse hook denies a native write until one consult
355
+ * (`used()` > 0). The host's own `hooks` are kept.
356
+ */
357
+ declare function ccModeOptions(kind: 'delegate' | 'advisor' | undefined, hostHooks: Record<string, unknown[]> | undefined, used: () => number): {
358
+ bridge: Set<string>;
359
+ disallow: string[];
360
+ hooks?: Record<string, unknown[]>;
361
+ };
362
+
263
363
  /**
264
364
  * Normalized reasoning/thinking control → provider-specific request fragment.
265
365
  *
@@ -337,6 +437,10 @@ interface RunResult {
337
437
  * ran it"), and on the guard's own success path that sentence is false. Whether a turn needed rescuing
338
438
  * is a telemetry question, and the `log.warn` at the nudge already answers it. */
339
439
  fabricatedToolClaims?: string[];
440
+ /** Delegate/advisor mode: the second model (provider-resolved id when known) and the summed usage of its
441
+ * calls this run — NOT included in `usage`, which is the agent's own model. */
442
+ workerModel?: string;
443
+ workerUsage?: ChatUsage;
340
444
  error?: unknown;
341
445
  }
342
446
  /** What a manual `/compact` actually freed (token estimates, ~4 chars/token). */
@@ -468,6 +572,19 @@ declare class AgentOptions {
468
572
  hooks?: Hooks;
469
573
  /** If true: add the `Task` tool so the agent can spawn depth-limited child agents over the VFS. */
470
574
  subagents: boolean;
575
+ /** DELEGATE MODE: `model` plans, `worker` writes. The planner's Write/Edit/MultiEdit/ApplyEdits/bash/Shell are
576
+ * refused at execution; Task/TaskBatch are on (maxDepth 1, children default to `worker`) and children get the
577
+ * parent's `postToolUse` too. Off when the models are equal or either is cursor/*. Wins over `advisor`. */
578
+ delegate?: {
579
+ worker: string;
580
+ };
581
+ /** ADVISOR MODE: `model` does the work; an `Advise` tool asks `advisor.model` (≤`limit`, default 3) with only
582
+ * the request + `snapshot()` (host state, optional) + the question. The first write waits for one consult. */
583
+ advisor?: {
584
+ model: string;
585
+ limit?: number;
586
+ snapshot?: () => string | Promise<string>;
587
+ };
471
588
  /** VFS dir of typed-subagent defs (`<dir>/<name>.md`). If set with `subagents`: inject a catalog + enable the `Task` `agentType` param. */
472
589
  agentsDir?: string;
473
590
  /** Current recursion depth (0 = top-level); spawned children run at depth+1. */
@@ -566,6 +683,11 @@ declare class Agent {
566
683
  private ctx;
567
684
  private lastTrimNotified;
568
685
  private activeTools;
686
+ private meter?;
687
+ private modeModel?;
688
+ private modeKind?;
689
+ private adv?;
690
+ private lastTask;
569
691
  /** claude-code bridge for agentx-only tools (ccBridge.ts) + the current step's executor it calls. */
570
692
  private ccServer?;
571
693
  private ccExec?;
@@ -687,6 +809,7 @@ declare class Agent {
687
809
  /** Drop inline base64 images from older messages so Bun/JSC can reclaim the heap (see contentBytes). */
688
810
  releaseStaleImages(keepRecent?: number): void;
689
811
  private runLoop;
812
+ private loop;
690
813
  /**
691
814
  * Drain a streamed chat() response: emit each text delta to the host
692
815
  * (`{kind:'text_delta'}`) and fold all chunks back into the single
@@ -1089,4 +1212,4 @@ declare class SecondChannel {
1089
1212
  private say;
1090
1213
  }
1091
1214
 
1092
- export { Agent as A, reasoningToChatFragment as B, type ChannelMode as C, DEFAULT_MUTATING as D, type Gender as G, type Hooks as H, type LineKind as L, ModelRouter as M, PermissionOptions as P, type ReasoningEffort as R, SecondChannel as S, type Tier as T, AgentOptions as a, type ChatFragment as b, type Classification as c, type Classifier as d, type CompactResult as e, type Decider as f, type Decision as g, ModelRouterOptions as h, PermissionPolicy as i, type PermissionRule as j, type PreToolUseDecision as k, RecordingHooks as l, RecordingLifecycle as m, type RouteDecision as n, type RouterState as o, type RunResult as p, SecondChannelOptions as q, type ToolUse as r, type ToolUseMeta as s, claudeCodeDisallowedTools as t, composeHooks as u, estimateTokens as v, jevAvailable as w, jevClassifier as x, pickTier as y, planMode as z };
1215
+ export { plannerBlocks as $, ADVISE_LIMIT as A, advisorFor as B, CC_WRITE_TOOLS as C, DEFAULT_MUTATING as D, advisorPrompt as E, ccModeOptions as F, type Gender as G, type Hooks as H, claudeCodeDisallowedTools as I, composeHooks as J, delegatePrompt as K, type LineKind as L, ModelRouter as M, delegateTools as N, delegateWorkerFor as O, PLANNER_BLOCKED as P, estimateTokens as Q, type ReasoningEffort as R, SecondChannel as S, type Tier as T, jevAvailable as U, jevClassifier as V, WRITE_TOOLS as W, makeAdvisor as X, meterWorkers as Y, pickTier as Z, planMode as _, type AdvisorSetup as a, reasoningToChatFragment as a0, Agent as b, AgentOptions as c, type ChannelMode as d, type ChatFragment as e, type ChatUsage as f, type Classification as g, type Classifier as h, type CompactResult as i, type Decider as j, type Decision as k, ModelRouterOptions as l, PLANNER_REFUSAL as m, PLAN_FIRST as n, PermissionOptions as o, PermissionPolicy as p, type PermissionRule as q, type PreToolUseDecision as r, RecordingHooks as s, RecordingLifecycle as t, type RouteDecision as u, type RouterState as v, type RunResult as w, SecondChannelOptions as x, type ToolUse as y, type ToolUseMeta as z };
@@ -552,6 +552,9 @@ interface AgentTool {
552
552
  * result. Omit for tools that return promptly.
553
553
  */
554
554
  maxDurationMs?: number;
555
+ /** This tool can change files (a file editor or a shell). Survives a host rename (`Shell` → `Bash`), so policy that
556
+ * must hold whatever the tool is called — delegate mode's planner refusal — keys on it, not on the name. */
557
+ writes?: boolean;
555
558
  /**
556
559
  * Is `maxDurationMs` SELF-ENFORCED — does this tool abort itself at that bound and return?
557
560
  * An enforced bound cannot be overrun, so a transport above it needs only modest slack; an ADVISORY
@@ -1,4 +1,4 @@
1
- import { k as JobRegistry, A as AgentTool } from './tools-DZHZIyxh.js';
1
+ import { k as JobRegistry, A as AgentTool } from './tools-DwfeF8VQ.js';
2
2
  import '@livx.cc/wcli/core';
3
3
 
4
4
  /**
@@ -1221,6 +1221,7 @@ function makeRealShellTool(options) {
1221
1221
  };
1222
1222
  return {
1223
1223
  name: "Shell",
1224
+ writes: true,
1224
1225
  // Rebind for an isolated child agent (git worktree): same policy/env/timeouts, new cwd. The
1225
1226
  // `registry` is deliberately dropped — it is bound to the PARENT's cwd (and, in hosts like
1226
1227
  // shraga-ee, to the parent's session), so a background job started from the child would run