Repository navigation
Conversation
size-limit report 📦Compared: 8cc0b63 (PR test merge using develop at 2c5b8f8) Against: 2c5b8f8 (develop) · base run #64128 ✅ Baseline matches: this diff contains only this PR's changes.
|
Optional E2E testsSome optional checks were not successful. They do not block the merge. 1 not successful, 56 successful. See the run.
Successful checks
|
| jsdom-worker: | ||
| specifier: ^0.3.0 | ||
| version: 0.3.0(node-fetch@2.7.0(encoding@0.1.13)) | ||
| version: 0.3.0(node-fetch@3.3.2) |
There was a problem hiding this comment.
Lockfile pins jsdom-worker to node-fetch 3
Medium Severity
Adding @earendil-works/pi-ai pulled node-fetch@3 into the workspace, and pnpm now satisfies jsdom-worker's node-fetch: * peer with that ESM-only release instead of node-fetch@2. jsdom-worker loads the peer with require(), which fails on v3, so @sentry/replay unit tests that import it are likely to break.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 94cc573. Configure here.
There was a problem hiding this comment.
this seems fine, as long as tests pass this should be ok.
| ...(model.provider ? { [GEN_AI_PROVIDER_NAME]: model.provider } : {}), | ||
| ...(model.id ? { [GEN_AI_REQUEST_MODEL]: model.id } : {}), | ||
| ...(conversationId ? { [GEN_AI_CONVERSATION_ID]: conversationId } : {}), | ||
| ...getServerAttributes(model), | ||
| ...(streaming ? { [GEN_AI_RESPONSE_STREAMING]: true } : {}), | ||
| ...(callOptions?.temperature !== undefined ? { [GEN_AI_REQUEST_TEMPERATURE]: callOptions.temperature } : {}), | ||
| ...(callOptions?.maxTokens !== undefined ? { [GEN_AI_REQUEST_MAX_TOKENS]: callOptions.maxTokens } : {}), | ||
| ...(callOptions?.reasoning ? { [GEN_AI_REQUEST_REASONING_LEVEL]: callOptions.reasoning } : {}), | ||
| ...(recordInputs && context ? getRequestContentAttributes(context) : {}), |
There was a problem hiding this comment.
all of this seems redundant, we can just define undefined values without spreading everywhere, this has the same effect.
| } | ||
|
|
||
| /** | ||
| * Diagnostics-channel-based integration for pi-ai (`@earendil-works/pi-ai` >= 0.80.0 < 2, whose API |
There was a problem hiding this comment.
the comment is too implementation specific, it should explain what it does for a consumer of the integration.
There was a problem hiding this comment.
The core approach holds up. I checked pi-ai 0.80.1, 0.85.1 and 1.4.0: complete* and fetchDeferred call their stream* counterpart synchronously before the first await, and compat hands off to compatModels.stream synchronously too. So the depth counter does dedupe the nested calls, and node-flue and the pi-durable e2e apps pass in CI. A few things before this lands:
- Cloudflare + Flue workers fail at startup.
cloudflare-flue-send-to-sentryfails at deploy validation withUncaught ReferenceError: Cannot access 'ModelsImpl' before initialization ... in createModels(job). It's the same error on all three runs of this branch, and it isn't caused by the missing OpenRouter key. My guess, which I haven't verified locally: this is an import cycle that pi-ai's new transform creates. The snippet injected intodist/models.js/dist/compat.jsimports@sentry/server-utils. That package's flue integration module has the@flue/runtimeimport added by the Vite provided-module plugin.@flue/runtimethen reachescreateModels()at module top level (via pi-ai'scompat), whilemodels.jsis still waiting on its own imports.cloudflare-pi-durable, which has no provided-module import, passes, which fits. Please break the cycle at the snippet/plugin layer rather than with a lazy import, and keep this e2e as the regression check. - CI.
Check lockfilefails on94cc5731("Run pnpm dedupe to apply the changes above"), and the branch now conflicts withdevelop, so the head commit5939453fhas no Build & Test run. - Release note.
skipPiAiProviderIntegrations()now runs on the first request through any pi-ai app, not just Flue/pi-durable ones. An app that calls pi-ai directly and also usesopenai/@anthropic-ai/sdk/@google/genaiitself loses those integrations' spans for the whole process. The JSDoc covers this, but it should also go in the release note next to the origin change.
Traces every `@earendil-works/pi-ai` request as a `gen_ai.chat` span, from the `Models` methods and the standalone `compat` functions. Flue and pi-durable send their model calls through pi-ai, so they no longer open chat spans of their own and rely on this integration instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`compat` loads pi-ai's model catalog with a JSON import, and Deno 2.8 drops import attributes once a module hook is registered, compiling the JSON as JavaScript. The `Models` test still runs on Deno. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…i suites Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Flue's model calls are now traced by the pi-ai integration, which needs the module hook or bundler plugin, while `instrument()` does not. Without them a Flue app silently lost its `gen_ai.chat` spans; it now gets a warning on its first model call. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The deferred calls pass a handle where the others pass the request, which the request mapping already reads as empty, so they share the `stream` and `complete` channels. Also drops comments and fields that still described the removed Flue turn spans, test cases already covered by the pi-ai helper tests, and corrects the engines comments of the pi suites: pnpm installs packages whose `engines` exclude the running Node. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
5939453 to
ec04022
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ec04022. Configure here.
…ead of `@sentry/server-utils` Every orchestrion-instrumented module imports `@sentry/server-utils`, so the `@flue/runtime` import spliced into its Flue integration closed a cycle through pi-ai, now that pi-ai is instrumented: an entry that loads pi-ai first ran Flue's module-level `createModels()` before pi-ai's `ModelsImpl` was initialized, and the worker failed at startup. Co-Authored-By: Francesco Gringl-Novy <francesco.novy@sentry.io>
Sets the optional span attributes directly, as span attributes drop `undefined` values, and describes `piAiIntegration` for its users. Co-Authored-By: Francesco Gringl-Novy <francesco.novy@sentry.io>
Co-Authored-By: Francesco Gringl-Novy <francesco.novy@sentry.io>
valibot 1.1.0 is affected by GHSA-vqpr-j7v3-hqw9, which fails dependency review. Co-Authored-By: Francesco Gringl-Novy <francesco.novy@sentry.io>
…tions Co-Authored-By: Francesco Gringl-Novy <francesco.novy@sentry.io>
Upgrade `@sentry/node` and `@sentry/nitro` to 11.10.0. Library instrumentation now uses build-time orchestrion instead of a runtime `--import` hook. Closes #2334 ## Build-time instrumentation - `juniorNitro()` adds the orchestrion Rollup plugin from `@sentry/server-utils/orchestrion/rollup`. Every Junior app gets library spans with no config change. `@sentry/nitro` adds only source maps and the Nitro request channel. - Remove `instrument.mjs`, `cross-env`, and `NODE_OPTIONS=--import` from `apps/example` and the `junior init` scaffold. `server.ts` already calls `initSentry()` first. - Remove the `import-in-the-middle` bundling workaround. v11 does not use it. - `nitro dev` does not bundle `node_modules`, so dev gets no library spans. Under v11 the old `--import` did not give them either. ## SDK options - `sendDefaultPii` → `dataCollection`. Collect only incoming request bodies, because outgoing calls carry prompts that the payload filter does not see. Set `databaseQueryData: false`. - Remove `traceLifecycle`, `registerEsmLoaderHooks`, `streamGenAiSpans`, `enableLogs`, `withStreamedSpan`, and the transaction scrubber. `SENTRY_ENABLE_LOGS=false` still drops logs. - Filter the AI provider integrations (Anthropic, OpenAI, Google, Mistral, Groq, Together, Vercel AI). pi-ai parses provider streams itself, so their spans duplicate Junior's `gen_ai` spans without usage or cost. Remove the filter after getsentry/sentry-javascript#25869. - The web search `generateText` call had no manual span and relied on the Vercel AI integration. It now has its own `gen_ai.chat` span with usage. - Remove `@opentelemetry/api` and `@opentelemetry/core` from Junior, the example app, and the scaffold. Nothing imports them, and v11 does not need them as peers. Remove the `@sentry/cli` build allowance, because v11 no longer installs it. ## Manual instrumentation - Delete `db/tracing.ts`. Sentry's `pg` and Neon spans replace it. Query text is the same and neither records parameter values. The automatic spans add connect spans but lose the PostgreSQL error code, `db.operation.name`, `db.collection.name`, and `app.db.driver`. - Remove the `http.server.request` webhook span and the `GET files.slack.com` span. Sentry's `http.server` and fetch spans replace them. - Automatic fetch spans and breadcrumbs record the request URL. The payload filter now keeps only the `https://files.slack.com` host for private Slack file URLs, because the path names the workspace and file. It also drops `url.fragment`, like `url.query`. - `withSpan` keeps an `error.type` that the callback set. Before, it replaced values such as `rate_limited` with the error name. Remove `setSpanStatus("error")` calls before a `throw`, because Sentry sets the error status. ## Verification - `pnpm typecheck`, `pnpm lint`, `pnpm release:check`, and `pnpm test` pass. - The example Vercel build passes `check-vercel-output.mjs`. - With `SENTRY_DEBUG=1`, a `node_server` build of the example logs `Bundler plugin ran, injected libraries=[@anthropic-ai/sdk, h3, openai, @google/genai, @mistralai/mistralai, @neondatabase/serverless, @redis/client, hono, ai, pg, pg-pool]`, and spans reach the DSN. - Not checked: a Vercel preview deploy against a real Sentry project. ## Review notes - 11.10.0 is younger than `minimumReleaseAge`, so its seven packages are in `minimumReleaseAgeExclude` with exact versions. Remove them later. ## Follow up work * Once getsentry/sentry-javascript#25869 ships, update the SDKs and remove the manual ai spans --------- Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: David Cramer <david@sentry.io>
|
This got a bit complex, I'll split this into some smaller PRs... |
…dependencies (#25933) **Why:** The Flue and pi-durable suites installed their packages through `additionalDependencies`: an unlocked `npm install` into a fresh tmp dir for every `createEsmAndCjsTests` call. That is 3 installs for Flue and 9 for pi-durable, per run and Node version. Measured locally for Flue: ~16s cold / ~3s warm and 210 MB each time. The unpinned `^` ranges also let upstream releases reach CI without review. As root devDependencies they are installed once and pinned by the lockfile. They were kept out because their `engines.node >= 22.19` broke `yarn install` on Node 20. Under pnpm, without `engine-strict`, that is only a warning. Both suites still skip below Node 22. Additionally, we used to use `createEsmAndCjsTests` and then skip for the cjs case. Instead, we can just use `createEsmTests` here. This prepares the split of the pi-ai integration (#25869). **How to review:** Best viewed with whitespace hidden. Dropping the trailing options argument made the formatter re-indent both suites, and switching to `createEsmTests` removed the hand-written CJS skips. No assertions change. The `allowBuilds` entries are for `@google/genai` and `protobufjs`, which the pi packages pull in. **Unsure about:** `pnpm dedupe` (enforced in CI) moves the root `@google/genai` from 1.20.0 to 1.52.0 and bumps some `@aws-sdk`/`@smithy` packages, since pi-ai depends on newer versions. The google-genai and aws-serverless suites pass locally. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>


Why: pi-ai had no instrumentation of its own: only Flue and pi-durable traced its requests, each with its own chat spans (turn observations and a
modelsproxy). Instrumenting pi-ai itself covers direct users too, and lets both frameworks drop their chat-span code (~1.1k lines) so there is a single source ofgen_ai.chatspans. The version range starts at 0.80 because Flue 2.0–2.2 depend on pi-ai 0.83–0.87;>=1would have dropped their chat spans.How to review: Start with
integrations/pi-ai.tsandorchestrion/config/pi-ai.ts.complete*awaitsstream*, andcompat.streamhands some models to aModelsof its own, so nested synchronous calls are deduped with a depth counter and only the outermost call gets a span.ai/pi-ai/chat.tsis the old pi-durablemodels.ts, moved. Flue now passes the conversation to the pi-ai span through the scope.On Cloudflare,
@sentry/cloudflare/vitenow splices the@flue/runtimeimport into the Cloudflare SDK'sbaseSdkmodule instead of@sentry/server-utils's Flue integration. Every orchestrion-instrumented module imports@sentry/server-utils, so with pi-ai instrumented the old location closed an import cycle that ran Flue's module-levelcreateModels()before pi-ai'sModelsImplexisted, and the worker failed at startup.Unsure about:
auto.ai.flue/auto.ai.pi_durabletoauto.ai.pi_ai.instrument(createFlueInstrumentation())keeps agent/tool spans but loses chat spans. Setups following our docs (--importon Node, the Vite plugin on Cloudflare, the Bun plugin) are unaffected, and Flue now warns once on its first model call when pi-ai was not instrumented. pi-durable is unaffected: it was only ever instrumented through the hook or plugin.flue.turn.purpose(compaction vs. agent turn) is dropped, since pi-ai cannot see it. Could be carried through the scope if we want it.wrangler devand a fake key: it starts, and recordsinvoke_agent>chat(auto.ai.pi_ai) > the provider HTTP span.Release note:
🤖 Generated with Claude Code
via Francesco Gringl-Novy.
--
View Junior Session [Sentry]