From 0c6da1a76e3658a35b85289118a9bcf9b552743f Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 7 Apr 2026 11:31:33 +0200 Subject: [PATCH 1/2] fix: Add tracing polyfill to `workerd` and `edge-light` runtimes --- js/src/edge-light/config.ts | 8 ++++++ js/src/edge-runtime-bootstrap.test.ts | 39 +++++++++++++++++++++++++++ js/src/workerd/config.ts | 8 ++++++ 3 files changed, 55 insertions(+) diff --git a/js/src/edge-light/config.ts b/js/src/edge-light/config.ts index 69287ef63..74b340c2c 100644 --- a/js/src/edge-light/config.ts +++ b/js/src/edge-light/config.ts @@ -1,6 +1,9 @@ import iso from "../isomorph"; import { _internalSetInitialState } from "../logger"; import { resolveRuntimeAsyncLocalStorage } from "../runtime-async-local-storage"; +import { tracingChannel } from "dc-browser"; +import { patchTracingChannel } from "../auto-instrumentations/patch-tracing-channel"; +import { registry } from "../instrumentation/registry"; let edgeLightConfigured = false; @@ -20,6 +23,10 @@ export function configureEdgeLight(): void { iso.newAsyncLocalStorage = () => new runtimeAsyncLocalStorage(); } + iso.newTracingChannel = <_M = unknown>(nameOrChannels: string | object) => + tracingChannel(nameOrChannels); + patchTracingChannel(tracingChannel); + iso.getEnv = (name: string) => { if (typeof process === "undefined" || typeof process.env === "undefined") { return undefined; @@ -39,5 +46,6 @@ export function configureEdgeLight(): void { }; _internalSetInitialState(); + registry.enable(); edgeLightConfigured = true; } diff --git a/js/src/edge-runtime-bootstrap.test.ts b/js/src/edge-runtime-bootstrap.test.ts index 6dc61cafa..b3e81a2ac 100644 --- a/js/src/edge-runtime-bootstrap.test.ts +++ b/js/src/edge-runtime-bootstrap.test.ts @@ -108,5 +108,44 @@ describe.each([ expect(result.childRootSpanId).toBe(root.spanId); expect(await backgroundLogger.drain()).toHaveLength(3); }); + + test("wrapAISDK logs spans in edge runtimes", async () => { + const braintrust = await import(entrypoint); + + braintrust._exportsForTestingOnly.setInitialTestState(); + await braintrust._exportsForTestingOnly.simulateLoginForTests(); + + const backgroundLogger = + braintrust._exportsForTestingOnly.useTestBackgroundLogger(); + braintrust.initLogger({ + projectId: "test-project-id", + projectName, + }); + + await braintrust.traced(async () => "ok", { name: "root" }); + + const wrapped = braintrust.wrapAISDK({ + generateText: async () => ({ + finishReason: "stop", + text: "ok", + usage: { + completionTokens: 1, + promptTokens: 1, + totalTokens: 2, + }, + }), + }); + + await wrapped.generateText({ + model: { modelId: "fake-model", provider: "fake-provider" }, + prompt: "hello", + }); + + const spans = await backgroundLogger.drain(); + const spanNames = spans.map((span) => span.span_attributes?.name); + + expect(spanNames).toContain("root"); + expect(spanNames).toContain("generateText"); + }); }, ); diff --git a/js/src/workerd/config.ts b/js/src/workerd/config.ts index 3bdba2a9d..d4e2a0e15 100644 --- a/js/src/workerd/config.ts +++ b/js/src/workerd/config.ts @@ -1,6 +1,9 @@ import iso from "../isomorph"; import { _internalSetInitialState } from "../logger"; import { resolveRuntimeAsyncLocalStorage } from "../runtime-async-local-storage"; +import { tracingChannel } from "dc-browser"; +import { patchTracingChannel } from "../auto-instrumentations/patch-tracing-channel"; +import { registry } from "../instrumentation/registry"; let workerdConfigured = false; @@ -20,6 +23,10 @@ export function configureWorkerd(): void { iso.newAsyncLocalStorage = () => new runtimeAsyncLocalStorage(); } + iso.newTracingChannel = <_M = unknown>(nameOrChannels: string | object) => + tracingChannel(nameOrChannels); + patchTracingChannel(tracingChannel); + iso.getEnv = (name: string) => { if (typeof process === "undefined" || typeof process.env === "undefined") { return undefined; @@ -39,5 +46,6 @@ export function configureWorkerd(): void { }; _internalSetInitialState(); + registry.enable(); workerdConfigured = true; } From b8d5c143aea9b0144798cff83557c4bc926d7a55 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Tue, 7 Apr 2026 11:51:21 +0200 Subject: [PATCH 2/2] fix typing --- js/src/edge-light/config.ts | 11 +++++++++-- js/src/workerd/config.ts | 11 +++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/js/src/edge-light/config.ts b/js/src/edge-light/config.ts index 74b340c2c..c32c40635 100644 --- a/js/src/edge-light/config.ts +++ b/js/src/edge-light/config.ts @@ -1,4 +1,8 @@ import iso from "../isomorph"; +import type { + IsoTracingChannel, + IsoTracingChannelCollection, +} from "../isomorph"; import { _internalSetInitialState } from "../logger"; import { resolveRuntimeAsyncLocalStorage } from "../runtime-async-local-storage"; import { tracingChannel } from "dc-browser"; @@ -23,8 +27,11 @@ export function configureEdgeLight(): void { iso.newAsyncLocalStorage = () => new runtimeAsyncLocalStorage(); } - iso.newTracingChannel = <_M = unknown>(nameOrChannels: string | object) => - tracingChannel(nameOrChannels); + iso.newTracingChannel = ( + nameOrChannels: string | IsoTracingChannelCollection, + ) => + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + tracingChannel(nameOrChannels as string | object) as IsoTracingChannel; patchTracingChannel(tracingChannel); iso.getEnv = (name: string) => { diff --git a/js/src/workerd/config.ts b/js/src/workerd/config.ts index d4e2a0e15..cc4f40b7a 100644 --- a/js/src/workerd/config.ts +++ b/js/src/workerd/config.ts @@ -1,4 +1,8 @@ import iso from "../isomorph"; +import type { + IsoTracingChannel, + IsoTracingChannelCollection, +} from "../isomorph"; import { _internalSetInitialState } from "../logger"; import { resolveRuntimeAsyncLocalStorage } from "../runtime-async-local-storage"; import { tracingChannel } from "dc-browser"; @@ -23,8 +27,11 @@ export function configureWorkerd(): void { iso.newAsyncLocalStorage = () => new runtimeAsyncLocalStorage(); } - iso.newTracingChannel = <_M = unknown>(nameOrChannels: string | object) => - tracingChannel(nameOrChannels); + iso.newTracingChannel = ( + nameOrChannels: string | IsoTracingChannelCollection, + ) => + // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + tracingChannel(nameOrChannels as string | object) as IsoTracingChannel; patchTracingChannel(tracingChannel); iso.getEnv = (name: string) => {