fix: unify AgentRun trace result authority
This commit is contained in:
@@ -428,8 +428,9 @@ function isAgentRunCommandAlreadyClaimed(error) {
|
||||
return statusCode === 409 && /command\s+[^\s]+\s+is not pending:/u.test(message);
|
||||
}
|
||||
|
||||
export async function syncAgentRunChatResult({ traceId, currentResult = null, options = {}, traceStore = defaultCodeAgentTraceStore }) {
|
||||
const mapped = currentResult ?? await loadPersistedAgentRunResult(traceId, options);
|
||||
export async function syncAgentRunChatResult({ traceId, currentResult = null, options = {}, traceStore = defaultCodeAgentTraceStore, appendResultEvent = true }) {
|
||||
const initial = currentResult ?? await loadPersistedAgentRunResult(traceId, options);
|
||||
const mapped = initial ? await resolveAgentRunTraceCommandMapping({ traceId, mapped: initial, options }) : initial;
|
||||
if (!mapped?.agentRun?.runId || !mapped?.agentRun?.commandId) return { result: currentResult, runnerTrace: traceStore.snapshot(traceId), found: Boolean(currentResult) };
|
||||
const env = options.env ?? process.env;
|
||||
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
||||
@@ -454,13 +455,70 @@ export async function syncAgentRunChatResult({ traceId, currentResult = null, op
|
||||
valuesPrinted: false
|
||||
};
|
||||
const base = { ...mapped, agentRun: nextMapping, updatedAt: nowIso(options.now) };
|
||||
const payload = agentRunResultToCodeAgentPayload({ base, result, traceStore, traceId });
|
||||
const payload = agentRunResultToCodeAgentPayload({ base, result, traceStore, traceId, appendResultEvent });
|
||||
options.codeAgentChatResults?.set?.(traceId, payload);
|
||||
return { result: payload, runnerTrace: payload.runnerTrace ?? traceStore.snapshot(traceId), found: true };
|
||||
}
|
||||
|
||||
async function resolveAgentRunTraceCommandMapping({ traceId, mapped, options = {} }) {
|
||||
const safeId = safeTraceId(traceId);
|
||||
const agentRun = mapped?.agentRun && typeof mapped.agentRun === "object" ? mapped.agentRun : null;
|
||||
if (!safeId || !agentRun?.runId) return mapped;
|
||||
const agentRunTraceId = safeTraceId(agentRun.traceId);
|
||||
const providerTraceId = safeTraceId(agentRun.providerTrace?.traceId);
|
||||
const traceSummaryCommandId = text(mapped?.traceSummary?.agentRun?.commandId);
|
||||
const commandId = text(agentRun.commandId);
|
||||
const traceFieldsMatch = agentRunTraceId === safeId && providerTraceId === safeId && (!traceSummaryCommandId || traceSummaryCommandId === commandId);
|
||||
if (mapped.status === "running" && traceFieldsMatch) return mapped;
|
||||
const env = options.env ?? process.env;
|
||||
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
||||
const managerUrl = resolveAgentRunManagerUrl(env, agentRun.managerUrl);
|
||||
const timeoutMs = parsePositiveInteger(env.HWLAB_CODE_AGENT_AGENTRUN_HTTP_TIMEOUT_MS, 20_000);
|
||||
const command = await findAgentRunCommandForTrace({ fetchImpl, managerUrl, timeoutMs, runId: agentRun.runId, traceId: safeId });
|
||||
if (!command?.id) {
|
||||
throw Object.assign(new Error(`AgentRun command registry has no command for ${safeId} in run ${agentRun.runId}`), {
|
||||
code: "agentrun_trace_command_not_found",
|
||||
statusCode: 404,
|
||||
traceId: safeId,
|
||||
runId: agentRun.runId
|
||||
});
|
||||
}
|
||||
if (command.id === commandId) {
|
||||
return {
|
||||
...mapped,
|
||||
finalResponse: null,
|
||||
traceSummary: null,
|
||||
agentRun: {
|
||||
...agentRun,
|
||||
traceId: safeId,
|
||||
lastSeq: 0,
|
||||
providerTrace: null,
|
||||
commandState: command.state ?? agentRun.commandState ?? null,
|
||||
updatedAt: nowIso(options.now),
|
||||
valuesPrinted: false
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
...mapped,
|
||||
finalResponse: null,
|
||||
traceSummary: null,
|
||||
agentRun: {
|
||||
...agentRun,
|
||||
commandId: command.id,
|
||||
traceId: safeId,
|
||||
lastSeq: 0,
|
||||
providerTrace: null,
|
||||
commandState: command.state ?? agentRun.commandState ?? null,
|
||||
updatedAt: nowIso(options.now),
|
||||
valuesPrinted: false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export async function refreshAgentRunTrace({ traceId, result = null, options = {}, traceStore = defaultCodeAgentTraceStore }) {
|
||||
const mapped = result ?? await loadPersistedAgentRunResult(traceId, options);
|
||||
const initial = result ?? await loadPersistedAgentRunResult(traceId, options);
|
||||
const mapped = initial ? await resolveAgentRunTraceCommandMapping({ traceId, mapped: initial, options }) : initial;
|
||||
if (!mapped?.agentRun?.runId) return traceStore.snapshot(traceId);
|
||||
const env = options.env ?? process.env;
|
||||
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
||||
@@ -609,141 +667,48 @@ export async function loadPersistedAgentRunResult(traceId, options = {}) {
|
||||
const safeId = safeTraceId(traceId);
|
||||
if (!safeId || typeof options.accessController?.getAgentSessionByTraceId !== "function") return null;
|
||||
const session = await options.accessController.getAgentSessionByTraceId(safeId);
|
||||
const traceEvidence = validAgentSessionTraceEvidence(session, safeId);
|
||||
const latestTraceId = safeTraceId(session?.lastTraceId ?? session?.session?.lastTraceId ?? session?.session?.traceId);
|
||||
const topLevelAgentRun = session?.session?.agentRun && typeof session.session.agentRun === "object" ? session.session.agentRun : null;
|
||||
const agentRunTraceId = safeTraceId(topLevelAgentRun?.traceId);
|
||||
const topLevelFinalTraceId = safeTraceId(session?.session?.finalResponse?.traceId ?? session?.session?.traceSummary?.traceId);
|
||||
const topLevelConflictsTrace = (agentRunTraceId && agentRunTraceId !== safeId) || (topLevelFinalTraceId && topLevelFinalTraceId !== safeId);
|
||||
const mayUseTopLevelAgentRun = !topLevelConflictsTrace && (latestTraceId === safeId || agentRunTraceId === safeId || topLevelFinalTraceId === safeId || (!latestTraceId && !agentRunTraceId && !topLevelFinalTraceId));
|
||||
const topLevelTraceEvidence = mayUseTopLevelAgentRun ? agentSessionTopLevelTraceEvidence(session, safeId) : null;
|
||||
if (!traceEvidence && topLevelTraceEvidence && ambiguousTopLevelAgentRunTrace(topLevelAgentRun)) {
|
||||
const repaired = await repairPersistedAgentRunResultFromRunCommands({ traceId: safeId, session, options }).catch(() => null);
|
||||
if (repaired) return repaired;
|
||||
}
|
||||
const agentRun = traceEvidence?.agentRun ?? (topLevelTraceEvidence ? topLevelAgentRun : null);
|
||||
const restored = persistedAgentRunResultFromSession({ traceId: safeId, session, agentRun, traceEvidence, options });
|
||||
if (restored) return restored;
|
||||
return await repairPersistedAgentRunResultFromRunCommands({ traceId: safeId, session, options });
|
||||
}
|
||||
|
||||
function persistedAgentRunResultFromSession({ traceId, session, agentRun, traceEvidence, options = {} }) {
|
||||
if (!agentRun || typeof agentRun !== "object" || !agentRun.runId || !agentRun.commandId) return null;
|
||||
if (!agentRunEvidenceMatchesTrace(agentRun, traceId, traceEvidence)) return null;
|
||||
const status = firstNonEmpty(traceEvidence?.status, session?.status === "canceled" ? "canceled" : null, agentRun.terminalStatus, agentRun.commandState, "running");
|
||||
const agentRun = agentRunSeedFromSession(session, safeId);
|
||||
if (!agentRun?.runId) return null;
|
||||
const backendProfile = firstNonEmpty(agentRun.backendProfile, "deepseek");
|
||||
const status = firstNonEmpty(session?.status === "canceled" ? "canceled" : null, agentRun.terminalStatus, agentRun.commandState, agentRun.status, "running");
|
||||
return {
|
||||
accepted: true,
|
||||
status,
|
||||
shortConnection: true,
|
||||
traceId,
|
||||
conversationId: safeConversationId(traceEvidence?.conversationId ?? session?.conversationId) || agentRun.conversationId || null,
|
||||
sessionId: safeSessionId(traceEvidence?.sessionId ?? session?.id) || agentRun.sessionId || null,
|
||||
threadId: safeOpaqueId(traceEvidence?.threadId ?? session?.threadId) || agentRun.threadId || null,
|
||||
messageId: traceEvidence?.messageId ?? session?.session?.messageId ?? `msg_${traceId.slice(4)}`,
|
||||
createdAt: traceEvidence?.createdAt ?? session?.startedAt ?? session?.updatedAt ?? nowIso(options.now),
|
||||
updatedAt: traceEvidence?.updatedAt ?? session?.updatedAt ?? nowIso(options.now),
|
||||
traceId: safeId,
|
||||
conversationId: safeConversationId(session?.conversationId) || agentRun.conversationId || null,
|
||||
sessionId: safeSessionId(session?.id) || agentRun.sessionId || null,
|
||||
threadId: safeOpaqueId(session?.threadId) || agentRun.threadId || null,
|
||||
messageId: `msg_${safeId.slice(4)}`,
|
||||
createdAt: session?.startedAt ?? session?.updatedAt ?? nowIso(options.now),
|
||||
updatedAt: session?.updatedAt ?? nowIso(options.now),
|
||||
ownerUserId: session?.ownerUserId,
|
||||
provider: providerForBackendProfile(agentRun.backendProfile ?? "deepseek"),
|
||||
model: modelForBackendProfile(agentRun.backendProfile, options.env ?? process.env),
|
||||
backend: backendForBackendProfile(agentRun.backendProfile ?? "deepseek"),
|
||||
infrastructureBackend: `agentrun-v01/${agentRun.backendProfile ?? "deepseek"}`,
|
||||
ownerRole: session?.ownerRole,
|
||||
provider: providerForBackendProfile(backendProfile),
|
||||
model: modelForBackendProfile(backendProfile, options.env ?? process.env),
|
||||
backend: backendForBackendProfile(backendProfile),
|
||||
infrastructureBackend: `agentrun-v01/${backendProfile}`,
|
||||
capabilityLevel: AGENTRUN_CAPABILITY_LEVEL,
|
||||
sessionMode: AGENTRUN_SESSION_MODE,
|
||||
implementationType: AGENTRUN_IMPLEMENTATION_TYPE,
|
||||
finalResponse: traceEvidence?.finalResponse ?? session?.session?.finalResponse ?? null,
|
||||
traceSummary: traceEvidence?.traceSummary ?? session?.session?.traceSummary ?? null,
|
||||
agentRun: { ...agentRun, adapter: ADAPTER_ID, valuesPrinted: false },
|
||||
agentRun: { ...agentRun, adapter: ADAPTER_ID, traceId: safeId, commandId: text(agentRun.commandId) || null, valuesPrinted: false },
|
||||
valuesPrinted: false
|
||||
};
|
||||
}
|
||||
|
||||
async function repairPersistedAgentRunResultFromRunCommands({ traceId, session, options = {} }) {
|
||||
const seedAgentRun = session?.session?.agentRun && typeof session.session.agentRun === "object" ? session.session.agentRun : null;
|
||||
if (!seedAgentRun?.runId) return null;
|
||||
const env = options.env ?? process.env;
|
||||
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
||||
const managerUrl = resolveAgentRunManagerUrl(env, seedAgentRun.managerUrl);
|
||||
const timeoutMs = parsePositiveInteger(env.HWLAB_CODE_AGENT_AGENTRUN_HTTP_TIMEOUT_MS, 20_000);
|
||||
const commands = await agentRunJson(fetchImpl, managerUrl, `/api/v1/runs/${encodeURIComponent(seedAgentRun.runId)}/commands?afterSeq=0&limit=100`, { method: "GET", timeoutMs });
|
||||
const command = (Array.isArray(commands?.items) ? commands.items : []).find((item) => agentRunCommandMatchesTrace(item, traceId));
|
||||
if (!command?.id) return null;
|
||||
const [result, eventsResponse] = await Promise.all([
|
||||
agentRunJson(fetchImpl, managerUrl, `/api/v1/runs/${encodeURIComponent(seedAgentRun.runId)}/commands/${encodeURIComponent(command.id)}/result`, { method: "GET", timeoutMs }),
|
||||
agentRunJson(fetchImpl, managerUrl, `/api/v1/runs/${encodeURIComponent(seedAgentRun.runId)}/events?afterSeq=0&limit=500`, { method: "GET", timeoutMs }).catch(() => ({ items: [] }))
|
||||
]);
|
||||
const rawEvents = Array.isArray(eventsResponse?.items) ? eventsResponse.items : [];
|
||||
const commandSeqs = rawEvents
|
||||
.filter((event) => agentRunEventCommandId(event) === command.id)
|
||||
.map((event) => Number(event?.seq ?? 0))
|
||||
.filter(Number.isFinite);
|
||||
const firstSeq = commandSeqs.length ? Math.min(...commandSeqs) : 0;
|
||||
const afterSeq = firstSeq > 0 ? firstSeq - 1 : 0;
|
||||
const endSeq = Math.max(0, ...commandSeqs);
|
||||
const traceEvents = rawEvents.filter((event) => agentRunEventBelongsToTrace(event, { currentCommandId: command.id, afterSeq, endSeq }));
|
||||
const now = nowIso(options.now);
|
||||
const backendProfile = firstNonEmpty(seedAgentRun.backendProfile, result?.backendProfile, command?.payload?.providerProfile, "deepseek");
|
||||
const agentRun = {
|
||||
...seedAgentRun,
|
||||
adapter: ADAPTER_ID,
|
||||
managerUrl,
|
||||
backendProfile,
|
||||
runId: result?.runId ?? seedAgentRun.runId,
|
||||
commandId: command.id,
|
||||
attemptId: result?.attemptId ?? seedAgentRun.attemptId ?? null,
|
||||
runnerId: result?.runnerId ?? seedAgentRun.runnerId ?? null,
|
||||
jobName: result?.jobName ?? seedAgentRun.jobName ?? null,
|
||||
namespace: result?.namespace ?? seedAgentRun.namespace ?? DEFAULT_RUNNER_NAMESPACE,
|
||||
status: result?.status ?? command.state ?? seedAgentRun.status ?? null,
|
||||
runStatus: result?.runStatus ?? seedAgentRun.runStatus ?? null,
|
||||
commandState: result?.commandState ?? command.state ?? null,
|
||||
terminalStatus: result?.terminalStatus ?? null,
|
||||
eventStartSeq: afterSeq > 0 ? afterSeq + 1 : null,
|
||||
lastSeq: endSeq || 0,
|
||||
traceId,
|
||||
sessionId: result?.sessionRef?.sessionId ?? command?.payload?.sessionId ?? seedAgentRun.sessionId ?? null,
|
||||
conversationId: result?.sessionRef?.conversationId ?? command?.payload?.conversationId ?? seedAgentRun.conversationId ?? session?.conversationId ?? null,
|
||||
threadId: result?.sessionRef?.threadId ?? command?.payload?.threadId ?? seedAgentRun.threadId ?? session?.threadId ?? null,
|
||||
valuesPrinted: false
|
||||
};
|
||||
const finalText = firstNonEmpty(result?.reply);
|
||||
const finalResponse = finalText ? {
|
||||
text: finalText,
|
||||
textChars: finalText.length,
|
||||
messageId: `msg_${traceId.slice(4)}`,
|
||||
role: "assistant",
|
||||
status: result?.status ?? result?.terminalStatus ?? "completed",
|
||||
traceId,
|
||||
createdAt: command.updatedAt ?? result?.updatedAt ?? now,
|
||||
updatedAt: command.updatedAt ?? result?.updatedAt ?? now,
|
||||
source: "agentrun-command-result-repair",
|
||||
valuesPrinted: false
|
||||
} : null;
|
||||
const traceSummary = {
|
||||
traceId,
|
||||
source: "agent-session-agentrun-command-repair",
|
||||
sourceEventCount: traceEvents.length,
|
||||
terminalStatus: result?.terminalStatus ?? command.state ?? null,
|
||||
agentRun: { runId: agentRun.runId, commandId: agentRun.commandId, lastSeq: agentRun.lastSeq, eventStartSeq: agentRun.eventStartSeq, valuesPrinted: false },
|
||||
updatedAt: now,
|
||||
valuesPrinted: false
|
||||
};
|
||||
const traceEvidence = {
|
||||
traceId,
|
||||
status: result?.status ?? result?.terminalStatus ?? command.state ?? "completed",
|
||||
conversationId: agentRun.conversationId,
|
||||
sessionId: safeSessionId(command?.payload?.hwlabSessionId) || safeSessionId(session?.id) || agentRun.sessionId,
|
||||
threadId: agentRun.threadId,
|
||||
messageId: `msg_${traceId.slice(4)}`,
|
||||
createdAt: command.createdAt ?? session?.startedAt ?? now,
|
||||
updatedAt: command.updatedAt ?? now,
|
||||
finalResponse,
|
||||
traceSummary,
|
||||
agentRun,
|
||||
valuesRedacted: true,
|
||||
secretMaterialStored: false
|
||||
};
|
||||
await persistTraceRepairEvidence({ session, traceId, traceEvidence, options });
|
||||
return persistedAgentRunResultFromSession({ traceId, session, agentRun, traceEvidence, options });
|
||||
function agentRunSeedFromSession(session, traceId) {
|
||||
const snapshot = session?.session && typeof session.session === "object" ? session.session : null;
|
||||
const traceResults = snapshot?.traceResults && typeof snapshot.traceResults === "object" ? snapshot.traceResults : null;
|
||||
const traceAgentRun = traceResults?.[traceId]?.agentRun && typeof traceResults[traceId].agentRun === "object" ? traceResults[traceId].agentRun : null;
|
||||
if (traceAgentRun?.runId) return traceAgentRun;
|
||||
const topLevelAgentRun = snapshot?.agentRun && typeof snapshot.agentRun === "object" ? snapshot.agentRun : null;
|
||||
return topLevelAgentRun?.runId ? topLevelAgentRun : null;
|
||||
}
|
||||
|
||||
async function findAgentRunCommandForTrace({ fetchImpl, managerUrl, timeoutMs, runId, traceId }) {
|
||||
if (!runId || !safeTraceId(traceId)) return null;
|
||||
const commands = await agentRunJson(fetchImpl, managerUrl, `/api/v1/runs/${encodeURIComponent(runId)}/commands?afterSeq=0&limit=100`, { method: "GET", timeoutMs });
|
||||
return (Array.isArray(commands?.items) ? commands.items : []).find((item) => agentRunCommandMatchesTrace(item, traceId)) ?? null;
|
||||
}
|
||||
|
||||
function agentRunCommandMatchesTrace(command, traceId) {
|
||||
@@ -751,71 +716,6 @@ function agentRunCommandMatchesTrace(command, traceId) {
|
||||
return command?.idempotencyKey === traceId || payload.traceId === traceId;
|
||||
}
|
||||
|
||||
async function persistTraceRepairEvidence({ session, traceId, traceEvidence, options = {} }) {
|
||||
if (!session?.id || !session.ownerUserId || typeof options.accessController?.recordAgentSessionOwner !== "function") return;
|
||||
await options.accessController.recordAgentSessionOwner({
|
||||
ownerUserId: session.ownerUserId,
|
||||
sessionId: session.id,
|
||||
projectId: session.projectId,
|
||||
agentId: session.agentId,
|
||||
status: session.status,
|
||||
conversationId: session.conversationId,
|
||||
threadId: session.threadId,
|
||||
lastTraceId: session.lastTraceId,
|
||||
session: { traceResults: { [traceId]: traceEvidence }, source: "agent-session-trace-repair", valuesRedacted: true, secretMaterialStored: false }
|
||||
});
|
||||
}
|
||||
|
||||
function agentSessionTraceEvidence(session, traceId) {
|
||||
const id = safeTraceId(traceId);
|
||||
const traceResults = session?.session?.traceResults && typeof session.session.traceResults === "object" ? session.session.traceResults : null;
|
||||
const evidence = id && traceResults?.[id] && typeof traceResults[id] === "object" ? traceResults[id] : null;
|
||||
return evidence ? { ...evidence, traceId: id } : null;
|
||||
}
|
||||
|
||||
function validAgentSessionTraceEvidence(session, traceId) {
|
||||
const evidence = agentSessionTraceEvidence(session, traceId);
|
||||
if (!evidence) return null;
|
||||
return agentRunEvidenceMatchesTrace(evidence.agentRun, traceId, evidence, { requireAgentRunTraceId: true }) ? evidence : null;
|
||||
}
|
||||
|
||||
function agentSessionTopLevelTraceEvidence(session, traceId) {
|
||||
const snapshot = session?.session && typeof session.session === "object" ? session.session : null;
|
||||
if (!snapshot) return null;
|
||||
const evidence = {
|
||||
finalResponse: snapshot.finalResponse,
|
||||
traceSummary: snapshot.traceSummary
|
||||
};
|
||||
return agentRunEvidenceMatchesTrace(snapshot.agentRun, traceId, evidence) ? evidence : null;
|
||||
}
|
||||
|
||||
function ambiguousTopLevelAgentRunTrace(agentRun) {
|
||||
const run = agentRun && typeof agentRun === "object" ? agentRun : null;
|
||||
return Boolean(run?.runId && run?.commandId && !safeTraceId(run.traceId));
|
||||
}
|
||||
|
||||
function agentRunEvidenceMatchesTrace(agentRun, traceId, traceEvidence = null, options = {}) {
|
||||
const id = safeTraceId(traceId);
|
||||
if (!id) return false;
|
||||
const run = agentRun && typeof agentRun === "object" ? agentRun : null;
|
||||
const runTraceId = safeTraceId(run?.traceId);
|
||||
if (run?.commandId && runTraceId && runTraceId !== id) return false;
|
||||
if (options.requireAgentRunTraceId === true && run?.commandId && runTraceId !== id) return false;
|
||||
const providerTrace = run?.providerTrace && typeof run.providerTrace === "object" ? run.providerTrace : null;
|
||||
const summary = traceEvidence?.traceSummary && typeof traceEvidence.traceSummary === "object" ? traceEvidence.traceSummary : null;
|
||||
const summaryRun = summary?.agentRun && typeof summary.agentRun === "object" ? summary.agentRun : null;
|
||||
const finalResponse = traceEvidence?.finalResponse && typeof traceEvidence.finalResponse === "object" ? traceEvidence.finalResponse : null;
|
||||
const traceIds = [runTraceId, providerTrace?.traceId, summary?.traceId, finalResponse?.traceId]
|
||||
.map((value) => safeTraceId(value))
|
||||
.filter(Boolean);
|
||||
if (traceIds.some((value) => value !== id)) return false;
|
||||
const commandIds = [run?.commandId, providerTrace?.commandId, summaryRun?.commandId]
|
||||
.map((value) => text(value))
|
||||
.filter(Boolean);
|
||||
if (commandIds.length > 1 && new Set(commandIds).size > 1) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
export function agentRunSessionEvidence(payload = {}) {
|
||||
if (!payload?.agentRun) return {};
|
||||
return {
|
||||
@@ -1314,7 +1214,7 @@ function agentRunToolCalls(result = {}, status = "completed") {
|
||||
}];
|
||||
}
|
||||
|
||||
function agentRunResultToCodeAgentPayload({ base, result, traceStore, traceId }) {
|
||||
function agentRunResultToCodeAgentPayload({ base, result, traceStore, traceId, appendResultEvent = true }) {
|
||||
const terminalStatus = String(result?.terminalStatus ?? "");
|
||||
const terminal = terminalStatus === "completed" || terminalStatus === "failed" || terminalStatus === "blocked" || terminalStatus === "cancelled";
|
||||
if (!terminal) {
|
||||
@@ -1325,17 +1225,21 @@ function agentRunResultToCodeAgentPayload({ base, result, traceStore, traceId })
|
||||
const terminalEventCreatedAt = agentRunResultTraceCreatedAt(runnerTrace, now);
|
||||
const providerTrace = agentRunProviderTrace({ base, result, terminalStatus });
|
||||
if (terminalStatus === "completed" && String(result?.reply ?? "").trim()) {
|
||||
traceStore.append(traceId, {
|
||||
type: "result",
|
||||
status: "completed",
|
||||
label: "agentrun:result:completed",
|
||||
createdAt: terminalEventCreatedAt,
|
||||
message: "AgentRun result is ready for HWLAB short-connection polling.",
|
||||
runId: base.agentRun.runId,
|
||||
commandId: base.agentRun.commandId,
|
||||
terminal: true,
|
||||
valuesPrinted: false
|
||||
});
|
||||
const finalResponse = agentRunCompletedFinalResponse({ base, result, traceId, now });
|
||||
const traceSummary = agentRunCompletedTraceSummary({ base, runnerTrace, finalResponse, traceId });
|
||||
if (appendResultEvent) {
|
||||
traceStore.append(traceId, {
|
||||
type: "result",
|
||||
status: "completed",
|
||||
label: "agentrun:result:completed",
|
||||
createdAt: terminalEventCreatedAt,
|
||||
message: "AgentRun result is ready for HWLAB short-connection polling.",
|
||||
runId: base.agentRun.runId,
|
||||
commandId: base.agentRun.commandId,
|
||||
terminal: true,
|
||||
valuesPrinted: false
|
||||
});
|
||||
}
|
||||
return {
|
||||
...base,
|
||||
status: "completed",
|
||||
@@ -1350,11 +1254,13 @@ function agentRunResultToCodeAgentPayload({ base, result, traceStore, traceId })
|
||||
skills: { status: "delegated", provider: ADAPTER_ID, count: 0, items: [], valuesPrinted: false },
|
||||
longLivedSessionGate: agentRunLongLivedSessionGate(base),
|
||||
providerTrace,
|
||||
finalResponse,
|
||||
traceSummary,
|
||||
reply: {
|
||||
messageId: base.messageId ?? `msg_${traceId.slice(4)}`,
|
||||
messageId: finalResponse.messageId,
|
||||
role: "assistant",
|
||||
content: String(result.reply),
|
||||
createdAt: now
|
||||
content: finalResponse.text,
|
||||
createdAt: finalResponse.createdAt
|
||||
},
|
||||
usage: null,
|
||||
agentRun: { ...base.agentRun, terminalStatus, completed: true, reuseEligible: true, providerTrace, valuesPrinted: false },
|
||||
@@ -1365,18 +1271,20 @@ function agentRunResultToCodeAgentPayload({ base, result, traceStore, traceId })
|
||||
const code = canceled ? "agentrun_canceled" : result?.failureKind ?? (terminalStatus === "blocked" ? "agentrun_blocked" : "agentrun_failed");
|
||||
const message = result?.failureMessage ?? result?.blocker?.message ?? (canceled ? "AgentRun command was canceled" : "AgentRun command failed");
|
||||
const attribution = agentRunFailureAttribution({ code, message, canceled });
|
||||
traceStore.append(traceId, {
|
||||
type: "result",
|
||||
status: canceled ? "canceled" : "failed",
|
||||
label: `agentrun:result:${canceled ? "canceled" : terminalStatus || "failed"}`,
|
||||
createdAt: terminalEventCreatedAt,
|
||||
errorCode: code,
|
||||
message: attribution.summary,
|
||||
runId: base.agentRun.runId,
|
||||
commandId: base.agentRun.commandId,
|
||||
terminal: true,
|
||||
valuesPrinted: false
|
||||
});
|
||||
if (appendResultEvent) {
|
||||
traceStore.append(traceId, {
|
||||
type: "result",
|
||||
status: canceled ? "canceled" : "failed",
|
||||
label: `agentrun:result:${canceled ? "canceled" : terminalStatus || "failed"}`,
|
||||
createdAt: terminalEventCreatedAt,
|
||||
errorCode: code,
|
||||
message: attribution.summary,
|
||||
runId: base.agentRun.runId,
|
||||
commandId: base.agentRun.commandId,
|
||||
terminal: true,
|
||||
valuesPrinted: false
|
||||
});
|
||||
}
|
||||
const partialContext = partialAgentRunContext(runnerTrace);
|
||||
return {
|
||||
...base,
|
||||
@@ -1418,6 +1326,47 @@ function agentRunResultToCodeAgentPayload({ base, result, traceStore, traceId })
|
||||
};
|
||||
}
|
||||
|
||||
function agentRunCompletedFinalResponse({ base, result, traceId, now }) {
|
||||
const textValue = String(result?.reply ?? "").trim();
|
||||
return {
|
||||
text: textValue,
|
||||
textChars: textValue.length,
|
||||
role: "assistant",
|
||||
status: "completed",
|
||||
traceId,
|
||||
messageId: base.messageId ?? base.reply?.messageId ?? `msg_${traceId.slice(4)}`,
|
||||
createdAt: base.reply?.createdAt ?? base.createdAt ?? now,
|
||||
updatedAt: now,
|
||||
valuesPrinted: false
|
||||
};
|
||||
}
|
||||
|
||||
function agentRunCompletedTraceSummary({ base, runnerTrace, finalResponse, traceId }) {
|
||||
const events = Array.isArray(runnerTrace?.events) ? runnerTrace.events : [];
|
||||
const lastSeq = Math.max(0, ...events.map((event) => Number(event?.seq ?? 0)).filter(Number.isFinite));
|
||||
return {
|
||||
traceId,
|
||||
source: "agentrun-command-result",
|
||||
sourceEventCount: Number(runnerTrace?.eventCount ?? events.length ?? 0),
|
||||
terminalStatus: "completed",
|
||||
finalAssistantRow: {
|
||||
role: finalResponse.role,
|
||||
status: finalResponse.status,
|
||||
textChars: finalResponse.textChars,
|
||||
textPreview: finalResponse.text.slice(0, 240),
|
||||
messageId: finalResponse.messageId,
|
||||
valuesPrinted: false
|
||||
},
|
||||
agentRun: {
|
||||
runId: base.agentRun?.runId ?? null,
|
||||
commandId: base.agentRun?.commandId ?? null,
|
||||
lastSeq,
|
||||
valuesPrinted: false
|
||||
},
|
||||
valuesPrinted: false
|
||||
};
|
||||
}
|
||||
|
||||
function partialAgentRunContext(runnerTrace = {}) {
|
||||
const events = Array.isArray(runnerTrace.events) ? runnerTrace.events : [];
|
||||
const assistantMessages = events
|
||||
|
||||
Reference in New Issue
Block a user