@livx.cc/agentx 0.99.80 → 0.99.82

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.
@@ -307,6 +307,11 @@ interface RunResult {
307
307
  totalTokens: number;
308
308
  cacheCreationTokens?: number;
309
309
  cacheReadTokens?: number;
310
+ /** What the context holds after the run: the LAST model call's prompt (a self-looping backend's own figure —
311
+ * claude-code sums its calls into promptTokens) — and the window it is measured against (the backend's
312
+ * reported one, else `Agent.contextCap`). context % = contextTokens / contextWindow. */
313
+ contextTokens?: number;
314
+ contextWindow?: number;
310
315
  };
311
316
  /** Present iff `finishReason === 'budget'`: the weighted spend vs `maxTokens`, and the last step's prompt
312
317
  * size — a prompt near the limit means the CONVERSATION is too big for one run (compact / new chat). */
@@ -669,8 +674,9 @@ declare class Agent {
669
674
  * retained window → halve the window → drop-oldest backstop. Deterministic, no LLM call.
670
675
  * `focus` (e.g. `/compact keep the API details`) preserves matching lines from the dropped span verbatim.
671
676
  * Returns before/after token estimates so the caller can report honestly (0 freed => say so).
677
+ * `target` (tokens): a tighter budget than half the window — a host compacting at its own threshold.
672
678
  */
673
- compactNow(maxMessages?: number, focus?: string): CompactResult;
679
+ compactNow(maxMessages?: number, focus?: string, target?: number): CompactResult;
674
680
  /** Drop inline base64 images from older messages so Bun/JSC can reclaim the heap (see contentBytes). */
675
681
  releaseStaleImages(keepRecent?: number): void;
676
682
  private runLoop;
package/dist/cli.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- import { m as RouterState, H as Hooks, n as RunResult, R as ReasoningEffort, A as Agent } from './Agent-BK-heHrw.js';
2
+ import { m as RouterState, H as Hooks, n as RunResult, R as ReasoningEffort, A as Agent } from './Agent-RHsiEAiP.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-lC3jn60o.js';
5
5
 
@@ -331,6 +331,8 @@ declare function jsonResult(res: RunResult, session: SessionData): {
331
331
  totalTokens: number;
332
332
  cacheCreationTokens?: number;
333
333
  cacheReadTokens?: number;
334
+ contextTokens?: number;
335
+ contextWindow?: number;
334
336
  } | undefined;
335
337
  providerFinishReason?: string | undefined;
336
338
  ok: boolean;
package/dist/cli.js CHANGED
@@ -5140,10 +5140,11 @@ var Agent = class _Agent {
5140
5140
  * retained window → halve the window → drop-oldest backstop. Deterministic, no LLM call.
5141
5141
  * `focus` (e.g. `/compact keep the API details`) preserves matching lines from the dropped span verbatim.
5142
5142
  * Returns before/after token estimates so the caller can report honestly (0 freed => say so).
5143
+ * `target` (tokens): a tighter budget than half the window — a host compacting at its own threshold.
5143
5144
  */
5144
- compactNow(maxMessages = 12, focus) {
5145
+ compactNow(maxMessages = 12, focus, target) {
5145
5146
  const cap = _Agent.contextCap(this.options);
5146
- const target = Math.round(cap * _Agent.COMPACT_TARGET);
5147
+ target = Math.min(Math.round(cap * _Agent.COMPACT_TARGET), target || Infinity);
5147
5148
  const kr = this.options.keepRecentImages ?? 1;
5148
5149
  const vis2 = this.sendsImages();
5149
5150
  const tokensBefore = estimateTokens(this.transcript, kr, vis2);
@@ -5351,6 +5352,8 @@ var Agent = class _Agent {
5351
5352
  usage.cacheCreationTokens += res.usage.cacheCreationTokens ?? 0;
5352
5353
  usage.cacheReadTokens += res.usage.cacheReadTokens ?? 0;
5353
5354
  const prompt = res.usage.promptTokens ?? 0, cacheRead = res.usage.cacheReadTokens ?? 0;
5355
+ usage.contextTokens = res.usage.contextTokens ?? prompt;
5356
+ usage.contextWindow = res.usage.contextWindow || _Agent.contextCap(o);
5354
5357
  if (prevPrompt < 0) {
5355
5358
  const u = sent.map((m) => m.role).lastIndexOf("user");
5356
5359
  prevPrompt = u > 0 ? estimateTokens(sent.slice(0, u)) : 0;
@@ -5581,7 +5584,7 @@ var Agent = class _Agent {
5581
5584
  const nj = a.id ? this.nativeJobs.get(a.id) : void 0;
5582
5585
  if (a.status === "running") {
5583
5586
  if (nj) nj.touch();
5584
- else if (a.id) this.nativeJobs.set(a.id, this.jobs.track({ kind: "native", label: a.name, holds: true, idleMs: this.nativeHoldMs, hardCapMs: this.toolHoldMs }));
5587
+ else if (a.id) this.nativeJobs.set(a.id, this.jobs.track({ kind: "native", label: a.name === "mcp" && a.input?.toolName ? `mcp:${a.input.toolName}` : a.name, holds: true, idleMs: this.nativeHoldMs, hardCapMs: this.toolHoldMs }));
5585
5588
  } else {
5586
5589
  if (nj) {
5587
5590
  if (typeof a.output === "string") nj.chunk(a.output.slice(-4e3));
@@ -20112,6 +20115,22 @@ async function main() {
20112
20115
  }
20113
20116
  });
20114
20117
  if (args.task) {
20118
+ const compactArg = /^\/compact(?:\s+([\s\S]*))?$/.exec(args.task.trim());
20119
+ if (compactArg) {
20120
+ const agent2 = await makeAgent(args, ai, cfg, [], []), store2 = new SessionStore(cwd), session2 = startSession(args, store2, agent2, cwd);
20121
+ const est = (m) => estimateTranscriptTokens(m, agent2.options.keepRecentImages, agent2.options.imageInput?.(agent2.options.model) !== false);
20122
+ const fixed = est(agent2.transcript.filter((m) => m.role === "system"));
20123
+ const r = agent2.compactNow(12, compactArg[1]?.trim() || void 0, Math.round(fixed + (est(agent2.transcript) - fixed) / 2));
20124
+ session2.messages = agent2.transcript;
20125
+ session2.meta.updated = Date.now();
20126
+ store2.save(session2);
20127
+ const obj = { ok: true, finishReason: "stop", text: "", steps: 0, compacted: r, sessionId: session2.meta.id };
20128
+ if (args.outputFormat === "json" || args.outputFormat === "stream-json") process.stdout.write(JSON.stringify(args.outputFormat === "stream-json" ? { type: "result", ...obj } : obj) + "\n");
20129
+ else err(dim(` compacted ~${(r.tokensBefore / 1e3).toFixed(1)}k \u2192 ~${(r.tokensAfter / 1e3).toFixed(1)}k tok of ${Math.round(r.cap / 1e3)}k
20130
+ `));
20131
+ worktreeCleanup?.();
20132
+ process.exit(0);
20133
+ }
20115
20134
  const mounted = await mountMcp(cfg, new McpOAuth({ storePath: join15(cwd, ".agent", "mcp-auth.json") }));
20116
20135
  const agent = await makeAgent(args, ai, cfg, mcpAgentTools(mounted), mounted.map((m) => m.name));
20117
20136
  const store = new SessionStore(cwd);