@evident-ai/cli 3.0.1-dev.6bbae3a → 3.0.1-dev.7272711
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 +5 -143
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1126,36 +1126,6 @@ async function sessionExists(port, id) {
|
|
|
1126
1126
|
return null;
|
|
1127
1127
|
}
|
|
1128
1128
|
}
|
|
1129
|
-
async function getSessionStatuses(port) {
|
|
1130
|
-
try {
|
|
1131
|
-
const res = await fetch(`${opencodeBase(port)}/session/status`);
|
|
1132
|
-
if (!res.ok) {
|
|
1133
|
-
console.error(
|
|
1134
|
-
`[getSessionStatuses] GET /session/status returned HTTP ${res.status} (port ${port})`
|
|
1135
|
-
);
|
|
1136
|
-
return null;
|
|
1137
|
-
}
|
|
1138
|
-
const body = await res.json();
|
|
1139
|
-
if (body == null || typeof body !== "object" || Array.isArray(body)) {
|
|
1140
|
-
console.error(
|
|
1141
|
-
`[getSessionStatuses] GET /session/status body was not a plain object (port ${port})`
|
|
1142
|
-
);
|
|
1143
|
-
return null;
|
|
1144
|
-
}
|
|
1145
|
-
return body;
|
|
1146
|
-
} catch (err) {
|
|
1147
|
-
console.error(
|
|
1148
|
-
`[getSessionStatuses] GET /session/status failed (port ${port}): ${err instanceof Error ? err.message : String(err)}`
|
|
1149
|
-
);
|
|
1150
|
-
return null;
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
async function isSessionOngoing(port, id) {
|
|
1154
|
-
const map = await getSessionStatuses(port);
|
|
1155
|
-
if (map == null) return null;
|
|
1156
|
-
const entry = map[id];
|
|
1157
|
-
return entry != null && entry.type !== "idle";
|
|
1158
|
-
}
|
|
1159
1129
|
async function createOpenCodeSession(port, directory) {
|
|
1160
1130
|
const url = new URL(`${opencodeBase(port)}/session`);
|
|
1161
1131
|
if (directory && directory.trim()) {
|
|
@@ -1820,7 +1790,6 @@ var DEFAULT_PAUSED_POLL_INTERVAL_MS = 2e3;
|
|
|
1820
1790
|
var DEFAULT_PAUSED_MAX_WAIT_MS = 10 * 60 * 1e3;
|
|
1821
1791
|
var DEFAULT_STUCK_QUEUED_MS = 6e4;
|
|
1822
1792
|
var HEARTBEAT_MS = 6e4;
|
|
1823
|
-
var ABSOLUTE_MAX_PROCESSING_MS = 6 * 60 * 60 * 1e3;
|
|
1824
1793
|
var POLL_MISS_GRACE_MS = HEARTBEAT_MS;
|
|
1825
1794
|
var ChannelAuthError = class extends Error {
|
|
1826
1795
|
constructor(message) {
|
|
@@ -1918,15 +1887,6 @@ var ChannelDriver = class {
|
|
|
1918
1887
|
* the row leaves the processing list, exactly like `dontRedispatch`.
|
|
1919
1888
|
*/
|
|
1920
1889
|
doneUndeliverable = /* @__PURE__ */ new Set();
|
|
1921
|
-
/**
|
|
1922
|
-
* "Already emitted `readopt_poll_unresolved` for this row" (#229). The b1 /
|
|
1923
|
-
* unreadable-status re-evaluate leaf leaves the row UN-tracked so it is re-read
|
|
1924
|
-
* every ~2s drain until the status map becomes readable — but the server-visible
|
|
1925
|
-
* signal is an OUTCOME, so it must fire at most ONCE per row, not once per drain
|
|
1926
|
-
* (Bugbot "Re-adopt signals flood every drain"). Cleared when the row leaves the
|
|
1927
|
-
* processing list, exactly like `dontRedispatch`/`doneUndeliverable`.
|
|
1928
|
-
*/
|
|
1929
|
-
readoptPollUnresolvedSignalled = /* @__PURE__ */ new Set();
|
|
1930
1890
|
/**
|
|
1931
1891
|
* "A null-id re-adopt re-dispatch is in flight, awaiting its read-back" (WI-5
|
|
1932
1892
|
* Task 5.4, High-2). Since we no longer send a caller-supplied id, a re-dispatch
|
|
@@ -2314,7 +2274,6 @@ var ChannelDriver = class {
|
|
|
2314
2274
|
opencodeMessageId,
|
|
2315
2275
|
message,
|
|
2316
2276
|
dispatchedAt: now,
|
|
2317
|
-
processingAnchorMs: now,
|
|
2318
2277
|
deadline: now + this.pausedMaxWaitMs,
|
|
2319
2278
|
started: false,
|
|
2320
2279
|
done: false,
|
|
@@ -2373,10 +2332,6 @@ var ChannelDriver = class {
|
|
|
2373
2332
|
opencodeMessageId,
|
|
2374
2333
|
message,
|
|
2375
2334
|
dispatchedAt: this.now(),
|
|
2376
|
-
// Anchor the absolute-age ceiling to the SERVER-SIDE `processed_at` (the same
|
|
2377
|
-
// value seeding `deadline`), NOT `dispatchedAt` — so a re-adopted zombie's age
|
|
2378
|
-
// reflects the real turn duration and the ceiling fires on the ORIGINAL turn.
|
|
2379
|
-
processingAnchorMs: processedAtMs,
|
|
2380
2335
|
deadline: processedAtMs + this.pausedMaxWaitMs,
|
|
2381
2336
|
// The server row is ALREADY `processing`; do not re-fire markProcessing.
|
|
2382
2337
|
started: true,
|
|
@@ -2665,19 +2620,6 @@ var ChannelDriver = class {
|
|
|
2665
2620
|
});
|
|
2666
2621
|
}
|
|
2667
2622
|
const activelyRunning = state === "running" && !awaitingHuman;
|
|
2668
|
-
if (activelyRunning && this.now() - inFlight.processingAnchorMs >= ABSOLUTE_MAX_PROCESSING_MS) {
|
|
2669
|
-
this.log({
|
|
2670
|
-
level: "error",
|
|
2671
|
-
message: `Message ${inFlight.evidentMessageId.slice(0, 8)} exceeded the absolute processing ceiling (${Math.round((this.now() - inFlight.processingAnchorMs) / 6e4)}min, session ${sessionId}) while still actively running \u2014 releasing so the cron can reclaim it`,
|
|
2672
|
-
conversation_id: conv.id,
|
|
2673
|
-
message_id: inFlight.evidentMessageId
|
|
2674
|
-
});
|
|
2675
|
-
void this.postSignal(conv.id, inFlight.evidentMessageId, "gave_up", {
|
|
2676
|
-
watched_for_ms: this.now() - inFlight.processingAnchorMs
|
|
2677
|
-
});
|
|
2678
|
-
this.removeInFlight(watcher, inFlight.evidentMessageId);
|
|
2679
|
-
return;
|
|
2680
|
-
}
|
|
2681
2623
|
if (activelyRunning && !inFlight.awaitingHumanLatched && !inFlight.aliveInFlight && this.now() - inFlight.lastAliveAt >= HEARTBEAT_MS) {
|
|
2682
2624
|
inFlight.aliveInFlight = true;
|
|
2683
2625
|
void this.postSignal(conv.id, inFlight.evidentMessageId, "alive").then((ok) => {
|
|
@@ -2740,17 +2682,12 @@ var ChannelDriver = class {
|
|
|
2740
2682
|
*/
|
|
2741
2683
|
async readoptProcessing() {
|
|
2742
2684
|
const rows = await this.getProcessingMessages();
|
|
2743
|
-
if (this.dontRedispatch.size > 0 || this.doneUndeliverable.size > 0
|
|
2685
|
+
if (this.dontRedispatch.size > 0 || this.doneUndeliverable.size > 0) {
|
|
2744
2686
|
const stillProcessing = new Set(rows.map((r) => r.id));
|
|
2745
|
-
for (const id of [
|
|
2746
|
-
...this.dontRedispatch,
|
|
2747
|
-
...this.doneUndeliverable,
|
|
2748
|
-
...this.readoptPollUnresolvedSignalled
|
|
2749
|
-
]) {
|
|
2687
|
+
for (const id of [...this.dontRedispatch, ...this.doneUndeliverable]) {
|
|
2750
2688
|
if (!stillProcessing.has(id)) {
|
|
2751
2689
|
const cleared = this.dontRedispatch.delete(id);
|
|
2752
2690
|
const clearedUndeliverable = this.doneUndeliverable.delete(id);
|
|
2753
|
-
this.readoptPollUnresolvedSignalled.delete(id);
|
|
2754
2691
|
if (cleared || clearedUndeliverable) {
|
|
2755
2692
|
this.log({
|
|
2756
2693
|
level: "info",
|
|
@@ -2804,10 +2741,8 @@ var ChannelDriver = class {
|
|
|
2804
2741
|
});
|
|
2805
2742
|
continue;
|
|
2806
2743
|
}
|
|
2807
|
-
const anyUntracked = sessionRows.some((row) => !this.isTracked(sessionId, row.id));
|
|
2808
|
-
const sessionOngoing = anyUntracked ? await isSessionOngoing(this.port, sessionId) : null;
|
|
2809
2744
|
for (const row of sessionRows) {
|
|
2810
|
-
await this.readoptOne(sessionId, row, messages
|
|
2745
|
+
await this.readoptOne(sessionId, row, messages);
|
|
2811
2746
|
}
|
|
2812
2747
|
}
|
|
2813
2748
|
}
|
|
@@ -2829,7 +2764,7 @@ var ChannelDriver = class {
|
|
|
2829
2764
|
*
|
|
2830
2765
|
* Only `ChannelAuthError` propagates.
|
|
2831
2766
|
*/
|
|
2832
|
-
async readoptOne(sessionId, row, messages
|
|
2767
|
+
async readoptOne(sessionId, row, messages) {
|
|
2833
2768
|
if (this.isTracked(sessionId, row.id)) {
|
|
2834
2769
|
this.log({
|
|
2835
2770
|
level: "info",
|
|
@@ -2869,7 +2804,6 @@ var ChannelDriver = class {
|
|
|
2869
2804
|
conversation_id: row.conversation_id,
|
|
2870
2805
|
message_id: row.id
|
|
2871
2806
|
});
|
|
2872
|
-
void this.postSignal(row.conversation_id, row.id, "readopt_undeliverable");
|
|
2873
2807
|
return;
|
|
2874
2808
|
}
|
|
2875
2809
|
this.log({
|
|
@@ -2881,7 +2815,6 @@ var ChannelDriver = class {
|
|
|
2881
2815
|
return;
|
|
2882
2816
|
}
|
|
2883
2817
|
this.dontRedispatch.delete(row.id);
|
|
2884
|
-
void this.postSignal(row.conversation_id, row.id, "readopt_done");
|
|
2885
2818
|
return;
|
|
2886
2819
|
}
|
|
2887
2820
|
if (state === "failed") {
|
|
@@ -2904,7 +2837,6 @@ var ChannelDriver = class {
|
|
|
2904
2837
|
conversation_id: row.conversation_id,
|
|
2905
2838
|
message_id: row.id
|
|
2906
2839
|
});
|
|
2907
|
-
void this.postSignal(row.conversation_id, row.id, "readopt_undeliverable");
|
|
2908
2840
|
return;
|
|
2909
2841
|
}
|
|
2910
2842
|
this.log({
|
|
@@ -2916,7 +2848,6 @@ var ChannelDriver = class {
|
|
|
2916
2848
|
return;
|
|
2917
2849
|
}
|
|
2918
2850
|
this.dontRedispatch.delete(row.id);
|
|
2919
|
-
void this.postSignal(row.conversation_id, row.id, "readopt_failed");
|
|
2920
2851
|
return;
|
|
2921
2852
|
}
|
|
2922
2853
|
if (this.dontRedispatch.has(row.id)) {
|
|
@@ -2928,52 +2859,7 @@ var ChannelDriver = class {
|
|
|
2928
2859
|
});
|
|
2929
2860
|
return;
|
|
2930
2861
|
}
|
|
2931
|
-
|
|
2932
|
-
if (state === "running" && ocId) {
|
|
2933
|
-
const reply = findLastAssistantReplyFor(messages, ocId);
|
|
2934
|
-
const shape = this.replyCompletionShape(reply);
|
|
2935
|
-
const ongoing = sessionOngoing;
|
|
2936
|
-
statusReadableOngoing = ongoing;
|
|
2937
|
-
if (ongoing === false) {
|
|
2938
|
-
this.log({
|
|
2939
|
-
level: "info",
|
|
2940
|
-
message: `Re-adopt: message ${row.id.slice(0, 8)} running/${shape} but session ${sessionId.slice(0, 8)} is not-ongoing per GET /session/status (absent/idle) \u2014 re-dispatching from scratch (status-gated recovery)`,
|
|
2941
|
-
conversation_id: row.conversation_id,
|
|
2942
|
-
message_id: row.id
|
|
2943
|
-
});
|
|
2944
|
-
await this.forceReadoptRun(sessionId, row);
|
|
2945
|
-
return;
|
|
2946
|
-
}
|
|
2947
|
-
if (ongoing === true) {
|
|
2948
|
-
this.log({
|
|
2949
|
-
level: "info",
|
|
2950
|
-
message: `Re-adopt: message ${row.id.slice(0, 8)} running/${shape} and session ${sessionId.slice(0, 8)} is ongoing per GET /session/status (busy/retry) \u2014 re-attaching watcher (no re-dispatch)`,
|
|
2951
|
-
conversation_id: row.conversation_id,
|
|
2952
|
-
message_id: row.id
|
|
2953
|
-
});
|
|
2954
|
-
} else {
|
|
2955
|
-
if (shape === "b1") {
|
|
2956
|
-
this.log({
|
|
2957
|
-
level: "info",
|
|
2958
|
-
message: `Re-adopt: message ${row.id.slice(0, 8)} running/b1 but GET /session/status was unreadable (null) for session ${sessionId.slice(0, 8)} \u2014 NOT latching a b1 row on a transient status blip; leaving it un-tracked to re-evaluate on the next drain`,
|
|
2959
|
-
conversation_id: row.conversation_id,
|
|
2960
|
-
message_id: row.id
|
|
2961
|
-
});
|
|
2962
|
-
if (!this.readoptPollUnresolvedSignalled.has(row.id)) {
|
|
2963
|
-
this.readoptPollUnresolvedSignalled.add(row.id);
|
|
2964
|
-
void this.postSignal(row.conversation_id, row.id, "readopt_poll_unresolved");
|
|
2965
|
-
}
|
|
2966
|
-
return;
|
|
2967
|
-
}
|
|
2968
|
-
this.log({
|
|
2969
|
-
level: "info",
|
|
2970
|
-
message: `Re-adopt: message ${row.id.slice(0, 8)} running/${shape} but GET /session/status was unreadable (null) for session ${sessionId.slice(0, 8)} \u2014 falling back to the #253 preamble + descendant cross-check`,
|
|
2971
|
-
conversation_id: row.conversation_id,
|
|
2972
|
-
message_id: row.id
|
|
2973
|
-
});
|
|
2974
|
-
}
|
|
2975
|
-
}
|
|
2976
|
-
if (statusReadableOngoing === null && state === "running" && ocId && isPreamblePinnedRunning(messages, ocId)) {
|
|
2862
|
+
if (state === "running" && ocId && isPreamblePinnedRunning(messages, ocId)) {
|
|
2977
2863
|
const descendantAlive = await this.isAnyDescendantSessionAlive(sessionId);
|
|
2978
2864
|
if (descendantAlive === true) {
|
|
2979
2865
|
this.log({
|
|
@@ -3006,7 +2892,6 @@ var ChannelDriver = class {
|
|
|
3006
2892
|
conversation_id: row.conversation_id,
|
|
3007
2893
|
message_id: row.id
|
|
3008
2894
|
});
|
|
3009
|
-
void this.postSignal(row.conversation_id, row.id, "readopt_reattached");
|
|
3010
2895
|
return;
|
|
3011
2896
|
}
|
|
3012
2897
|
await this.forceReadoptRun(sessionId, row);
|
|
@@ -3059,7 +2944,6 @@ var ChannelDriver = class {
|
|
|
3059
2944
|
conversation_id: row.conversation_id,
|
|
3060
2945
|
message_id: row.id
|
|
3061
2946
|
});
|
|
3062
|
-
void this.postSignal(row.conversation_id, row.id, "readopt_window_elapsed");
|
|
3063
2947
|
return;
|
|
3064
2948
|
}
|
|
3065
2949
|
const options = {
|
|
@@ -3088,7 +2972,6 @@ var ChannelDriver = class {
|
|
|
3088
2972
|
conversation_id: row.conversation_id,
|
|
3089
2973
|
message_id: row.id
|
|
3090
2974
|
});
|
|
3091
|
-
void this.postSignal(row.conversation_id, row.id, "readopt_orphan_unsent");
|
|
3092
2975
|
return;
|
|
3093
2976
|
}
|
|
3094
2977
|
if (ocId === null) {
|
|
@@ -3099,7 +2982,6 @@ var ChannelDriver = class {
|
|
|
3099
2982
|
conversation_id: row.conversation_id,
|
|
3100
2983
|
message_id: row.id
|
|
3101
2984
|
});
|
|
3102
|
-
void this.postSignal(row.conversation_id, row.id, "readopt_orphan_unsent");
|
|
3103
2985
|
return;
|
|
3104
2986
|
}
|
|
3105
2987
|
const conv = this.convForRow(sessionId, row);
|
|
@@ -3109,7 +2991,6 @@ var ChannelDriver = class {
|
|
|
3109
2991
|
this.readopted.add(row.id);
|
|
3110
2992
|
this.awaitingReadopt.delete(row.id);
|
|
3111
2993
|
this.ensureWatcherRunning(sessionId);
|
|
3112
|
-
void this.postSignal(row.conversation_id, row.id, "readopt_redispatched");
|
|
3113
2994
|
}
|
|
3114
2995
|
/**
|
|
3115
2996
|
* True if `evidentMessageId` is already being driven — either in the
|
|
@@ -3377,25 +3258,6 @@ var ChannelDriver = class {
|
|
|
3377
3258
|
}
|
|
3378
3259
|
return false;
|
|
3379
3260
|
}
|
|
3380
|
-
/**
|
|
3381
|
-
* Cheap decision-telemetry label for a running row's LAST correlated reply
|
|
3382
|
-
* (WI-2 Task 2.2): which running SHAPE it is, for the status-gated recovery log.
|
|
3383
|
-
* - `b1` — the reply itself is still in flight (`time.completed == null`) —
|
|
3384
|
-
* the aborted-in-flight production bug after a restart.
|
|
3385
|
-
* - `b2` — a COMPLETED reply pinned running only by `finish === "tool-calls"`
|
|
3386
|
-
* (the sub-agent preamble — #253's shape).
|
|
3387
|
-
* - `other` — any other shape (defensive; a running row is normally b1 or b2).
|
|
3388
|
-
* Reads `info.time.completed` / `info.finish` (tolerating the legacy top-level
|
|
3389
|
-
* shape) directly rather than re-importing the module-private `completedOf`/
|
|
3390
|
-
* `finishOf` — this is a display label only, not a correctness predicate.
|
|
3391
|
-
*/
|
|
3392
|
-
replyCompletionShape(reply) {
|
|
3393
|
-
if (!reply) return "other";
|
|
3394
|
-
const completed = reply.info?.time?.completed ?? reply.time?.completed;
|
|
3395
|
-
if (completed == null) return "b1";
|
|
3396
|
-
const finish = reply.info?.finish ?? reply.finish;
|
|
3397
|
-
return finish === "tool-calls" ? "b2" : "other";
|
|
3398
|
-
}
|
|
3399
3261
|
/**
|
|
3400
3262
|
* Attribute a surfaced interaction to the in-flight message it paused on (M-1).
|
|
3401
3263
|
*
|