@livx.cc/agentx 0.99.58 → 0.99.59

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,5 +1,103 @@
1
1
  import { IFilesystem } from '@livx.cc/wcli/core';
2
- import { M as Message, H as HostBridge, A as AgentTool, C as ChatLike, k as JobRegistry, o as MessageContent, U as UserQuestion } from './tools-HsbxgqjF.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-HsbxgqjF.js';
3
+
4
+ /**
5
+ * `--model auto`: per-turn model routing. A classifier (Jev by default — injected, so a regex or
6
+ * cheap-model classifier can replace it) picks a capability tier — fast | standard | premium — for each user turn (tiers map to any provider's models).
7
+ *
8
+ * The MAIN session only ever runs on fast/standard: switching it to premium throws away the prompt cache.
9
+ * A hard turn is instead OFFLOADED to a premium sub-agent (same child machinery as the `Task` tool):
10
+ * the main model writes a brief, the last 2 turns ride along verbatim, and the premium answer is appended
11
+ * to the main transcript as that turn's reply. The premium side-conversation is kept in `state` and
12
+ * RESUMED (delta + new question only) when the classifier says the turn continues the same thread.
13
+ *
14
+ * Classifier failure/timeout ⇒ standard (logged). `state` is plain JSON so a host can persist it
15
+ * across processes (the CLI stores it in the session, so `-c`/`--resume` keeps the premium thread).
16
+ */
17
+
18
+ type Tier = 'fast' | 'standard' | 'premium';
19
+ interface Turn {
20
+ user: string;
21
+ assistant: string;
22
+ }
23
+ interface RouteInput {
24
+ previousModel: 'fast' | 'standard';
25
+ history: Turn[];
26
+ next: string;
27
+ lastOffload?: string;
28
+ }
29
+ /** Classifier output: tier probabilities (+ the raw argmax) and, when asked, P(same thread as last offload). */
30
+ interface Classification {
31
+ probs: Partial<Record<Tier, number>>;
32
+ choice: Tier;
33
+ sameThread?: number;
34
+ }
35
+ type Classifier = (input: RouteInput) => Promise<Classification>;
36
+ interface RouteDecision {
37
+ tier: Tier;
38
+ model: string;
39
+ probs: Partial<Record<Tier, number>>;
40
+ choice?: Tier;
41
+ sameThread?: number;
42
+ offload?: 'fresh' | 'continue';
43
+ fallback?: string;
44
+ classifyMs: number;
45
+ }
46
+ interface RouterState {
47
+ main?: string;
48
+ offload?: {
49
+ messages: Message[];
50
+ mainLen: number;
51
+ question: string;
52
+ };
53
+ offloads?: number;
54
+ reuses?: number;
55
+ }
56
+ type Usage = NonNullable<RunResult['usage']>;
57
+ declare class ModelRouterOptions {
58
+ classifier: Classifier;
59
+ /** Capability tiers → model id (any provider). fast/standard run the main session; premium is only ever an offload. */
60
+ models: Record<Tier, string>;
61
+ /** Escalate to a stronger tier when it holds at least this much probability mass (upward bias). */
62
+ threshold: number;
63
+ /** P(same thread) at or above which the previous premium side-conversation is resumed. */
64
+ sameThreadAt: number;
65
+ classifyTimeoutMs: number;
66
+ /** Host-supplied pricing (model, usage) → USD, so mixed-model turns are costed per model. */
67
+ costOf: (model: string, usage?: Usage) => number;
68
+ /** Step budget for the premium sub-agent. */
69
+ offloadMaxSteps: number;
70
+ /** Host-supplied provider options per model (e.g. claude-code's subscription env); applied on every tier switch + the offload child. */
71
+ providerOptionsFor?: (model: string) => Record<string, unknown> | undefined;
72
+ }
73
+ /** Upward-biased tier pick: premium if P(premium) ≥ th; standard over fast if P(standard)+P(premium) ≥ th. */
74
+ declare function pickTier(c: Classification, th: number): Tier;
75
+ declare class ModelRouter {
76
+ options?: Partial<ModelRouterOptions> | undefined;
77
+ state: RouterState;
78
+ constructor(options?: Partial<ModelRouterOptions> | undefined);
79
+ private get o();
80
+ /** Classify one turn. Never throws: classifier failure/timeout ⇒ standard. */
81
+ decide(transcript: Message[], next: string): Promise<RouteDecision>;
82
+ /** Run one user turn on `agent` with routing. Returns a RunResult carrying `costUsd` + `routing`. */
83
+ send(agent: Agent, content: MessageContent): Promise<RunResult>;
84
+ private offload;
85
+ /** The main model writes the task brief on its own (cached) context, tools off; the transcript is restored after. */
86
+ private brief;
87
+ private use;
88
+ private spawn;
89
+ }
90
+ /** Default classifier: Jev (TypeSafe). The module is loaded lazily from `jevModule`
91
+ * (default `@livx.cc/mcp-jev/jev`, or `$AGENTX_JEV_MODULE`); provider keys come from `env`,
92
+ * optionally merged with a dotenv file at `$AGENTX_JEV_ENV`. Any load/eval error ⇒ router falls back. */
93
+ type JevOpts = {
94
+ jevModule?: string;
95
+ envFile?: string;
96
+ provider?: string;
97
+ };
98
+ /** True when Jev can actually run here (module resolves + at least one provider key) — gates `auto` as the default model. */
99
+ declare function jevAvailable(opts?: JevOpts): Promise<boolean>;
100
+ declare function jevClassifier(opts?: JevOpts): Classifier;
3
101
 
