@evident-ai/cli 3.0.1-dev.51bb855 → 3.0.1-dev.60e0bdb
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 +59 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -490,6 +490,29 @@ var TelemetryEventTypes = {
|
|
|
490
490
|
var MAX_FRAME_BYTES = 256 * 1024;
|
|
491
491
|
var TUNNEL_DRAIN_PING_PATH = "/__evident/drain";
|
|
492
492
|
|
|
493
|
+
// ../../packages/types/src/logging/index.ts
|
|
494
|
+
var CORRELATION_ID_HEADER = "x-evident-correlation-id";
|
|
495
|
+
function log(level, event, fields) {
|
|
496
|
+
const method = level === "debug" ? "log" : level;
|
|
497
|
+
try {
|
|
498
|
+
console[method]("[evident]", JSON.stringify({ level, event, ...fields }));
|
|
499
|
+
} catch (err) {
|
|
500
|
+
console.error(
|
|
501
|
+
"[evident] log_serialize_failed",
|
|
502
|
+
event,
|
|
503
|
+
err instanceof Error ? err.message : String(err)
|
|
504
|
+
);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
function stripQuery(url) {
|
|
508
|
+
try {
|
|
509
|
+
return new URL(url).pathname;
|
|
510
|
+
} catch {
|
|
511
|
+
const q = url.indexOf("?");
|
|
512
|
+
return q === -1 ? url : url.slice(0, q);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
493
516
|
// src/lib/telemetry.ts
|
|
494
517
|
var CLI_VERSION = process.env.npm_package_version || "unknown";
|
|
495
518
|
var eventBuffer = [];
|
|
@@ -1192,12 +1215,20 @@ var StreamForwarder = class {
|
|
|
1192
1215
|
}
|
|
1193
1216
|
async handleOpen(frame) {
|
|
1194
1217
|
const { sid, method, path, headers, has_body } = frame;
|
|
1218
|
+
const correlationId = headers?.[CORRELATION_ID_HEADER];
|
|
1219
|
+
const startedAt = Date.now();
|
|
1195
1220
|
if (path === TUNNEL_DRAIN_PING_PATH) {
|
|
1196
1221
|
this.callbacks.onDrainPing?.();
|
|
1197
1222
|
this.send({ type: "head", sid, status: 204, headers: {} });
|
|
1198
1223
|
this.send({ type: "res_end", sid });
|
|
1199
1224
|
return;
|
|
1200
1225
|
}
|
|
1226
|
+
log("info", "agent_request", {
|
|
1227
|
+
correlation_id: correlationId,
|
|
1228
|
+
sid,
|
|
1229
|
+
method,
|
|
1230
|
+
path: stripQuery(path)
|
|
1231
|
+
});
|
|
1201
1232
|
const ac = new AbortController();
|
|
1202
1233
|
let bodyPromise;
|
|
1203
1234
|
let pushBody;
|
|
@@ -1244,6 +1275,12 @@ var StreamForwarder = class {
|
|
|
1244
1275
|
if (!STRIP_RES.has(key.toLowerCase())) resHeaders[key] = value;
|
|
1245
1276
|
});
|
|
1246
1277
|
this.send({ type: "head", sid, status: upstream.status, headers: resHeaders });
|
|
1278
|
+
log("info", "agent_response", {
|
|
1279
|
+
correlation_id: correlationId,
|
|
1280
|
+
sid,
|
|
1281
|
+
status: upstream.status,
|
|
1282
|
+
duration_ms: Date.now() - startedAt
|
|
1283
|
+
});
|
|
1247
1284
|
this.callbacks.onHead?.(sid, upstream.status);
|
|
1248
1285
|
try {
|
|
1249
1286
|
if (upstream.body) {
|
|
@@ -2535,7 +2572,7 @@ async function getAgentInfo(agentId, authHeader) {
|
|
|
2535
2572
|
// src/commands/run.ts
|
|
2536
2573
|
var MAX_ACTIVITY_LOG_ENTRIES = 10;
|
|
2537
2574
|
var CHANNEL_POLL_INTERVAL_MS = Number(process.env.EVIDENT_CHANNEL_POLL_INTERVAL_MS) || 2e3;
|
|
2538
|
-
function
|
|
2575
|
+
function log2(state, message, isError = false) {
|
|
2539
2576
|
if (state.json) {
|
|
2540
2577
|
console.log(
|
|
2541
2578
|
JSON.stringify({
|
|
@@ -2560,9 +2597,9 @@ function logActivity(state, entry) {
|
|
|
2560
2597
|
}
|
|
2561
2598
|
if (!state.interactive) {
|
|
2562
2599
|
if (entry.type === "error") {
|
|
2563
|
-
|
|
2600
|
+
log2(state, entry.error ?? "Unknown error", true);
|
|
2564
2601
|
} else if (entry.type === "info" && entry.message) {
|
|
2565
|
-
|
|
2602
|
+
log2(state, entry.message);
|
|
2566
2603
|
}
|
|
2567
2604
|
}
|
|
2568
2605
|
}
|
|
@@ -2648,6 +2685,7 @@ async function handleAuthError(state, error2) {
|
|
|
2648
2685
|
}
|
|
2649
2686
|
async function driveChannels(state, driver) {
|
|
2650
2687
|
let idlePolls = 0;
|
|
2688
|
+
let lastSeenProxiedActivityAt = state.lastProxiedActivityAt;
|
|
2651
2689
|
while (state.running) {
|
|
2652
2690
|
if (state.connection?.reconnecting && state.connection.reconnectPromise) {
|
|
2653
2691
|
logActivity(state, { type: "info", message: "Waiting for tunnel reconnection..." });
|
|
@@ -2657,7 +2695,9 @@ async function driveChannels(state, driver) {
|
|
|
2657
2695
|
try {
|
|
2658
2696
|
const processed = await driver.drainPending();
|
|
2659
2697
|
state.messageCount += processed;
|
|
2660
|
-
|
|
2698
|
+
const proxiedActivity = state.lastProxiedActivityAt !== lastSeenProxiedActivityAt;
|
|
2699
|
+
lastSeenProxiedActivityAt = state.lastProxiedActivityAt;
|
|
2700
|
+
if (processed > 0 || driver.hasInFlightWatchers() || proxiedActivity) {
|
|
2661
2701
|
idlePolls = 0;
|
|
2662
2702
|
if (processed > 0 && state.interactive) displayStatus(state);
|
|
2663
2703
|
} else if (state.idleTimeout !== null) {
|
|
@@ -2709,7 +2749,7 @@ async function cleanup(state) {
|
|
|
2709
2749
|
logActivity(state, { type: "info", message: "Stopped OpenCode process" });
|
|
2710
2750
|
displayStatus(state);
|
|
2711
2751
|
} else {
|
|
2712
|
-
|
|
2752
|
+
log2(state, "Stopped OpenCode process");
|
|
2713
2753
|
}
|
|
2714
2754
|
state.opencodeProcess = null;
|
|
2715
2755
|
}
|
|
@@ -2732,10 +2772,11 @@ async function run(options) {
|
|
|
2732
2772
|
running: true,
|
|
2733
2773
|
activityLog: [],
|
|
2734
2774
|
messageCount: 0,
|
|
2775
|
+
lastProxiedActivityAt: null,
|
|
2735
2776
|
authHeader: ""
|
|
2736
2777
|
};
|
|
2737
2778
|
if (state.idleTimeout === null && (process.env.GITHUB_ACTIONS || process.env.CI)) {
|
|
2738
|
-
|
|
2779
|
+
log2(
|
|
2739
2780
|
state,
|
|
2740
2781
|
"Warning: No --idle-timeout set in CI environment. The runner will poll indefinitely until the job times out. Consider adding --idle-timeout 30 to avoid wasting runner minutes.",
|
|
2741
2782
|
false
|
|
@@ -2746,7 +2787,7 @@ async function run(options) {
|
|
|
2746
2787
|
logActivity(state, { type: "info", message: "Shutting down..." });
|
|
2747
2788
|
displayStatus(state);
|
|
2748
2789
|
} else {
|
|
2749
|
-
|
|
2790
|
+
log2(state, "Shutting down...");
|
|
2750
2791
|
}
|
|
2751
2792
|
await cleanup(state);
|
|
2752
2793
|
await shutdownTelemetry();
|
|
@@ -2779,7 +2820,7 @@ async function run(options) {
|
|
|
2779
2820
|
const resolved = await resolveAgentIdFromKey(state.authHeader);
|
|
2780
2821
|
if (resolved.agent_id) {
|
|
2781
2822
|
state.agentId = resolved.agent_id;
|
|
2782
|
-
|
|
2823
|
+
log2(state, `Resolved agent ID from key: ${state.agentId}`);
|
|
2783
2824
|
if (state.interactive && !state.json) {
|
|
2784
2825
|
logActivity(state, {
|
|
2785
2826
|
type: "info",
|
|
@@ -2842,7 +2883,7 @@ async function run(options) {
|
|
|
2842
2883
|
port: state.port,
|
|
2843
2884
|
interactive: state.interactive,
|
|
2844
2885
|
agentId: state.agentId,
|
|
2845
|
-
log: (message) =>
|
|
2886
|
+
log: (message) => log2(state, message)
|
|
2846
2887
|
});
|
|
2847
2888
|
state.port = oc.port;
|
|
2848
2889
|
state.opencodeProcess = oc.process;
|
|
@@ -2852,7 +2893,7 @@ async function run(options) {
|
|
|
2852
2893
|
ocSpinner?.succeed(`OpenCode running on port ${state.port}${version}`);
|
|
2853
2894
|
const versionWarning = buildOpenCodeVersionWarning(state.opencodeVersion);
|
|
2854
2895
|
if (versionWarning) {
|
|
2855
|
-
|
|
2896
|
+
log2(state, versionWarning, false);
|
|
2856
2897
|
if (state.interactive && !state.json) {
|
|
2857
2898
|
logActivity(state, { type: "info", message: versionWarning });
|
|
2858
2899
|
}
|
|
@@ -2921,9 +2962,14 @@ async function run(options) {
|
|
|
2921
2962
|
logActivity(state, { type: "error", error: error2 });
|
|
2922
2963
|
if (state.interactive) displayStatus(state);
|
|
2923
2964
|
},
|
|
2924
|
-
// Web traffic is proxied transparently;
|
|
2965
|
+
// Web traffic is proxied transparently; note opencode is live and stamp
|
|
2966
|
+
// proxied activity so the idle loop treats interactive proxy use as work.
|
|
2967
|
+
// Fires per forwarded response head (incl. every SSE open) and excludes
|
|
2968
|
+
// the internal drain-ping, so an actively-used proxy keeps the timer
|
|
2969
|
+
// fresh while a lone idle SSE with no follow-up requests still ages out.
|
|
2925
2970
|
onResponse: () => {
|
|
2926
2971
|
state.opencodeConnected = true;
|
|
2972
|
+
state.lastProxiedActivityAt = Date.now();
|
|
2927
2973
|
},
|
|
2928
2974
|
// A channel message was queued and the api-worker pinged us over the
|
|
2929
2975
|
// tunnel to drain immediately instead of waiting for the next poll tick.
|
|
@@ -2962,7 +3008,7 @@ async function run(options) {
|
|
|
2962
3008
|
throw error2;
|
|
2963
3009
|
}
|
|
2964
3010
|
if (!interactive || state.json) {
|
|
2965
|
-
|
|
3011
|
+
log2(state, "Driving channel messages...");
|
|
2966
3012
|
}
|
|
2967
3013
|
await driveChannels(state, channelDriver);
|
|
2968
3014
|
await cleanup(state);
|
|
@@ -2974,7 +3020,7 @@ async function run(options) {
|
|
|
2974
3020
|
})
|
|
2975
3021
|
);
|
|
2976
3022
|
} else if (!interactive) {
|
|
2977
|
-
|
|
3023
|
+
log2(state, `Completed. Processed ${state.messageCount} message(s).`);
|
|
2978
3024
|
}
|
|
2979
3025
|
await shutdownTelemetry();
|
|
2980
3026
|
process.exit(0);
|