@elizaos/client 1.6.1-alpha.6 → 1.6.1-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/main-BM2lpId8.js.map +1 -1
- package/package.json +4 -4
- package/src/components/agent-prism/Avatar.tsx +56 -68
- package/src/components/agent-prism/Badge.tsx +22 -29
- package/src/components/agent-prism/Button.tsx +39 -51
- package/src/components/agent-prism/CollapseAndExpandControls.tsx +9 -25
- package/src/components/agent-prism/CollapsibleSection.tsx +18 -18
- package/src/components/agent-prism/DetailsView/DetailsView.tsx +25 -30
- package/src/components/agent-prism/DetailsView/DetailsViewAttributesTab.tsx +6 -12
- package/src/components/agent-prism/DetailsView/DetailsViewHeader.tsx +9 -13
- package/src/components/agent-prism/DetailsView/DetailsViewHeaderActions.tsx +2 -2
- package/src/components/agent-prism/DetailsView/DetailsViewInputOutputTab.tsx +30 -60
- package/src/components/agent-prism/DetailsView/DetailsViewMetrics.tsx +10 -18
- package/src/components/agent-prism/DetailsView/DetailsViewRawDataTab.tsx +3 -3
- package/src/components/agent-prism/IconButton.tsx +25 -28
- package/src/components/agent-prism/PriceBadge.tsx +4 -4
- package/src/components/agent-prism/SearchInput.tsx +3 -9
- package/src/components/agent-prism/SpanCard/SpanCard.tsx +74 -104
- package/src/components/agent-prism/SpanCard/SpanCardBadges.tsx +7 -13
- package/src/components/agent-prism/SpanCard/SpanCardConnector.tsx +9 -9
- package/src/components/agent-prism/SpanCard/SpanCardTimeline.tsx +15 -20
- package/src/components/agent-prism/SpanCard/SpanCardToggle.tsx +5 -9
- package/src/components/agent-prism/SpanStatus.tsx +24 -30
- package/src/components/agent-prism/Tabs.tsx +16 -19
- package/src/components/agent-prism/TextInput.tsx +18 -21
- package/src/components/agent-prism/TimestampBadge.tsx +5 -9
- package/src/components/agent-prism/TokensBadge.tsx +6 -10
- package/src/components/agent-prism/TraceList/TraceList.tsx +11 -17
- package/src/components/agent-prism/TraceList/TraceListItem.tsx +18 -24
- package/src/components/agent-prism/TraceList/TraceListItemHeader.tsx +8 -20
- package/src/components/agent-prism/TraceViewer.tsx +36 -53
- package/src/components/agent-prism/TreeView.tsx +7 -7
- package/src/components/agent-prism/shared.ts +81 -93
- package/src/components/agent-runs/AgentRunTimeline.tsx +3 -5
- package/src/components/chat.tsx +7 -7
- package/src/lib/agent-prism-utils.ts +29 -32
- package/src/lib/eliza-span-adapter.ts +438 -440
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { cn } from
|
|
2
|
-
import { X } from
|
|
1
|
+
import { cn } from '@/lib/utils';
|
|
2
|
+
import { X } from 'lucide-react';
|
|
3
3
|
import {
|
|
4
4
|
useRef,
|
|
5
5
|
type ChangeEvent,
|
|
6
6
|
type ComponentPropsWithRef,
|
|
7
7
|
type ReactNode,
|
|
8
8
|
type RefObject,
|
|
9
|
-
} from
|
|
9
|
+
} from 'react';
|
|
10
10
|
|
|
11
|
-
export type TextInputProps = ComponentPropsWithRef<
|
|
11
|
+
export type TextInputProps = ComponentPropsWithRef<'input'> & {
|
|
12
12
|
/**
|
|
13
13
|
* Callback fired when the input value changes
|
|
14
14
|
*/
|
|
@@ -53,7 +53,7 @@ export type TextInputProps = ComponentPropsWithRef<"input"> & {
|
|
|
53
53
|
};
|
|
54
54
|
|
|
55
55
|
const iconBaseClassName =
|
|
56
|
-
|
|
56
|
+
'absolute top-1/2 -translate-y-1/2 flex items-center justify-center text-foreground';
|
|
57
57
|
|
|
58
58
|
export const TextInput = ({
|
|
59
59
|
className,
|
|
@@ -87,22 +87,19 @@ export const TextInput = ({
|
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
return (
|
|
90
|
-
<div className={cn(
|
|
90
|
+
<div className={cn('w-full', className)}>
|
|
91
91
|
{label && (
|
|
92
92
|
<label
|
|
93
93
|
htmlFor={id}
|
|
94
|
-
className={cn(
|
|
95
|
-
"block text-sm font-medium text-foreground ",
|
|
96
|
-
hideLabel && "sr-only",
|
|
97
|
-
)}
|
|
94
|
+
className={cn('block text-sm font-medium text-foreground ', hideLabel && 'sr-only')}
|
|
98
95
|
>
|
|
99
96
|
{label}
|
|
100
97
|
</label>
|
|
101
98
|
)}
|
|
102
99
|
<div
|
|
103
100
|
className={cn(
|
|
104
|
-
|
|
105
|
-
label && !hideLabel &&
|
|
101
|
+
'relative flex w-full items-center justify-center',
|
|
102
|
+
label && !hideLabel && 'mt-1'
|
|
106
103
|
)}
|
|
107
104
|
>
|
|
108
105
|
<input
|
|
@@ -111,24 +108,24 @@ export const TextInput = ({
|
|
|
111
108
|
onChange={handleChange}
|
|
112
109
|
className={cn(
|
|
113
110
|
inputClassName,
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
!!startIcon &&
|
|
117
|
-
!!onClear &&
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
111
|
+
'flex h-7 items-center truncate',
|
|
112
|
+
'w-full px-2',
|
|
113
|
+
!!startIcon && 'pl-8',
|
|
114
|
+
!!onClear && 'pr-8',
|
|
115
|
+
'rounded border border-border bg-transparent ',
|
|
116
|
+
'text-foreground placeholder:text-muted-foreground ',
|
|
117
|
+
'hover:border-border dark:hover:border-gray-700'
|
|
121
118
|
)}
|
|
122
119
|
{...rest}
|
|
123
120
|
/>
|
|
124
121
|
{startIcon && (
|
|
125
|
-
<div className={cn(iconBaseClassName,
|
|
122
|
+
<div className={cn(iconBaseClassName, 'left-2')} aria-hidden>
|
|
126
123
|
{startIcon}
|
|
127
124
|
</div>
|
|
128
125
|
)}
|
|
129
126
|
{onClear && rest.value && (
|
|
130
127
|
<button
|
|
131
|
-
className={cn(iconBaseClassName,
|
|
128
|
+
className={cn(iconBaseClassName, 'right-2')}
|
|
132
129
|
aria-label="Clear input value"
|
|
133
130
|
onClick={handleClear}
|
|
134
131
|
type="button"
|
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import type { ComponentPropsWithRef } from
|
|
1
|
+
import type { ComponentPropsWithRef } from 'react';
|
|
2
2
|
|
|
3
|
-
import { Badge, type BadgeProps } from
|
|
3
|
+
import { Badge, type BadgeProps } from './Badge';
|
|
4
4
|
|
|
5
|
-
export type TimestampBadgeProps = ComponentPropsWithRef<
|
|
5
|
+
export type TimestampBadgeProps = ComponentPropsWithRef<'span'> & {
|
|
6
6
|
timestamp: number;
|
|
7
|
-
size?: BadgeProps[
|
|
7
|
+
size?: BadgeProps['size'];
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
export const TimestampBadge = ({
|
|
11
|
-
timestamp,
|
|
12
|
-
size,
|
|
13
|
-
...rest
|
|
14
|
-
}: TimestampBadgeProps) => {
|
|
10
|
+
export const TimestampBadge = ({ timestamp, size, ...rest }: TimestampBadgeProps) => {
|
|
15
11
|
return (
|
|
16
12
|
<Badge
|
|
17
13
|
variant="outline"
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import type { ComponentPropsWithRef } from
|
|
1
|
+
import type { ComponentPropsWithRef } from 'react';
|
|
2
2
|
|
|
3
|
-
import { Coins } from
|
|
3
|
+
import { Coins } from 'lucide-react';
|
|
4
4
|
|
|
5
|
-
import { Badge, type BadgeProps } from
|
|
5
|
+
import { Badge, type BadgeProps } from './Badge';
|
|
6
6
|
|
|
7
|
-
export type TokensBadgeProps = ComponentPropsWithRef<
|
|
7
|
+
export type TokensBadgeProps = ComponentPropsWithRef<'span'> & {
|
|
8
8
|
tokensCount: number;
|
|
9
|
-
size?: BadgeProps[
|
|
9
|
+
size?: BadgeProps['size'];
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
export const TokensBadge = ({
|
|
13
|
-
tokensCount,
|
|
14
|
-
size,
|
|
15
|
-
...rest
|
|
16
|
-
}: TokensBadgeProps) => {
|
|
12
|
+
export const TokensBadge = ({ tokensCount, size, ...rest }: TokensBadgeProps) => {
|
|
17
13
|
return (
|
|
18
14
|
<Badge
|
|
19
15
|
iconStart={<Coins className="size-2.5" />}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { TraceRecord } from
|
|
1
|
+
import type { TraceRecord } from '@evilmartians/agent-prism-types';
|
|
2
2
|
|
|
3
|
-
import { cn } from
|
|
4
|
-
import { ArrowLeft } from
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
import { ArrowLeft } from 'lucide-react';
|
|
5
5
|
|
|
6
|
-
import { Badge, type BadgeProps } from
|
|
7
|
-
import { IconButton } from
|
|
8
|
-
import { TraceListItem } from
|
|
6
|
+
import { Badge, type BadgeProps } from '../Badge.tsx';
|
|
7
|
+
import { IconButton } from '../IconButton.tsx';
|
|
8
|
+
import { TraceListItem } from './TraceListItem.tsx';
|
|
9
9
|
|
|
10
10
|
type TraceRecordWithBadges = TraceRecord & {
|
|
11
11
|
badges?: Array<BadgeProps>;
|
|
@@ -31,20 +31,15 @@ export const TraceList = ({
|
|
|
31
31
|
return (
|
|
32
32
|
<div
|
|
33
33
|
className={cn(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
expanded ?
|
|
37
|
-
className
|
|
34
|
+
'w-full min-w-0',
|
|
35
|
+
'flex flex-col gap-3',
|
|
36
|
+
expanded ? 'w-full' : 'w-fit',
|
|
37
|
+
className
|
|
38
38
|
)}
|
|
39
39
|
>
|
|
40
40
|
<header className="flex min-h-6 items-center justify-between gap-2">
|
|
41
41
|
<div className="flex items-center gap-2">
|
|
42
|
-
<h2
|
|
43
|
-
className={cn(
|
|
44
|
-
"font-semibold text-lg text-foreground",
|
|
45
|
-
!expanded && "hidden",
|
|
46
|
-
)}
|
|
47
|
-
>
|
|
42
|
+
<h2 className={cn('font-semibold text-lg text-foreground', !expanded && 'hidden')}>
|
|
48
43
|
Traces
|
|
49
44
|
</h2>
|
|
50
45
|
|
|
@@ -55,7 +50,6 @@ export const TraceList = ({
|
|
|
55
50
|
label={traces.length}
|
|
56
51
|
/>
|
|
57
52
|
</div>
|
|
58
|
-
|
|
59
53
|
</header>
|
|
60
54
|
|
|
61
55
|
{expanded && (
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import type { TraceRecord } from
|
|
1
|
+
import type { TraceRecord } from '@evilmartians/agent-prism-types';
|
|
2
2
|
|
|
3
|
-
import { cn } from
|
|
4
|
-
import { useCallback, type KeyboardEvent } from
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
import { useCallback, type KeyboardEvent } from 'react';
|
|
5
5
|
|
|
6
|
-
import { type AvatarProps } from
|
|
7
|
-
import { Badge, type BadgeProps } from
|
|
8
|
-
import { PriceBadge } from
|
|
9
|
-
import { TimestampBadge } from
|
|
10
|
-
import { TokensBadge } from
|
|
11
|
-
import { TraceListItemHeader } from
|
|
6
|
+
import { type AvatarProps } from '../Avatar.tsx';
|
|
7
|
+
import { Badge, type BadgeProps } from '../Badge.tsx';
|
|
8
|
+
import { PriceBadge } from '../PriceBadge.tsx';
|
|
9
|
+
import { TimestampBadge } from '../TimestampBadge.tsx';
|
|
10
|
+
import { TokensBadge } from '../TokensBadge.tsx';
|
|
11
|
+
import { TraceListItemHeader } from './TraceListItemHeader.tsx';
|
|
12
12
|
|
|
13
13
|
interface TraceListItemProps {
|
|
14
14
|
trace: TraceRecord;
|
|
@@ -27,12 +27,12 @@ export const TraceListItem = ({
|
|
|
27
27
|
}: TraceListItemProps) => {
|
|
28
28
|
const handleKeyDown = useCallback(
|
|
29
29
|
(e: KeyboardEvent): void => {
|
|
30
|
-
if (e.key ===
|
|
30
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
31
31
|
e.preventDefault();
|
|
32
32
|
onClick?.();
|
|
33
33
|
}
|
|
34
34
|
},
|
|
35
|
-
[onClick]
|
|
35
|
+
[onClick]
|
|
36
36
|
);
|
|
37
37
|
|
|
38
38
|
const { name, agentDescription, totalCost, totalTokens, startTime } = trace;
|
|
@@ -40,12 +40,10 @@ export const TraceListItem = ({
|
|
|
40
40
|
return (
|
|
41
41
|
<div
|
|
42
42
|
className={cn(
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
isSelected
|
|
47
|
-
? "bg-muted"
|
|
48
|
-
: "bg-card",
|
|
43
|
+
'group w-full',
|
|
44
|
+
'flex flex-col gap-2.5 p-4',
|
|
45
|
+
'cursor-pointer',
|
|
46
|
+
isSelected ? 'bg-muted' : 'bg-card'
|
|
49
47
|
)}
|
|
50
48
|
role="button"
|
|
51
49
|
tabIndex={0}
|
|
@@ -60,19 +58,15 @@ export const TraceListItem = ({
|
|
|
60
58
|
{agentDescription}
|
|
61
59
|
</span>
|
|
62
60
|
|
|
63
|
-
{typeof totalCost ===
|
|
61
|
+
{typeof totalCost === 'number' && <PriceBadge cost={totalCost} />}
|
|
64
62
|
|
|
65
|
-
{typeof totalTokens ===
|
|
66
|
-
<TokensBadge tokensCount={totalTokens} />
|
|
67
|
-
)}
|
|
63
|
+
{typeof totalTokens === 'number' && <TokensBadge tokensCount={totalTokens} />}
|
|
68
64
|
|
|
69
65
|
{badges?.map((badge, index) => (
|
|
70
66
|
<Badge key={index} theme={badge.theme} size="4" label={badge.label} />
|
|
71
67
|
))}
|
|
72
68
|
|
|
73
|
-
{typeof startTime ===
|
|
74
|
-
<TimestampBadge timestamp={startTime} />
|
|
75
|
-
)}
|
|
69
|
+
{typeof startTime === 'number' && <TimestampBadge timestamp={startTime} />}
|
|
76
70
|
</div>
|
|
77
71
|
</div>
|
|
78
72
|
);
|
|
@@ -1,27 +1,22 @@
|
|
|
1
|
-
import type { TraceRecord } from
|
|
1
|
+
import type { TraceRecord } from '@evilmartians/agent-prism-types';
|
|
2
2
|
|
|
3
|
-
import { formatDuration } from
|
|
3
|
+
import { formatDuration } from '@evilmartians/agent-prism-data';
|
|
4
4
|
|
|
5
|
-
import { Avatar, type AvatarProps } from
|
|
6
|
-
import { Badge } from
|
|
5
|
+
import { Avatar, type AvatarProps } from '../Avatar.tsx';
|
|
6
|
+
import { Badge } from '../Badge.tsx';
|
|
7
7
|
|
|
8
8
|
interface TraceListItemHeaderProps {
|
|
9
9
|
trace: TraceRecord;
|
|
10
10
|
avatar?: AvatarProps;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export const TraceListItemHeader = ({
|
|
14
|
-
trace,
|
|
15
|
-
avatar,
|
|
16
|
-
}: TraceListItemHeaderProps) => {
|
|
13
|
+
export const TraceListItemHeader = ({ trace, avatar }: TraceListItemHeaderProps) => {
|
|
17
14
|
return (
|
|
18
15
|
<header className="flex min-w-0 flex-wrap items-center justify-between gap-2">
|
|
19
16
|
<div className="flex min-w-0 items-center gap-1.5 overflow-hidden">
|
|
20
17
|
{avatar && <Avatar size="4" {...avatar} />}
|
|
21
18
|
|
|
22
|
-
<h3 className="font-medium max-w-full truncate text-sm text-foreground">
|
|
23
|
-
{trace.name}
|
|
24
|
-
</h3>
|
|
19
|
+
<h3 className="font-medium max-w-full truncate text-sm text-foreground">{trace.name}</h3>
|
|
25
20
|
</div>
|
|
26
21
|
|
|
27
22
|
<div className="flex items-center gap-2">
|
|
@@ -29,17 +24,10 @@ export const TraceListItemHeader = ({
|
|
|
29
24
|
size="5"
|
|
30
25
|
theme="gray"
|
|
31
26
|
variant="outline"
|
|
32
|
-
label={
|
|
33
|
-
trace.spansCount === 1 ? "1 span" : `${trace.spansCount} spans`
|
|
34
|
-
}
|
|
27
|
+
label={trace.spansCount === 1 ? '1 span' : `${trace.spansCount} spans`}
|
|
35
28
|
/>
|
|
36
29
|
|
|
37
|
-
<Badge
|
|
38
|
-
size="5"
|
|
39
|
-
theme="gray"
|
|
40
|
-
variant="outline"
|
|
41
|
-
label={formatDuration(trace.durationMs)}
|
|
42
|
-
/>
|
|
30
|
+
<Badge size="5" theme="gray" variant="outline" label={formatDuration(trace.durationMs)} />
|
|
43
31
|
</div>
|
|
44
32
|
</header>
|
|
45
33
|
);
|
|
@@ -1,40 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
CollapseAllButton,
|
|
20
|
-
ExpandAllButton,
|
|
21
|
-
} from "./CollapseAndExpandControls";
|
|
22
|
-
import { DetailsView } from "./DetailsView/DetailsView";
|
|
23
|
-
import { SearchInput } from "./SearchInput";
|
|
24
|
-
import { TraceList } from "./TraceList/TraceList";
|
|
25
|
-
import { TraceListItemHeader } from "./TraceList/TraceListItemHeader";
|
|
26
|
-
import { TreeView } from "./TreeView";
|
|
1
|
+
import { flattenSpans, formatDuration } from '@evilmartians/agent-prism-data';
|
|
2
|
+
import { type TraceRecord, type TraceSpan } from '@evilmartians/agent-prism-types';
|
|
3
|
+
import { filterSpansRecursively } from '@/lib/agent-prism-utils';
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
import { ArrowLeft } from 'lucide-react';
|
|
6
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
7
|
+
|
|
8
|
+
import type { BadgeProps } from './Badge';
|
|
9
|
+
import type { SpanCardViewOptions } from './SpanCard/SpanCard';
|
|
10
|
+
|
|
11
|
+
import { Button } from './Button';
|
|
12
|
+
import { CollapseAllButton, ExpandAllButton } from './CollapseAndExpandControls';
|
|
13
|
+
import { DetailsView } from './DetailsView/DetailsView';
|
|
14
|
+
import { SearchInput } from './SearchInput';
|
|
15
|
+
import { TraceList } from './TraceList/TraceList';
|
|
16
|
+
import { TraceListItemHeader } from './TraceList/TraceListItemHeader';
|
|
17
|
+
import { TreeView } from './TreeView';
|
|
27
18
|
import {
|
|
28
19
|
Select,
|
|
29
20
|
SelectContent,
|
|
30
21
|
SelectItem,
|
|
31
22
|
SelectTrigger,
|
|
32
23
|
SelectValue,
|
|
33
|
-
} from
|
|
34
|
-
import { Badge } from
|
|
35
|
-
import { PriceBadge } from
|
|
36
|
-
import { TimestampBadge } from
|
|
37
|
-
import { TokensBadge } from
|
|
24
|
+
} from '@/components/ui/select';
|
|
25
|
+
import { Badge } from './Badge';
|
|
26
|
+
import { PriceBadge } from './PriceBadge';
|
|
27
|
+
import { TimestampBadge } from './TimestampBadge';
|
|
28
|
+
import { TokensBadge } from './TokensBadge';
|
|
38
29
|
|
|
39
30
|
export interface TraceViewerData {
|
|
40
31
|
traceRecord: TraceRecord;
|
|
@@ -49,16 +40,14 @@ export interface TraceViewerProps {
|
|
|
49
40
|
}
|
|
50
41
|
|
|
51
42
|
export const TraceViewer = ({ data }: TraceViewerProps) => {
|
|
52
|
-
const [selectedTrace, setSelectedTrace] = useState<
|
|
53
|
-
|
|
54
|
-
>(data[0]?.traceRecord);
|
|
55
|
-
const [selectedTraceSpans, setSelectedTraceSpans] = useState<TraceSpan[]>(
|
|
56
|
-
data[0]?.spans ?? [],
|
|
43
|
+
const [selectedTrace, setSelectedTrace] = useState<TraceRecordWithDisplayData | undefined>(
|
|
44
|
+
data[0]?.traceRecord
|
|
57
45
|
);
|
|
46
|
+
const [selectedTraceSpans, setSelectedTraceSpans] = useState<TraceSpan[]>(data[0]?.spans ?? []);
|
|
58
47
|
const [selectedSpan, setSelectedSpan] = useState<TraceSpan | undefined>(
|
|
59
|
-
data[0]?.spans?.[0]?.children?.[0]
|
|
48
|
+
data[0]?.spans?.[0]?.children?.[0]
|
|
60
49
|
);
|
|
61
|
-
const [searchValue, setSearchValue] = useState(
|
|
50
|
+
const [searchValue, setSearchValue] = useState('');
|
|
62
51
|
|
|
63
52
|
const [traceListExpanded, setTraceListExpanded] = useState(true);
|
|
64
53
|
|
|
@@ -103,11 +92,9 @@ export const TraceViewer = ({ data }: TraceViewerProps) => {
|
|
|
103
92
|
const handleTraceSelect = useCallback(
|
|
104
93
|
(trace: TraceRecord) => {
|
|
105
94
|
setSelectedTrace(trace);
|
|
106
|
-
setSelectedTraceSpans(
|
|
107
|
-
data.find((item) => item.traceRecord.id === trace.id)?.spans ?? [],
|
|
108
|
-
);
|
|
95
|
+
setSelectedTraceSpans(data.find((item) => item.traceRecord.id === trace.id)?.spans ?? []);
|
|
109
96
|
},
|
|
110
|
-
[data]
|
|
97
|
+
[data]
|
|
111
98
|
);
|
|
112
99
|
|
|
113
100
|
const props: LayoutProps = {
|
|
@@ -201,7 +188,7 @@ const DesktopLayout = ({
|
|
|
201
188
|
<div className="flex items-center gap-4 w-full">
|
|
202
189
|
<span className="font-semibold text-base">{selectedTrace.name}</span>
|
|
203
190
|
<div className="flex items-center gap-2 ml-auto">
|
|
204
|
-
{typeof selectedTrace.startTime ===
|
|
191
|
+
{typeof selectedTrace.startTime === 'number' && (
|
|
205
192
|
<span className="text-xs text-muted-foreground font-mono">
|
|
206
193
|
{new Date(selectedTrace.startTime).toLocaleTimeString()}
|
|
207
194
|
</span>
|
|
@@ -235,7 +222,7 @@ const DesktopLayout = ({
|
|
|
235
222
|
)}
|
|
236
223
|
</div>
|
|
237
224
|
<div className="flex items-center gap-2 flex-shrink-0">
|
|
238
|
-
{typeof trace.startTime ===
|
|
225
|
+
{typeof trace.startTime === 'number' && (
|
|
239
226
|
<span className="text-xs text-muted-foreground font-mono">
|
|
240
227
|
{new Date(trace.startTime).toLocaleTimeString()}
|
|
241
228
|
</span>
|
|
@@ -264,7 +251,7 @@ const DesktopLayout = ({
|
|
|
264
251
|
<SearchInput
|
|
265
252
|
id="span-search-desktop"
|
|
266
253
|
name="search"
|
|
267
|
-
onClear={() => setSearchValue(
|
|
254
|
+
onClear={() => setSearchValue('')}
|
|
268
255
|
value={searchValue}
|
|
269
256
|
onValueChange={setSearchValue}
|
|
270
257
|
className="max-w-60 grow"
|
|
@@ -279,9 +266,7 @@ const DesktopLayout = ({
|
|
|
279
266
|
</div>
|
|
280
267
|
|
|
281
268
|
{filteredSpans.length === 0 ? (
|
|
282
|
-
<div className="p-3 text-center text-muted-foreground">
|
|
283
|
-
No spans found
|
|
284
|
-
</div>
|
|
269
|
+
<div className="p-3 text-center text-muted-foreground">No spans found</div>
|
|
285
270
|
) : (
|
|
286
271
|
<TreeView
|
|
287
272
|
spans={filteredSpans}
|
|
@@ -325,7 +310,7 @@ const DesktopLayout = ({
|
|
|
325
310
|
)}
|
|
326
311
|
</div>
|
|
327
312
|
<div className="flex items-center gap-2 flex-shrink-0">
|
|
328
|
-
{typeof trace.startTime ===
|
|
313
|
+
{typeof trace.startTime === 'number' && (
|
|
329
314
|
<span className="text-xs text-muted-foreground font-mono">
|
|
330
315
|
{new Date(trace.startTime).toLocaleTimeString()}
|
|
331
316
|
</span>
|
|
@@ -408,7 +393,7 @@ const MobileLayout = ({
|
|
|
408
393
|
<SearchInput
|
|
409
394
|
id="span-search-mobile"
|
|
410
395
|
name="search"
|
|
411
|
-
onClear={() => setSearchValue(
|
|
396
|
+
onClear={() => setSearchValue('')}
|
|
412
397
|
value={searchValue}
|
|
413
398
|
onValueChange={setSearchValue}
|
|
414
399
|
className="max-w-60 grow"
|
|
@@ -423,9 +408,7 @@ const MobileLayout = ({
|
|
|
423
408
|
</div>
|
|
424
409
|
|
|
425
410
|
{filteredSpans.length === 0 ? (
|
|
426
|
-
<div className="p-3 text-center text-muted-foreground">
|
|
427
|
-
No spans found
|
|
428
|
-
</div>
|
|
411
|
+
<div className="p-3 text-center text-muted-foreground">No spans found</div>
|
|
429
412
|
) : (
|
|
430
413
|
<TreeView
|
|
431
414
|
spans={filteredSpans}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { TraceSpan } from
|
|
1
|
+
import type { TraceSpan } from '@evilmartians/agent-prism-types';
|
|
2
2
|
|
|
3
|
-
import { findTimeRange, flattenSpans } from
|
|
4
|
-
import { cn } from
|
|
5
|
-
import { type FC } from
|
|
3
|
+
import { findTimeRange, flattenSpans } from '@evilmartians/agent-prism-data';
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
import { type FC } from 'react';
|
|
6
6
|
|
|
7
|
-
import { SpanCard, type SpanCardViewOptions } from
|
|
7
|
+
import { SpanCard, type SpanCardViewOptions } from './SpanCard/SpanCard';
|
|
8
8
|
|
|
9
9
|
interface TreeViewProps {
|
|
10
10
|
spans: TraceSpan[];
|
|
@@ -19,7 +19,7 @@ interface TreeViewProps {
|
|
|
19
19
|
export const TreeView: FC<TreeViewProps> = ({
|
|
20
20
|
spans,
|
|
21
21
|
onSpanSelect,
|
|
22
|
-
className =
|
|
22
|
+
className = '',
|
|
23
23
|
selectedSpan,
|
|
24
24
|
expandedSpansIds,
|
|
25
25
|
onExpandSpansIdsChange,
|
|
@@ -32,7 +32,7 @@ export const TreeView: FC<TreeViewProps> = ({
|
|
|
32
32
|
return (
|
|
33
33
|
<div className="w-full min-w-0 p-4">
|
|
34
34
|
<ul
|
|
35
|
-
className={cn(className,
|
|
35
|
+
className={cn(className, 'overflow-x-auto space-y-1')}
|
|
36
36
|
role="tree"
|
|
37
37
|
aria-label="Hierarchical card list"
|
|
38
38
|
>
|