From 410783c12661baaead06f5ee9e76133e57abda06 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Sun, 26 Apr 2026 13:57:46 -0700 Subject: [PATCH] fix(diagnostics): chain run traces to request scope --- src/agents/pi-embedded-runner/run/attempt.ts | 6 +++-- src/infra/diagnostic-trace-context.test.ts | 28 ++++++++++++++++++++ src/infra/diagnostic-trace-context.ts | 10 +++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/agents/pi-embedded-runner/run/attempt.ts b/src/agents/pi-embedded-runner/run/attempt.ts index 7a44cec7bd2..e05a9571e70 100644 --- a/src/agents/pi-embedded-runner/run/attempt.ts +++ b/src/agents/pi-embedded-runner/run/attempt.ts @@ -12,8 +12,8 @@ import { filterHeartbeatPairs } from "../../../auto-reply/heartbeat-filter.js"; import { resolveChannelCapabilities } from "../../../config/channel-capabilities.js"; import { emitTrustedDiagnosticEvent } from "../../../infra/diagnostic-events.js"; import { - createDiagnosticTraceContext, createChildDiagnosticTraceContext, + createDiagnosticTraceContextFromActiveScope, freezeDiagnosticTraceContext, } from "../../../infra/diagnostic-trace-context.js"; import { isEmbeddedMode } from "../../../infra/embedded-mode.js"; @@ -648,7 +648,9 @@ export async function runEmbeddedAttempt( const sessionLabel = params.sessionKey ?? params.sessionId; const contextInjectionMode = resolveContextInjectionMode(params.config); const agentDir = params.agentDir ?? resolveOpenClawAgentDir(); - const diagnosticTrace = freezeDiagnosticTraceContext(createDiagnosticTraceContext()); + const diagnosticTrace = freezeDiagnosticTraceContext( + createDiagnosticTraceContextFromActiveScope(), + ); const runTrace = freezeDiagnosticTraceContext( createChildDiagnosticTraceContext(diagnosticTrace), ); diff --git a/src/infra/diagnostic-trace-context.test.ts b/src/infra/diagnostic-trace-context.test.ts index 91c24dd9649..2f678edcb0f 100644 --- a/src/infra/diagnostic-trace-context.test.ts +++ b/src/infra/diagnostic-trace-context.test.ts @@ -2,6 +2,7 @@ import { afterEach, describe, expect, it } from "vitest"; import { createChildDiagnosticTraceContext, createDiagnosticTraceContext, + createDiagnosticTraceContextFromActiveScope, freezeDiagnosticTraceContext, formatDiagnosticTraceparent, getActiveDiagnosticTraceContext, @@ -158,4 +159,31 @@ describe("diagnostic-trace-context", () => { expect(getActiveDiagnosticTraceContext()).toBeUndefined(); }); + + it("creates child trace contexts from the active request scope", () => { + const requestTrace = createDiagnosticTraceContext({ + traceId: TRACE_ID, + spanId: SPAN_ID, + traceFlags: "00", + }); + + runWithDiagnosticTraceContext(requestTrace, () => { + const scoped = createDiagnosticTraceContextFromActiveScope({ + spanId: CHILD_SPAN_ID, + }); + + expect(scoped).toEqual({ + traceId: TRACE_ID, + spanId: CHILD_SPAN_ID, + parentSpanId: SPAN_ID, + traceFlags: "00", + }); + }); + + expect(createDiagnosticTraceContextFromActiveScope({ spanId: CHILD_SPAN_ID })).toEqual({ + traceId: expect.stringMatching(/^[0-9a-f]{32}$/), + spanId: CHILD_SPAN_ID, + traceFlags: "01", + }); + }); }); diff --git a/src/infra/diagnostic-trace-context.ts b/src/infra/diagnostic-trace-context.ts index 87c97d0d567..d8705af730e 100644 --- a/src/infra/diagnostic-trace-context.ts +++ b/src/infra/diagnostic-trace-context.ts @@ -198,6 +198,16 @@ export function createChildDiagnosticTraceContext( }); } +export function createDiagnosticTraceContextFromActiveScope( + input: Omit = {}, +): DiagnosticTraceContext { + const active = getActiveDiagnosticTraceContext(); + if (!active) { + return createDiagnosticTraceContext(input); + } + return createChildDiagnosticTraceContext(active, input); +} + export function freezeDiagnosticTraceContext( context: DiagnosticTraceContext, ): DiagnosticTraceContext {