Skip to content

[FE / chore] Move tracing away from legacy endpoints#4573

Open
ardaerzin wants to merge 6 commits into
mainfrom
fe-chore/age-3788-move-tracing-away-from-deprecated-and-then-legacy-endpoints
Open

[FE / chore] Move tracing away from legacy endpoints#4573
ardaerzin wants to merge 6 commits into
mainfrom
fe-chore/age-3788-move-tracing-away-from-deprecated-and-then-legacy-endpoints

Conversation

@ardaerzin
Copy link
Copy Markdown
Contributor

Summary

Testing

Verified locally

Added or updated tests

QA follow-up

Demo

Checklist

  • I have included a video or screen recording for UI changes, or marked Demo as N/A
  • Relevant tests pass locally
  • Relevant linting and formatting pass locally
  • I have signed the CLA, or I will sign it when the bot prompts me

Contributor Resources

ardaerzin added 4 commits June 5, 2026 17:51
…-3788)

Move the web tracing calls (sessions, delete, single-trace, flat-span,
batch-trace + rate-limit meta) from the deprecated /tracing/* stack onto the
Fern /spans/* and /traces/* endpoints under @agenta/entities, keeping Zod
validation at the boundary.

- New scaffolding: trace/api/{client,request,adapters}.ts + envelope Zod schemas
- Repoint OSS drawers, observability + sessions consumers to @agenta/entities/trace
- Flip span/trace_type enum catch-all "undefined" -> "unknown" (backend value)
- Fix sessions enrichment grouping for the new endpoints' canonicalized ag.* attrs
- Add unit + integration tests for the migrated functions and adapters

Only /tracing/spans/analytics remains (Phase 6, gated on the MetricSpec contract).
…e-tracing-away-from-deprecated-and-then-legacy-endpoints
…endpoint (AGE-3788)

The ETL hydration + mapping resolver now read traces via the migrated
fetchAllPreviewTraces (Fern queryTraces, POST /traces/query) adapted to the
legacy map shape, not the deprecated POST /tracing/spans/query. Comment-only.
…ry (AGE-3788)

Move the observability generations dashboard off the deprecated
POST /tracing/spans/analytics onto the Fern client's
traces.querySpansAnalytics (POST /spans/analytics/query).

- entities: add fetchSpansAnalytics + analyticsResponseSchema/metricsBucketSchema.
  Omit specs so the backend applies DEFAULT_ANALYTICS_SPECS; filter is a
  JSON-string query param; project/app scope rides queryParams.
- oss: rewrite fetchGenerationsDashboardData to use fetchSpansAnalytics and
  analyticsToGeneration, which reads the spec-based metrics dict
  (buckets[].metrics keyed by dotted MetricSpec.path) instead of the old
  total/errors bucket split. Drop the last raw /tracing/* fetch.
- remove the now-dead TracingDashboardData type.
- add 6 unit tests for fetchSpansAnalytics.
@linear-code
Copy link
Copy Markdown

linear-code Bot commented Jun 6, 2026

AGE-3788

@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 6, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview, Comment Jun 6, 2026 5:20pm

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 6, 2026

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Project-scoped tracing queries for per-project trace isolation
  • Improvements

    • Analytics pipeline updated for more accurate dashboard metrics and aggregated latency
    • Dashboard tolerates missing/optional metric fields when analytics data is absent
    • Trace deletion and session querying flows made more reliable and scoped per project
    • Safer error handling: non-abort failures return null/no-data instead of throwing
  • Tests

    • New integration and unit tests covering the tracing migration, adapters, and analytics query paths

Walkthrough

Migrates tracing consumers and analytics from legacy /tracing endpoints to Fern-backed traces/spans APIs: adds Zod schemas and request builders, Fern client wrapper and adapters, updates OSS UI/state to pass projectId and tag session traces, and adds unit and integration tests.

Changes

Fern-Based Trace API Migration

Layer / File(s) Summary
Fern schemas and request primitives
web/packages/agenta-entities/src/trace/core/schema.ts, web/packages/agenta-entities/src/trace/api/request.ts, web/oss/src/services/tracing/types/index.ts
Adds Zod envelope schemas and enums (catch-all -> "unknown"), TraceQueryParams, toFilteringInput, and builders that map legacy filter/windowing into Fern request shapes; makes some GenerationDashboardData fields optional.
Fern client wrapper & call helpers
web/packages/agenta-entities/src/trace/api/client.ts
Adds getTracesClient, projectScopedRequest, callFern, and abort/error detection to standardize Fern calls and error handling.
Fern-to-legacy adapters
web/packages/agenta-entities/src/trace/api/adapters.ts
Adapters to convert TraceOutput[]/TraceOutput/TraceSpan[] into legacy TracesResponse and TraceSpanNode[] shapes for existing renderers.
Trace API migration
web/packages/agenta-entities/src/trace/api/api.ts, web/packages/agenta-entities/src/trace/api/index.ts
Migrates fetchAllPreviewTraces, fetchAllPreviewTracesWithMeta, fetchPreviewTrace, deletePreviewTrace, fetchSessions, and adds fetchSpansAnalytics; validates Fern responses, adapts shapes, and parses rate-limit headers for meta variant.
OSS analytics transform & dashboard wiring
web/oss/src/services/tracing/lib/helpers.ts, web/oss/src/services/tracing/api/index.ts
Replaces tracingToGeneration with analyticsToGeneration; fetchGenerationsDashboardData now calls fetchSpansAnalytics and handles null/malformed results as empty data.
OSS consumers: drawers, header, modal
web/oss/src/components/SharedDrawers/..., web/oss/src/components/SharedDrawers/TraceDrawer/store/traceDrawerStore.ts
OSS UI/state imports trace functions from @agenta/entities/trace, includes projectId in query keys and calls (uses projectId ?? ""), and casts fallback transforms where required.
Session & trace state helpers
web/oss/src/state/newObservability/atoms/queries.ts, web/oss/src/state/newObservability/atoms/queryHelpers.ts
Session atoms call Fern fetchSessions with projectId; trace query helpers call fetchAllPreviewTracesWithMeta with project scoping; traces are tagged with __sessionId for grouping.
Request helpers & re-exports
web/packages/agenta-entities/src/trace/core/index.ts, web/packages/agenta-entities/src/trace/api/index.ts
Barrel exports extended to include new schemas, request builders, client helpers, and adapters for downstream consumers.
Unit & integration tests
web/packages/agenta-entities/tests/unit/*, web/packages/agenta-entities/tests/integration/*
Adds unit tests for adapters and API wrappers, and gated integration tests validating undashed trace-id support, rate-limit header shape, Fern connectivity, and spans analytics shape/live-data checks.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: migrating frontend tracing from legacy endpoints to Fern-based entities, which matches the core objective of the changeset.
Description check ✅ Passed The description is minimal but related to the changeset. While it doesn't provide detailed testing information, it correctly indicates this is a chore/refactoring PR for moving tracing endpoints, which aligns with the actual changes made.
Docstring Coverage ✅ Passed Docstring coverage is 94.74% which is sufficient. The required threshold is 60.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fe-chore/age-3788-move-tracing-away-from-deprecated-and-then-legacy-endpoints

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 and usage tips.

@ardaerzin ardaerzin changed the title [FE / chore]/ <ove tracing away from deprecated and then legacy endpoints [FE / chore] Move tracing away from deprecated and then legacy endpoints Jun 6, 2026
@ardaerzin ardaerzin changed the title [FE / chore] Move tracing away from deprecated and then legacy endpoints [FE / chore] Move tracing away from legacy endpoints Jun 6, 2026
@ardaerzin ardaerzin marked this pull request as ready for review June 6, 2026 12:54
@dosubot dosubot Bot added size:XXL This PR changes 1000+ lines, ignoring generated files. Frontend refactoring A code change that neither fixes a bug nor adds a feature tests typescript labels Jun 6, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (2)
web/packages/agenta-entities/tests/unit/trace-migration-adapters.test.ts (1)

125-129: ⚡ Quick win

Incomplete test fixture could mask validation gaps.

Line 127 casts {spans: {}} to TraceOutput without providing the trace_id field. While the current code skips entries without trace_id, this incomplete fixture could cause false positives if upstream schema validation tightens.

✨ Strengthen the fixture
-        const out = fernTracesToLegacyTraceMap([{spans: {}} as TraceOutput])
+        const out = fernTracesToLegacyTraceMap([{trace_id: undefined, spans: {}} as TraceOutput])

Or test the skip behavior explicitly with a proper partial:

-        const out = fernTracesToLegacyTraceMap([{spans: {}} as TraceOutput])
+        // Explicitly test missing trace_id behavior
+        const out = fernTracesToLegacyTraceMap([{spans: {}, trace_id: undefined} as unknown as TraceOutput])
web/packages/agenta-entities/tests/unit/trace-migration-api.test.ts (1)

212-234: 💤 Low value

Consider stronger typing for the adapter response.

Lines 221-224 use a loose inline type that only declares count and traces as Record<string, unknown>. While this works for the test, a more precise type would catch regressions in the adapter's output shape.

💡 Optional: Use the actual return type
-        const res = (await fetchAllPreviewTraces({focus: "trace", filter}, "", "proj-9")) as {
-            count: number
-            traces: Record<string, unknown>
-        }
+        const res = (await fetchAllPreviewTraces({focus: "trace", filter}, "", "proj-9")) as TracesResponse

Then access res.traces knowing it matches the expected schema.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: ed419b8f-554f-4ecf-b72d-ea787f77377c

📥 Commits

Reviewing files that changed from the base of the PR and between 98b8a9d and c1dd28b.

📒 Files selected for processing (22)
  • web/oss/src/components/SharedDrawers/SessionDrawer/store/sessionDrawerStore.ts
  • web/oss/src/components/SharedDrawers/TraceDrawer/components/DeleteTraceModal/index.tsx
  • web/oss/src/components/SharedDrawers/TraceDrawer/components/TraceHeader/index.tsx
  • web/oss/src/components/SharedDrawers/TraceDrawer/store/traceDrawerStore.ts
  • web/oss/src/services/tracing/api/index.ts
  • web/oss/src/services/tracing/lib/helpers.ts
  • web/oss/src/services/tracing/types/index.ts
  • web/oss/src/state/newObservability/atoms/queries.ts
  • web/oss/src/state/newObservability/atoms/queryHelpers.ts
  • web/packages/agenta-entities/src/evaluationRun/etl/hydrateScenariosTransform.ts
  • web/packages/agenta-entities/src/evaluationRun/etl/resolveMappings.ts
  • web/packages/agenta-entities/src/trace/api/adapters.ts
  • web/packages/agenta-entities/src/trace/api/api.ts
  • web/packages/agenta-entities/src/trace/api/client.ts
  • web/packages/agenta-entities/src/trace/api/index.ts
  • web/packages/agenta-entities/src/trace/api/request.ts
  • web/packages/agenta-entities/src/trace/core/index.ts
  • web/packages/agenta-entities/src/trace/core/schema.ts
  • web/packages/agenta-entities/src/trace/index.ts
  • web/packages/agenta-entities/tests/integration/trace-migration.integration.test.ts
  • web/packages/agenta-entities/tests/unit/trace-migration-adapters.test.ts
  • web/packages/agenta-entities/tests/unit/trace-migration-api.test.ts

Comment thread web/oss/src/services/tracing/lib/helpers.ts Outdated
Comment on lines 136 to 143
return {
timestamp: formatTick(b.timestamp, range),
success_count: succC,
failure_count: errC,
cost: succCost + errCost,
latency: succC ? succDurS / Math.max(succC, 1) : 0, // avg latency per success in the bucket
total_tokens: succTok + errTok,
success_count: success,
failure_count: failure,
cost,
latency: durationCount ? durationS / durationCount : 0, // avg latency in the bucket
total_tokens: tokens,
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if any code accesses the missing fields from the dashboard data
rg -n -C2 'prompt_tokens|completion_tokens|enviornment|variant' --type=ts --type=tsx -g '!**/types/**' web/oss/src/components/pages/observability/

Repository: Agenta-AI/agenta

Length of output: 88


🏁 Script executed:

#!/bin/bash
# Check GenerationDashboardData interface definition and usages
rg -n 'GenerationDashboardData' --type=ts web/oss/src/

Repository: Agenta-AI/agenta

Length of output: 1236


Fix analyticsToGeneration bucket shape to match GenerationDashboardData.data[] fields.

analyticsToGeneration currently returns only { timestamp, success_count, failure_count, cost, latency, total_tokens }, but GenerationDashboardData.data requires prompt_tokens, completion_tokens, enviornment, and variant; the as GenerationDashboardData cast in web/oss/src/services/tracing/api/index.ts masks this mismatch at compile time. If the observability UI reads these fields, it will get undefined; either populate them (with defaults) in analyticsToGeneration or update the interface to reflect reality.

Comment thread web/packages/agenta-entities/src/trace/api/request.ts Outdated
Comment thread web/packages/agenta-entities/tests/unit/trace-migration-api.test.ts
CodeRabbit follow-ups (quick wins; no behavior change):
- toFilteringInput: reject array-shaped filters (typeof [] === 'object')
  before casting to FilteringInput.
- GenerationDashboardData: make the never-populated, unread prompt_tokens /
  completion_tokens / enviornment / variant fields optional in both the
  services/tracing and types_ee copies, and drop the masking
  'as GenerationDashboardData' cast (annotate analyticsToGeneration's return).
- integration test: parse AGENTA_TEST_EXPECT_RATELIMIT explicitly so
  'false'/'0' don't enable the EE-only assertion path.
- golden-convergence test: replace 'as never' with 'as unknown as
  TracesResponse'; tighten the focus=trace adapter assertion to TracesResponse.
- adapters test: exercise the missing-trace_id skip path explicitly.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 6, 2026

Railway Preview Environment

Preview URL https://gateway-production-f728.up.railway.app/w
Project agenta-oss-pr-4573
Image tag pr-4573-b1abe35
Status Deployed
Railway logs Open logs
Workflow logs View workflow run
Updated at 2026-06-06T17:27:31.239Z

…on tests (AGE-3788)

Verified against live project data via a gated integration test:
ag.metrics.duration.cumulative is in MILLISECONDS (avg ~1229ms across 8.5k
traces), but analyticsToGeneration divided by 1000 while the dashboard renders
latency with an 'ms' suffix — so avg/per-bucket latency displayed 1000x too
small (1229ms shown as '1.23ms'). The legacy transform had the same bug on the
same attribute; this corrects it now that real data confirms the unit.

Also adds /spans/analytics/query integration coverage:
- shape smoke (gated on hasBackend) — proves the Fern call + envelope parse.
- live-data assertions (gated on AGENTA_LIVE_* env, no secrets committed) —
  prove the default-spec dotted metric paths the OSS transform reads are
  present with numeric aggregates.
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 583389c6-287e-4459-a7fd-44231d6140a8

📥 Commits

Reviewing files that changed from the base of the PR and between 623cfe1 and 7ab989d.

📒 Files selected for processing (2)
  • web/oss/src/services/tracing/lib/helpers.ts
  • web/packages/agenta-entities/tests/integration/trace-migration.integration.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • web/oss/src/services/tracing/lib/helpers.ts

Comment on lines +215 to +219
beforeAll(() => {
process.env.AGENTA_HOST = LIVE_API_URL
process.env.AGENTA_API_KEY = LIVE_API_KEY
getAgentaSdkClient({host: LIVE_API_URL, apiKey: LIVE_API_KEY})
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check if getAgentaSdkClient supports re-initialization or reads env vars on each call

# Find the SDK client implementation to understand singleton behavior
rg -nP --type=ts -C5 'export.*getAgentaSdkClient' --glob '!**/node_modules/**'

# Check if the client reads from env vars on each call or caches the first config
rg -nP --type=ts -C5 'AGENTA_HOST|AGENTA_API_KEY' --glob '**/sdk/**' --glob '!**/node_modules/**'

Repository: Agenta-AI/agenta

Length of output: 13190


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="web/packages/agenta-entities/tests/integration/trace-migration.integration.test.ts"

echo "---- Context: ${FILE} (lines 1-140) ----"
sed -n '1,140p' "$FILE" | nl -ba | sed -n '1,140p'

echo "---- Context: ${FILE} (lines 180-280) ----"
sed -n '180,280p' "$FILE" | nl -ba

echo "---- Find getTracesClient usage in the test ----"
rg -n "getTracesClient|getAgentaSdkClient|init\(" "$FILE"

echo "---- Locate getTracesClient implementation ----"
rg -n "function getTracesClient|getTracesClient\s*\(" web/packages -S --glob '!**/node_modules/**' | head -n 50

Repository: Agenta-AI/agenta

Length of output: 237


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="web/packages/agenta-entities/tests/integration/trace-migration.integration.test.ts"

echo "---- Context: ${FILE} (lines 1-220) ----"
if [ -f "$FILE" ]; then
  cat -n "$FILE" | sed -n '1,220p'
else
  echo "File not found: $FILE"
  exit 1
fi

echo "---- Context: ${FILE} (lines 220-320) ----"
cat -n "$FILE" | sed -n '220,320p' | head -n 120

echo "---- Find getTracesClient usage in the test ----"
rg -n "getTracesClient|getAgentaSdkClient|AGENTA_HOST|AGENTA_API_KEY|init\(" "$FILE" || true

echo "---- Locate getTracesClient implementation ----"
rg -n "getTracesClient" web/packages --glob '!**/node_modules/**' | head -n 50 || true

echo "---- Locate SDK init/entrypoint used by traces helpers ----"
rg -n "getAgentaSdkClient\(" web/packages --glob '!**/node_modules/**' | head -n 50 || true

Repository: Agenta-AI/agenta

Length of output: 18686


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="web/packages/agenta-sdk/src/index.ts"
echo "---- File: $FILE ----"
wc -l "$FILE"
cat -n "$FILE" | sed -n '1,160p'

Repository: Agenta-AI/agenta

Length of output: 4391


Fix live-data Phase 6 test to avoid stale getAgentaSdkClient singleton config.

getAgentaSdkClient is a lazy singleton that ignores subsequent arguments once _singleton is set (web/packages/agenta-sdk/src/index.ts). In trace-migration.integration.test.ts, the top-level beforeAll seeds the singleton with TEST_CONFIG (lines 64-69), so the Phase 6 “real data” beforeAll calling getAgentaSdkClient({host: LIVE_API_URL, apiKey: LIVE_API_KEY}) (lines 215-219) won’t switch the backend to LIVE.

Adjust the test so the first SDK initialization uses LIVE creds when hasLiveAnalytics is true (or route fetchSpansAnalytics through an init(LIVE...) client / add a way to reset the singleton between configurations).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Frontend refactoring A code change that neither fixes a bug nor adds a feature size:XXL This PR changes 1000+ lines, ignoring generated files. tests typescript

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant