Skip to content

chore(weave_ts): Weave Node SDK — dual-build PR 1: source-code compatibility fixups#6682

Open
chance-wnb wants to merge 1 commit intochance/instrument_ts_fixfrom
chance/sdk_dual_build1
Open

chore(weave_ts): Weave Node SDK — dual-build PR 1: source-code compatibility fixups#6682
chance-wnb wants to merge 1 commit intochance/instrument_ts_fixfrom
chance/sdk_dual_build1

Conversation

@chance-wnb
Copy link
Copy Markdown
Contributor

@chance-wnb chance-wnb commented Apr 22, 2026

Weave Node SDK — dual-build PR 1: source-code compatibility fixups

First of a PR stack that migrates the Weave Node SDK from CJS-only to dual CJS/ESM. The background, motivation, and full plan are in Tech-Report-Should-the-Weave-Node-SDK-ship-a-dual-CJS-ESM-build (see §7 for the PR breakdown).

This PR contains only source-code refactors. No build-tool changes, no package.json exports changes, no new published entry points. The current CJS tsc build output is unchanged in shape; all existing consumers continue to work identically.

Why this PR exists

Before we can flip on a dual build (PR 2), the source tree has to compile cleanly to both CJS and ESM. Three classes of source-level CJS-isms would break under ESM emit today, and all of them are fixed here:

  1. __dirname usage — doesn't exist in ESM output.
  2. Runtime require() of an ESM-or-CJS dependency — doesn't exist in ESM output, and even in CJS can trigger duplicate module loads that reset shared state (the exact class of bug described in §4 of the report).
  3. Module-scoped mutable state — survives ESM emit, but any module that ends up loaded twice (CJS copy + ESM copy, the "dual-package hazard") produces two independent copies of that state. Singletons keyed on globalThis[Symbol.for(...)] resolve to the same object across copies.

Changes

1. Replace __dirname in src/utils/userAgent.ts with build-time version generation

  • New scripts/generate-version.mjs: reads package.json, writes src/utils/generatedVersion.ts as a static export const packageVersion = "…". The script is .mjs so Node treats it as ESM regardless of the package's "type" field.
  • userAgent.ts now re-exports the constant; no filesystem access, no __dirname, no import.meta.url. Works identically in CJS and ESM output.
  • Wired into package.json as prebuild and pretest; generated file added to .gitignore.

2. Remove runtime require('@openai/agents-realtime') in openai.realtime.agent.ts

  • patchRealtimeSession() used to synchronously require('@openai/agents-realtime') as a manual fallback. That doesn't exist in ESM output, and under CJS risked loading a second module copy (same §4 bug shape).
  • Rewritten to use dynamic await import('@openai/agents-realtime') — compiles cleanly to both CJS and ESM.
  • Public API break: patchRealtimeSession(): voidpatchRealtimeSession(): Promise<boolean>. Mirrors the existing analog instrumentOpenAIAgents(), which is already async. Acceptable at 0.13.0 (pre-1.0). The JSDoc is updated; callers now need to await it.
  • Includes a post-await re-check of the patched flag to handle the race where the dynamic import itself triggers the ESM hook (which would otherwise cause RealtimeSession.prototype.sendAudio to be double-wrapped).

3. Audit module-scoped state → globalThis[Symbol.for(...)] singletons

New helper src/utils/globalSingleton.ts encapsulates the "get-or-init from globalThis[Symbol.for(key)]" pattern so each call site is a one-liner and key duplication is impossible.

Migrated to the helper:

New migrations introduced by this PR:

Pre-existing migrations refactored onto the helper (no behavior change, just deduping the inline || pattern):

Left as-is on purpose:

  • src/utils/commonJSLoader.ts — state is CJS-loader-local by design and guarded by typeof module !== 'undefined'. Under dual build, the ESM copy's patching block is skipped entirely. ESM-compile compatibility of this file is a PR 2 concern.

What is explicitly NOT in this PR

  • No tsup introduction, no package.json exports changes, no .mjs output, no .d.mts files. Those are PR 2.
  • No CI guardrails (publint, @arethetypeswrong/cli). Those are PR 4.
  • No integration test fixtures exercising both CJS and ESM hosts. That's PR 3.

Test plan

  • pnpm run build — clean TypeScript compile.
  • WANDB_API_KEY=dummy pnpm run test — 183 passed, 7 skipped (pre-existing live-network tests), 0 failed. Same counts as master.

Follow-up

Next in the stack is PR 2 (dual build via tsup + conditional exports), which is where the refactors in this PR actually start paying off. See §7 of Tech-Report-Should-the-Weave-Node-SDK-ship-a-dual-CJS-ESM-build for the remaining scope.

Copy link
Copy Markdown
Contributor Author

chance-wnb commented Apr 22, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@wandbot-3000
Copy link
Copy Markdown

wandbot-3000 Bot commented Apr 22, 2026

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@chance-wnb chance-wnb changed the title Weave Node SDK — dual-build PR 1: source-code compatibility fixups chore(weave): Weave Node SDK — dual-build PR 1: source-code compatibility fixups Apr 22, 2026
@chance-wnb chance-wnb changed the base branch from master to graphite-base/6682 April 22, 2026 22:07
@chance-wnb chance-wnb force-pushed the chance/sdk_dual_build1 branch from 9d65f30 to 89dae95 Compare April 22, 2026 22:07
@chance-wnb chance-wnb changed the base branch from graphite-base/6682 to chance/instrument_ts_fix April 22, 2026 22:07
@chance-wnb chance-wnb marked this pull request as ready for review April 22, 2026 22:10
@chance-wnb chance-wnb requested a review from a team as a code owner April 22, 2026 22:10
@chance-wnb chance-wnb changed the title chore(weave): Weave Node SDK — dual-build PR 1: source-code compatibility fixups chore(weave_ts): Weave Node SDK — dual-build PR 1: source-code compatibility fixups Apr 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant