Skip to content

Commit 9c12ca8

Browse files
Error parse, span attributes sorted correctly, error shown in main timeline (#501)
* error parse * span * changeset * changes * changeset * fix * Delete .changeset/great-animals-allow.md
1 parent f034064 commit 9c12ca8

File tree

5 files changed

+56
-50
lines changed

5 files changed

+56
-50
lines changed

.changeset/dry-facts-notice.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@inkeep/agents-manage-ui": patch
3+
"@inkeep/agents-run-api": patch
4+
---
5+
6+
error parse and span fix

agents-manage-ui/src/components/traces/timeline/span-attributes.tsx

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
'use client';
22

33
import { Streamdown } from 'streamdown';
4-
import { CodeBubble } from '@/components/traces/timeline/bubble';
5-
import { LabeledBlock } from '@/components/traces/timeline/blocks';
64

75
// Constants for attribute categorization and sorting
8-
const PROCESS_ATTRIBUTE_PREFIXES = ['host.', 'process.'] as const;
6+
const PROCESS_ATTRIBUTE_PREFIXES = ['host.', 'process.', 'signoz.'] as const;
97
const PINNED_ATTRIBUTE_KEYS = [
108
'name',
119
'spanID',
@@ -93,18 +91,9 @@ function sortAttributes(attributes: AttributeMap): AttributeMap {
9391
*/
9492
function ProcessAttributesSection({ processAttributes }: ProcessAttributesSectionProps) {
9593
return (
96-
<div className="border rounded-lg border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-900/50">
97-
<div className="px-3 py-2 border-b border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 rounded-t-lg">
98-
<span className="text-sm font-medium text-gray-900 dark:text-gray-100">
99-
Process Attributes
100-
</span>
101-
</div>
102-
103-
<div className="p-3 rounded-b-lg">
104-
<CodeBubble className="max-h-60 overflow-y-auto">
105-
<Streamdown>{`\`\`\`json\n${JSON.stringify(processAttributes, null, 2)}\n\`\`\``}</Streamdown>
106-
</CodeBubble>
107-
</div>
94+
<div>
95+
<h3 className="text-sm font-medium mb-2">Process Attributes</h3>
96+
<Streamdown>{`\`\`\`json\n${JSON.stringify(processAttributes, null, 2)}\n\`\`\``}</Streamdown>
10897
</div>
10998
);
11099
}
@@ -116,23 +105,29 @@ export function SpanAttributes({ span, className }: SpanAttributesProps) {
116105
const { processAttributes, otherAttributes, hasProcessAttributes } = separateAttributes(span);
117106
const sortedOtherAttributes = sortAttributes(otherAttributes);
118107

108+
// Sort process attributes alphabetically
109+
const sortedProcessAttributes = Object.keys(processAttributes)
110+
.sort()
111+
.reduce((acc, key) => {
112+
acc[key] = processAttributes[key];
113+
return acc;
114+
}, {} as AttributeMap);
119115
const hasOtherAttributes = Object.keys(otherAttributes).length > 0;
120116
const hasAnyAttributes = hasOtherAttributes || hasProcessAttributes;
121117

122118
return (
123119
<div className={`space-y-3 ${className ?? ''}`}>
124120
{/* Main span attributes */}
125121
{hasOtherAttributes && (
126-
<LabeledBlock label="Advanced Span Attributes">
127-
<CodeBubble className="max-h-60 overflow-y-auto">
128-
<Streamdown>{`\`\`\`json\n${JSON.stringify(sortedOtherAttributes, null, 2)}\n\`\`\``}</Streamdown>
129-
</CodeBubble>
130-
</LabeledBlock>
122+
<div>
123+
<h3 className="text-sm font-medium mb-2">Advanced Span Attributes</h3>
124+
<Streamdown>{`\`\`\`json\n${JSON.stringify(sortedOtherAttributes, null, 2)}\n\`\`\``}</Streamdown>
125+
</div>
131126
)}
132127

133128
{/* Process attributes section */}
134129
{hasProcessAttributes && (
135-
<ProcessAttributesSection processAttributes={processAttributes} />
130+
<ProcessAttributesSection processAttributes={sortedProcessAttributes} />
136131
)}
137132

138133
{/* Empty state */}

agents-manage-ui/src/components/traces/timeline/timeline-item.tsx

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import {
2-
AlertCircle,
32
ArrowRight,
43
ArrowUpRight,
54
CheckCircle,
@@ -403,28 +402,28 @@ export function TimelineItem({
403402
</div>
404403
)}
405404

406-
{/* OTEL status for failed agent.generate spans */}
407-
{activity.type === ACTIVITY_TYPES.AI_GENERATION &&
408-
activity.name === 'agent.generate' &&
409-
activity.hasError &&
410-
(activity.otelStatusCode || activity.otelStatusDescription) && (
411-
<div className="mt-2">
412-
<div className="flex items-start gap-2">
413-
<AlertCircle className="h-4 w-4 text-red-600 mt-0.5 flex-shrink-0" />
414-
<div className="space-y-1.5 flex-1">
415-
{activity.otelStatusCode && (
416-
<div className="text-xs text-muted-foreground">
417-
<span className="font-medium">Status Code:</span>{' '}
418-
<span className="font-mono">{activity.otelStatusCode}</span>
419-
</div>
420-
)}
421-
{activity.otelStatusDescription && (
422-
<CodeBubble className="bg-red-50 border-red-200 text-red-800 dark:bg-red-900/20 dark:border-red-800 dark:text-red-300">
423-
{activity.otelStatusDescription}
424-
</CodeBubble>
425-
)}
426-
</div>
427-
</div>
405+
{/* Error display for failed AI/Agent generations */}
406+
{(activity.hasError) &&
407+
activity.otelStatusDescription && (
408+
<div className="space-y-2">
409+
<button
410+
type="button"
411+
onClick={() => onToggleAiMessageCollapse && onToggleAiMessageCollapse(activity.id)}
412+
className="flex items-center gap-1 text-xs text-red-500 hover:text-red-600 transition-colors"
413+
title={isAiMessageCollapsed ? 'Expand error message' : 'Collapse error message'}
414+
>
415+
{isAiMessageCollapsed ? (
416+
<ChevronRight className="h-3 w-3" />
417+
) : (
418+
<ChevronDown className="h-3 w-3" />
419+
)}
420+
Error Details
421+
</button>
422+
{!isAiMessageCollapsed && (
423+
<Bubble className="bg-red-50 border-red-200 text-red-800 dark:bg-red-900/20 dark:border-red-800 dark:text-red-300">
424+
{activity.otelStatusDescription}
425+
</Bubble>
426+
)}
428427
</div>
429428
)}
430429

agents-manage-ui/src/components/traces/timeline/timeline-wrapper.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ export function TimelineWrapper({
211211
.filter(
212212
(activity) =>
213213
activity.type === ACTIVITY_TYPES.AI_ASSISTANT_MESSAGE ||
214-
activity.type === ACTIVITY_TYPES.AI_MODEL_STREAMED_TEXT
214+
activity.type === ACTIVITY_TYPES.AI_MODEL_STREAMED_TEXT ||
215+
(activity.hasError && activity.otelStatusDescription)
215216
)
216217
.map((activity) => activity.id);
217218
}, [sortedActivities]);
@@ -262,7 +263,8 @@ export function TimelineWrapper({
262263
.filter(
263264
(activity) =>
264265
activity.type === ACTIVITY_TYPES.AI_ASSISTANT_MESSAGE ||
265-
activity.type === ACTIVITY_TYPES.AI_MODEL_STREAMED_TEXT
266+
activity.type === ACTIVITY_TYPES.AI_MODEL_STREAMED_TEXT ||
267+
(activity.hasError && activity.otelStatusDescription)
266268
)
267269
.map((activity) => activity.id);
268270
const allCollapsed = aiMessageIds.every((id) => newCollapsed.has(id));
@@ -323,7 +325,8 @@ export function TimelineWrapper({
323325
{sortedActivities.some(
324326
(activity) =>
325327
activity.type === ACTIVITY_TYPES.AI_ASSISTANT_MESSAGE ||
326-
activity.type === ACTIVITY_TYPES.AI_MODEL_STREAMED_TEXT
328+
activity.type === ACTIVITY_TYPES.AI_MODEL_STREAMED_TEXT ||
329+
(activity.hasError && activity.otelStatusDescription)
327330
) && (
328331
<div className="flex items-center gap-1">
329332
<Button

agents-run-api/src/agents/Agent.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,9 +1723,12 @@ export class Agent {
17231723
}
17241724
break;
17251725
case 'error':
1726-
// Handle streaming errors by throwing them to propagate up
1727-
throw event.error;
1728-
// Handle other event types if needed
1726+
if (event.error instanceof Error) {
1727+
throw event.error;
1728+
} else {
1729+
const errorMessage = (event.error as any)?.error?.message;
1730+
throw new Error(errorMessage);
1731+
}
17291732
}
17301733
}
17311734

0 commit comments

Comments
 (0)