From 2bf8f9ec9714cbd33a0ecfb7b40dd7a335180fb7 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Fri, 5 Jun 2026 15:35:21 +0900 Subject: fix(observability): nest turn/step/prompt/provider.request spans into a tree (+ buildSpanOpen parent propagation) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit run-turn: step is now turnSpan.child; prompt/provider.request/tool-call are step's children (stepSpan.log passed into provider.stream). logger.ts: buildSpanOpen now propagates the child's computed parentSpanId onto the span-open record — a latent bug where span.child(...) never set parentSpanId on open (close was already correct). Verified: tsc -b clean, 279 tests, biome 0/0. Live: span tree turn->step->{prompt,provider.request}; the trace CLI easy-view renders the nesting. --- packages/kernel/src/logging/logger.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'packages/kernel/src/logging/logger.ts') diff --git a/packages/kernel/src/logging/logger.ts b/packages/kernel/src/logging/logger.ts index 507ace6..70bc18c 100644 --- a/packages/kernel/src/logging/logger.ts +++ b/packages/kernel/src/logging/logger.ts @@ -82,6 +82,7 @@ function buildSpanOpen( spanId: string, attrs?: Attributes, body?: string, + parentSpanId?: string, ): SpanOpenRecord { const base = { kind: "span-open" as const, @@ -91,11 +92,12 @@ function buildSpanOpen( extensionId: state.ctx.extensionId, }; const merged = mergeAttributes(state.attrs, attrs); + const effectiveParent = parentSpanId ?? state.ctx.parentSpanId; return { ...base, ...(state.ctx.conversationId !== undefined ? { conversationId: state.ctx.conversationId } : {}), ...(state.ctx.turnId !== undefined ? { turnId: state.ctx.turnId } : {}), - ...(state.ctx.parentSpanId !== undefined ? { parentSpanId: state.ctx.parentSpanId } : {}), + ...(effectiveParent !== undefined ? { parentSpanId: effectiveParent } : {}), ...(merged !== undefined ? { attributes: merged } : {}), ...(body !== undefined ? { body } : {}), }; @@ -145,7 +147,7 @@ export function createLogger( ...(mergedParent !== undefined ? { parentSpanId: mergedParent } : {}), }; - const openRecord = buildSpanOpen(state, name, spanId, spanAttrs, body); + const openRecord = buildSpanOpen(state, name, spanId, spanAttrs, body, mergedParent); const spanAttrsMutable: Record = spanAttrs !== undefined ? { ...spanAttrs } : {}; const links: SpanLink[] = []; -- cgit v1.2.3