@proagentstore/cli 0.4.15 → 0.4.17
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.
|
@@ -63,16 +63,21 @@ export class HeadlessSession {
|
|
|
63
63
|
// that keeps refreshing lastOutputAt). The user can also Restart from diagnostics.
|
|
64
64
|
// Rule 1 deliberately waits for first output so a slow first token can't flip us
|
|
65
65
|
// to idle mid-turn (which would make the brain proceed against a half-done turn).
|
|
66
|
+
//
|
|
67
|
+
// This is derived PURELY from timers each call — it does NOT latch `this.run` to
|
|
68
|
+
// "idle". Latching was a one-way trap: once a >1.5s pause (slow compile / test run /
|
|
69
|
+
// network) flipped us idle, resumed output couldn't restore "thinking" (onStdout only
|
|
70
|
+
// bumps lastOutputAt), so the brain proceeded against a still-running turn and
|
|
71
|
+
// double-sent or falsely called done. Recomputing means fresh output → quiet resets →
|
|
72
|
+
// "thinking" again, all on its own.
|
|
66
73
|
if (this.mode === "raw" && this.run === "thinking") {
|
|
67
74
|
const now = Date.now();
|
|
68
75
|
const quiet = now - this.lastOutputAt;
|
|
69
76
|
const elapsed = now - this.turnStartedAt;
|
|
70
|
-
|
|
71
|
-
this.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
else if (elapsed > 15 * 60 * 1000)
|
|
75
|
-
this.run = "idle";
|
|
77
|
+
const settled = (this.sawOutputSinceInput && quiet > 1500) ||
|
|
78
|
+
(!this.sawOutputSinceInput && elapsed > 8000) ||
|
|
79
|
+
elapsed > 15 * 60 * 1000;
|
|
80
|
+
return settled ? "idle" : "thinking";
|
|
76
81
|
}
|
|
77
82
|
return this.run === "thinking" ? "thinking" : "idle";
|
|
78
83
|
}
|
|
@@ -1045,6 +1045,13 @@ export class LocalRunner {
|
|
|
1045
1045
|
// "running" — report failure so the console can say "session expired, re-run".
|
|
1046
1046
|
if (!session)
|
|
1047
1047
|
return { ok: false };
|
|
1048
|
+
// Reject an empty value: browserHandoffStatus reports needs_input as solved only when
|
|
1049
|
+
// inputValue is a real string, so accepting "" would flip the task to "running" yet
|
|
1050
|
+
// never resolve → the workflow polls until it times out (15-min wedge, "failed").
|
|
1051
|
+
// Report failure so the caller (API/MCP) learns it wasn't accepted, like the
|
|
1052
|
+
// no-session branch. (The console already blocks empty; this closes the API path.)
|
|
1053
|
+
if (!value || !value.trim())
|
|
1054
|
+
return { ok: false };
|
|
1048
1055
|
session.inputValue = value;
|
|
1049
1056
|
const task = this.store.getTask(taskId);
|
|
1050
1057
|
if (task) {
|
package/dist/index.js
CHANGED
|
@@ -854,6 +854,10 @@ function openRelaySocket(instanceId, wsBase, mintToken, localUrl, runnerToken, f
|
|
|
854
854
|
relayToken = await mintToken();
|
|
855
855
|
} catch (e) {
|
|
856
856
|
const msg = e instanceof Error ? e.message : String(e);
|
|
857
|
+
if (/^402\b/.test(msg)) {
|
|
858
|
+
writeLine(`Runner unavailable for ${instanceId.slice(0, 8)}\u2026: ${msg.replace(/^402\s*/, "")}`);
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
857
861
|
const hint = /401|token|sign/i.test(msg) ? " (run `pags login`)" : "";
|
|
858
862
|
writeLine(`Relay token mint failed: ${instanceId.slice(0, 8)}\u2026${hint} \u2014 retrying in ${Math.round(backoffMs / 1e3)}s`);
|
|
859
863
|
setTimeout(() => {
|