vigthoria-cli 1.11.43 → 1.11.44
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/commands/chat.js +19 -12
- package/dist/utils/api.js +27 -15
- package/package.json +1 -1
package/dist/commands/chat.js
CHANGED
|
@@ -22,21 +22,28 @@ import { inferAgentTaskType as sharedInferAgentTaskType, inferAgentTaskTypeWithC
|
|
|
22
22
|
import { resolveAgentRoute } from '../utils/agentRoute.js';
|
|
23
23
|
import { runTemplateInstantPath } from '../utils/templateInstantPath.js';
|
|
24
24
|
import { isV3StreamKeepaliveEvent } from '../utils/v3-stream-events.js';
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
//
|
|
25
|
+
// Stream health policy (corrected 2026-07-04 after TestFarm incident with
|
|
26
|
+
// Gideon Lenz / C:\vigthoria\Apps\monopoly): agentic tasks have no
|
|
27
|
+
// predictable duration, so there is intentionally NO overall wall-clock
|
|
28
|
+
// timeout -- DEFAULT_V3_AGENT_TIMEOUT_MS stays disabled (0) by default and
|
|
29
|
+
// must never kill an actively-streaming request just because it's "taking
|
|
30
|
+
// long". The only legitimate failure signal for SSE/chunked streams is
|
|
31
|
+
// silence: DEFAULT_V3_AGENT_IDLE_TIMEOUT_MS aborts only when zero bytes
|
|
32
|
+
// arrive for a stretch, which is what "the model/agent has gone dark"
|
|
33
|
+
// actually looks like on the wire.
|
|
33
34
|
const DEFAULT_V3_AGENT_TIMEOUT_MS = (() => {
|
|
35
|
+
// Agentic tasks are open-ended by design — a build/refactor/analysis can
|
|
36
|
+
// legitimately take minutes or hours depending on scope. There must be NO
|
|
37
|
+
// overall wall-clock cap that kills an actively-streaming, healthy request.
|
|
38
|
+
// The only correct failure signal for SSE/streamed responses is silence:
|
|
39
|
+
// see DEFAULT_V3_AGENT_IDLE_TIMEOUT_MS below, which aborts only when zero
|
|
40
|
+
// bytes arrive for a stretch — never based on total elapsed duration.
|
|
34
41
|
const rawValue = process.env.VIGTHORIA_AGENT_TIMEOUT_MS || process.env.V3_AGENT_TIMEOUT_MS;
|
|
35
42
|
if (!rawValue) {
|
|
36
|
-
return
|
|
43
|
+
return 0; // disabled — no overall duration cap
|
|
37
44
|
}
|
|
38
45
|
const parsed = Number.parseInt(rawValue, 10);
|
|
39
|
-
return Number.isFinite(parsed) && parsed >= 0 ? parsed :
|
|
46
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
40
47
|
})();
|
|
41
48
|
const DEFAULT_V3_AGENT_IDLE_TIMEOUT_MS = (() => {
|
|
42
49
|
const rawValue = process.env.VIGTHORIA_AGENT_IDLE_TIMEOUT_MS || process.env.V3_AGENT_IDLE_TIMEOUT_MS;
|
|
@@ -880,9 +887,9 @@ export class ChatCommand {
|
|
|
880
887
|
}
|
|
881
888
|
const seconds = Math.round(idleMs / 1000);
|
|
882
889
|
const idleTimeoutSec = Math.round(DEFAULT_V3_AGENT_IDLE_TIMEOUT_MS / 1000);
|
|
883
|
-
process.stderr.write(chalk.yellow(` [Wait] Model still working (${seconds}s) —
|
|
890
|
+
process.stderr.write(chalk.yellow(` [Wait] Model still working (${seconds}s) — this can legitimately take a while for large tasks. ` +
|
|
884
891
|
(idleTimeoutSec > 0
|
|
885
|
-
? `
|
|
892
|
+
? `Only complete silence (~${idleTimeoutSec}s with zero bytes received) will trigger an auto-recover/retry — active progress is never interrupted.\n`
|
|
886
893
|
: `\n`)));
|
|
887
894
|
spinner.start();
|
|
888
895
|
spinner.text = 'Waiting for model response...';
|
package/dist/utils/api.js
CHANGED
|
@@ -260,17 +260,24 @@ export function propagateError(err) {
|
|
|
260
260
|
},
|
|
261
261
|
};
|
|
262
262
|
}
|
|
263
|
-
//
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
//
|
|
263
|
+
// Stream health policy — see matching comment in src/commands/chat.ts.
|
|
264
|
+
// No overall wall-clock timeout for agentic requests (duration is
|
|
265
|
+
// unpredictable and must never kill a healthy, actively-streaming request).
|
|
266
|
+
// Only silence (zero bytes for a stretch, see DEFAULT_V3_AGENT_IDLE_TIMEOUT_MS)
|
|
267
|
+
// is a legitimate failure signal for SSE/chunked streams.
|
|
267
268
|
const DEFAULT_V3_AGENT_TIMEOUT_MS = (() => {
|
|
269
|
+
// Agentic tasks are open-ended by design — a build/refactor/analysis can
|
|
270
|
+
// legitimately take minutes or hours depending on scope. There must be NO
|
|
271
|
+
// overall wall-clock cap that kills an actively-streaming, healthy request.
|
|
272
|
+
// The only correct failure signal for SSE/streamed responses is silence:
|
|
273
|
+
// see DEFAULT_V3_AGENT_IDLE_TIMEOUT_MS below, which aborts only when zero
|
|
274
|
+
// bytes arrive for a stretch — never based on total elapsed duration.
|
|
268
275
|
const rawValue = process.env.VIGTHORIA_AGENT_TIMEOUT_MS || process.env.V3_AGENT_TIMEOUT_MS;
|
|
269
276
|
if (!rawValue) {
|
|
270
|
-
return
|
|
277
|
+
return 0; // disabled — no overall duration cap
|
|
271
278
|
}
|
|
272
279
|
const parsed = Number.parseInt(rawValue, 10);
|
|
273
|
-
return Number.isFinite(parsed) && parsed >= 0 ? parsed :
|
|
280
|
+
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
274
281
|
})();
|
|
275
282
|
const DEFAULT_V3_AGENT_IDLE_TIMEOUT_MS = (() => {
|
|
276
283
|
const rawValue = process.env.VIGTHORIA_AGENT_IDLE_TIMEOUT_MS || process.env.V3_AGENT_IDLE_TIMEOUT_MS;
|
|
@@ -3825,14 +3832,18 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
3825
3832
|
else {
|
|
3826
3833
|
chunk = await new Promise((resolve, reject) => {
|
|
3827
3834
|
let idleTimer = null;
|
|
3828
|
-
//
|
|
3829
|
-
//
|
|
3830
|
-
//
|
|
3831
|
-
//
|
|
3832
|
-
//
|
|
3833
|
-
//
|
|
3835
|
+
// Idle/silence detection (NOT a task-duration timeout): this timer
|
|
3836
|
+
// only ever fires after idleTimeoutMs with ZERO new bytes on the
|
|
3837
|
+
// wire. What we do next depends on WHY it's silent:
|
|
3838
|
+
// - A client-side tool is genuinely still running (e.g. a local
|
|
3839
|
+
// build/install the CLI itself launched) -- its own duration is
|
|
3840
|
+
// unpredictable by design, so we reschedule indefinitely; this
|
|
3841
|
+
// is known, bounded-elsewhere work, not "the agent went dark".
|
|
3842
|
+
// - Otherwise, silence really does mean nothing is coming from
|
|
3843
|
+
// the agent, so after a generous grace window we recover
|
|
3844
|
+
// (if the workspace already has output) or fail cleanly.
|
|
3834
3845
|
let idleRescheduleCount = 0;
|
|
3835
|
-
const maxIdleReschedules =
|
|
3846
|
+
const maxIdleReschedules = 20; // ~20 min of genuine zero-byte silence
|
|
3836
3847
|
const clearIdleTimer = () => {
|
|
3837
3848
|
if (idleTimer) {
|
|
3838
3849
|
clearTimeout(idleTimer);
|
|
@@ -3842,8 +3853,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|
|
3842
3853
|
const scheduleIdleTimer = () => {
|
|
3843
3854
|
clearIdleTimer();
|
|
3844
3855
|
idleTimer = setTimeout(() => {
|
|
3845
|
-
if (this.pendingV3ClientToolTasks.size > 0
|
|
3846
|
-
|
|
3856
|
+
if (this.pendingV3ClientToolTasks.size > 0) {
|
|
3857
|
+
// Known local work in progress -- never cap this, its own
|
|
3858
|
+
// completion will produce the next chunk/event.
|
|
3847
3859
|
scheduleIdleTimer();
|
|
3848
3860
|
return;
|
|
3849
3861
|
}
|