Skip to content

test(e2e): Add a node-flue end-to-end application - #24377

Open
RulaKhaled wants to merge 3 commits into
feat/flue-instrumentation-testsfrom
feat/flue-e2e-app
Open

test(e2e): Add a node-flue end-to-end application#24377
RulaKhaled wants to merge 3 commits into
feat/flue-instrumentation-testsfrom
feat/flue-e2e-app

Conversation

@RulaKhaled

@RulaKhaled RulaKhaled commented Sep 14, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #24266 — review that first, this is the e2e app only.

The node-integration-test calls __flueBindAgentModule by hand, standing in for what @flue/vite does from the 'use agent' directive, so it can't show whether a scaffolded app actually works. This is flue init output, built and served the way a user runs it, against a real provider.

Covered, in both dev and prod and in both the base and orchestrion variants:

  • invoke_agent / chat / execute_tool with usage and cost
  • a thrown tool error becoming an issue
  • a manual span inside a tool nesting under execute_tool
  • an orchestrion-instrumented dataloader span landing in the agent's trace
  • the provider's http.client call nesting inside chat

The loader runs inside a tool rather than a route so its span shares the agent's trace. No build externals are needed unlike node-eve — a Flue node build leaves dependencies as bare specifiers, so dataloader stays a real module for the transform to hook. @flue/* is pinned because the internal registry proxy 403s on releases it hasn't scanned.

Found: a thrown tool error produced an errored span and no issue at all, since Flue catches the throw and hands it back to the model as a tool result. Fixed in #24265.

@RulaKhaled
RulaKhaled added this pull request to stack #24376 September 14, 2026 14:05
@github-actions

github-actions Bot commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 28.96 kB - -
@sentry/browser - with treeshaking flags 27.26 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 27.15 kB - -
@sentry/browser (incl. Tracing) 50.51 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 50.52 kB - -
@sentry/browser (incl. Tracing, Profiling) 53.5 kB - -
@sentry/browser (incl. Tracing, Replay) 90.07 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 79.16 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 94.77 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 107.73 kB - -
@sentry/browser (incl. Feedback) 46.46 kB - -
@sentry/browser (incl. sendFeedback) 34.01 kB - -
@sentry/browser (incl. FeedbackAsync) 39.12 kB - -
@sentry/browser (incl. Metrics) 29.98 kB - -
@sentry/browser (incl. Logs) 30.24 kB - -
@sentry/browser (incl. Metrics & Logs) 30.91 kB - -
@sentry/react 30.72 kB - -
@sentry/react (incl. Tracing) 52.81 kB - -
@sentry/vue 36.2 kB - -
@sentry/vue (incl. Tracing) 52.76 kB - -
@sentry/svelte 28.98 kB - -
CDN Bundle 30.7 kB - -
CDN Bundle (incl. Tracing) 51.01 kB - -
CDN Bundle (incl. Logs, Metrics) 32.98 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 52.99 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 73.67 kB - -
CDN Bundle (incl. Tracing, Replay) 88.56 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 90.53 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 94.64 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 96.63 kB - -
CDN Bundle - uncompressed 90.83 kB - -
CDN Bundle (incl. Tracing) - uncompressed 152.33 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 97.41 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 158.29 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 226.82 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 271.9 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 277.85 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 285.6 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 291.54 kB - -
@sentry/nextjs (client) 55.13 kB - -
@sentry/sveltekit (client) 50.93 kB - -
@sentry/core/server 37.13 kB - -
@sentry/core/browser 13.66 kB - -
@sentry/node 130.44 kB +0.02% +20 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 81.83 kB - -
@sentry/node - without tracing 89.64 kB +0.04% +29 B 🔺
@sentry/node - without channel injection 109.36 kB +0.02% +20 B 🔺
@sentry/aws-serverless 97.86 kB +0.03% +20 B 🔺
@sentry/cloudflare (withSentry) - minified 203.36 kB - -
@sentry/cloudflare (withSentry) 506.44 kB - -

View base workflow run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit cd8dd44. Configure here.

Comment thread dev-packages/e2e-tests/test-applications/node-flue/tests/utils.ts
Comment thread dev-packages/e2e-tests/test-applications/node-flue/src/agents/hello.ts Outdated
RulaKhaled and others added 3 commits September 14, 2026 23:04
The node-integration-test suite drives Flue from a hand-written scenario that
calls `__flueBindAgentModule` itself, standing in for what `@flue/vite` does at
build time. It cannot show whether a scaffolded app works. This app is what
`flue init` produces — plain vite, `'use agent'`, `createAgentRouter` — built and
served the way a user runs it, against a real provider.

Covers: AI spans, errors captured as issues, a manual span nesting inside a tool,
an orchestrion-instrumented `dataloader` span landing in the agent's trace, and
both dev and prod. Also asserts the provider's HTTP call nests inside `chat`,
which nothing else covers.

The loader is called from inside a tool rather than a route, so its span shares
the agent's trace instead of sitting in one of its own.

No build externals are needed, unlike node-eve: a Flue node build leaves
dependencies as bare specifiers, so `dataloader` stays a real module for the
transform to hook. The `@flue/*` versions are pinned because the internal
registry proxy 403s on releases it has not scanned, and a caret range drifts onto
them; the `(latest)` variant is where new versions get exercised.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two lines over the width limit; I formatted the server-utils sources but not the
test application.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`runAgentTurn` returned on the `202` and dropped the `streamUrl`, so a turn kept
running while the next test started waiting for spans — a leftover trace could
satisfy the wrong assertion. It now reads the conversation back until it reports
a settlement.

Scoping the waits by `gen_ai.conversation.id` would not have worked: Flue
generates that id (`conv_01M2G81…`), so it is not the path segment the test
chose and the test cannot know it up front.

Also names `count_items` in the agent instructions — an earlier edit missed, so
the dataloader test was relying on the tool description alone — and drops the
`loaders.ts` comment describing the route-based setup that no longer exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@RulaKhaled
RulaKhaled requested review from a team as code owners September 14, 2026 20:04
@RulaKhaled
RulaKhaled requested review from JPeer264 and mydea and removed request for a team September 14, 2026 20:04
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