@mastra/playground-ui 6.4.1 → 6.5.0-alpha.1

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.
Files changed (92) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/index.cjs.js +1869 -1918
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.es.js +1844 -1902
  5. package/dist/index.es.js.map +1 -1
  6. package/dist/src/components/assistant-ui/messages/assistant-message.d.ts +1 -3
  7. package/dist/src/components/assistant-ui/thread.d.ts +1 -3
  8. package/dist/src/components/assistant-ui/tools/badges/agent-badge.d.ts +5 -8
  9. package/dist/src/components/assistant-ui/tools/badges/badge-wrapper.d.ts +2 -1
  10. package/dist/src/components/assistant-ui/tools/badges/tool-badge.d.ts +3 -5
  11. package/dist/src/components/assistant-ui/tools/badges/workflow-badge.d.ts +3 -5
  12. package/dist/src/components/assistant-ui/tools/tool-fallback.d.ts +6 -2
  13. package/dist/src/components/ui/containers/buttons-group.d.ts +6 -0
  14. package/dist/src/components/ui/containers/index.d.ts +2 -0
  15. package/dist/src/components/ui/containers/sections.d.ts +6 -0
  16. package/dist/src/components/ui/elements/entry-list/entry-list-entries-skeleton.d.ts +6 -0
  17. package/dist/src/components/ui/elements/entry-list/entry-list-entries.d.ts +6 -0
  18. package/dist/src/components/ui/elements/entry-list/entry-list-entry-col.d.ts +7 -0
  19. package/dist/src/components/ui/elements/entry-list/entry-list-entry.d.ts +11 -0
  20. package/dist/src/components/ui/elements/entry-list/entry-list-header.d.ts +6 -0
  21. package/dist/src/components/ui/elements/entry-list/entry-list-message.d.ts +8 -0
  22. package/dist/src/components/ui/elements/entry-list/entry-list-next-page-loading.d.ts +9 -0
  23. package/dist/src/components/ui/elements/entry-list/entry-list-pagination.d.ts +8 -0
  24. package/dist/src/components/ui/elements/entry-list/entry-list-root.d.ts +6 -0
  25. package/dist/src/components/ui/elements/entry-list/entry-list-skeleton.d.ts +2 -0
  26. package/dist/src/components/ui/elements/entry-list/entry-list-trim.d.ts +6 -0
  27. package/dist/src/components/ui/elements/entry-list/entry-list.d.ts +20 -18
  28. package/dist/src/components/ui/elements/entry-list/helpers.d.ts +10 -0
  29. package/dist/src/components/ui/elements/entry-list/index.d.ts +3 -4
  30. package/dist/src/components/ui/elements/entry-list/shared.d.ts +1 -5
  31. package/dist/src/components/ui/elements/entry-list/types.d.ts +5 -0
  32. package/dist/src/components/ui/elements/headers/page-header.d.ts +2 -2
  33. package/dist/src/components/ui/elements/index.d.ts +3 -0
  34. package/dist/src/components/ui/elements/main-sidebar/index.d.ts +1 -0
  35. package/dist/src/components/ui/elements/main-sidebar/main-sidebar-bottom.d.ts +6 -0
  36. package/dist/src/components/ui/elements/main-sidebar/main-sidebar-context.d.ts +12 -0
  37. package/dist/src/components/ui/elements/main-sidebar/main-sidebar-nav-header.d.ts +8 -0
  38. package/dist/src/components/ui/elements/main-sidebar/main-sidebar-nav-link.d.ts +17 -0
  39. package/dist/src/components/ui/elements/main-sidebar/main-sidebar-nav-list.d.ts +12 -0
  40. package/dist/src/components/ui/elements/main-sidebar/main-sidebar-nav-section.d.ts +13 -0
  41. package/dist/src/components/ui/elements/main-sidebar/main-sidebar-nav-separator.d.ts +5 -0
  42. package/dist/src/components/ui/elements/main-sidebar/main-sidebar-nav.d.ts +6 -0
  43. package/dist/src/components/ui/elements/main-sidebar/main-sidebar-root.d.ts +6 -0
  44. package/dist/src/components/ui/elements/main-sidebar/main-sidebar.d.ts +21 -0
  45. package/dist/src/components/ui/elements/notification/index.d.ts +1 -0
  46. package/dist/src/components/ui/elements/notification/notification.d.ts +9 -0
  47. package/dist/src/components/ui/elements/section/index.d.ts +1 -0
  48. package/dist/src/components/ui/elements/section/section-header.d.ts +7 -0
  49. package/dist/src/components/ui/elements/section/section-heading.d.ts +8 -0
  50. package/dist/src/components/ui/elements/section/section-root.d.ts +5 -0
  51. package/dist/src/components/ui/elements/section/section.d.ts +8 -0
  52. package/dist/src/components/ui/elements/side-dialog/index.d.ts +0 -6
  53. package/dist/src/components/ui/elements/side-dialog/side-dialog-code-section.d.ts +3 -1
  54. package/dist/src/components/ui/elements/side-dialog/side-dialog-content.d.ts +1 -14
  55. package/dist/src/components/ui/elements/side-dialog/side-dialog-nav.d.ts +6 -0
  56. package/dist/src/components/ui/elements/side-dialog/side-dialog-root.d.ts +11 -0
  57. package/dist/src/components/ui/elements/side-dialog/side-dialog-top.d.ts +2 -4
  58. package/dist/src/components/ui/elements/side-dialog/side-dialog.d.ts +16 -12
  59. package/dist/src/components/ui/elements/tabs/tabs-content.d.ts +7 -0
  60. package/dist/src/components/ui/elements/tabs/tabs-list.d.ts +7 -0
  61. package/dist/src/components/ui/elements/tabs/tabs-root.d.ts +9 -0
  62. package/dist/src/components/ui/elements/tabs/tabs-tab.d.ts +8 -0
  63. package/dist/src/components/ui/elements/tabs/tabs.d.ts +20 -36
  64. package/dist/src/domains/agents/components/agent-chat.d.ts +1 -1
  65. package/dist/src/domains/agents/index.d.ts +1 -0
  66. package/dist/src/domains/agents/utils/__tests__/extractPrompt.test.d.ts +1 -0
  67. package/dist/src/domains/agents/utils/extractPrompt.d.ts +2 -0
  68. package/dist/src/domains/observability/components/index.d.ts +4 -0
  69. package/dist/src/domains/observability/components/span-details.d.ts +1 -2
  70. package/dist/src/domains/observability/components/span-dialog.d.ts +8 -2
  71. package/dist/src/domains/observability/components/span-score-list.d.ts +17 -0
  72. package/dist/src/domains/observability/components/span-scoring.d.ts +6 -0
  73. package/dist/src/domains/observability/components/span-tabs.d.ts +16 -0
  74. package/dist/src/domains/observability/components/trace-dialog.d.ts +4 -2
  75. package/dist/src/domains/observability/components/trace-timeline.d.ts +1 -4
  76. package/dist/src/domains/observability/components/traces-list.d.ts +22 -0
  77. package/dist/src/domains/scores/components/score-dialog.d.ts +5 -3
  78. package/dist/src/domains/scores/components/scores-list.d.ts +21 -0
  79. package/dist/src/domains/scores/hooks/use-trace-span-scores.d.ts +7 -0
  80. package/dist/src/domains/scores/hooks/use-trigger-scorer.d.ts +1 -1
  81. package/dist/src/domains/scores/index.d.ts +2 -0
  82. package/dist/src/index.d.ts +1 -0
  83. package/dist/src/services/mastra-runtime-provider.d.ts +1 -1
  84. package/dist/src/types.d.ts +3 -1
  85. package/package.json +12 -10
  86. package/dist/src/components/ui/elements/entry-list/entry-list-cell.d.ts +0 -7
  87. package/dist/src/components/ui/elements/entry-list/entry-list-item.d.ts +0 -9
  88. package/dist/src/components/ui/elements/entry-list/entry-list-page-header.d.ts +0 -8
  89. package/dist/src/domains/scores/components/scorers-dropdown.d.ts +0 -8
  90. package/dist/src/services/agent-network-message.d.ts +0 -2
  91. package/dist/src/services/stream-chunk-message.d.ts +0 -32
  92. package/dist/src/services/vnext-message-provider.d.ts +0 -10
package/dist/index.es.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { useMessagePart, useMessage, MessagePrimitive, ActionBarPrimitive, useAttachment, AttachmentPrimitive, useComposerRuntime, ComposerPrimitive, useComposer, ThreadPrimitive, CompositeAttachmentAdapter, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, WebSpeechSynthesisAdapter, useExternalStoreRuntime, AssistantRuntimeProvider } from '@assistant-ui/react';
3
- import { CheckIcon as CheckIcon$1, CopyIcon, AlertCircle, Check, Copy, ChevronUpIcon, X, Share2, Braces, Loader2, Network, ChevronDown, PauseIcon, HourglassIcon, CircleDashed, Footprints, CircleCheck, CircleX, Minus, Plus, Maximize, Workflow, AlertCircleIcon, ChevronDownIcon, CirclePause, CalendarIcon, Brackets, PlusIcon, TrashIcon, Circle, StopCircle, SearchIcon, BrainIcon, TriangleAlert, AudioLinesIcon, StopCircleIcon, FileText, CircleXIcon, Link, CloudUpload, Mic, ArrowUp, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, SaveIcon, RefreshCw, ExternalLink, InfoIcon as InfoIcon$1, TriangleAlertIcon, ChevronRightIcon, ArrowLeftIcon, ArrowRightIcon, XIcon, ChevronsRightIcon, ArrowUpIcon, ArrowDownIcon, AlignLeftIcon, AlignJustifyIcon, CircleAlertIcon, GaugeIcon, HashIcon, Info, GripVertical, AlertTriangleIcon, NetworkIcon, WorkflowIcon as WorkflowIcon$1, PackageIcon, GitBranchIcon, PackageOpenIcon, OctagonXIcon, FrownIcon, ChevronUp, ChevronsLeftRight, TimerIcon, ChevronsLeftRightIcon, ChevronFirstIcon, ChevronLastIcon, ListTreeIcon, ArrowRightToLineIcon, CoinsIcon, EyeIcon, ChevronsLeftRightEllipsisIcon, PanelTopIcon, PanelLeftIcon, CircleSlash, Clock as Clock$1 } from 'lucide-react';
3
+ import { CheckIcon as CheckIcon$1, CopyIcon, AlertCircle, TriangleAlert, Check, Copy, ChevronUpIcon, X, Share2, Braces, Loader2, Network, ChevronDown, PauseIcon, HourglassIcon, CircleDashed, Footprints, CircleCheck, CircleX, Minus, Plus, Maximize, Workflow, AlertCircleIcon, ChevronDownIcon, CirclePause, CalendarIcon, Brackets, PlusIcon, TrashIcon, Circle, StopCircle, SearchIcon, BrainIcon, AudioLinesIcon, StopCircleIcon, FileText, CircleXIcon, Link, CloudUpload, Mic, ArrowUp, Search, RefreshCcwIcon, ChevronRight, SortAsc, SortDesc, SaveIcon, RefreshCw, ExternalLink, InfoIcon as InfoIcon$1, TriangleAlertIcon, ChevronRightIcon, ArrowLeftIcon, ArrowRightIcon, ChevronsRightIcon, AlignLeftIcon, AlignJustifyIcon, ArrowUpIcon, ArrowDownIcon, CircleAlertIcon, XIcon, PanelRightIcon, GaugeIcon, EyeIcon, ChevronsLeftRightEllipsisIcon, CalculatorIcon, HashIcon, FileInputIcon, FileOutputIcon, ReceiptText, Info, RotateCcw, GripVertical, AlertTriangleIcon, NetworkIcon, WorkflowIcon as WorkflowIcon$1, PackageIcon, GitBranchIcon, PackageOpenIcon, OctagonXIcon, FrownIcon, ChevronUp, ChevronsLeftRight, TimerIcon, ChevronsLeftRightIcon, ChevronFirstIcon, ChevronLastIcon, ArrowRightToLineIcon, CoinsIcon, BracesIcon, CircleGaugeIcon, PanelTopIcon, ListTreeIcon, PanelLeftIcon, CircleSlash, Clock as Clock$1 } from 'lucide-react';
4
4
  import * as React from 'react';
5
- import React__default, { forwardRef, memo, useState, useEffect, useRef, useCallback, useMemo, createContext, useContext, Fragment as Fragment$1, useId, isValidElement } from 'react';
5
+ import React__default, { forwardRef, memo, useState, useEffect, useRef, useCallback, useMemo, createContext, useContext, Fragment as Fragment$1, useId } from 'react';
6
6
  import { Slot } from '@radix-ui/react-slot';
7
7
  import * as TooltipPrimitive from '@radix-ui/react-tooltip';
8
8
  import { TooltipProvider as TooltipProvider$1 } from '@radix-ui/react-tooltip';
@@ -37,7 +37,7 @@ import { create } from 'zustand';
37
37
  import { persist } from 'zustand/middleware';
38
38
  import { AutoForm as AutoForm$1, buildZodFieldConfig } from '@autoform/react';
39
39
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
40
- import { format, isValid, formatDistanceToNow, formatDate } from 'date-fns';
40
+ import { format, isValid, formatDistanceToNow, formatDate, isToday } from 'date-fns';
41
41
  import { useDebouncedCallback } from 'use-debounce';
42
42
  import { DayPicker } from 'react-day-picker';
43
43
  import * as PopoverPrimitive from '@radix-ui/react-popover';
@@ -47,7 +47,7 @@ import * as LabelPrimitive from '@radix-ui/react-label';
47
47
  import { ZodProvider, getFieldConfigInZodStack, getDefaultValueInZodStack } from '@autoform/zod/v4';
48
48
  import { z as z$1 } from 'zod/v3';
49
49
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
50
- import { useMastraClient, mapWorkflowStreamChunkToWatchResult, useChat, toAssistantUIMessage } from '@mastra/react';
50
+ import { useMastraClient, useChat, toAssistantUIMessage } from '@mastra/react';
51
51
  import { useQuery, useMutation, QueryClient, QueryClientProvider } from '@tanstack/react-query';
52
52
  import './index.css';export * from '@tanstack/react-query';
53
53
  import { useReactTable, getCoreRowModel, flexRender } from '@tanstack/react-table';
@@ -64,7 +64,6 @@ import { DragDropContext, Droppable, Draggable } from '@hello-pangea/dnd';
64
64
  import * as SwitchPrimitives from '@radix-ui/react-switch';
65
65
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
66
66
  import { format as format$1 } from 'date-fns/format';
67
- import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
68
67
 
69
68
  function r(e){var t,f,n="";if("string"==typeof e||"number"==typeof e)n+=e;else if("object"==typeof e)if(Array.isArray(e)){var o=e.length;for(t=0;t<o;t++)e[t]&&(f=r(e[t]))&&(n&&(n+=" "),n+=f);}else for(f in e)e[f]&&(n&&(n+=" "),n+=f);return n}function clsx(){for(var e,t,f=0,n="",o=arguments.length;f<o;f++)(e=arguments[f])&&(t=r(e))&&(n&&(n+=" "),n+=t);return n}
70
69
 
@@ -3414,42 +3413,6 @@ const defaultComponents = unstable_memoizeMarkdownComponents({
3414
3413
  img: ImageWithFallback
3415
3414
  });
3416
3415
 
3417
- const ErrorAwareText = () => {
3418
- const part = useMessagePart();
3419
- const text = part.text || "";
3420
- try {
3421
- const trimmedText = text.trim();
3422
- if (trimmedText.startsWith("__ERROR__:")) {
3423
- const errorMessage = trimmedText.substring("__ERROR__:".length);
3424
- return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 p-4 rounded-lg bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-900/50", children: [
3425
- /* @__PURE__ */ jsx(AlertCircle, { className: "w-5 h-5 text-red-500 dark:text-red-400 mt-0.5 flex-shrink-0" }),
3426
- /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
3427
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-red-800 dark:text-red-200 mb-1", children: "Error" }),
3428
- /* @__PURE__ */ jsx("p", { className: "text-sm text-red-700 dark:text-red-300", children: errorMessage })
3429
- ] })
3430
- ] });
3431
- } else if (trimmedText.startsWith("Error:")) {
3432
- const errorMessage = trimmedText.substring("Error:".length).trim();
3433
- return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 p-4 rounded-lg bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-900/50", children: [
3434
- /* @__PURE__ */ jsx(AlertCircle, { className: "w-5 h-5 text-red-500 dark:text-red-400 mt-0.5 flex-shrink-0" }),
3435
- /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
3436
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-red-800 dark:text-red-200 mb-1", children: "Error" }),
3437
- /* @__PURE__ */ jsx("p", { className: "text-sm text-red-700 dark:text-red-300", children: errorMessage })
3438
- ] })
3439
- ] });
3440
- }
3441
- return /* @__PURE__ */ jsx(MarkdownText, {});
3442
- } catch (error) {
3443
- return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 p-4 rounded-lg bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-900/50", children: [
3444
- /* @__PURE__ */ jsx(AlertCircle, { className: "w-5 h-5 text-red-500 dark:text-red-400 mt-0.5 flex-shrink-0" }),
3445
- /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
3446
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-red-800 dark:text-red-200 mb-1", children: "Error" }),
3447
- /* @__PURE__ */ jsx("p", { className: "text-sm text-red-700 dark:text-red-300", children: String(text) })
3448
- ] })
3449
- ] });
3450
- }
3451
- };
3452
-
3453
3416
  const AgentIcon = (props) => /* @__PURE__ */ jsxs("svg", { width: "17", height: "16", viewBox: "0 0 17 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", ...props, children: [
3454
3417
  /* @__PURE__ */ jsx(
3455
3418
  "path",
@@ -4242,6 +4205,91 @@ const AgentNetworkCoinIcon = (props) => /* @__PURE__ */ jsxs("svg", { width: "12
4242
4205
  ) }) })
4243
4206
  ] });
4244
4207
 
