|
1 | 1 | /** |
2 | 2 | * Raw trace panel — single JsonEditor with bordered chrome around the tree. |
3 | 3 | * When `requestPayloadHistory` is provided (live chat), Raw shows the resolved model request payload |
4 | | - * (`system`, `tools`, `messages`). `messages` are merged with `trace.messages` from the live envelope |
5 | | - * when the snapshot (post-turn) is ahead of the last captured request, so the panel matches Chat/Trace |
6 | | - * as soon as the assistant finishes — not only after the next user message. Otherwise shows the stored |
7 | | - * trace blob (evals / offline). |
| 4 | + * (`system`, `tools`, `messages`) from the last `request_payload` event. `messages` are merged with |
| 5 | + * `trace.messages` from the live envelope when the snapshot is ahead of the last captured request. |
| 6 | + * If the chat shell passes this prop but `entries` is empty (e.g. a rehydrated stored session, which |
| 7 | + * never replays `request_payload`), we fall back to the `trace` blob so Raw matches Trace/Chat instead |
| 8 | + * of showing an endless spinner. Otherwise shows the stored trace blob (evals / offline). |
8 | 9 | */ |
9 | 10 |
|
10 | 11 | import { Copy, Loader2, ScanSearch } from "lucide-react"; |
@@ -109,60 +110,67 @@ export function TraceRawView({ |
109 | 110 | const latestEntry = orderedEntries.at(-1) ?? null; |
110 | 111 |
|
111 | 112 | if (requestPayloadHistory) { |
112 | | - if (!hasUiMessages || orderedEntries.length === 0 || !latestEntry) { |
| 113 | + const hasLiveRequestLine = |
| 114 | + hasUiMessages && orderedEntries.length > 0 && latestEntry != null; |
| 115 | + |
| 116 | + if (hasLiveRequestLine && latestEntry) { |
| 117 | + const displayPayload = mergeLiveRequestPayloadWithTraceSnapshot( |
| 118 | + latestEntry.payload, |
| 119 | + trace, |
| 120 | + ); |
| 121 | + |
| 122 | + if (growWithContent) { |
| 123 | + return ( |
| 124 | + <div |
| 125 | + className="flex min-h-0 w-full min-w-0 flex-1 flex-col" |
| 126 | + data-testid="trace-raw-view" |
| 127 | + > |
| 128 | + <div className="min-h-0 flex-1"> |
| 129 | + <JsonEditor |
| 130 | + height={jsonHeight} |
| 131 | + value={displayPayload} |
| 132 | + viewOnly |
| 133 | + collapsible |
| 134 | + collapseStringsAfterLength={100} |
| 135 | + /> |
| 136 | + </div> |
| 137 | + </div> |
| 138 | + ); |
| 139 | + } |
| 140 | + |
113 | 141 | return ( |
114 | 142 | <div |
115 | 143 | className="flex min-h-0 flex-1 flex-col overflow-hidden w-full" |
116 | 144 | data-testid="trace-raw-view" |
117 | 145 | > |
118 | | - <RawViewTraceStyleLoading /> |
| 146 | + <div className="flex-1 min-h-0 overflow-auto"> |
| 147 | + <div className="min-h-0 rounded-lg border border-border bg-muted/20"> |
| 148 | + <JsonEditor |
| 149 | + height={jsonHeight} |
| 150 | + value={displayPayload} |
| 151 | + viewOnly |
| 152 | + collapsible |
| 153 | + collapseStringsAfterLength={100} |
| 154 | + className="min-h-0" |
| 155 | + /> |
| 156 | + </div> |
| 157 | + </div> |
119 | 158 | </div> |
120 | 159 | ); |
121 | 160 | } |
122 | 161 |
|
123 | | - const displayPayload = mergeLiveRequestPayloadWithTraceSnapshot( |
124 | | - latestEntry.payload, |
125 | | - trace, |
126 | | - ); |
127 | | - |
128 | | - if (growWithContent) { |
| 162 | + if (!hasUiMessages) { |
129 | 163 | return ( |
130 | 164 | <div |
131 | | - className="flex min-h-0 w-full min-w-0 flex-1 flex-col" |
| 165 | + className="flex min-h-0 flex-1 flex-col overflow-hidden w-full" |
132 | 166 | data-testid="trace-raw-view" |
133 | 167 | > |
134 | | - <div className="min-h-0 flex-1"> |
135 | | - <JsonEditor |
136 | | - height={jsonHeight} |
137 | | - value={displayPayload} |
138 | | - viewOnly |
139 | | - collapsible |
140 | | - collapseStringsAfterLength={100} |
141 | | - /> |
142 | | - </div> |
| 168 | + <RawViewTraceStyleLoading /> |
143 | 169 | </div> |
144 | 170 | ); |
145 | 171 | } |
146 | 172 |
|
147 | | - return ( |
148 | | - <div |
149 | | - className="flex min-h-0 flex-1 flex-col overflow-hidden w-full" |
150 | | - data-testid="trace-raw-view" |
151 | | - > |
152 | | - <div className="flex-1 min-h-0 overflow-auto"> |
153 | | - <div className="min-h-0 rounded-lg border border-border bg-muted/20"> |
154 | | - <JsonEditor |
155 | | - height={jsonHeight} |
156 | | - value={displayPayload} |
157 | | - viewOnly |
158 | | - collapsible |
159 | | - collapseStringsAfterLength={100} |
160 | | - className="min-h-0" |
161 | | - /> |
162 | | - </div> |
163 | | - </div> |
164 | | - </div> |
165 | | - ); |
| 173 | + // Rehydrated session: no `request_payload` replay, but we have thread messages — use `trace` below. |
166 | 174 | } |
167 | 175 |
|
168 | 176 | if (trace == null) { |
|
0 commit comments