@livx.cc/agentx 0.99.17 → 0.99.19
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-BfQS-MfB.d.ts → Agent-Cn9BxS8h.d.ts} +12 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +96 -16
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +64 -6
- 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, h as RunResult, A as Agent } from './Agent-
|
|
2
|
-
export { C as ChatFragment, D as DEFAULT_MUTATING, b as Decision, P as PermissionOptions, c as PermissionPolicy, d as PermissionRule, e as PreToolUseDecision, R as ReasoningEffort, f as RecordingHooks, g as RecordingLifecycle, T as ToolUse, i as ToolUseMeta, j as composeHooks, p as planMode, r as reasoningToChatFragment } from './Agent-
|
|
1
|
+
import { a as AgentOptions, H as Hooks, h as RunResult, A as Agent } from './Agent-Cn9BxS8h.js';
|
|
2
|
+
export { C as ChatFragment, D as DEFAULT_MUTATING, b as Decision, P as PermissionOptions, c as PermissionPolicy, d as PermissionRule, e as PreToolUseDecision, R as ReasoningEffort, f as RecordingHooks, g as RecordingLifecycle, T as ToolUse, i as ToolUseMeta, j as composeHooks, p as planMode, r as reasoningToChatFragment } from './Agent-Cn9BxS8h.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
|
@@ -3181,6 +3181,10 @@ var AgentOptions = class {
|
|
|
3181
3181
|
maxTokens = 2e5;
|
|
3182
3182
|
/** Wall-clock ceiling in ms for the whole run. 0 = unbounded. */
|
|
3183
3183
|
timeoutMs = 12e4;
|
|
3184
|
+
/** Idle-stall watchdog for a SINGLE streamed model request: abort it if no chunk (text OR reasoning)
|
|
3185
|
+
* arrives for this long. The between-steps `timeoutMs` can't preempt an in-flight `chat()`, so a
|
|
3186
|
+
* provider that goes silent mid-stream would otherwise park the loop forever. 0 = off. */
|
|
3187
|
+
stallMs = 6e4;
|
|
3184
3188
|
/** Stop if the identical tool-call batch (name+args) repeats this many times in a row. 0 = off. */
|
|
3185
3189
|
maxRepeats = 3;
|
|
3186
3190
|
/** Cumulative cap on tool calls dispatched across the run. 0 = unbounded. */
|
|
@@ -3613,8 +3617,15 @@ var Agent = class _Agent {
|
|
|
3613
3617
|
for (let attempt = 0; ; attempt++) {
|
|
3614
3618
|
try {
|
|
3615
3619
|
if (useStream) {
|
|
3616
|
-
const
|
|
3617
|
-
|
|
3620
|
+
const stall = this.armStallWatchdog(o.signal, o.stallMs);
|
|
3621
|
+
try {
|
|
3622
|
+
const r = await o.ai.chat({ model: o.model, messages: sent, tools: sentTools, stream: true, signal: stall.signal, ...o.toolChoice ? { toolChoice: o.toolChoice } : {}, ...reasonOpts });
|
|
3623
|
+
res = await this.consumeStream(r, stall.poke);
|
|
3624
|
+
} catch (err) {
|
|
3625
|
+
throw stall.reclassify(err);
|
|
3626
|
+
} finally {
|
|
3627
|
+
stall.clear();
|
|
3628
|
+
}
|
|
3618
3629
|
} else {
|
|
3619
3630
|
const r = await o.ai.chat({ model: o.model, messages: sent, tools: sentTools, stream: false, signal: o.signal, ...o.toolChoice ? { toolChoice: o.toolChoice } : {}, ...reasonOpts });
|
|
3620
3631
|
res = r;
|
|
@@ -3624,16 +3635,21 @@ var Agent = class _Agent {
|
|
|
3624
3635
|
const sc = err?.statusCode;
|
|
3625
3636
|
const serverSide = sc >= 500 || sc === 408 || /Service Unavailable|overloaded|Internal server error|Bad gateway|Gateway time/i.test(String(err?.message ?? ""));
|
|
3626
3637
|
const network = !sc && /ECONNRESET|ECONNREFUSED|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|EPIPE|socket hang up|fetch failed|network|terminated|UND_ERR/i.test(String(err?.message ?? err?.code ?? err));
|
|
3627
|
-
const
|
|
3638
|
+
const stalled = err?.code === "stall";
|
|
3639
|
+
const transient = !o.signal?.aborted && !isAbortError(err) && attempt < 2 && (network || serverSide || stalled);
|
|
3628
3640
|
if (!transient) throw err;
|
|
3629
3641
|
const waitMs = 1e3 * (attempt + 1);
|
|
3630
|
-
log4.warn(
|
|
3631
|
-
o.host?.notify?.({ kind: "retry", message:
|
|
3642
|
+
log4.warn(`${stalled ? "model stall" : "network drop"} mid-step (${err?.message ?? err}) \u2014 retrying in ${waitMs}ms`);
|
|
3643
|
+
o.host?.notify?.({ kind: "retry", message: `${stalled ? "model stalled" : "connection dropped"} \u2014 retrying step (#${attempt + 1})` });
|
|
3632
3644
|
await new Promise((r) => setTimeout(r, waitMs));
|
|
3633
3645
|
}
|
|
3634
3646
|
}
|
|
3635
3647
|
} catch (err) {
|
|
3636
3648
|
if (err?.code === "budget") return kill("budget");
|
|
3649
|
+
if (err?.code === "stall") {
|
|
3650
|
+
log4.warn(`model stalled out after retries: ${err?.message ?? err}`);
|
|
3651
|
+
return kill("timeout");
|
|
3652
|
+
}
|
|
3637
3653
|
if (o.signal?.aborted || isAbortError(err)) return kill("aborted");
|
|
3638
3654
|
const body = err?.body ?? err?.response?.data ?? err?.error;
|
|
3639
3655
|
let bodyStr;
|
|
@@ -3704,12 +3720,54 @@ var Agent = class _Agent {
|
|
|
3704
3720
|
* (`{kind:'text_delta'}`) and fold all chunks back into the single
|
|
3705
3721
|
* ChatResponse the non-stream path would have returned.
|
|
3706
3722
|
*/
|
|
3707
|
-
|
|
3723
|
+
/**
|
|
3724
|
+
* Idle-stall watchdog for one streamed model request. Returns a linked AbortController `signal` to
|
|
3725
|
+
* hand to `chat()`, a `poke()` to reset the idle timer on each chunk, a `reclassify()` that turns a
|
|
3726
|
+
* watchdog-fired abort into an Error{code:'stall'} (leaving a parent/user abort untouched), and a
|
|
3727
|
+
* `clear()` to disarm. Aborts the request if no `poke()` (or completion) happens within `stallMs`.
|
|
3728
|
+
* `stallMs = 0` disables the timer but still links parent-abort → child so cancellation propagates.
|
|
3729
|
+
*/
|
|
3730
|
+
armStallWatchdog(parent, stallMs) {
|
|
3731
|
+
const ac = new AbortController();
|
|
3732
|
+
let fired = false;
|
|
3733
|
+
const onParentAbort = () => ac.abort();
|
|
3734
|
+
if (parent?.aborted) ac.abort();
|
|
3735
|
+
else parent?.addEventListener("abort", onParentAbort, { once: true });
|
|
3736
|
+
let timer;
|
|
3737
|
+
const poke = () => {
|
|
3738
|
+
if (!stallMs) return;
|
|
3739
|
+
if (timer) clearTimeout(timer);
|
|
3740
|
+
timer = setTimeout(() => {
|
|
3741
|
+
fired = true;
|
|
3742
|
+
ac.abort();
|
|
3743
|
+
}, stallMs);
|
|
3744
|
+
};
|
|
3745
|
+
poke();
|
|
3746
|
+
return {
|
|
3747
|
+
signal: ac.signal,
|
|
3748
|
+
poke,
|
|
3749
|
+
clear: () => {
|
|
3750
|
+
if (timer) clearTimeout(timer);
|
|
3751
|
+
parent?.removeEventListener("abort", onParentAbort);
|
|
3752
|
+
},
|
|
3753
|
+
// Distinguish OUR abort (silent provider) from a parent/user cancel, which must stay an abort.
|
|
3754
|
+
reclassify: (err) => {
|
|
3755
|
+
if (fired && !parent?.aborted) {
|
|
3756
|
+
const e = new Error(`model stalled: no stream output for ${stallMs >= 1e3 ? `${Math.round(stallMs / 1e3)}s` : `${stallMs}ms`}`);
|
|
3757
|
+
e.code = "stall";
|
|
3758
|
+
return e;
|
|
3759
|
+
}
|
|
3760
|
+
return err;
|
|
3761
|
+
}
|
|
3762
|
+
};
|
|
3763
|
+
}
|
|
3764
|
+
async consumeStream(stream, poke) {
|
|
3708
3765
|
let content = "";
|
|
3709
3766
|
let finishReason;
|
|
3710
3767
|
let toolCalls;
|
|
3711
3768
|
let usage;
|
|
3712
3769
|
for await (const chunk of stream) {
|
|
3770
|
+
poke?.();
|
|
3713
3771
|
if (this.options.signal?.aborted) break;
|
|
3714
3772
|
if (chunk.reasoningContent) this.options.host.notify({ kind: "thinking_delta", message: chunk.reasoningContent });
|
|
3715
3773
|
if (chunk.toolActivity) {
|