Skip to main content
initialize() must run before your LLM SDK is imported (the rule is explained on Installation). In Next.js the only place that’s guaranteed is the instrumentation.ts hook at your project root (or src/instrumentation.ts if you use a src/ folder):
Do not call initialize() from inside a route file. Always pass instrumentModules in Next.js (only the SDKs you actually use): the bundler can load LLM SDKs in ways auto-instrumentation can’t see, which silently drops all LLM spans.

Keep LLM SDKs external

Keep the LLM SDKs external so every bundle shares one runtime copy. If they get inlined, each bundle has its own private copy and instrumentModules patches one your routes never use. List belvedir itself as well: a route or server action that bundles its own copy calls withSession()/flush() on an uninitialized duplicate, so flush silently no-ops and spans drop on serverless.
On Next 13/14 the key is experimental.serverComponentsExternalPackages; the Next 15 name is silently ignored there, and the build prints an Unrecognized key(s) warning you shouldn’t ignore.

Use the Node.js runtime

The SDK needs Node.js APIs, so a route declared with export const runtime = "edge" runs untraced: the logs show initialize() failed; the app will run untraced and no spans arrive. Use the Node.js runtime (export const runtime = "nodejs", the default) for every route that makes LLM calls.

Deploying on Vercel

Set BELVEDIR_API_KEY in your Vercel project’s Environment Variables, then redeploy. Vercel functions can freeze or exit as soon as the response is sent, before batched spans export, so await flush() at the end of every handler that makes LLM calls; see Flush on serverless.