agent.libx.js 0.92.2 → 0.92.3
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/cli/cli.ts +4 -0
- package/dist/{Agent-BzwprwHr.d.ts → Agent-QwBA0wu6.d.ts} +10 -1
- package/dist/cli.d.ts +2 -2
- package/dist/cli.js +49 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +48 -3
- package/dist/index.js.map +1 -1
- package/dist/{mcp-Bn5TlRbV.d.ts → mcp-wwgXyhbi.d.ts} +1 -1
- package/dist/mcp.client.d.ts +2 -2
- package/dist/{tools-CeK5AquG.d.ts → tools-GPWp7oXq.d.ts} +4 -0
- package/dist/tools.shell.d.ts +1 -1
- package/dist/tools.shell.js +21 -1
- package/dist/tools.shell.js.map +1 -1
- package/package.json +1 -1
package/cli/cli.ts
CHANGED
|
@@ -373,6 +373,10 @@ function displayHooks(fs?: IFilesystem): Hooks {
|
|
|
373
373
|
err(cyan(`\n ⚙ ${call.name}`) + dim(' ' + summarizeCall(call.name, call.args)) + '\n');
|
|
374
374
|
if (EDIT.has(call.name)) before.set(String(call.args?.path), await read(call.args?.path));
|
|
375
375
|
},
|
|
376
|
+
onToolOutput(_call, chunk) {
|
|
377
|
+
if (!verboseOutput) return; // Ctrl+O verbose: live-tail streaming tool output (default chrome stays calm)
|
|
378
|
+
for (const ln of String(chunk).split('\n')) if (ln.trim()) err(dim(` ⋮ ${ln.length > 200 ? ln.slice(0, 200) + '…' : ln}\n`));
|
|
379
|
+
},
|
|
376
380
|
async postToolUse(call, result) {
|
|
377
381
|
spinner.stop();
|
|
378
382
|
try {
|
|
@@ -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-
|
|
2
|
+
import { M as Message, H as HostBridge, A as AgentTool, C as ChatLike, e as MessageContent } from './tools-GPWp7oXq.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Hooks — deterministic interception points around tool execution, run by the
|
|
@@ -31,6 +31,9 @@ interface Hooks {
|
|
|
31
31
|
preToolUse?(call: ToolUse, meta?: ToolUseMeta): Promise<PreToolUseDecision | void> | PreToolUseDecision | void;
|
|
32
32
|
/** Observe a tool's result after it ran (audit, metrics, side-channel). */
|
|
33
33
|
postToolUse?(call: ToolUse, result: string, meta?: ToolUseMeta): void | Promise<void>;
|
|
34
|
+
/** Observe a tool's INCREMENTAL output while it runs (only tools that stream, e.g. the real
|
|
35
|
+
* Shell). Fire-and-forget — sync, never awaited, never alters the result. */
|
|
36
|
+
onToolOutput?(call: ToolUse, chunk: string, meta?: ToolUseMeta): void;
|
|
34
37
|
/** Fired once when the agent loop stops cleanly with the model's final text. */
|
|
35
38
|
onStop?(finalText: string): void;
|
|
36
39
|
/** Fired once at session start (a fresh `run()`, or the first `send()`). Return a string to inject
|
|
@@ -59,11 +62,17 @@ declare class RecordingHooks implements Hooks {
|
|
|
59
62
|
result: string;
|
|
60
63
|
meta?: ToolUseMeta;
|
|
61
64
|
}>;
|
|
65
|
+
outputs: Array<{
|
|
66
|
+
call: ToolUse;
|
|
67
|
+
chunk: string;
|
|
68
|
+
meta?: ToolUseMeta;
|
|
69
|
+
}>;
|
|
62
70
|
stops: string[];
|
|
63
71
|
/** tool name -> reason; a matching preToolUse call is blocked with that reason. */
|
|
64
72
|
constructor(blocks?: Record<string, string>);
|
|
65
73
|
preToolUse(call: ToolUse, meta?: ToolUseMeta): PreToolUseDecision | void;
|
|
66
74
|
postToolUse(call: ToolUse, result: string, meta?: ToolUseMeta): void;
|
|
75
|
+
onToolOutput(call: ToolUse, chunk: string, meta?: ToolUseMeta): void;
|
|
67
76
|
onStop(finalText: string): void;
|
|
68
77
|
}
|
|
69
78
|
/** Recording lifecycle hooks for tests: capture session-start/prompt-submit/pre-compact + script transforms. */
|
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-
|
|
2
|
+
import { h as RunResult, R as ReasoningEffort } from './Agent-QwBA0wu6.js';
|
|
3
3
|
import { IFilesystem } from '@livx.cc/wcli/core';
|
|
4
|
-
import { M as Message, c as ContentPart } from './tools-
|
|
4
|
+
import { M as Message, c as ContentPart } from './tools-GPWp7oXq.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* On-disk session store for the CLI: each conversation is one JSON file at
|
package/dist/cli.js
CHANGED
|
@@ -1386,6 +1386,18 @@ function makeRealShellTool(options) {
|
|
|
1386
1386
|
timedOut = true;
|
|
1387
1387
|
ctl.abort();
|
|
1388
1388
|
}, timeoutMs);
|
|
1389
|
+
let pend = "";
|
|
1390
|
+
let flushTimer = null;
|
|
1391
|
+
const flushEmit = (ctx2) => {
|
|
1392
|
+
if (flushTimer) {
|
|
1393
|
+
clearTimeout(flushTimer);
|
|
1394
|
+
flushTimer = null;
|
|
1395
|
+
}
|
|
1396
|
+
if (pend) {
|
|
1397
|
+
ctx2.emit?.(redactSecrets(pend));
|
|
1398
|
+
pend = "";
|
|
1399
|
+
}
|
|
1400
|
+
};
|
|
1389
1401
|
try {
|
|
1390
1402
|
return await new Promise((resolve4) => {
|
|
1391
1403
|
let out = "";
|
|
@@ -1402,7 +1414,13 @@ function makeRealShellTool(options) {
|
|
|
1402
1414
|
return finish(`[exit 1] failed to spawn shell: ${e?.message ?? e}`);
|
|
1403
1415
|
}
|
|
1404
1416
|
const collect = (chunk) => {
|
|
1405
|
-
|
|
1417
|
+
const s = typeof chunk === "string" ? chunk : chunk?.toString?.("utf8") ?? "";
|
|
1418
|
+
out += s;
|
|
1419
|
+
if (ctx.emit && !settled) {
|
|
1420
|
+
pend += s;
|
|
1421
|
+
if (pend.length >= 1024) flushEmit(ctx);
|
|
1422
|
+
else flushTimer ??= setTimeout(() => flushEmit(ctx), 250);
|
|
1423
|
+
}
|
|
1406
1424
|
};
|
|
1407
1425
|
proc.stdout?.on("data", collect);
|
|
1408
1426
|
proc.stderr?.on("data", collect);
|
|
@@ -1412,6 +1430,7 @@ function makeRealShellTool(options) {
|
|
|
1412
1430
|
finish(`[exit 1] ${err2?.message ?? err2}${out ? "\n" + clean(out) : ""}`);
|
|
1413
1431
|
});
|
|
1414
1432
|
proc.on("close", (code) => {
|
|
1433
|
+
flushEmit(ctx);
|
|
1415
1434
|
if (ctl.signal.aborted) return finish(reasonFor(timedOut, timeoutMs, clean(out)));
|
|
1416
1435
|
const body = clean(out);
|
|
1417
1436
|
if (code && code !== 0) return finish(`[exit ${code}]${body ? "\n" + body : ""}`);
|
|
@@ -1420,6 +1439,7 @@ function makeRealShellTool(options) {
|
|
|
1420
1439
|
});
|
|
1421
1440
|
} finally {
|
|
1422
1441
|
clearTimeout(timer);
|
|
1442
|
+
if (flushTimer) clearTimeout(flushTimer);
|
|
1423
1443
|
ctx.signal?.removeEventListener("abort", onAbort);
|
|
1424
1444
|
}
|
|
1425
1445
|
}
|
|
@@ -2409,6 +2429,9 @@ function composeHooks(...list) {
|
|
|
2409
2429
|
async postToolUse(call, result, meta) {
|
|
2410
2430
|
for (const h of hooks) await h.postToolUse?.(call, result, meta);
|
|
2411
2431
|
},
|
|
2432
|
+
onToolOutput(call, chunk, meta) {
|
|
2433
|
+
for (const h of hooks) h.onToolOutput?.(call, chunk, meta);
|
|
2434
|
+
},
|
|
2412
2435
|
onStop(text) {
|
|
2413
2436
|
for (const h of hooks) h.onStop?.(text);
|
|
2414
2437
|
},
|
|
@@ -2919,6 +2942,13 @@ var Agent = class _Agent {
|
|
|
2919
2942
|
let threw = false;
|
|
2920
2943
|
try {
|
|
2921
2944
|
log3.debug(`${tc.function.name}(${tc.function.arguments})`);
|
|
2945
|
+
this.ctx.emit = hooks?.onToolOutput ? (chunk) => {
|
|
2946
|
+
try {
|
|
2947
|
+
hooks.onToolOutput(call, chunk, meta);
|
|
2948
|
+
} catch (e) {
|
|
2949
|
+
log3.debug(`onToolOutput hook error: ${e}`);
|
|
2950
|
+
}
|
|
2951
|
+
} : void 0;
|
|
2922
2952
|
const raw = await tool.run(args, this.ctx);
|
|
2923
2953
|
if (typeof raw === "string") {
|
|
2924
2954
|
result = raw;
|
|
@@ -2931,6 +2961,8 @@ var Agent = class _Agent {
|
|
|
2931
2961
|
log3.debug(`${tc.function.name} -> error: ${msg}`);
|
|
2932
2962
|
result = `Error: ${msg}`;
|
|
2933
2963
|
threw = true;
|
|
2964
|
+
} finally {
|
|
2965
|
+
this.ctx.emit = void 0;
|
|
2934
2966
|
}
|
|
2935
2967
|
if (!threw) result = await this.maybeAutoTest(tc.function.name, result);
|
|
2936
2968
|
await hooks?.postToolUse?.(call, result, meta);
|
|
@@ -3514,6 +3546,10 @@ ${recent}` : brief;
|
|
|
3514
3546
|
postToolUse: async (call, result, meta) => {
|
|
3515
3547
|
await base?.postToolUse?.(call, result, meta);
|
|
3516
3548
|
report.post(call);
|
|
3549
|
+
},
|
|
3550
|
+
onToolOutput: (call, chunk, meta) => {
|
|
3551
|
+
base?.onToolOutput?.(call, chunk, meta);
|
|
3552
|
+
report.output(chunk);
|
|
3517
3553
|
}
|
|
3518
3554
|
} : base;
|
|
3519
3555
|
const worker = new Agent({
|
|
@@ -3550,13 +3586,18 @@ ${recent}` : brief;
|
|
|
3550
3586
|
const rec = this.tasks.get(id);
|
|
3551
3587
|
if (!rec || rec.status !== "running") return clearInterval(timer);
|
|
3552
3588
|
if (!inflight || !due()) return;
|
|
3553
|
-
|
|
3589
|
+
const last = inflight.tail.trim().split("\n").filter(Boolean).pop()?.slice(-80);
|
|
3590
|
+
emit(rec, `still inside ${describeCall(inflight.call)} \u2014 ${Math.round((Date.now() - inflight.at) / 1e3)}s on this step${last ? `, last output: ${last}` : ""}`, inflight.call);
|
|
3554
3591
|
}, Math.max(this.options.progressIntervalMs, 250));
|
|
3555
3592
|
timer.unref?.();
|
|
3556
3593
|
return {
|
|
3557
3594
|
pre: (call) => {
|
|
3558
|
-
inflight = { call, at: Date.now() };
|
|
3595
|
+
inflight = { call, at: Date.now(), tail: "" };
|
|
3559
3596
|
},
|
|
3597
|
+
output: (chunk) => {
|
|
3598
|
+
if (inflight) inflight.tail = (inflight.tail + chunk).slice(-500);
|
|
3599
|
+
},
|
|
3600
|
+
// digest only — NEVER re-voices directly
|
|
3560
3601
|
post: (call) => {
|
|
3561
3602
|
steps++;
|
|
3562
3603
|
inflight = null;
|
|
@@ -7106,6 +7147,11 @@ function displayHooks(fs) {
|
|
|
7106
7147
|
\u2699 ${call.name}`) + dim(" " + summarizeCall(call.name, call.args)) + "\n");
|
|
7107
7148
|
if (EDIT.has(call.name)) before.set(String(call.args?.path), await read(call.args?.path));
|
|
7108
7149
|
},
|
|
7150
|
+
onToolOutput(_call, chunk) {
|
|
7151
|
+
if (!verboseOutput) return;
|
|
7152
|
+
for (const ln of String(chunk).split("\n")) if (ln.trim()) err(dim(` \u22EE ${ln.length > 200 ? ln.slice(0, 200) + "\u2026" : ln}
|
|
7153
|
+
`));
|
|
7154
|
+
},
|
|
7109
7155
|
async postToolUse(call, result) {
|
|
7110
7156
|
spinner.stop();
|
|
7111
7157
|
try {
|