diff --git a/internal/cloud/access-control.ts b/internal/cloud/access-control.ts index 9a968ffd..15727402 100644 --- a/internal/cloud/access-control.ts +++ b/internal/cloud/access-control.ts @@ -2689,12 +2689,17 @@ function redactAgentRunSummary(value) { runStatus: textOr(agentRun.runStatus, ""), commandState: textOr(agentRun.commandState, ""), terminalStatus: textOr(agentRun.terminalStatus, ""), + runnerJobCount: numberOrNull(agentRun.runnerJobCount), lastSeq: numberOrNull(agentRun.lastSeq), eventStartSeq: numberOrNull(agentRun.eventStartSeq ?? agentRun.commandStartSeq ?? agentRun.startSeq), sessionId: textOr(agentRun.sessionId, ""), conversationId: textOr(agentRun.conversationId, ""), threadId: textOr(agentRun.threadId, ""), traceId: textOr(agentRun.traceId, ""), + reused: typeof agentRun.reused === "boolean" ? agentRun.reused : undefined, + runnerReused: typeof agentRun.runnerReused === "boolean" ? agentRun.runnerReused : undefined, + threadReused: typeof agentRun.threadReused === "boolean" ? agentRun.threadReused : undefined, + persistentResume: typeof agentRun.persistentResume === "boolean" ? agentRun.persistentResume : undefined, reuseEligible: typeof agentRun.reuseEligible === "boolean" ? agentRun.reuseEligible : undefined }); } diff --git a/internal/cloud/code-agent-agentrun-adapter.ts b/internal/cloud/code-agent-agentrun-adapter.ts index b3fc5406..3d5e4c22 100644 --- a/internal/cloud/code-agent-agentrun-adapter.ts +++ b/internal/cloud/code-agent-agentrun-adapter.ts @@ -448,7 +448,7 @@ export async function syncAgentRunChatResult({ traceId, currentResult = null, op timeoutMs, env }); - const nextMapping = { + const nextMapping = withAgentRunRunnerJobCount({ ...mapped.agentRun, ...agentRunResultRefs(result), lastSeq: eventsResponse ? agentRunTraceCursorSeq(eventsResponse, mapped.agentRun.lastSeq) : mapped.agentRun.lastSeq, @@ -458,7 +458,7 @@ export async function syncAgentRunChatResult({ traceId, currentResult = null, op terminalStatus: result?.terminalStatus ?? mapped.agentRun.terminalStatus ?? null, updatedAt: nowIso(options.now), valuesPrinted: false - }; + }); const base = { ...mapped, agentRun: nextMapping, updatedAt: nowIso(options.now) }; const payload = agentRunResultToCodeAgentPayload({ base, result, traceStore, traceId, appendResultEvent }); options.codeAgentChatResults?.set?.(traceId, payload); @@ -2065,6 +2065,17 @@ function agentRunResultRefs(result = {}) { return refs; } +function withAgentRunRunnerJobCount(mapping = {}) { + if (!mapping || typeof mapping !== "object") return mapping; + const count = Number(mapping.runnerJobCount); + if (Number.isFinite(count) && count >= 0) return mapping; + const runnerJobEnsured = mapping.reused === true || mapping.status === "runner-job-ensured"; + if (runnerJobEnsured && (mapping.runnerJobId || mapping.jobName || mapping.attemptId || mapping.runnerId)) { + return { ...mapping, runnerJobCount: 1 }; + } + return mapping; +} + function hwlabSessionIdForParams(params = {}, traceId) { return safeSessionId(params.sessionId) || agentRunSessionId(traceId); } diff --git a/internal/cloud/server-agent-chat.test.ts b/internal/cloud/server-agent-chat.test.ts index 3fb158a2..d5023898 100644 --- a/internal/cloud/server-agent-chat.test.ts +++ b/internal/cloud/server-agent-chat.test.ts @@ -538,7 +538,12 @@ test("cloud api /v1/agent/chat delegates v0.2 turns to AgentRun v0.1 over adapte deferredOwnerRecordStarted = true; await new Promise((resolve) => { releaseOwnerRecord = resolve; }); } - const record = testAgentSessionRecord(input); + const existing = ownerSessions.get(input.sessionId ?? input.id); + const record = testAgentSessionRecord({ + ...existing, + ...input, + session: { ...(existing?.session ?? {}), ...(input.session ?? {}) } + }); ownerSessions.set(record.id, record); return record; }, @@ -902,7 +907,12 @@ test("cloud api AgentRun adapter reports persistent thread resume when a complet return { ok: true, actor: TEST_AGENT_ACTOR, session: TEST_AUTH_SESSION }; }, async recordAgentSessionOwner(input) { - const record = testAgentSessionRecord(input); + const existing = ownerSessions.get(input.sessionId ?? input.id); + const record = testAgentSessionRecord({ + ...existing, + ...input, + session: { ...(existing?.session ?? {}), ...(input.session ?? {}) } + }); ownerSessions.set(record.id, record); return record; },