@elizaos/client 1.6.1-alpha.5 → 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-Bbs84AcL.js → main-BM2lpId8.js} +60 -60
- package/dist/assets/main-BM2lpId8.js.map +1 -0
- package/dist/assets/{main-4tyUgNqd.js → main-CQAV8tyh.js} +4 -4
- package/dist/assets/main-CQAV8tyh.js.map +1 -0
- package/dist/assets/react-vendor-C1OK-nqm.js +611 -0
- package/dist/assets/react-vendor-C1OK-nqm.js.map +1 -0
- package/dist/index.html +1 -1
- package/package.json +25 -25
- 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
- package/dist/assets/main-4tyUgNqd.js.map +0 -1
- package/dist/assets/main-Bbs84AcL.js.map +0 -1
- package/dist/assets/react-vendor-DxnAFk-d.js +0 -611
- package/dist/assets/react-vendor-DxnAFk-d.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as Collapsible from
|
|
2
|
-
import { cn } from
|
|
3
|
-
import { ChevronDown } from
|
|
4
|
-
import * as React from
|
|
1
|
+
import * as Collapsible from '@radix-ui/react-collapsible';
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
import { ChevronDown } from 'lucide-react';
|
|
4
|
+
import * as React from 'react';
|
|
5
5
|
|
|
6
6
|
export interface CollapsibleSectionProps {
|
|
7
7
|
/**
|
|
@@ -51,9 +51,9 @@ export const CollapsibleSection: React.FC<CollapsibleSectionProps> = ({
|
|
|
51
51
|
rightContent,
|
|
52
52
|
children,
|
|
53
53
|
defaultOpen = false,
|
|
54
|
-
className =
|
|
55
|
-
triggerClassName =
|
|
56
|
-
contentClassName =
|
|
54
|
+
className = '',
|
|
55
|
+
triggerClassName = '',
|
|
56
|
+
contentClassName = '',
|
|
57
57
|
onOpenChange,
|
|
58
58
|
}) => {
|
|
59
59
|
const [open, setOpen] = React.useState(defaultOpen);
|
|
@@ -63,42 +63,42 @@ export const CollapsibleSection: React.FC<CollapsibleSectionProps> = ({
|
|
|
63
63
|
setOpen(open);
|
|
64
64
|
onOpenChange?.(open);
|
|
65
65
|
},
|
|
66
|
-
[onOpenChange]
|
|
66
|
+
[onOpenChange]
|
|
67
67
|
);
|
|
68
68
|
|
|
69
69
|
const handleKeyDown = React.useCallback(
|
|
70
70
|
(e: React.KeyboardEvent<HTMLDivElement>): void => {
|
|
71
|
-
if (e.key ===
|
|
71
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
72
72
|
e.preventDefault();
|
|
73
73
|
handleOpenChange(!open);
|
|
74
74
|
}
|
|
75
75
|
},
|
|
76
|
-
[handleOpenChange, open]
|
|
76
|
+
[handleOpenChange, open]
|
|
77
77
|
);
|
|
78
78
|
|
|
79
79
|
return (
|
|
80
80
|
<Collapsible.Root
|
|
81
81
|
open={open}
|
|
82
82
|
onOpenChange={handleOpenChange}
|
|
83
|
-
className={cn(
|
|
83
|
+
className={cn('rounded-lg', className)}
|
|
84
84
|
>
|
|
85
85
|
<Collapsible.Trigger asChild>
|
|
86
86
|
<div
|
|
87
87
|
tabIndex={0}
|
|
88
88
|
role="button"
|
|
89
89
|
className={cn(
|
|
90
|
-
|
|
91
|
-
triggerClassName
|
|
90
|
+
'mb-1 flex w-full items-center justify-between gap-2 rounded-lg px-1 py-3 text-left text-sm font-medium text-foreground',
|
|
91
|
+
triggerClassName
|
|
92
92
|
)}
|
|
93
93
|
onKeyDown={handleKeyDown}
|
|
94
94
|
aria-expanded={open}
|
|
95
|
-
aria-label={`${open ?
|
|
95
|
+
aria-label={`${open ? 'Collapse' : 'Expand'} content of "${title}" section`}
|
|
96
96
|
>
|
|
97
97
|
<div className="flex w-full items-center gap-2">
|
|
98
98
|
<ChevronDown
|
|
99
99
|
className={cn(
|
|
100
|
-
|
|
101
|
-
open &&
|
|
100
|
+
'h-3 w-3 text-muted-foreground transition-transform duration-200',
|
|
101
|
+
open && 'rotate-180'
|
|
102
102
|
)}
|
|
103
103
|
/>
|
|
104
104
|
<span className="truncate">{title}</span>
|
|
@@ -110,8 +110,8 @@ export const CollapsibleSection: React.FC<CollapsibleSectionProps> = ({
|
|
|
110
110
|
|
|
111
111
|
<Collapsible.Content
|
|
112
112
|
className={cn(
|
|
113
|
-
|
|
114
|
-
contentClassName
|
|
113
|
+
'data-[state=closed]:animate-slideUp data-[state=open]:animate-slideDown',
|
|
114
|
+
contentClassName
|
|
115
115
|
)}
|
|
116
116
|
>
|
|
117
117
|
{children}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import type { TraceSpan } from
|
|
1
|
+
import type { TraceSpan } from '@evilmartians/agent-prism-types';
|
|
2
2
|
|
|
3
|
-
import { cn } from
|
|
4
|
-
import { SquareTerminal, Tags, ArrowRightLeft } from
|
|
5
|
-
import { useState, type ReactElement, type ReactNode } from
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
|
+
import { SquareTerminal, Tags, ArrowRightLeft } from 'lucide-react';
|
|
5
|
+
import { useState, type ReactElement, type ReactNode } from 'react';
|
|
6
6
|
|
|
7
|
-
import type { AvatarProps } from
|
|
7
|
+
import type { AvatarProps } from '../Avatar';
|
|
8
8
|
|
|
9
|
-
import { Tabs, type TabItem } from
|
|
10
|
-
import { DetailsViewAttributesTab } from
|
|
11
|
-
import { DetailsViewHeader } from
|
|
12
|
-
import { DetailsViewInputOutputTab } from
|
|
13
|
-
import { DetailsViewMetrics } from
|
|
14
|
-
import { DetailsViewRawDataTab } from
|
|
9
|
+
import { Tabs, type TabItem } from '../Tabs';
|
|
10
|
+
import { DetailsViewAttributesTab } from './DetailsViewAttributesTab';
|
|
11
|
+
import { DetailsViewHeader } from './DetailsViewHeader';
|
|
12
|
+
import { DetailsViewInputOutputTab } from './DetailsViewInputOutputTab';
|
|
13
|
+
import { DetailsViewMetrics } from './DetailsViewMetrics';
|
|
14
|
+
import { DetailsViewRawDataTab } from './DetailsViewRawDataTab';
|
|
15
15
|
|
|
16
|
-
type DetailsViewTab =
|
|
16
|
+
type DetailsViewTab = 'input-output' | 'attributes' | 'raw';
|
|
17
17
|
|
|
18
18
|
export interface DetailsViewProps {
|
|
19
19
|
/**
|
|
@@ -71,22 +71,22 @@ export const DetailsView = ({
|
|
|
71
71
|
customHeader,
|
|
72
72
|
onTabChange,
|
|
73
73
|
}: DetailsViewProps): ReactElement => {
|
|
74
|
-
const [tab, setTab] = useState<DetailsViewTab>(defaultTab ||
|
|
74
|
+
const [tab, setTab] = useState<DetailsViewTab>(defaultTab || 'input-output');
|
|
75
75
|
|
|
76
76
|
const tabItems: TabItem<DetailsViewTab>[] = [
|
|
77
77
|
{
|
|
78
|
-
value:
|
|
79
|
-
label:
|
|
78
|
+
value: 'input-output',
|
|
79
|
+
label: 'In/Out',
|
|
80
80
|
icon: <ArrowRightLeft className="size-4" />,
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
|
-
value:
|
|
84
|
-
label:
|
|
83
|
+
value: 'attributes',
|
|
84
|
+
label: 'Attributes',
|
|
85
85
|
icon: <Tags className="size-4" />,
|
|
86
86
|
},
|
|
87
87
|
{
|
|
88
|
-
value:
|
|
89
|
-
label:
|
|
88
|
+
value: 'raw',
|
|
89
|
+
label: 'RAW',
|
|
90
90
|
icon: <SquareTerminal className="size-4" />,
|
|
91
91
|
},
|
|
92
92
|
];
|
|
@@ -97,10 +97,10 @@ export const DetailsView = ({
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
const resolvedHeaderActions =
|
|
100
|
-
typeof headerActions ===
|
|
100
|
+
typeof headerActions === 'function' ? headerActions(data) : headerActions;
|
|
101
101
|
|
|
102
102
|
const headerContent = customHeader ? (
|
|
103
|
-
typeof customHeader ===
|
|
103
|
+
typeof customHeader === 'function' ? (
|
|
104
104
|
customHeader({ data })
|
|
105
105
|
) : (
|
|
106
106
|
customHeader
|
|
@@ -115,12 +115,7 @@ export const DetailsView = ({
|
|
|
115
115
|
);
|
|
116
116
|
|
|
117
117
|
return (
|
|
118
|
-
<div
|
|
119
|
-
className={cn(
|
|
120
|
-
"min-w-0 rounded-lg border border-border bg-card p-4 shadow-sm",
|
|
121
|
-
className,
|
|
122
|
-
)}
|
|
123
|
-
>
|
|
118
|
+
<div className={cn('min-w-0 rounded-lg border border-border bg-card p-4 shadow-sm', className)}>
|
|
124
119
|
{headerContent}
|
|
125
120
|
|
|
126
121
|
<DetailsViewMetrics data={data} />
|
|
@@ -133,9 +128,9 @@ export const DetailsView = ({
|
|
|
133
128
|
defaultValue={defaultTab}
|
|
134
129
|
/>
|
|
135
130
|
|
|
136
|
-
{tab ===
|
|
137
|
-
{tab ===
|
|
138
|
-
{tab ===
|
|
131
|
+
{tab === 'input-output' && <DetailsViewInputOutputTab data={data} />}
|
|
132
|
+
{tab === 'attributes' && <DetailsViewAttributesTab data={data} />}
|
|
133
|
+
{tab === 'raw' && <DetailsViewRawDataTab data={data} />}
|
|
139
134
|
</div>
|
|
140
135
|
);
|
|
141
136
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { TraceSpan } from
|
|
1
|
+
import type { TraceSpan } from '@evilmartians/agent-prism-types';
|
|
2
2
|
|
|
3
|
-
import { CollapsibleSection } from
|
|
4
|
-
import { TextInput } from
|
|
3
|
+
import { CollapsibleSection } from '../CollapsibleSection';
|
|
4
|
+
import { TextInput } from '../TextInput';
|
|
5
5
|
|
|
6
6
|
interface AttributesTabProps {
|
|
7
7
|
data: TraceSpan;
|
|
@@ -11,9 +11,7 @@ export const DetailsViewAttributesTab = ({ data }: AttributesTabProps) => (
|
|
|
11
11
|
<div className="space-y-6">
|
|
12
12
|
{(!data.attributes || data.attributes.length === 0) && (
|
|
13
13
|
<div className="p-6 text-center">
|
|
14
|
-
<p className="text-muted-foreground ">
|
|
15
|
-
No attributes available for this span.
|
|
16
|
-
</p>
|
|
14
|
+
<p className="text-muted-foreground ">No attributes available for this span.</p>
|
|
17
15
|
</div>
|
|
18
16
|
)}
|
|
19
17
|
|
|
@@ -22,14 +20,10 @@ export const DetailsViewAttributesTab = ({ data }: AttributesTabProps) => (
|
|
|
22
20
|
attribute.value.stringValue ||
|
|
23
21
|
attribute.value.intValue ||
|
|
24
22
|
attribute.value.boolValue?.toString() ||
|
|
25
|
-
|
|
23
|
+
'N/A';
|
|
26
24
|
|
|
27
25
|
return (
|
|
28
|
-
<CollapsibleSection
|
|
29
|
-
key={`${attribute.key}-${index}`}
|
|
30
|
-
title={attribute.key}
|
|
31
|
-
defaultOpen
|
|
32
|
-
>
|
|
26
|
+
<CollapsibleSection key={`${attribute.key}-${index}`} title={attribute.key} defaultOpen>
|
|
33
27
|
<TextInput
|
|
34
28
|
id={`${data.id}-attribute-${index}`}
|
|
35
29
|
value={value}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { TraceSpan } from
|
|
1
|
+
import type { TraceSpan } from '@evilmartians/agent-prism-types';
|
|
2
2
|
|
|
3
|
-
import { Check, Copy } from
|
|
4
|
-
import { useState, type ReactNode } from
|
|
3
|
+
import { Check, Copy } from 'lucide-react';
|
|
4
|
+
import { useState, type ReactNode } from 'react';
|
|
5
5
|
|
|
6
|
-
import { Avatar, type AvatarProps } from
|
|
7
|
-
import { IconButton } from
|
|
8
|
-
import { SpanStatus } from
|
|
6
|
+
import { Avatar, type AvatarProps } from '../Avatar';
|
|
7
|
+
import { IconButton } from '../IconButton';
|
|
8
|
+
import { SpanStatus } from '../SpanStatus.tsx';
|
|
9
9
|
|
|
10
10
|
export interface DetailsViewHeaderProps {
|
|
11
11
|
data: TraceSpan;
|
|
@@ -29,7 +29,7 @@ export const DetailsViewHeader = ({
|
|
|
29
29
|
avatar,
|
|
30
30
|
copyButton,
|
|
31
31
|
actions,
|
|
32
|
-
className =
|
|
32
|
+
className = 'mb-4 flex flex-wrap items-center gap-4',
|
|
33
33
|
}: DetailsViewHeaderProps) => {
|
|
34
34
|
const [hasCopied, setHasCopied] = useState(false);
|
|
35
35
|
|
|
@@ -46,9 +46,7 @@ export const DetailsViewHeader = ({
|
|
|
46
46
|
<div className="flex items-center gap-1.5">
|
|
47
47
|
{avatar && <Avatar size="4" {...avatar} />}
|
|
48
48
|
|
|
49
|
-
<span className="text-base tracking-wide text-foreground ">
|
|
50
|
-
{data.title}
|
|
51
|
-
</span>
|
|
49
|
+
<span className="text-base tracking-wide text-foreground ">{data.title}</span>
|
|
52
50
|
|
|
53
51
|
<div className="flex size-5 items-center justify-center">
|
|
54
52
|
<SpanStatus status={data.status} />
|
|
@@ -56,9 +54,7 @@ export const DetailsViewHeader = ({
|
|
|
56
54
|
|
|
57
55
|
{copyButton && (
|
|
58
56
|
<IconButton
|
|
59
|
-
aria-label={
|
|
60
|
-
copyButton.isEnabled ? "Copy span details" : "Copy disabled"
|
|
61
|
-
}
|
|
57
|
+
aria-label={copyButton.isEnabled ? 'Copy span details' : 'Copy disabled'}
|
|
62
58
|
variant="ghost"
|
|
63
59
|
onClick={handleCopy}
|
|
64
60
|
>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ReactNode } from
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
export interface DetailsViewHeaderActionsProps {
|
|
4
4
|
/**
|
|
@@ -13,7 +13,7 @@ export interface DetailsViewHeaderActionsProps {
|
|
|
13
13
|
|
|
14
14
|
export const DetailsViewHeaderActions = ({
|
|
15
15
|
children,
|
|
16
|
-
className =
|
|
16
|
+
className = 'flex flex-wrap items-center gap-2',
|
|
17
17
|
}: DetailsViewHeaderActionsProps) => {
|
|
18
18
|
if (!children) return null;
|
|
19
19
|
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import type { TraceSpan } from
|
|
1
|
+
import type { TraceSpan } from '@evilmartians/agent-prism-types';
|
|
2
2
|
|
|
3
|
-
import { Check, Copy } from
|
|
4
|
-
import { useState, type ReactElement } from
|
|
5
|
-
import JSONPretty from
|
|
6
|
-
import colors from
|
|
3
|
+
import { Check, Copy } from 'lucide-react';
|
|
4
|
+
import { useState, type ReactElement } from 'react';
|
|
5
|
+
import JSONPretty from 'react-json-pretty';
|
|
6
|
+
import colors from 'tailwindcss/colors';
|
|
7
7
|
|
|
8
|
-
import { CollapsibleSection } from
|
|
9
|
-
import { IconButton } from
|
|
10
|
-
import { Tabs, type TabItem } from
|
|
8
|
+
import { CollapsibleSection } from '../CollapsibleSection';
|
|
9
|
+
import { IconButton } from '../IconButton';
|
|
10
|
+
import { Tabs, type TabItem } from '../Tabs';
|
|
11
11
|
|
|
12
12
|
interface DetailsViewInputOutputTabProps {
|
|
13
13
|
data: TraceSpan;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
type IOTab =
|
|
16
|
+
type IOTab = 'json' | 'plain';
|
|
17
17
|
|
|
18
|
-
type IOSection =
|
|
18
|
+
type IOSection = 'Input' | 'Output';
|
|
19
19
|
|
|
20
20
|
export const DetailsViewInputOutputTab = ({
|
|
21
21
|
data,
|
|
@@ -26,9 +26,7 @@ export const DetailsViewInputOutputTab = ({
|
|
|
26
26
|
if (!hasInput && !hasOutput) {
|
|
27
27
|
return (
|
|
28
28
|
<div className="p-6 text-center">
|
|
29
|
-
<p className="text-muted-foreground ">
|
|
30
|
-
No input or output data available for this span.
|
|
31
|
-
</p>
|
|
29
|
+
<p className="text-muted-foreground ">No input or output data available for this span.</p>
|
|
32
30
|
</div>
|
|
33
31
|
);
|
|
34
32
|
}
|
|
@@ -36,7 +34,7 @@ export const DetailsViewInputOutputTab = ({
|
|
|
36
34
|
let parsedInput: string | null = null;
|
|
37
35
|
let parsedOutput: string | null = null;
|
|
38
36
|
|
|
39
|
-
if (typeof data.input ===
|
|
37
|
+
if (typeof data.input === 'string') {
|
|
40
38
|
try {
|
|
41
39
|
parsedInput = JSON.parse(data.input);
|
|
42
40
|
} catch {
|
|
@@ -44,7 +42,7 @@ export const DetailsViewInputOutputTab = ({
|
|
|
44
42
|
}
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
if (typeof data.output ===
|
|
45
|
+
if (typeof data.output === 'string') {
|
|
48
46
|
try {
|
|
49
47
|
parsedOutput = JSON.parse(data.output);
|
|
50
48
|
} catch {
|
|
@@ -54,20 +52,12 @@ export const DetailsViewInputOutputTab = ({
|
|
|
54
52
|
|
|
55
53
|
return (
|
|
56
54
|
<div className="space-y-3">
|
|
57
|
-
{typeof data.input ===
|
|
58
|
-
<IOSection
|
|
59
|
-
section="Input"
|
|
60
|
-
content={data.input}
|
|
61
|
-
parsedContent={parsedInput}
|
|
62
|
-
/>
|
|
55
|
+
{typeof data.input === 'string' && (
|
|
56
|
+
<IOSection section="Input" content={data.input} parsedContent={parsedInput} />
|
|
63
57
|
)}
|
|
64
58
|
|
|
65
|
-
{typeof data.output ===
|
|
66
|
-
<IOSection
|
|
67
|
-
section="Output"
|
|
68
|
-
content={data.output}
|
|
69
|
-
parsedContent={parsedOutput}
|
|
70
|
-
/>
|
|
59
|
+
{typeof data.output === 'string' && (
|
|
60
|
+
<IOSection section="Output" content={data.output} parsedContent={parsedOutput} />
|
|
71
61
|
)}
|
|
72
62
|
</div>
|
|
73
63
|
);
|
|
@@ -79,23 +69,19 @@ interface IOSectionProps {
|
|
|
79
69
|
parsedContent: string | null;
|
|
80
70
|
}
|
|
81
71
|
|
|
82
|
-
const IOSection = ({
|
|
83
|
-
|
|
84
|
-
content,
|
|
85
|
-
parsedContent,
|
|
86
|
-
}: IOSectionProps): ReactElement => {
|
|
87
|
-
const [tab, setTab] = useState<IOTab>("plain");
|
|
72
|
+
const IOSection = ({ section, content, parsedContent }: IOSectionProps): ReactElement => {
|
|
73
|
+
const [tab, setTab] = useState<IOTab>('plain');
|
|
88
74
|
const [open, setOpen] = useState(true);
|
|
89
75
|
|
|
90
76
|
const tabItems: TabItem<IOTab>[] = [
|
|
91
77
|
{
|
|
92
|
-
value:
|
|
93
|
-
label:
|
|
78
|
+
value: 'json',
|
|
79
|
+
label: 'JSON',
|
|
94
80
|
disabled: !parsedContent,
|
|
95
81
|
},
|
|
96
82
|
{
|
|
97
|
-
value:
|
|
98
|
-
label:
|
|
83
|
+
value: 'plain',
|
|
84
|
+
label: 'Plain',
|
|
99
85
|
},
|
|
100
86
|
];
|
|
101
87
|
|
|
@@ -118,40 +104,26 @@ const IOSection = ({
|
|
|
118
104
|
}
|
|
119
105
|
triggerClassName="min-h-16"
|
|
120
106
|
>
|
|
121
|
-
<IOContent
|
|
122
|
-
content={content}
|
|
123
|
-
section={section}
|
|
124
|
-
tab={tab}
|
|
125
|
-
parsedContent={parsedContent}
|
|
126
|
-
/>
|
|
107
|
+
<IOContent content={content} section={section} tab={tab} parsedContent={parsedContent} />
|
|
127
108
|
</CollapsibleSection>
|
|
128
109
|
);
|
|
129
110
|
};
|
|
130
111
|
|
|
131
|
-
interface IOContentProps extends Omit<IOSectionProps,
|
|
112
|
+
interface IOContentProps extends Omit<IOSectionProps, 'title'> {
|
|
132
113
|
tab: IOTab;
|
|
133
114
|
parsedContent: string | null;
|
|
134
115
|
}
|
|
135
116
|
|
|
136
|
-
const IOContent = ({
|
|
137
|
-
tab,
|
|
138
|
-
content,
|
|
139
|
-
section,
|
|
140
|
-
parsedContent,
|
|
141
|
-
}: IOContentProps): ReactElement => {
|
|
117
|
+
const IOContent = ({ tab, content, section, parsedContent }: IOContentProps): ReactElement => {
|
|
142
118
|
if (!content) {
|
|
143
|
-
return
|
|
144
|
-
<p className="p-3 text-sm italic text-muted-foreground ">
|
|
145
|
-
No data available
|
|
146
|
-
</p>
|
|
147
|
-
);
|
|
119
|
+
return <p className="p-3 text-sm italic text-muted-foreground ">No data available</p>;
|
|
148
120
|
}
|
|
149
121
|
|
|
150
122
|
return (
|
|
151
123
|
<div className="relative rounded-lg border border-border ">
|
|
152
124
|
<CopyButton section={section} content={content} />
|
|
153
125
|
|
|
154
|
-
{tab ===
|
|
126
|
+
{tab === 'json' && (
|
|
155
127
|
<>
|
|
156
128
|
{parsedContent ? (
|
|
157
129
|
<JSONPretty
|
|
@@ -165,14 +137,12 @@ const IOContent = ({
|
|
|
165
137
|
valueStyle="color: hsl(var(--chart-1));"
|
|
166
138
|
/>
|
|
167
139
|
) : (
|
|
168
|
-
<div className="p-4 text-sm text-muted-foreground">
|
|
169
|
-
Invalid JSON format
|
|
170
|
-
</div>
|
|
140
|
+
<div className="p-4 text-sm text-muted-foreground">Invalid JSON format</div>
|
|
171
141
|
)}
|
|
172
142
|
</>
|
|
173
143
|
)}
|
|
174
144
|
|
|
175
|
-
{tab ===
|
|
145
|
+
{tab === 'plain' && (
|
|
176
146
|
<div className="rounded-lg bg-muted/50 p-4">
|
|
177
147
|
<pre className="overflow-x-auto whitespace-pre-wrap text-left font-mono text-xs text-foreground">
|
|
178
148
|
{content}
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import type { TraceSpan } from
|
|
1
|
+
import type { TraceSpan } from '@evilmartians/agent-prism-types';
|
|
2
2
|
|
|
3
|
-
import { getDurationMs, formatDuration } from
|
|
4
|
-
import { Coins } from
|
|
3
|
+
import { getDurationMs, formatDuration } from '@evilmartians/agent-prism-data';
|
|
4
|
+
import { Coins } from 'lucide-react';
|
|
5
5
|
|
|
6
|
-
import { Badge } from
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
getSpanCategoryLabel,
|
|
10
|
-
getSpanCategoryTheme,
|
|
11
|
-
} from "../shared.ts";
|
|
12
|
-
import { TimestampBadge } from "../TimestampBadge.tsx";
|
|
6
|
+
import { Badge } from '../Badge';
|
|
7
|
+
import { getSpanCategoryIcon, getSpanCategoryLabel, getSpanCategoryTheme } from '../shared.ts';
|
|
8
|
+
import { TimestampBadge } from '../TimestampBadge.tsx';
|
|
13
9
|
|
|
14
10
|
interface DetailsViewMetricsProps {
|
|
15
11
|
data: TraceSpan;
|
|
@@ -28,7 +24,7 @@ export const DetailsViewMetrics = ({ data }: DetailsViewMetricsProps) => {
|
|
|
28
24
|
label={getSpanCategoryLabel(data.type)}
|
|
29
25
|
/>
|
|
30
26
|
|
|
31
|
-
{typeof data.tokensCount ===
|
|
27
|
+
{typeof data.tokensCount === 'number' && (
|
|
32
28
|
<Badge
|
|
33
29
|
iconStart={<Coins className="size-2.5" />}
|
|
34
30
|
theme="gray"
|
|
@@ -37,17 +33,13 @@ export const DetailsViewMetrics = ({ data }: DetailsViewMetricsProps) => {
|
|
|
37
33
|
/>
|
|
38
34
|
)}
|
|
39
35
|
|
|
40
|
-
{typeof data.cost ===
|
|
36
|
+
{typeof data.cost === 'number' && (
|
|
41
37
|
<Badge theme="gray" size="4" label={`$ ${data.cost.toFixed(4)}`} />
|
|
42
38
|
)}
|
|
43
39
|
|
|
44
|
-
<span className="text-xs text-muted-foreground">
|
|
45
|
-
LATENCY: {formatDuration(durationMs)}
|
|
46
|
-
</span>
|
|
40
|
+
<span className="text-xs text-muted-foreground">LATENCY: {formatDuration(durationMs)}</span>
|
|
47
41
|
|
|
48
|
-
{typeof data.startTime ===
|
|
49
|
-
<TimestampBadge timestamp={data.startTime} />
|
|
50
|
-
)}
|
|
42
|
+
{typeof data.startTime === 'number' && <TimestampBadge timestamp={data.startTime} />}
|
|
51
43
|
</div>
|
|
52
44
|
);
|
|
53
45
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { TraceSpan } from
|
|
1
|
+
import type { TraceSpan } from '@evilmartians/agent-prism-types';
|
|
2
2
|
|
|
3
|
-
import JSONPretty from
|
|
3
|
+
import JSONPretty from 'react-json-pretty';
|
|
4
4
|
|
|
5
5
|
interface RawDataTabProps {
|
|
6
6
|
data: TraceSpan;
|
|
@@ -13,7 +13,7 @@ export const DetailsViewRawDataTab = ({ data }: RawDataTabProps) => (
|
|
|
13
13
|
booleanStyle="color: hsl(var(--primary));"
|
|
14
14
|
className="overflow-x-auto rounded-xl p-4 text-left"
|
|
15
15
|
data={data.raw}
|
|
16
|
-
id={`json-pretty-${data.id ||
|
|
16
|
+
id={`json-pretty-${data.id || 'span-details'}`}
|
|
17
17
|
keyStyle="color: hsl(var(--primary));"
|
|
18
18
|
mainStyle="color: hsl(var(--muted-foreground)); font-size: 12px;"
|
|
19
19
|
stringStyle="color: hsl(var(--chart-2));"
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
import type { ComponentPropsWithRef } from
|
|
1
|
+
import type { ComponentPropsWithRef } from 'react';
|
|
2
2
|
|
|
3
|
-
import { cn } from
|
|
3
|
+
import { cn } from '@/lib/utils';
|
|
4
4
|
|
|
5
|
-
import type { ComponentSize } from
|
|
5
|
+
import type { ComponentSize } from './shared';
|
|
6
6
|
|
|
7
|
-
type IconButtonSize = Extract<
|
|
8
|
-
|
|
9
|
-
"6" | "7" | "8" | "9" | "10" | "11" | "12" | "16"
|
|
10
|
-
>;
|
|
11
|
-
type IconButtonVariant = "default" | "ghost";
|
|
7
|
+
type IconButtonSize = Extract<ComponentSize, '6' | '7' | '8' | '9' | '10' | '11' | '12' | '16'>;
|
|
8
|
+
type IconButtonVariant = 'default' | 'ghost';
|
|
12
9
|
|
|
13
|
-
export type IconButtonProps = ComponentPropsWithRef<
|
|
10
|
+
export type IconButtonProps = ComponentPropsWithRef<'button'> & {
|
|
14
11
|
/**
|
|
15
12
|
* The size of the icon button
|
|
16
13
|
*/
|
|
@@ -25,33 +22,33 @@ export type IconButtonProps = ComponentPropsWithRef<"button"> & {
|
|
|
25
22
|
* Accessible label for screen readers
|
|
26
23
|
* Required for accessibility compliance
|
|
27
24
|
*/
|
|
28
|
-
|
|
25
|
+
'aria-label': string;
|
|
29
26
|
};
|
|
30
27
|
|
|
31
28
|
const sizeClasses: Record<IconButtonSize, string> = {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
'6': 'h-6 min-h-6',
|
|
30
|
+
'7': 'h-7 min-h-7',
|
|
31
|
+
'8': 'h-8 min-h-8',
|
|
32
|
+
'9': 'h-9 min-h-9',
|
|
33
|
+
'10': 'h-10 min-h-10',
|
|
34
|
+
'11': 'h-11 min-h-11',
|
|
35
|
+
'12': 'h-12 min-h-12',
|
|
36
|
+
'16': 'h-16 min-h-16',
|
|
40
37
|
};
|
|
41
38
|
|
|
42
39
|
const variantClasses: Record<IconButtonVariant, string> = {
|
|
43
|
-
default:
|
|
44
|
-
ghost:
|
|
40
|
+
default: 'border border-border bg-transparent ',
|
|
41
|
+
ghost: 'bg-transparent',
|
|
45
42
|
};
|
|
46
43
|
|
|
47
44
|
// TODO: Remake to call Icon component directly instead of passing children
|
|
48
45
|
export const IconButton = ({
|
|
49
46
|
children,
|
|
50
47
|
className,
|
|
51
|
-
size =
|
|
52
|
-
variant =
|
|
53
|
-
type =
|
|
54
|
-
|
|
48
|
+
size = '6',
|
|
49
|
+
variant = 'default',
|
|
50
|
+
type = 'button',
|
|
51
|
+
'aria-label': ariaLabel,
|
|
55
52
|
...rest
|
|
56
53
|
}: IconButtonProps) => {
|
|
57
54
|
return (
|
|
@@ -61,11 +58,11 @@ export const IconButton = ({
|
|
|
61
58
|
className={cn(
|
|
62
59
|
className,
|
|
63
60
|
sizeClasses[size],
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
'inline-flex aspect-square shrink-0 items-center justify-center',
|
|
62
|
+
'rounded-md',
|
|
66
63
|
variantClasses[variant],
|
|
67
|
-
|
|
68
|
-
|
|
64
|
+
'text-muted-foreground ',
|
|
65
|
+
'hover:bg-gray-200 dark:hover:bg-gray-800'
|
|
69
66
|
)}
|
|
70
67
|
{...rest}
|
|
71
68
|
>
|
|
@@ -1,10 +1,10 @@
|
|
|
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 PriceBadgeProps = ComponentPropsWithRef<
|
|
5
|
+
export type PriceBadgeProps = ComponentPropsWithRef<'span'> & {
|
|
6
6
|
cost: number;
|
|
7
|
-
size?: BadgeProps[
|
|
7
|
+
size?: BadgeProps['size'];
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
export const PriceBadge = ({ cost, size, ...rest }: PriceBadgeProps) => {
|