4208
+ const variants = {
4209
+ "header-md": "text-header-md leading-header-md",
4210
+ "ui-lg": "text-ui-lg leading-ui-lg",
4211
+ "ui-md": "text-ui-md leading-ui-md",
4212
+ "ui-sm": "text-ui-sm leading-ui-sm",
4213
+ "ui-xs": "text-ui-xs leading-ui-xs"
4214
+ };
4215
+ const fonts = {
4216
+ mono: "font-mono"
4217
+ };
4218
+ const Txt = ({ as: Root = "p", className, variant = "ui-md", font, ...props }) => {
4219
+ return /* @__PURE__ */ jsx(Root, { className: clsx(variants[variant], font && fonts[font], className), ...props });
4220
+ };
4221
+
4222
+ const variantClasses$3 = {
4223
+ warning: "bg-yellow-900/20 border-sm border-yellow-200 text-yellow-200",
4224
+ destructive: "bg-red-900/20 border-sm border-red-200 text-red-200"
4225
+ };
4226
+ const variantIcons = {
4227
+ warning: TriangleAlert,
4228
+ destructive: AlertCircle
4229
+ };
4230
+ const Alert$1 = ({ children, variant = "destructive" }) => {
4231
+ const Ico = variantIcons[variant];
4232
+ return /* @__PURE__ */ jsx("div", { className: clsx(variantClasses$3[variant], "p-2 rounded-md"), children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
4233
+ /* @__PURE__ */ jsx(Icon, { className: "mt-0.5", children: /* @__PURE__ */ jsx(Ico, {}) }),
4234
+ /* @__PURE__ */ jsx("div", { children })
4235
+ ] }) });
4236
+ };
4237
+ const AlertTitle$1 = ({ children, as: As = "h5" }) => {
4238
+ return /* @__PURE__ */ jsx(Txt, { as: As, variant: "ui-md", className: "font-semibold", children });
4239
+ };
4240
+ const AlertDescription$1 = ({ children, as: As = "p" }) => {
4241
+ return /* @__PURE__ */ jsx(Txt, { as: As, variant: "ui-sm", children });
4242
+ };
4243
+
4244
+ const ErrorAwareText = () => {
4245
+ const part = useMessagePart();
4246
+ const text = part.text || "";
4247
+ const metadata = part.metadata || {};
4248
+ if (metadata?.status === "warning") {
4249
+ return /* @__PURE__ */ jsxs(Alert$1, { variant: "warning", children: [
4250
+ /* @__PURE__ */ jsx(AlertTitle$1, { as: "h5", children: "Warning" }),
4251
+ /* @__PURE__ */ jsx(AlertDescription$1, { as: "p", children: text })
4252
+ ] });
4253
+ }
4254
+ if (metadata?.status === "error") {
4255
+ return /* @__PURE__ */ jsxs(Alert$1, { variant: "destructive", children: [
4256
+ /* @__PURE__ */ jsx(AlertTitle$1, { as: "h5", children: "Error" }),
4257
+ /* @__PURE__ */ jsx(AlertDescription$1, { as: "p", children: text })
4258
+ ] });
4259
+ }
4260
+ try {
4261
+ const trimmedText = text.trim();
4262
+ if (trimmedText.startsWith("__ERROR__:")) {
4263
+ const errorMessage = trimmedText.substring("__ERROR__:".length);
4264
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 p-4 rounded-lg bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-900/50", children: [
4265
+ /* @__PURE__ */ jsx(AlertCircle, { className: "w-5 h-5 text-red-500 dark:text-red-400 mt-0.5 flex-shrink-0" }),
4266
+ /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
4267
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-red-800 dark:text-red-200 mb-1", children: "Error" }),
4268
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-red-700 dark:text-red-300", children: errorMessage })
4269
+ ] })
4270
+ ] });
4271
+ } else if (trimmedText.startsWith("Error:")) {
4272
+ const errorMessage = trimmedText.substring("Error:".length).trim();
4273
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 p-4 rounded-lg bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-900/50", children: [
4274
+ /* @__PURE__ */ jsx(AlertCircle, { className: "w-5 h-5 text-red-500 dark:text-red-400 mt-0.5 flex-shrink-0" }),
4275
+ /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
4276
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-red-800 dark:text-red-200 mb-1", children: "Error" }),
4277
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-red-700 dark:text-red-300", children: errorMessage })
4278
+ ] })
4279
+ ] });
4280
+ }
4281
+ return /* @__PURE__ */ jsx(MarkdownText, {});
4282
+ } catch (error) {
4283
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 p-4 rounded-lg bg-red-50 dark:bg-red-950/20 border border-red-200 dark:border-red-900/50", children: [
4284
+ /* @__PURE__ */ jsx(AlertCircle, { className: "w-5 h-5 text-red-500 dark:text-red-400 mt-0.5 flex-shrink-0" }),
4285
+ /* @__PURE__ */ jsxs("div", { className: "flex-1", children: [
4286
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-red-800 dark:text-red-200 mb-1", children: "Error" }),
4287
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-red-700 dark:text-red-300", children: String(text) })
4288
+ ] })
4289
+ ] });
4290
+ }
4291
+ };
4292
+
4245
4293
  function useCopyToClipboard({ text, copyMessage = "Copied to clipboard!" }) {
4246
4294
  const [isCopied, setIsCopied] = useState(false);
4247
4295
  const timeoutRef = useRef(null);
@@ -4307,12 +4355,12 @@ const SyntaxHighlighter$2 = ({
4307
4355
  const formattedCode = JSON.stringify(data, null, 2);
4308
4356
  const theme = useCodemirrorTheme$2();
4309
4357
  return /* @__PURE__ */ jsxs("div", { className: clsx("rounded-md bg-surface4 p-1 font-mono relative", className), children: [
4310
- /* @__PURE__ */ jsx(CopyButton, { content: formattedCode, className: "absolute top-2 right-2 z-[9999]" }),
4358
+ /* @__PURE__ */ jsx(CopyButton, { content: formattedCode, className: "absolute top-2 right-2 z-20" }),
4311
4359
  /* @__PURE__ */ jsx(CodeMirror, { value: formattedCode, theme, extensions: [jsonLanguage] })
4312
4360
  ] });
4313
4361
  };
4314
4362
 
4315
- const variantClasses$3 = {
4363
+ const variantClasses$2 = {
4316
4364
  default: "text-icon3",
4317
4365
  success: "text-accent1",
4318
4366
  error: "text-accent2",
@@ -4325,12 +4373,12 @@ const Badge$1 = ({ icon, variant = "default", className, children, ...props }) =
4325
4373
  className: clsx(
4326
4374
  "font-mono bg-surface4 text-ui-sm gap-md h-badge-default inline-flex items-center rounded-md shrink-0",
4327
4375
  icon ? "pl-md pr-1.5" : "px-1.5",
4328
- icon || variant === "default" ? "text-icon5" : variantClasses$3[variant],
4376
+ icon || variant === "default" ? "text-icon5" : variantClasses$2[variant],
4329
4377
  className
4330
4378
  ),
4331
4379
  ...props,
4332
4380
  children: [
4333
- icon && /* @__PURE__ */ jsx("span", { className: variantClasses$3[variant], children: /* @__PURE__ */ jsx(Icon, { children: icon }) }),
4381
+ icon && /* @__PURE__ */ jsx("span", { className: variantClasses$2[variant], children: /* @__PURE__ */ jsx(Icon, { children: icon }) }),
4334
4382
  children
4335
4383
  ]
4336
4384
  }
@@ -4343,10 +4391,11 @@ const BadgeWrapper = ({
4343
4391
  icon,
4344
4392
  title,
4345
4393
  collapsible = true,
4346
- extraInfo
4394
+ extraInfo,
4395
+ "data-testid": dataTestId
4347
4396
  }) => {
4348
4397
  const [isCollapsed, setIsCollapsed] = useState(initialCollapsed);
4349
- return /* @__PURE__ */ jsxs("div", { className: "mb-4", children: [
4398
+ return /* @__PURE__ */ jsxs("div", { className: "mb-4", "data-testid": dataTestId, children: [
4350
4399
  /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-2 items-center justify-between", children: [
4351
4400
  /* @__PURE__ */ jsxs(
4352
4401
  "button",
@@ -4417,20 +4466,6 @@ DialogTitle.displayName = DialogPrimitive.Title.displayName;
4417
4466
  const DialogDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(DialogPrimitive.Description, { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
4418
4467
  DialogDescription.displayName = DialogPrimitive.Description.displayName;
4419
4468
 
4420
- const variants = {
4421
- "header-md": "text-header-md leading-header-md",
4422
- "ui-lg": "text-ui-lg leading-ui-lg",
4423
- "ui-md": "text-ui-md leading-ui-md",
4424
- "ui-sm": "text-ui-sm leading-ui-sm",
4425
- "ui-xs": "text-ui-xs leading-ui-xs"
4426
- };
4427
- const fonts = {
4428
- mono: "font-mono"
4429
- };
4430
- const Txt = ({ as: Root = "p", className, variant = "ui-md", font, ...props }) => {
4431
- return /* @__PURE__ */ jsx(Root, { className: clsx(variants[variant], font && fonts[font], className), ...props });
4432
- };
4433
-
4434
4469
  const NetworkChoiceMetadata = ({ selectionReason, open, onOpenChange, input }) => {
4435
4470
  let inputSlot = null;
4436
4471
  if (input) {
@@ -4476,7 +4511,7 @@ const NetworkChoiceMetadataDialogTrigger = ({
4476
4511
  ] });
4477
4512
  };
4478
4513
 
4479
- const ToolBadge = ({ toolName, args, result, networkMetadata, toolOutput }) => {
4514
+ const ToolBadge = ({ toolName, args, result, metadata, toolOutput }) => {
4480
4515
  let argSlot = null;
4481
4516
  try {
4482
4517
  const { __mastraMetadata: _, ...formattedArgs } = typeof args === "object" ? args : JSON.parse(args);
@@ -4485,16 +4520,19 @@ const ToolBadge = ({ toolName, args, result, networkMetadata, toolOutput }) => {
4485
4520
  argSlot = /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap", children: args });
4486
4521
  }
4487
4522
  let resultSlot = typeof result === "string" ? /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap bg-surface4 p-4 rounded-md", children: result }) : /* @__PURE__ */ jsx(SyntaxHighlighter$2, { data: result });
4523
+ const selectionReason = metadata?.mode === "network" ? metadata.selectionReason : void 0;
4524
+ const agentNetworkInput = metadata?.mode === "network" ? metadata.agentInput : void 0;
4488
4525
  return /* @__PURE__ */ jsx(
4489
4526
  BadgeWrapper,
4490
4527
  {
4528
+ "data-testid": "tool-badge",
4491
4529
  icon: /* @__PURE__ */ jsx(ToolsIcon, { className: "text-[#ECB047]" }),
4492
4530
  title: toolName,
4493
- extraInfo: networkMetadata && /* @__PURE__ */ jsx(
4531
+ extraInfo: metadata?.mode === "network" && /* @__PURE__ */ jsx(
4494
4532
  NetworkChoiceMetadataDialogTrigger,
4495
4533
  {
4496
- selectionReason: networkMetadata?.selectionReason || "",
4497
- input: networkMetadata?.input
4534
+ selectionReason: selectionReason || "",
4535
+ input: agentNetworkInput
4498
4536
  }
4499
4537
  ),
4500
4538
  children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
@@ -5100,7 +5138,7 @@ const sizeClasses = {
5100
5138
  md: "h-button-md gap-md",
5101
5139
  lg: "h-button-lg gap-lg"
5102
5140
  };
5103
- const variantClasses$2 = {
5141
+ const variantClasses$1 = {
5104
5142
  default: "bg-surface2 hover:bg-surface4 text-icon3 hover:text-icon6",
5105
5143
  light: "bg-surface3 hover:bg-surface5 text-icon6"
5106
5144
  };
@@ -5111,7 +5149,7 @@ const Button$1 = ({ className, as, size = "md", variant = "default", ...props })
5111
5149
  {
5112
5150
  className: clsx(
5113
5151
  "bg-surface2 border-sm border-border1 px-lg text-ui-md inline-flex items-center justify-center rounded-md border",
5114
- variantClasses$2[variant],
5152
+ variantClasses$1[variant],
5115
5153
  sizeClasses[size],
5116
5154
  className,
5117
5155
  {
@@ -6070,20 +6108,20 @@ const alertVariants = cva(
6070
6108
  }
6071
6109
  }
6072
6110
  );
6073
- const Alert$1 = React.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, role: "alert", className: cn(alertVariants({ variant }), className), ...props }));
6074
- Alert$1.displayName = "Alert";
6075
- const AlertTitle$1 = React.forwardRef(
6111
+ const Alert = React.forwardRef(({ className, variant, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, role: "alert", className: cn(alertVariants({ variant }), className), ...props }));
6112
+ Alert.displayName = "Alert";
6113
+ const AlertTitle = React.forwardRef(
6076
6114
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("h5", { ref, className: cn("mb-1 font-medium leading-none tracking-tight", className), ...props })
6077
6115
  );
6078
- AlertTitle$1.displayName = "AlertTitle";
6079
- const AlertDescription$1 = React.forwardRef(
6116
+ AlertTitle.displayName = "AlertTitle";
6117
+ const AlertDescription = React.forwardRef(
6080
6118
  ({ className, ...props }, ref) => /* @__PURE__ */ jsx("div", { ref, className: cn("text-sm [&_p]:leading-relaxed", className), ...props })
6081
6119
  );
6082
- AlertDescription$1.displayName = "AlertDescription";
6120
+ AlertDescription.displayName = "AlertDescription";
6083
6121
 
6084
- const ErrorMessage = ({ error }) => /* @__PURE__ */ jsxs(Alert$1, { variant: "destructive", children: [
6122
+ const ErrorMessage = ({ error }) => /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
6085
6123
  /* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
6086
- /* @__PURE__ */ jsx(AlertTitle$1, { children: error })
6124
+ /* @__PURE__ */ jsx(AlertTitle, { children: error })
6087
6125
  ] });
6088
6126
 
6089
6127
  const SubmitButton = ({ children }) => /* @__PURE__ */ jsx(Button$2, { type: "submit", children });
@@ -6865,7 +6903,8 @@ function DynamicForm({
6865
6903
  },
6866
6904
  defaultValues: isNotZodObject ? defaultValues ? { "​": defaultValues } : void 0 : defaultValues,
6867
6905
  formProps: {
6868
- className
6906
+ className,
6907
+ noValidate: true
6869
6908
  },
6870
6909
  uiComponents: {
6871
6910
  SubmitButton: ({ children }) => onSubmit ? /* @__PURE__ */ jsx(Button$1, { variant: "light", className: "w-full", size: "lg", disabled: isSubmitLoading, children: isSubmitLoading ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Loader2, { className: "animate-spin" }) }) : submitButtonLabel || children }) : null
@@ -7658,7 +7697,7 @@ function WorkflowTable({ workflows, isLoading }) {
7658
7697
  return /* @__PURE__ */ jsx(EmptyWorkflowsTable, {});
7659
7698
  }
7660
7699
  const filteredRows = rows.filter((row) => row.original.name.toLowerCase().includes(search.toLowerCase()));
7661
- return /* @__PURE__ */ jsxs(Fragment, { children: [
7700
+ return /* @__PURE__ */ jsxs("div", { children: [
7662
7701
  /* @__PURE__ */ jsx(SearchbarWrapper, { children: /* @__PURE__ */ jsx(Searchbar, { onSearch: setSearch, label: "Search workflows", placeholder: "Search workflows" }) }),
7663
7702
  isLoading ? /* @__PURE__ */ jsx(WorkflowTableSkeleton, {}) : /* @__PURE__ */ jsx(ScrollableContainer, { children: /* @__PURE__ */ jsxs(Table$1, { children: [
7664
7703
  /* @__PURE__ */ jsx(Thead, { className: "sticky top-0", children: ths.headers.map((header) => /* @__PURE__ */ jsx(Th, { style: { width: header.index === 0 ? "auto" : header.column.getSize() }, children: flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }),
@@ -7700,24 +7739,27 @@ const EmptyWorkflowsTable = () => /* @__PURE__ */ jsx("div", { className: "flex
7700
7739
  }
7701
7740
  ) });
7702
7741
 
7703
- const WorkflowBadge = ({ workflow, runId, workflowId, isStreaming, networkMetadata }) => {
7742
+ const WorkflowBadge = ({ workflow, runId, workflowId, isStreaming, metadata }) => {
7704
7743
  const { data: runs, isLoading: isRunsLoading } = useWorkflowRuns(workflowId, {
7705
7744
  enabled: Boolean(runId) && !isStreaming
7706
7745
  });
7707
7746
  const run = runs?.runs.find((run2) => run2.runId === runId);
7708
7747
  const isLoading = isRunsLoading || !run;
7709
7748
  const snapshot = typeof run?.snapshot === "object" ? run?.snapshot : void 0;
7749
+ const selectionReason = metadata?.mode === "network" ? metadata.selectionReason : void 0;
7750
+ const agentNetworkInput = metadata?.mode === "network" ? metadata.agentInput : void 0;
7710
7751
  return /* @__PURE__ */ jsxs(
7711
7752
  BadgeWrapper,
7712
7753
  {
7754
+ "data-testid": "workflow-badge",
7713
7755
  icon: /* @__PURE__ */ jsx(WorkflowIcon, { className: "text-accent3" }),
7714
7756
  title: workflow.name,
7715
7757
  initialCollapsed: false,
7716
- extraInfo: networkMetadata && /* @__PURE__ */ jsx(
7758
+ extraInfo: metadata?.mode === "network" && /* @__PURE__ */ jsx(
7717
7759
  NetworkChoiceMetadataDialogTrigger,
7718
7760
  {
7719
- selectionReason: networkMetadata?.selectionReason || "",
7720
- input: networkMetadata?.input
7761
+ selectionReason: selectionReason ?? "",
7762
+ input: agentNetworkInput
7721
7763
  }
7722
7764
  ),
7723
7765
  children: [
@@ -7769,18 +7811,21 @@ const LoadingBadge = () => {
7769
7811
  );
7770
7812
  };
7771
7813
 
7772
- const AgentBadge = ({ agentId, messages = [], networkMetadata }) => {
7814
+ const AgentBadge = ({ agentId, messages = [], metadata }) => {
7815
+ const selectionReason = metadata?.mode === "network" ? metadata.selectionReason : void 0;
7816
+ const agentNetworkInput = metadata?.mode === "network" ? metadata.agentInput : void 0;
7773
7817
  return /* @__PURE__ */ jsx(
7774
7818
  BadgeWrapper,
7775
7819
  {
7820
+ "data-testid": "agent-badge",
7776
7821
  icon: /* @__PURE__ */ jsx(AgentIcon, { className: "text-accent1" }),
7777
7822
  title: agentId,
7778
7823
  initialCollapsed: false,
7779
- extraInfo: networkMetadata && /* @__PURE__ */ jsx(
7824
+ extraInfo: metadata?.mode === "network" && /* @__PURE__ */ jsx(
7780
7825
  NetworkChoiceMetadataDialogTrigger,
7781
7826
  {
7782
- selectionReason: networkMetadata?.selectionReason || "",
7783
- input: networkMetadata?.input
7827
+ selectionReason: selectionReason ?? "",
7828
+ input: agentNetworkInput
7784
7829
  }
7785
7830
  ),
7786
7831
  children: messages.map((message, index) => {
@@ -7799,6 +7844,9 @@ const AgentBadge = ({ agentId, messages = [], networkMetadata }) => {
7799
7844
  type: "tool-call",
7800
7845
  toolCallId: message.toolCallId,
7801
7846
  addResult: () => {
7847
+ },
7848
+ metadata: {
7849
+ mode: "stream"
7802
7850
  }
7803
7851
  }
7804
7852
  ) }, index);
@@ -7810,30 +7858,25 @@ const AgentBadge = ({ agentId, messages = [], networkMetadata }) => {
7810
7858
  const ToolFallback = ({ toolName, result, args, ...props }) => {
7811
7859
  return /* @__PURE__ */ jsx(WorkflowRunProvider, { children: /* @__PURE__ */ jsx(ToolFallbackInner, { toolName, result, args, ...props }) });
7812
7860
  };
7813
- const ToolFallbackInner = ({ toolName, result, args }) => {
7814
- useWorkflowStream(args.__mastraMetadata?.workflowFullState);
7861
+ const ToolFallbackInner = ({ toolName, result, args, metadata, ...props }) => {
7862
+ useWorkflowStream(result);
7815
7863
  const { data: workflow, isLoading } = useWorkflow(toolName);
7816
- const isAgent = args.__mastraMetadata?.from === "AGENT";
7864
+ const isAgent = metadata?.mode === "network" && metadata.from === "AGENT";
7817
7865
  if (isAgent) {
7818
- return /* @__PURE__ */ jsx(
7819
- AgentBadge,
7820
- {
7821
- agentId: toolName,
7822
- messages: args?.__mastraMetadata?.messages,
7823
- networkMetadata: args?.__mastraMetadata?.networkMetadata
7824
- }
7825
- );
7866
+ const messages = result?.childMessages ?? [];
7867
+ return /* @__PURE__ */ jsx(AgentBadge, { agentId: toolName, messages, metadata });
7826
7868
  }
7827
7869
  if (isLoading) return /* @__PURE__ */ jsx(LoadingBadge, {});
7828
7870
  if (workflow) {
7871
+ const isStreaming = metadata?.mode === "stream" || metadata?.mode === "network";
7829
7872
  return /* @__PURE__ */ jsx(
7830
7873
  WorkflowBadge,
7831
7874
  {
7832
7875
  workflowId: toolName,
7833
7876
  workflow,
7834
- isStreaming: args.__mastraMetadata?.isStreaming,
7877
+ isStreaming,
7835
7878
  runId: result?.runId,
7836
- networkMetadata: args?.__mastraMetadata?.networkMetadata
7879
+ metadata
7837
7880
  }
7838
7881
  );
7839
7882
  }
@@ -7843,8 +7886,8 @@ const ToolFallbackInner = ({ toolName, result, args }) => {
7843
7886
  toolName,
7844
7887
  args,
7845
7888
  result,
7846
- toolOutput: args?.__mastraMetadata?.toolOutput || [],
7847
- networkMetadata: args?.__mastraMetadata?.networkMetadata
7889
+ toolOutput: result?.toolOutput || [],
7890
+ metadata
7848
7891
  }
7849
7892
  );
7850
7893
  };
@@ -8409,32 +8452,23 @@ const ProviderLogo = ({ providerId, className = "", size = 20 }) => {
8409
8452
  );
8410
8453
  };
8411
8454
 
8412
- const statusClasses = {
8413
- warning: "bg-yellow-900/20 border-sm border-yellow-200 text-yellow-200 rounded-lg px-4 py-2 flex gap-4 items-center",
8414
- default: ""
8415
- };
8416
- const AssistantMessage = ({ ToolFallback: ToolFallbackCustom, hasModelList }) => {
8455
+ const AssistantMessage = ({ hasModelList }) => {
8417
8456
  const data = useMessage();
8418
8457
  const messageId = data.id;
8419
8458
  const isToolCallAndOrReasoning = data.content.every(({ type }) => type === "tool-call" || type === "reasoning");
8420
8459
  const modelMetadata = data.metadata?.custom?.modelMetadata;
8421
- const messageStatus = data.metadata?.custom?.status;
8422
- const statusClass = statusClasses[messageStatus || "default"];
8423
8460
  const showModelUsed = hasModelList && modelMetadata;
8424
8461
  return /* @__PURE__ */ jsxs(MessagePrimitive.Root, { className: "max-w-full", "data-message-id": messageId, children: [
8425
- /* @__PURE__ */ jsxs("div", { className: clsx("text-icon6 text-ui-lg leading-ui-lg", statusClass), children: [
8426
- messageStatus === "warning" && /* @__PURE__ */ jsx(Icon, { size: "lg", children: /* @__PURE__ */ jsx(TriangleAlert, {}) }),
8427
- /* @__PURE__ */ jsx(
8428
- MessagePrimitive.Parts,
8429
- {
8430
- components: {
8431
- Text: ErrorAwareText,
8432
- tools: { Fallback: ToolFallbackCustom || ToolFallback },
8433
- Reasoning
8434
- }
8462
+ /* @__PURE__ */ jsx("div", { className: "text-icon6 text-ui-lg leading-ui-lg", children: /* @__PURE__ */ jsx(
8463
+ MessagePrimitive.Parts,
8464
+ {
8465
+ components: {
8466
+ Text: ErrorAwareText,
8467
+ tools: { Fallback: ToolFallback },
8468
+ Reasoning
8435
8469
  }
8436
- )
8437
- ] }),
8470
+ }
8471
+ ) }),
8438
8472
  !isToolCallAndOrReasoning && /* @__PURE__ */ jsxs("div", { className: cn("h-6 pt-4 flex gap-2 items-center", { "pb-1": showModelUsed }), children: [
8439
8473
  showModelUsed && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5", children: [
8440
8474
  /* @__PURE__ */ jsx(ProviderLogo, { providerId: modelMetadata.modelProvider, size: 14 }),
@@ -9031,11 +9065,11 @@ const useThreadInput = () => {
9031
9065
  return useContext(ThreadInputContext);
9032
9066
  };
9033
9067
 
9034
- const Thread = ({ ToolFallback, agentName, agentId, hasMemory, hasModelList }) => {
9068
+ const Thread = ({ agentName, agentId, hasMemory, hasModelList }) => {
9035
9069
  const areaRef = useRef(null);
9036
9070
  useAutoscroll(areaRef, { enabled: true });
9037
9071
  const WrappedAssistantMessage = (props) => {
9038
- return /* @__PURE__ */ jsx(AssistantMessage, { ...props, ToolFallback, hasModelList });
9072
+ return /* @__PURE__ */ jsx(AssistantMessage, { ...props, hasModelList });
9039
9073
  };
9040
9074
  return /* @__PURE__ */ jsxs(ThreadWrapper, { children: [
9041
9075
  /* @__PURE__ */ jsxs(ThreadPrimitive.Viewport, { ref: areaRef, autoScroll: false, className: "overflow-y-scroll scroll-smooth h-full", children: [
@@ -9411,645 +9445,72 @@ const useAdapters = (agentId) => {
9411
9445
  };
9412
9446
  };
9413
9447
 
9414
- const handleNetworkMessageFromMemory = (content) => {
9415
- if (content.primitiveType === "workflow") {
9416
- return {
9417
- role: "assistant",
9418
- content: [
9419
- {
9420
- type: "tool-call",
9421
- toolCallId: content.finalResult.runId,
9422
- toolName: content.primitiveId,
9423
- result: { runId: content.finalResult.runId },
9424
- args: {
9425
- __mastraMetadata: {
9426
- from: "WORKFLOW",
9427
- networkMetadata: {
9428
- selectionReason: content?.selectionReason,
9429
- input: content?.input
9430
- }
9431
- }
9432
- }
9433
- }
9434
- ]
9435
- };
9448
+ const handleFinishReason = (finishReason) => {
9449
+ switch (finishReason) {
9450
+ case "tool-calls":
9451
+ throw new Error("Stream finished with reason tool-calls, try increasing maxSteps");
9436
9452
  }
9437
- if (content.primitiveType === "agent") {
9438
- const badgeMessages = [];
9439
- let toolCalls = {};
9440
- const messages = content.finalResult.messages.slice(1);
9441
- for (const message of messages) {
9442
- if (typeof message.content === "string") {
9443
- badgeMessages.push({
9444
- type: "text",
9445
- content: message.content
9446
- });
9447
- continue;
9448
- }
9449
- for (const part of message.content) {
9450
- if (part.type === "text") {
9451
- badgeMessages.push({
9452
- type: "text",
9453
- content: part.content
9454
- });
9455
- } else if (part.type === "tool-result") {
9456
- badgeMessages.push({
9457
- type: "tool",
9458
- toolName: part.toolName,
9459
- toolOutput: part.result,
9460
- // tool output
9461
- toolCallId: part.toolCallId,
9462
- args: toolCalls?.[part.toolCallId]?.args || {}
9463
- });
9464
- } else if (part.type === "tool-call") {
9465
- toolCalls[part.toolCallId] = part;
9466
- }
9453
+ };
9454
+ const convertToAIAttachments = async (attachments) => {
9455
+ const promises = (attachments ?? []).filter((attachment) => attachment.type === "image" || attachment.type === "document").map(async (attachment) => {
9456
+ const isFileFromURL = attachment.name.startsWith("https://");
9457
+ if (attachment.type === "document") {
9458
+ if (attachment.contentType === "application/pdf") {
9459
+ const pdfText = attachment.content?.[0]?.text || "";
9460
+ return {
9461
+ role: "user",
9462
+ content: [
9463
+ {
9464
+ type: "file",
9465
+ data: isFileFromURL ? attachment.name : `data:application/pdf;base64,${pdfText}`,
9466
+ mimeType: attachment.contentType,
9467
+ filename: attachment.name
9468
+ }
9469
+ ]
9470
+ };
9467
9471
  }
9472
+ return {
9473
+ role: "user",
9474
+ // @ts-expect-error - TODO: fix this type issue somehow
9475
+ content: attachment.content[0]?.text || ""
9476
+ };
9468
9477
  }
9469
9478
  return {
9470
- role: "assistant",
9471
- content: [
9472
- {
9473
- type: "tool-call",
9474
- toolCallId: content.finalResult.runId,
9475
- toolName: content.primitiveId,
9476
- result: { runId: content.finalResult.runId },
9477
- args: {
9478
- __mastraMetadata: {
9479
- from: "AGENT",
9480
- networkMetadata: {
9481
- selectionReason: content?.selectionReason || "",
9482
- input: content?.input || ""
9483
- },
9484
- messages: badgeMessages
9485
- }
9486
- }
9487
- }
9488
- ]
9489
- };
9490
- }
9491
- if (content.primitiveType === "tool") {
9492
- return {
9493
- role: "assistant",
9479
+ role: "user",
9494
9480
  content: [
9495
9481
  {
9496
- type: "tool-call",
9497
- toolCallId: content.finalResult.toolCallId,
9498
- toolName: content.primitiveId,
9499
- result: content.finalResult.result,
9500
- args: {
9501
- ...content?.input,
9502
- __mastraMetadata: {
9503
- networkMetadata: {
9504
- selectionReason: content?.selectionReason || "",
9505
- input: content?.input || ""
9506
- }
9507
- }
9508
- }
9482
+ type: "image",
9483
+ image: isFileFromURL ? attachment.name : await fileToBase64(attachment.file),
9484
+ mimeType: attachment.file.type
9509
9485
  }
9510
9486
  ]
9511
9487
  };
9512
- }
9513
- return { role: "assistant", content: [{ type: "text", text: "Unknown response" }] };
9488
+ });
9489
+ return Promise.all(promises);
9514
9490
  };
9515
-
9516
- const handleStreamChunk = ({ chunk, conversation }) => {
9517
- switch (chunk.type) {
9518
- case "tripwire": {
9519
- return [
9520
- ...conversation,
9521
- {
9522
- role: "assistant",
9523
- metadata: {
9524
- custom: {
9525
- status: "warning"
9526
- }
9527
- },
9528
- content: [
9529
- {
9530
- type: "text",
9531
- text: chunk.payload.tripwireReason
9532
- }
9533
- ]
9534
- }
9535
- ];
9536
- }
9537
- case "start": {
9538
- const newMessage = {
9539
- role: "assistant",
9540
- content: []
9541
- };
9542
- return [...conversation, newMessage];
9543
- }
9544
- case "text-start":
9545
- case "text-delta": {
9546
- const lastMessage = conversation[conversation.length - 1];
9547
- if (!lastMessage) return conversation;
9548
- if (lastMessage.role === "assistant" && typeof lastMessage.content !== `string` && (!lastMessage.content || lastMessage.content.length === 0 || lastMessage.content[lastMessage.content.length - 1]?.type !== `text`)) {
9549
- return [
9550
- ...conversation.slice(0, -1),
9551
- {
9552
- ...lastMessage,
9553
- content: [...lastMessage.content || [], { type: "text", text: "" }]
9554
- }
9555
- ];
9556
- }
9557
- if (chunk.type === `text-start`) return conversation;
9558
- if (typeof lastMessage.content === `string`) {
9559
- return [
9560
- ...conversation.slice(0, -1),
9561
- {
9562
- ...lastMessage,
9563
- content: lastMessage.content + chunk.payload.text
9564
- }
9565
- ];
9491
+ const initializeMessageState = (initialMessages) => {
9492
+ const convertedMessages = initialMessages?.map((message) => {
9493
+ const attachmentsAsContentParts = (message.experimental_attachments || []).map((image) => ({
9494
+ type: image.contentType.startsWith(`image/`) ? "image" : image.contentType.startsWith(`audio/`) ? "audio" : "file",
9495
+ mimeType: image.contentType,
9496
+ image: image.url
9497
+ }));
9498
+ const formattedParts = (message.parts || []).map((part) => {
9499
+ if (part.type === "reasoning") {
9500
+ return {
9501
+ type: "reasoning",
9502
+ text: part.reasoning || part?.details?.filter((detail) => detail.type === "text")?.map((detail) => detail.text).join(" ")
9503
+ };
9566
9504
  }
9567
- const lastPart = lastMessage.content?.[lastMessage.content.length - 1];
9568
- if (!lastPart || lastPart.type !== `text`) return conversation;
9569
- return [
9570
- ...conversation.slice(0, -1),
9571
- {
9572
- ...lastMessage,
9573
- content: [...lastMessage.content.slice(0, -1), { ...lastPart, text: lastPart.text + chunk.payload.text }]
9574
- }
9575
- ];
9576
- }
9577
- case "tool-output": {
9578
- if (chunk.payload.output?.type.startsWith("workflow-")) {
9579
- return handleWorkflowChunk({
9580
- workflowChunk: chunk.payload.output,
9581
- conversation,
9582
- entityName: chunk.payload.toolName
9583
- });
9584
- }
9585
- const lastMessage = conversation[conversation.length - 1];
9586
- if (lastMessage && lastMessage.role === "assistant" && Array.isArray(lastMessage.content)) {
9587
- const updatedContent = lastMessage.content.map((part) => {
9588
- if (typeof part === "object" && part.type === "tool-call" && part.toolCallId === chunk.payload.toolCallId) {
9589
- const existingToolOutput = part.args?.__mastraMetadata?.toolOutput || [];
9590
- return {
9591
- ...part,
9592
- args: {
9593
- ...part.args,
9594
- __mastraMetadata: {
9595
- ...part.args?.__mastraMetadata,
9596
- toolOutput: [...existingToolOutput, chunk?.payload?.output]
9597
- }
9598
- }
9599
- };
9600
- }
9601
- return part;
9602
- });
9603
- const updatedMessage = {
9604
- ...lastMessage,
9605
- content: updatedContent
9606
- };
9607
- return [...conversation.slice(0, -1), updatedMessage];
9608
- }
9609
- return [...conversation];
9610
- }
9611
- case "tool-call": {
9612
- const lastMessage = conversation[conversation.length - 1];
9613
- if (lastMessage && lastMessage.role === "assistant") {
9614
- const updatedMessage = {
9615
- ...lastMessage,
9616
- content: Array.isArray(lastMessage.content) ? [
9617
- ...lastMessage.content,
9618
- {
9619
- type: "tool-call",
9620
- toolCallId: chunk.payload.toolCallId,
9621
- toolName: chunk.payload.toolName,
9622
- args: {
9623
- ...chunk.payload.args,
9624
- __mastraMetadata: {
9625
- ...chunk.payload.args?.__mastraMetadata,
9626
- isStreaming: true
9627
- }
9628
- }
9629
- }
9630
- ] : [
9631
- ...typeof lastMessage.content === "string" ? [{ type: "text", text: lastMessage.content }] : [],
9632
- {
9633
- type: "tool-call",
9634
- toolCallId: chunk.payload.toolCallId,
9635
- toolName: chunk.payload.toolName,
9636
- args: {
9637
- ...chunk.payload.args,
9638
- __mastraMetadata: {
9639
- ...chunk.payload.args?.__mastraMetadata,
9640
- isStreaming: true
9641
- }
9642
- }
9643
- }
9644
- ]
9645
- };
9646
- return [...conversation.slice(0, -1), updatedMessage];
9647
- }
9648
- const newMessage = {
9649
- role: "assistant",
9650
- content: [
9651
- {
9652
- type: "tool-call",
9653
- toolCallId: chunk.payload.toolCallId,
9654
- toolName: chunk.payload.toolName,
9655
- args: {
9656
- ...chunk.payload.args,
9657
- __mastraMetadata: {
9658
- ...chunk.payload.args?.__mastraMetadata,
9659
- isStreaming: true
9660
- }
9661
- }
9662
- }
9663
- ]
9664
- };
9665
- return [...conversation, newMessage];
9666
- }
9667
- case "tool-result": {
9668
- const lastMessage = conversation[conversation.length - 1];
9669
- if (lastMessage && lastMessage.role === "assistant" && Array.isArray(lastMessage.content)) {
9670
- const updatedContent = lastMessage.content.map((part) => {
9671
- if (typeof part === "object" && part.type === "tool-call" && part.toolCallId === chunk.payload.toolCallId) {
9672
- return {
9673
- ...part,
9674
- result: chunk.payload.result
9675
- };
9676
- }
9677
- return part;
9678
- });
9679
- const updatedMessage = {
9680
- ...lastMessage,
9681
- content: updatedContent
9682
- };
9683
- return [...conversation.slice(0, -1), updatedMessage];
9684
- }
9685
- return [...conversation];
9686
- }
9687
- case "error": {
9688
- if (typeof chunk.payload.error === "string") {
9689
- const errorMessage = {
9690
- role: "assistant",
9691
- content: `Error: ${chunk.payload.error}`
9692
- };
9693
- return [...conversation, errorMessage];
9694
- }
9695
- return [...conversation];
9696
- }
9697
- case "finish": {
9698
- const lastMessage = conversation[conversation.length - 1];
9699
- handleFinishReason$1(chunk.payload.stepResult.reason);
9700
- if (lastMessage && lastMessage.role === "assistant") {
9701
- const updatedMessage = {
9702
- ...lastMessage,
9703
- metadata: {
9704
- custom: {
9705
- modelMetadata: chunk.payload.metadata.modelMetadata
9706
- }
9707
- }
9708
- };
9709
- return [...conversation.slice(0, -1), updatedMessage];
9710
- }
9711
- return [...conversation];
9712
- }
9713
- case "reasoning-delta": {
9714
- const lastMessage = conversation[conversation.length - 1];
9715
- if (lastMessage && lastMessage.role === "assistant" && Array.isArray(lastMessage.content)) {
9716
- const updatedContent = lastMessage.content.map((part) => {
9717
- if (typeof part === "object" && part.type === "reasoning") {
9718
- return {
9719
- ...part,
9720
- text: part.text + chunk.payload.text
9721
- };
9722
- }
9723
- return part;
9724
- });
9725
- const updatedMessage = {
9726
- ...lastMessage,
9727
- content: updatedContent
9728
- };
9729
- return [...conversation.slice(0, -1), updatedMessage];
9730
- }
9731
- const newMessage = {
9732
- role: "assistant",
9733
- content: [
9734
- {
9735
- type: "reasoning",
9736
- text: chunk.payload.text
9737
- }
9738
- ]
9739
- };
9740
- return [...conversation, newMessage];
9741
- }
9742
- default:
9743
- return [...conversation];
9744
- }
9745
- };
9746
- const handleFinishReason$1 = (finishReason) => {
9747
- switch (finishReason) {
9748
- case "tool-calls":
9749
- throw new Error("Stream finished with reason tool-calls, try increasing maxSteps");
9750
- }
9751
- };
9752
- const handleWorkflowChunk = ({
9753
- workflowChunk,
9754
- conversation,
9755
- entityName
9756
- }) => {
9757
- const lastMessage = conversation[conversation.length - 1];
9758
- const contentArray = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
9759
- const newMessage = {
9760
- ...lastMessage,
9761
- content: contentArray.map((part) => {
9762
- if (part.type === "tool-call") {
9763
- return {
9764
- ...part,
9765
- toolName: part?.entityName || entityName,
9766
- args: {
9767
- ...part.args,
9768
- __mastraMetadata: {
9769
- ...part.args?.__mastraMetadata,
9770
- workflowFullState: mapWorkflowStreamChunkToWatchResult(
9771
- part.args?.__mastraMetadata?.workflowFullState || {},
9772
- workflowChunk
9773
- ),
9774
- isStreaming: true
9775
- }
9776
- }
9777
- };
9778
- }
9779
- return part;
9780
- })
9781
- };
9782
- return [...conversation.slice(0, -1), newMessage];
9783
- };
9784
- const handleAgentChunk = ({
9785
- agentChunk,
9786
- conversation,
9787
- entityName
9788
- }) => {
9789
- switch (agentChunk.type) {
9790
- case "tool-result": {
9791
- const lastMessage = conversation[conversation.length - 1];
9792
- const contentArray = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
9793
- const newMessage = {
9794
- ...lastMessage,
9795
- content: contentArray.map((part) => {
9796
- if (part.type === "tool-call") {
9797
- const messages = part.args?.__mastraMetadata?.messages || [];
9798
- const next = {
9799
- ...part,
9800
- toolName: part?.entityName || entityName,
9801
- args: {
9802
- ...part.args,
9803
- __mastraMetadata: {
9804
- ...part.args?.__mastraMetadata,
9805
- isStreaming: true,
9806
- messages: [
9807
- ...messages.slice(0, -1),
9808
- {
9809
- ...messages[messages.length - 1],
9810
- type: "tool",
9811
- toolName: agentChunk.payload.toolName,
9812
- args: agentChunk.payload.args,
9813
- toolOutput: agentChunk.payload.result
9814
- }
9815
- ]
9816
- }
9817
- }
9818
- };
9819
- return next;
9820
- }
9821
- return part;
9822
- })
9823
- };
9824
- return [...conversation.slice(0, -1), newMessage];
9825
- }
9826
- case "tool-call": {
9827
- const lastMessage = conversation[conversation.length - 1];
9828
- const contentArray = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
9829
- const newMessage = {
9830
- ...lastMessage,
9831
- content: contentArray.map((part) => {
9832
- if (part.type === "tool-call") {
9833
- const messages = part.args?.__mastraMetadata?.messages || [];
9834
- const next = {
9835
- ...part,
9836
- toolName: part?.entityName || entityName,
9837
- args: {
9838
- ...part.args,
9839
- __mastraMetadata: {
9840
- ...part.args?.__mastraMetadata,
9841
- isStreaming: true,
9842
- messages: [
9843
- ...messages,
9844
- {
9845
- type: "tool",
9846
- toolCallId: agentChunk.payload.toolCallId,
9847
- toolName: agentChunk.payload.toolName,
9848
- args: {
9849
- ...agentChunk.payload.args,
9850
- __mastraMetadata: {
9851
- ...agentChunk.payload.args?.__mastraMetadata,
9852
- isStreaming: true
9853
- }
9854
- }
9855
- }
9856
- ]
9857
- }
9858
- }
9859
- };
9860
- return next;
9861
- }
9862
- return part;
9863
- })
9864
- };
9865
- return [...conversation.slice(0, -1), newMessage];
9866
- }
9867
- case "text-delta": {
9868
- const lastMessage = conversation[conversation.length - 1];
9869
- const contentArray = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
9870
- const newMessage = {
9871
- ...lastMessage,
9872
- content: contentArray.map((part) => {
9873
- if (part.type === "tool-call") {
9874
- const messages = part.args?.__mastraMetadata?.messages || [];
9875
- const lastMastraMessage = messages[messages.length - 1];
9876
- const nextMessages = lastMastraMessage?.type === "text" ? [
9877
- ...messages.slice(0, -1),
9878
- { type: "text", content: (lastMastraMessage?.content || "") + agentChunk.payload.text }
9879
- ] : [...messages, { type: "text", content: agentChunk.payload.text }];
9880
- return {
9881
- ...part,
9882
- toolName: part?.entityName || entityName,
9883
- args: {
9884
- ...part.args,
9885
- __mastraMetadata: {
9886
- ...part.args?.__mastraMetadata,
9887
- isStreaming: true,
9888
- messages: nextMessages
9889
- }
9890
- }
9891
- };
9892
- }
9893
- return part;
9894
- })
9895
- };
9896
- return [...conversation.slice(0, -1), newMessage];
9897
- }
9898
- case "tool-output": {
9899
- if (!agentChunk.payload.output.type.startsWith("workflow-")) return [...conversation];
9900
- const lastMessage = conversation[conversation.length - 1];
9901
- const contentArray = Array.isArray(lastMessage.content) ? lastMessage.content : [{ type: "text", text: lastMessage.content }];
9902
- const newMessage = {
9903
- ...lastMessage,
9904
- content: contentArray.map((part) => {
9905
- if (part.type === "tool-call") {
9906
- const messages = part.args?.__mastraMetadata?.messages || [];
9907
- const lastMastraMessage = messages[messages.length - 1];
9908
- const nextMessages = lastMastraMessage?.type === "tool" ? [
9909
- ...messages.slice(0, -1),
9910
- {
9911
- ...lastMastraMessage,
9912
- args: {
9913
- ...agentChunk.payload.args,
9914
- __mastraMetadata: {
9915
- ...agentChunk.payload.args?.__mastraMetadata,
9916
- workflowFullState: mapWorkflowStreamChunkToWatchResult(
9917
- lastMastraMessage.args?.__mastraMetadata?.workflowFullState || {},
9918
- agentChunk.payload.output
9919
- ),
9920
- isStreaming: true
9921
- }
9922
- }
9923
- }
9924
- ] : messages;
9925
- return {
9926
- ...part,
9927
- toolName: part?.entityName || entityName,
9928
- args: {
9929
- ...part.args,
9930
- __mastraMetadata: {
9931
- ...part.args?.__mastraMetadata,
9932
- isStreaming: true,
9933
- messages: nextMessages
9934
- }
9935
- }
9936
- };
9937
- }
9938
- return part;
9939
- })
9940
- };
9941
- return [...conversation.slice(0, -1), newMessage];
9942
- }
9943
- default:
9944
- case "agent-execution-end":
9945
- return [...conversation];
9946
- }
9947
- };
9948
- const createRootToolAssistantMessage = ({
9949
- chunk,
9950
- entityName,
9951
- conversation,
9952
- runId,
9953
- from,
9954
- networkMetadata
9955
- }) => {
9956
- if (!entityName || !runId) return [...conversation];
9957
- const newMessage = {
9958
- role: "assistant",
9959
- content: [
9960
- {
9961
- type: "tool-call",
9962
- toolCallId: runId,
9963
- toolName: entityName,
9964
- args: {
9965
- ...chunk?.payload?.args,
9966
- __mastraMetadata: {
9967
- from,
9968
- networkMetadata,
9969
- ...chunk.payload.args?.__mastraMetadata,
9970
- isStreaming: true
9971
- }
9972
- }
9973
- }
9974
- ]
9975
- };
9976
- return [...conversation, newMessage];
9977
- };
9978
-
9979
- const handleFinishReason = (finishReason) => {
9980
- switch (finishReason) {
9981
- case "tool-calls":
9982
- throw new Error("Stream finished with reason tool-calls, try increasing maxSteps");
9983
- }
9984
- };
9985
- const convertToAIAttachments = async (attachments) => {
9986
- const promises = (attachments ?? []).filter((attachment) => attachment.type === "image" || attachment.type === "document").map(async (attachment) => {
9987
- const isFileFromURL = attachment.name.startsWith("https://");
9988
- if (attachment.type === "document") {
9989
- if (attachment.contentType === "application/pdf") {
9990
- const pdfText = attachment.content?.[0]?.text || "";
9991
- return {
9992
- role: "user",
9993
- content: [
9994
- {
9995
- type: "file",
9996
- data: isFileFromURL ? attachment.name : `data:application/pdf;base64,${pdfText}`,
9997
- mimeType: attachment.contentType,
9998
- filename: attachment.name
9999
- }
10000
- ]
10001
- };
10002
- }
10003
- return {
10004
- role: "user",
10005
- // @ts-expect-error - TODO: fix this type issue somehow
10006
- content: attachment.content[0]?.text || ""
10007
- };
10008
- }
10009
- return {
10010
- role: "user",
10011
- content: [
10012
- {
10013
- type: "image",
10014
- image: isFileFromURL ? attachment.name : await fileToBase64(attachment.file),
10015
- mimeType: attachment.file.type
10016
- }
10017
- ]
10018
- };
10019
- });
10020
- return Promise.all(promises);
10021
- };
10022
- const initializeMessageState = (initialMessages) => {
10023
- const convertedMessages = initialMessages?.map((message) => {
10024
- let content;
10025
- try {
10026
- content = JSON.parse(message.content);
10027
- if (content.isNetwork) {
10028
- return handleNetworkMessageFromMemory(content);
10029
- }
10030
- } catch (e) {
10031
- }
10032
- const attachmentsAsContentParts = (message.experimental_attachments || []).map((image) => ({
10033
- type: image.contentType.startsWith(`image/`) ? "image" : image.contentType.startsWith(`audio/`) ? "audio" : "file",
10034
- mimeType: image.contentType,
10035
- image: image.url
10036
- }));
10037
- const formattedParts = (message.parts || []).map((part) => {
10038
- if (part.type === "reasoning") {
10039
- return {
10040
- type: "reasoning",
10041
- text: part.reasoning || part?.details?.filter((detail) => detail.type === "text")?.map((detail) => detail.text).join(" ")
10042
- };
10043
- }
10044
- if (part.type === "tool-invocation") {
10045
- if (part.toolInvocation.state === "result") {
10046
- return {
10047
- type: "tool-call",
10048
- toolCallId: part.toolInvocation.toolCallId,
10049
- toolName: part.toolInvocation.toolName,
10050
- args: part.toolInvocation.args,
10051
- result: part.toolInvocation.result
10052
- };
9505
+ if (part.type === "tool-invocation") {
9506
+ if (part.toolInvocation.state === "result") {
9507
+ return {
9508
+ type: "tool-call",
9509
+ toolCallId: part.toolInvocation.toolCallId,
9510
+ toolName: part.toolInvocation.toolName,
9511
+ args: part.toolInvocation.args,
9512
+ result: part.toolInvocation.result
9513
+ };
10053
9514
  }
10054
9515
  }
10055
9516
  if (part.type === "file") {
@@ -10077,6 +9538,7 @@ function MastraRuntimeProvider({
10077
9538
  children,
10078
9539
  agentId,
10079
9540
  initialMessages,
9541
+ initialLegacyMessages,
10080
9542
  memory,
10081
9543
  threadId,
10082
9544
  refreshThreadList,
@@ -10084,20 +9546,19 @@ function MastraRuntimeProvider({
10084
9546
  runtimeContext,
10085
9547
  modelVersion
10086
9548
  }) {
10087
- const initializeMessages = () => memory ? initializeMessageState(initialMessages || []) : [];
10088
9549
  const [isLegacyRunning, setIsLegacyRunning] = useState(false);
10089
- const [legacyMessages, setLegacyMessages] = useState(initializeMessages());
9550
+ const [legacyMessages, setLegacyMessages] = useState(
9551
+ () => memory ? initializeMessageState(initialLegacyMessages || []) : []
9552
+ );
10090
9553
  const {
10091
- setMessages,
10092
9554
  messages,
10093
- generate,
10094
- stream,
10095
- network,
9555
+ sendMessage,
10096
9556
  cancelRun,
10097
- isRunning: isRunningStream
9557
+ isRunning: isRunningStream,
9558
+ setMessages
10098
9559
  } = useChat({
10099
9560
  agentId,
10100
- initializeMessages
9561
+ initializeMessages: () => initialMessages || []
10101
9562
  });
10102
9563
  const { refetch: refreshWorkingMemory } = useWorkingMemory();
10103
9564
  const abortControllerRef = useRef(null);
@@ -10130,7 +9591,8 @@ function MastraRuntimeProvider({
10130
9591
  topP,
10131
9592
  maxTokens,
10132
9593
  instructions,
10133
- providerOptions
9594
+ providerOptions,
9595
+ maxSteps
10134
9596
  };
10135
9597
  const baseClient = useMastraClient();
10136
9598
  const isVNext = modelVersion === "v2";
@@ -10138,9 +9600,7 @@ function MastraRuntimeProvider({
10138
9600
  if (message.content[0]?.type !== "text") throw new Error("Only text messages are supported");
10139
9601
  const attachments = await convertToAIAttachments(message.attachments);
10140
9602
  const input = message.content[0].text;
10141
- if (isVNext) {
10142
- setMessages((s) => [...s, { role: "user", content: input, attachments: message.attachments }]);
10143
- } else {
9603
+ if (!isVNext) {
10144
9604
  setLegacyMessages((s) => [...s, { role: "user", content: input, attachments: message.attachments }]);
10145
9605
  }
10146
9606
  const controller = new AbortController();
@@ -10153,134 +9613,44 @@ function MastraRuntimeProvider({
10153
9613
  try {
10154
9614
  if (isVNext) {
10155
9615
  if (chatWithNetwork) {
10156
- let currentEntityId;
10157
- await network({
10158
- coreUserMessages: [
10159
- {
10160
- role: "user",
10161
- content: input
10162
- },
10163
- ...attachments
10164
- ],
9616
+ await sendMessage({
9617
+ message: input,
9618
+ mode: "network",
9619
+ coreUserMessages: attachments,
10165
9620
  runtimeContext: runtimeContextInstance,
10166
9621
  threadId,
10167
9622
  modelSettings: modelSettingsArgs,
10168
9623
  signal: controller.signal,
10169
- onNetworkChunk: (chunk, conversation) => {
10170
- if (chunk.type.startsWith("agent-execution-event-")) {
10171
- const agentChunk = chunk.payload;
10172
- if (!currentEntityId) return conversation;
10173
- return handleAgentChunk({ agentChunk, conversation, entityName: currentEntityId });
10174
- } else if (chunk.type === "tool-execution-start") {
10175
- const { args: argsData } = chunk.payload;
10176
- const nestedArgs = argsData.args || {};
10177
- const mastraMetadata = argsData.__mastraMetadata || {};
10178
- const selectionReason = argsData.selectionReason || "";
10179
- return handleStreamChunk({
10180
- chunk: {
10181
- ...chunk,
10182
- type: "tool-call",
10183
- payload: {
10184
- ...chunk.payload,
10185
- toolCallId: argsData.toolCallId || "unknown",
10186
- toolName: argsData.toolName || "unknown",
10187
- args: {
10188
- ...nestedArgs,
10189
- __mastraMetadata: {
10190
- ...mastraMetadata,
10191
- networkMetadata: {
10192
- selectionReason,
10193
- input: nestedArgs
10194
- }
10195
- }
10196
- }
10197
- }
10198
- },
10199
- conversation
10200
- });
10201
- } else if (chunk.type === "tool-execution-end") {
10202
- const next = handleStreamChunk({
10203
- chunk: { ...chunk, type: "tool-result" },
10204
- conversation
10205
- });
10206
- if (chunk.payload?.toolName === "updateWorkingMemory" && typeof chunk.payload.result === "object" && "success" in chunk.payload.result && chunk.payload.result?.success) {
10207
- refreshWorkingMemory?.();
10208
- }
10209
- return next;
10210
- } else if (chunk.type.startsWith("workflow-execution-event-")) {
10211
- const workflowChunk = chunk.payload;
10212
- if (!currentEntityId) return conversation;
10213
- return handleWorkflowChunk({ workflowChunk, conversation, entityName: currentEntityId });
10214
- } else if (chunk.type === "workflow-execution-start" || chunk.type === "agent-execution-start") {
10215
- currentEntityId = chunk.payload?.args?.primitiveId;
10216
- const runId = chunk.payload.runId;
10217
- if (!currentEntityId || !runId) return conversation;
10218
- return createRootToolAssistantMessage({
10219
- entityName: currentEntityId,
10220
- conversation,
10221
- runId,
10222
- chunk,
10223
- from: chunk.type === "agent-execution-start" ? "AGENT" : "WORKFLOW",
10224
- networkMetadata: {
10225
- selectionReason: chunk?.payload?.args?.selectionReason || "",
10226
- input: chunk?.payload?.args?.prompt
10227
- }
10228
- });
10229
- } else if (chunk.type === "network-execution-event-step-finish") {
10230
- return [
10231
- ...conversation,
10232
- { role: "assistant", content: [{ type: "text", text: chunk?.payload?.result || "" }] }
10233
- ];
10234
- } else {
10235
- return handleStreamChunk({ chunk, conversation });
9624
+ onNetworkChunk: async (chunk) => {
9625
+ if (chunk.type === "tool-execution-end" && chunk.payload?.toolName === "updateWorkingMemory" && typeof chunk.payload.result === "object" && "success" in chunk.payload.result && chunk.payload.result?.success) {
9626
+ refreshWorkingMemory?.();
10236
9627
  }
10237
9628
  }
10238
9629
  });
10239
9630
  } else {
10240
9631
  if (chatWithGenerate) {
10241
- await generate({
10242
- coreUserMessages: [
10243
- {
10244
- role: "user",
10245
- content: input
10246
- },
10247
- ...attachments
10248
- ],
9632
+ await sendMessage({
9633
+ message: input,
9634
+ mode: "generate",
9635
+ coreUserMessages: attachments,
10249
9636
  runtimeContext: runtimeContextInstance,
10250
9637
  threadId,
10251
9638
  modelSettings: modelSettingsArgs,
10252
- signal: controller.signal,
10253
- onFinish: ({ messages: messages2, tripwireReason }) => {
10254
- const next = messages2.length > 0 ? messages2.map((message2) => toAssistantUIMessage(message2)) : [];
10255
- if (tripwireReason) {
10256
- next.push({
10257
- role: "assistant",
10258
- content: [{ type: "text", text: tripwireReason }],
10259
- metadata: { custom: { status: "warning" } }
10260
- });
10261
- }
10262
- return next;
10263
- }
9639
+ signal: controller.signal
10264
9640
  });
10265
9641
  return;
10266
9642
  } else {
10267
- await stream({
10268
- coreUserMessages: [
10269
- {
10270
- role: "user",
10271
- content: input
10272
- },
10273
- ...attachments
10274
- ],
9643
+ await sendMessage({
9644
+ message: input,
9645
+ mode: "stream",
9646
+ coreUserMessages: attachments,
10275
9647
  runtimeContext: runtimeContextInstance,
10276
9648
  threadId,
10277
9649
  modelSettings: modelSettingsArgs,
10278
- onChunk: (chunk, conversation) => {
10279
- const next = handleStreamChunk({ chunk, conversation });
9650
+ onChunk: async (chunk) => {
10280
9651
  if (chunk.type === "tool-result" && chunk.payload?.toolName === "updateWorkingMemory" && typeof chunk.payload.result === "object" && "success" in chunk.payload.result && chunk.payload.result?.success) {
10281
9652
  refreshWorkingMemory?.();
10282
9653
  }
10283
- return next;
10284
9654
  },
10285
9655
  signal: controller.signal
10286
9656
  });
@@ -10575,7 +9945,7 @@ function MastraRuntimeProvider({
10575
9945
  if (isVNext) {
10576
9946
  setMessages((currentConversation) => [
10577
9947
  ...currentConversation,
10578
- { role: "assistant", content: [{ type: "text", text: `${error}` }] }
9948
+ { role: "assistant", parts: [{ type: "text", text: `${error}` }] }
10579
9949
  ]);
10580
9950
  } else {
10581
9951
  setLegacyMessages((currentConversation) => [
@@ -10596,20 +9966,17 @@ function MastraRuntimeProvider({
10596
9966
  }
10597
9967
  };
10598
9968
  const { adapters, isReady } = useAdapters(agentId);
9969
+ const vnextmessages = messages.map(toAssistantUIMessage);
10599
9970
  const runtime = useExternalStoreRuntime({
10600
9971
  isRunning: isLegacyRunning || isRunningStream,
10601
- messages: isVNext ? messages : legacyMessages,
9972
+ messages: isVNext ? vnextmessages : legacyMessages,
10602
9973
  convertMessage: (x) => x,
10603
9974
  onNew,
10604
9975
  onCancel,
10605
9976
  adapters: isReady ? adapters : void 0
10606
9977
  });
10607
9978
  if (!isReady) return null;
10608
- return /* @__PURE__ */ jsxs(AssistantRuntimeProvider, { runtime, children: [
10609
- " ",
10610
- children,
10611
- " "
10612
- ] });
9979
+ return /* @__PURE__ */ jsx(AssistantRuntimeProvider, { runtime, children });
10613
9980
  }
10614
9981
 
10615
9982
  const defaultSettings = {
@@ -10677,6 +10044,7 @@ const AgentChat = ({
10677
10044
  agentName,
10678
10045
  threadId,
10679
10046
  initialMessages,
10047
+ initialLegacyMessages,
10680
10048
  memory,
10681
10049
  refreshThreadList,
10682
10050
  modelVersion,
@@ -10692,6 +10060,7 @@ const AgentChat = ({
10692
10060
  modelVersion,
10693
10061
  threadId,
10694
10062
  initialMessages,
10063
+ initialLegacyMessages,
10695
10064
  memory,
10696
10065
  refreshThreadList,
10697
10066
  settings,
@@ -10812,7 +10181,7 @@ const TableCaption = React.forwardRef(
10812
10181
  );
10813
10182
  TableCaption.displayName = "TableCaption";
10814
10183
 
10815
- const Tabs = TabsPrimitive.Root;
10184
+ const Tabs$1 = TabsPrimitive.Root;
10816
10185
  const TabsList = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
10817
10186
  TabsPrimitive.List,
10818
10187
  {
@@ -10855,12 +10224,12 @@ const PlaygroundTabs = ({
10855
10224
  setInternalTab(typedValue);
10856
10225
  }
10857
10226
  };
10858
- return /* @__PURE__ */ jsx(Tabs, { value: currentTab, onValueChange: handleTabChange, className: cn("h-full", className), children });
10227
+ return /* @__PURE__ */ jsx(Tabs$1, { value: currentTab, onValueChange: handleTabChange, className: cn("h-full", className), children });
10859
10228
  };
10860
- const TabList = ({ children, className }) => {
10229
+ const TabList$1 = ({ children, className }) => {
10861
10230
  return /* @__PURE__ */ jsx("div", { className: cn("w-full overflow-x-auto", className), children: /* @__PURE__ */ jsx(TabsList, { className: "border-b border-border1 flex min-w-full shrink-0", children }) });
10862
10231
  };
10863
- const Tab = ({ children, value, onClick }) => {
10232
+ const Tab$1 = ({ children, value, onClick }) => {
10864
10233
  return /* @__PURE__ */ jsx(
10865
10234
  TabsTrigger,
10866
10235
  {
@@ -10871,7 +10240,7 @@ const Tab = ({ children, value, onClick }) => {
10871
10240
  }
10872
10241
  );
10873
10242
  };
10874
- const TabContent = ({ children, value }) => {
10243
+ const TabContent$1 = ({ children, value }) => {
10875
10244
  return /* @__PURE__ */ jsx(TabsContent, { value, className: "h-full overflow-hidden flex flex-col", children });
10876
10245
  };
10877
10246
 
@@ -10896,12 +10265,12 @@ function AgentEvals({ liveEvals, ciEvals, onRefetchLiveEvals, onRefetchCiEvals }
10896
10265
  return onRefetchCiEvals();
10897
10266
  }
10898
10267
  return /* @__PURE__ */ jsxs(PlaygroundTabs, { defaultTab: "live", children: [
10899
- /* @__PURE__ */ jsxs(TabList, { children: [
10900
- /* @__PURE__ */ jsx(Tab, { value: "live", children: "Live" }),
10901
- /* @__PURE__ */ jsx(Tab, { value: "ci", children: "CI" })
10268
+ /* @__PURE__ */ jsxs(TabList$1, { children: [
10269
+ /* @__PURE__ */ jsx(Tab$1, { value: "live", children: "Live" }),
10270
+ /* @__PURE__ */ jsx(Tab$1, { value: "ci", children: "CI" })
10902
10271
  ] }),
10903
- /* @__PURE__ */ jsx(TabContent, { value: "live", children: /* @__PURE__ */ jsx(EvalTable, { evals: liveEvals, isCIMode: false, onRefresh: handleRefresh }) }),
10904
- /* @__PURE__ */ jsx(TabContent, { value: "ci", children: /* @__PURE__ */ jsx(EvalTable, { evals: ciEvals, isCIMode: true, onRefresh: handleRefresh }) })
10272
+ /* @__PURE__ */ jsx(TabContent$1, { value: "live", children: /* @__PURE__ */ jsx(EvalTable, { evals: liveEvals, isCIMode: false, onRefresh: handleRefresh }) }),
10273
+ /* @__PURE__ */ jsx(TabContent$1, { value: "ci", children: /* @__PURE__ */ jsx(EvalTable, { evals: ciEvals, isCIMode: true, onRefresh: handleRefresh }) })
10905
10274
  ] });
10906
10275
  }
10907
10276
  function EvalTable({ evals, isCIMode = false, onRefresh }) {
@@ -11450,13 +10819,35 @@ const AgentSettings = ({ modelVersion, hasMemory = false, hasSubAgents = false }
11450
10819
  ] });
11451
10820
  };
11452
10821
 
10822
+ const resolveInstructionPart = (part) => {
10823
+ if (typeof part === "string") {
10824
+ return part.trim();
10825
+ }
10826
+ return part.text?.trim() || "";
10827
+ };
10828
+ const extractPrompt = (instructions) => {
10829
+ if (typeof instructions === "string") {
10830
+ return instructions.trim();
10831
+ }
10832
+ if (typeof instructions === "object" && "content" in instructions) {
10833
+ if (Array.isArray(instructions.content)) {
10834
+ return instructions.content.map(resolveInstructionPart).join("\n\n").trim();
10835
+ }
10836
+ return instructions.content.trim();
10837
+ }
10838
+ if (Array.isArray(instructions)) {
10839
+ return instructions.map(extractPrompt).join("\n\n").trim();
10840
+ }
10841
+ return "";
10842
+ };
10843
+
11453
10844
  const NameCell$3 = ({ row }) => {
11454
10845
  const { Link, paths } = useLinkComponent();
11455
10846
  return /* @__PURE__ */ jsx(
11456
10847
  EntryCell,
11457
10848
  {
11458
10849
  name: /* @__PURE__ */ jsx(Link, { className: "w-full space-y-0", href: paths.agentLink(row.original.id), children: row.original.name }),
11459
- description: row.original.instructions
10850
+ description: extractPrompt(row.original.instructions)
11460
10851
  }
11461
10852
  );
11462
10853
  };
@@ -11551,7 +10942,7 @@ function AgentsTable({ agents, isLoading }) {
11551
10942
  return /* @__PURE__ */ jsx(EmptyAgentsTable, {});
11552
10943
  }
11553
10944
  const filteredRows = rows.filter((row) => row.original.name.toLowerCase().includes(search.toLowerCase()));
11554
- return /* @__PURE__ */ jsxs(Fragment, { children: [
10945
+ return /* @__PURE__ */ jsxs("div", { children: [
11555
10946
  /* @__PURE__ */ jsx(SearchbarWrapper, { children: /* @__PURE__ */ jsx(Searchbar, { onSearch: setSearch, label: "Search agents", placeholder: "Search agents" }) }),
11556
10947
  isLoading ? /* @__PURE__ */ jsx(AgentsTableSkeleton, {}) : /* @__PURE__ */ jsx(ScrollableContainer, { children: /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Table$1, { children: [
11557
10948
  /* @__PURE__ */ jsx(Thead, { className: "sticky top-0", children: ths.headers.map((header) => /* @__PURE__ */ jsx(Th, { style: { width: header.column.getSize() ?? "auto" }, children: flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }),
@@ -12175,36 +11566,8 @@ function RelationWrapper({ description, children }) {
12175
11566
  ] }) : children;
12176
11567
  }
12177
11568
 
12178
- function EntryListTextCell({ children, isLoading }) {
12179
- const [randomWidth, setRandomWidth] = useState(void 0);
12180
- useEffect(() => {
12181
- setRandomWidth(Math.floor(Math.random() * (90 - 50 + 1)) + 50);
12182
- }, []);
12183
- if (!randomWidth) return null;
12184
- return /* @__PURE__ */ jsx("div", { className: "text-icon4 text-[0.875rem] truncate ", children: isLoading ? /* @__PURE__ */ jsx(
12185
- "div",
12186
- {
12187
- className: "bg-surface4 rounded-md animate-pulse text-transparent h-[1rem] select-none",
12188
- style: { width: `${randomWidth}%` }
12189
- }
12190
- ) : children });
12191
- }
12192
- function EntryListStatusCell({ status }) {
12193
- return /* @__PURE__ */ jsxs("div", { className: cn("flex justify-center items-center w-full relative"), children: [
12194
- status ? /* @__PURE__ */ jsx(
12195
- "div",
12196
- {
12197
- className: cn("w-[0.6rem] h-[0.6rem] rounded-full", {
12198
- "bg-green-600": status === "success",
12199
- "bg-red-700": status === "failed"
12200
- })
12201
- }
12202
- ) : /* @__PURE__ */ jsx("div", { className: "text-icon2 text-[0.75rem] leading-none", children: "-" }),
12203
- /* @__PURE__ */ jsxs(VisuallyHidden$1, { children: [
12204
- "Status: ",
12205
- status ? status : "not provided"
12206
- ] })
12207
- ] });
11569
+ function EntryListRoot({ children }) {
11570
+ return /* @__PURE__ */ jsx("div", { className: "grid", children });
12208
11571
  }
12209
11572
 
12210
11573
  function getColumnTemplate(columns) {
@@ -12216,33 +11579,53 @@ function getColumnTemplate(columns) {
12216
11579
  }).join(" ");
12217
11580
  }
12218
11581
 
12219
- function EntryListItem({
12220
- item,
12221
- selectedItemId,
12222
- onClick,
12223
- children,
12224
- columns,
12225
- isLoading
12226
- }) {
12227
- const isSelected = selectedItemId === item.id;
11582
+ function EntryListHeader({ columns }) {
11583
+ return /* @__PURE__ */ jsx("div", { className: cn("sticky top-0 bg-surface4 z-[1] rounded-t-lg px-[1.5rem]"), children: /* @__PURE__ */ jsx(
11584
+ "div",
11585
+ {
11586
+ className: cn("grid gap-[1.5rem] text-left uppercase py-[.75rem] text-icon3 text-[0.75rem]"),
11587
+ style: { gridTemplateColumns: getColumnTemplate(columns) },
11588
+ children: columns?.map((col) => /* @__PURE__ */ jsx("span", { children: col.label || col.name }, col.name))
11589
+ }
11590
+ ) });
11591
+ }
11592
+
11593
+ function EntryListEntries({ children }) {
11594
+ return /* @__PURE__ */ jsx("ul", { className: "grid bg-surface3 overflow-y-auto", children });
11595
+ }
11596
+
11597
+ function EntryListTrim({ children }) {
11598
+ return /* @__PURE__ */ jsx("div", { className: cn("rounded-lg border border-border1 overflow-clip"), children });
11599
+ }
11600
+
11601
+ function EntryListEntry({ entry, isSelected, onClick, children, columns }) {
12228
11602
  const handleClick = () => {
12229
- return onClick && onClick(item?.id);
11603
+ onClick?.(entry?.id);
12230
11604
  };
12231
11605
  return /* @__PURE__ */ jsx(
12232
11606
  "li",
12233
11607
  {
12234
- className: cn("border-b text-[#ccc] border-border1 last:border-b-0 text-[0.875rem]", {
12235
- "bg-surface5": isSelected
12236
- }),
12237
- children: /* @__PURE__ */ jsx(
11608
+ className: cn(
11609
+ "border-t text-[#ccc] border-border1 last:border-b-0 text-[0.875rem]",
11610
+ "[&:last-child>button]:rounded-b-lg",
11611
+ {
11612
+ "bg-surface5": isSelected
11613
+ }
11614
+ ),
11615
+ children: /* @__PURE__ */ jsx(
12238
11616
  "button",
12239
11617
  {
12240
11618
  onClick: handleClick,
12241
- className: cn("grid w-full px-[1.5rem] gap-[2rem] text-left items-center min-h-[3rem]", {
12242
- "hover:bg-surface5": !isLoading
12243
- }),
11619
+ className: cn(
11620
+ "grid w-full px-[1.5rem] gap-[1.5rem] text-left items-center min-h-[3rem]",
11621
+ "focus-visible:outline-none focus-visible:shadow-[inset_0_0_0_1px_rgba(24,251,111,.75)]",
11622
+ {
11623
+ // hover effect only not for skeleton and selected
11624
+ "hover:bg-surface4": entry && !isSelected
11625
+ }
11626
+ ),
12244
11627
  style: { gridTemplateColumns: getColumnTemplate(columns) },
12245
- disabled: isLoading,
11628
+ disabled: !entry,
12246
11629
  children
12247
11630
  }
12248
11631
  )
@@ -12250,178 +11633,180 @@ function EntryListItem({
12250
11633
  );
12251
11634
  }
12252
11635
 
12253
- function EntryList({
12254
- items: dataItems,
12255
- selectedItemId,
12256
- onItemClick,
11636
+ function EntryListMessage({ children, message, className, type }) {
11637
+ if (!children && !message) {
11638
+ return null;
11639
+ }
11640
+ return /* @__PURE__ */ jsx("div", { className: cn("grid border-t border-border1", className), children: message ? /* @__PURE__ */ jsxs(
11641
+ "p",
11642
+ {
11643
+ className: cn(
11644
+ "text-icon3 text-[0.875rem] text-center grid p-[2rem] justify-center justify-items-center gap-[.5rem]",
11645
+ "[&>svg]:w-[1.5em] [&>svg]:h-[1.5em] [&>svg]:opacity-75",
11646
+ {
11647
+ "[&>svg]:text-red-500": type === "error"
11648
+ }
11649
+ ),
11650
+ children: [
11651
+ type === "error" ? /* @__PURE__ */ jsx(TriangleAlertIcon, {}) : /* @__PURE__ */ jsx(InfoIcon$1, {}),
11652
+ " ",
11653
+ message
11654
+ ]
11655
+ }
11656
+ ) : children });
11657
+ }
11658
+
11659
+ function EntryListNextPageLoading({
12257
11660
  isLoading,
12258
- isLoadingNextPage,
12259
- total,
12260
- page,
12261
11661
  hasMore,
12262
- onNextPage,
12263
- onPrevPage,
12264
- perPage,
12265
- columns,
12266
- searchTerm,
12267
11662
  setEndOfListElement,
12268
- errorMsg
11663
+ loadingText = "Loading more data...",
11664
+ noMoreDataText = "No more data to load"
12269
11665
  }) {
12270
- const loadingItems = Array.from({ length: 3 }).map((_, index) => {
12271
- return {
12272
- id: `loading-${index + 1}`,
12273
- ...(columns || []).reduce(
12274
- (acc, col) => {
12275
- acc[col.name] = `...`;
12276
- return acc;
12277
- },
12278
- {}
12279
- )
12280
- };
12281
- });
12282
- const items = isLoading ? loadingItems : dataItems;
12283
- return /* @__PURE__ */ jsxs("div", { className: "grid mb-[3rem]", children: [
12284
- /* @__PURE__ */ jsx("div", { className: cn("sticky top-0 bg-surface4 z-[1] rounded-t-lg border border-border1 px-[1.5rem]"), children: /* @__PURE__ */ jsx(
11666
+ if (!setEndOfListElement) {
11667
+ return null;
11668
+ }
11669
+ return /* @__PURE__ */ jsxs("div", { ref: setEndOfListElement, className: "text-[0.875rem] text-icon3 opacity-50 flex mt-[2rem] justify-center", children: [
11670
+ isLoading && loadingText,
11671
+ !hasMore && !isLoading && noMoreDataText
11672
+ ] });
11673
+ }
11674
+
11675
+ function EntryListPagination({ currentPage, hasMore, onNextPage, onPrevPage }) {
11676
+ const showNavigation = typeof currentPage === "number" && currentPage > 0 || hasMore;
11677
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex pt-[1.5rem] items-center justify-center text-icon3 text-[0.875rem] gap-[2rem] "), children: [
11678
+ /* @__PURE__ */ jsxs("span", { children: [
11679
+ "Page ",
11680
+ /* @__PURE__ */ jsx("b", { children: currentPage ? currentPage + 1 : "1" })
11681
+ ] }),
11682
+ showNavigation && /* @__PURE__ */ jsxs(
12285
11683
  "div",
12286
- {
12287
- className: cn("grid gap-[2rem] text-left uppercase py-[.75rem] text-icon3 text-[0.75rem]"),
12288
- style: { gridTemplateColumns: getColumnTemplate(columns) },
12289
- children: columns?.map((col) => /* @__PURE__ */ jsx("span", { children: col.label || col.name }, col.name))
12290
- }
12291
- ) }),
12292
- errorMsg && !isLoading && /* @__PURE__ */ jsx("div", { className: "grid border border-border1 border-t-0 bg-surface3 rounded-xl rounded-t-none", children: /* @__PURE__ */ jsxs(
12293
- "p",
12294
11684
  {
12295
11685
  className: cn(
12296
- "text-[0.875rem] text-center items-center flex justify-center p-[2.5rem] gap-[1rem] text-icon3",
12297
- "[&>svg]:w-[1.5em]",
12298
- "[&>svg]:h-[1.5em]",
12299
- "[&>svg]:text-red-500"
11686
+ "flex gap-[1rem]",
11687
+ "[&>button]:flex [&>button]:items-center [&>button]:gap-[0.5rem] [&>button]:text-icon4 [&>button:hover]:text-icon5 [&>button]:transition-colors [&>button]:border [&>button]:border-border1 [&>button]:p-[0.25rem] [&>button]:px-[0.5rem] [&>button]:rounded-md",
11688
+ "[&_svg]:w-[1em] [&_svg]:h-[1em] [&_svg]:text-icon3"
12300
11689
  ),
12301
11690
  children: [
12302
- /* @__PURE__ */ jsx(TriangleAlertIcon, {}),
12303
- " ",
12304
- errorMsg || "Something went wrong while fetching the data."
11691
+ typeof currentPage === "number" && currentPage > 0 && /* @__PURE__ */ jsxs("button", { onClick: onPrevPage, children: [
11692
+ /* @__PURE__ */ jsx(ArrowLeftIcon, {}),
11693
+ "Previous"
11694
+ ] }),
11695
+ hasMore && /* @__PURE__ */ jsxs("button", { onClick: onNextPage, children: [
11696
+ "Next",
11697
+ /* @__PURE__ */ jsx(ArrowRightIcon, {})
11698
+ ] })
12305
11699
  ]
12306
11700
  }
12307
- ) }),
12308
- !isLoading && !errorMsg && items?.length === 0 && /* @__PURE__ */ jsx("div", { className: "grid border border-border1 border-t-0 bg-surface3 rounded-xl rounded-t-none", children: /* @__PURE__ */ jsx("p", { className: "text-icon3 text-[0.875rem] text-center h-[3.5rem] items-center flex justify-center", children: searchTerm ? `No results found for "${searchTerm}"` : "No entries found" }) }),
12309
- !errorMsg && items?.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
12310
- /* @__PURE__ */ jsx("ul", { className: "grid border border-border1 border-t-0 bg-surface3 rounded-xl rounded-t-none overflow-y-auto", children: items.map((item) => {
12311
- return /* @__PURE__ */ jsx(
12312
- EntryListItem,
12313
- {
12314
- item,
12315
- selectedItemId,
12316
- onClick: isLoading ? void 0 : onItemClick,
12317
- columns,
12318
- isLoading,
12319
- children: (columns || []).map((col, index) => {
12320
- const isValidReactElement = isValidElement(item?.[col.name]);
12321
- const key = `${index}-${item.id}`;
12322
- return isValidReactElement ? /* @__PURE__ */ jsx(React__default.Fragment, { children: item?.[col.name] }, key) : /* @__PURE__ */ jsx(EntryListTextCell, { isLoading, children: item?.[col.name] }, key);
12323
- })
12324
- },
12325
- item.id
12326
- );
12327
- }) }),
12328
- setEndOfListElement && /* @__PURE__ */ jsxs(
12329
- "div",
12330
- {
12331
- ref: setEndOfListElement,
12332
- className: "text-[0.875rem] text-icon3 opacity-50 flex mt-[2rem] justify-center",
12333
- children: [
12334
- isLoadingNextPage && "Loading...",
12335
- !hasMore && !isLoadingNextPage && !isLoading && "No more data to load"
12336
- ]
12337
- }
12338
- ),
12339
- typeof page === "number" && typeof perPage === "number" && typeof total === "number" && /* @__PURE__ */ jsxs("div", { className: cn("flex pt-[1.5rem] items-center justify-center text-icon3 text-[0.875rem] gap-[2rem]"), children: [
12340
- /* @__PURE__ */ jsxs("span", { children: [
12341
- "Page ",
12342
- page ? page + 1 : "1"
12343
- ] }),
12344
- /* @__PURE__ */ jsxs(
12345
- "div",
12346
- {
12347
- className: cn(
12348
- "flex gap-[1rem]",
12349
- "[&>button]:flex [&>button]:items-center [&>button]:gap-[0.5rem] [&>button]:text-icon4 [&>button:hover]:text-icon5 [&>button]:transition-colors [&>button]:border [&>button]:border-border1 [&>button]:p-[0.25rem] [&>button]:px-[0.5rem] [&>button]:rounded-md",
12350
- " [&_svg]:w-[1em] [&_svg]:h-[1em] [&_svg]:text-icon3"
12351
- ),
12352
- children: [
12353
- typeof page === "number" && page > 0 && /* @__PURE__ */ jsxs("button", { onClick: onPrevPage, disabled: page === 0, children: [
12354
- /* @__PURE__ */ jsx(ArrowLeftIcon, {}),
12355
- "Previous"
12356
- ] }),
12357
- hasMore && /* @__PURE__ */ jsxs("button", { onClick: onNextPage, disabled: !hasMore, children: [
12358
- "Next",
12359
- /* @__PURE__ */ jsx(ArrowRightIcon, {})
12360
- ] })
12361
- ]
12362
- }
12363
- )
12364
- ] })
11701
+ )
11702
+ ] });
11703
+ }
11704
+
11705
+ function EntryListEntryTextCol({ children, isLoading }) {
11706
+ return /* @__PURE__ */ jsx("div", { className: "text-icon4 text-[0.875rem] truncate ", children: isLoading ? /* @__PURE__ */ jsx("div", { className: "bg-surface4 rounded-md animate-pulse text-transparent h-[1rem] select-none" }) : children });
11707
+ }
11708
+ function EntryListEntryStatusCol({ status }) {
11709
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex justify-center items-center w-full relative"), children: [
11710
+ status ? /* @__PURE__ */ jsx(
11711
+ "div",
11712
+ {
11713
+ className: cn("w-[0.6rem] h-[0.6rem] rounded-full", {
11714
+ "bg-green-600": status === "success",
11715
+ "bg-red-700": status === "failed"
11716
+ })
11717
+ }
11718
+ ) : /* @__PURE__ */ jsx("div", { className: "text-icon2 text-[0.75rem] leading-none", children: "-" }),
11719
+ /* @__PURE__ */ jsxs(VisuallyHidden$1, { children: [
11720
+ "Status: ",
11721
+ status ? status : "not provided"
12365
11722
  ] })
12366
11723
  ] });
12367
11724
  }
12368
11725
 
12369
- function EntryListToolbar({ children, className }) {
12370
- return /* @__PURE__ */ jsx(
12371
- "div",
12372
- {
12373
- className: cn("flex justify-between bg-surface4 z-[1] mt-[1rem] mb-[1rem] rounded-lg px-[1.5rem] ", className),
12374
- children
12375
- }
12376
- );
11726
+ const EntryList = Object.assign(EntryListRoot, {
11727
+ Header: EntryListHeader,
11728
+ Trim: EntryListTrim,
11729
+ Entries: EntryListEntries,
11730
+ Entry: EntryListEntry,
11731
+ Message: EntryListMessage,
11732
+ NextPageLoading: EntryListNextPageLoading,
11733
+ Pagination: EntryListPagination,
11734
+ EntryText: EntryListEntryTextCol,
11735
+ EntryStatus: EntryListEntryStatusCol
11736
+ });
11737
+
11738
+ const widths = ["75%", "50%", "65%", "90%", "60%", "80%"];
11739
+ function EntryListEntriesSkeleton({ columns, numberOfRows = 3 }) {
11740
+ const getPseudoRandomWidth = (rowIdx, colIdx) => {
11741
+ const index = (rowIdx + colIdx + (columns?.length || 0) + (numberOfRows || 0)) % widths.length;
11742
+ return widths[index];
11743
+ };
11744
+ return /* @__PURE__ */ jsx(EntryListEntries, { children: Array.from({ length: numberOfRows }).map((_, rowIdx) => /* @__PURE__ */ jsx(EntryListEntry, { columns, children: (columns || []).map((col, colIdx) => {
11745
+ const key = `${col.name}-${colIdx}`;
11746
+ return /* @__PURE__ */ jsx(
11747
+ "div",
11748
+ {
11749
+ className: "bg-surface4 rounded-md animate-pulse text-transparent h-[1rem] select-none",
11750
+ style: { width: `${getPseudoRandomWidth(rowIdx, colIdx)}` }
11751
+ },
11752
+ key
11753
+ );
11754
+ }) }, rowIdx)) });
12377
11755
  }
12378
11756
 
12379
- function EntryListPageHeader({ title, description, icon, children }) {
12380
- return /* @__PURE__ */ jsxs(
12381
- "div",
12382
- {
12383
- className: cn(
12384
- "grid z-[1] top-0 gap-y-[0.5rem] text-icon4 bg-surface2 py-[3rem]",
12385
- "3xl:h-full 3xl:content-start 3xl:grid-rows-[auto_1fr] h-full 3xl:overflow-y-auto"
12386
- ),
12387
- children: [
12388
- /* @__PURE__ */ jsxs("div", { className: "grid gap-[1rem] w", children: [
12389
- /* @__PURE__ */ jsxs("div", { className: cn("flex gap-[.75em] items-center", "[&>svg]:w-[1.1em] [&>svg]:h-[1.1em] [&>svg]:text-icon4"), children: [
12390
- icon,
12391
- /* @__PURE__ */ jsx("h1", { className: "text-icon6 text-[1.25rem]", children: title })
12392
- ] }),
12393
- /* @__PURE__ */ jsx("p", { className: "m-0 text-[0.875rem]", children: description })
12394
- ] }),
12395
- children
12396
- ]
12397
- }
12398
- );
11757
+ function EntryListSkeleton({ columns, numberOfRows }) {
11758
+ return /* @__PURE__ */ jsx(EntryList, { children: /* @__PURE__ */ jsxs(EntryListTrim, { children: [
11759
+ /* @__PURE__ */ jsx(EntryListHeader, { columns }),
11760
+ /* @__PURE__ */ jsx(EntryListEntriesSkeleton, { columns, numberOfRows })
11761
+ ] }) });
12399
11762
  }
12400
11763
 
12401
- function SideDialog({
11764
+ function getToNextEntryFn({ entries, id, update }) {
11765
+ const currentIndex = entries.findIndex((entry) => entry.id === id);
11766
+ const thereIsNextItem = currentIndex < entries.length - 1;
11767
+ if (thereIsNextItem) {
11768
+ return () => {
11769
+ const nextItem = entries[currentIndex + 1];
11770
+ update(nextItem.id);
11771
+ };
11772
+ }
11773
+ return void 0;
11774
+ }
11775
+ function getToPreviousEntryFn({ entries, id, update }) {
11776
+ const currentIndex = entries.findIndex((entry) => entry.id === id);
11777
+ const thereIsPreviousItem = currentIndex > 0;
11778
+ if (thereIsPreviousItem) {
11779
+ return () => {
11780
+ const previousItem = entries[currentIndex - 1];
11781
+ update(previousItem.id);
11782
+ };
11783
+ }
11784
+ return void 0;
11785
+ }
11786
+
11787
+ function SideDialogRoot({
12402
11788
  dialogTitle,
12403
11789
  dialogDescription,
12404
11790
  isOpen,
12405
11791
  onClose,
12406
11792
  children,
12407
11793
  variant = "default",
12408
- hasCloseButton = true,
11794
+ level = 1,
12409
11795
  className
12410
11796
  }) {
12411
11797
  const isConfirmation = variant === "confirmation";
12412
11798
  return /* @__PURE__ */ jsx(DialogPrimitive.Root, { open: isOpen, onOpenChange: onClose, children: /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [
12413
- !isConfirmation && /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { className: cn("bg-black top-0 bottom-0 right-0 left-0 fixed z-50 opacity-[0.25]") }),
11799
+ !isConfirmation && /* @__PURE__ */ jsx(DialogPrimitive.Overlay, { className: cn("bg-black top-0 bottom-0 right-0 left-0 fixed z-50 opacity-40") }),
12414
11800
  /* @__PURE__ */ jsxs(
12415
11801
  DialogPrimitive.Content,
12416
11802
  {
12417
11803
  className: cn(
12418
- "fixed top-0 bottom-0 right-0 border-l border-border1 z-50 bg-surface4",
12419
- "w-[calc(100vw-20rem)] max-w-[50rem]",
12420
- "3xl:max-w-[60rem]",
12421
- "4xl:max-w-[50%]",
12422
- "data-[state=closed]:animate-out data-[state=closed]:fade-out-0",
11804
+ "fixed top-0 bottom-0 right-0 border-l border-border2 z-50 bg-surface2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 ",
12423
11805
  {
12424
- "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:slide-in-from-right-1/4": !isConfirmation,
11806
+ "w-[75vw] 2xl:w-[65vw] 4xl:w-[55vw]": level === 1,
11807
+ "w-[70vw] 2xl:w-[59vw] 4xl:w-[48vw]": level === 2,
11808
+ "w-[65vw] 2xl:w-[53vw] 4xl:w-[41vw]": level === 3,
11809
+ "data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:slide-in-from-right-1/4 shadow-[-3rem_0_2rem_0_rgba(0,0,0,0.75)]": !isConfirmation,
12425
11810
  "bg-surface2/70": isConfirmation
12426
11811
  },
12427
11812
  className
@@ -12431,15 +11816,15 @@ function SideDialog({
12431
11816
  /* @__PURE__ */ jsx(DialogPrimitive.Title, { children: dialogTitle }),
12432
11817
  /* @__PURE__ */ jsx(DialogPrimitive.Description, { children: dialogDescription })
12433
11818
  ] }),
12434
- !isConfirmation && hasCloseButton && /* @__PURE__ */ jsx(DialogPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsx(
11819
+ !isConfirmation && /* @__PURE__ */ jsx(DialogPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsx(
12435
11820
  "button",
12436
11821
  {
12437
11822
  className: cn(
12438
- "flex appearance-none items-center justify-center rounded-bl-lg h-[3.5rem] w-[3.5rem] absolute too-0 left-[-3.5rem] bg-surface4 text-icon4 border-l border-b border-border1",
11823
+ "flex appearance-none items-center justify-center rounded-bl-lg h-[3.5rem] w-[3.5rem] absolute top-0 left-[-3.5rem] bg-surface2 text-icon4 border-l border-b border-border2",
12439
11824
  "hover:surface5 hover:text-icon5"
12440
11825
  ),
12441
11826
  "aria-label": "Close",
12442
- children: isConfirmation ? /* @__PURE__ */ jsx(XIcon, {}) : /* @__PURE__ */ jsx(ChevronsRightIcon, {})
11827
+ children: /* @__PURE__ */ jsx(ChevronsRightIcon, {})
12443
11828
  }
12444
11829
  ) }),
12445
11830
  /* @__PURE__ */ jsx(
@@ -12457,125 +11842,97 @@ function SideDialog({
12457
11842
  ] }) });
12458
11843
  }
12459
11844
 
12460
- function SideDialogHeader({ children, className }) {
12461
- return /* @__PURE__ */ jsx("div", { className: cn("flex justify-between items-center pb-[1rem]", className), children });
11845
+ function MainContentLayout({
11846
+ children,
11847
+ className,
11848
+ style
11849
+ }) {
11850
+ const devStyleRequested = devUIStyleRequested("MainContentLayout");
11851
+ return /* @__PURE__ */ jsx(
11852
+ "main",
11853
+ {
11854
+ className: cn(`grid grid-rows-[auto_1fr] h-full items-start content-start`, className),
11855
+ style: { ...style, ...devStyleRequested ? { border: "3px dotted red" } : {} },
11856
+ children
11857
+ }
11858
+ );
12462
11859
  }
12463
-
12464
- function SideDialogFooter({ children, onNext, onPrevious, showInnerNav }) {
12465
- const handleOnNext = () => {
12466
- onNext?.();
12467
- };
12468
- const handleOnPrevious = () => {
12469
- onPrevious?.();
12470
- };
12471
- return /* @__PURE__ */ jsxs(
11860
+ function MainContentContent({
11861
+ children,
11862
+ className,
11863
+ isCentered = false,
11864
+ isDivided = false,
11865
+ hasLeftServiceColumn = false,
11866
+ style
11867
+ }) {
11868
+ const devStyleRequested = devUIStyleRequested("MainContentContent");
11869
+ return /* @__PURE__ */ jsx(
12472
11870
  "div",
12473
11871
  {
12474
11872
  className: cn(
12475
- "flex items-center justify-end gap-[1rem] px-[1.5rem] py-[1rem] min-h-[4rem] border-t border-border1",
11873
+ `grid overflow-y-auto h-full `,
11874
+ `overflow-x-auto min-w-[min-content]`,
12476
11875
  {
12477
- "justify-between": showInnerNav
12478
- }
11876
+ "items-start content-start": !isCentered && !isDivided && !hasLeftServiceColumn,
11877
+ "grid place-items-center": isCentered,
11878
+ "grid-cols-[1fr_1fr]": isDivided && !hasLeftServiceColumn,
11879
+ "grid-cols-[12rem_1fr_1fr]": isDivided && hasLeftServiceColumn,
11880
+ "grid-cols-[auto_1fr]": !isDivided && hasLeftServiceColumn
11881
+ },
11882
+ className
12479
11883
  ),
12480
- children: [
12481
- (onNext || onPrevious) && showInnerNav && /* @__PURE__ */ jsxs("div", { className: cn("flex gap-[1rem]"), children: [
12482
- /* @__PURE__ */ jsx(DialogPrimitive.Close, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { onClick: handleOnNext, disabled: !onNext, variant: "ghost", children: [
12483
- /* @__PURE__ */ jsx(XIcon, {}),
12484
- "Close"
12485
- ] }) }),
12486
- /* @__PURE__ */ jsxs(Button, { onClick: handleOnNext, disabled: !onNext, variant: "ghost", children: [
12487
- "Next",
12488
- /* @__PURE__ */ jsx(ArrowUpIcon, {})
12489
- ] }),
12490
- /* @__PURE__ */ jsxs(Button, { onClick: handleOnPrevious, disabled: !onPrevious, variant: "ghost", children: [
12491
- /* @__PURE__ */ jsx(ArrowDownIcon, {}),
12492
- "Previous"
12493
- ] })
12494
- ] }),
12495
- /* @__PURE__ */ jsx("div", { children })
12496
- ]
11884
+ style: { ...style, ...devStyleRequested ? { border: "3px dotted orange" } : {} },
11885
+ children
12497
11886
  }
12498
11887
  );
12499
11888
  }
12500
- function SideDialogFooterGroup({ children }) {
12501
- return /* @__PURE__ */ jsx("div", { className: "flex items-baseline gap-[1rem]", children });
11889
+ function devUIStyleRequested(name) {
11890
+ try {
11891
+ const raw = localStorage.getItem("add-dev-style-to-components");
11892
+ if (!raw) return false;
11893
+ const components = raw.split(",").map((c) => c.trim()).filter(Boolean);
11894
+ return components.includes(name);
11895
+ } catch (error) {
11896
+ console.error("Error reading or parsing localStorage:", error);
11897
+ return false;
11898
+ }
12502
11899
  }
12503
11900
 
12504
- function SideDialogContent({ children, className, isCentered, isFullHeight, variant }) {
12505
- return /* @__PURE__ */ jsx("div", { className: cn("p-[3rem] py-[2rem] overflow-y-scroll", className), children: /* @__PURE__ */ jsx(
12506
- "div",
12507
- {
12508
- className: cn("grid gap-[2rem] max-w-[50rem] w-full mx-auto pb-[1rem] ", {
12509
- "items-center justify-center h-full content-center": isCentered,
12510
- "min-h-full": isFullHeight,
12511
- "content-start": !isFullHeight && !isCentered
12512
- }),
12513
- children
12514
- }
12515
- ) });
11901
+ function ButtonsGroup({ children, className }) {
11902
+ return /* @__PURE__ */ jsx("div", { className: cn(`flex gap-2 items-center`, "[&>button]:flex-grow", className), children });
11903
+ }
11904
+
11905
+ function Sections({ children, className }) {
11906
+ return /* @__PURE__ */ jsx("div", { className: cn("grid gap-[3rem]", className), children });
11907
+ }
11908
+
11909
+ function SectionRoot({ children, className }) {
11910
+ return /* @__PURE__ */ jsx("section", { className: cn(`grid gap-[1rem]`, className), children });
11911
+ }
11912
+
11913
+ function SectionHeader({ children, className }) {
11914
+ return /* @__PURE__ */ jsx("header", { className: cn("grid items-center grid-cols-[1fr_auto]", className), children });
12516
11915
  }
12517
- function SideDialogSection({ children }) {
11916
+
11917
+ function SectionHeading({ headingLevel = "h2", children, className }) {
11918
+ const HeadingTag = headingLevel;
12518
11919
  return /* @__PURE__ */ jsx(
12519
- "div",
11920
+ HeadingTag,
12520
11921
  {
12521
11922
  className: cn(
12522
- "grid text-[0.875rem] text-icon5 gap-[1rem] justify-items-start",
12523
- "[&>h3]:text-icon3 [&>h3]:text-[1rem] [&>h3]:font-semibold [&>h3]:border-b [&>h3]:border-border1 [&>h3]:pb-[1rem] [&>h3]:pr-[1rem] [&>h3]:inline-flex [&>h3]:gap-[.5rem] [&>h3]:items-center",
12524
- "[&>h3>svg]:w-[1em] [&>h3>svg]:h-[1em] [&>h3>svg]:text-icon3"
11923
+ "flex items-center gap-[0.5em] text-[0.9375rem] font-bold text-icon4",
11924
+ "[&>svg]:w-[1.2em] [&>svg]:h-[1.2em] [&>svg]:opacity-50",
11925
+ className
12525
11926
  ),
12526
11927
  children
12527
11928
  }
12528
11929
  );
12529
11930
  }
12530
- function SideDialogKeyValueList({ items, className }) {
12531
- return /* @__PURE__ */ jsx("dl", { className: cn("grid grid-cols-[auto_1fr] gap-x-[2rem] gap-y-[.5rem] text-[0.875rem] content-start", className), children: items.map((item, index) => /* @__PURE__ */ jsxs(Fragment, { children: [
12532
- /* @__PURE__ */ jsxs("dt", { className: "text-icon3", children: [
12533
- item.key,
12534
- ":"
12535
- ] }),
12536
- /* @__PURE__ */ jsx("dd", { className: "text-icon4", children: item.value })
12537
- ] })) });
12538
- }
12539
11931
 
12540
- function SideDialogTop({ children, onNext, onPrevious, showInnerNav, className }) {
12541
- const handleOnNext = () => {
12542
- onNext?.();
12543
- };
12544
- const handleOnPrevious = () => {
12545
- onPrevious?.();
12546
- };
12547
- return /* @__PURE__ */ jsx(
12548
- "div",
12549
- {
12550
- className: cn(`flex justify-between h-[3.5rem] items-center text-icon5 text-[.875rem] pl-[1.5rem]`, className),
12551
- children: /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-[2rem]", "[&_svg]:w-[1.1em] [&_svg]:h-[1.1em] [&_svg]:text-icon3"), children: [
12552
- children,
12553
- (onNext || onPrevious) && showInnerNav && /* @__PURE__ */ jsxs(Fragment, { children: [
12554
- /* @__PURE__ */ jsx("span", { className: "text-icon3", children: "|" }),
12555
- /* @__PURE__ */ jsxs(
12556
- "div",
12557
- {
12558
- className: cn(
12559
- "flex gap-[1rem] items-baseline"
12560
- // '[&>button]:text-[0.875rem] [&>button]:flex [&>button]:items-center [&>button]:px-[0.5rem] [&>button]:py-[0.8rem] [&>button]:leading-[1]',
12561
- ),
12562
- children: [
12563
- /* @__PURE__ */ jsxs(Button, { onClick: handleOnPrevious, disabled: !onPrevious, variant: "ghost", children: [
12564
- "Previous",
12565
- /* @__PURE__ */ jsx(ArrowUpIcon, {})
12566
- ] }),
12567
- /* @__PURE__ */ jsxs(Button, { onClick: handleOnNext, disabled: !onNext, variant: "ghost", children: [
12568
- "Next",
12569
- /* @__PURE__ */ jsx(ArrowDownIcon, {})
12570
- ] })
12571
- ]
12572
- }
12573
- )
12574
- ] })
12575
- ] })
12576
- }
12577
- );
12578
- }
11932
+ const Section = Object.assign(SectionRoot, {
11933
+ Header: SectionHeader,
11934
+ Heading: SectionHeading
11935
+ });
12579
11936
 
12580
11937
  const useCodemirrorTheme = () => {
12581
11938
  return useMemo(
@@ -12593,7 +11950,7 @@ const useCodemirrorTheme = () => {
12593
11950
  []
12594
11951
  );
12595
11952
  };
12596
- function SideDialogCodeSection({ codeStr = "", title, simplified = false }) {
11953
+ function SideDialogCodeSection({ codeStr = "", title, icon, simplified = false }) {
12597
11954
  const theme = useCodemirrorTheme();
12598
11955
  const [showAsMultilineText, setShowAsMultilineText] = useState(false);
12599
11956
  const hasMultilineText = useMemo(() => {
@@ -12605,22 +11962,19 @@ function SideDialogCodeSection({ codeStr = "", title, simplified = false }) {
12605
11962
  }
12606
11963
  }, [codeStr]);
12607
11964
  const finalCodeStr = showAsMultilineText ? codeStr?.replace(/\\n/g, "\n") : codeStr;
12608
- return /* @__PURE__ */ jsx("section", { className: "border border-border1 rounded-lg", children: /* @__PURE__ */ jsxs("div", { className: "border-b border-border1 last:border-b-0 grid", children: [
12609
- /* @__PURE__ */ jsxs("div", { className: "p-[1rem] px-[1.5rem] border-b border-border1 grid grid-cols-[1fr_auto]", children: [
12610
- /* @__PURE__ */ jsx("h3", { children: title }),
12611
- /* @__PURE__ */ jsxs("div", { className: "flex gap-2 items-center justify-end", children: [
11965
+ return /* @__PURE__ */ jsxs(Section, { children: [
11966
+ /* @__PURE__ */ jsxs(Section.Header, { children: [
11967
+ /* @__PURE__ */ jsxs(Section.Heading, { children: [
11968
+ icon,
11969
+ title
11970
+ ] }),
11971
+ /* @__PURE__ */ jsxs(ButtonsGroup, { children: [
12612
11972
  /* @__PURE__ */ jsx(CopyButton, { content: codeStr || "No content" }),
12613
11973
  hasMultilineText && /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: () => setShowAsMultilineText(!showAsMultilineText), children: showAsMultilineText ? /* @__PURE__ */ jsx(AlignLeftIcon, {}) : /* @__PURE__ */ jsx(AlignJustifyIcon, {}) })
12614
11974
  ] })
12615
11975
  ] }),
12616
- /* @__PURE__ */ jsx(
12617
- "div",
12618
- {
12619
- className: cn("bg-surface3 p-[1rem] overflow-auto text-icon4 text-[0.875rem] [&>div]:border-none break-all"),
12620
- children: codeStr && /* @__PURE__ */ jsx(Fragment, { children: simplified ? /* @__PURE__ */ jsx("div", { className: "text-icon4 text-[0.875rem] py-[1rem] font-mono break-all mx-[1.5rem]", children: /* @__PURE__ */ jsx("pre", { className: "text-wrap", children: codeStr }) }) : /* @__PURE__ */ jsx(CodeMirror, { extensions: [json(), EditorView.lineWrapping], theme, value: finalCodeStr }) })
12621
- }
12622
- )
12623
- ] }) });
11976
+ codeStr && /* @__PURE__ */ jsx("div", { className: "bg-black/20 p-[1rem] overflow-hidden rounded-xl border border-white/10 text-icon4 text-[0.875rem] break-all", children: simplified ? /* @__PURE__ */ jsx("div", { className: "text-icon4 font-mono break-all px-[0.5rem]", children: /* @__PURE__ */ jsx("pre", { className: "text-wrap", children: codeStr }) }) : /* @__PURE__ */ jsx(CodeMirror, { extensions: [json(), EditorView.lineWrapping], theme, value: finalCodeStr }) })
11977
+ ] });
12624
11978
  }
12625
11979
  function containsInnerNewline(obj) {
12626
11980
  if (typeof obj === "string") {
@@ -12653,6 +12007,69 @@ function SideDialogHeading({ children, className, as = "h1" }) {
12653
12007
  );
12654
12008
  }
12655
12009
 
12010
+ function SideDialogContent({ children, className }) {
12011
+ return /* @__PURE__ */ jsx("div", { className: cn("p-[1.5rem] pl-[2.25rem] overflow-y-scroll grid gap-[1.5rem] content-start", className), children: /* @__PURE__ */ jsx("div", { className: cn("grid gap-[1.5rem] mb-[2rem] "), children }) });
12012
+ }
12013
+
12014
+ function SideDialogHeader({ children, className }) {
12015
+ return /* @__PURE__ */ jsx("div", { className: cn("flex justify-between items-center pb-[1rem]", className), children });
12016
+ }
12017
+
12018
+ function SideDialogTop({ children, withTopSeparator, className }) {
12019
+ return /* @__PURE__ */ jsx(
12020
+ "div",
12021
+ {
12022
+ className: cn(
12023
+ `flex h-[3.5rem] items-center text-icon5 text-[.875rem] pl-[1.5rem] relative gap-[1rem]`,
12024
+ '[&:after]:content-[""] [&:after]:absolute [&:after]:left-[1.5rem] [&:after]:right-[1.5rem] [&:after]:bottom-0 [&:after]:border-b [&:after]:border-border1',
12025
+ {
12026
+ '[&:before]:content-[""] [&:before]:absolute [&:before]:left-[1.5rem] [&:before]:right-[1.5rem] [&:before]:top-0 [&:before]:border-t [&:before]:border-border1': withTopSeparator
12027
+ },
12028
+ className
12029
+ ),
12030
+ children
12031
+ }
12032
+ );
12033
+ }
12034
+
12035
+ function SideDialogNav({ onNext, onPrevious, className }) {
12036
+ const handleOnNext = () => {
12037
+ onNext?.();
12038
+ };
12039
+ const handleOnPrevious = () => {
12040
+ onPrevious?.();
12041
+ };
12042
+ return /* @__PURE__ */ jsx(
12043
+ "div",
12044
+ {
12045
+ className: cn(
12046
+ "flex items-center gap-[1rem]",
12047
+ "[&_svg]:w-[1.1em] [&_svg]:h-[1.1em] [&_svg]:text-icon3",
12048
+ className
12049
+ ),
12050
+ children: (onNext || onPrevious) && /* @__PURE__ */ jsxs("div", { className: cn("flex gap-[1rem] items-baseline"), children: [
12051
+ /* @__PURE__ */ jsxs(Button, { onClick: handleOnPrevious, disabled: !onPrevious, variant: "ghost", children: [
12052
+ "Previous",
12053
+ /* @__PURE__ */ jsx(ArrowUpIcon, {})
12054
+ ] }),
12055
+ /* @__PURE__ */ jsxs(Button, { onClick: handleOnNext, disabled: !onNext, variant: "ghost", children: [
12056
+ "Next",
12057
+ /* @__PURE__ */ jsx(ArrowDownIcon, {})
12058
+ ] })
12059
+ ] })
12060
+ }
12061
+ );
12062
+ }
12063
+
12064
+ const SideDialog = Object.assign(SideDialogRoot, {
12065
+ Top: SideDialogTop,
12066
+ Header: SideDialogHeader,
12067
+ Heading: SideDialogHeading,
12068
+ Content: SideDialogContent,
12069
+ CodeSection: SideDialogCodeSection,
12070
+ Nav: SideDialogNav
12071
+ });
12072
+
12656
12073
  function EntityMainHeader({
12657
12074
  title,
12658
12075
  description,
@@ -12687,26 +12104,36 @@ function EntityMainHeader({
12687
12104
  }
12688
12105
 
12689
12106
  function PageHeader({ title, description, icon, className }) {
12690
- return /* @__PURE__ */ jsxs(
12691
- "header",
12692
- {
12693
- className: cn(
12694
- "grid gap-[.5rem] pt-[2rem] pb-[2rem]",
12695
- "[&>h1]:text-icon6 [&>h1]:text-[1.25rem] [&>h1]:font-normal [&>h1]:flex [&>h1]:items-center [&>h1]:gap-[0.5rem]",
12696
- "[&_svg]:w-[1.4rem] [&_svg]:h-[1.4rem] [&_svg]:text-icon3",
12697
- "[&>p]:text-icon4 [&>p]:text-[0.875rem] [&>p]:m-0",
12698
- className
12699
- ),
12700
- children: [
12701
- /* @__PURE__ */ jsxs("h1", { children: [
12107
+ const titleIsLoading = title === "loading";
12108
+ const descriptionIsLoading = description === "loading";
12109
+ return /* @__PURE__ */ jsxs("header", { className: cn("grid gap-[.5rem] pt-[2rem] pb-[2rem]", className), children: [
12110
+ /* @__PURE__ */ jsx(
12111
+ "h1",
12112
+ {
12113
+ className: cn(
12114
+ "text-icon6 text-[1.25rem] font-normal flex items-center gap-[0.5rem]",
12115
+ "[&>svg]:w-[1.4rem] [&>svg]:h-[1.4rem] [&>svg]:text-icon3",
12116
+ {
12117
+ "bg-surface4 w-[15rem] max-w-[50%] rounded-md animate-pulse": titleIsLoading
12118
+ }
12119
+ ),
12120
+ children: titleIsLoading ? /* @__PURE__ */ jsx(Fragment, { children: " " }) : /* @__PURE__ */ jsxs(Fragment, { children: [
12702
12121
  icon && icon,
12703
12122
  " ",
12704
12123
  title
12705
- ] }),
12706
- description && /* @__PURE__ */ jsx("p", { children: description })
12707
- ]
12708
- }
12709
- );
12124
+ ] })
12125
+ }
12126
+ ),
12127
+ description && /* @__PURE__ */ jsx(
12128
+ "p",
12129
+ {
12130
+ className: cn("text-icon4 text-[0.875rem] m-0", {
12131
+ "bg-surface4 w-[40rem] max-w-[80%] rounded-md animate-pulse": descriptionIsLoading
12132
+ }),
12133
+ children: descriptionIsLoading ? /* @__PURE__ */ jsx(Fragment, { children: " " }) : description
12134
+ }
12135
+ )
12136
+ ] });
12710
12137
  }
12711
12138
 
12712
12139
  function DatePicker({ className, classNames, showOutsideDays = true, ...props }) {
@@ -13017,67 +12444,357 @@ const DateTimePickerContent = ({
13017
12444
  }
13018
12445
  ),
13019
12446
  /* @__PURE__ */ jsx(
13020
- TimePicker,
12447
+ TimePicker,
12448
+ {
12449
+ onValueChange: handleTimeStrChange,
12450
+ className: "m-4 mt-0 w-auto",
12451
+ defaultValue: value ? formatDate(new Date(value), "hh:mm a") : defaultTimeStrValue
12452
+ }
12453
+ ),
12454
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_auto] gap-[0.5rem] m-4 mt-0", children: [
12455
+ /* @__PURE__ */ jsx(
12456
+ Button,
12457
+ {
12458
+ variant: "primary",
12459
+ tabIndex: 0,
12460
+ onClick: () => {
12461
+ dateInputValueIsValid ? handleApply() : handleCancel();
12462
+ },
12463
+ children: newValueDefined ? `Apply` : `Cancel`
12464
+ }
12465
+ ),
12466
+ newValueDefined && /* @__PURE__ */ jsx(Button, { variant: "outline", tabIndex: 0, onClick: handleClear, children: "Clear" })
12467
+ ] })
12468
+ ]
12469
+ }
12470
+ );
12471
+ };
12472
+ const DefaultTrigger = React.forwardRef(
12473
+ ({ value, placeholder, className, ...props }, ref) => {
12474
+ return /* @__PURE__ */ jsxs(Button, { ref, variant: "outline", className: cn("justify-start", className), ...props, children: [
12475
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "h-4 w-4" }),
12476
+ value ? /* @__PURE__ */ jsx("span", { className: "text-white", children: format(value, "PP p") }) : /* @__PURE__ */ jsx("span", { className: "text-gray", children: placeholder ?? "Pick a date" })
12477
+ ] });
12478
+ }
12479
+ );
12480
+
12481
+ function TextAndIcon({ children, className }) {
12482
+ return /* @__PURE__ */ jsx(
12483
+ "span",
12484
+ {
12485
+ className: cn(
12486
+ "flex items-center gap-[0.5em] text-icon4 text-[0.875rem]",
12487
+ "[&>svg]:w-[1.1em] [&>svg]:h-[1.1em] [&>svg]:opacity-50 [&_svg]:flex-shrink-0",
12488
+ className
12489
+ ),
12490
+ children
12491
+ }
12492
+ );
12493
+ }
12494
+
12495
+ function getShortId(id) {
12496
+ if (!id) return void 0;
12497
+ return id.slice(0, 8);
12498
+ }
12499
+
12500
+ function Notification({ children, className, isVisible, autoDismiss = true, dismissTime = 5e3 }) {
12501
+ const [localIsVisible, setLocalIsVisible] = useState(isVisible);
12502
+ useEffect(() => {
12503
+ if (autoDismiss && isVisible) {
12504
+ const timer = setTimeout(() => {
12505
+ setLocalIsVisible(false);
12506
+ }, dismissTime);
12507
+ return () => clearTimeout(timer);
12508
+ }
12509
+ }, [autoDismiss, isVisible, dismissTime]);
12510
+ useEffect(() => {
12511
+ setLocalIsVisible(isVisible);
12512
+ }, [isVisible]);
12513
+ if (!localIsVisible) return null;
12514
+ return /* @__PURE__ */ jsxs(
12515
+ "div",
12516
+ {
12517
+ className: cn(
12518
+ "grid grid-cols-[1fr_auto] gap-[0.5rem] rounded-l bg-white/5 p-[1.5rem] py-[1rem] text-[0.875rem] text-icon3 items-center",
12519
+ "[&>svg]:w-[1.1em] [&>svg]:h-[1.1em] [&>svg]:opacity-50",
12520
+ className
12521
+ ),
12522
+ children: [
12523
+ /* @__PURE__ */ jsx("div", { className: "flex gap-[0.5rem] items-center", children }),
12524
+ /* @__PURE__ */ jsxs(Button, { variant: "ghost", onClick: () => setLocalIsVisible(false), children: [
12525
+ /* @__PURE__ */ jsx(XIcon, {}),
12526
+ /* @__PURE__ */ jsx(VisuallyHidden$1, { children: "Dismiss" })
12527
+ ] })
12528
+ ]
12529
+ }
12530
+ );
12531
+ }
12532
+
12533
+ function MainSidebarNavSeparator({ className }) {
12534
+ return /* @__PURE__ */ jsx(
12535
+ "div",
12536
+ {
12537
+ className: cn(
12538
+ "min-h-[1.3rem] relative",
12539
+ '[&:after]:content-[""] [&:after]:block [&:after]:absolute [&:after]:h-[0px] [&:after]:border-border1 [&:after]:border-t [&:after]:top-[48%] [&:after]:left-[0.75rem] [&:after]:right-[0.75rem]',
12540
+ className
12541
+ )
12542
+ }
12543
+ );
12544
+ }
12545
+
12546
+ function MainSidebarRoot({ children, className }) {
12547
+ const { state, toggleSidebar } = useMainSidebar();
12548
+ const isCollapsed = state === "collapsed";
12549
+ return /* @__PURE__ */ jsxs(
12550
+ "div",
12551
+ {
12552
+ className: cn(
12553
+ "flex flex-col h-full px-[1rem] pb-[1rem] relative overflow-y-auto",
12554
+ {
12555
+ "lg:min-w-[13rem] xl:min-w-[14rem] 2xl:min-w-[15rem] 3xl:min-w-[16rem] 4xl:min-w-[17rem]": !isCollapsed
12556
+ },
12557
+ className
12558
+ ),
12559
+ children: [
12560
+ children,
12561
+ /* @__PURE__ */ jsx(MainSidebarNavSeparator, {}),
12562
+ /* @__PURE__ */ jsx(
12563
+ "button",
12564
+ {
12565
+ onClick: toggleSidebar,
12566
+ className: cn(
12567
+ "inline-flex w-auto items-center text-icon3 h-[2rem] px-[0.75rem] rounded-md",
12568
+ "hover:bg-surface4",
12569
+ "[&_svg]:w-[1rem] [&_svg]:h-[1rem] [&_svg]:text-icon3",
12570
+ {
12571
+ "ml-auto": !isCollapsed
12572
+ }
12573
+ ),
12574
+ "aria-label": "Toggle sidebar",
12575
+ children: /* @__PURE__ */ jsx(
12576
+ PanelRightIcon,
12577
+ {
12578
+ className: cn({
12579
+ "rotate-180": isCollapsed
12580
+ })
12581
+ }
12582
+ )
12583
+ }
12584
+ ),
12585
+ /* @__PURE__ */ jsx(
12586
+ "button",
13021
12587
  {
13022
- onValueChange: handleTimeStrChange,
13023
- className: "m-4 mt-0 w-auto",
13024
- defaultValue: value ? formatDate(new Date(value), "hh:mm a") : defaultTimeStrValue
12588
+ onClick: toggleSidebar,
12589
+ className: cn("w-[.75rem] h-full right-0 top-0 absolute opacity-10", {
12590
+ "cursor-w-resize": !isCollapsed,
12591
+ "cursor-e-resize": isCollapsed
12592
+ }),
12593
+ "aria-label": "Toggle sidebar"
13025
12594
  }
13026
- ),
13027
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1fr_auto] gap-[0.5rem] m-4 mt-0", children: [
13028
- /* @__PURE__ */ jsx(
13029
- Button,
13030
- {
13031
- variant: "primary",
13032
- tabIndex: 0,
13033
- onClick: () => {
13034
- dateInputValueIsValid ? handleApply() : handleCancel();
13035
- },
13036
- children: newValueDefined ? `Apply` : `Cancel`
13037
- }
13038
- ),
13039
- newValueDefined && /* @__PURE__ */ jsx(Button, { variant: "outline", tabIndex: 0, onClick: handleClear, children: "Clear" })
13040
- ] })
12595
+ )
13041
12596
  ]
13042
12597
  }
13043
12598
  );
13044
- };
13045
- const DefaultTrigger = React.forwardRef(
13046
- ({ value, placeholder, className, ...props }, ref) => {
13047
- return /* @__PURE__ */ jsxs(Button, { ref, variant: "outline", className: cn("justify-start", className), ...props, children: [
13048
- /* @__PURE__ */ jsx(CalendarIcon, { className: "h-4 w-4" }),
13049
- value ? /* @__PURE__ */ jsx("span", { className: "text-white", children: format(value, "PP p") }) : /* @__PURE__ */ jsx("span", { className: "text-gray", children: placeholder ?? "Pick a date" })
13050
- ] });
13051
- }
13052
- );
12599
+ }
13053
12600
 
13054
- function TextAndIcon({ children, className }) {
12601
+ function MainSidebarBottom({ children, className }) {
12602
+ return /* @__PURE__ */ jsx("div", { className: cn("mt-auto", className), children });
12603
+ }
12604
+
12605
+ function MainSidebarNav({ children, className }) {
12606
+ return /* @__PURE__ */ jsx("nav", { className: cn("", className), children });
12607
+ }
12608
+
12609
+ function MainSidebarNavSection({ children, className }) {
12610
+ return /* @__PURE__ */ jsx("section", { className: cn("grid items-start content-center relative", className), children });
12611
+ }
12612
+
12613
+ function MainSidebarNavLink({
12614
+ link,
12615
+ state = "default",
12616
+ children,
12617
+ isActive,
12618
+ className
12619
+ }) {
12620
+ const { Link } = useLinkComponent();
12621
+ const isDefaultState = state === "default";
12622
+ const isFeatured = link?.variant === "featured";
12623
+ const linkParams = link?.url?.startsWith("http") ? { target: "_blank", rel: "noreferrer" } : {};
13055
12624
  return /* @__PURE__ */ jsx(
13056
- "span",
12625
+ "li",
13057
12626
  {
13058
12627
  className: cn(
13059
- "flex items-center gap-[0.5em] text-icon4 text-[0.875rem]",
13060
- "[&>svg]:w-[1.2em] [&>svg]:h-[1.2em] [&>svg]:opacity-50 [&_svg]:flex-shrink-0",
12628
+ "flex ",
12629
+ "[&>a]:flex [&>a]:items-center [&>a]:min-h-[2rem] [&>a]:gap-[10px] [&>a]:text-[0.8125rem] [&>a]:text-icon3 [&>a]:py-[6px] [&>a]:px-[0.75rem] [&>a]:w-full [&>a]:rounded-lg [&>a]:justify-center",
12630
+ "[&_svg]:w-[1rem] [&_svg]:h-[1rem] [&_svg]:text-icon3/60",
12631
+ "[&>a:hover]:bg-surface4 [&>a:hover]:text-icon5 [&>a:hover_svg]:text-icon3",
12632
+ {
12633
+ "[&>a]:text-icon5 [&>a]:bg-surface3": isActive,
12634
+ "[&_svg]:text-icon5": isActive,
12635
+ "[&>a]:justify-start ": isDefaultState,
12636
+ "[&_svg]:text-icon3": !isDefaultState,
12637
+ "[&>a]:rounded-md [&>a]:my-[0.5rem] [&>a]:bg-accent1/75 [&>a:hover]:bg-accent1/85 [&>a]:text-black [&>a:hover]:text-black": isFeatured,
12638
+ "[&_svg]:text-black/75": isFeatured
12639
+ },
13061
12640
  className
13062
12641
  ),
13063
- children
12642
+ children: link ? /* @__PURE__ */ jsxs(Link, { href: link.url, ...linkParams, children: [
12643
+ isDefaultState ? /* @__PURE__ */ jsx(Fragment, { children: link.icon && link.icon }) : /* @__PURE__ */ jsxs(Tooltip, { children: [
12644
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: link.icon && link.icon }),
12645
+ /* @__PURE__ */ jsx(TooltipContent, { side: "right", align: "center", className: "bg-border1 text-icon6 ml-[1rem]", children: link.name })
12646
+ ] }),
12647
+ isDefaultState ? link.name : /* @__PURE__ */ jsx(VisuallyHidden$1, { children: link.name }),
12648
+ " ",
12649
+ children
12650
+ ] }) : children
13064
12651
  }
13065
12652
  );
13066
12653
  }
13067
12654
 
13068
- function getShortId(id) {
13069
- if (!id) return void 0;
13070
- return id.slice(0, 8);
12655
+ function MainSidebarNavHeader({ children, className, state = "default" }) {
12656
+ const isDefaultState = state === "default";
12657
+ return /* @__PURE__ */ jsxs("div", { className: cn("grid grid-cols-[auto_1fr] items-center min-h-[2.8rem] ", className), children: [
12658
+ /* @__PURE__ */ jsx(
12659
+ "header",
12660
+ {
12661
+ className: cn("text-[0.6875rem] uppercase text-icon3/75 tracking-widest", {
12662
+ "pl-[0.75rem]": isDefaultState
12663
+ }),
12664
+ children: isDefaultState ? children : /* @__PURE__ */ jsx(VisuallyHidden$1, { children })
12665
+ }
12666
+ ),
12667
+ /* @__PURE__ */ jsx(MainSidebarNavSeparator, {})
12668
+ ] });
12669
+ }
12670
+
12671
+ function MainSidebarNavList({ children, className }) {
12672
+ return /* @__PURE__ */ jsx("ul", { className: cn("grid gap-[0.25rem] items-start content-center ", className), children });
12673
+ }
12674
+
12675
+ const SIDEBAR_COOKIE_NAME = "sidebar:state";
12676
+ const MainSidebarContext = React__default.createContext(null);
12677
+ function useMainSidebar() {
12678
+ const context = React__default.useContext(MainSidebarContext);
12679
+ if (!context) {
12680
+ throw new Error("useMainSidebar must be used within a MainSidebarProvider.");
12681
+ }
12682
+ return context;
12683
+ }
12684
+ function stateInitializer() {
12685
+ const storedState = window.localStorage.getItem(SIDEBAR_COOKIE_NAME);
12686
+ return storedState === "collapsed" ? "collapsed" : "default";
12687
+ }
12688
+ const setLocalStorage = (value) => {
12689
+ window.localStorage.setItem(SIDEBAR_COOKIE_NAME, value.toString());
12690
+ };
12691
+ function MainSidebarProvider({ children }) {
12692
+ const [state, setState] = React__default.useState(stateInitializer);
12693
+ const toggleSidebar = React__default.useCallback(() => {
12694
+ setLocalStorage(state === "default" ? "collapsed" : "default");
12695
+ setState(state === "default" ? "collapsed" : "default");
12696
+ }, [state]);
12697
+ const contextValue = React__default.useMemo(
12698
+ () => ({
12699
+ state,
12700
+ toggleSidebar
12701
+ }),
12702
+ [state, toggleSidebar]
12703
+ );
12704
+ return /* @__PURE__ */ jsx(MainSidebarContext.Provider, { value: contextValue, children });
12705
+ }
12706
+
12707
+ const MainSidebar = Object.assign(MainSidebarRoot, {
12708
+ Bottom: MainSidebarBottom,
12709
+ Nav: MainSidebarNav,
12710
+ NavSection: MainSidebarNavSection,
12711
+ NavLink: MainSidebarNavLink,
12712
+ NavHeader: MainSidebarNavHeader,
12713
+ NavList: MainSidebarNavList,
12714
+ NavSeparator: MainSidebarNavSeparator
12715
+ });
12716
+
12717
+ const scoresListColumns = [
12718
+ { name: "date", label: "Date", size: "4.5rem" },
12719
+ { name: "time", label: "Time", size: "6.5rem" },
12720
+ { name: "input", label: "Input", size: "1fr" },
12721
+ { name: "entityId", label: "Entity", size: "10rem" },
12722
+ { name: "score", label: "Score", size: "3rem" }
12723
+ ];
12724
+ function ScoresList({
12725
+ scores,
12726
+ pagination,
12727
+ onScoreClick,
12728
+ onPageChange,
12729
+ errorMsg,
12730
+ selectedScoreId
12731
+ }) {
12732
+ if (!scores) {
12733
+ return null;
12734
+ }
12735
+ const scoresHasMore = pagination?.hasMore;
12736
+ const handleNextPage = () => {
12737
+ if (scoresHasMore) {
12738
+ onPageChange?.(pagination.page + 1);
12739
+ }
12740
+ };
12741
+ const handlePrevPage = () => {
12742
+ if (pagination?.page && pagination.page > 0) {
12743
+ onPageChange?.(pagination.page - 1);
12744
+ }
12745
+ };
12746
+ return /* @__PURE__ */ jsxs(EntryList, { children: [
12747
+ /* @__PURE__ */ jsxs(EntryList.Trim, { children: [
12748
+ /* @__PURE__ */ jsx(EntryList.Header, { columns: scoresListColumns }),
12749
+ errorMsg ? /* @__PURE__ */ jsx(EntryList.Message, { message: errorMsg, type: "error" }) : /* @__PURE__ */ jsx(Fragment, { children: scores.length > 0 ? /* @__PURE__ */ jsx(EntryList.Entries, { children: scores.map((score) => {
12750
+ const createdAtDate = new Date(score.createdAt);
12751
+ const isTodayDate = isToday(createdAtDate);
12752
+ const entry = {
12753
+ id: score.id,
12754
+ date: isTodayDate ? "Today" : format(createdAtDate, "MMM dd"),
12755
+ time: format(createdAtDate, "h:mm:ss aaa"),
12756
+ input: JSON.stringify(score?.input),
12757
+ entityId: score.entityId,
12758
+ score: score.score
12759
+ };
12760
+ return /* @__PURE__ */ jsx(
12761
+ EntryList.Entry,
12762
+ {
12763
+ entry,
12764
+ isSelected: selectedScoreId === score.id,
12765
+ columns: scoresListColumns,
12766
+ onClick: onScoreClick,
12767
+ children: scoresListColumns.map((col, index) => {
12768
+ const key = `${index}-${score.id}`;
12769
+ return /* @__PURE__ */ jsx(EntryList.EntryText, { children: entry?.[col.name] }, key);
12770
+ })
12771
+ },
12772
+ entry.id
12773
+ );
12774
+ }) }) : /* @__PURE__ */ jsx(EntryList.Message, { message: "No scores for this scorer yet" }) })
12775
+ ] }),
12776
+ /* @__PURE__ */ jsx(
12777
+ EntryList.Pagination,
12778
+ {
12779
+ currentPage: pagination?.page || 0,
12780
+ onNextPage: handleNextPage,
12781
+ onPrevPage: handlePrevPage,
12782
+ hasMore: scoresHasMore
12783
+ }
12784
+ )
12785
+ ] });
13071
12786
  }
13072
12787
 
13073
12788
  function ScoreDialog({
13074
- scorer,
13075
12789
  score,
12790
+ scorerName,
13076
12791
  isOpen,
13077
12792
  onClose,
13078
12793
  onNext,
13079
12794
  onPrevious,
13080
- computeTraceLink
12795
+ computeTraceLink,
12796
+ dialogLevel = 1,
12797
+ usageContext = "scorerPage"
13081
12798
  }) {
13082
12799
  const { Link } = useLinkComponent();
13083
12800
  return /* @__PURE__ */ jsxs(
@@ -13087,77 +12804,144 @@ function ScoreDialog({
13087
12804
  dialogDescription: "View and analyze score details",
13088
12805
  isOpen,
13089
12806
  onClose,
13090
- className: cn("w-[calc(100vw-20rem)] max-w-[80%]", "3xl:max-w-[65%]", "4xl:max-w-[55%]"),
12807
+ level: dialogLevel,
13091
12808
  children: [
13092
- /* @__PURE__ */ jsx(SideDialogTop, { onNext, onPrevious, showInnerNav: true, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[1rem] text-icon4 text-[0.875rem]", children: [
13093
- /* @__PURE__ */ jsxs(TextAndIcon, { children: [
12809
+ /* @__PURE__ */ jsxs(SideDialog.Top, { children: [
12810
+ usageContext === "scorerPage" && /* @__PURE__ */ jsxs(TextAndIcon, { children: [
13094
12811
  /* @__PURE__ */ jsx(GaugeIcon, {}),
13095
12812
  " ",
13096
- scorer?.config?.name
12813
+ scorerName
12814
+ ] }),
12815
+ usageContext === "aiSpanDialog" && /* @__PURE__ */ jsxs(Fragment, { children: [
12816
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
12817
+ /* @__PURE__ */ jsx(EyeIcon, {}),
12818
+ " ",
12819
+ getShortId(score?.traceId)
12820
+ ] }),
12821
+ score?.spanId && /* @__PURE__ */ jsxs(Fragment, { children: [
12822
+ "›",
12823
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
12824
+ /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
12825
+ getShortId(score?.spanId)
12826
+ ] })
12827
+ ] })
13097
12828
  ] }),
13098
12829
  "›",
13099
12830
  /* @__PURE__ */ jsxs(TextAndIcon, { children: [
13100
- /* @__PURE__ */ jsx(HashIcon, {}),
13101
- score?.id
13102
- ] })
13103
- ] }) }),
13104
- /* @__PURE__ */ jsx("div", { className: "p-[1.5rem] px-[2.5rem] overflow-y-auto grid gap-[1.5rem] content-start", children: /* @__PURE__ */ jsxs("div", { className: "grid gap-[1.5rem] mb-[2rem]", children: [
13105
- score?.traceId && /* @__PURE__ */ jsx(
13106
- KeyValueList,
13107
- {
13108
- data: [
13109
- {
13110
- label: "Trace ID",
13111
- value: /* @__PURE__ */ jsx(Link, { href: computeTraceLink(score?.traceId), children: score?.traceId }),
13112
- key: "traceId"
13113
- },
13114
- ...score?.spanId ? [
12831
+ /* @__PURE__ */ jsx(CalculatorIcon, {}),
12832
+ getShortId(score?.id)
12833
+ ] }),
12834
+ "|",
12835
+ /* @__PURE__ */ jsx(SideDialog.Nav, { onNext, onPrevious })
12836
+ ] }),
12837
+ /* @__PURE__ */ jsxs(SideDialog.Content, { children: [
12838
+ /* @__PURE__ */ jsxs(SideDialog.Header, { children: [
12839
+ /* @__PURE__ */ jsxs(SideDialog.Heading, { children: [
12840
+ /* @__PURE__ */ jsx(CalculatorIcon, {}),
12841
+ " Score"
12842
+ ] }),
12843
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
12844
+ /* @__PURE__ */ jsx(HashIcon, {}),
12845
+ " ",
12846
+ score?.id
12847
+ ] })
12848
+ ] }),
12849
+ /* @__PURE__ */ jsxs(Sections, { children: [
12850
+ /* @__PURE__ */ jsx(
12851
+ KeyValueList,
12852
+ {
12853
+ data: [
12854
+ ...usageContext === "aiSpanDialog" ? [
12855
+ {
12856
+ label: "Scorer",
12857
+ value: score?.scorer?.name || "-",
12858
+ key: "scorer-name"
12859
+ }
12860
+ ] : [],
13115
12861
  {
13116
- label: "Span ID",
13117
- value: /* @__PURE__ */ jsx(Link, { href: computeTraceLink(score?.traceId, score?.spanId), children: score?.spanId }),
13118
- key: "spanId"
13119
- }
13120
- ] : []
13121
- ],
13122
- LinkComponent: Link
13123
- }
13124
- ),
13125
- /* @__PURE__ */ jsx(
13126
- SideDialogCodeSection,
13127
- {
13128
- title: `Score: ${Number.isNaN(score?.score) ? "n/a" : score?.score}`,
13129
- codeStr: score?.reason,
13130
- simplified: true
13131
- }
13132
- ),
13133
- /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Input", codeStr: JSON.stringify(score?.input || null, null, 2) }),
13134
- /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Output", codeStr: JSON.stringify(score?.output || null, null, 2) }),
13135
- /* @__PURE__ */ jsx(
13136
- SideDialogCodeSection,
13137
- {
13138
- title: "Preprocess Prompt",
13139
- codeStr: score?.preprocessPrompt || "null",
13140
- simplified: true
13141
- }
13142
- ),
13143
- /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Analyze Prompt", codeStr: score?.analyzePrompt || "null", simplified: true }),
13144
- /* @__PURE__ */ jsx(
13145
- SideDialogCodeSection,
13146
- {
13147
- title: "Generate Score Prompt",
13148
- codeStr: score?.generateScorePrompt || "null",
13149
- simplified: true
13150
- }
13151
- ),
13152
- /* @__PURE__ */ jsx(
13153
- SideDialogCodeSection,
13154
- {
13155
- title: "Generate Reason Prompt",
13156
- codeStr: score?.generateReasonPrompt || "null",
13157
- simplified: true
13158
- }
13159
- )
13160
- ] }) })
12862
+ label: "Created at",
12863
+ value: score?.createdAt ? format$1(new Date(score?.createdAt), "MMM d, h:mm:ss aaa") : "n/a",
12864
+ key: "date"
12865
+ },
12866
+ ...usageContext !== "aiSpanDialog" ? [
12867
+ {
12868
+ label: "Trace ID",
12869
+ value: score?.traceId ? /* @__PURE__ */ jsx(Link, { href: computeTraceLink(score?.traceId), children: score?.traceId }) : "n/a",
12870
+ key: "traceId"
12871
+ },
12872
+ {
12873
+ label: "Span ID",
12874
+ value: score?.traceId && score?.spanId ? /* @__PURE__ */ jsx(Link, { href: computeTraceLink(score?.traceId, score?.spanId), children: score?.spanId }) : "n/a",
12875
+ key: "spanId"
12876
+ }
12877
+ ] : []
12878
+ ],
12879
+ LinkComponent: Link
12880
+ }
12881
+ ),
12882
+ /* @__PURE__ */ jsx(
12883
+ SideDialog.CodeSection,
12884
+ {
12885
+ title: `Score: ${Number.isNaN(score?.score) ? "n/a" : score?.score}`,
12886
+ icon: /* @__PURE__ */ jsx(GaugeIcon, {}),
12887
+ codeStr: score?.reason || "null",
12888
+ simplified: true
12889
+ }
12890
+ ),
12891
+ /* @__PURE__ */ jsx(
12892
+ SideDialog.CodeSection,
12893
+ {
12894
+ title: "Input",
12895
+ icon: /* @__PURE__ */ jsx(FileInputIcon, {}),
12896
+ codeStr: JSON.stringify(score?.input || null, null, 2)
12897
+ }
12898
+ ),
12899
+ /* @__PURE__ */ jsx(
12900
+ SideDialog.CodeSection,
12901
+ {
12902
+ title: "Output",
12903
+ icon: /* @__PURE__ */ jsx(FileOutputIcon, {}),
12904
+ codeStr: JSON.stringify(score?.output || null, null, 2)
12905
+ }
12906
+ ),
12907
+ /* @__PURE__ */ jsx(
12908
+ SideDialog.CodeSection,
12909
+ {
12910
+ title: "Preprocess Prompt",
12911
+ icon: /* @__PURE__ */ jsx(ReceiptText, {}),
12912
+ codeStr: score?.preprocessPrompt || "null",
12913
+ simplified: true
12914
+ }
12915
+ ),
12916
+ /* @__PURE__ */ jsx(
12917
+ SideDialog.CodeSection,
12918
+ {
12919
+ title: "Analyze Prompt",
12920
+ icon: /* @__PURE__ */ jsx(ReceiptText, {}),
12921
+ codeStr: score?.analyzePrompt || "null",
12922
+ simplified: true
12923
+ }
12924
+ ),
12925
+ /* @__PURE__ */ jsx(
12926
+ SideDialog.CodeSection,
12927
+ {
12928
+ title: "Generate Score Prompt",
12929
+ icon: /* @__PURE__ */ jsx(ReceiptText, {}),
12930
+ codeStr: score?.generateScorePrompt || "null",
12931
+ simplified: true
12932
+ }
12933
+ ),
12934
+ /* @__PURE__ */ jsx(
12935
+ SideDialog.CodeSection,
12936
+ {
12937
+ title: "Generate Reason Prompt",
12938
+ icon: /* @__PURE__ */ jsx(ReceiptText, {}),
12939
+ codeStr: score?.generateReasonPrompt || "null",
12940
+ simplified: true
12941
+ }
12942
+ )
12943
+ ] })
12944
+ ] })
13161
12945
  ]
13162
12946
  }
13163
12947
  );
@@ -13298,7 +13082,7 @@ function ScorersTable({ scorers, isLoading }) {
13298
13082
  return /* @__PURE__ */ jsx(EmptyScorersTable, {});
13299
13083
  }
13300
13084
  const filteredRows = rows.filter((row) => row.original.scorer.config.name.toLowerCase().includes(search.toLowerCase()));
13301
- return /* @__PURE__ */ jsxs(Fragment, { children: [
13085
+ return /* @__PURE__ */ jsxs("div", { children: [
13302
13086
  /* @__PURE__ */ jsx(SearchbarWrapper, { children: /* @__PURE__ */ jsx(Searchbar, { onSearch: setSearch, label: "Search scorers", placeholder: "Search scorers" }) }),
13303
13087
  isLoading ? /* @__PURE__ */ jsx(ScorersTableSkeleton, {}) : /* @__PURE__ */ jsx(ScrollableContainer, { children: /* @__PURE__ */ jsxs(Table$1, { children: [
13304
13088
  /* @__PURE__ */ jsx(Thead, { className: "sticky top-0", children: ths.headers.map((header) => /* @__PURE__ */ jsx(Th, { style: { width: header.index === 0 ? "auto" : header.column.getSize() }, children: flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }),
@@ -13334,26 +13118,16 @@ const EmptyScorersTable = () => /* @__PURE__ */ jsx("div", { className: "flex h-
13334
13118
  }
13335
13119
  ) });
13336
13120
 
13337
- const variantClasses$1 = {
13338
- warning: "bg-yellow-900/20 border-sm border-yellow-200 text-yellow-200",
13339
- destructive: "bg-red-900/20 border-sm border-red-200 text-red-200"
13340
- };
13341
- const variantIcons = {
13342
- warning: TriangleAlert,
13343
- destructive: AlertCircle
13344
- };
13345
- const Alert = ({ children, variant = "destructive" }) => {
13346
- const Ico = variantIcons[variant];
13347
- return /* @__PURE__ */ jsx("div", { className: clsx(variantClasses$1[variant], "p-2 rounded-md"), children: /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2", children: [
13348
- /* @__PURE__ */ jsx(Icon, { className: "mt-0.5", children: /* @__PURE__ */ jsx(Ico, {}) }),
13349
- /* @__PURE__ */ jsx("div", { children })
13350
- ] }) });
13351
- };
13352
- const AlertTitle = ({ children, as: As = "h5" }) => {
13353
- return /* @__PURE__ */ jsx(Txt, { as: As, variant: "ui-md", className: "font-semibold", children });
13354
- };
13355
- const AlertDescription = ({ children, as: As = "p" }) => {
13356
- return /* @__PURE__ */ jsx(Txt, { as: As, variant: "ui-sm", children });
13121
+ const useTraceSpanScores = ({ traceId = "", spanId = "", page }) => {
13122
+ const client = useMastraClient();
13123
+ return useQuery({
13124
+ queryKey: ["trace-span-scores", traceId, spanId, page],
13125
+ queryFn: () => client.getScoresBySpan({ traceId, spanId, page: page || 0, perPage: 10 }),
13126
+ enabled: !!traceId && !!spanId,
13127
+ refetchInterval: 3e3,
13128
+ gcTime: 0,
13129
+ staleTime: 0
13130
+ });
13357
13131
  };
13358
13132
 
13359
13133
  const AgentMetadataModelSwitcher = ({
@@ -13362,6 +13136,8 @@ const AgentMetadataModelSwitcher = ({
13362
13136
  updateModel,
13363
13137
  apiUrl = "/api/agents/providers"
13364
13138
  }) => {
13139
+ const [originalProvider] = useState(defaultProvider);
13140
+ const [originalModel] = useState(defaultModel);
13365
13141
  const [selectedModel, setSelectedModel] = useState(defaultModel);
13366
13142
  const [showModelSuggestions, setShowModelSuggestions] = useState(false);
13367
13143
  const [selectedProvider, setSelectedProvider] = useState(defaultProvider || "");
@@ -13492,15 +13268,15 @@ const AgentMetadataModelSwitcher = ({
13492
13268
  if (modelInputRef.current === document.activeElement || providerInputRef.current === document.activeElement || showProviderSuggestions || showModelSuggestions) {
13493
13269
  return;
13494
13270
  }
13495
- const providerChanged = currentModelProvider && currentModelProvider !== defaultProvider;
13271
+ const providerChanged = currentModelProvider && currentModelProvider !== originalProvider;
13496
13272
  const modelEmpty = !selectedModel || selectedModel === "";
13497
13273
  if (providerChanged && modelEmpty) {
13498
- setSelectedProvider(cleanProviderId(defaultProvider));
13499
- setSelectedModel(defaultModel);
13500
- if (defaultProvider && defaultModel) {
13274
+ setSelectedProvider(cleanProviderId(originalProvider));
13275
+ setSelectedModel(originalModel);
13276
+ if (originalProvider && originalModel) {
13501
13277
  updateModel({
13502
- provider: defaultProvider,
13503
- modelId: defaultModel
13278
+ provider: originalProvider,
13279
+ modelId: originalModel
13504
13280
  }).catch((error) => {
13505
13281
  console.error("Failed to reset model:", error);
13506
13282
  });
@@ -13515,8 +13291,8 @@ const AgentMetadataModelSwitcher = ({
13515
13291
  registerResetFn,
13516
13292
  currentModelProvider,
13517
13293
  selectedModel,
13518
- defaultProvider,
13519
- defaultModel,
13294
+ originalProvider,
13295
+ originalModel,
13520
13296
  updateModel,
13521
13297
  showProviderSuggestions,
13522
13298
  showModelSuggestions
@@ -13527,6 +13303,27 @@ const AgentMetadataModelSwitcher = ({
13527
13303
  /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500", children: "Loading providers..." })
13528
13304
  ] });
13529
13305
  }
13306
+ const handleReset = async () => {
13307
+ setSelectedProvider(cleanProviderId(originalProvider));
13308
+ setSelectedModel(originalModel);
13309
+ setProviderSearch("");
13310
+ setModelSearch("");
13311
+ setIsSearchingProvider(false);
13312
+ setIsSearchingModel(false);
13313
+ setShowProviderSuggestions(false);
13314
+ setShowModelSuggestions(false);
13315
+ try {
13316
+ setLoading(true);
13317
+ await updateModel({
13318
+ provider: originalProvider,
13319
+ modelId: originalModel
13320
+ });
13321
+ } catch (error) {
13322
+ console.error("Failed to reset model:", error);
13323
+ } finally {
13324
+ setLoading(false);
13325
+ }
13326
+ };
13530
13327
  return /* @__PURE__ */ jsxs(Fragment, { children: [
13531
13328
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col xl:flex-row items-stretch xl:items-center gap-2 w-full", children: [
13532
13329
  /* @__PURE__ */ jsxs(
@@ -13579,6 +13376,7 @@ const AgentMetadataModelSwitcher = ({
13579
13376
  /* @__PURE__ */ jsx(
13580
13377
  Input,
13581
13378
  {
13379
+ "aria-label": "Search providers",
13582
13380
  spellCheck: "false",
13583
13381
  ref: providerInputRef,
13584
13382
  className: `w-full ${!isSearchingProvider && currentModelProvider ? "pl-8 pr-8" : ""}`,
@@ -13617,20 +13415,6 @@ const AgentMetadataModelSwitcher = ({
13617
13415
  handleProviderSelect(provider);
13618
13416
  }
13619
13417
  break;
13620
- case "Tab":
13621
- if (!e.shiftKey) {
13622
- e.preventDefault();
13623
- if (highlightedProviderIndex >= 0 && highlightedProviderIndex < filteredProviders2.length) {
13624
- const provider = filteredProviders2[highlightedProviderIndex];
13625
- handleProviderSelect(provider);
13626
- } else {
13627
- setShowProviderSuggestions(false);
13628
- setIsSearchingProvider(false);
13629
- setProviderSearch("");
13630
- setHighlightedProviderIndex(-1);
13631
- }
13632
- }
13633
- break;
13634
13418
  case "Escape":
13635
13419
  e.preventDefault();
13636
13420
  setIsSearchingProvider(false);
@@ -13639,8 +13423,6 @@ const AgentMetadataModelSwitcher = ({
13639
13423
  setShowProviderSuggestions(false);
13640
13424
  break;
13641
13425
  }
13642
- } else if (e.key === "Tab") {
13643
- return;
13644
13426
  }
13645
13427
  },
13646
13428
  onFocus: () => {
@@ -13732,6 +13514,7 @@ const AgentMetadataModelSwitcher = ({
13732
13514
  /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
13733
13515
  Input,
13734
13516
  {
13517
+ "aria-label": "Search models",
13735
13518
  spellCheck: "false",
13736
13519
  ref: modelInputRef,
13737
13520
  className: "w-full xl:w-3/5",
@@ -13784,7 +13567,6 @@ const AgentMetadataModelSwitcher = ({
13784
13567
  }, 0);
13785
13568
  break;
13786
13569
  case "Enter":
13787
- case "Tab":
13788
13570
  e.preventDefault();
13789
13571
  if (highlightedModelIndex >= 0 && highlightedModelIndex < filteredModels.length) {
13790
13572
  const model = filteredModels[highlightedModelIndex];
@@ -13869,14 +13651,26 @@ const AgentMetadataModelSwitcher = ({
13869
13651
  )
13870
13652
  ]
13871
13653
  }
13654
+ ),
13655
+ /* @__PURE__ */ jsx(
13656
+ Button$1,
13657
+ {
13658
+ variant: "light",
13659
+ size: "md",
13660
+ onClick: handleReset,
13661
+ disabled: loading,
13662
+ className: "flex items-center gap-1.5 text-xs whitespace-nowrap !border-0",
13663
+ title: "Reset to original model",
13664
+ children: /* @__PURE__ */ jsx(RotateCcw, { className: "w-3.5 h-3.5" })
13665
+ }
13872
13666
  )
13873
13667
  ] }),
13874
13668
  (() => {
13875
13669
  const currentProvider = providers.find((p) => p.id === currentModelProvider);
13876
13670
  if (currentProvider && !currentProvider.connected) {
13877
- return /* @__PURE__ */ jsx("div", { className: "pt-2 p-2", children: /* @__PURE__ */ jsxs(Alert, { variant: "warning", children: [
13878
- /* @__PURE__ */ jsx(AlertTitle, { as: "h5", children: "Provider not connected" }),
13879
- /* @__PURE__ */ jsxs(AlertDescription, { as: "p", children: [
13671
+ return /* @__PURE__ */ jsx("div", { className: "pt-2 p-2", children: /* @__PURE__ */ jsxs(Alert$1, { variant: "warning", children: [
13672
+ /* @__PURE__ */ jsx(AlertTitle$1, { as: "h5", children: "Provider not connected" }),
13673
+ /* @__PURE__ */ jsxs(AlertDescription$1, { as: "p", children: [
13880
13674
  "Set the",
13881
13675
  " ",
13882
13676
  /* @__PURE__ */ jsx("code", { className: "px-1 py-0.5 bg-yellow-100 dark:bg-yellow-900/50 rounded", children: Array.isArray(currentProvider.envVar) ? currentProvider.envVar.join(", ") : currentProvider.envVar }),
@@ -14017,7 +13811,7 @@ const AgentMetadataNetworkList = ({ agents }) => {
14017
13811
  if (agents.length === 0) {
14018
13812
  return /* @__PURE__ */ jsx(AgentMetadataListEmpty, { children: "No agents" });
14019
13813
  }
14020
- return /* @__PURE__ */ jsx(AgentMetadataList, { children: agents.map((agent) => /* @__PURE__ */ jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsx(Link, { href: paths.agentLink(agent.id), children: /* @__PURE__ */ jsx(Badge$1, { variant: "success", icon: /* @__PURE__ */ jsx(AgentIcon, {}), children: agent.name }) }) }, agent.id)) });
13814
+ return /* @__PURE__ */ jsx(AgentMetadataList, { children: agents.map((agent) => /* @__PURE__ */ jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsx(Link, { href: paths.agentLink(agent.id), "data-testid": "agent-badge", children: /* @__PURE__ */ jsx(Badge$1, { variant: "success", icon: /* @__PURE__ */ jsx(AgentIcon, {}), children: agent.name }) }) }, agent.id)) });
14021
13815
  };
14022
13816
  const AgentMetadata = ({
14023
13817
  agentId,
@@ -14050,7 +13844,7 @@ const AgentMetadata = ({
14050
13844
  {
14051
13845
  title: "Model",
14052
13846
  hint: modelVersion === "v2" ? void 0 : {
14053
- link: "https://mastra.ai/en/reference/agents/migration-guide",
13847
+ link: "https://mastra.ai/guides/migrations/vnext-to-standard-apis",
14054
13848
  title: "You are using a legacy v1 model",
14055
13849
  icon: /* @__PURE__ */ jsx(AlertTriangleIcon, { fontSize: 14, className: "mb-0.5" })
14056
13850
  },
@@ -14073,9 +13867,12 @@ const AgentMetadata = ({
14073
13867
  link: "https://mastra.ai/en/docs/agents/agent-memory",
14074
13868
  title: "Agent Memory documentation"
14075
13869
  },
14076
- children: hasMemoryEnabled ? /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(MemoryIcon, {}), variant: "success", className: "font-medium", children: "On" }) : /* @__PURE__ */ jsxs(Alert, { variant: "warning", children: [
14077
- /* @__PURE__ */ jsx(AlertTitle, { as: "h5", children: "Memory not enabled" }),
14078
- /* @__PURE__ */ jsxs(AlertDescription, { as: "p", children: [
13870
+ children: hasMemoryEnabled ? /* @__PURE__ */ jsxs(Badge$1, { icon: /* @__PURE__ */ jsx(MemoryIcon, {}), variant: "success", className: "font-medium", children: [
13871
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Memory is enabled" }),
13872
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "On" })
13873
+ ] }) : /* @__PURE__ */ jsxs(Alert$1, { variant: "warning", children: [
13874
+ /* @__PURE__ */ jsx(AlertTitle$1, { as: "h5", children: "Memory not enabled" }),
13875
+ /* @__PURE__ */ jsxs(AlertDescription$1, { as: "p", children: [
14079
13876
  "Thread messages will not be stored. To activate memory, see the",
14080
13877
  " ",
14081
13878
  /* @__PURE__ */ jsx(
@@ -14135,14 +13932,14 @@ const AgentMetadataToolList = ({ tools, agentId }) => {
14135
13932
  if (tools.length === 0) {
14136
13933
  return /* @__PURE__ */ jsx(AgentMetadataListEmpty, { children: "No tools" });
14137
13934
  }
14138
- return /* @__PURE__ */ jsx(AgentMetadataList, { children: tools.map((tool) => /* @__PURE__ */ jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsx(Link, { href: paths.agentToolLink(agentId, tool.id), children: /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(ToolsIcon, { className: "text-[#ECB047]" }), children: tool.id }) }) }, tool.id)) });
13935
+ return /* @__PURE__ */ jsx(AgentMetadataList, { children: tools.map((tool) => /* @__PURE__ */ jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsx(Link, { href: paths.agentToolLink(agentId, tool.id), "data-testid": "tool-badge", children: /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(ToolsIcon, { className: "text-[#ECB047]" }), children: tool.id }) }) }, tool.id)) });
14139
13936
  };
14140
13937
  const AgentMetadataWorkflowList = ({ workflows }) => {
14141
13938
  const { Link, paths } = useLinkComponent();
14142
13939
  if (workflows.length === 0) {
14143
13940
  return /* @__PURE__ */ jsx(AgentMetadataListEmpty, { children: "No workflows" });
14144
13941
  }
14145
- return /* @__PURE__ */ jsx(AgentMetadataList, { children: workflows.map((workflow) => /* @__PURE__ */ jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsx(Link, { href: paths.workflowLink(workflow.id), children: /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(WorkflowIcon, { className: "text-accent3" }), children: workflow.name }) }) }, workflow.id)) });
13942
+ return /* @__PURE__ */ jsx(AgentMetadataList, { children: workflows.map((workflow) => /* @__PURE__ */ jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsx(Link, { href: paths.workflowLink(workflow.id), "data-testid": "workflow-badge", children: /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(WorkflowIcon, { className: "text-accent3" }), children: workflow.name }) }) }, workflow.id)) });
14146
13943
  };
14147
13944
  const AgentMetadataScorerList = ({ entityId, entityType }) => {
14148
13945
  const { Link, paths } = useLinkComponent();
@@ -14160,7 +13957,7 @@ const AgentMetadataScorerList = ({ entityId, entityType }) => {
14160
13957
  if (scorerList.length === 0) {
14161
13958
  return /* @__PURE__ */ jsx(AgentMetadataListEmpty, { children: "No Scorers" });
14162
13959
  }
14163
- return /* @__PURE__ */ jsx(AgentMetadataList, { children: scorerList.map((scorer) => /* @__PURE__ */ jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsx(Link, { href: paths.scorerLink(scorer.id), children: /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(GaugeIcon, { className: "text-icon3" }), children: scorer.scorer.config.name }) }) }, scorer.id)) });
13960
+ return /* @__PURE__ */ jsx(AgentMetadataList, { children: scorerList.map((scorer) => /* @__PURE__ */ jsx(AgentMetadataListItem, { children: /* @__PURE__ */ jsx(Link, { href: paths.scorerLink(scorer.id), "data-testid": "scorer-badge", children: /* @__PURE__ */ jsx(Badge$1, { icon: /* @__PURE__ */ jsx(GaugeIcon, { className: "text-icon3" }), children: scorer.scorer.config.name }) }) }, scorer.id)) });
14164
13961
  };
14165
13962
 
14166
13963
  const AgentMetadataPrompt = ({ prompt }) => {
@@ -14455,7 +14252,7 @@ function ToolTable({ tools, agents, isLoading }) {
14455
14252
  return /* @__PURE__ */ jsx(EmptyToolsTable, {});
14456
14253
  }
14457
14254
  const filteredRows = rows.filter((row) => row.original.id.toLowerCase().includes(search.toLowerCase()));
14458
- return /* @__PURE__ */ jsxs(Fragment, { children: [
14255
+ return /* @__PURE__ */ jsxs("div", { children: [
14459
14256
  /* @__PURE__ */ jsx(SearchbarWrapper, { children: /* @__PURE__ */ jsx(Searchbar, { onSearch: setSearch, label: "Search tools", placeholder: "Search tools" }) }),
14460
14257
  isLoading ? /* @__PURE__ */ jsx(ToolTableSkeleton, {}) : /* @__PURE__ */ jsx(ScrollableContainer, { children: /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Table$1, { children: [
14461
14258
  /* @__PURE__ */ jsx(Thead, { className: "sticky top-0", children: ths.headers.map((header) => /* @__PURE__ */ jsx(Th, { style: { width: header.column.getSize() ?? "auto" }, children: flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }),
@@ -16158,12 +15955,51 @@ function TreePositionMark({ isLastChild, hasChildren = false }) {
16158
15955
  'after:content-[""] after:absolute after:left-0 after:top-0 after:bottom-0 after:w-[0px] after:border-r-[0.5px] after:border-white after:border-dashed',
16159
15956
  'before:content-[""] before:absolute before:left-0 before:top-[50%] before:w-full before:h-[0px] before:border-b-[0.5px] before:border-white before:border-dashed',
16160
15957
  {
16161
- "after:bottom-[50%]": isLastChild
16162
- }
16163
- ),
16164
- children: hasChildren && /* @__PURE__ */ jsx("div", { className: "absolute -right-[1px] top-[50%] bottom-0 w-[0px] border-r-[0.5px] border-white border-dashed" })
15958
+ "after:bottom-[50%]": isLastChild
15959
+ }
15960
+ ),
15961
+ children: hasChildren && /* @__PURE__ */ jsx("div", { className: "absolute -right-[1px] top-[50%] bottom-0 w-[0px] border-r-[0.5px] border-white border-dashed" })
15962
+ }
15963
+ );
15964
+ }
15965
+
15966
+ function TraceTimeline({ hierarchicalSpans = [], onSpanClick, selectedSpanId, isLoading }) {
15967
+ const overallLatency = hierarchicalSpans?.[0]?.latency || 0;
15968
+ const overallStartTime = hierarchicalSpans?.[0]?.startTime || "";
15969
+ const overallEndTime = hierarchicalSpans?.[0]?.endTime || "";
15970
+ return /* @__PURE__ */ jsx(Fragment, { children: isLoading ? /* @__PURE__ */ jsxs(
15971
+ "div",
15972
+ {
15973
+ className: cn(
15974
+ "flex items-center text-[0.875rem] gap-[1rem] bg-surface3/50 rounded-md p-[1.5rem] justify-center text-icon3",
15975
+ "[&_svg]:w-[1.25em] [&_svg]:h-[1.25em] [&_svg]:opacity-50"
15976
+ ),
15977
+ children: [
15978
+ /* @__PURE__ */ jsx(Spinner, {}),
15979
+ " Loading Trace Timeline ..."
15980
+ ]
15981
+ }
15982
+ ) : /* @__PURE__ */ jsx(
15983
+ "div",
15984
+ {
15985
+ className: cn("grid items-start content-start gap-y-[2px] overflow-hidden", "xl:gap-x-[1rem] xl:py-[1rem]", {
15986
+ "xl:grid-cols-[3fr_auto]": !overallEndTime,
15987
+ "xl:grid-cols-[3fr_2fr]": overallEndTime
15988
+ }),
15989
+ children: hierarchicalSpans?.map((span) => /* @__PURE__ */ jsx(
15990
+ TraceTimelineSpan,
15991
+ {
15992
+ span,
15993
+ onSpanClick,
15994
+ selectedSpanId,
15995
+ overallLatency,
15996
+ overallStartTime,
15997
+ overallEndTime
15998
+ },
15999
+ span.id
16000
+ ))
16165
16001
  }
16166
- );
16002
+ ) });
16167
16003
  }
16168
16004
 
16169
16005
  function TraceTimelineLegend({ spans = [] }) {
@@ -16179,65 +16015,6 @@ function TraceTimelineLegend({ spans = [] }) {
16179
16015
  }) });
16180
16016
  }
16181
16017
 
16182
- function TraceTimeline({
16183
- spans = [],
16184
- hierarchicalSpans = [],
16185
- onSpanClick,
16186
- selectedSpanId,
16187
- isLoading,
16188
- className
16189
- }) {
16190
- const overallLatency = hierarchicalSpans?.[0]?.latency || 0;
16191
- const overallStartTime = hierarchicalSpans?.[0]?.startTime || "";
16192
- const overallEndTime = hierarchicalSpans?.[0]?.endTime || "";
16193
- return /* @__PURE__ */ jsxs("div", { className: cn("grid gap-[1rem]", className), children: [
16194
- /* @__PURE__ */ jsxs("div", { className: "flex w-full justify-between pr-[2.5rem]", children: [
16195
- /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", children: [
16196
- /* @__PURE__ */ jsx(ListTreeIcon, {}),
16197
- " Timeline"
16198
- ] }),
16199
- /* @__PURE__ */ jsx(TraceTimelineLegend, { spans })
16200
- ] }),
16201
- isLoading ? /* @__PURE__ */ jsxs(
16202
- "div",
16203
- {
16204
- className: cn(
16205
- "flex items-center text-[0.875rem] gap-[1rem] bg-surface3/50 rounded-md p-[1.5rem] mr-[1.5rem] justify-center text-icon3 mt-[.5rem]",
16206
- "[&_svg]:w-[1.25em] [&_svg]:h-[1.25em] [&_svg]:opacity-50"
16207
- ),
16208
- children: [
16209
- /* @__PURE__ */ jsx(Spinner, {}),
16210
- " Loading Trace Timeline ..."
16211
- ]
16212
- }
16213
- ) : /* @__PURE__ */ jsx(
16214
- "div",
16215
- {
16216
- className: cn(
16217
- "grid items-start content-start gap-y-[2px] bg-surface2 rounded-lg overflow-hidden pl-[1.5rem] py-[1.5rem]",
16218
- "xl:gap-x-[1rem] xl:py-[1rem]",
16219
- {
16220
- "xl:grid-cols-[3fr_auto]": !overallEndTime,
16221
- "xl:grid-cols-[3fr_2fr]": overallEndTime
16222
- }
16223
- ),
16224
- children: hierarchicalSpans?.map((span) => /* @__PURE__ */ jsx(
16225
- TraceTimelineSpan,
16226
- {
16227
- span,
16228
- onSpanClick,
16229
- selectedSpanId,
16230
- overallLatency,
16231
- overallStartTime,
16232
- overallEndTime
16233
- },
16234
- span.id
16235
- ))
16236
- }
16237
- )
16238
- ] });
16239
- }
16240
-
16241
16018
  function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
16242
16019
  if (!traceUsage && !spanUsage) {
16243
16020
  console.warn("No usage data available");
@@ -16350,12 +16127,11 @@ function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
16350
16127
  icon: /* @__PURE__ */ jsx(CoinsIcon, {})
16351
16128
  }
16352
16129
  };
16353
- let tokenPresentations = {};
16354
- if (hasV5Format) {
16355
- tokenPresentations = { ...commonTokenPresentations, ...v5TokenPresentations };
16356
- } else {
16357
- tokenPresentations = { ...commonTokenPresentations, ...legacyTokenPresentations };
16358
- }
16130
+ let tokenPresentations = {
16131
+ ...commonTokenPresentations,
16132
+ ...v5TokenPresentations,
16133
+ ...legacyTokenPresentations
16134
+ };
16359
16135
  let usageKeyOrder = [];
16360
16136
  if (hasV5Format) {
16361
16137
  usageKeyOrder = ["totalTokens", "inputTokens", "outputTokens", "reasoningTokens", "cachedInputTokens"];
@@ -16363,55 +16139,42 @@ function TraceSpanUsage({ traceUsage, traceSpans = [], spanUsage, className }) {
16363
16139
  usageKeyOrder = ["totalTokens", "promptTokens", "completionTokens"];
16364
16140
  }
16365
16141
  const usageAsArray = Object.entries(traceUsage || spanUsage || {}).map(([key, value]) => ({ key, value })).sort((a, b) => usageKeyOrder.indexOf(a.key) - usageKeyOrder.indexOf(b.key));
16366
- return /* @__PURE__ */ jsx(
16142
+ return /* @__PURE__ */ jsx("div", { className: cn("flex gap-[1.5rem] flex-wrap", className), children: usageAsArray.map(({ key, value }) => /* @__PURE__ */ jsxs(
16367
16143
  "div",
16368
16144
  {
16369
- className: cn(
16370
- "grid gap-[1.5rem]",
16371
- {
16372
- "xl:grid-cols-3": usageAsArray.length === 3,
16373
- "xl:grid-cols-2": usageAsArray.length === 2
16374
- },
16375
- className
16376
- ),
16377
- children: usageAsArray.map(({ key, value }) => /* @__PURE__ */ jsxs(
16378
- "div",
16379
- {
16380
- className: cn("bg-white/5 p-[1rem] px-[1.25rem] rounded-lg text-[0.875rem]", {
16381
- "min-h-[5.5rem]": traceUsage
16382
- }),
16383
- children: [
16384
- /* @__PURE__ */ jsxs(
16385
- "div",
16386
- {
16387
- className: cn(
16388
- "grid grid-cols-[1.5rem_1fr_auto] gap-[.5rem] items-center",
16389
- "[&>svg]:w-[1.5em] [&>svg]:h-[1.5em] [&>svg]:opacity-70"
16390
- ),
16391
- children: [
16392
- tokenPresentations?.[key]?.icon,
16393
- /* @__PURE__ */ jsx("span", { className: "text-[0.875rem]", children: tokenPresentations?.[key]?.label }),
16394
- /* @__PURE__ */ jsx("b", { className: "text-[1rem]", children: value })
16395
- ]
16396
- }
16145
+ className: cn("bg-white/5 p-[.75rem] px-[1rem] rounded-lg text-[0.875rem] flex-grow", {
16146
+ "min-h-[5.5rem]": traceUsage
16147
+ }),
16148
+ children: [
16149
+ /* @__PURE__ */ jsxs(
16150
+ "div",
16151
+ {
16152
+ className: cn(
16153
+ "grid grid-cols-[1.5rem_1fr_auto] gap-[.5rem] items-center",
16154
+ "[&>svg]:w-[1.5em] [&>svg]:h-[1.5em] [&>svg]:opacity-70"
16397
16155
  ),
16398
- tokensByProviderValid && /* @__PURE__ */ jsx("div", { className: "text-[0.875rem] mt-[0.5rem] pl-[2rem] ", children: Object.entries(tokensByProvider).map(([provider, providerTokens]) => /* @__PURE__ */ jsxs(
16399
- "dl",
16400
- {
16401
- className: "grid grid-cols-[1fr_auto] gap-x-[1rem] gap-y-[.25rem] justify-between text-icon3",
16402
- children: [
16403
- /* @__PURE__ */ jsx("dt", { children: provider }),
16404
- /* @__PURE__ */ jsx("dd", { children: providerTokens?.[key] })
16405
- ]
16406
- },
16407
- provider
16408
- )) })
16409
- ]
16410
- },
16411
- key
16412
- ))
16413
- }
16414
- );
16156
+ children: [
16157
+ tokenPresentations?.[key]?.icon,
16158
+ /* @__PURE__ */ jsx("span", { className: "text-[0.875rem]", children: tokenPresentations?.[key]?.label }),
16159
+ /* @__PURE__ */ jsx("b", { className: "text-[1rem]", children: value })
16160
+ ]
16161
+ }
16162
+ ),
16163
+ tokensByProviderValid && /* @__PURE__ */ jsx("div", { className: "text-[0.875rem] mt-[0.5rem] pl-[2rem]", children: Object.entries(tokensByProvider).map(([provider, providerTokens]) => /* @__PURE__ */ jsxs(
16164
+ "dl",
16165
+ {
16166
+ className: "grid grid-cols-[1fr_auto] gap-x-[1rem] gap-y-[.25rem] justify-between text-icon3",
16167
+ children: [
16168
+ /* @__PURE__ */ jsx("dt", { children: provider }),
16169
+ /* @__PURE__ */ jsx("dd", { children: providerTokens?.[key] })
16170
+ ]
16171
+ },
16172
+ provider
16173
+ )) })
16174
+ ]
16175
+ },
16176
+ key
16177
+ )) });
16415
16178
  }
16416
16179
 
16417
16180
  function useTraceInfo(trace) {
@@ -16494,253 +16257,199 @@ function getSpanInfo({ span, withTraceId = true, withSpanId = true }) {
16494
16257
  return baseInfo;
16495
16258
  }
16496
16259
 
16497
- const ScoreTable = ({ scores, onItemClick }) => {
16498
- return /* @__PURE__ */ jsxs(Table$1, { children: [
16499
- /* @__PURE__ */ jsxs(Thead, { children: [
16500
- /* @__PURE__ */ jsx(Th, { children: "Type" }),
16501
- /* @__PURE__ */ jsx(Th, { children: "Scorer" }),
16502
- /* @__PURE__ */ jsx(Th, { children: "Score" }),
16503
- /* @__PURE__ */ jsx(Th, { children: "Created At" })
16504
- ] }),
16505
- /* @__PURE__ */ jsx(Tbody, { children: scores.map((score) => /* @__PURE__ */ jsxs(Row, { onClick: () => onItemClick(score.scorerName), children: [
16506
- /* @__PURE__ */ jsx(TxtCell, { children: /* @__PURE__ */ jsx(Badge$1, { children: score.type }) }),
16507
- /* @__PURE__ */ jsx(TxtCell, { children: score.scorerName }),
16508
- /* @__PURE__ */ jsx(TxtCell, { children: score.score }),
16509
- /* @__PURE__ */ jsx(DateTimeCell, { dateTime: new Date(score.createdAt) })
16510
- ] }, score.scoreId)) })
16511
- ] });
16260
+ const TabsRoot = ({
16261
+ children,
16262
+ defaultTab,
16263
+ value,
16264
+ onValueChange,
16265
+ className
16266
+ }) => {
16267
+ const [internalTab, setInternalTab] = useState(defaultTab);
16268
+ const isControlled = value !== void 0 && onValueChange !== void 0;
16269
+ const currentTab = isControlled ? value : internalTab;
16270
+ const handleTabChange = (newValue) => {
16271
+ const typedValue = newValue;
16272
+ if (isControlled) {
16273
+ onValueChange(typedValue);
16274
+ } else {
16275
+ setInternalTab(typedValue);
16276
+ }
16277
+ };
16278
+ return /* @__PURE__ */ jsx(
16279
+ TabsPrimitive.Root,
16280
+ {
16281
+ value: currentTab,
16282
+ onValueChange: handleTabChange,
16283
+ className: cn("grid gap-[3rem] overflow-y-auto", className),
16284
+ children
16285
+ }
16286
+ );
16512
16287
  };
16513
16288
 
16514
- function SpanDetails({ span, onScorerTriggered }) {
16515
- if (!span) {
16516
- return null;
16517
- }
16518
- return /* @__PURE__ */ jsxs("div", { className: "grid gap-[1.5rem] mb-[2rem]", children: [
16519
- /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Input", codeStr: JSON.stringify(span.input || null, null, 2) }),
16520
- /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Output", codeStr: JSON.stringify(span.output || null, null, 2) }),
16521
- /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Metadata", codeStr: JSON.stringify(span.metadata || null, null, 2) }),
16522
- /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Attributes", codeStr: JSON.stringify(span.attributes || null, null, 2) }),
16523
- span?.links?.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-[2.5rem] pr-[2.5rem]", children: [
16524
- /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", className: "pb-[1rem]", children: [
16525
- /* @__PURE__ */ jsx(GaugeIcon, {}),
16526
- " Scores"
16527
- ] }),
16528
- /* @__PURE__ */ jsx("div", { className: "bg-surface2 rounded-lg overflow-hidden border-sm border-border1", children: /* @__PURE__ */ jsx(
16529
- ScoreTable,
16289
+ const TabList = ({ children, variant = "default", className }) => {
16290
+ return /* @__PURE__ */ jsx("div", { className: cn("w-full overflow-x-auto", className), children: /* @__PURE__ */ jsx(
16291
+ TabsPrimitive.List,
16292
+ {
16293
+ className: cn(
16294
+ "flex items-center",
16530
16295
  {
16531
- scores: span?.links,
16532
- onItemClick: (scorerName) => onScorerTriggered(scorerName, span.traceId, span.spanId)
16533
- }
16534
- ) })
16535
- ] })
16536
- ] });
16537
- }
16296
+ // variant: default
16297
+ "text-[0.9375rem]": variant === "default",
16298
+ "[&>button]:py-[0.5rem] [&>button]:px-[1.5rem] [&>button]:font-normal [&>button]:text-icon3 [&>button]:flex-1 [&>button]:border-b [&>button]:border-border1": variant === "default",
16299
+ "[&>button[data-state=active]]:text-icon5 [&>button[data-state=active]]:transition-colors [&>button[data-state=active]]:duration-200 [&>button[data-state=active]]:border-icon3": variant === "default",
16300
+ // variant: buttons
16301
+ "border border-border1 flex justify-stretch rounded-md overflow-hidden text-[0.875rem] min-h-[2.5rem]": variant === "buttons",
16302
+ "[&>button]:flex-1 [&>button]:py-[0.5rem] [&>button]:px-[1rem] [&>button]:text-icon3": variant === "buttons",
16303
+ "[&>button[data-state=active]]:text-icon5 [&>button[data-state=active]]:bg-[#222]": variant === "buttons"
16304
+ },
16305
+ className
16306
+ ),
16307
+ children
16308
+ }
16309
+ ) });
16310
+ };
16538
16311
 
16539
- const DropdownMenu = DropdownMenuPrimitive.Root;
16540
- const DropdownMenuGroup = DropdownMenuPrimitive.Group;
16541
- const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
16542
- const DropdownMenuSub = DropdownMenuPrimitive.Sub;
16543
- const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
16544
- const DropdownMenuTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Trigger, { ref, className: cn("cursor-pointer focus-visible:rounded", className), ...props, children }));
16545
- DropdownMenuTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName;
16546
- const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
16547
- DropdownMenuPrimitive.SubTrigger,
16548
- {
16549
- ref,
16550
- className: cn(
16551
- "focus:bg-accent data-[state=open]:bg-accent flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm",
16552
- inset && "pl-8",
16553
- className
16554
- ),
16555
- ...props,
16556
- children: [
16557
- children,
16558
- /* @__PURE__ */ jsx(ChevronDown, { className: "ml-auto -rotate-90" })
16559
- ]
16560
- }
16561
- ));
16562
- DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
16563
- const DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16564
- DropdownMenuPrimitive.SubContent,
16565
- {
16566
- ref,
16567
- className: cn(
16568
- "popover-background data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 z-50 min-w-[8rem] overflow-auto overflow-x-hidden rounded-none p-1",
16569
- className
16570
- ),
16571
- ...props
16572
- }
16573
- ));
16574
- DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
16575
- const DropdownMenuContent = React.forwardRef(({ className, container, sideOffset = 4, ...props }, ref) => {
16576
- return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { container, children: /* @__PURE__ */ jsx(
16577
- DropdownMenuPrimitive.Content,
16312
+ const Tab = ({ children, value, onClick, className }) => {
16313
+ return /* @__PURE__ */ jsx(TabsPrimitive.Trigger, { value, className: cn("hover:text-icon5", className), onClick, children });
16314
+ };
16315
+
16316
+ const TabContent = ({ children, value, className }) => {
16317
+ return /* @__PURE__ */ jsx(
16318
+ TabsPrimitive.Content,
16578
16319
  {
16579
- ref,
16580
- sideOffset,
16581
- className: clsx(
16582
- "data-[state=open]:fade-in-0 data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 bg-surface2 text-icon3 border-sm border-border1 z-50 min-w-[8rem] overflow-auto rounded-md p-1 shadow-md",
16320
+ value,
16321
+ className: cn(
16322
+ "grid overflow-y-auto ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:none",
16583
16323
  className
16584
16324
  ),
16585
- ...props
16325
+ children
16586
16326
  }
16587
- ) });
16327
+ );
16328
+ };
16329
+
16330
+ const Tabs = Object.assign(TabsRoot, {
16331
+ List: TabList,
16332
+ Tab,
16333
+ Content: TabContent
16588
16334
  });
16589
- DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
16590
- const DropdownMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
16591
- DropdownMenuPrimitive.Item,
16592
- {
16593
- ref,
16594
- className: cn(
16595
- "focus:text-accent-foreground relative flex cursor-default cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 font-sans text-[0.8125rem] transition-colors focus:bg-[#66686A]/20 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&>span]:truncate",
16596
- inset && "pl-8",
16597
- className
16598
- ),
16599
- ...props
16335
+
16336
+ function SpanDetails({ span }) {
16337
+ if (!span) {
16338
+ return null;
16600
16339
  }
16601
- ));
16602
- DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
16603
- const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
16604
- DropdownMenuPrimitive.CheckboxItem,
16605
- {
16606
- ref,
16607
- className: cn(
16608
- "focus:bg-accent focus:text-accent-foreground relative flex w-full cursor-default cursor-pointer select-none items-center gap-4 rounded-sm px-2 py-1.5 text-sm transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
16609
- className
16340
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
16341
+ /* @__PURE__ */ jsx(
16342
+ SideDialog.CodeSection,
16343
+ {
16344
+ title: "Input",
16345
+ icon: /* @__PURE__ */ jsx(FileInputIcon, {}),
16346
+ codeStr: JSON.stringify(span.input || null, null, 2)
16347
+ }
16610
16348
  ),
16611
- checked,
16612
- ...props,
16613
- children: [
16614
- /* @__PURE__ */ jsx("div", { className: "border-sm border-border1 flex h-4 w-4 items-center justify-center rounded-sm", children: checked && /* @__PURE__ */ jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsx(Check, {}) }) }),
16615
- children
16616
- ]
16617
- }
16618
- ));
16619
- DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
16620
- const DropdownMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
16621
- DropdownMenuPrimitive.RadioItem,
16622
- {
16623
- ref,
16624
- className: cn(
16625
- "focus:text-accent-foreground relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm transition-colors focus:bg-[#66686A]/20 data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
16626
- className
16349
+ /* @__PURE__ */ jsx(
16350
+ SideDialog.CodeSection,
16351
+ {
16352
+ title: "Output",
16353
+ icon: /* @__PURE__ */ jsx(FileOutputIcon, {}),
16354
+ codeStr: JSON.stringify(span.output || null, null, 2)
16355
+ }
16627
16356
  ),
16628
- ...props,
16629
- children: [
16630
- /* @__PURE__ */ jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsx(DropdownMenuPrimitive.ItemIndicator, { children: /* @__PURE__ */ jsx(Circle, { className: "h-2 w-2 fill-current" }) }) }),
16631
- children
16632
- ]
16633
- }
16634
- ));
16635
- DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
16636
- const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
16637
- DropdownMenuPrimitive.Label,
16638
- {
16639
- ref,
16640
- className: cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className),
16641
- ...props
16642
- }
16643
- ));
16644
- DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
16645
- const DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
16646
- DropdownMenuPrimitive.Separator,
16647
- {
16648
- ref,
16649
- className: cn("popover-dividers-bg -mx-1 my-1 h-px", className),
16650
- ...props
16651
- }
16652
- ));
16653
- DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
16654
- const DropdownMenuShortcut = ({ className, ...props }) => {
16655
- return /* @__PURE__ */ jsx("span", { className: cn("ml-auto text-xs tracking-widest opacity-60", className), ...props });
16656
- };
16657
- DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
16658
- function Dropdown({
16659
- open,
16660
- onOpenChange,
16661
- children,
16662
- modal
16663
- }) {
16664
- return /* @__PURE__ */ jsx(DropdownMenu, { modal, open, onOpenChange, children });
16357
+ /* @__PURE__ */ jsx(
16358
+ SideDialog.CodeSection,
16359
+ {
16360
+ title: "Metadata",
16361
+ icon: /* @__PURE__ */ jsx(BracesIcon, {}),
16362
+ codeStr: JSON.stringify(span.metadata || null, null, 2)
16363
+ }
16364
+ ),
16365
+ /* @__PURE__ */ jsx(
16366
+ SideDialog.CodeSection,
16367
+ {
16368
+ title: "Attributes",
16369
+ icon: /* @__PURE__ */ jsx(BracesIcon, {}),
16370
+ codeStr: JSON.stringify(span.attributes || null, null, 2)
16371
+ }
16372
+ )
16373
+ ] });
16665
16374
  }
16666
- Dropdown.Trigger = DropdownMenuTrigger;
16667
- Dropdown.Content = DropdownMenuContent;
16668
- Dropdown.Group = DropdownMenuGroup;
16669
- Dropdown.Portal = DropdownMenuPortal;
16670
- Dropdown.Item = DropdownMenuItem;
16671
- Dropdown.CheckboxItem = DropdownMenuCheckboxItem;
16672
- Dropdown.RadioItem = DropdownMenuRadioItem;
16673
- Dropdown.Label = DropdownMenuLabel;
16674
- Dropdown.Separator = DropdownMenuSeparator;
16675
- Dropdown.Shortcut = DropdownMenuShortcut;
16676
- Dropdown.Sub = DropdownMenuSub;
16677
- Dropdown.SubContent = DropdownMenuSubContent;
16678
- Dropdown.SubTrigger = DropdownMenuSubTrigger;
16679
- Dropdown.RadioGroup = DropdownMenuRadioGroup;
16680
-
16681
- const useTriggerScorer = (onScorerTriggered) => {
16682
- const client = useMastraClient();
16683
- return useMutation({
16684
- mutationFn: async ({ scorerName, traceId, spanId }) => {
16685
- const response = await client.score({
16686
- scorerName,
16687
- targets: [{ traceId, spanId }]
16688
- });
16689
- return response;
16690
- },
16691
- onSuccess: (_, variables) => {
16692
- toast.success("Scorer triggered successfully");
16693
- onScorerTriggered(variables.scorerName, variables.traceId, variables.spanId);
16694
- },
16695
- onError: () => {
16696
- toast.error("Error triggering scorer");
16697
- }
16698
- });
16699
- };
16700
16375
 
16701
- const ScorersDropdown = ({ trace, spanId, onScorerTriggered, entityType }) => {
16702
- const { data: scorers = {}, isLoading } = useScorers();
16703
- const { mutate: triggerScorer, isPending } = useTriggerScorer(onScorerTriggered);
16704
- let scorerList = Object.entries(scorers).map(([key, scorer]) => ({
16705
- id: key,
16706
- name: scorer.scorer.config.name,
16707
- description: scorer.scorer.config.description,
16708
- isRegistered: scorer.isRegistered,
16709
- type: scorer.scorer.config.type
16710
- })).filter((scorer) => scorer.isRegistered);
16711
- if (entityType !== "Agent" || spanId) {
16712
- scorerList = scorerList.filter((scorer) => scorer.type !== "agent");
16376
+ function SpanTabs({
16377
+ trace,
16378
+ span,
16379
+ spanScoresData,
16380
+ onSpanScoresPageChange,
16381
+ isLoadingSpanScoresData,
16382
+ spanInfo = [],
16383
+ defaultActiveTab = "details",
16384
+ initialScoreId,
16385
+ computeTraceLink
16386
+ }) {
16387
+ const { Link } = useLinkComponent();
16388
+ let entityType;
16389
+ if (span?.attributes?.agentId) {
16390
+ entityType = "Agent";
16391
+ } else if (span?.attributes?.workflowId) {
16392
+ entityType = "Workflow";
16713
16393
  }
16714
- const isWaiting = isPending || isLoading;
16715
- return /* @__PURE__ */ jsxs(Dropdown, { children: [
16716
- /* @__PURE__ */ jsx(Dropdown.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button$1, { variant: "light", disabled: isWaiting, children: [
16717
- isWaiting ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Spinner, {}) }) : /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(GaugeIcon, {}) }),
16718
- "Run scorer",
16719
- /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronDown, {}) })
16394
+ return /* @__PURE__ */ jsxs(Tabs, { defaultTab: defaultActiveTab, children: [
16395
+ /* @__PURE__ */ jsxs(Tabs.List, { children: [
16396
+ /* @__PURE__ */ jsx(Tabs.Tab, { value: "details", children: "Details" }),
16397
+ /* @__PURE__ */ jsxs(Tabs.Tab, { value: "scores", children: [
16398
+ "Scoring ",
16399
+ spanScoresData?.pagination && `(${spanScoresData.pagination.total || 0})`
16400
+ ] })
16401
+ ] }),
16402
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "details", children: /* @__PURE__ */ jsxs(Sections, { children: [
16403
+ span?.attributes?.usage && /* @__PURE__ */ jsx(TraceSpanUsage, { spanUsage: span.attributes.usage }),
16404
+ /* @__PURE__ */ jsx(KeyValueList, { data: spanInfo, LinkComponent: Link }),
16405
+ /* @__PURE__ */ jsx(SpanDetails, { span })
16720
16406
  ] }) }),
16721
- /* @__PURE__ */ jsx(Dropdown.Content, { children: scorerList.map((scorer) => /* @__PURE__ */ jsx(
16722
- Dropdown.Item,
16723
- {
16724
- onClick: () => triggerScorer({ scorerName: scorer.name, traceId: trace.traceId, spanId }),
16725
- children: /* @__PURE__ */ jsx("span", { children: scorer.name })
16726
- },
16727
- scorer.id
16728
- )) })
16407
+ /* @__PURE__ */ jsx(Tabs.Content, { value: "scores", children: /* @__PURE__ */ jsxs(Sections, { children: [
16408
+ /* @__PURE__ */ jsxs(Section, { children: [
16409
+ /* @__PURE__ */ jsx(Section.Header, { children: /* @__PURE__ */ jsxs(Section.Heading, { children: [
16410
+ /* @__PURE__ */ jsx(CircleGaugeIcon, {}),
16411
+ " Scoring"
16412
+ ] }) }),
16413
+ /* @__PURE__ */ jsx(SpanScoring, { traceId: trace?.traceId, spanId: span?.spanId, entityType })
16414
+ ] }),
16415
+ /* @__PURE__ */ jsxs(Section, { children: [
16416
+ /* @__PURE__ */ jsx(Section.Header, { children: /* @__PURE__ */ jsxs(Section.Heading, { children: [
16417
+ /* @__PURE__ */ jsx(CircleGaugeIcon, {}),
16418
+ " Scores"
16419
+ ] }) }),
16420
+ /* @__PURE__ */ jsx(
16421
+ SpanScoreList,
16422
+ {
16423
+ scoresData: spanScoresData,
16424
+ onPageChange: onSpanScoresPageChange,
16425
+ isLoadingScoresData: isLoadingSpanScoresData,
16426
+ initialScoreId,
16427
+ traceId: trace?.traceId,
16428
+ spanId: span?.spanId,
16429
+ computeTraceLink
16430
+ }
16431
+ )
16432
+ ] })
16433
+ ] }) })
16729
16434
  ] });
16730
- };
16435
+ }
16731
16436
 
16732
16437
  function SpanDialog({
16733
16438
  trace,
16734
16439
  span,
16440
+ spanScoresData,
16441
+ onSpanScoresPageChange,
16442
+ isLoadingSpanScoresData,
16735
16443
  isOpen,
16736
16444
  onClose,
16737
16445
  onNext,
16738
16446
  onPrevious,
16739
16447
  onViewToggle,
16740
16448
  spanInfo = [],
16741
- onScorerTriggered
16449
+ defaultActiveTab = "details",
16450
+ initialScoreId,
16451
+ computeTraceLink
16742
16452
  }) {
16743
- const { Link } = useLinkComponent();
16744
16453
  return /* @__PURE__ */ jsxs(
16745
16454
  SideDialog,
16746
16455
  {
@@ -16748,43 +16457,53 @@ function SpanDialog({
16748
16457
  dialogDescription: "View and analyze span details",
16749
16458
  isOpen,
16750
16459
  onClose,
16751
- hasCloseButton: true,
16752
- className: cn("w-[calc(100vw-25rem)] max-w-[65%]", "3xl:max-w-[50%]", "4xl:max-w-[40%]"),
16460
+ level: 2,
16753
16461
  children: [
16754
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between pr-[1.5rem]", children: [
16755
- /* @__PURE__ */ jsx(SideDialogTop, { onNext, onPrevious, showInnerNav: true, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[1rem] text-icon4 text-[0.875rem]", children: [
16756
- /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16757
- /* @__PURE__ */ jsx(EyeIcon, {}),
16462
+ /* @__PURE__ */ jsxs(SideDialog.Top, { children: [
16463
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16464
+ /* @__PURE__ */ jsx(EyeIcon, {}),
16465
+ " ",
16466
+ getShortId(span?.traceId)
16467
+ ] }),
16468
+ "›",
16469
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16470
+ /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
16471
+ getShortId(span?.spanId)
16472
+ ] }),
16473
+ "|",
16474
+ /* @__PURE__ */ jsx(SideDialog.Nav, { onNext, onPrevious }),
16475
+ /* @__PURE__ */ jsxs("button", { className: "ml-auto mr-[2rem]", onClick: onViewToggle, children: [
16476
+ /* @__PURE__ */ jsx(PanelTopIcon, {}),
16477
+ /* @__PURE__ */ jsx(VisuallyHidden$1, { children: "Switch to dialog view" })
16478
+ ] })
16479
+ ] }),
16480
+ /* @__PURE__ */ jsxs(SideDialog.Content, { children: [
16481
+ /* @__PURE__ */ jsxs(SideDialog.Header, { children: [
16482
+ /* @__PURE__ */ jsxs(SideDialog.Heading, { children: [
16483
+ /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
16758
16484
  " ",
16759
- getShortId(span?.traceId)
16485
+ span?.name
16760
16486
  ] }),
16761
- "›",
16762
16487
  /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16763
- /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
16764
- getShortId(span?.spanId)
16488
+ /* @__PURE__ */ jsx(HashIcon, {}),
16489
+ " ",
16490
+ span?.spanId
16765
16491
  ] })
16766
- ] }) }),
16767
- /* @__PURE__ */ jsx("button", { className: "flex items-center gap-1", onClick: onViewToggle, children: /* @__PURE__ */ jsx(PanelTopIcon, {}) })
16768
- ] }),
16769
- /* @__PURE__ */ jsxs("div", { className: "p-[1.5rem] px-[2.5rem] overflow-y-auto grid gap-[1.5rem] content-start", children: [
16770
- /* @__PURE__ */ jsxs("div", { children: [
16771
- /* @__PURE__ */ jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
16772
- /* @__PURE__ */ jsxs(SideDialogHeading, { children: [
16773
- /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
16774
- " ",
16775
- span?.name
16776
- ] }),
16777
- /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16778
- /* @__PURE__ */ jsx(HashIcon, {}),
16779
- " ",
16780
- span?.spanId
16781
- ] })
16782
- ] }),
16783
- span?.traceId && span?.spanId && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ScorersDropdown, { trace, spanId: span?.spanId, onScorerTriggered }) })
16784
16492
  ] }),
16785
- span?.attributes?.usage && /* @__PURE__ */ jsx(TraceSpanUsage, { spanUsage: span.attributes.usage, className: "mt-[1.5rem]" }),
16786
- /* @__PURE__ */ jsx(KeyValueList, { data: spanInfo, LinkComponent: Link, className: "mt-[1.5rem]" }),
16787
- /* @__PURE__ */ jsx(SpanDetails, { span, onScorerTriggered })
16493
+ /* @__PURE__ */ jsx(
16494
+ SpanTabs,
16495
+ {
16496
+ trace,
16497
+ span,
16498
+ spanScoresData,
16499
+ onSpanScoresPageChange,
16500
+ isLoadingSpanScoresData,
16501
+ spanInfo,
16502
+ defaultActiveTab,
16503
+ initialScoreId,
16504
+ computeTraceLink
16505
+ }
16506
+ )
16788
16507
  ] })
16789
16508
  ]
16790
16509
  }
@@ -16802,15 +16521,30 @@ function TraceDialog({
16802
16521
  isLoadingSpans,
16803
16522
  computeAgentsLink,
16804
16523
  computeWorkflowsLink,
16805
- onScorerTriggered,
16806
- initialSpanId
16524
+ computeTraceLink,
16525
+ initialSpanId,
16526
+ initialSpanTab,
16527
+ initialScoreId
16807
16528
  }) {
16808
- const { Link } = useLinkComponent();
16529
+ const { Link, navigate } = useLinkComponent();
16809
16530
  const [dialogIsOpen, setDialogIsOpen] = useState(Boolean(initialSpanId));
16810
16531
  const [selectedSpanId, setSelectedSpanId] = useState(initialSpanId);
16811
16532
  const [combinedView, setCombinedView] = useState(false);
16533
+ const [spanDialogDefaultTab, setSpanDialogDefaultTab] = useState(initialSpanTab || "details");
16812
16534
  const selectedSpan = traceSpans.find((span) => span.spanId === selectedSpanId);
16813
16535
  const traceInfo = useTraceInfo(traceDetails);
16536
+ const [spanScoresPage, setSpanScoresPage] = useState(0);
16537
+ useEffect(() => {
16538
+ if (initialSpanId) {
16539
+ setSelectedSpanId(initialSpanId);
16540
+ setDialogIsOpen(true);
16541
+ }
16542
+ }, [initialSpanId]);
16543
+ useEffect(() => {
16544
+ if (spanScoresPage > 0) {
16545
+ setSpanScoresPage(0);
16546
+ }
16547
+ }, [selectedSpanId]);
16814
16548
  const hierarchicalSpans = useMemo(() => {
16815
16549
  return formatHierarchicalSpans(traceSpans);
16816
16550
  }, [traceSpans]);
@@ -16828,39 +16562,38 @@ function TraceDialog({
16828
16562
  };
16829
16563
  return flattenSpans(hierarchicalSpans);
16830
16564
  }, [hierarchicalSpans]);
16565
+ const { data: spanScoresData, isLoading: isLoadingSpanScoresData } = useTraceSpanScores({
16566
+ traceId,
16567
+ spanId: selectedSpanId || flatSpans?.[0]?.id,
16568
+ page: spanScoresPage
16569
+ });
16831
16570
  const handleSpanClick = (id) => {
16832
16571
  setSelectedSpanId(id);
16572
+ setSpanDialogDefaultTab("details");
16833
16573
  setDialogIsOpen(true);
16834
16574
  };
16835
- const toNextSpan = () => {
16836
- const currentIndex = flatSpans.findIndex((span) => span.id === selectedSpanId);
16837
- const nextItem = flatSpans[currentIndex + 1];
16838
- if (nextItem) {
16839
- setSelectedSpanId(nextItem.id);
16575
+ const handleToScoring = () => {
16576
+ setSelectedSpanId(hierarchicalSpans[0]?.id);
16577
+ setSpanDialogDefaultTab("scores");
16578
+ if (traceId) {
16579
+ navigate(`${computeTraceLink(traceId, hierarchicalSpans?.[0]?.id)}&tab=scores`);
16840
16580
  }
16841
16581
  };
16842
- const toPreviousSpan = () => {
16843
- const currentIndex = flatSpans.findIndex((span) => span.id === selectedSpanId);
16844
- const previousItem = flatSpans[currentIndex - 1];
16845
- if (previousItem) {
16846
- setSelectedSpanId(previousItem.id);
16582
+ const handleToLastScore = () => {
16583
+ setSelectedSpanId(hierarchicalSpans[0]?.id);
16584
+ setSpanDialogDefaultTab("scores");
16585
+ if (traceId) {
16586
+ navigate(
16587
+ `${computeTraceLink(
16588
+ traceId,
16589
+ hierarchicalSpans?.[0]?.id
16590
+ )}&tab=scores&scoreId=${spanScoresData?.scores?.[0]?.id}`
16591
+ );
16847
16592
  }
16848
16593
  };
16849
- const thereIsNextSpan = () => {
16850
- const currentIndex = flatSpans.findIndex((span) => span.id === selectedSpanId);
16851
- return currentIndex < flatSpans.length - 1;
16852
- };
16853
- const thereIsPreviousSpan = () => {
16854
- const currentIndex = flatSpans.findIndex((span) => span.id === selectedSpanId);
16855
- return currentIndex > 0;
16856
- };
16857
16594
  const selectedSpanInfo = getSpanInfo({ span: selectedSpan, withTraceId: !combinedView, withSpanId: combinedView });
16858
- let entityType;
16859
- if (traceDetails?.attributes?.agentId) {
16860
- entityType = "Agent";
16861
- } else if (traceDetails?.attributes?.workflowId) {
16862
- entityType = "Workflow";
16863
- }
16595
+ const toNextSpan = getToNextEntryFn({ entries: flatSpans, id: selectedSpanId, update: setSelectedSpanId });
16596
+ const toPreviousSpan = getToPreviousEntryFn({ entries: flatSpans, id: selectedSpanId, update: setSelectedSpanId });
16864
16597
  return /* @__PURE__ */ jsxs(Fragment, { children: [
16865
16598
  /* @__PURE__ */ jsxs(
16866
16599
  SideDialog,
@@ -16869,111 +16602,100 @@ function TraceDialog({
16869
16602
  dialogDescription: "View and analyze trace details",
16870
16603
  isOpen,
16871
16604
  onClose,
16872
- hasCloseButton: !dialogIsOpen || combinedView,
16873
- className: cn("w-[calc(100vw-20rem)] max-w-[80%]", "3xl:max-w-[65%]", "4xl:max-w-[55%]"),
16605
+ level: 1,
16874
16606
  children: [
16875
- /* @__PURE__ */ jsx(SideDialogTop, { onNext, onPrevious, showInnerNav: true, children: /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16876
- /* @__PURE__ */ jsx(EyeIcon, {}),
16877
- " ",
16878
- getShortId(traceId)
16879
- ] }) }),
16607
+ /* @__PURE__ */ jsxs(SideDialog.Top, { children: [
16608
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16609
+ /* @__PURE__ */ jsx(EyeIcon, {}),
16610
+ " ",
16611
+ getShortId(traceId)
16612
+ ] }),
16613
+ "|",
16614
+ /* @__PURE__ */ jsx(SideDialog.Nav, { onNext, onPrevious })
16615
+ ] }),
16880
16616
  /* @__PURE__ */ jsxs(
16881
16617
  "div",
16882
16618
  {
16883
- className: cn("pt-[1.5rem] pl-[2.5rem] grid-rows-[auto_1fr] grid h-full overflow-y-auto", {
16884
- "grid-rows-[auto_1fr_1fr]": selectedSpan && combinedView
16619
+ className: cn("overflow-y-auto", {
16620
+ "grid grid-rows-[2fr_3fr]": Boolean(selectedSpan && combinedView)
16885
16621
  }),
16886
16622
  children: [
16887
- /* @__PURE__ */ jsxs(SideDialogHeader, { className: "pr-[2.5rem]", children: [
16888
- /* @__PURE__ */ jsxs(SideDialogHeading, { children: [
16889
- /* @__PURE__ */ jsx(EyeIcon, {}),
16890
- " ",
16891
- traceDetails?.name
16892
- ] }),
16893
- /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16894
- /* @__PURE__ */ jsx(HashIcon, {}),
16895
- " ",
16896
- traceId
16897
- ] })
16898
- ] }),
16899
- /* @__PURE__ */ jsxs("div", { className: cn("overflow-y-auto pb-[2.5rem]"), children: [
16900
- traceDetails && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
16901
- ScorersDropdown,
16902
- {
16903
- trace: traceDetails,
16904
- spanId: selectedSpanId,
16905
- onScorerTriggered,
16906
- entityType
16907
- }
16908
- ) }),
16909
- traceDetails?.metadata?.usage && /* @__PURE__ */ jsx(
16910
- TraceSpanUsage,
16911
- {
16912
- traceUsage: traceDetails?.metadata?.usage,
16913
- traceSpans,
16914
- className: "mt-[2rem] pr-[1.5rem]"
16915
- }
16916
- ),
16917
- /* @__PURE__ */ jsx(KeyValueList, { data: traceInfo, LinkComponent: Link, className: "mt-[2rem]" }),
16918
- /* @__PURE__ */ jsx(
16919
- TraceTimeline,
16920
- {
16921
- hierarchicalSpans,
16922
- spans: traceSpans,
16923
- onSpanClick: handleSpanClick,
16924
- selectedSpanId,
16925
- isLoading: isLoadingSpans,
16926
- className: "pr-[2.5rem] pt-[2.5rem]"
16927
- }
16928
- ),
16929
- traceDetails?.links?.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-[2.5rem] pr-[2.5rem]", children: [
16930
- /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", className: "pb-[1rem]", children: [
16931
- /* @__PURE__ */ jsx(GaugeIcon, {}),
16932
- " Scores"
16623
+ /* @__PURE__ */ jsxs(SideDialog.Content, { children: [
16624
+ /* @__PURE__ */ jsxs(SideDialog.Header, { children: [
16625
+ /* @__PURE__ */ jsxs(SideDialog.Heading, { children: [
16626
+ /* @__PURE__ */ jsx(EyeIcon, {}),
16627
+ " ",
16628
+ traceDetails?.name
16933
16629
  ] }),
16934
- /* @__PURE__ */ jsx("div", { className: "bg-surface2 rounded-lg overflow-hidden border-sm border-border1", children: /* @__PURE__ */ jsx(
16935
- ScoreTable,
16936
- {
16937
- scores: traceDetails?.links,
16938
- onItemClick: (scorerName) => onScorerTriggered(scorerName, traceDetails.traceId, selectedSpanId)
16939
- }
16940
- ) })
16941
- ] })
16942
- ] }),
16943
- selectedSpan && combinedView && /* @__PURE__ */ jsxs("div", { className: "overflow-y-auto grid grid-rows-[auto_1fr] relative", children: [
16944
- /* @__PURE__ */ jsx("div", { className: "absolute left-0 right-[2.5rem] h-[.5rem] bg-surface1 rounded-full top-0" }),
16945
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between pb-[.5rem] pt-[1rem] border-b border-border1 pr-[2.5rem]", children: [
16946
- /* @__PURE__ */ jsx(
16947
- SideDialogTop,
16948
- {
16949
- onNext: thereIsNextSpan() ? toNextSpan : void 0,
16950
- onPrevious: thereIsPreviousSpan() ? toPreviousSpan : void 0,
16951
- showInnerNav: true,
16952
- className: "pl-0",
16953
- children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-[1rem] text-icon4 text-[0.875rem]", children: [
16954
- /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16955
- /* @__PURE__ */ jsx(EyeIcon, {}),
16956
- " ",
16957
- getShortId(traceId)
16630
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16631
+ /* @__PURE__ */ jsx(HashIcon, {}),
16632
+ " ",
16633
+ traceId
16634
+ ] })
16635
+ ] }),
16636
+ traceDetails && /* @__PURE__ */ jsxs(Sections, { children: [
16637
+ /* @__PURE__ */ jsxs("div", { className: "grid xl:grid-cols-[3fr_2fr] gap-[1rem] items-start", children: [
16638
+ /* @__PURE__ */ jsx(KeyValueList, { data: traceInfo, LinkComponent: Link }),
16639
+ /* @__PURE__ */ jsxs("div", { className: "bg-surface3 p-[1.5rem] rounded-lg grid gap-[1rem]", children: [
16640
+ /* @__PURE__ */ jsx("h4", { className: "text-[1rem]", children: /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16641
+ /* @__PURE__ */ jsx(GaugeIcon, {}),
16642
+ " Evaluate trace"
16643
+ ] }) }),
16644
+ /* @__PURE__ */ jsxs(ButtonsGroup, { className: "w-full", children: [
16645
+ /* @__PURE__ */ jsxs(Button, { onClick: handleToScoring, children: [
16646
+ "Scoring ",
16647
+ /* @__PURE__ */ jsx(CircleGaugeIcon, {}),
16648
+ " "
16958
16649
  ] }),
16959
- "›",
16960
- /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16961
- /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
16962
- " ",
16963
- getShortId(selectedSpanId)
16650
+ spanScoresData?.scores?.[0] && /* @__PURE__ */ jsxs(Button, { onClick: handleToLastScore, children: [
16651
+ "Last score: ",
16652
+ /* @__PURE__ */ jsx("b", { children: spanScoresData?.scores?.[0]?.score })
16964
16653
  ] })
16965
16654
  ] })
16966
- }
16967
- ),
16968
- /* @__PURE__ */ jsx("div", { className: "flex items-center gap-[1rem]", children: /* @__PURE__ */ jsx("button", { className: "flex items-center gap-1", onClick: () => setCombinedView(false), children: /* @__PURE__ */ jsx(PanelLeftIcon, {}) }) })
16655
+ ] })
16656
+ ] }),
16657
+ /* @__PURE__ */ jsxs(Section, { children: [
16658
+ /* @__PURE__ */ jsxs(Section.Header, { children: [
16659
+ /* @__PURE__ */ jsxs(Section.Heading, { children: [
16660
+ /* @__PURE__ */ jsx(ListTreeIcon, {}),
16661
+ " Timeline"
16662
+ ] }),
16663
+ /* @__PURE__ */ jsx(TraceTimelineLegend, { spans: traceSpans })
16664
+ ] }),
16665
+ /* @__PURE__ */ jsx(
16666
+ TraceTimeline,
16667
+ {
16668
+ hierarchicalSpans,
16669
+ onSpanClick: handleSpanClick,
16670
+ selectedSpanId,
16671
+ isLoading: isLoadingSpans
16672
+ }
16673
+ )
16674
+ ] })
16675
+ ] })
16676
+ ] }),
16677
+ selectedSpan && combinedView && /* @__PURE__ */ jsxs("div", { className: "grid grid-rows-[auto_1fr] relative overflow-y-auto", children: [
16678
+ /* @__PURE__ */ jsxs(SideDialog.Top, { withTopSeparator: true, children: [
16679
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
16680
+ /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
16681
+ " ",
16682
+ getShortId(selectedSpanId)
16683
+ ] }),
16684
+ "|",
16685
+ /* @__PURE__ */ jsx(SideDialog.Nav, { onNext: toNextSpan, onPrevious: toPreviousSpan }),
16686
+ /* @__PURE__ */ jsxs("button", { className: "ml-auto mr-[2rem]", onClick: () => setCombinedView(false), children: [
16687
+ /* @__PURE__ */ jsx(PanelLeftIcon, {}),
16688
+ " ",
16689
+ /* @__PURE__ */ jsx(VisuallyHidden$1, { children: "Switch to dialog view" })
16690
+ ] })
16969
16691
  ] }),
16970
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[20rem_1fr] gap-[1rem] overflow-y-auto", children: [
16971
- /* @__PURE__ */ jsxs("div", { className: "overflow-y-auto grid content-start p-[1.5rem] pl-0 gap-[2rem]", children: [
16972
- /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", children: [
16692
+ /* @__PURE__ */ jsxs("div", { className: cn("h-full overflow-y-auto grid gap-[2rem] grid-cols-[20rem_1fr]"), children: [
16693
+ /* @__PURE__ */ jsxs("div", { className: "overflow-y-auto grid content-start p-[2rem] gap-[2rem]", children: [
16694
+ /* @__PURE__ */ jsxs(SideDialog.Heading, { as: "h2", children: [
16973
16695
  /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
16974
16696
  " ",
16975
16697
  selectedSpan?.name
16976
- ] }) }),
16698
+ ] }),
16977
16699
  selectedSpan?.attributes?.usage && /* @__PURE__ */ jsx(
16978
16700
  TraceSpanUsage,
16979
16701
  {
@@ -16983,7 +16705,20 @@ function TraceDialog({
16983
16705
  ),
16984
16706
  /* @__PURE__ */ jsx(KeyValueList, { data: selectedSpanInfo, LinkComponent: Link })
16985
16707
  ] }),
16986
- /* @__PURE__ */ jsx("div", { className: "overflow-y-auto pr-[2.5rem] pt-[2rem]", children: /* @__PURE__ */ jsx(SpanDetails, { span: selectedSpan, onScorerTriggered }) })
16708
+ /* @__PURE__ */ jsx("div", { className: "overflow-y-auto pr-[2rem] pt-[2rem] h-full", children: /* @__PURE__ */ jsx(
16709
+ SpanTabs,
16710
+ {
16711
+ trace: traceDetails,
16712
+ span: selectedSpan,
16713
+ spanScoresData,
16714
+ onSpanScoresPageChange: setSpanScoresPage,
16715
+ isLoadingSpanScoresData,
16716
+ spanInfo: selectedSpanInfo,
16717
+ defaultActiveTab: spanDialogDefaultTab,
16718
+ initialScoreId,
16719
+ computeTraceLink
16720
+ }
16721
+ ) })
16987
16722
  ] })
16988
16723
  ] })
16989
16724
  ]
@@ -16997,16 +16732,22 @@ function TraceDialog({
16997
16732
  {
16998
16733
  trace: traceDetails,
16999
16734
  span: selectedSpan,
16735
+ spanScoresData,
16736
+ onSpanScoresPageChange: setSpanScoresPage,
16737
+ isLoadingSpanScoresData,
17000
16738
  isOpen: Boolean(dialogIsOpen && selectedSpanId && !combinedView),
17001
16739
  onClose: () => {
16740
+ navigate(computeTraceLink(traceId || ""));
17002
16741
  setDialogIsOpen(false);
17003
16742
  setSelectedSpanId(void 0);
17004
16743
  },
17005
- onNext: thereIsNextSpan() ? toNextSpan : void 0,
17006
- onPrevious: thereIsPreviousSpan() ? toPreviousSpan : void 0,
16744
+ onNext: toNextSpan,
16745
+ onPrevious: toPreviousSpan,
17007
16746
  onViewToggle: () => setCombinedView(!combinedView),
17008
16747
  spanInfo: selectedSpanInfo,
17009
- onScorerTriggered
16748
+ defaultActiveTab: spanDialogDefaultTab,
16749
+ initialScoreId,
16750
+ computeTraceLink
17010
16751
  }
17011
16752
  )
17012
16753
  ] });
@@ -17075,61 +16816,262 @@ function TracesTools({
17075
16816
  ] });
17076
16817
  }
17077
16818
 
17078
- function MainContentLayout({
17079
- children,
17080
- className,
17081
- style
16819
+ const tracesListColumns = [
16820
+ { name: "shortId", label: "ID", size: "6rem" },
16821
+ { name: "date", label: "Date", size: "4.5rem" },
16822
+ { name: "time", label: "Time", size: "6.5rem" },
16823
+ { name: "name", label: "Name", size: "1fr" },
16824
+ { name: "entityId", label: "Entity", size: "10rem" },
16825
+ { name: "status", label: "Status", size: "3rem" }
16826
+ ];
16827
+ function TracesList({
16828
+ traces,
16829
+ selectedTraceId,
16830
+ onTraceClick,
16831
+ errorMsg,
16832
+ setEndOfListElement,
16833
+ filtersApplied,
16834
+ isFetchingNextPage,
16835
+ hasNextPage
17082
16836
  }) {
17083
- const devStyleRequested = devUIStyleRequested("MainContentLayout");
17084
- return /* @__PURE__ */ jsx(
17085
- "main",
17086
- {
17087
- className: cn(`grid grid-rows-[auto_1fr] h-full items-start content-start`, className),
17088
- style: { ...style, ...devStyleRequested ? { border: "3px dotted red" } : {} },
17089
- children
17090
- }
17091
- );
16837
+ if (!traces) {
16838
+ return null;
16839
+ }
16840
+ return /* @__PURE__ */ jsxs(EntryList, { children: [
16841
+ /* @__PURE__ */ jsxs(EntryList.Trim, { children: [
16842
+ /* @__PURE__ */ jsx(EntryList.Header, { columns: tracesListColumns }),
16843
+ errorMsg ? /* @__PURE__ */ jsx(EntryList.Message, { message: errorMsg, type: "error" }) : /* @__PURE__ */ jsx(Fragment, { children: traces.length > 0 ? /* @__PURE__ */ jsx(EntryList.Entries, { children: traces.map((trace) => {
16844
+ const createdAtDate = new Date(trace.createdAt);
16845
+ const isTodayDate = isToday(createdAtDate);
16846
+ const entry = {
16847
+ id: trace.traceId,
16848
+ shortId: getShortId(trace?.traceId) || "n/a",
16849
+ date: isTodayDate ? "Today" : format(createdAtDate, "MMM dd"),
16850
+ time: format(createdAtDate, "h:mm:ss aaa"),
16851
+ name: trace?.name,
16852
+ entityId: trace?.attributes?.agentId || trace?.attributes?.workflowId,
16853
+ status: trace?.attributes?.status
16854
+ };
16855
+ return /* @__PURE__ */ jsx(
16856
+ EntryList.Entry,
16857
+ {
16858
+ entry,
16859
+ isSelected: selectedTraceId === trace.traceId,
16860
+ columns: tracesListColumns,
16861
+ onClick: onTraceClick,
16862
+ children: tracesListColumns.map((col, index) => {
16863
+ const key = `${index}-${trace.traceId}`;
16864
+ return col.name === "status" ? /* @__PURE__ */ jsx(EntryList.EntryStatus, { status: entry?.[col.name] }, key) : /* @__PURE__ */ jsx(EntryList.EntryText, { children: entry?.[col.name] }, key);
16865
+ })
16866
+ },
16867
+ entry.id
16868
+ );
16869
+ }) }) : /* @__PURE__ */ jsx(
16870
+ EntryList.Message,
16871
+ {
16872
+ message: filtersApplied ? "No traces found for applied filters" : "No traces found yet"
16873
+ }
16874
+ ) })
16875
+ ] }),
16876
+ /* @__PURE__ */ jsx(
16877
+ EntryList.NextPageLoading,
16878
+ {
16879
+ setEndOfListElement,
16880
+ loadingText: "Loading more traces...",
16881
+ noMoreDataText: "All traces loaded",
16882
+ isLoading: isFetchingNextPage,
16883
+ hasMore: hasNextPage
16884
+ }
16885
+ )
16886
+ ] });
17092
16887
  }
17093
- function MainContentContent({
17094
- children,
17095
- className,
17096
- isCentered = false,
17097
- isDivided = false,
17098
- hasLeftServiceColumn = false,
17099
- style
16888
+
16889
+ const traceScoresListColumns = [
16890
+ { name: "shortId", label: "ID", size: "1fr" },
16891
+ { name: "date", label: "Date", size: "1fr" },
16892
+ { name: "time", label: "Time", size: "1fr" },
16893
+ { name: "score", label: "Score", size: "1fr" },
16894
+ { name: "scorer", label: "Scorer", size: "1fr" }
16895
+ ];
16896
+ function SpanScoreList({
16897
+ scoresData,
16898
+ isLoadingScoresData,
16899
+ traceId,
16900
+ spanId,
16901
+ initialScoreId,
16902
+ onPageChange,
16903
+ computeTraceLink
17100
16904
  }) {
17101
- const devStyleRequested = devUIStyleRequested("MainContentContent");
17102
- return /* @__PURE__ */ jsx(
17103
- "div",
17104
- {
17105
- className: cn(
17106
- `grid overflow-y-auto h-full `,
17107
- `overflow-x-auto min-w-[min-content]`,
16905
+ const { navigate } = useLinkComponent();
16906
+ const [dialogIsOpen, setDialogIsOpen] = useState(false);
16907
+ const [selectedScore, setSelectedScore] = useState();
16908
+ useEffect(() => {
16909
+ if (initialScoreId) {
16910
+ handleOnScore(initialScoreId);
16911
+ }
16912
+ }, [initialScoreId]);
16913
+ const handleOnScore = (scoreId) => {
16914
+ const score = scoresData?.scores?.find((s) => s?.id === scoreId);
16915
+ setSelectedScore(score);
16916
+ setDialogIsOpen(true);
16917
+ };
16918
+ if (isLoadingScoresData) {
16919
+ return /* @__PURE__ */ jsx(EntryListSkeleton, { columns: traceScoresListColumns });
16920
+ }
16921
+ const updateSelectedScore = (scoreId) => {
16922
+ const score = scoresData?.scores?.find((s) => s?.id === scoreId);
16923
+ setSelectedScore(score);
16924
+ };
16925
+ const toNextScore = getToNextEntryFn({
16926
+ entries: scoresData?.scores || [],
16927
+ id: selectedScore?.id,
16928
+ update: updateSelectedScore
16929
+ });
16930
+ const toPreviousScore = getToPreviousEntryFn({
16931
+ entries: scoresData?.scores || [],
16932
+ id: selectedScore?.id,
16933
+ update: updateSelectedScore
16934
+ });
16935
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
16936
+ /* @__PURE__ */ jsxs(EntryList, { children: [
16937
+ /* @__PURE__ */ jsxs(EntryList.Trim, { children: [
16938
+ /* @__PURE__ */ jsx(EntryList.Header, { columns: traceScoresListColumns }),
16939
+ scoresData?.scores && scoresData.scores.length > 0 ? /* @__PURE__ */ jsx(EntryList.Entries, { children: scoresData?.scores?.map((score) => {
16940
+ const createdAtDate = new Date(score.createdAt);
16941
+ const isTodayDate = isToday(createdAtDate);
16942
+ const entry = {
16943
+ id: score?.id,
16944
+ shortId: getShortId(score?.id) || "n/a",
16945
+ date: isTodayDate ? "Today" : format(createdAtDate, "MMM dd"),
16946
+ time: format(createdAtDate, "h:mm:ss aaa"),
16947
+ score: score?.score,
16948
+ scorer: score?.scorer?.name
16949
+ };
16950
+ return /* @__PURE__ */ jsx(
16951
+ EntryList.Entry,
16952
+ {
16953
+ columns: traceScoresListColumns,
16954
+ onClick: () => handleOnScore(score.id),
16955
+ entry,
16956
+ children: traceScoresListColumns.map((col) => {
16957
+ const key = `col-${col.name}`;
16958
+ return /* @__PURE__ */ jsx(EntryList.EntryText, { children: entry?.[col.name] }, key);
16959
+ })
16960
+ },
16961
+ score.id
16962
+ );
16963
+ }) }) : /* @__PURE__ */ jsx(EntryList.Message, { message: "No scores found", type: "info" })
16964
+ ] }),
16965
+ /* @__PURE__ */ jsx(
16966
+ EntryList.Pagination,
17108
16967
  {
17109
- "items-start content-start": !isCentered && !isDivided && !hasLeftServiceColumn,
17110
- "grid place-items-center": isCentered,
17111
- "grid-cols-[1fr_1fr]": isDivided && !hasLeftServiceColumn,
17112
- "grid-cols-[12rem_1fr_1fr]": isDivided && hasLeftServiceColumn,
17113
- "grid-cols-[auto_1fr]": !isDivided && hasLeftServiceColumn
16968
+ currentPage: scoresData?.pagination?.page || 0,
16969
+ hasMore: scoresData?.pagination?.hasMore,
16970
+ onNextPage: () => onPageChange && onPageChange((scoresData?.pagination?.page || 0) + 1),
16971
+ onPrevPage: () => onPageChange && onPageChange((scoresData?.pagination?.page || 0) - 1)
16972
+ }
16973
+ )
16974
+ ] }),
16975
+ /* @__PURE__ */ jsx(
16976
+ ScoreDialog,
16977
+ {
16978
+ scorerName: selectedScore?.scorer?.name || "",
16979
+ score: selectedScore,
16980
+ isOpen: dialogIsOpen,
16981
+ onClose: () => {
16982
+ if (traceId) {
16983
+ navigate(`${computeTraceLink(traceId, spanId)}&tab=scores`);
16984
+ }
16985
+ setDialogIsOpen(false);
17114
16986
  },
17115
- className
17116
- ),
17117
- style: { ...style, ...devStyleRequested ? { border: "3px dotted orange" } : {} },
17118
- children
17119
- }
17120
- );
16987
+ dialogLevel: 3,
16988
+ onNext: toNextScore,
16989
+ onPrevious: toPreviousScore,
16990
+ computeTraceLink: (traceId2, spanId2) => `/observability?traceId=${traceId2}${spanId2 ? `&spanId=${spanId2}` : ""}`,
16991
+ usageContext: "aiSpanDialog"
16992
+ }
16993
+ )
16994
+ ] });
17121
16995
  }
17122
- function devUIStyleRequested(name) {
17123
- try {
17124
- const raw = localStorage.getItem("add-dev-style-to-components");
17125
- if (!raw) return false;
17126
- const components = raw.split(",").map((c) => c.trim()).filter(Boolean);
17127
- return components.includes(name);
17128
- } catch (error) {
17129
- console.error("Error reading or parsing localStorage:", error);
17130
- return false;
16996
+
16997
+ const useTriggerScorer = () => {
16998
+ const client = useMastraClient();
16999
+ return useMutation({
17000
+ mutationFn: async ({ scorerName, traceId, spanId }) => {
17001
+ const response = await client.score({
17002
+ scorerName,
17003
+ targets: [{ traceId, spanId }]
17004
+ });
17005
+ return response;
17006
+ }
17007
+ });
17008
+ };
17009
+
17010
+ const SpanScoring = ({ traceId, spanId, entityType }) => {
17011
+ const { data: scorers = {}, isLoading } = useScorers();
17012
+ const [selectedScorer, setSelectedScorer] = useState(null);
17013
+ const { mutate: triggerScorer, isPending, isSuccess } = useTriggerScorer();
17014
+ const [notificationIsVisible, setNotificationIsVisible] = useState(false);
17015
+ useEffect(() => {
17016
+ if (isSuccess) {
17017
+ setNotificationIsVisible(true);
17018
+ }
17019
+ }, [isSuccess]);
17020
+ let scorerList = Object.entries(scorers).map(([key, scorer]) => ({
17021
+ id: key,
17022
+ name: scorer.scorer.config.name,
17023
+ description: scorer.scorer.config.description,
17024
+ isRegistered: scorer.isRegistered,
17025
+ type: scorer.scorer.config.type
17026
+ })).filter((scorer) => scorer.isRegistered);
17027
+ if (entityType !== "Agent" || spanId) {
17028
+ scorerList = scorerList.filter((scorer) => scorer.type !== "agent");
17131
17029
  }
17132
- }
17030
+ const isWaiting = isPending || isLoading;
17031
+ const handleStartScoring = () => {
17032
+ if (selectedScorer) {
17033
+ setNotificationIsVisible(false);
17034
+ triggerScorer({
17035
+ scorerName: selectedScorer,
17036
+ traceId: traceId || "",
17037
+ spanId
17038
+ });
17039
+ }
17040
+ };
17041
+ const handleScorerChange = (val) => {
17042
+ setSelectedScorer(val);
17043
+ setNotificationIsVisible(false);
17044
+ };
17045
+ const selectedScorerDescription = scorerList.find((s) => s.name === selectedScorer)?.description || "";
17046
+ return /* @__PURE__ */ jsxs("div", { children: [
17047
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[3fr_1fr] gap-[1rem] items-start", children: [
17048
+ /* @__PURE__ */ jsxs("div", { className: "grid gap-[0.5rem]", children: [
17049
+ /* @__PURE__ */ jsx(
17050
+ SelectField,
17051
+ {
17052
+ name: "select-scorer",
17053
+ placeholder: "Select a scorer...",
17054
+ options: scorerList.map((scorer) => ({ label: scorer.name, value: scorer.name })),
17055
+ onValueChange: handleScorerChange,
17056
+ value: selectedScorer || "",
17057
+ className: "min-w-[20rem]",
17058
+ disabled: isWaiting
17059
+ }
17060
+ ),
17061
+ selectedScorerDescription && /* @__PURE__ */ jsxs(TextAndIcon, { className: "text-icon3", children: [
17062
+ /* @__PURE__ */ jsx(InfoIcon$1, {}),
17063
+ " ",
17064
+ selectedScorerDescription
17065
+ ] })
17066
+ ] }),
17067
+ /* @__PURE__ */ jsx(Button, { disabled: !selectedScorer || isWaiting, onClick: handleStartScoring, children: isPending ? "Starting..." : "Start Scoring" })
17068
+ ] }),
17069
+ /* @__PURE__ */ jsxs(Notification, { isVisible: notificationIsVisible, className: "mt-[1rem]", children: [
17070
+ /* @__PURE__ */ jsx(InfoIcon$1, {}),
17071
+ " Scorer triggered! When finished successfully, it will appear in the list below. It could take a moment."
17072
+ ] })
17073
+ ] });
17074
+ };
17133
17075
 
17134
17076
  const Breadcrumb = ({ children, label }) => {
17135
17077
  return /* @__PURE__ */ jsx("nav", { "aria-label": label, children: /* @__PURE__ */ jsx("ol", { className: "gap-sm flex items-center", children }) });
@@ -17736,7 +17678,7 @@ function MCPTable({ mcpServers, isLoading }) {
17736
17678
  return /* @__PURE__ */ jsx(EmptyMCPTable, {});
17737
17679
  }
17738
17680
  const filteredRows = rows.filter((row) => row.original.name.toLowerCase().includes(search.toLowerCase()));
17739
- return /* @__PURE__ */ jsxs(Fragment, { children: [
17681
+ return /* @__PURE__ */ jsxs("div", { children: [
17740
17682
  /* @__PURE__ */ jsx(SearchbarWrapper, { children: /* @__PURE__ */ jsx(Searchbar, { onSearch: setSearch, label: "Search MCP servers", placeholder: "Search MCP servers" }) }),
17741
17683
  isLoading ? /* @__PURE__ */ jsx(MCPTableSkeleton, {}) : /* @__PURE__ */ jsx(ScrollableContainer, { children: /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Table$1, { children: [
17742
17684
  /* @__PURE__ */ jsx(Thead, { className: "sticky top-0", children: ths.headers.map((header) => /* @__PURE__ */ jsx(Th, { style: { width: header.column.getSize() ?? "auto" }, children: flexRender(header.column.columnDef.header, header.getContext()) }, header.id)) }),
@@ -17822,5 +17764,5 @@ const WorkflowRunStatusBadge = ({ status }) => {
17822
17764
  return /* @__PURE__ */ jsx(Badge$1, { variant: "default", children: status });
17823
17765
  };
17824
17766
 
17825
- export { AgentChat, AgentCoinIcon, AgentEntityHeader, AgentEvals, AgentIcon, AgentMetadata, AgentMetadataList, AgentMetadataListEmpty, AgentMetadataListItem, AgentMetadataNetworkList, AgentMetadataPrompt, AgentMetadataScorerList, AgentMetadataSection, AgentMetadataToolList, AgentMetadataWorkflowList, AgentMetadataWrapper, AgentNetworkCoinIcon, AgentSettings, AgentSettingsContext, AgentSettingsProvider, AgentsTable, AiIcon, Alert, AlertDescription, AlertDialog, AlertTitle, ApiIcon, Badge$1 as Badge, BranchIcon, Breadcrumb, Button$1 as Button, Cell, ChatThreads, CheckIcon, ChevronIcon, Collapsible, CollapsibleContent, CollapsibleTrigger, CommitIcon, CrossIcon, Crumb, DarkLogo, DateTimeCell, DateTimePicker, DateTimePickerContent, DbIcon, DebugIcon, DefaultTrigger, DeploymentIcon, DividerIcon, DocsIcon, DynamicForm, EmptyState, Entity, EntityContent, EntityDescription, EntityHeader, EntityIcon, EntityMainHeader, EntityName, Entry, EntryCell, EntryList, EntryListItem, EntryListPageHeader, EntryListStatusCell, EntryListTextCell, EntryListToolbar, EnvIcon, EvaluatorCoinIcon, FiltersIcon, FolderIcon, FormActions, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, InputField, JudgeIcon, Kbd, KeyValueList, LatencyIcon, LinkComponentProvider, LogsIcon, MCPTable, MainContentContent, MainContentLayout, MastraResizablePanel, McpCoinIcon, McpServerIcon, MemoryIcon, MemorySearch, ModelResetProvider, OpenAIIcon, PageHeader, PlaygroundQueryClient, PlaygroundTabs, PromptIcon, RadioGroup, RadioGroupField, RadioGroupItem, RepoIcon, Row, RuntimeContext, RuntimeContextWrapper, ScoreDialog, ScoreIcon, ScorersTable, ScoresTools, SearchField, Searchbar, SearchbarWrapper, SelectField, SettingsIcon, SideDialog, SideDialogCodeSection, SideDialogContent, SideDialogFooter, SideDialogFooterGroup, SideDialogHeader, SideDialogHeading, SideDialogKeyValueList, SideDialogSection, SideDialogTop, SlashIcon, SliderField, Tab, TabContent, TabList, Table$1 as Table, Tbody, TemplateFailure, TemplateForm, TemplateInfo, TemplateInstallation, TemplateSuccess, TemplatesList, TemplatesTools, TextAndIcon, TextareaField, Th, Thead, ThreadDeleteButton, ThreadInputProvider, ThreadItem, ThreadLink, ThreadList, Threads, ToolCoinIcon, ToolFallback, ToolTable, ToolsIcon, TraceDialog, TraceIcon, TraceTimeline, TraceTimelineLegend, TraceTimelineSpan, TracesTools, TracesView, TracesViewSkeleton, TsIcon, Txt, TxtCell, UnitCell, VariablesIcon, WorkflowCoinIcon, WorkflowGraph, WorkflowIcon, WorkflowRunContext, WorkflowRunDetail, WorkflowRunList, WorkflowRunProvider, WorkflowTable, WorkflowTrigger, WorkingMemoryContext, WorkingMemoryProvider, allowedAiSpanAttributes, cleanString, convertWorkflowRunStateToStreamResult, formatDuration, formatHierarchicalSpans, formatOtelTimestamp, formatOtelTimestamp2, getColumnTemplate, getShortId, getSpanTypeUi, parseError, providerMapToIcon, spanTypePrefixes, transformKey, useAgentSettings, useCurrentRun, useInView, useLinkComponent, useMCPServerTools, useModelReset, usePlaygroundStore, usePolling, useScorer, useScorers, useScoresByEntityId, useScoresByScorerId, useSpeechRecognition, useThreadInput, useWorkflow, useWorkflowRuns, useWorkingMemory };
17767
+ export { AgentChat, AgentCoinIcon, AgentEntityHeader, AgentEvals, AgentIcon, AgentMetadata, AgentMetadataList, AgentMetadataListEmpty, AgentMetadataListItem, AgentMetadataNetworkList, AgentMetadataPrompt, AgentMetadataScorerList, AgentMetadataSection, AgentMetadataToolList, AgentMetadataWorkflowList, AgentMetadataWrapper, AgentNetworkCoinIcon, AgentSettings, AgentSettingsContext, AgentSettingsProvider, AgentsTable, AiIcon, Alert$1 as Alert, AlertDescription$1 as AlertDescription, AlertDialog, AlertTitle$1 as AlertTitle, ApiIcon, Badge$1 as Badge, BranchIcon, Breadcrumb, Button$1 as Button, ButtonsGroup, Cell, ChatThreads, CheckIcon, ChevronIcon, Collapsible, CollapsibleContent, CollapsibleTrigger, CommitIcon, CrossIcon, Crumb, DarkLogo, DateTimeCell, DateTimePicker, DateTimePickerContent, DbIcon, DebugIcon, DefaultTrigger, DeploymentIcon, DividerIcon, DocsIcon, DynamicForm, EmptyState, Entity, EntityContent, EntityDescription, EntityHeader, EntityIcon, EntityMainHeader, EntityName, Entry, EntryCell, EntryList, EntryListSkeleton, EnvIcon, EvaluatorCoinIcon, FiltersIcon, FolderIcon, FormActions, GithubCoinIcon, GithubIcon, GoogleIcon, Header, HeaderAction, HeaderGroup, HeaderTitle, HomeIcon, Icon, InfoIcon, InputField, JudgeIcon, Kbd, KeyValueList, LatencyIcon, LinkComponentProvider, LogsIcon, MCPTable, MainContentContent, MainContentLayout, MainSidebar, MainSidebarProvider, MastraResizablePanel, McpCoinIcon, McpServerIcon, MemoryIcon, MemorySearch, ModelResetProvider, Notification, OpenAIIcon, PageHeader, PlaygroundQueryClient, PlaygroundTabs, PromptIcon, RadioGroup, RadioGroupField, RadioGroupItem, RepoIcon, Row, RuntimeContext, RuntimeContextWrapper, ScoreDialog, ScoreIcon, ScorersTable, ScoresList, ScoresTools, SearchField, Searchbar, SearchbarWrapper, Section, Sections, SelectField, SettingsIcon, SideDialog, SlashIcon, SliderField, SpanScoreList, SpanScoring, SpanTabs, Tab$1 as Tab, TabContent$1 as TabContent, TabList$1 as TabList, Table$1 as Table, Tbody, TemplateFailure, TemplateForm, TemplateInfo, TemplateInstallation, TemplateSuccess, TemplatesList, TemplatesTools, TextAndIcon, TextareaField, Th, Thead, ThreadDeleteButton, ThreadInputProvider, ThreadItem, ThreadLink, ThreadList, Threads, ToolCoinIcon, ToolFallback, ToolTable, ToolsIcon, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TraceDialog, TraceIcon, TraceTimeline, TraceTimelineLegend, TraceTimelineSpan, TracesList, TracesTools, TracesView, TracesViewSkeleton, TsIcon, Txt, TxtCell, UnitCell, VariablesIcon, WorkflowCoinIcon, WorkflowGraph, WorkflowIcon, WorkflowRunContext, WorkflowRunDetail, WorkflowRunList, WorkflowRunProvider, WorkflowTable, WorkflowTrigger, WorkingMemoryContext, WorkingMemoryProvider, allowedAiSpanAttributes, cleanString, convertWorkflowRunStateToStreamResult, extractPrompt, formatDuration, formatHierarchicalSpans, formatOtelTimestamp, formatOtelTimestamp2, getColumnTemplate, getShortId, getSpanTypeUi, getToNextEntryFn, getToPreviousEntryFn, parseError, providerMapToIcon, scoresListColumns, spanTypePrefixes, traceScoresListColumns, tracesListColumns, transformKey, useAgentSettings, useCurrentRun, useInView, useLinkComponent, useMCPServerTools, useMainSidebar, useModelReset, usePlaygroundStore, usePolling, useScorer, useScorers, useScoresByEntityId, useScoresByScorerId, useSpeechRecognition, useThreadInput, useTraceSpanScores, useWorkflow, useWorkflowRuns, useWorkingMemory };
17826
17768
  //# sourceMappingURL=index.es.js.map