Skip to content

Commit 091f5eb

Browse files
authored
feat(agents): Show truncated messages info (#102947)
<img width="753" height="115" alt="Screenshot 2025-11-07 at 09 16 43" src="https://github.com/user-attachments/assets/8c40d020-f525-4feb-bad8-5be66183b913" />
1 parent 8567f68 commit 091f5eb

File tree

2 files changed

+57
-6
lines changed
  • static/app/views/performance/newTraceDetails/traceDrawer/details/span

2 files changed

+57
-6
lines changed

static/app/views/performance/newTraceDetails/traceDrawer/details/span/eapSections/aiInput.tsx

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@ import {Fragment, useEffect, useEffectEvent, useLayoutEffect, useState} from 're
22
import styled from '@emotion/styled';
33
import * as Sentry from '@sentry/react';
44

5+
import {Alert} from '@sentry/scraps/alert';
6+
import {Container} from '@sentry/scraps/layout';
7+
import {ExternalLink} from '@sentry/scraps/link';
8+
59
import {Button} from 'sentry/components/core/button';
6-
import {t} from 'sentry/locale';
10+
import {t, tct, tn} from 'sentry/locale';
711
import {space} from 'sentry/styles/space';
812
import type {EventTransaction} from 'sentry/types/event';
913
import {defined} from 'sentry/utils';
1014
import usePrevious from 'sentry/utils/usePrevious';
11-
import type {TraceItemResponseAttribute} from 'sentry/views/explore/hooks/useTraceItemDetails';
15+
import type {
16+
TraceItemDetailsMeta,
17+
TraceItemResponseAttribute,
18+
} from 'sentry/views/explore/hooks/useTraceItemDetails';
1219
import {
1320
getIsAiNode,
1421
getTraceNodeAttribute,
@@ -170,13 +177,17 @@ function useInvalidRoleDetection(roles: string[]) {
170177
export function AIInputSection({
171178
node,
172179
attributes,
180+
attributesMeta,
173181
event,
174182
}: {
175183
node: TraceTreeNode<TraceTree.EAPSpan | TraceTree.Span | TraceTree.Transaction>;
176184
attributes?: TraceItemResponseAttribute[];
185+
attributesMeta?: TraceItemDetailsMeta;
177186
event?: EventTransaction;
178187
}) {
179188
const shouldRender = getIsAiNode(node) && hasAIInputAttribute(node, attributes, event);
189+
const messagesMeta = attributesMeta?.['gen_ai.request.messages']?.meta as any;
190+
const originalMessagesLength: number | undefined = messagesMeta?.['']?.len;
180191

181192
let promptMessages = shouldRender
182193
? getTraceNodeAttribute('gen_ai.request.messages', node, event, attributes)
@@ -227,7 +238,12 @@ export function AIInputSection({
227238
{messages}
228239
</TraceDrawerComponents.MultilineText>
229240
) : null}
230-
{Array.isArray(messages) ? <MessagesArrayRenderer messages={messages} /> : null}
241+
{Array.isArray(messages) ? (
242+
<MessagesArrayRenderer
243+
messages={messages}
244+
originalLength={originalMessagesLength}
245+
/>
246+
) : null}
231247
{toolArgs ? (
232248
<TraceDrawerComponents.MultilineJSON value={toolArgs} maxDefaultDepth={1} />
233249
) : null}
@@ -248,8 +264,16 @@ const MAX_MESSAGES_TO_SHOW = MAX_MESSAGES_AT_START + MAX_MESSAGES_AT_END;
248264
* As the whole message history takes up too much space we only show the first two (as those often contain the system and initial user prompt)
249265
* and the last messages with the option to expand
250266
*/
251-
function MessagesArrayRenderer({messages}: {messages: AIMessage[]}) {
267+
function MessagesArrayRenderer({
268+
messages,
269+
originalLength,
270+
}: {
271+
messages: AIMessage[];
272+
originalLength?: number;
273+
}) {
252274
const [isExpanded, setIsExpanded] = useState(messages.length <= MAX_MESSAGES_TO_SHOW);
275+
const truncatedMessages = originalLength ? originalLength - messages.length : 0;
276+
const isTruncated = truncatedMessages > 0;
253277

254278
// Reset the expanded state when the messages length changes
255279
const previousMessagesLength = usePrevious(messages.length);
@@ -259,6 +283,22 @@ function MessagesArrayRenderer({messages}: {messages: AIMessage[]}) {
259283
}
260284
}, [messages.length, previousMessagesLength]);
261285

286+
const truncationAlert = isTruncated ? (
287+
<Container paddingBottom="lg">
288+
<Alert type="muted">
289+
{tct(
290+
'Due to [link:size limitations], the oldest [count] got dropped from the history.',
291+
{
292+
count: tn('message', '%s messages', truncatedMessages),
293+
link: (
294+
<ExternalLink href="https://develop.sentry.dev/sdk/expected-features/data-handling/#variable-size" />
295+
),
296+
}
297+
)}
298+
</Alert>
299+
</Container>
300+
) : null;
301+
262302
const renderMessage = (message: AIMessage, index: number) => {
263303
return (
264304
<Fragment key={index}>
@@ -278,11 +318,17 @@ function MessagesArrayRenderer({messages}: {messages: AIMessage[]}) {
278318
};
279319

280320
if (isExpanded) {
281-
return messages.map(renderMessage);
321+
return (
322+
<Fragment>
323+
{truncationAlert}
324+
{messages.map(renderMessage)}
325+
</Fragment>
326+
);
282327
}
283328

284329
return (
285330
<Fragment>
331+
{truncationAlert}
286332
{messages.slice(0, MAX_MESSAGES_AT_START).map(renderMessage)}
287333
<ButtonDivider>
288334
<Button onClick={() => setIsExpanded(true)} size="xs">

static/app/views/performance/newTraceDetails/traceDrawer/details/span/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ function EAPSpanNodeDetailsContent({
427427
traceItemData: TraceItemDetailsResponse;
428428
}) {
429429
const attributes = traceItemData.attributes;
430+
const attributesMeta = traceItemData.meta;
430431
const links = traceItemData.links;
431432
const isTransaction = isEAPTransactionNode(node) && !!eventTransaction;
432433

@@ -487,7 +488,11 @@ function EAPSpanNodeDetailsContent({
487488
hideNodeActions={hideNodeActions}
488489
/>
489490
<AIIOAlert node={node} attributes={attributes} />
490-
<AIInputSection node={node} attributes={attributes} />
491+
<AIInputSection
492+
node={node}
493+
attributes={attributes}
494+
attributesMeta={attributesMeta}
495+
/>
491496
<AIOutputSection node={node} attributes={attributes} />
492497
<MCPInputSection node={node} attributes={attributes} />
493498
<MCPOutputSection node={node} attributes={attributes} />

0 commit comments

Comments
 (0)