feat(frontend): Observability Drawer View Improvements#3783
feat(frontend): Observability Drawer View Improvements#3783
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…llInView - Add "Raw" view mode to display original string values before auto-parsing - Rename "Rendered JSON" to "Field Rendering" for clarity - Preserve `originalStringValue` in PathItem for stringified JSON fields - Refactor view mode options logic to show appropriate modes based on data type - Remove text truncation from ReadOnlyTextView (now handled by editor config) - Consolidate field rendering logic and improve messages
…nd search functionality
…terals in DrillInContent
…t and DrillInFieldHeader components
web/oss/src/components/SharedDrawers/TraceDrawer/components/AccordionTreePanel.tsx
Outdated
Show resolved
Hide resolved
web/oss/src/components/SharedDrawers/TraceDrawer/components/TraceContent/index.tsx
Outdated
Show resolved
Hide resolved
| <TraceSpanDrillInView | ||
| spanId={spanId} | ||
| initialPath={"data.ag.data.inputs.parameters"} | ||
| /> |
There was a problem hiding this comment.
🔴 AccordionTreePanel body replaced with hardcoded test path, actual rendering commented out
The AccordionTreePanel component's entire rendering body has been replaced with a hardcoded TraceSpanDrillInView using initialPath="data.ag.data.inputs.parameters", and the actual rendering logic (lines 370-417) is commented out. The component also destructures spanId from props which is not declared in AccordionTreePanelProps, so it will always be undefined.
Root Cause
At AccordionTreePanel.tsx:366-369, the component now always renders:
<TraceSpanDrillInView
spanId={spanId} // always undefined - not in props type
initialPath={"data.ag.data.inputs.parameters"} // hardcoded test path
/>The spanId prop is destructured at line 174 but is not part of AccordionTreePanelProps (lines 26-35). Since it's not in the type and no callers pass it, it will always be undefined at runtime, causing TraceSpanDrillInView to receive an undefined spanId.
The actual rendering logic (handling value, label, view modes, search, etc.) is completely commented out on lines 370-417.
Impact: If any code path still uses AccordionTreePanel, it will render broken content with an undefined spanId and a hardcoded path instead of the intended data. While the main callers have been migrated away, the component is still exported and could be imported elsewhere.
Prompt for agents
In web/oss/src/components/SharedDrawers/TraceDrawer/components/AccordionTreePanel.tsx, the component body at lines 366-369 has been replaced with a hardcoded TraceSpanDrillInView that uses an undeclared spanId prop and a hardcoded initialPath. The actual rendering logic is commented out on lines 370-417. Either: (1) restore the commented-out rendering logic and remove the hardcoded TraceSpanDrillInView, (2) properly add spanId to AccordionTreePanelProps and wire it correctly, or (3) if the component is truly dead code, remove the entire file and its export.
Was this helpful? React with 👍 or 👎 to provide feedback.
| children: spanId ? ( | ||
| <TraceSpanDrillInView | ||
| spanId={spanId} | ||
| title={errorPayload ? "Error" : "Raw Data"} | ||
| rootScope="span" | ||
| hideBreadcrumb | ||
| showFieldDrillIn={false} | ||
| enableFieldViewModes | ||
| /> | ||
| ), | ||
| ) : null, |
There was a problem hiding this comment.
🔴 Raw Data tab always renders null when activeTrace is missing (error case regression)
When activeTrace is null/undefined (failed generation), the Raw Data tab always renders null because spanId is derived from activeTrace?.span_id which is always undefined in this branch.
Root Cause
In TraceContent/index.tsx, spanId is set at line 39:
const spanId = activeTrace?.span_idThen at line 53, when !activeTrace (error/failed generation scenario), the code tries to conditionally render:
children: spanId ? (
<TraceSpanDrillInView spanId={spanId} ... />
) : null,Since activeTrace is falsy in this branch, spanId will always be undefined, so the ternary always evaluates to null. The Raw Data tab will be empty.
The old code handled this case by constructing a payload from traceResponse?.response or the error:
const rawPayload = traceResponse?.response || (errorPayload ? {error: errorPayload} : {})and passing it to AccordionTreePanel which could display it. That fallback is now lost.
Impact: When a trace fails to generate, users see an empty Raw Data tab instead of error details. This is a regression from the previous behavior.
Prompt for agents
In web/oss/src/components/SharedDrawers/TraceDrawer/components/TraceContent/index.tsx, when !activeTrace (lines 53-71), spanId is always undefined because it's derived from activeTrace?.span_id. The Raw Data tab therefore always shows null. The old code used traceResponse?.response or {error: errorPayload} as a fallback to display error information. You need to either: (1) find an alternative way to display error/raw data when activeTrace is null (perhaps using the error prop directly), or (2) ensure spanId can be sourced from somewhere other than activeTrace in error scenarios.
Was this helpful? React with 👍 or 👎 to provide feedback.
Railway Preview Environment
Updated at 2026-02-23T14:50:26.402Z |
web/oss/src/components/SharedDrawers/TraceDrawer/components/AccordionTreePanel.tsx
Outdated
Show resolved
Hide resolved
web/oss/src/components/SharedDrawers/TraceDrawer/components/AccordionTreePanel.tsx
Outdated
Show resolved
Hide resolved
| /> | ||
| ) | ||
| } | ||
|
|
||
| if (selectedViewMode === "rendered-json") { | ||
| // Render as a valid JSON string literal (escaped stringified JSON) | ||
| const jsonValue = toStringifiedJsonLiteral(item.value) | ||
| return ( | ||
| <ReadOnlyCodeView | ||
| editorId={`drill-field-${fieldKey}`} | ||
| language="json" |
There was a problem hiding this comment.
🟡 "Field Rendering" (rendered-json) view mode shows double-escaped JSON string literal instead of rendered content
When enableFieldViewModes is true and a user selects the "Field Rendering" view mode for messages-type data, renderFieldContentByMode calls toStringifiedJsonLiteral() which double-escapes the value into a JSON string literal, rather than rendering it with ChatMessageList or showing readable unpacked JSON.
Root Cause
In DrillInContent.tsx:1120-1130, the rendered-json case calls toStringifiedJsonLiteral(item.value) which at DrillInContent.tsx:1026-1036 does:
function toStringifiedJsonLiteral(value: unknown): string {
const compactJsonString = typeof value === "string"
? ... : (JSON.stringify(value) ?? "null")
return JSON.stringify(compactJsonString) ?? '""'
}For a messages array like [{role: "user", content: "hello"}], this produces a double-escaped string like "[{\\"role\\":\\"user\\",\\"content\\":\\"hello\\"}]" — an unreadable escaped JSON string literal.
The comment in getFieldViewModeOptions at line 496-499 explicitly states:
// Only show "Field Rendering" when we have custom components to render the data
// Currently only messages dataType has custom rendering (ChatMessageList)But the implementation doesn't use ChatMessageList. When enableFieldViewModes is true, renderFieldContent at line 1235 immediately delegates to renderFieldContentByMode, bypassing all type-specific rendering including ChatMessageList (at line 1247-1261).
This is inconsistent with AccordionTreePanel.tsx where "rendered-json" shows renderStringifiedJson (recursively unpacked JSON) — a readable format.
Impact: Users who select "Field Rendering" for messages-type fields in the observability drawer see an unreadable double-escaped JSON string instead of a nicely rendered message list or readable JSON.
Prompt for agents
In web/oss/src/components/DrillInView/DrillInContent.tsx, the renderFieldContentByMode function's "rendered-json" case at lines 1120-1130 should be updated to either: (1) Render messages using ChatMessageList (matching the comment's intent at lines 496-499 that says this mode is for custom component rendering), or (2) Show the recursively unpacked/rendered JSON using renderStringifiedJson (matching what AccordionTreePanel does for rendered-json). Currently toStringifiedJsonLiteral produces an unreadable double-escaped JSON string literal. The minimal fix would be to replace the toStringifiedJsonLiteral call with safeJsonStringify(renderStringifiedJson(item.value).value) to at least show readable unpacked JSON.
Was this helpful? React with 👍 or 👎 to provide feedback.
mmabrouk
left a comment
There was a problem hiding this comment.
Thanks @ardaerzin and @bekossy for the work
The feature here does not fit to the PRD that we discussed. We talked explicitly about not changing the UI and only changing it so that it becomes more like the playground (white background for the header).
CleanShot.2026-02-23.at.15.54.21.mp4
This PR at the current state (maybe intermediate, but I saw Arda approve):
- Changes the UI for the collapsible cards and disconnects the header from the body, adds things, etc..
- Removes chat messages (at least when I tested)
- Removes expand functionality (click to expand json) and instead have a drill in when you click on a collapsed thing
Uh oh!
There was an error while loading. Please reload this page.