feat: migrate tracing web client from deprecated to new API endpoints#4571
feat: migrate tracing web client from deprecated to new API endpoints#4571GanJiaKouN16 wants to merge 1 commit into
Conversation
Migrate 4 of 5 deprecated /tracing/* endpoints to their canonical
replacements. The analytics endpoint (/tracing/spans/analytics) is
deferred per issue author's recommendation.
Endpoint migrations:
- POST /tracing/spans/query → POST /spans/query
- GET /tracing/traces/{id} → GET /traces/{id}
- DELETE /tracing/traces/{id} → DELETE /traces/{id}
- POST /tracing/sessions/query → POST /spans/sessions/query
Changes:
- Add traceResponseSchema, traceIdResponseSchema, sessionIdsResponseSchema
Zod schemas for the new response shapes
- Update entities API (api.ts) to hit new endpoints with new response
parsing. POST /spans/query now always returns flat SpansResponse
(focus param removed). GET /traces/{id} returns single TraceResponse.
- Update OSS API (index.ts) to hit new URLs, strip focus param
- Update annotationFormController to handle new trace response shape
({trace: {trace_id, spans}} instead of {traces: {id: {spans}}})
- Add isTraceResponse type guard and transformTraceResponseToTree helper
- Existing consumer branching logic (isTracesResponse/isSpansResponse)
continues to work — POST /spans/query always returns SpansResponse
so isTracesResponse branch becomes dead code for list queries
Fixes Agenta-AI#4492
|
Someone is attempting to deploy a commit to the agenta projects Team on Vercel. A member of the Team first needs to authorize it. |
|
GanJiaKouN16 seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
|
Ready to act? Review this PR in Change Stack to turn feedback into patch suggestions you can inspect and refine. 📝 WalkthroughSummary by CodeRabbit
WalkthroughThis pull request migrates the tracing API client from deprecated ChangesTrace API Endpoint & Response Shape Migration
🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
web/packages/agenta-entities/src/trace/api/api.ts (2)
41-48:⚠️ Potential issue | 🟠 Major | ⚡ Quick win
TraceQueryParamsstill accepts deprecated keys.Removing
focusfrom the named fields does not make stale callers fail because the[key: string]: unknowncatch-all still accepts{focus: "trace"}and any other legacy payload fields. That weakens the#4492migration: callers can keep compiling while this function silently dropsfocusand always returns flat spans. Please tighten this type to the actual supported request shape so legacy callers break at compile time.Suggested direction
export interface TraceQueryParams { size?: number format?: string filter?: string | Record<string, unknown> oldest?: string newest?: string cursor?: string - [key: string]: unknown }
62-97: 🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy liftUse the Fern client for these migrated endpoints.
These new
/spans/*and/traces/*calls are still hand-built with rawaxios, string URLs, and manual query serialization. That leaves this package with a second API surface to keep in sync during the migration. Please switch these functions togetAgentaSdkClient({host: getAgentaApiUrl()})and pass query params via{queryParams: {...}}instead of interpolating them into the URL.As per coding guidelines, "All new frontend API code must go through the Fern-generated client, not raw axios", "Use
getAgentaSdkClient({host: getAgentaApiUrl()})— it is a lazy singleton, share it across calls", and "Pass query params via{queryParams: {...}}, NOT axios's{params: {...}}."Also applies to: 110-149, 177-210
Source: Coding guidelines
web/oss/src/services/tracing/api/index.ts (1)
19-57: 🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy liftAvoid adding a second manual client for the canonical tracing endpoints.
This file reimplements the same
/spans/*and/traces/*migration withfetchJson, ad-hoc payload shaping, and untypedRecord<string, any>params. That duplicatesweb/packages/agenta-entities/src/trace/api/api.ts, lets legacy keys likefocuskeep flowing through type-checking here, and raises the odds that the next contract change lands in only one layer. Please route these OSS calls through the shared Fern client instead of extending the legacy wrapper.As per coding guidelines, "All new frontend API code must go through the Fern-generated client, not raw axios", "Use
getAgentaSdkClient({host: getAgentaApiUrl()})— it is a lazy singleton, share it across calls", and "Pass query params via{queryParams: {...}}, NOT axios's{params: {...}}."Also applies to: 91-205
Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 5093432f-fff7-4beb-a28e-c2367296fbfb
📒 Files selected for processing (8)
web/oss/src/services/tracing/api/index.tsweb/packages/agenta-annotation/src/state/controllers/annotationFormController.tsweb/packages/agenta-entities/src/trace/api/api.tsweb/packages/agenta-entities/src/trace/api/helpers.tsweb/packages/agenta-entities/src/trace/api/index.tsweb/packages/agenta-entities/src/trace/core/index.tsweb/packages/agenta-entities/src/trace/core/schema.tsweb/packages/agenta-entities/src/trace/index.ts
| const traceEntry = | ||
| traceResponse?.trace ?? (() => { | ||
| const traceKey = traceId.replace(/-/g, "") | ||
| return (traceResponse as any)?.traces?.[traceKey] ?? | ||
| (traceResponse as any)?.traces?.[traceId] | ||
| })() |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Type the legacy fallback path instead of casting to any
This keeps the rollout fallback while preserving strict typing in package code.
Suggested fix
+ type LegacyTraceResponse = {
+ traces?: Record<string, {spans?: Record<string, TraceSpan>}>
+ }
const traceEntry =
traceResponse?.trace ?? (() => {
const traceKey = traceId.replace(/-/g, "")
- return (traceResponse as any)?.traces?.[traceKey] ??
- (traceResponse as any)?.traces?.[traceId]
+ const legacy = traceResponse as LegacyTraceResponse | null
+ return legacy?.traces?.[traceKey] ?? legacy?.traces?.[traceId]
})()As per coding guidelines: web/packages/**/*.{ts,tsx} requires “Do not use any types in package code; follow strict typing rules.”
Source: Coding guidelines
| return typeof data === "object" && data !== null && "spans" in data && Array.isArray((data as any).spans) | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Remove any from the response type guard
Use a typed unknown narrowing instead of (data as any) in package code.
Suggested fix
export const isSpansResponse = (data: unknown): data is SpansResponse => {
- return typeof data === "object" && data !== null && "spans" in data && Array.isArray((data as any).spans)
+ if (typeof data !== "object" || data === null) return false
+ return Array.isArray((data as {spans?: unknown}).spans)
}As per coding guidelines: web/packages/**/*.{ts,tsx} requires “Do not use any types in package code; follow strict typing rules.”
Source: Coding guidelines
| export const traceResponseSchema = z.object({ | ||
| count: z.number().optional().default(0), | ||
| trace: z | ||
| .object({ | ||
| trace_id: z.string().optional().nullable(), | ||
| spans: z.record(z.string(), traceSpanSchema).optional().nullable(), | ||
| }) | ||
| .optional() | ||
| .nullable(), | ||
| }) |
There was a problem hiding this comment.
Legacy fallback data is stripped at the parse boundary
traceResponseSchema currently omits legacy traces, so parsed output drops that key before resolveTraceLinkSpanId can use its fallback path. This breaks the intended rollout compatibility if an environment still serves legacy shape.
Suggested fix
export const traceResponseSchema = z.object({
count: z.number().optional().default(0),
trace: z
.object({
trace_id: z.string().optional().nullable(),
spans: z.record(z.string(), traceSpanSchema).optional().nullable(),
})
.optional()
.nullable(),
+ // Keep legacy shape during rollout so downstream fallback can still read it.
+ traces: z
+ .record(
+ z.string(),
+ z.object({
+ spans: z.record(z.string(), traceSpanSchema),
+ }),
+ )
+ .optional(),
})Based on learnings from PR objectives: backward-compatible fallback for legacy response shapes should be preserved during rollout.
|
closing as duplicate of #4573 |
Summary
Migrates 4 of 5 deprecated
/tracing/*endpoints to their canonical replacements. The analytics endpoint (/tracing/spans/analytics) is deferred per issue author's recommendation.Endpoint migrations
POST /tracing/spans/queryPOST /spans/queryfocusparam removed (always returns flat spans)GET /tracing/traces/{id}GET /traces/{id}tracesrecord → singletraceobject)DELETE /tracing/traces/{id}DELETE /traces/{id}POST /tracing/sessions/queryPOST /spans/sessions/queryFiles changed (8)
New Zod schemas (
web/packages/agenta-entities/src/trace/core/schema.ts):traceResponseSchema— forGET /traces/{id}:{count, trace: {trace_id, spans}}traceIdResponseSchema— forDELETE /traces/{id}:{count, trace_id}sessionIdsResponseSchema— forPOST /spans/sessions/query:{count, session_ids, windowing}Entities API (
web/packages/agenta-entities/src/trace/api/api.ts):fetchAllPreviewTraces→POST /spans/query, stripsfocusparam, always returnsSpansResponsefetchPreviewTrace→GET /traces/{id}, returnsTraceResponsedeletePreviewTrace→DELETE /traces/{id}, returnsTraceIdResponsefetchSessions→POST /spans/sessions/query, returnsSessionIdsResponseNew helpers (
web/packages/agenta-entities/src/trace/api/helpers.ts):isTraceResponse— type guard for new single-trace responsetransformTraceResponseToTree— builds span tree fromTraceResponseOSS API (
web/oss/src/services/tracing/api/index.ts):focusparam stripped fromfetchAllPreviewTracesandfetchAllPreviewTracesWithMetaAnnotation controller (
web/packages/agenta-annotation/src/state/controllers/annotationFormController.ts):{trace: {trace_id, spans}}shape with legacy fallbackBackward compatibility
isTracesResponse/isSpansResponse) continues to workPOST /spans/queryalways returnsSpansResponsenow, so theisTracesResponsebranch becomes dead code for list queries (harmless)normalizeTracesResponse()in drawer stores already handles.traceshape/tracing/spans/analytics(deferred to separate PR)Fixes #4492