Skip to content

fix(ai): roll up OpenTelemetry usage across iterations#928

Open
dexhunter wants to merge 1 commit into
TanStack:mainfrom
dexhunter:fix/otel-root-usage-rollup-916
Open

fix(ai): roll up OpenTelemetry usage across iterations#928
dexhunter wants to merge 1 commit into
TanStack:mainfrom
dexhunter:fix/otel-root-usage-rollup-916

Conversation

@dexhunter

@dexhunter dexhunter commented Jul 12, 2026

Copy link
Copy Markdown

Summary

  • roll up numeric OpenTelemetry usage attributes across chat iterations on the request root span
  • apply the accumulated usage once before the root onSpanEnd callback on finish, error, and abort paths
  • retain per-iteration spans and metrics, with compact unit coverage and a deterministic tool-loop E2E test

Provenance

Weco supplied the request-level accumulator direction. The strict evaluator rejected its initial field mapping, so the final implementation was rebuilt through the existing usageAttributes() contract and hardened across every terminal path. Public autoresearch trajectory

Validation

  • strict evaluator: root_usage_abs_error_tokens improved from 550 to 0; finish, error, and abort fixtures passed
  • pnpm --filter @tanstack/ai test:lib --run tests/middlewares/otel.test.ts (50 tests passed)
  • pnpm --filter @tanstack/ai test:lib (1,137 tests passed)
  • pnpm --filter @tanstack/ai test:types
  • pnpm --filter @tanstack/ai test:eslint (no errors; existing warnings only)
  • pnpm --filter @tanstack/ai-e2e test:types
  • focused tool-loop E2E passed; the constrained full E2E run passed 347 tests with one skipped, one retry-only flaky test, and one environment-only Miniflare EPIPE failure that reproduces on the unchanged base
  • CI=1 pnpm test:pr
  • Prettier and git diff --check

Conflict Review

PR #896 changes adjacent usage-attribute tests and E2E helpers but does not implement request-level root-span rollup. It may require a small test/helper rebase if merged first; it is not a behavioral duplicate of this fix.

Fixes #916

Summary by CodeRabbit

  • Bug Fixes

    • Corrected OpenTelemetry usage reporting for multi-step chat runs.
    • Root spans now include combined token usage, including runs ending with errors or cancellations.
    • Preserved accurate usage details for each individual iteration.
  • Tests

    • Added coverage for multi-iteration and tool-based chat scenarios.
    • Expanded validation across supported provider configurations.

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5d64a073-67a0-421c-aa91-889b7369fb81

📥 Commits

Reviewing files that changed from the base of the PR and between 5fcaf90 and 027dbf8.

📒 Files selected for processing (5)
  • .changeset/otel-root-usage-rollup.md
  • packages/ai/src/middlewares/otel.ts
  • packages/ai/tests/middlewares/otel.test.ts
  • testing/e2e/src/routes/api.otel-usage.ts
  • testing/e2e/tests/middleware.spec.ts

📝 Walkthrough

Walkthrough

The OpenTelemetry middleware now accumulates usage across chat iterations and applies it once to the root span on finish, error, or abort. Unit and E2E tests cover multi-iteration tool loops, per-iteration spans, metrics, and aggregated root attributes.

Changes

OpenTelemetry root usage rollup

Layer / File(s) Summary
Accumulate and apply root usage
packages/ai/src/middlewares/otel.ts, .changeset/otel-root-usage-rollup.md
Chat request state accumulates usage attributes and applies them once to the root span on finish, error, or abort, with finish usage as fallback.
Validate rollup and terminal paths
packages/ai/tests/middlewares/otel.test.ts
Tests cover mixed iteration usage, preserved iteration attributes, token metrics, and root usage captured during error and abort completion.
Exercise multi-iteration tool flow
testing/e2e/src/routes/api.otel-usage.ts, testing/e2e/tests/middleware.spec.ts
Adds a tool-loop route path and verifies two client iterations plus aggregated root token usage in the E2E span data.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant E2ETest
  participant OtelUsageRoute
  participant Chat
  participant otelMiddleware
  participant SpanExporter
  E2ETest->>OtelUsageRoute: POST provider=tool-loop
  OtelUsageRoute->>Chat: invoke chat with weatherTool
  Chat->>otelMiddleware: emit usage for each iteration
  otelMiddleware->>otelMiddleware: accumulate root usage
  Chat->>otelMiddleware: finish after tool loop
  otelMiddleware->>SpanExporter: export iteration spans and rolled-up root span
  SpanExporter-->>E2ETest: return captured spans
Loading

Possibly related PRs

  • TanStack/ai#747: Both changes update OpenTelemetry usage attributes and tests in the middleware.

Suggested reviewers: AlemTuzlak, tombeckenham

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main change: rolling up OpenTelemetry usage across iterations.
Description check ✅ Passed The description covers the change, validation, and linked issue, though it doesn't use the repo's exact template headings.
Linked Issues check ✅ Passed The middleware now accumulates usage across iterations and applies it on finish, error, and abort, matching #916.
Out of Scope Changes check ✅ Passed All changes are directly related to the OTEL usage roll-up fix and its supporting tests and changeset.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

testing/e2e/tests/middleware.spec.ts

Parsing error: "parserOptions.project" has been provided for @typescript-eslint/parser.
The file was not found in any of the provided project(s): testing/e2e/tests/middleware.spec.ts


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.

otelMiddleware root chat span carries last-iteration usage, not the documented cross-iteration roll-up

1 participant