march-cli 0.1.17 → 0.1.19
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/package.json
CHANGED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { getOpenAICodexWebSocketDebugStats } from "@earendil-works/pi-ai/openai-codex-responses";
|
|
2
|
+
|
|
3
|
+
export function getCodexTransportDebugSnapshot(session) {
|
|
4
|
+
if (!isCodexTransportDebugEnabled()) return null;
|
|
5
|
+
const sessionId = session?.sessionId;
|
|
6
|
+
return sessionId ? (getOpenAICodexWebSocketDebugStats(sessionId) ?? null) : null;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function dumpCodexTransportDebug({ before, session, ui, logger }) {
|
|
10
|
+
if (!isCodexTransportDebugEnabled()) return;
|
|
11
|
+
const sessionId = session?.sessionId;
|
|
12
|
+
const after = sessionId ? (getOpenAICodexWebSocketDebugStats(sessionId) ?? null) : null;
|
|
13
|
+
const fields = formatCodexTransportDebugFields(sessionId, before, after);
|
|
14
|
+
logger?.event("codex.transport", fields);
|
|
15
|
+
writeCodexTransportDebug(ui, formatCodexTransportDebugLines(fields));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isCodexTransportDebugEnabled() {
|
|
19
|
+
const value = process.env.MARCH_CODEX_TRANSPORT_DEBUG;
|
|
20
|
+
return value === "1" || value === "true" || value === "yes";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function formatCodexTransportDebugFields(sessionId, before, after) {
|
|
24
|
+
const delta = (key) => (after?.[key] ?? 0) - (before?.[key] ?? 0);
|
|
25
|
+
return {
|
|
26
|
+
sessionId: sessionId ?? "unknown",
|
|
27
|
+
requests: delta("requests"),
|
|
28
|
+
totalRequests: after?.requests ?? 0,
|
|
29
|
+
connectionsCreated: delta("connectionsCreated"),
|
|
30
|
+
connectionsReused: delta("connectionsReused"),
|
|
31
|
+
cachedContextRequests: delta("cachedContextRequests"),
|
|
32
|
+
storeTrueRequests: delta("storeTrueRequests"),
|
|
33
|
+
fullContextRequests: delta("fullContextRequests"),
|
|
34
|
+
deltaRequests: delta("deltaRequests"),
|
|
35
|
+
websocketFailures: delta("websocketFailures"),
|
|
36
|
+
sseFallbacks: delta("sseFallbacks"),
|
|
37
|
+
websocketFallbackActive: Boolean(after?.websocketFallbackActive),
|
|
38
|
+
lastInputItems: after?.lastInputItems ?? 0,
|
|
39
|
+
lastDeltaInputItems: after?.lastDeltaInputItems ?? 0,
|
|
40
|
+
lastWebSocketError: after?.lastWebSocketError ?? null,
|
|
41
|
+
hasStats: Boolean(after),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function formatCodexTransportDebugLines(fields) {
|
|
46
|
+
if (!fields.hasStats) return [`[codex-transport] sessionId=${fields.sessionId} no Codex WebSocket stats`];
|
|
47
|
+
return [
|
|
48
|
+
`[codex-transport] sessionId=${fields.sessionId}`,
|
|
49
|
+
` requests=${fields.requests} totalRequests=${fields.totalRequests}`,
|
|
50
|
+
` wsConnections created=${fields.connectionsCreated} reused=${fields.connectionsReused}`,
|
|
51
|
+
` modes full=${fields.fullContextRequests} delta=${fields.deltaRequests} cached=${fields.cachedContextRequests} storeTrue=${fields.storeTrueRequests}`,
|
|
52
|
+
` fallback websocketFailures=${fields.websocketFailures} sseFallbacks=${fields.sseFallbacks} active=${fields.websocketFallbackActive}`,
|
|
53
|
+
` error lastWebSocketError=${formatDebugValue(fields.lastWebSocketError)}`,
|
|
54
|
+
` lastInputItems=${fields.lastInputItems} lastDeltaInputItems=${fields.lastDeltaInputItems}`,
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function formatDebugValue(value) {
|
|
59
|
+
if (value === null || value === undefined || value === "") return "none";
|
|
60
|
+
if (typeof value === "string") return JSON.stringify(value);
|
|
61
|
+
try {
|
|
62
|
+
return JSON.stringify(value);
|
|
63
|
+
} catch {
|
|
64
|
+
return JSON.stringify(String(value));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function writeCodexTransportDebug(ui, lines) {
|
|
69
|
+
if (ui?.debugLines) {
|
|
70
|
+
ui.debugLines(lines);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (!ui?.writeln) return;
|
|
74
|
+
for (const line of lines) ui.writeln(line);
|
|
75
|
+
}
|
package/src/agent/runner.mjs
CHANGED
|
@@ -12,6 +12,7 @@ import { createRunnerRuntimeHost } from "./runtime/runner-runtime-host.mjs";
|
|
|
12
12
|
import { createRuntimeUiBridge } from "./runtime/ui-event-bridge.mjs";
|
|
13
13
|
import { getRunnerSessionStats, syncEngineSessionState } from "./runner/runner-session-state.mjs";
|
|
14
14
|
import { notifyTurnEndBestEffort, notifyTurnEndDetached, providerContextToPayload } from "./runner/runner-utils.mjs";
|
|
15
|
+
import { dumpCodexTransportDebug, getCodexTransportDebugSnapshot } from "./runner/codex-transport-debug.mjs";
|
|
15
16
|
import { resolveRunnerSessionOptions } from "./session/session-options.mjs";
|
|
16
17
|
import { createSessionBinding } from "./session/session-binding.mjs";
|
|
17
18
|
import { maybeAutoNameSession } from "./session/session-auto-name.mjs";
|
|
@@ -110,6 +111,7 @@ export async function createRunner({ cwd, modelId = null, provider = null, provi
|
|
|
110
111
|
currentTurnContextMode = contextMode;
|
|
111
112
|
nextTurnContextMode = "rebuild";
|
|
112
113
|
const turnStartedAt = Date.now();
|
|
114
|
+
const codexTransportStatsBefore = getCodexTransportDebugSnapshot(sessionBinding.get());
|
|
113
115
|
const turnLog = beginLoggedTurn({ logger, engine, modelId, provider, contextMode, userMessage, userRecallHints, startedAt: turnStartedAt }); currentTurnId = turnLog.turnId;
|
|
114
116
|
try {
|
|
115
117
|
const result = await runRunnerTurn({
|
|
@@ -140,6 +142,7 @@ export async function createRunner({ cwd, modelId = null, provider = null, provi
|
|
|
140
142
|
turnLog.endError(err);
|
|
141
143
|
throw err;
|
|
142
144
|
} finally {
|
|
145
|
+
dumpCodexTransportDebug({ before: codexTransportStatsBefore, session: sessionBinding.get(), ui: runtimeUi, logger });
|
|
143
146
|
currentTurnId = null;
|
|
144
147
|
currentTurnContextMode = "rebuild";
|
|
145
148
|
}
|
|
@@ -12,6 +12,7 @@ export function createRemoteRuntimeUiClient(peer) {
|
|
|
12
12
|
retryStart: (event) => peer.notify("uiEvent", { type: "retry_start", ...event }),
|
|
13
13
|
retryEnd: (event) => peer.notify("uiEvent", { type: "retry_end", ...event }),
|
|
14
14
|
status: (text) => peer.notify("uiEvent", { type: "status", text }),
|
|
15
|
+
debugLines: (lines) => peer.notify("uiEvent", { type: "debug_lines", lines }),
|
|
15
16
|
memoryHint: ({ source, hints }) => peer.notify("uiEvent", { type: "memory_hint", source, hints }),
|
|
16
17
|
editDiff: (path, diffLines) => peer.notify("uiEvent", { type: "edit_diff", path, diffLines }),
|
|
17
18
|
requestPermission: (request) => peer.call("uiRequest", { type: "permission_request", ...request }),
|
|
@@ -49,6 +49,7 @@ export function createRuntimeUiClient(eventBus) {
|
|
|
49
49
|
retryStart: (event) => eventBus.emit({ type: "retry_start", ...event }),
|
|
50
50
|
retryEnd: (event) => eventBus.emit({ type: "retry_end", ...event }),
|
|
51
51
|
status: (text) => eventBus.emit({ type: "status", text }),
|
|
52
|
+
debugLines: (lines) => eventBus.emit({ type: "debug_lines", lines }),
|
|
52
53
|
memoryHint: ({ source, hints }) => eventBus.emit({ type: "memory_hint", source, hints }),
|
|
53
54
|
editDiff: (path, diffLines) => eventBus.emit({ type: "edit_diff", path, diffLines }),
|
|
54
55
|
requestPermission: (request) => eventBus.request({ type: "permission_request", ...request }),
|
|
@@ -69,6 +70,7 @@ export function dispatchRuntimeUiEvent(ui, event) {
|
|
|
69
70
|
case "retry_start": return ui.retryStart?.(pickRetryStart(event));
|
|
70
71
|
case "retry_end": return ui.retryEnd?.(pickRetryEnd(event));
|
|
71
72
|
case "status": return ui.status?.(event.text);
|
|
73
|
+
case "debug_lines": return writeDebugLines(ui, event.lines);
|
|
72
74
|
case "memory_hint": return ui.memoryHint?.({ source: event.source, hints: event.hints });
|
|
73
75
|
case "edit_diff": return ui.editDiff?.(event.path, event.diffLines);
|
|
74
76
|
case "permission_request": return ui.requestPermission?.({ toolName: event.toolName, params: event.params, category: event.category });
|
|
@@ -76,6 +78,14 @@ export function dispatchRuntimeUiEvent(ui, event) {
|
|
|
76
78
|
}
|
|
77
79
|
}
|
|
78
80
|
|
|
81
|
+
function writeDebugLines(ui, lines) {
|
|
82
|
+
if (!Array.isArray(lines)) return undefined;
|
|
83
|
+
if (ui?.debugLines) return ui.debugLines(lines);
|
|
84
|
+
if (!ui?.writeln) return undefined;
|
|
85
|
+
for (const line of lines) ui.writeln(line);
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
79
89
|
function pickRetryStart({ attempt, maxAttempts, delayMs, errorMessage }) {
|
|
80
90
|
return { attempt, maxAttempts, delayMs, errorMessage };
|
|
81
91
|
}
|