4
102
  /**
5
103
  * Hooks — deterministic interception points around tool execution, run by the
@@ -201,6 +299,10 @@ interface RunResult {
201
299
  };
202
300
  /** True if ANY turn's usage was estimated (provider gave none) rather than exact — lets the UI mark cost `~`. */
203
301
  usageEstimated?: boolean;
302
+ /** Set by a router (`--model auto`) whose turn spans several models: the turn's USD at each model's own rate. */
303
+ costUsd?: number;
304
+ /** `--model auto` routing decision for this turn. */
305
+ routing?: RouteDecision;
204
306
  /** Advertised tools the model NAMED in the reply it is handing back while the run's invocation ledger
205
307
  * shows zero calls to them — a fabricated tool use, proven against ground truth rather than guessed
206
308
  * from phrasing. A host can use it to tell the user plainly instead of shipping the invented result.
@@ -630,4 +732,4 @@ declare class Agent {
630
732
  * stub made `/compact` chase a target it could never reach and drop-oldest the conversation away. */
631
733
  declare function estimateTokens(m: Message[], keepRecentImages?: number): number;
632
734
 
633
- export { Agent as A, type ChatFragment as C, DEFAULT_MUTATING as D, type Hooks as H, PermissionOptions as P, type ReasoningEffort as R, type ToolUse as T, AgentOptions as a, type CompactResult as b, type Decision as c, PermissionPolicy as d, type PermissionRule as e, type PreToolUseDecision as f, RecordingHooks as g, RecordingLifecycle as h, type RunResult as i, type ToolUseMeta as j, composeHooks as k, estimateTokens as l, planMode as p, reasoningToChatFragment as r };
735
+ export { Agent as A, type ChatFragment as C, DEFAULT_MUTATING as D, type Hooks as H, ModelRouter as M, PermissionOptions as P, type ReasoningEffort as R, type Tier as T, AgentOptions as a, type Classification as b, type Classifier as c, type CompactResult as d, type Decision as e, ModelRouterOptions as f, PermissionPolicy as g, type PermissionRule as h, type PreToolUseDecision as i, RecordingHooks as j, RecordingLifecycle as k, type RouteDecision as l, type RouterState as m, type RunResult as n, type ToolUse as o, type ToolUseMeta as p, composeHooks as q, estimateTokens as r, jevAvailable as s, jevClassifier as t, pickTier as u, planMode as v, reasoningToChatFragment as w };
package/dist/cli.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- import { H as Hooks, i as RunResult, R as ReasoningEffort, A as Agent } from './Agent-CXkPfYX2.js';
2
+ import { m as RouterState, H as Hooks, n as RunResult, R as ReasoningEffort, A as Agent } from './Agent-DqFJubs5.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-HsbxgqjF.js';
5
5
 
