@4pm/cli 1.19.0 → 1.19.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/dist/index.js +32 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -38032,6 +38032,9 @@ var OutputBatcher = class {
|
|
|
38032
38032
|
flushIntervalMs: 200,
|
|
38033
38033
|
flushSizeKb: 64,
|
|
38034
38034
|
maxBufferKb: 512,
|
|
38035
|
+
// Well under the cli-server WS maxPayload (8 MiB — ADR-0322) even after the enveloped frame's
|
|
38036
|
+
// AES-256-GCM + base64 + JSON inflation (~1.37×), and small enough to keep SSE replay chunks light.
|
|
38037
|
+
maxFrameKb: 256,
|
|
38035
38038
|
overflow: "backpressure",
|
|
38036
38039
|
...options
|
|
38037
38040
|
};
|
|
@@ -38062,7 +38065,9 @@ var OutputBatcher = class {
|
|
|
38062
38065
|
}
|
|
38063
38066
|
}
|
|
38064
38067
|
/**
|
|
38065
|
-
* Flush the
|
|
38068
|
+
* Flush the current buffer immediately, splitting it into frames no larger than `maxFrameKb`
|
|
38069
|
+
* (ADR-0322) so a single large burst never produces one over-`maxPayload` WS frame. The
|
|
38070
|
+
* `truncated` flag is carried on the last frame only.
|
|
38066
38071
|
*/
|
|
38067
38072
|
flush() {
|
|
38068
38073
|
if (this.timer) {
|
|
@@ -38070,7 +38075,7 @@ var OutputBatcher = class {
|
|
|
38070
38075
|
this.timer = null;
|
|
38071
38076
|
}
|
|
38072
38077
|
if (this.buffer.length === 0 && !this.truncated) return;
|
|
38073
|
-
const
|
|
38078
|
+
const buf = this.buffer;
|
|
38074
38079
|
const truncated = this.truncated;
|
|
38075
38080
|
this.buffer = "";
|
|
38076
38081
|
this.truncated = false;
|
|
@@ -38078,7 +38083,16 @@ var OutputBatcher = class {
|
|
|
38078
38083
|
this.paused = false;
|
|
38079
38084
|
this.opts.onPressure?.(false);
|
|
38080
38085
|
}
|
|
38081
|
-
this.opts.
|
|
38086
|
+
const max = this.opts.maxFrameKb * 1024;
|
|
38087
|
+
if (buf.length <= max) {
|
|
38088
|
+
this.opts.onFlush(buf, truncated);
|
|
38089
|
+
return;
|
|
38090
|
+
}
|
|
38091
|
+
for (let i = 0; i < buf.length; i += max) {
|
|
38092
|
+
const slice = buf.slice(i, i + max);
|
|
38093
|
+
const isLast = i + max >= buf.length;
|
|
38094
|
+
this.opts.onFlush(slice, isLast && truncated);
|
|
38095
|
+
}
|
|
38082
38096
|
}
|
|
38083
38097
|
};
|
|
38084
38098
|
|
|
@@ -39500,6 +39514,13 @@ function appendCommandOutput(commandId, text) {
|
|
|
39500
39514
|
} catch {
|
|
39501
39515
|
}
|
|
39502
39516
|
}
|
|
39517
|
+
function resetCommandOutput(commandId) {
|
|
39518
|
+
if (!dir) return;
|
|
39519
|
+
try {
|
|
39520
|
+
rmSync4(join13(dir, `${commandId}.log`), { force: true });
|
|
39521
|
+
} catch {
|
|
39522
|
+
}
|
|
39523
|
+
}
|
|
39503
39524
|
function readCommandOutput(commandId) {
|
|
39504
39525
|
if (!dir) return null;
|
|
39505
39526
|
const path = join13(dir, `${commandId}.log`);
|
|
@@ -40465,6 +40486,7 @@ async function runCommand(dispatch, emit, opts) {
|
|
|
40465
40486
|
}
|
|
40466
40487
|
|
|
40467
40488
|
// src/core/ai-runner.ts
|
|
40489
|
+
var TIMEOUT_EXIT = 124;
|
|
40468
40490
|
function isAuthFailure(text) {
|
|
40469
40491
|
return /\b401\b|invalid authentication|authentication credentials|oauth[^]*revoked|not authenticated|please run.*login/i.test(
|
|
40470
40492
|
text
|
|
@@ -40532,7 +40554,7 @@ async function runAiFailover(plan, commandId, cwd2, handlers, timeoutMs = 0) {
|
|
|
40532
40554
|
};
|
|
40533
40555
|
}
|
|
40534
40556
|
if (finalExit === 0 && apiErr.isError) finalExit = apiErr.status && apiErr.status > 0 ? apiErr.status : 1;
|
|
40535
|
-
const reason = isAuthFailure(captured) ? "auth" : apiErr.status === 429 || isOutOfCredits(captured) ? "credits" : isSessionLimit(captured) ? "limit" : "other";
|
|
40557
|
+
const reason = finalExit === TIMEOUT_EXIT ? "timeout" : isAuthFailure(captured) ? "auth" : apiErr.status === 429 || isOutOfCredits(captured) ? "credits" : isSessionLimit(captured) ? "limit" : "other";
|
|
40536
40558
|
if (i === total - 1) break;
|
|
40537
40559
|
handlers.onAttemptFail(attempt.label, reason);
|
|
40538
40560
|
}
|
|
@@ -41280,13 +41302,18 @@ ${guardedPrompt}`;
|
|
|
41280
41302
|
}
|
|
41281
41303
|
},
|
|
41282
41304
|
onAttemptStart: (label, index, total, cmd2) => {
|
|
41305
|
+
if (index > 0) {
|
|
41306
|
+
answerText = "";
|
|
41307
|
+
resetCommandOutput(commandId);
|
|
41308
|
+
ctx.send(WsChannels.COMMAND_OUTPUT, { commandId, seq: seq++, chunk: "", reset: true });
|
|
41309
|
+
}
|
|
41283
41310
|
const text = `\u2192 trying ${cmd2} profile "${label}" (${index + 1}/${total})\u2026`;
|
|
41284
41311
|
ctx.bus.push({ source: origin, kind: "log", text });
|
|
41285
41312
|
ctx.send(WsChannels.COMMAND_OUTPUT, { commandId, seq: seq++, chunk: `${text}
|
|
41286
41313
|
`, log: true });
|
|
41287
41314
|
},
|
|
41288
41315
|
onAttemptFail: (label, reason) => {
|
|
41289
|
-
const text = reason === "limit" ? `profile "${label}" hit its session limit \u2014 trying next` : reason === "credits" ? `profile "${label}" is out of usage credits \u2014 trying next` : reason === "auth" ? `profile "${label}" failed to authenticate \u2014 trying next` : `profile "${label}" run failed \u2014 trying next`;
|
|
41316
|
+
const text = reason === "limit" ? `profile "${label}" hit its session limit \u2014 trying next` : reason === "credits" ? `profile "${label}" is out of usage credits \u2014 trying next` : reason === "auth" ? `profile "${label}" failed to authenticate \u2014 trying next` : reason === "timeout" ? `profile "${label}" timed out \u2014 trying next` : `profile "${label}" run failed \u2014 trying next`;
|
|
41290
41317
|
ctx.bus.push({ source: origin, kind: "log", text, level: "warn" });
|
|
41291
41318
|
ctx.send(WsChannels.COMMAND_OUTPUT, { commandId, seq: seq++, chunk: `${text}
|
|
41292
41319
|
`, log: true });
|