@livx.cc/agentx 0.99.45 → 0.99.46
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/dist/{Agent-Bzs57-iD.d.ts → Agent-OcAg2yxA.d.ts} +14 -0
- package/dist/cli.d.ts +4 -3
- package/dist/cli.js +56 -9
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +54 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as AgentOptions, H as Hooks, i as RunResult, A as Agent } from './Agent-
|
|
2
|
-
export { C as ChatFragment, b as CompactResult, D as DEFAULT_MUTATING, c as Decision, P as PermissionOptions, d as PermissionPolicy, e as PermissionRule, f as PreToolUseDecision, R as ReasoningEffort, g as RecordingHooks, h as RecordingLifecycle, T as ToolUse, j as ToolUseMeta, k as composeHooks, l as estimateTokens, p as planMode, r as reasoningToChatFragment } from './Agent-
|
|
1
|
+
import { a as AgentOptions, H as Hooks, i as RunResult, A as Agent } from './Agent-OcAg2yxA.js';
|
|
2
|
+
export { C as ChatFragment, b as CompactResult, D as DEFAULT_MUTATING, c as Decision, P as PermissionOptions, d as PermissionPolicy, e as PermissionRule, f as PreToolUseDecision, R as ReasoningEffort, g as RecordingHooks, h as RecordingLifecycle, T as ToolUse, j as ToolUseMeta, k as composeHooks, l as estimateTokens, p as planMode, r as reasoningToChatFragment } from './Agent-OcAg2yxA.js';
|
|
3
3
|
export { MODEL_ALIASES, ModelSwitch, ResolveModelSwitchOpts, modelShortLabel, resolveModelAlias, resolveModelSwitch } from './models.js';
|
|
4
4
|
import { IFilesystem, FileMetadata } from '@livx.cc/wcli/core';
|
|
5
5
|
export { CommandExecutor, FileMetadata, IFilesystem, IndexedDbFilesystem, MemFilesystem, registerHeadlessCommands } from '@livx.cc/wcli/core';
|
package/dist/index.js
CHANGED
|
@@ -3947,6 +3947,10 @@ var AgentOptions = class {
|
|
|
3947
3947
|
* not prose: a named tool with zero invocations is provable. On detection the loop nudges ONCE for a real
|
|
3948
3948
|
* call, and records the names in `RunResult.fabricatedToolClaims` either way. */
|
|
3949
3949
|
catchFabricatedToolUse = true;
|
|
3950
|
+
/** An empty model turn (no text, no tools) that ends the loop after work is re-prompted ONCE, then finishes
|
|
3951
|
+
* as `finishReason:'empty'` (a failure) instead of a phantom 'stop'. Off for layers that deliberately
|
|
3952
|
+
* allow a silent turn and repair it themselves (the duplex voice reflex). */
|
|
3953
|
+
failEmptyTurns = true;
|
|
3950
3954
|
/** Fold the dropped middle of an over-long transcript into a synthetic summary (edge-safe, no LLM). Off => drop-oldest. */
|
|
3951
3955
|
compaction;
|
|
3952
3956
|
/** Add `Checkpoint`/`Rollback` tools (requires the fs to be an OverlayFilesystem). */
|
|
@@ -4020,6 +4024,14 @@ var Agent = class _Agent {
|
|
|
4020
4024
|
/** Per-run ground truth: every tool name actually INVOKED this run (native dispatch + delegated
|
|
4021
4025
|
* runtime activity). The ledger that makes a fabricated tool claim provable. Reset per run. */
|
|
4022
4026
|
invokedTools = /* @__PURE__ */ new Set();
|
|
4027
|
+
/** Delegated-runtime HOST tools currently executing (cursor toolExecutor). While > 0 the provider is
|
|
4028
|
+
* not silent — it is waiting on US — so the idle-stall watchdog must not fire (see armStallWatchdog). */
|
|
4029
|
+
hostToolsInFlight = 0;
|
|
4030
|
+
/** The hold is bounded by the transport tool deadline: a host tool that never settles (the helper already gave
|
|
4031
|
+
* up on it) must not disable stall protection for the rest of the request — or this instance. */
|
|
4032
|
+
hostToolHoldUntil = 0;
|
|
4033
|
+
/** Resets the active request's stall timer; a host tool's completion restarts the model's idle window. */
|
|
4034
|
+
stallPoke;
|
|
4023
4035
|
/** Advertised tools this run's text claimed to have used while the ledger showed zero calls. */
|
|
4024
4036
|
fabricatedClaims = /* @__PURE__ */ new Set();
|
|
4025
4037
|
activeHooks;
|
|
@@ -4322,6 +4334,7 @@ var Agent = class _Agent {
|
|
|
4322
4334
|
let toolCallsTotal = 0;
|
|
4323
4335
|
let lastFp = "";
|
|
4324
4336
|
let repeats = 0;
|
|
4337
|
+
let emptyNudged = false;
|
|
4325
4338
|
let closureNudged = false;
|
|
4326
4339
|
let lastProgressAt = start;
|
|
4327
4340
|
const kill = (finishReason) => {
|
|
@@ -4330,12 +4343,13 @@ var Agent = class _Agent {
|
|
|
4330
4343
|
const claims = this.survivingClaims();
|
|
4331
4344
|
return { text: lastAssistantText(this.transcript), steps, finishReason, messages: this.transcript, usage, usageEstimated, ...claims.length ? { fabricatedToolClaims: claims } : {} };
|
|
4332
4345
|
};
|
|
4346
|
+
const overBudget = () => !!o.maxTokens && usage.totalTokens - 0.9 * usage.cacheReadTokens >= o.maxTokens;
|
|
4347
|
+
const canNudge = () => steps < o.maxSteps && !overBudget();
|
|
4333
4348
|
while (true) {
|
|
4334
4349
|
if (o.signal?.aborted) return kill("aborted");
|
|
4335
4350
|
if (steps >= o.maxSteps) return kill("max_steps");
|
|
4336
4351
|
if (o.timeoutMs && Date.now() - lastProgressAt - this.parkedMs >= o.timeoutMs) return kill("timeout");
|
|
4337
|
-
|
|
4338
|
-
if (o.maxTokens && budgetTokens >= o.maxTokens) return kill("budget");
|
|
4352
|
+
if (overBudget()) return kill("budget");
|
|
4339
4353
|
steps++;
|
|
4340
4354
|
this.options.host?.notify?.({ kind: "turn_start", message: `step ${steps}` });
|
|
4341
4355
|
let res;
|
|
@@ -4356,7 +4370,14 @@ var Agent = class _Agent {
|
|
|
4356
4370
|
toolTimeoutMs: effectiveToolTimeoutMs,
|
|
4357
4371
|
toolExecutor: async (name, args) => {
|
|
4358
4372
|
const tc = { id: `cursor-${Date.now()}`, type: "function", function: { name, arguments: JSON.stringify(args) } };
|
|
4359
|
-
|
|
4373
|
+
this.hostToolsInFlight++;
|
|
4374
|
+
this.hostToolHoldUntil = Math.max(this.hostToolHoldUntil, Date.now() + effectiveToolTimeoutMs);
|
|
4375
|
+
try {
|
|
4376
|
+
return await this.dispatch(tc);
|
|
4377
|
+
} finally {
|
|
4378
|
+
this.hostToolsInFlight--;
|
|
4379
|
+
this.stallPoke?.();
|
|
4380
|
+
}
|
|
4360
4381
|
}
|
|
4361
4382
|
} : void 0;
|
|
4362
4383
|
const claudeSteerPo = o.model.startsWith("claude-code/") ? { steer: () => this.drainPendingSteers() } : void 0;
|
|
@@ -4477,9 +4498,22 @@ var Agent = class _Agent {
|
|
|
4477
4498
|
}
|
|
4478
4499
|
if (toolCalls.length === 0) {
|
|
4479
4500
|
if (this.drainInjections()) continue;
|
|
4501
|
+
if (emptyTurn && o.failEmptyTurns) {
|
|
4502
|
+
if (!emptyNudged && canNudge()) {
|
|
4503
|
+
emptyNudged = true;
|
|
4504
|
+
log6.warn(`empty model turn after tool work (step ${steps}, provider finishReason=${res.finishReason ?? "n/a"}) \u2014 nudging once`);
|
|
4505
|
+
this.transcript.push({ role: "user", content: "Continue \u2014 you returned nothing. Answer the user now using the tool results above, or keep working if you are not done." });
|
|
4506
|
+
continue;
|
|
4507
|
+
}
|
|
4508
|
+
log6.warn(`model returned empty turns after tool work \u2014 surfacing as failed`);
|
|
4509
|
+
const e = new Error("empty_response: model returned an empty turn (no text, no tools) after a re-prompt");
|
|
4510
|
+
e.code = "empty";
|
|
4511
|
+
return { text: "", steps, finishReason: "empty", ...res.finishReason ? { providerFinishReason: res.finishReason } : {}, messages: this.transcript, usage, usageEstimated, error: e };
|
|
4512
|
+
}
|
|
4480
4513
|
const fabricated = o.catchFabricatedToolUse && !closureNudged ? this.fabricatedToolNames(contentText(res.content ?? "")) : [];
|
|
4481
4514
|
for (const n of fabricated) this.fabricatedClaims.add(n);
|
|
4482
|
-
if (fabricated.length &&
|
|
4515
|
+
if (fabricated.length && !canNudge()) log6.warn(`fabricated tool use: text names ${fabricated.join(", ")} but no step/budget left to demand the call \u2014 finishing with the existing answer`);
|
|
4516
|
+
if (fabricated.length && canNudge()) {
|
|
4483
4517
|
closureNudged = true;
|
|
4484
4518
|
log6.warn(`fabricated tool use: text names ${fabricated.join(", ")} but the run invoked ${this.invokedTools.size ? [...this.invokedTools].join(", ") : "nothing"} \u2014 demanding the real call`);
|
|
4485
4519
|
this.transcript.push({
|
|
@@ -4488,7 +4522,7 @@ var Agent = class _Agent {
|
|
|
4488
4522
|
});
|
|
4489
4523
|
continue;
|
|
4490
4524
|
}
|
|
4491
|
-
if (o.closeDelegatedTurns && res.endedWithoutClosing && !closureNudged &&
|
|
4525
|
+
if (o.closeDelegatedTurns && res.endedWithoutClosing && !closureNudged && canNudge()) {
|
|
4492
4526
|
closureNudged = true;
|
|
4493
4527
|
log6.verbose("delegated turn went silent after a tool \u2014 nudging a closing answer");
|
|
4494
4528
|
this.transcript.push({
|
|
@@ -4502,7 +4536,7 @@ var Agent = class _Agent {
|
|
|
4502
4536
|
this.releaseStaleImages();
|
|
4503
4537
|
await this.activeHooks?.onStop?.(res.content ?? "");
|
|
4504
4538
|
const claims = this.survivingClaims();
|
|
4505
|
-
return { text: res.content ?? "", steps, finishReason: "stop", messages: this.transcript, usage, usageEstimated, ...claims.length ? { fabricatedToolClaims: claims } : {} };
|
|
4539
|
+
return { text: res.content ?? "", steps, finishReason: "stop", ...res.finishReason ? { providerFinishReason: res.finishReason } : {}, messages: this.transcript, usage, usageEstimated, ...claims.length ? { fabricatedToolClaims: claims } : {} };
|
|
4506
4540
|
}
|
|
4507
4541
|
const fp = toolCalls.map((tc) => tc.function.name + ":" + (tc.function.arguments ?? "")).join("|");
|
|
4508
4542
|
repeats = fp === lastFp ? repeats + 1 : 1;
|
|
@@ -4566,10 +4600,12 @@ var Agent = class _Agent {
|
|
|
4566
4600
|
if (!stallMs) return;
|
|
4567
4601
|
if (timer) clearTimeout(timer);
|
|
4568
4602
|
timer = setTimeout(() => {
|
|
4603
|
+
if (this.hostToolsInFlight > 0 && Date.now() < this.hostToolHoldUntil) return poke();
|
|
4569
4604
|
fired = true;
|
|
4570
4605
|
ac.abort(stallError());
|
|
4571
4606
|
}, stallMs);
|
|
4572
4607
|
};
|
|
4608
|
+
this.stallPoke = poke;
|
|
4573
4609
|
poke();
|
|
4574
4610
|
const stalled = () => fired && !parent?.aborted;
|
|
4575
4611
|
return {
|
|
@@ -4578,6 +4614,7 @@ var Agent = class _Agent {
|
|
|
4578
4614
|
stalled,
|
|
4579
4615
|
clear: () => {
|
|
4580
4616
|
if (timer) clearTimeout(timer);
|
|
4617
|
+
if (this.stallPoke === poke) this.stallPoke = void 0;
|
|
4581
4618
|
parent?.removeEventListener("abort", onParentAbort);
|
|
4582
4619
|
},
|
|
4583
4620
|
reclassify: (err) => stalled() ? stallError() : err
|
|
@@ -4673,8 +4710,9 @@ var Agent = class _Agent {
|
|
|
4673
4710
|
*/
|
|
4674
4711
|
fabricatedToolNames(text) {
|
|
4675
4712
|
const out = [];
|
|
4713
|
+
const invoked = new Set([...this.invokedTools].map(toolKey));
|
|
4676
4714
|
for (const t of this.activeTools) {
|
|
4677
|
-
if (
|
|
4715
|
+
if (invoked.has(toolKey(t.name))) continue;
|
|
4678
4716
|
if (t.name.length < 4 || !/[_\-A-Z]/.test(t.name)) continue;
|
|
4679
4717
|
const re = new RegExp(`(?:^|[^\\w])${t.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?:[^\\w]|$)`);
|
|
4680
4718
|
if (re.test(text)) out.push(t.name);
|
|
@@ -4687,7 +4725,8 @@ var Agent = class _Agent {
|
|
|
4687
4725
|
* call that demonstrably ran. See `RunResult.fabricatedToolClaims`. */
|
|
4688
4726
|
survivingClaims() {
|
|
4689
4727
|
if (!this.fabricatedClaims.size) return [];
|
|
4690
|
-
|
|
4728
|
+
const invoked = new Set([...this.invokedTools].map(toolKey));
|
|
4729
|
+
return [...this.fabricatedClaims].filter((n) => !invoked.has(toolKey(n)));
|
|
4691
4730
|
}
|
|
4692
4731
|
async dispatch(tc) {
|
|
4693
4732
|
this.invokedTools.add(tc.function.name);
|
|
@@ -5075,6 +5114,11 @@ function lastAssistantText(messages) {
|
|
|
5075
5114
|
}
|
|
5076
5115
|
return "";
|
|
5077
5116
|
}
|
|
5117
|
+
var TOOL_ALIASES = { bash: "shell" };
|
|
5118
|
+
function toolKey(name) {
|
|
5119
|
+
const k = name.toLowerCase();
|
|
5120
|
+
return TOOL_ALIASES[k] ?? k;
|
|
5121
|
+
}
|
|
5078
5122
|
|
|
5079
5123
|
// src/index.ts
|
|
5080
5124
|
init_NodeDiskFilesystem();
|
|
@@ -7843,6 +7887,8 @@ ${nowLine()}. Anchor every relative or time-sensitive reference \u2014 "today",
|
|
|
7843
7887
|
instructionFiles: false,
|
|
7844
7888
|
maxSteps: 8,
|
|
7845
7889
|
timeoutMs: 3e4,
|
|
7890
|
+
failEmptyTurns: false,
|
|
7891
|
+
// a silent reflex turn after a dispatch is legitimate — the voice layer repairs it
|
|
7846
7892
|
...o.reflexOptions,
|
|
7847
7893
|
tools,
|
|
7848
7894
|
// Composed AFTER the spread so the dispatch guard can't be dropped by reflexOptions.
|