@@ -15,6 +15,8 @@ interface SessionMeta {
15
15
  updated: number;
16
16
  cwd: string;
17
17
  model?: string;
18
+ /** `-m auto` router state (main model + reusable opus side-conversation). */
19
+ router?: RouterState;
18
20
  turns: number;
19
21
  title: string;
20
22
  /** Cumulative tokens across all turns in this session (for `/cost`). */
@@ -152,6 +154,7 @@ interface Args {
152
154
  updateCheck?: boolean;
153
155
  update?: boolean;
154
156
  listModels?: boolean;
157
+ autoRoute?: boolean;
155
158
  }
156
159
  declare function parseArgs(argv: string[]): Args;
157
160
  declare function makeHost(format?: 'text' | 'json' | 'stream-json', opts?: {
@@ -210,6 +213,14 @@ declare function costOf(pricing: {
210
213
  inputCostPer1K: number;
211
214
  outputCostPer1K: number;
212
215
  } | undefined, promptTokens?: number, completionTokens?: number, cacheCreationTokens?: number, cacheReadTokens?: number, model?: string): number;
216
+ /** Cost of one turn at `model`'s rate (looks up ai.libx.js pricing). Subscription `claude-code/<alias>` models
217
+ * are priced at their API-equivalent Anthropic rate so auto-vs-pinned comparisons stay meaningful. */
218
+ declare function turnCost(model: string, usage?: {
219
+ promptTokens?: number;
220
+ completionTokens?: number;
221
+ cacheCreationTokens?: number;
222
+ cacheReadTokens?: number;
223
+ }): number;
213
224
  /** Format a USD amount: 2 decimals at $1+, 4 below (agent turns are sub-cent). */
214
225
  declare function fmtUsd(n: number): string;
215
226
  /** ~4 chars/token estimate over a transcript (matches the Agent's context-budget heuristic).
@@ -284,6 +295,9 @@ declare function expandMentions(fs: IFilesystem, line: string): Promise<{
284
295
  declare function jsonResult(res: RunResult, session: SessionData): {
285
296
  error?: any;
286
297
  question?: UserQuestion | undefined;
298
+ sessionId: string;
299
+ costUsd?: number | undefined;
300
+ routing?: Record<string, unknown> | undefined;
287
301
  text: string;
288
302
  steps: number;
289
303
  tools: number;
@@ -294,7 +308,6 @@ declare function jsonResult(res: RunResult, session: SessionData): {
294
308
  cacheCreationTokens?: number;
295
309
  cacheReadTokens?: number;
296
310
  } | undefined;
297
- sessionId: string;
298
311
  providerFinishReason?: string | undefined;
299
312
  ok: boolean;
300
313
  finishReason: "error" | "budget" | "stop" | "max_steps" | "timeout" | "loop" | "max_tool_calls" | "aborted" | "needs_input" | "empty";
@@ -313,4 +326,4 @@ declare function runTurn(agent: Agent, store: SessionStore, session: SessionData
313
326
  res?: RunResult;
314
327
  }>;
315
328
 
316
- export { type PermMode, abortActiveTurn, appendMemoryNote, cacheMultipliers, condenseReplay, costOf, estimateTranscriptTokens, expandMentions, exportMarkdown, fmtUsd, formatHistory, formatStatus, formatTranscriptFull, jsonResult, makeHost, mcpMentionResolver, mentionRefs, parseArgs, pastePathClassifier, readImageParts, readMultiline, resolvePermMode, runShellLine, runTurn, setMcpMentionResolver, summarizeResult };
329
+ export { type PermMode, abortActiveTurn, appendMemoryNote, cacheMultipliers, condenseReplay, costOf, estimateTranscriptTokens, expandMentions, exportMarkdown, fmtUsd, formatHistory, formatStatus, formatTranscriptFull, jsonResult, makeHost, mcpMentionResolver, mentionRefs, parseArgs, pastePathClassifier, readImageParts, readMultiline, resolvePermMode, runShellLine, runTurn, setMcpMentionResolver, summarizeResult, turnCost };