fix: restore web trace context for CLI replay

This commit is contained in:
Codex
2026-06-02 00:34:21 +08:00
parent 5dc263e10a
commit 3b504cdf13
2 changed files with 60 additions and 2 deletions
+14
View File
@@ -334,6 +334,20 @@ test("cloud api /v1/agent/chat delegates v0.2 turns to AgentRun v0.1 over adapte
assert.ok(payload.runnerTrace.events.some((event) => event.label === "agentrun:backend:runner-job-created"));
assert.ok(calls.some((call) => call.path === "/api/v1/runs/run_hwlab_adapter/runner-jobs"));
const inspectByTrace = await fetch(`http://127.0.0.1:${port}/v1/agent/chat/inspect?traceId=${traceId}`);
assert.equal(inspectByTrace.status, 200);
const inspectByTraceBody = await inspectByTrace.json();
assert.equal(inspectByTraceBody.ok, true);
assert.equal(inspectByTraceBody.latestTraceId, traceId);
assert.equal(inspectByTraceBody.session.sessionId, "ses_server-test-agentrun");
assert.equal(inspectByTraceBody.session.conversationId, "cnv_server-test-agentrun");
assert.equal(inspectByTraceBody.session.threadId, "019e8078-db67-7750-a5d9-1a99f3abd445");
assert.equal(inspectByTraceBody.conversationFacts.conversationId, "cnv_server-test-agentrun");
assert.equal(inspectByTraceBody.conversationFacts.threadId, "019e8078-db67-7750-a5d9-1a99f3abd445");
assert.equal(inspectByTraceBody.runnerTrace.traceId, traceId);
assert.equal(inspectByTraceBody.valuesRedacted, true);
assert.equal(JSON.stringify(inspectByTraceBody).includes("test-device-pod-session-token"), false);
const trace = await fetch(`http://127.0.0.1:${port}/v1/agent/chat/trace/${traceId}`);
assert.equal(trace.status, 200);
const traceBody = await trace.json();
+46 -2
View File
@@ -509,8 +509,9 @@ export async function handleCodeAgentInspectHttp(request, response, url, options
const registryInspect = sessionRegistry && typeof sessionRegistry.inspect === "function"
? sessionRegistry.inspect(query)
: { ok: false, status: "unavailable", traceIds: [], session: null, conversationFacts: null };
const session = matchedManagerSession ?? registryInspect.session ?? null;
const conversationFacts = registryInspect.conversationFacts ?? null;
const resultEvidence = await codeAgentInspectResultEvidence(query.traceId, options);
const session = matchedManagerSession ?? registryInspect.session ?? resultEvidence.session ?? null;
const conversationFacts = registryInspect.conversationFacts ?? resultEvidence.conversationFacts ?? null;
const requestedRunnerTrace = query.traceId ? traceStore.snapshot(query.traceId) : null;
const requestedTraceFound = Boolean(requestedRunnerTrace && requestedRunnerTrace.status !== "missing");
const traceIds = uniqueStrings([
@@ -518,6 +519,7 @@ export async function handleCodeAgentInspectHttp(request, response, url, options
session?.currentTraceId,
session?.lastTraceId,
conversationFacts?.latestTraceId,
resultEvidence.latestTraceId,
...(Array.isArray(conversationFacts?.traceIds) ? conversationFacts.traceIds : []),
...(Array.isArray(registryInspect.traceIds) ? registryInspect.traceIds : [])
]);
@@ -545,6 +547,48 @@ export async function handleCodeAgentInspectHttp(request, response, url, options
});
}
async function codeAgentInspectResultEvidence(traceId, options = {}) {
if (!safeTraceId(traceId)) return { session: null, conversationFacts: null, latestTraceId: null };
const cached = options.codeAgentChatResults?.get?.(traceId) ?? null;
const persisted = cached ? null : await loadPersistedAgentRunResult(traceId, options);
const result = cached ?? persisted ?? null;
if (!result || typeof result !== "object") return { session: null, conversationFacts: null, latestTraceId: null };
const agentRun = result.agentRun && typeof result.agentRun === "object" ? result.agentRun : null;
const resultSession = result.session && typeof result.session === "object" ? result.session : null;
const sessionReuse = result.sessionReuse && typeof result.sessionReuse === "object" ? result.sessionReuse : null;
const providerTrace = result.providerTrace && typeof result.providerTrace === "object" ? result.providerTrace : null;
const sessionId = safeSessionId(result.sessionId ?? resultSession?.sessionId ?? sessionReuse?.sessionId ?? agentRun?.sessionId) || null;
const conversationId = safeConversationId(result.conversationId ?? resultSession?.conversationId ?? sessionReuse?.conversationId ?? agentRun?.conversationId) || null;
const threadId = safeOpaqueId(result.threadId ?? resultSession?.threadId ?? sessionReuse?.threadId ?? providerTrace?.threadId ?? agentRun?.threadId) || null;
const status = textValue(resultSession?.status ?? result.status ?? agentRun?.status) || null;
const updatedAt = textValue(result.updatedAt ?? agentRun?.updatedAt ?? resultSession?.updatedAt) || null;
const session = sessionId || conversationId || threadId ? {
sessionId,
conversationId,
threadId,
status,
lastTraceId: traceId,
source: "code-agent-result",
agentRun: agentRun ? agentRunSessionEvidence(result).agentRun : null,
valuesRedacted: true,
secretMaterialStored: false
} : null;
const conversationFacts = conversationId ? {
conversationId,
sessionId,
threadId,
latestTraceId: traceId,
traceIds: [traceId],
turnCount: 1,
source: "code-agent-result",
latestStatus: status,
updatedAt,
valuesRedacted: true,
secretMaterialStored: false
} : null;
return { session, conversationFacts, latestTraceId: traceId };
}
function sessionMatchesInspectQuery(session, query) {
if (!session || typeof session !== "object") return false;
if (query.sessionId && session.sessionId === query.sessionId) return true;