From 1c4cf292745da0142d76951140e36cae0ef80a5d Mon Sep 17 00:00:00 2001 From: lyon Date: Sat, 20 Jun 2026 11:17:57 +0800 Subject: [PATCH] feat: enrich AgentRun dispatch error OTel spans --- internal/cloud/server-code-agent-http.ts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/internal/cloud/server-code-agent-http.ts b/internal/cloud/server-code-agent-http.ts index cf5a93b8..4314f522 100644 --- a/internal/cloud/server-code-agent-http.ts +++ b/internal/cloud/server-code-agent-http.ts @@ -829,10 +829,11 @@ async function submitCodeAgentChatTurn({ params, options, traceId }) { }); } catch (error) { if (isCodeAgentResultCanceled(results.get(traceId))) return; + const dispatchErrorAttributes = codeAgentDispatchErrorOtelAttributes(error); void emitCodeAgentOtelSpan("agentrun_dispatch", traceId, executionOptions.env ?? process.env, { status: "error", error, - attributes: { sessionId: safeSessionId(params.sessionId) || null, turnId: codeAgentTurnLifecycleFields(traceId, params).turnId } + attributes: { sessionId: safeSessionId(params.sessionId) || null, turnId: codeAgentTurnLifecycleFields(traceId, params).turnId, ...dispatchErrorAttributes } }); await settleAdmittedCodeAgentFailure({ base: initial ?? codeAgentAdmittedFailureBasePayload({ params, options, traceId }), @@ -1028,6 +1029,23 @@ function codeAgentDispatchFailure(error) { }; } +function codeAgentDispatchErrorOtelAttributes(error) { + const agentRunError = error?.agentRunError && typeof error.agentRunError === "object" ? error.agentRunError : null; + const details = agentRunError?.error?.details && typeof agentRunError.error.details === "object" ? agentRunError.error.details : null; + return { + failureKind: safeOtelText(error?.code ?? agentRunError?.failureKind, 120), + upstreamStatusCode: Number.isInteger(error?.statusCode) ? error.statusCode : null, + upstreamTraceId: safeTraceId(agentRunError?.traceId) || null, + upstreamMessage: safeOtelText(agentRunError?.message ?? error?.message, 300), + upstreamStderrTail: safeOtelText(details?.stderr, 600) + }; +} + +function safeOtelText(value, limit = 300) { + const text = String(value ?? "").replace(/[\u0000-\u001f\u007f]+/gu, " ").trim(); + return text ? text.slice(0, limit) : null; +} + function codeAgentAdmittedFailureBasePayload({ params = {}, options = {}, traceId } = {}) { const now = new Date().toISOString(); return {