@testchimp/cli 0.1.52 → 0.1.54
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/chimphands/run.js +34 -7
- package/package.json +1 -1
package/dist/chimphands/run.js
CHANGED
|
@@ -115,6 +115,8 @@ class AgentEventPoster {
|
|
|
115
115
|
lastStreamPostAt = 0;
|
|
116
116
|
/** When false, liveStream tokens are dropped; completed events still persist. */
|
|
117
117
|
uiAttached = false;
|
|
118
|
+
ephemeralFailLogAt = 0;
|
|
119
|
+
ephemeralFailCount = 0;
|
|
118
120
|
constructor(backend, apiKey, sessionId) {
|
|
119
121
|
this.backend = backend;
|
|
120
122
|
this.apiKey = apiKey;
|
|
@@ -163,6 +165,7 @@ class AgentEventPoster {
|
|
|
163
165
|
eph.opencodeSessionId = opts.opencodeSessionId;
|
|
164
166
|
try {
|
|
165
167
|
const text = await postJson(this.backend, this.apiKey, "/api/chimphands/post_ephemeral_agent_event", eph);
|
|
168
|
+
this.ephemeralFailCount = 0;
|
|
166
169
|
let delivered = false;
|
|
167
170
|
try {
|
|
168
171
|
const parsed = JSON.parse(text);
|
|
@@ -176,7 +179,7 @@ class AgentEventPoster {
|
|
|
176
179
|
// Mid-turn liveStream must not fall through to durable — that would write
|
|
177
180
|
// every token to PG. Turn-end reconcile persists the final transcript.
|
|
178
181
|
if (opts?.liveStream) {
|
|
179
|
-
|
|
182
|
+
this.logEphemeralIssue("ephemeral not delivered (replica miss?) — skipping durable for liveStream");
|
|
180
183
|
return;
|
|
181
184
|
}
|
|
182
185
|
// Completed/non-live: durable fallback for cross-replica UI.
|
|
@@ -185,7 +188,7 @@ class AgentEventPoster {
|
|
|
185
188
|
catch (err) {
|
|
186
189
|
const detail = err instanceof Error ? err.message : String(err);
|
|
187
190
|
if (opts?.liveStream) {
|
|
188
|
-
|
|
191
|
+
this.logEphemeralIssue(`ephemeral post failed — skipping durable for liveStream: ${detail}`);
|
|
189
192
|
return;
|
|
190
193
|
}
|
|
191
194
|
console.error(`ChimpHands ephemeral post failed — durable fallback: ${detail}`);
|
|
@@ -195,6 +198,16 @@ class AgentEventPoster {
|
|
|
195
198
|
});
|
|
196
199
|
return this.chain;
|
|
197
200
|
}
|
|
201
|
+
/** Avoid flooding GHA logs when ephemeral 500s every ~150ms. */
|
|
202
|
+
logEphemeralIssue(message) {
|
|
203
|
+
this.ephemeralFailCount += 1;
|
|
204
|
+
const now = Date.now();
|
|
205
|
+
if (this.ephemeralFailCount <= 2 || now - this.ephemeralFailLogAt >= 10_000) {
|
|
206
|
+
this.ephemeralFailLogAt = now;
|
|
207
|
+
const suffix = this.ephemeralFailCount > 2 ? ` (x${this.ephemeralFailCount} since last log)` : "";
|
|
208
|
+
console.error(`ChimpHands ${message}${suffix}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
198
211
|
fireAndForget(role, content, opts) {
|
|
199
212
|
void this.enqueue(role, content, opts).catch((err) => {
|
|
200
213
|
const detail = err instanceof Error ? err.message : String(err);
|
|
@@ -874,20 +887,34 @@ function killListenersOnPort(port) {
|
|
|
874
887
|
async function waitForOpencodeHttp(attachUrl, timeoutMs) {
|
|
875
888
|
const base = attachUrl.replace(/\/$/, "");
|
|
876
889
|
const deadline = Date.now() + timeoutMs;
|
|
890
|
+
const perTryMs = 2_000;
|
|
891
|
+
let attempt = 0;
|
|
892
|
+
let lastErr = "";
|
|
877
893
|
while (Date.now() < deadline) {
|
|
894
|
+
attempt += 1;
|
|
878
895
|
for (const path of ["/global/health", "/"]) {
|
|
879
896
|
try {
|
|
880
|
-
const res = await fetch(`${base}${path}
|
|
881
|
-
|
|
897
|
+
const res = await fetch(`${base}${path}`, {
|
|
898
|
+
signal: AbortSignal.timeout(perTryMs),
|
|
899
|
+
});
|
|
900
|
+
if (res.ok || res.status === 401 || res.status === 404) {
|
|
901
|
+
console.error(`ChimpHands OpenCode HTTP ready at ${attachUrl}${path} (http ${res.status}, attempt ${attempt})`);
|
|
882
902
|
return;
|
|
903
|
+
}
|
|
904
|
+
lastErr = `HTTP ${res.status}`;
|
|
883
905
|
}
|
|
884
|
-
catch {
|
|
885
|
-
|
|
906
|
+
catch (err) {
|
|
907
|
+
lastErr = err instanceof Error ? err.message : String(err);
|
|
886
908
|
}
|
|
887
909
|
}
|
|
910
|
+
if (attempt === 1 || attempt % 5 === 0) {
|
|
911
|
+
const left = Math.max(0, deadline - Date.now());
|
|
912
|
+
console.error(`ChimpHands waiting for OpenCode HTTP at ${attachUrl} (attempt ${attempt}, ${Math.ceil(left / 1000)}s left): ${lastErr || "not ready"}`);
|
|
913
|
+
}
|
|
888
914
|
await sleep(400);
|
|
889
915
|
}
|
|
890
|
-
throw new Error(`OpenCode server not ready at ${attachUrl} within ${timeoutMs}ms`
|
|
916
|
+
throw new Error(`OpenCode server not ready at ${attachUrl} within ${timeoutMs}ms` +
|
|
917
|
+
(lastErr ? ` (last: ${lastErr})` : ""));
|
|
891
918
|
}
|
|
892
919
|
/**
|
|
893
920
|
* Restart local `opencode serve` after writing opencode.json so the server loads
|
package/package.json
CHANGED