@elizaos/client 1.6.1-alpha.6 → 1.6.1-beta.0
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-CQAV8tyh.js → main-CLvs0bX8.js} +3 -3
- package/dist/assets/{main-CQAV8tyh.js.map → main-CLvs0bX8.js.map} +1 -1
- package/dist/assets/{main-BM2lpId8.js → main-llvbgk6E.js} +52 -52
- package/dist/assets/{main-BM2lpId8.js.map → main-llvbgk6E.js.map} +1 -1
- package/dist/index.html +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,35 +1,24 @@
|
|
|
1
|
-
import type { TraceSpan } from
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} from
|
|
15
|
-
|
|
16
|
-
import { Avatar, type AvatarProps } from "../Avatar.tsx";
|
|
17
|
-
import { getSpanCategoryTheme } from "../shared.ts";
|
|
18
|
-
import { SpanStatus } from "../SpanStatus.tsx";
|
|
19
|
-
import { SpanCardBadges } from "./SpanCardBadges.tsx";
|
|
20
|
-
import {
|
|
21
|
-
type SpanCardConnectorType,
|
|
22
|
-
SpanCardConnector,
|
|
23
|
-
} from "./SpanCardConnector.tsx";
|
|
24
|
-
import { SpanCardTimeline } from "./SpanCardTimeline.tsx";
|
|
25
|
-
import { SpanCardToggle } from "./SpanCardToggle.tsx";
|
|
1
|
+
import type { TraceSpan } from '@evilmartians/agent-prism-types';
|
|
2
|
+
|
|
3
|
+
import { formatDuration, getTimelineData } from '@evilmartians/agent-prism-data';
|
|
4
|
+
import * as Collapsible from '@radix-ui/react-collapsible';
|
|
5
|
+
import { cn } from '@/lib/utils';
|
|
6
|
+
import { type FC, useCallback, type KeyboardEvent, type MouseEvent } from 'react';
|
|
7
|
+
|
|
8
|
+
import { Avatar, type AvatarProps } from '../Avatar.tsx';
|
|
9
|
+
import { getSpanCategoryTheme } from '../shared.ts';
|
|
10
|
+
import { SpanStatus } from '../SpanStatus.tsx';
|
|
11
|
+
import { SpanCardBadges } from './SpanCardBadges.tsx';
|
|
12
|
+
import { type SpanCardConnectorType, SpanCardConnector } from './SpanCardConnector.tsx';
|
|
13
|
+
import { SpanCardTimeline } from './SpanCardTimeline.tsx';
|
|
14
|
+
import { SpanCardToggle } from './SpanCardToggle.tsx';
|
|
26
15
|
|
|
27
16
|
const LAYOUT_CONSTANTS = {
|
|
28
17
|
CONNECTOR_WIDTH: 20,
|
|
29
18
|
CONTENT_BASE_WIDTH: 320,
|
|
30
19
|
} as const;
|
|
31
20
|
|
|
32
|
-
type ExpandButtonPlacement =
|
|
21
|
+
type ExpandButtonPlacement = 'inside' | 'outside';
|
|
33
22
|
|
|
34
23
|
export type SpanCardViewOptions = {
|
|
35
24
|
withStatus?: boolean;
|
|
@@ -38,7 +27,7 @@ export type SpanCardViewOptions = {
|
|
|
38
27
|
|
|
39
28
|
const DEFAULT_VIEW_OPTIONS: Required<SpanCardViewOptions> = {
|
|
40
29
|
withStatus: true,
|
|
41
|
-
expandButton:
|
|
30
|
+
expandButton: 'inside',
|
|
42
31
|
};
|
|
43
32
|
|
|
44
33
|
interface SpanCardProps {
|
|
@@ -73,15 +62,13 @@ const getContentWidth = ({
|
|
|
73
62
|
contentPadding: number;
|
|
74
63
|
expandButton: ExpandButtonPlacement;
|
|
75
64
|
}) => {
|
|
76
|
-
let width =
|
|
77
|
-
LAYOUT_CONSTANTS.CONTENT_BASE_WIDTH -
|
|
78
|
-
level * LAYOUT_CONSTANTS.CONNECTOR_WIDTH;
|
|
65
|
+
let width = LAYOUT_CONSTANTS.CONTENT_BASE_WIDTH - level * LAYOUT_CONSTANTS.CONNECTOR_WIDTH;
|
|
79
66
|
|
|
80
|
-
if (hasExpandButton && expandButton ===
|
|
67
|
+
if (hasExpandButton && expandButton === 'inside') {
|
|
81
68
|
width -= LAYOUT_CONSTANTS.CONNECTOR_WIDTH;
|
|
82
69
|
}
|
|
83
70
|
|
|
84
|
-
if (expandButton ===
|
|
71
|
+
if (expandButton === 'outside' && level === 0) {
|
|
85
72
|
width -= LAYOUT_CONSTANTS.CONNECTOR_WIDTH;
|
|
86
73
|
}
|
|
87
74
|
|
|
@@ -95,7 +82,7 @@ const getGridTemplateColumns = ({
|
|
|
95
82
|
connectorsColumnWidth: number;
|
|
96
83
|
expandButton: ExpandButtonPlacement;
|
|
97
84
|
}) => {
|
|
98
|
-
if (expandButton ===
|
|
85
|
+
if (expandButton === 'inside') {
|
|
99
86
|
return `${connectorsColumnWidth}px 1fr`;
|
|
100
87
|
}
|
|
101
88
|
|
|
@@ -136,36 +123,32 @@ const getConnectorsLayout = ({
|
|
|
136
123
|
|
|
137
124
|
if (level === 0) {
|
|
138
125
|
return {
|
|
139
|
-
connectors: expandButton ===
|
|
126
|
+
connectors: expandButton === 'inside' ? [] : ['vertical'],
|
|
140
127
|
connectorsColumnWidth: 20,
|
|
141
128
|
};
|
|
142
129
|
}
|
|
143
130
|
|
|
144
131
|
for (let i = 0; i < level - 1; i++) {
|
|
145
|
-
connectors.push(
|
|
132
|
+
connectors.push('vertical');
|
|
146
133
|
}
|
|
147
134
|
|
|
148
135
|
if (!isLastChild) {
|
|
149
|
-
connectors.push(
|
|
136
|
+
connectors.push('t-right');
|
|
150
137
|
}
|
|
151
138
|
|
|
152
139
|
if (isLastChild) {
|
|
153
|
-
connectors.push(
|
|
140
|
+
connectors.push('corner-top-right');
|
|
154
141
|
}
|
|
155
142
|
|
|
156
|
-
let connectorsColumnWidth =
|
|
157
|
-
connectors.length * LAYOUT_CONSTANTS.CONNECTOR_WIDTH;
|
|
143
|
+
let connectorsColumnWidth = connectors.length * LAYOUT_CONSTANTS.CONNECTOR_WIDTH;
|
|
158
144
|
|
|
159
145
|
if (hasExpandButton) {
|
|
160
146
|
connectorsColumnWidth += LAYOUT_CONSTANTS.CONNECTOR_WIDTH;
|
|
161
147
|
}
|
|
162
148
|
|
|
163
149
|
for (let i = 0; i < prevConnectors.length; i++) {
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
prevConnectors[i] === "corner-top-right"
|
|
167
|
-
) {
|
|
168
|
-
connectors[i] = "empty";
|
|
150
|
+
if (prevConnectors[i] === 'empty' || prevConnectors[i] === 'corner-top-right') {
|
|
151
|
+
connectors[i] = 'empty';
|
|
169
152
|
}
|
|
170
153
|
}
|
|
171
154
|
|
|
@@ -175,30 +158,24 @@ const getConnectorsLayout = ({
|
|
|
175
158
|
};
|
|
176
159
|
};
|
|
177
160
|
|
|
178
|
-
const useSpanCardEventHandlers = (
|
|
179
|
-
data: TraceSpan,
|
|
180
|
-
onSpanSelect?: (span: TraceSpan) => void,
|
|
181
|
-
) => {
|
|
161
|
+
const useSpanCardEventHandlers = (data: TraceSpan, onSpanSelect?: (span: TraceSpan) => void) => {
|
|
182
162
|
const handleCardClick = useCallback((): void => {
|
|
183
163
|
onSpanSelect?.(data);
|
|
184
164
|
}, [data, onSpanSelect]);
|
|
185
165
|
|
|
186
166
|
const handleKeyDown = useCallback(
|
|
187
167
|
(e: KeyboardEvent): void => {
|
|
188
|
-
if (e.key ===
|
|
168
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
189
169
|
e.preventDefault();
|
|
190
170
|
handleCardClick();
|
|
191
171
|
}
|
|
192
172
|
},
|
|
193
|
-
[handleCardClick]
|
|
173
|
+
[handleCardClick]
|
|
194
174
|
);
|
|
195
175
|
|
|
196
|
-
const handleToggleClick = useCallback(
|
|
197
|
-
(
|
|
198
|
-
|
|
199
|
-
},
|
|
200
|
-
[],
|
|
201
|
-
);
|
|
176
|
+
const handleToggleClick = useCallback((e: MouseEvent | KeyboardEvent): void => {
|
|
177
|
+
e.stopPropagation();
|
|
178
|
+
}, []);
|
|
202
179
|
|
|
203
180
|
return {
|
|
204
181
|
handleCardClick,
|
|
@@ -230,33 +207,33 @@ const SpanCardChildren: FC<{
|
|
|
230
207
|
onExpandSpansIdsChange,
|
|
231
208
|
viewOptions = DEFAULT_VIEW_OPTIONS,
|
|
232
209
|
}) => {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
210
|
+
if (!data.children?.length) return null;
|
|
211
|
+
|
|
212
|
+
return (
|
|
213
|
+
<div className="relative">
|
|
214
|
+
<Collapsible.Content>
|
|
215
|
+
<ul role="group">
|
|
216
|
+
{data.children.map((child, idx) => (
|
|
217
|
+
<SpanCard
|
|
218
|
+
viewOptions={viewOptions}
|
|
219
|
+
key={child.id}
|
|
220
|
+
data={child}
|
|
221
|
+
minStart={minStart}
|
|
222
|
+
maxEnd={maxEnd}
|
|
223
|
+
level={level + 1}
|
|
224
|
+
selectedSpan={selectedSpan}
|
|
225
|
+
onSpanSelect={onSpanSelect}
|
|
226
|
+
isLastChild={idx === (data.children || []).length - 1}
|
|
227
|
+
prevLevelConnectors={prevLevelConnectors}
|
|
228
|
+
expandedSpansIds={expandedSpansIds}
|
|
229
|
+
onExpandSpansIdsChange={onExpandSpansIdsChange}
|
|
230
|
+
/>
|
|
231
|
+
))}
|
|
232
|
+
</ul>
|
|
233
|
+
</Collapsible.Content>
|
|
234
|
+
</div>
|
|
235
|
+
);
|
|
236
|
+
};
|
|
260
237
|
|
|
261
238
|
export const SpanCard: FC<SpanCardProps> = ({
|
|
262
239
|
data,
|
|
@@ -275,8 +252,7 @@ export const SpanCard: FC<SpanCardProps> = ({
|
|
|
275
252
|
const isExpanded = expandedSpansIds.includes(data.id);
|
|
276
253
|
|
|
277
254
|
const withStatus = viewOptions.withStatus ?? DEFAULT_VIEW_OPTIONS.withStatus;
|
|
278
|
-
const expandButton =
|
|
279
|
-
viewOptions.expandButton || DEFAULT_VIEW_OPTIONS.expandButton;
|
|
255
|
+
const expandButton = viewOptions.expandButton || DEFAULT_VIEW_OPTIONS.expandButton;
|
|
280
256
|
|
|
281
257
|
const handleToggleClick = useCallback(
|
|
282
258
|
(expanded: boolean) => {
|
|
@@ -290,7 +266,7 @@ export const SpanCard: FC<SpanCardProps> = ({
|
|
|
290
266
|
onExpandSpansIdsChange([...expandedSpansIds, data.id]);
|
|
291
267
|
}
|
|
292
268
|
},
|
|
293
|
-
[isExpanded, expandedSpansIds, data.id, onExpandSpansIdsChange]
|
|
269
|
+
[isExpanded, expandedSpansIds, data.id, onExpandSpansIdsChange]
|
|
294
270
|
);
|
|
295
271
|
|
|
296
272
|
const state: SpanCardState = {
|
|
@@ -307,8 +283,7 @@ export const SpanCard: FC<SpanCardProps> = ({
|
|
|
307
283
|
maxEnd,
|
|
308
284
|
});
|
|
309
285
|
|
|
310
|
-
const hasExpandButtonAsFirstChild =
|
|
311
|
-
expandButton === "inside" && state.hasChildren;
|
|
286
|
+
const hasExpandButtonAsFirstChild = expandButton === 'inside' && state.hasChildren;
|
|
312
287
|
|
|
313
288
|
const contentPadding = getContentPadding({
|
|
314
289
|
level,
|
|
@@ -341,16 +316,11 @@ export const SpanCard: FC<SpanCardProps> = ({
|
|
|
341
316
|
aria-expanded={state.hasChildren ? state.isExpanded : undefined}
|
|
342
317
|
className="list-none"
|
|
343
318
|
>
|
|
344
|
-
<Collapsible.Root
|
|
345
|
-
open={state.isExpanded}
|
|
346
|
-
onOpenChange={handleToggleClick}
|
|
347
|
-
>
|
|
319
|
+
<Collapsible.Root open={state.isExpanded} onOpenChange={handleToggleClick}>
|
|
348
320
|
<div
|
|
349
321
|
className={cn(
|
|
350
|
-
|
|
351
|
-
state.isSelected
|
|
352
|
-
? "bg-accent/50 border border-accent"
|
|
353
|
-
: "hover:bg-muted/30",
|
|
322
|
+
'relative grid w-full rounded-md transition-colors',
|
|
323
|
+
state.isSelected ? 'bg-accent/50 border border-accent' : 'hover:bg-muted/30'
|
|
354
324
|
)}
|
|
355
325
|
style={{
|
|
356
326
|
gridTemplateColumns,
|
|
@@ -362,7 +332,7 @@ export const SpanCard: FC<SpanCardProps> = ({
|
|
|
362
332
|
aria-pressed={state.isSelected}
|
|
363
333
|
aria-describedby={`span-card-desc-${data.id}`}
|
|
364
334
|
aria-expanded={state.hasChildren ? state.isExpanded : undefined}
|
|
365
|
-
aria-label={`${state.isSelected ?
|
|
335
|
+
aria-label={`${state.isSelected ? 'Selected' : 'Not selected'} span card for ${data.title} at level ${level}`}
|
|
366
336
|
>
|
|
367
337
|
<div className="flex flex-nowrap">
|
|
368
338
|
{connectors.map((connector, idx) => (
|
|
@@ -383,10 +353,10 @@ export const SpanCard: FC<SpanCardProps> = ({
|
|
|
383
353
|
</div>
|
|
384
354
|
<div
|
|
385
355
|
className={cn(
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
level !== 0 && !hasExpandButtonAsFirstChild &&
|
|
389
|
-
level !== 0 && hasExpandButtonAsFirstChild &&
|
|
356
|
+
'flex flex-nowrap items-center align-middle gap-x-3 gap py-3 px-2',
|
|
357
|
+
'min-h-5 w-full cursor-pointer',
|
|
358
|
+
level !== 0 && !hasExpandButtonAsFirstChild && 'pl-2',
|
|
359
|
+
level !== 0 && hasExpandButtonAsFirstChild && 'pl-1'
|
|
390
360
|
)}
|
|
391
361
|
>
|
|
392
362
|
<div
|
|
@@ -409,7 +379,7 @@ export const SpanCard: FC<SpanCardProps> = ({
|
|
|
409
379
|
</div>
|
|
410
380
|
|
|
411
381
|
<div className="flex flex-shrink flex-grow flex-nowrap items-center justify-end gap-1 min-w-0">
|
|
412
|
-
{expandButton ===
|
|
382
|
+
{expandButton === 'outside' && withStatus && (
|
|
413
383
|
<div className="flex-shrink-0">
|
|
414
384
|
<SpanStatus status={data.status} />
|
|
415
385
|
</div>
|
|
@@ -428,7 +398,7 @@ export const SpanCard: FC<SpanCardProps> = ({
|
|
|
428
398
|
{formatDuration(durationMs)}
|
|
429
399
|
</span>
|
|
430
400
|
|
|
431
|
-
{expandButton ===
|
|
401
|
+
{expandButton === 'inside' && withStatus && (
|
|
432
402
|
<div>
|
|
433
403
|
<SpanStatus status={data.status} />
|
|
434
404
|
</div>
|
|
@@ -437,7 +407,7 @@ export const SpanCard: FC<SpanCardProps> = ({
|
|
|
437
407
|
</div>
|
|
438
408
|
</div>
|
|
439
409
|
|
|
440
|
-
{expandButton ===
|
|
410
|
+
{expandButton === 'outside' &&
|
|
441
411
|
(state.hasChildren ? (
|
|
442
412
|
<SpanCardToggle
|
|
443
413
|
isExpanded={state.isExpanded}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import type { TraceSpan } from
|
|
1
|
+
import type { TraceSpan } from '@evilmartians/agent-prism-types';
|
|
2
2
|
|
|
3
|
-
import { Badge } from
|
|
4
|
-
import { PriceBadge } from
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
getSpanCategoryLabel,
|
|
8
|
-
getSpanCategoryTheme,
|
|
9
|
-
} from "../shared.ts";
|
|
10
|
-
import { TokensBadge } from "../TokensBadge.tsx";
|
|
3
|
+
import { Badge } from '../Badge.tsx';
|
|
4
|
+
import { PriceBadge } from '../PriceBadge.tsx';
|
|
5
|
+
import { getSpanCategoryIcon, getSpanCategoryLabel, getSpanCategoryTheme } from '../shared.ts';
|
|
6
|
+
import { TokensBadge } from '../TokensBadge.tsx';
|
|
11
7
|
|
|
12
8
|
interface SpanCardBagdesProps {
|
|
13
9
|
data: TraceSpan;
|
|
@@ -25,11 +21,9 @@ export const SpanCardBadges = ({ data }: SpanCardBagdesProps) => {
|
|
|
25
21
|
label={getSpanCategoryLabel(data.type)}
|
|
26
22
|
/>
|
|
27
23
|
|
|
28
|
-
{typeof data.tokensCount ===
|
|
29
|
-
<TokensBadge tokensCount={data.tokensCount} />
|
|
30
|
-
)}
|
|
24
|
+
{typeof data.tokensCount === 'number' && <TokensBadge tokensCount={data.tokensCount} />}
|
|
31
25
|
|
|
32
|
-
{typeof data.cost ===
|
|
26
|
+
{typeof data.cost === 'number' && <PriceBadge cost={data.cost} />}
|
|
33
27
|
</div>
|
|
34
28
|
);
|
|
35
29
|
};
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
export type SpanCardConnectorType =
|
|
2
|
-
|
|
|
3
|
-
|
|
|
4
|
-
|
|
|
5
|
-
|
|
|
6
|
-
|
|
|
2
|
+
| 'horizontal'
|
|
3
|
+
| 'vertical'
|
|
4
|
+
| 't-right'
|
|
5
|
+
| 'corner-top-right'
|
|
6
|
+
| 'empty';
|
|
7
7
|
|
|
8
8
|
interface SpanCardConnectorProps {
|
|
9
9
|
type: SpanCardConnectorType;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export const SpanCardConnector = ({ type }: SpanCardConnectorProps) => {
|
|
13
|
-
if (type ===
|
|
13
|
+
if (type === 'empty') return <div className="w-5 shrink-0 grow" />;
|
|
14
14
|
|
|
15
15
|
return (
|
|
16
16
|
<div className="relative w-5 shrink-0 grow">
|
|
17
|
-
{(type ===
|
|
17
|
+
{(type === 'vertical' || type === 't-right') && (
|
|
18
18
|
<div className="absolute bottom-0 left-1/2 top-0 w-0.5 -translate-x-1/2 bg-muted" />
|
|
19
19
|
)}
|
|
20
20
|
|
|
21
|
-
{type ===
|
|
21
|
+
{type === 't-right' && (
|
|
22
22
|
<div className="absolute left-2.5 top-2.5 h-0.5 w-2.5 -translate-y-[3px] bg-muted" />
|
|
23
23
|
)}
|
|
24
24
|
|
|
25
|
-
{type ===
|
|
25
|
+
{type === 'corner-top-right' && (
|
|
26
26
|
<>
|
|
27
27
|
<div className="absolute left-1/2 top-2 size-0.5 -translate-x-1/2 -translate-y-px bg-muted" />
|
|
28
28
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { TraceSpan } from
|
|
1
|
+
import type { TraceSpan } from '@evilmartians/agent-prism-types';
|
|
2
2
|
|
|
3
|
-
import { getTimelineData } from
|
|
4
|
-
import { cn } from
|
|
3
|
+
import { getTimelineData } from '@evilmartians/agent-prism-data';
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
5
|
|
|
6
|
-
import type { ColorVariant } from
|
|
6
|
+
import type { ColorVariant } from '../shared.ts';
|
|
7
7
|
|
|
8
8
|
interface SpanCardTimelineProps {
|
|
9
9
|
spanCard: TraceSpan;
|
|
@@ -14,16 +14,16 @@ interface SpanCardTimelineProps {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
const timelineBgColors: Record<ColorVariant, string> = {
|
|
17
|
-
purple:
|
|
18
|
-
indigo:
|
|
19
|
-
orange:
|
|
20
|
-
teal:
|
|
21
|
-
cyan:
|
|
22
|
-
sky:
|
|
23
|
-
yellow:
|
|
24
|
-
emerald:
|
|
25
|
-
red:
|
|
26
|
-
gray:
|
|
17
|
+
purple: 'bg-primary',
|
|
18
|
+
indigo: 'bg-primary',
|
|
19
|
+
orange: 'bg-chart-1',
|
|
20
|
+
teal: 'bg-chart-2',
|
|
21
|
+
cyan: 'bg-chart-3',
|
|
22
|
+
sky: 'bg-chart-4',
|
|
23
|
+
yellow: 'bg-chart-5',
|
|
24
|
+
emerald: 'bg-accent',
|
|
25
|
+
red: 'bg-destructive',
|
|
26
|
+
gray: 'bg-muted-foreground',
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
export const SpanCardTimeline = ({
|
|
@@ -40,12 +40,7 @@ export const SpanCardTimeline = ({
|
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
return (
|
|
43
|
-
<span
|
|
44
|
-
className={cn(
|
|
45
|
-
"relative flex h-4 min-w-20 flex-1 rounded bg-muted",
|
|
46
|
-
className,
|
|
47
|
-
)}
|
|
48
|
-
>
|
|
43
|
+
<span className={cn('relative flex h-4 min-w-20 flex-1 rounded bg-muted', className)}>
|
|
49
44
|
<span className="pointer-events-none absolute inset-x-1 top-1/2 h-1.5 -translate-y-1/2">
|
|
50
45
|
<span
|
|
51
46
|
className={`absolute h-full rounded-sm ${timelineBgColors[theme]}`}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as Collapsible from
|
|
2
|
-
import { ChevronDown, ChevronRight } from
|
|
3
|
-
import { type KeyboardEvent, type MouseEvent } from
|
|
1
|
+
import * as Collapsible from '@radix-ui/react-collapsible';
|
|
2
|
+
import { ChevronDown, ChevronRight } from 'lucide-react';
|
|
3
|
+
import { type KeyboardEvent, type MouseEvent } from 'react';
|
|
4
4
|
|
|
5
5
|
interface SpanCardToggleProps {
|
|
6
6
|
isExpanded: boolean;
|
|
@@ -8,17 +8,13 @@ interface SpanCardToggleProps {
|
|
|
8
8
|
onToggleClick: (e: MouseEvent | KeyboardEvent) => void;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export const SpanCardToggle = ({
|
|
12
|
-
isExpanded,
|
|
13
|
-
title,
|
|
14
|
-
onToggleClick,
|
|
15
|
-
}: SpanCardToggleProps) => (
|
|
11
|
+
export const SpanCardToggle = ({ isExpanded, title, onToggleClick }: SpanCardToggleProps) => (
|
|
16
12
|
<Collapsible.Trigger asChild>
|
|
17
13
|
<button
|
|
18
14
|
className="flex h-4 w-5 shrink-0 items-center justify-center"
|
|
19
15
|
onClick={onToggleClick}
|
|
20
16
|
onKeyDown={onToggleClick}
|
|
21
|
-
aria-label={`${isExpanded ?
|
|
17
|
+
aria-label={`${isExpanded ? 'Collapse' : 'Expand'} ${title} children`}
|
|
22
18
|
aria-expanded={isExpanded}
|
|
23
19
|
type="button"
|
|
24
20
|
>
|
|
@@ -1,42 +1,36 @@
|
|
|
1
|
-
import type { TraceSpanStatus } from
|
|
2
|
-
import type { ComponentPropsWithRef } from
|
|
1
|
+
import type { TraceSpanStatus } from '@evilmartians/agent-prism-types';
|
|
2
|
+
import type { ComponentPropsWithRef } from 'react';
|
|
3
3
|
|
|
4
|
-
import { cn } from
|
|
5
|
-
import { Check, Ellipsis, Info, TriangleAlert } from
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
import { Check, Ellipsis, Info, TriangleAlert } from 'lucide-react';
|
|
6
6
|
|
|
7
|
-
type StatusVariant =
|
|
7
|
+
type StatusVariant = 'dot' | 'badge';
|
|
8
8
|
|
|
9
|
-
export type StatusProps = ComponentPropsWithRef<
|
|
9
|
+
export type StatusProps = ComponentPropsWithRef<'div'> & {
|
|
10
10
|
status: TraceSpanStatus;
|
|
11
11
|
variant?: StatusVariant;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
const STATUS_COLORS_DOT: Record<TraceSpanStatus, string> = {
|
|
15
|
-
success:
|
|
16
|
-
error:
|
|
17
|
-
pending:
|
|
18
|
-
warning:
|
|
15
|
+
success: 'bg-green-500 dark:bg-green-500',
|
|
16
|
+
error: 'bg-red-500 dark:bg-red-500',
|
|
17
|
+
pending: 'bg-violet-500 dark:bg-violet-500',
|
|
18
|
+
warning: 'bg-yellow-500 dark:bg-yellow-500',
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
const STATUS_COLORS_BADGE: Record<TraceSpanStatus, string> = {
|
|
22
|
-
success:
|
|
23
|
-
error:
|
|
24
|
-
pending:
|
|
25
|
-
|
|
26
|
-
warning:
|
|
27
|
-
"bg-yellow-100 dark:bg-yellow-950 text-yellow-600 dark:text-yellow-400",
|
|
22
|
+
success: 'bg-green-100 dark:bg-green-950 text-green-600 dark:text-green-400',
|
|
23
|
+
error: 'bg-red-100 dark:bg-red-950 text-red-600 dark:text-red-400',
|
|
24
|
+
pending: 'bg-violet-100 dark:bg-violet-950 text-violet-600 dark:text-violet-400',
|
|
25
|
+
warning: 'bg-yellow-100 dark:bg-yellow-950 text-yellow-600 dark:text-yellow-400',
|
|
28
26
|
};
|
|
29
27
|
|
|
30
|
-
export const SpanStatus = ({
|
|
31
|
-
status,
|
|
32
|
-
variant = "dot",
|
|
33
|
-
...rest
|
|
34
|
-
}: StatusProps) => {
|
|
28
|
+
export const SpanStatus = ({ status, variant = 'dot', ...rest }: StatusProps) => {
|
|
35
29
|
const title = `Status: ${status}`;
|
|
36
30
|
|
|
37
31
|
return (
|
|
38
32
|
<div className="flex size-4 items-center justify-center" {...rest}>
|
|
39
|
-
{variant ===
|
|
33
|
+
{variant === 'dot' ? (
|
|
40
34
|
<SpanStatusDot status={status} title={title} />
|
|
41
35
|
) : (
|
|
42
36
|
<SpanStatusBadge status={status} title={title} />
|
|
@@ -52,7 +46,7 @@ interface StatusWithTitleProps extends StatusProps {
|
|
|
52
46
|
const SpanStatusDot = ({ status, title }: StatusWithTitleProps) => {
|
|
53
47
|
return (
|
|
54
48
|
<span
|
|
55
|
-
className={cn(
|
|
49
|
+
className={cn('block size-1.5 rounded-full', STATUS_COLORS_DOT[status])}
|
|
56
50
|
aria-label={title}
|
|
57
51
|
title={title}
|
|
58
52
|
/>
|
|
@@ -63,17 +57,17 @@ const SpanStatusBadge = ({ status, title }: StatusWithTitleProps) => {
|
|
|
63
57
|
return (
|
|
64
58
|
<span
|
|
65
59
|
className={cn(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
STATUS_COLORS_BADGE[status]
|
|
60
|
+
'inline-flex items-center justify-center',
|
|
61
|
+
'h-3.5 w-4 rounded',
|
|
62
|
+
STATUS_COLORS_BADGE[status]
|
|
69
63
|
)}
|
|
70
64
|
aria-label={title}
|
|
71
65
|
title={title}
|
|
72
66
|
>
|
|
73
|
-
{status ===
|
|
74
|
-
{status ===
|
|
75
|
-
{status ===
|
|
76
|
-
{status ===
|
|
67
|
+
{status === 'success' && <Check className="size-2.5" aria-hidden />}
|
|
68
|
+
{status === 'error' && <TriangleAlert className="size-2.5" aria-hidden />}
|
|
69
|
+
{status === 'warning' && <Info className="size-2.5" aria-hidden />}
|
|
70
|
+
{status === 'pending' && <Ellipsis className="size-2.5" aria-hidden />}
|
|
77
71
|
</span>
|
|
78
72
|
);
|
|
79
73
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { ComponentPropsWithRef } from
|
|
1
|
+
import type { ComponentPropsWithRef } from 'react';
|
|
2
2
|
|
|
3
|
-
import * as RadixTabs from
|
|
4
|
-
import { cn } from
|
|
5
|
-
import * as React from
|
|
3
|
+
import * as RadixTabs from '@radix-ui/react-tabs';
|
|
4
|
+
import { cn } from '@/lib/utils';
|
|
5
|
+
import * as React from 'react';
|
|
6
6
|
|
|
7
7
|
export interface TabItem<T extends string = string> {
|
|
8
8
|
value: T;
|
|
@@ -11,14 +11,14 @@ export interface TabItem<T extends string = string> {
|
|
|
11
11
|
disabled?: boolean;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
export type TabTheme =
|
|
14
|
+
export type TabTheme = 'underline' | 'pill';
|
|
15
15
|
|
|
16
16
|
const BASE_TRIGGER =
|
|
17
|
-
|
|
17
|
+
'text-sm font-medium transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed';
|
|
18
18
|
|
|
19
19
|
const THEMES = {
|
|
20
20
|
underline: {
|
|
21
|
-
list:
|
|
21
|
+
list: 'h-9 flex border-b border-border ',
|
|
22
22
|
trigger: `w-full justify-center px-3 ${BASE_TRIGGER}
|
|
23
23
|
text-muted-foreground hover:text-foreground data-[state=active]:text-foreground
|
|
24
24
|
dark:hover:text-gray-200 dark:data-[state=active]:text-gray-200
|
|
@@ -27,7 +27,7 @@ const THEMES = {
|
|
|
27
27
|
hover:border-muted `,
|
|
28
28
|
},
|
|
29
29
|
pill: {
|
|
30
|
-
list:
|
|
30
|
+
list: 'h-9 inline-flex gap-1 p-1 bg-muted rounded-lg',
|
|
31
31
|
trigger: `px-3 ${BASE_TRIGGER} rounded-md
|
|
32
32
|
text-muted-foreground hover:text-foreground data-[state=active]:text-foreground
|
|
33
33
|
dark:hover:text-gray-200 dark:data-[state=active]:text-gray-200
|
|
@@ -36,10 +36,7 @@ const THEMES = {
|
|
|
36
36
|
},
|
|
37
37
|
} as const;
|
|
38
38
|
|
|
39
|
-
export type TabsProps<T extends string = string> = Omit<
|
|
40
|
-
ComponentPropsWithRef<"div">,
|
|
41
|
-
"dir"
|
|
42
|
-
> & {
|
|
39
|
+
export type TabsProps<T extends string = string> = Omit<ComponentPropsWithRef<'div'>, 'dir'> & {
|
|
43
40
|
/**
|
|
44
41
|
* Array of tab items to display
|
|
45
42
|
*/
|
|
@@ -84,7 +81,7 @@ export type TabsProps<T extends string = string> = Omit<
|
|
|
84
81
|
/**
|
|
85
82
|
* The direction of the content of the tabs
|
|
86
83
|
*/
|
|
87
|
-
dir?:
|
|
84
|
+
dir?: 'ltr' | 'rtl';
|
|
88
85
|
};
|
|
89
86
|
|
|
90
87
|
export const Tabs = <T extends string = string>({
|
|
@@ -92,10 +89,10 @@ export const Tabs = <T extends string = string>({
|
|
|
92
89
|
defaultValue,
|
|
93
90
|
value,
|
|
94
91
|
onValueChange,
|
|
95
|
-
theme =
|
|
96
|
-
className =
|
|
97
|
-
tabsListClassName =
|
|
98
|
-
triggerClassName =
|
|
92
|
+
theme = 'underline',
|
|
93
|
+
className = '',
|
|
94
|
+
tabsListClassName = '',
|
|
95
|
+
triggerClassName = '',
|
|
99
96
|
dir,
|
|
100
97
|
...rest
|
|
101
98
|
}: TabsProps<T>) => {
|
|
@@ -122,9 +119,9 @@ export const Tabs = <T extends string = string>({
|
|
|
122
119
|
value={item.value}
|
|
123
120
|
disabled={item.disabled}
|
|
124
121
|
className={cn(
|
|
125
|
-
|
|
122
|
+
'flex items-center overflow-hidden',
|
|
126
123
|
currentTheme.trigger,
|
|
127
|
-
triggerClassName
|
|
124
|
+
triggerClassName
|
|
128
125
|
)}
|
|
129
126
|
>
|
|
130
127
|
{item.icon && (
|