@mastra/playground-ui 6.2.2-alpha.2 → 6.2.2-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -63,6 +63,7 @@ const HoverCard = require('@radix-ui/react-hover-card');
63
63
  const AlertDialogPrimitive = require('@radix-ui/react-alert-dialog');
64
64
  const runtimeContext = require('@mastra/core/runtime-context');
65
65
  const format = require('date-fns/format');
66
+ const DropdownMenuPrimitive = require('@radix-ui/react-dropdown-menu');
66
67
 
67
68
  function _interopNamespaceDefault(e) {
68
69
  const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
@@ -97,6 +98,7 @@ const TabsPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(TabsPrimi
97
98
  const VisuallyHidden__namespace = /*#__PURE__*/_interopNamespaceDefault(VisuallyHidden);
98
99
  const HoverCard__namespace = /*#__PURE__*/_interopNamespaceDefault(HoverCard);
99
100
  const AlertDialogPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(AlertDialogPrimitive);
101
+ const DropdownMenuPrimitive__namespace = /*#__PURE__*/_interopNamespaceDefault(DropdownMenuPrimitive);
100
102
 
101
103
  const createMastraClient = (baseUrl, mastraClientHeaders = {}) => {
102
104
  return new clientJs.MastraClient({
@@ -4552,16 +4554,16 @@ const usePlaygroundStore = zustand.create()(
4552
4554
  )
4553
4555
  );
4554
4556
 
4555
- const useWorkflow = (workflowId, enabled = true) => {
4557
+ const useWorkflow = (workflowId) => {
4556
4558
  const client = useMastraClient();
4557
4559
  const { runtimeContext } = usePlaygroundStore();
4558
4560
  return reactQuery.useQuery({
4559
4561
  queryKey: ["workflow", workflowId],
4560
- queryFn: () => client.getWorkflow(workflowId).details(runtimeContext),
4562
+ queryFn: () => workflowId ? client.getWorkflow(workflowId).details(runtimeContext) : null,
4563
+ enabled: Boolean(workflowId),
4561
4564
  retry: false,
4562
4565
  refetchOnWindowFocus: false,
4563
- throwOnError: false,
4564
- enabled
4566
+ throwOnError: false
4565
4567
  });
4566
4568
  };
4567
4569
  const useLegacyWorkflow = (workflowId) => {
@@ -8292,7 +8294,7 @@ const Row = React.forwardRef(
8292
8294
  "tr",
8293
8295
  {
8294
8296
  className: clsx(
8295
- "border-b-sm border-border1 hover:bg-surface3 focus:bg-surface3 -outline-offset-2",
8297
+ "border-b-sm border-border1 hover:bg-surface3 focus:bg-surface3 -outline-offset-2 last:border-b-0",
8296
8298
  selected && "bg-surface4",
8297
8299
  onClick && "cursor-pointer",
8298
8300
  className
@@ -12947,13 +12949,13 @@ function KeyValueList({ data, LinkComponent, className, labelsAreHidden, isLoadi
12947
12949
  style: { width: `${Math.floor(Math.random() * (90 - 30 + 1)) + 50}%` },
12948
12950
  children: " "
12949
12951
  }
12950
- ) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: isValueItemArray ? value?.map((item) => {
12952
+ ) : isValueItemArray ? value?.map((item) => {
12951
12953
  return item.path ? /* @__PURE__ */ jsxRuntime.jsx(RelationWrapper, { description: item.description, children: /* @__PURE__ */ jsxRuntime.jsxs(Link, { href: item.path, children: [
12952
12954
  item?.name,
12953
12955
  " ",
12954
12956
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, {})
12955
12957
  ] }) }, item.id) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: item?.name }, item.id);
12956
- }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: value ? value : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3 text-[0.75rem]", children: "n/a" }) }) })
12958
+ }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: value ? value : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-icon3 text-[0.75rem]", children: "n/a" }) })
12957
12959
  }
12958
12960
  )
12959
12961
  ] }, label + index);
@@ -13649,7 +13651,7 @@ const DateTimePicker = ({
13649
13651
  /* @__PURE__ */ jsxRuntime.jsx(
13650
13652
  PopoverContent,
13651
13653
  {
13652
- className: "backdrop-blur-4xl w-auto p-0 bg-surface4 max-w-[16.5rem]",
13654
+ className: "backdrop-blur-4xl w-auto !p-0 bg-surface4 max-w-[16.5rem]",
13653
13655
  align: "start",
13654
13656
  "data-testid": "datepicker-calendar",
13655
13657
  children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -13775,7 +13777,7 @@ const DateTimePickerContent = ({
13775
13777
  "div",
13776
13778
  {
13777
13779
  "aria-label": "Choose date",
13778
- className: cn("relative mt-2 flex flex-col ", className),
13780
+ className: cn("relative flex flex-col", className),
13779
13781
  onKeyDown: (e) => {
13780
13782
  e.stopPropagation();
13781
13783
  if (e.key === "Escape") {
@@ -13872,7 +13874,16 @@ function getShortId(id) {
13872
13874
  return id.slice(0, 8);
13873
13875
  }
13874
13876
 
13875
- function ScoreDialog({ scorer, score, isOpen, onClose, onNext, onPrevious }) {
13877
+ function ScoreDialog({
13878
+ scorer,
13879
+ score,
13880
+ isOpen,
13881
+ onClose,
13882
+ onNext,
13883
+ onPrevious,
13884
+ computeTraceLink
13885
+ }) {
13886
+ const { Link } = useLinkComponent();
13876
13887
  return /* @__PURE__ */ jsxRuntime.jsxs(
13877
13888
  SideDialog,
13878
13889
  {
@@ -13895,10 +13906,30 @@ function ScoreDialog({ scorer, score, isOpen, onClose, onNext, onPrevious }) {
13895
13906
  ] })
13896
13907
  ] }) }),
13897
13908
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-[1.5rem] px-[2.5rem] overflow-y-auto grid gap-[1.5rem] content-start", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-[1.5rem] mb-[2rem]", children: [
13909
+ score?.traceId && /* @__PURE__ */ jsxRuntime.jsx(
13910
+ KeyValueList,
13911
+ {
13912
+ data: [
13913
+ {
13914
+ label: "Trace ID",
13915
+ value: /* @__PURE__ */ jsxRuntime.jsx(Link, { href: computeTraceLink(score?.traceId), children: score?.traceId }),
13916
+ key: "traceId"
13917
+ },
13918
+ ...score?.spanId ? [
13919
+ {
13920
+ label: "Span ID",
13921
+ value: /* @__PURE__ */ jsxRuntime.jsx(Link, { href: computeTraceLink(score?.traceId, score?.spanId), children: score?.spanId }),
13922
+ key: "spanId"
13923
+ }
13924
+ ] : []
13925
+ ],
13926
+ LinkComponent: Link
13927
+ }
13928
+ ),
13898
13929
  /* @__PURE__ */ jsxRuntime.jsx(
13899
13930
  SideDialogCodeSection,
13900
13931
  {
13901
- title: `Score: ${score?.score ? score?.score : "n/a"}`,
13932
+ title: `Score: ${Number.isNaN(score?.score) ? "n/a" : score?.score}`,
13902
13933
  codeStr: score?.reason,
13903
13934
  simplified: true
13904
13935
  }
@@ -13990,29 +14021,11 @@ const useScoresByEntityId = (entityId, entityType, page = 0) => {
13990
14021
  };
13991
14022
  const useScoresByScorerId = ({ scorerId, page = 0, entityId, entityType }) => {
13992
14023
  const client = useMastraClient();
13993
- const [scores, setScores] = React.useState(null);
13994
- const [isLoading, setIsLoading] = React.useState(true);
13995
- React.useEffect(() => {
13996
- const fetchScores = async () => {
13997
- setIsLoading(true);
13998
- try {
13999
- const res = await client.getScoresByScorerId({
14000
- scorerId,
14001
- page: page || 0,
14002
- entityId: entityId || void 0,
14003
- entityType: entityType || void 0,
14004
- perPage: 10
14005
- });
14006
- setScores(res);
14007
- setIsLoading(false);
14008
- } catch (error) {
14009
- setScores(null);
14010
- setIsLoading(false);
14011
- }
14012
- };
14013
- fetchScores();
14014
- }, [scorerId, page, entityId, entityType]);
14015
- return { scores, isLoading };
14024
+ return reactQuery.useQuery({
14025
+ queryKey: ["scores", scorerId, page, entityId, entityType],
14026
+ queryFn: () => client.getScoresByScorerId({ scorerId, page, entityId, entityType, perPage: 10 }),
14027
+ refetchInterval: 5e3
14028
+ });
14016
14029
  };
14017
14030
  const useScorer = (scorerId) => {
14018
14031
  const client = useMastraClient();
@@ -14038,25 +14051,12 @@ const useScorer = (scorerId) => {
14038
14051
  };
14039
14052
  const useScorers = () => {
14040
14053
  const client = useMastraClient();
14041
- const [scorers, setScorers] = React.useState({});
14042
- const [isLoading, setIsLoading] = React.useState(true);
14043
- React.useEffect(() => {
14044
- const fetchScorers = async () => {
14045
- setIsLoading(true);
14046
- try {
14047
- const res = await client.getScorers();
14048
- setScorers(res);
14049
- } catch (error) {
14050
- setScorers({});
14051
- console.error("Error fetching agents", error);
14052
- sonner.toast.error("Error fetching agents");
14053
- } finally {
14054
- setIsLoading(false);
14055
- }
14056
- };
14057
- fetchScorers();
14058
- }, []);
14059
- return { scorers, isLoading };
14054
+ return reactQuery.useQuery({
14055
+ queryKey: ["scorers"],
14056
+ queryFn: () => client.getScorers(),
14057
+ staleTime: 0,
14058
+ gcTime: 0
14059
+ });
14060
14060
  };
14061
14061
 
14062
14062
  const NameCell = ({ row }) => {
@@ -14303,7 +14303,9 @@ const AgentMetadataModelSwitcher = ({
14303
14303
  defaultModel,
14304
14304
  updateModel,
14305
14305
  closeEditor,
14306
- modelProviders
14306
+ modelProviders,
14307
+ autoSave = false,
14308
+ selectProviderPlaceholder = "Select provider"
14307
14309
  }) => {
14308
14310
  const [selectedModel, setSelectedModel] = React.useState(defaultModel);
14309
14311
  const [showSuggestions, setShowSuggestions] = React.useState(false);
@@ -14315,10 +14317,19 @@ const AgentMetadataModelSwitcher = ({
14315
14317
  return "";
14316
14318
  });
14317
14319
  const [loading, setLoading] = React.useState(false);
14320
+ const [infoMsg, setInfoMsg] = React.useState("");
14318
14321
  const modelsList = Object.entries(Models).filter(([provider]) => modelProviders.includes(provider));
14319
14322
  const allModels = modelsList.flatMap(([_, { models }]) => models);
14320
14323
  const providersList = modelsList.map(([provider, { icon }]) => ({ provider, icon }));
14321
14324
  const model = allModels.find((model2) => model2.model === selectedModel);
14325
+ React.useEffect(() => {
14326
+ const isValidModel = allModels.some((model2) => model2.model === selectedModel);
14327
+ if (selectedModel && !isValidModel) {
14328
+ setInfoMsg("Model not in suggestions—make sure the name is correct.");
14329
+ } else {
14330
+ setInfoMsg("");
14331
+ }
14332
+ }, [selectedModel, allModels]);
14322
14333
  const handleSave = async () => {
14323
14334
  setLoading(true);
14324
14335
  const providerToUse = model?.provider ?? selectedProvider;
@@ -14326,67 +14337,156 @@ const AgentMetadataModelSwitcher = ({
14326
14337
  setLoading(false);
14327
14338
  closeEditor();
14328
14339
  };
14329
- const filteredModels = allModels.filter((model2) => model2.model.includes(selectedModel));
14330
- return /* @__PURE__ */ jsxRuntime.jsx(TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
14340
+ const filteredModels = allModels.filter((model2) => {
14341
+ if (selectedProvider) {
14342
+ return model2.model.includes(selectedModel) && model2.provider === selectedProvider;
14343
+ }
14344
+ return model2.model.includes(selectedModel);
14345
+ });
14346
+ const handleProviderChange = (provider) => {
14347
+ setSelectedProvider(provider);
14348
+ setSelectedModel("");
14349
+ if (autoSave) {
14350
+ updateModel({
14351
+ provider,
14352
+ modelId: ""
14353
+ });
14354
+ }
14355
+ };
14356
+ const handleModelInputBlur = (e) => {
14357
+ setShowSuggestions(false);
14358
+ const isValidModel = allModels.some((model2) => model2.model === e.target.value);
14359
+ if (!isValidModel) {
14360
+ if (autoSave) {
14361
+ updateModel({
14362
+ provider: selectedProvider,
14363
+ modelId: e.target.value
14364
+ });
14365
+ }
14366
+ }
14367
+ };
14368
+ const handleModelClick = (model2) => {
14369
+ setSelectedModel(model2.model);
14370
+ const isValidModel = allModels.some((m) => m.model === model2.model);
14371
+ if (isValidModel) {
14372
+ setSelectedProvider(model2.provider);
14373
+ }
14374
+ if (autoSave) {
14375
+ updateModel({
14376
+ provider: model2.provider,
14377
+ modelId: model2.model
14378
+ });
14379
+ }
14380
+ setShowSuggestions(false);
14381
+ };
14382
+ const handleModelInputChange = (e) => {
14383
+ setSelectedModel(e.target.value);
14384
+ const isValidModel = allModels.some((m) => m.model === e.target.value);
14385
+ if (isValidModel) {
14386
+ const model2 = allModels.find((m) => m.model === e.target.value);
14387
+ if (model2) {
14388
+ setSelectedProvider(model2.provider);
14389
+ }
14390
+ }
14391
+ };
14392
+ const handleModelReset = () => {
14393
+ setSelectedModel("");
14394
+ setInfoMsg("");
14395
+ if (autoSave) {
14396
+ updateModel({
14397
+ provider: selectedProvider,
14398
+ modelId: ""
14399
+ });
14400
+ }
14401
+ };
14402
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
14331
14403
  /* @__PURE__ */ jsxRuntime.jsxs(
14332
- Select$1,
14404
+ "div",
14333
14405
  {
14334
- value: model?.provider ?? selectedProvider,
14335
- onValueChange: setSelectedProvider,
14336
- disabled: !!model?.provider,
14406
+ className: cn("grid items-center gap-2", {
14407
+ "xl:grid-cols-[auto_1fr_auto]": !autoSave,
14408
+ "xl:grid-cols-[auto_1fr]": autoSave
14409
+ }),
14337
14410
  children: [
14338
- /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "max-w-[150px]", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select provider" }) }),
14339
- /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: providersList.map((provider) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: provider.provider, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
14340
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: providerMapToIcon[provider.icon] }),
14341
- provider.provider
14342
- ] }) }, provider.provider)) })
14411
+ /* @__PURE__ */ jsxRuntime.jsxs(Select$1, { value: selectedProvider, onValueChange: handleProviderChange, disabled: !!model?.provider, children: [
14412
+ /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: selectProviderPlaceholder }) }),
14413
+ /* @__PURE__ */ jsxRuntime.jsx(SelectContent, { children: providersList.map((provider) => /* @__PURE__ */ jsxRuntime.jsx(SelectItem, { value: provider.provider, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
14414
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: providerMapToIcon[provider.icon] }),
14415
+ provider.provider
14416
+ ] }) }, provider.provider)) })
14417
+ ] }),
14418
+ /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: showSuggestions, children: [
14419
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
14420
+ /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
14421
+ Input,
14422
+ {
14423
+ id: "model-input",
14424
+ list: "model-suggestions",
14425
+ className: "flex-1 w-full h-[2.25rem] rounded-md min-w-[12rem]",
14426
+ type: "text",
14427
+ value: selectedModel,
14428
+ onChange: handleModelInputChange,
14429
+ onFocus: () => setShowSuggestions(true),
14430
+ onBlur: handleModelInputBlur,
14431
+ placeholder: "Enter model name or select from suggestions...",
14432
+ autoComplete: "off"
14433
+ }
14434
+ ) }),
14435
+ selectedModel && /* @__PURE__ */ jsxRuntime.jsx(
14436
+ "button",
14437
+ {
14438
+ className: "flex items-center justify-center absolute top-0 right-0 text-icon3 hover:text-white hover:text-icon4 w-[2.25rem] h-[2.25rem] p-[.5rem] rounded-md",
14439
+ onClick: handleModelReset,
14440
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.XIcon, {})
14441
+ }
14442
+ )
14443
+ ] }),
14444
+ filteredModels.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
14445
+ PopoverContent,
14446
+ {
14447
+ onOpenAutoFocus: (e) => e.preventDefault(),
14448
+ className: "flex flex-col w-[var(--radix-popover-trigger-width)] max-h-[calc(var(--radix-popover-content-available-height)-50px)] overflow-y-auto",
14449
+ children: filteredModels.map((model2) => /* @__PURE__ */ jsxRuntime.jsx(
14450
+ "button",
14451
+ {
14452
+ className: "flex items-center justify-start gap-2 cursor-pointer hover:bg-surface5 p-2 text-[0.875rem]",
14453
+ onClick: () => handleModelClick(model2),
14454
+ children: model2.model
14455
+ },
14456
+ model2.provider + model2.model
14457
+ ))
14458
+ }
14459
+ )
14460
+ ] }),
14461
+ !autoSave && /* @__PURE__ */ jsxRuntime.jsx(
14462
+ Button$2,
14463
+ {
14464
+ onClick: handleSave,
14465
+ variant: "secondary",
14466
+ size: "sm",
14467
+ disabled: loading || !selectedModel,
14468
+ className: "w-full",
14469
+ children: loading ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}) }) : "Save"
14470
+ }
14471
+ )
14343
14472
  ]
14344
14473
  }
14345
14474
  ),
14346
- /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: showSuggestions, children: [
14347
- /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
14348
- Input,
14349
- {
14350
- id: "model-input",
14351
- list: "model-suggestions",
14352
- className: "flex-1",
14353
- type: "text",
14354
- value: selectedModel,
14355
- onChange: (e) => {
14356
- setSelectedModel(e.target.value);
14357
- setShowSuggestions(true);
14358
- },
14359
- placeholder: "Enter model name or select from suggestions..."
14360
- }
14361
- ) }),
14362
- filteredModels.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
14363
- PopoverContent,
14364
- {
14365
- onOpenAutoFocus: (e) => e.preventDefault(),
14366
- className: "flex flex-col gap-2 w-[var(--radix-popover-trigger-width)] max-h-[calc(var(--radix-popover-content-available-height)-50px)] overflow-y-auto",
14367
- children: filteredModels.map((model2) => /* @__PURE__ */ jsxRuntime.jsxs(
14368
- "div",
14369
- {
14370
- className: "flex items-center gap-2 cursor-pointer hover:bg-surface5 p-2",
14371
- onClick: () => {
14372
- setSelectedModel(model2.model);
14373
- setShowSuggestions(false);
14374
- },
14375
- children: [
14376
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: providerMapToIcon[model2.icon] }),
14377
- model2.model
14378
- ]
14379
- },
14380
- model2.provider + model2.model
14381
- ))
14382
- }
14383
- )
14384
- ] }),
14385
- /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
14386
- /* @__PURE__ */ jsxRuntime.jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: handleSave, className: "text-icon3 hover:text-icon6", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: loading ? /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleCheck, {}) }) }) }),
14387
- /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: loading ? "Saving..." : "Save new model" })
14388
- ] })
14389
- ] }) });
14475
+ infoMsg && /* @__PURE__ */ jsxRuntime.jsxs(
14476
+ "div",
14477
+ {
14478
+ className: cn(
14479
+ "text-[0.75rem] text-icon3 flex gap-[.5rem] mt-[0.5rem] ml-[.5rem]",
14480
+ "[&>svg]:w-[1.1em] [&>svg]:h-[1.1em] [&>svg]:opacity-7 [&>svg]:flex-shrink-0 [&>svg]:mt-[0.1rem]"
14481
+ ),
14482
+ children: [
14483
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.InfoIcon, {}),
14484
+ " ",
14485
+ infoMsg
14486
+ ]
14487
+ }
14488
+ )
14489
+ ] });
14390
14490
  };
14391
14491
 
14392
14492
  const AgentMetadataNetworkList = ({ agents }) => {
@@ -14499,11 +14599,11 @@ const AgentMetadataWorkflowList = ({ workflows }) => {
14499
14599
  };
14500
14600
  const AgentMetadataScorerList = ({ entityId, entityType }) => {
14501
14601
  const { Link, paths } = useLinkComponent();
14502
- const { scorers, isLoading } = useScorers();
14602
+ const { data: scorers = {}, isLoading } = useScorers();
14503
14603
  const scorerList = Object.keys(scorers).filter((scorerKey) => {
14504
14604
  const scorer = scorers[scorerKey];
14505
14605
  if (entityType === "AGENT") {
14506
- return scorer.agentIds.includes(entityId);
14606
+ return scorer.agentNames.includes(entityId);
14507
14607
  }
14508
14608
  return scorer.workflowIds.includes(entityId);
14509
14609
  }).map((scorerKey) => ({ ...scorers[scorerKey], id: scorerKey }));
@@ -16292,7 +16392,7 @@ function TemplateForm({
16292
16392
  "h2",
16293
16393
  {
16294
16394
  className: cn(
16295
- "text-icon5 text-[1.125rem] font-semibold flex items-center gap-[0.5rem]",
16395
+ "text-icon4 text-[1.125rem] font-semibold flex items-center gap-[0.5rem]",
16296
16396
  "[&>svg]:w-[1.2em] [&_svg]:h-[1.2em] [&_svg]:opacity-70 "
16297
16397
  ),
16298
16398
  children: [
@@ -16305,29 +16405,13 @@ function TemplateForm({
16305
16405
  SelectField,
16306
16406
  {
16307
16407
  options: providerOptions,
16308
- label: "Provider",
16408
+ label: "Template AI Model Provider",
16309
16409
  onValueChange: onProviderChange,
16310
16410
  value: selectedProvider,
16311
- placeholder: "Select a provider"
16411
+ placeholder: "Select"
16312
16412
  }
16313
16413
  ),
16314
16414
  selectedProvider && Object.entries(variables || {}).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16315
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-[0.5rem]", children: [
16316
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-icon3 text-[0.875rem] font-medium", children: "Select AI Model for Template Installation *" }),
16317
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-icon4 text-[0.75rem]", children: "This model will be used by the workflow to process and install the template" }),
16318
- /* @__PURE__ */ jsxRuntime.jsx(
16319
- AgentMetadataModelSwitcher,
16320
- {
16321
- defaultProvider: defaultModelProvider || "",
16322
- defaultModel: defaultModelId || "",
16323
- updateModel: onModelUpdate || (() => Promise.resolve({ message: "Updated" })),
16324
- closeEditor: () => {
16325
- },
16326
- modelProviders: ["openai", "anthropic", "google", "xai", "groq"]
16327
- }
16328
- ),
16329
- (!defaultModelProvider || !defaultModelId) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-red-500 text-[0.75rem]", children: "Please select an AI model to continue" })
16330
- ] }),
16331
16415
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-icon3 text-[0.875rem]", children: "Set required Environmental Variables" }),
16332
16416
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-[1fr_1fr] gap-[1rem] items-start", children: isLoadingEnvVars ? /* @__PURE__ */ jsxRuntime.jsxs(
16333
16417
  "div",
@@ -16367,13 +16451,31 @@ function TemplateForm({
16367
16451
  className: "w-full"
16368
16452
  }
16369
16453
  )
16370
- ] }, key)) })
16454
+ ] }, key)) }),
16455
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t border-border1 pt-[3rem] mt-[0.875rem] relative", children: [
16456
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute w-[2rem] h-[2rem] rounded-full bg-surface2 top-0 left-[50%] translate-x-[-50%] translate-y-[-1rem] text-[0.75rem] text-icon3 flex items-center justify-center", children: "And" }),
16457
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-icon4 text-[1rem]", children: "Set AI Model for Template Installation" }),
16458
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-icon3 text-[0.875rem] mt-[.5rem] mb-[2rem]", children: "This model will be used by the workflow to process and install the template" }),
16459
+ /* @__PURE__ */ jsxRuntime.jsx(
16460
+ AgentMetadataModelSwitcher,
16461
+ {
16462
+ defaultProvider: defaultModelProvider || "",
16463
+ defaultModel: defaultModelId || "",
16464
+ updateModel: onModelUpdate || (() => Promise.resolve({ message: "Updated" })),
16465
+ closeEditor: () => {
16466
+ },
16467
+ modelProviders: ["openai", "anthropic", "google", "xai", "groq"],
16468
+ autoSave: true,
16469
+ selectProviderPlaceholder: "Provider"
16470
+ }
16471
+ )
16472
+ ] })
16371
16473
  ] }),
16372
16474
  selectedProvider && !isLoadingEnvVars && /* @__PURE__ */ jsxRuntime.jsxs(
16373
- "button",
16475
+ Button,
16374
16476
  {
16375
16477
  className: cn(
16376
- "flex items-center gap-[0.5rem] justify-center text-[0.875rem] w-full bg-surface5 min-h-[2.5rem] rounded-lg text-icon5 hover:bg-surface6 transition-colors",
16478
+ "flex items-center gap-[0.5rem] mt-[1rem] justify-center text-[0.875rem] w-full bg-surface5 min-h-[2.5rem] rounded-lg text-icon5 hover:bg-surface6 transition-colors",
16377
16479
  "[&>svg]:w-[1.1em] [&_svg]:h-[1.1em] [&_svg]:text-icon5"
16378
16480
  ),
16379
16481
  onClick: handleInstallTemplate,
@@ -16612,7 +16714,7 @@ function TemplateFailure({ errorMsg, validationErrors }) {
16612
16714
  };
16613
16715
  };
16614
16716
  const { icon, title } = getIconAndTitle();
16615
- return /* @__PURE__ */ jsxRuntime.jsxs(Container, { className: "space-y-4 text-icon3 mb-[2rem] content-center max-w-2xl mx-auto", children: [
16717
+ return /* @__PURE__ */ jsxRuntime.jsxs(Container, { className: "space-y-4 text-icon3 mb-[2rem] content-center", children: [
16616
16718
  /* @__PURE__ */ jsxRuntime.jsxs(
16617
16719
  "div",
16618
16720
  {
@@ -17710,10 +17812,14 @@ function TraceTimeline({
17710
17812
  ) : /* @__PURE__ */ jsxRuntime.jsx(
17711
17813
  "div",
17712
17814
  {
17713
- className: cn("grid items-start content-start gap-y-[2px]", "xl:gap-x-[1rem] xl:py-[1rem]", {
17714
- "xl:grid-cols-[3fr_auto]": !overallEndTime,
17715
- "xl:grid-cols-[3fr_2fr]": overallEndTime
17716
- }),
17815
+ className: cn(
17816
+ "grid items-start content-start gap-y-[2px] bg-surface2 rounded-lg overflow-hidden pl-[1.5rem] py-[1.5rem]",
17817
+ "xl:gap-x-[1rem] xl:py-[1rem]",
17818
+ {
17819
+ "xl:grid-cols-[3fr_auto]": !overallEndTime,
17820
+ "xl:grid-cols-[3fr_2fr]": overallEndTime
17821
+ }
17822
+ ),
17717
17823
  children: hierarchicalSpans?.map((span) => /* @__PURE__ */ jsxRuntime.jsx(
17718
17824
  TraceTimelineSpan,
17719
17825
  {
@@ -17987,7 +18093,24 @@ function getSpanInfo({ span, withTraceId = true, withSpanId = true }) {
17987
18093
  return baseInfo;
17988
18094
  }
17989
18095
 
17990
- function SpanDetails({ span }) {
18096
+ const ScoreTable = ({ scores, onItemClick }) => {
18097
+ return /* @__PURE__ */ jsxRuntime.jsxs(Table$1, { children: [
18098
+ /* @__PURE__ */ jsxRuntime.jsxs(Thead, { children: [
18099
+ /* @__PURE__ */ jsxRuntime.jsx(Th, { children: "Type" }),
18100
+ /* @__PURE__ */ jsxRuntime.jsx(Th, { children: "Scorer" }),
18101
+ /* @__PURE__ */ jsxRuntime.jsx(Th, { children: "Score" }),
18102
+ /* @__PURE__ */ jsxRuntime.jsx(Th, { children: "Created At" })
18103
+ ] }),
18104
+ /* @__PURE__ */ jsxRuntime.jsx(Tbody, { children: scores.map((score) => /* @__PURE__ */ jsxRuntime.jsxs(Row, { onClick: () => onItemClick(score.scorerName), children: [
18105
+ /* @__PURE__ */ jsxRuntime.jsx(TxtCell, { children: /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { children: score.type }) }),
18106
+ /* @__PURE__ */ jsxRuntime.jsx(TxtCell, { children: score.scorerName }),
18107
+ /* @__PURE__ */ jsxRuntime.jsx(TxtCell, { children: score.score }),
18108
+ /* @__PURE__ */ jsxRuntime.jsx(DateTimeCell, { dateTime: new Date(score.createdAt) })
18109
+ ] }, score.scoreId)) })
18110
+ ] });
18111
+ };
18112
+
18113
+ function SpanDetails({ span, onScorerTriggered }) {
17991
18114
  if (!span) {
17992
18115
  return null;
17993
18116
  }
@@ -17995,18 +18118,226 @@ function SpanDetails({ span }) {
17995
18118
  /* @__PURE__ */ jsxRuntime.jsx(SideDialogCodeSection, { title: "Input", codeStr: JSON.stringify(span.input || null, null, 2) }),
17996
18119
  /* @__PURE__ */ jsxRuntime.jsx(SideDialogCodeSection, { title: "Output", codeStr: JSON.stringify(span.output || null, null, 2) }),
17997
18120
  /* @__PURE__ */ jsxRuntime.jsx(SideDialogCodeSection, { title: "Metadata", codeStr: JSON.stringify(span.metadata || null, null, 2) }),
17998
- /* @__PURE__ */ jsxRuntime.jsx(SideDialogCodeSection, { title: "Attributes", codeStr: JSON.stringify(span.attributes || null, null, 2) })
18121
+ /* @__PURE__ */ jsxRuntime.jsx(SideDialogCodeSection, { title: "Attributes", codeStr: JSON.stringify(span.attributes || null, null, 2) }),
18122
+ span?.links?.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-[2.5rem] pr-[2.5rem]", children: [
18123
+ /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeading, { as: "h2", className: "pb-[1rem]", children: [
18124
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GaugeIcon, {}),
18125
+ " Scores"
18126
+ ] }),
18127
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface2 rounded-lg overflow-hidden border-sm border-border1", children: /* @__PURE__ */ jsxRuntime.jsx(
18128
+ ScoreTable,
18129
+ {
18130
+ scores: span?.links,
18131
+ onItemClick: (scorerName) => onScorerTriggered(scorerName, span.traceId, span.spanId)
18132
+ }
18133
+ ) })
18134
+ ] })
17999
18135
  ] });
18000
18136
  }
18001
18137
 
18138
+ const DropdownMenu = DropdownMenuPrimitive__namespace.Root;
18139
+ const DropdownMenuGroup = DropdownMenuPrimitive__namespace.Group;
18140
+ const DropdownMenuPortal = DropdownMenuPrimitive__namespace.Portal;
18141
+ const DropdownMenuSub = DropdownMenuPrimitive__namespace.Sub;
18142
+ const DropdownMenuRadioGroup = DropdownMenuPrimitive__namespace.RadioGroup;
18143
+ const DropdownMenuTrigger = React__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.Trigger, { ref, className: cn("cursor-pointer focus-visible:rounded", className), ...props, children }));
18144
+ DropdownMenuTrigger.displayName = DropdownMenuPrimitive__namespace.Trigger.displayName;
18145
+ const DropdownMenuSubTrigger = React__namespace.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
18146
+ DropdownMenuPrimitive__namespace.SubTrigger,
18147
+ {
18148
+ ref,
18149
+ className: cn(
18150
+ "focus:bg-accent data-[state=open]:bg-accent flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm",
18151
+ inset && "pl-8",
18152
+ className
18153
+ ),
18154
+ ...props,
18155
+ children: [
18156
+ children,
18157
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "ml-auto -rotate-90" })
18158
+ ]
18159
+ }
18160
+ ));
18161
+ DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive__namespace.SubTrigger.displayName;
18162
+ const DropdownMenuSubContent = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
18163
+ DropdownMenuPrimitive__namespace.SubContent,
18164
+ {
18165
+ ref,
18166
+ className: cn(
18167
+ "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",
18168
+ className
18169
+ ),
18170
+ ...props
18171
+ }
18172
+ ));
18173
+ DropdownMenuSubContent.displayName = DropdownMenuPrimitive__namespace.SubContent.displayName;
18174
+ const DropdownMenuContent = React__namespace.forwardRef(({ className, container, sideOffset = 4, ...props }, ref) => {
18175
+ return /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.Portal, { container, children: /* @__PURE__ */ jsxRuntime.jsx(
18176
+ DropdownMenuPrimitive__namespace.Content,
18177
+ {
18178
+ ref,
18179
+ sideOffset,
18180
+ className: clsx(
18181
+ "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",
18182
+ className
18183
+ ),
18184
+ ...props
18185
+ }
18186
+ ) });
18187
+ });
18188
+ DropdownMenuContent.displayName = DropdownMenuPrimitive__namespace.Content.displayName;
18189
+ const DropdownMenuItem = React__namespace.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
18190
+ DropdownMenuPrimitive__namespace.Item,
18191
+ {
18192
+ ref,
18193
+ className: cn(
18194
+ "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",
18195
+ inset && "pl-8",
18196
+ className
18197
+ ),
18198
+ ...props
18199
+ }
18200
+ ));
18201
+ DropdownMenuItem.displayName = DropdownMenuPrimitive__namespace.Item.displayName;
18202
+ const DropdownMenuCheckboxItem = React__namespace.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
18203
+ DropdownMenuPrimitive__namespace.CheckboxItem,
18204
+ {
18205
+ ref,
18206
+ className: cn(
18207
+ "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",
18208
+ className
18209
+ ),
18210
+ checked,
18211
+ ...props,
18212
+ children: [
18213
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-sm border-border1 flex h-4 w-4 items-center justify-center rounded-sm", children: checked && /* @__PURE__ */ jsxRuntime.jsx(Icon, { size: "sm", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, {}) }) }),
18214
+ children
18215
+ ]
18216
+ }
18217
+ ));
18218
+ DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive__namespace.CheckboxItem.displayName;
18219
+ const DropdownMenuRadioItem = React__namespace.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
18220
+ DropdownMenuPrimitive__namespace.RadioItem,
18221
+ {
18222
+ ref,
18223
+ className: cn(
18224
+ "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",
18225
+ className
18226
+ ),
18227
+ ...props,
18228
+ children: [
18229
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuPrimitive__namespace.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Circle, { className: "h-2 w-2 fill-current" }) }) }),
18230
+ children
18231
+ ]
18232
+ }
18233
+ ));
18234
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive__namespace.RadioItem.displayName;
18235
+ const DropdownMenuLabel = React__namespace.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
18236
+ DropdownMenuPrimitive__namespace.Label,
18237
+ {
18238
+ ref,
18239
+ className: cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className),
18240
+ ...props
18241
+ }
18242
+ ));
18243
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive__namespace.Label.displayName;
18244
+ const DropdownMenuSeparator = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
18245
+ DropdownMenuPrimitive__namespace.Separator,
18246
+ {
18247
+ ref,
18248
+ className: cn("popover-dividers-bg -mx-1 my-1 h-px", className),
18249
+ ...props
18250
+ }
18251
+ ));
18252
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive__namespace.Separator.displayName;
18253
+ const DropdownMenuShortcut = ({ className, ...props }) => {
18254
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn("ml-auto text-xs tracking-widest opacity-60", className), ...props });
18255
+ };
18256
+ DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
18257
+ function Dropdown({
18258
+ open,
18259
+ onOpenChange,
18260
+ children,
18261
+ modal
18262
+ }) {
18263
+ return /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu, { modal, open, onOpenChange, children });
18264
+ }
18265
+ Dropdown.Trigger = DropdownMenuTrigger;
18266
+ Dropdown.Content = DropdownMenuContent;
18267
+ Dropdown.Group = DropdownMenuGroup;
18268
+ Dropdown.Portal = DropdownMenuPortal;
18269
+ Dropdown.Item = DropdownMenuItem;
18270
+ Dropdown.CheckboxItem = DropdownMenuCheckboxItem;
18271
+ Dropdown.RadioItem = DropdownMenuRadioItem;
18272
+ Dropdown.Label = DropdownMenuLabel;
18273
+ Dropdown.Separator = DropdownMenuSeparator;
18274
+ Dropdown.Shortcut = DropdownMenuShortcut;
18275
+ Dropdown.Sub = DropdownMenuSub;
18276
+ Dropdown.SubContent = DropdownMenuSubContent;
18277
+ Dropdown.SubTrigger = DropdownMenuSubTrigger;
18278
+ Dropdown.RadioGroup = DropdownMenuRadioGroup;
18279
+
18280
+ const useTriggerScorer = (onScorerTriggered) => {
18281
+ const client = useMastraClient();
18282
+ return reactQuery.useMutation({
18283
+ mutationFn: async ({ scorerName, traceId, spanId }) => {
18284
+ const response = await client.score({
18285
+ scorerName,
18286
+ targets: [{ traceId, spanId }]
18287
+ });
18288
+ return response;
18289
+ },
18290
+ onSuccess: (_, variables) => {
18291
+ sonner.toast.success("Scorer triggered successfully");
18292
+ onScorerTriggered(variables.scorerName, variables.traceId, variables.spanId);
18293
+ },
18294
+ onError: () => {
18295
+ sonner.toast.error("Error triggering scorer");
18296
+ }
18297
+ });
18298
+ };
18299
+
18300
+ const ScorersDropdown = ({ trace, spanId, onScorerTriggered, entityType }) => {
18301
+ const { data: scorers = {}, isLoading } = useScorers();
18302
+ const { mutate: triggerScorer, isPending } = useTriggerScorer(onScorerTriggered);
18303
+ let scorerList = Object.entries(scorers).map(([key, scorer]) => ({
18304
+ id: key,
18305
+ name: scorer.scorer.config.name,
18306
+ description: scorer.scorer.config.description,
18307
+ isRegistered: scorer.isRegistered,
18308
+ type: scorer.scorer.config.type
18309
+ })).filter((scorer) => scorer.isRegistered);
18310
+ if (entityType !== "Agent" || spanId) {
18311
+ scorerList = scorerList.filter((scorer) => scorer.type !== "agent");
18312
+ }
18313
+ const isWaiting = isPending || isLoading;
18314
+ return /* @__PURE__ */ jsxRuntime.jsxs(Dropdown, { children: [
18315
+ /* @__PURE__ */ jsxRuntime.jsx(Dropdown.Trigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(Button$1, { variant: "light", disabled: isWaiting, children: [
18316
+ isWaiting ? /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(Spinner, {}) }) : /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GaugeIcon, {}) }),
18317
+ "Run scorer",
18318
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, {}) })
18319
+ ] }) }),
18320
+ /* @__PURE__ */ jsxRuntime.jsx(Dropdown.Content, { children: scorerList.map((scorer) => /* @__PURE__ */ jsxRuntime.jsx(
18321
+ Dropdown.Item,
18322
+ {
18323
+ onClick: () => triggerScorer({ scorerName: scorer.name, traceId: trace.traceId, spanId }),
18324
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: scorer.name })
18325
+ },
18326
+ scorer.id
18327
+ )) })
18328
+ ] });
18329
+ };
18330
+
18002
18331
  function SpanDialog({
18332
+ trace,
18003
18333
  span,
18004
18334
  isOpen,
18005
18335
  onClose,
18006
18336
  onNext,
18007
18337
  onPrevious,
18008
18338
  onViewToggle,
18009
- spanInfo = []
18339
+ spanInfo = [],
18340
+ onScorerTriggered
18010
18341
  }) {
18011
18342
  const { Link } = useLinkComponent();
18012
18343
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -18035,21 +18366,24 @@ function SpanDialog({
18035
18366
  /* @__PURE__ */ jsxRuntime.jsx("button", { className: "flex items-center gap-1", onClick: onViewToggle, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelTopIcon, {}) })
18036
18367
  ] }),
18037
18368
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-[1.5rem] px-[2.5rem] overflow-y-auto grid gap-[1.5rem] content-start", children: [
18038
- /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
18039
- /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeading, { children: [
18040
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsLeftRightEllipsisIcon, {}),
18041
- " ",
18042
- span?.name
18369
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
18370
+ /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
18371
+ /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeading, { children: [
18372
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsLeftRightEllipsisIcon, {}),
18373
+ " ",
18374
+ span?.name
18375
+ ] }),
18376
+ /* @__PURE__ */ jsxRuntime.jsxs(TextAndIcon, { children: [
18377
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.HashIcon, {}),
18378
+ " ",
18379
+ span?.spanId
18380
+ ] })
18043
18381
  ] }),
18044
- /* @__PURE__ */ jsxRuntime.jsxs(TextAndIcon, { children: [
18045
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.HashIcon, {}),
18046
- " ",
18047
- span?.spanId
18048
- ] })
18382
+ span?.traceId && span?.spanId && /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ScorersDropdown, { trace, spanId: span?.spanId, onScorerTriggered }) })
18049
18383
  ] }),
18050
18384
  span?.attributes?.usage && /* @__PURE__ */ jsxRuntime.jsx(TraceSpanUsage, { spanUsage: span.attributes.usage, className: "mt-[1.5rem]" }),
18051
18385
  /* @__PURE__ */ jsxRuntime.jsx(KeyValueList, { data: spanInfo, LinkComponent: Link, className: "mt-[1.5rem]" }),
18052
- /* @__PURE__ */ jsxRuntime.jsx(SpanDetails, { span })
18386
+ /* @__PURE__ */ jsxRuntime.jsx(SpanDetails, { span, onScorerTriggered })
18053
18387
  ] })
18054
18388
  ]
18055
18389
  }
@@ -18064,11 +18398,15 @@ function TraceDialog({
18064
18398
  onClose,
18065
18399
  onNext,
18066
18400
  onPrevious,
18067
- isLoadingSpans
18401
+ isLoadingSpans,
18402
+ computeAgentsLink,
18403
+ computeWorkflowsLink,
18404
+ onScorerTriggered,
18405
+ initialSpanId
18068
18406
  }) {
18069
18407
  const { Link } = useLinkComponent();
18070
- const [dialogIsOpen, setDialogIsOpen] = React.useState(false);
18071
- const [selectedSpanId, setSelectedSpanId] = React.useState(void 0);
18408
+ const [dialogIsOpen, setDialogIsOpen] = React.useState(Boolean(initialSpanId));
18409
+ const [selectedSpanId, setSelectedSpanId] = React.useState(initialSpanId);
18072
18410
  const [combinedView, setCombinedView] = React.useState(false);
18073
18411
  const selectedSpan = traceSpans.find((span) => span.spanId === selectedSpanId);
18074
18412
  const traceInfo = useTraceInfo(traceDetails);
@@ -18116,6 +18454,12 @@ function TraceDialog({
18116
18454
  return currentIndex > 0;
18117
18455
  };
18118
18456
  const selectedSpanInfo = getSpanInfo({ span: selectedSpan, withTraceId: !combinedView, withSpanId: combinedView });
18457
+ let entityType;
18458
+ if (traceDetails?.attributes?.agentId) {
18459
+ entityType = "Agent";
18460
+ } else if (traceDetails?.attributes?.workflowId) {
18461
+ entityType = "Workflow";
18462
+ }
18119
18463
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18120
18464
  /* @__PURE__ */ jsxRuntime.jsxs(
18121
18465
  SideDialog,
@@ -18139,7 +18483,7 @@ function TraceDialog({
18139
18483
  "grid-rows-[auto_1fr_1fr]": selectedSpan && combinedView
18140
18484
  }),
18141
18485
  children: [
18142
- /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
18486
+ /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeader, { className: "pr-[2.5rem]", children: [
18143
18487
  /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeading, { children: [
18144
18488
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.EyeIcon, {}),
18145
18489
  " ",
@@ -18152,6 +18496,15 @@ function TraceDialog({
18152
18496
  ] })
18153
18497
  ] }),
18154
18498
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("overflow-y-auto pb-[2.5rem]"), children: [
18499
+ traceDetails && /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(
18500
+ ScorersDropdown,
18501
+ {
18502
+ trace: traceDetails,
18503
+ spanId: selectedSpanId,
18504
+ onScorerTriggered,
18505
+ entityType
18506
+ }
18507
+ ) }),
18155
18508
  traceDetails?.metadata?.usage && /* @__PURE__ */ jsxRuntime.jsx(
18156
18509
  TraceSpanUsage,
18157
18510
  {
@@ -18171,7 +18524,20 @@ function TraceDialog({
18171
18524
  isLoading: isLoadingSpans,
18172
18525
  className: "pr-[2.5rem] pt-[2.5rem]"
18173
18526
  }
18174
- )
18527
+ ),
18528
+ traceDetails?.links?.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pt-[2.5rem] pr-[2.5rem]", children: [
18529
+ /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeading, { as: "h2", className: "pb-[1rem]", children: [
18530
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.GaugeIcon, {}),
18531
+ " Scores"
18532
+ ] }),
18533
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface2 rounded-lg overflow-hidden border-sm border-border1", children: /* @__PURE__ */ jsxRuntime.jsx(
18534
+ ScoreTable,
18535
+ {
18536
+ scores: traceDetails?.links,
18537
+ onItemClick: (scorerName) => onScorerTriggered(scorerName, traceDetails.traceId, selectedSpanId)
18538
+ }
18539
+ ) })
18540
+ ] })
18175
18541
  ] }),
18176
18542
  selectedSpan && combinedView && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-y-auto grid grid-rows-[auto_1fr] relative", children: [
18177
18543
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 right-[2.5rem] h-[.5rem] bg-surface1 rounded-full top-0" }),
@@ -18202,11 +18568,11 @@ function TraceDialog({
18202
18568
  ] }),
18203
18569
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[20rem_1fr] gap-[1rem] overflow-y-auto", children: [
18204
18570
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-y-auto grid content-start p-[1.5rem] pl-0 gap-[2rem]", children: [
18205
- /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeading, { as: "h2", children: [
18571
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeading, { as: "h2", children: [
18206
18572
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsLeftRightEllipsisIcon, {}),
18207
18573
  " ",
18208
18574
  selectedSpan?.name
18209
- ] }),
18575
+ ] }) }),
18210
18576
  selectedSpan?.attributes?.usage && /* @__PURE__ */ jsxRuntime.jsx(
18211
18577
  TraceSpanUsage,
18212
18578
  {
@@ -18216,7 +18582,7 @@ function TraceDialog({
18216
18582
  ),
18217
18583
  /* @__PURE__ */ jsxRuntime.jsx(KeyValueList, { data: selectedSpanInfo, LinkComponent: Link })
18218
18584
  ] }),
18219
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-y-auto pr-[2.5rem] pt-[2rem]", children: /* @__PURE__ */ jsxRuntime.jsx(SpanDetails, { span: selectedSpan }) })
18585
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-y-auto pr-[2.5rem] pt-[2rem]", children: /* @__PURE__ */ jsxRuntime.jsx(SpanDetails, { span: selectedSpan, onScorerTriggered }) })
18220
18586
  ] })
18221
18587
  ] })
18222
18588
  ]
@@ -18225,16 +18591,21 @@ function TraceDialog({
18225
18591
  ]
18226
18592
  }
18227
18593
  ),
18228
- /* @__PURE__ */ jsxRuntime.jsx(
18594
+ traceDetails && /* @__PURE__ */ jsxRuntime.jsx(
18229
18595
  SpanDialog,
18230
18596
  {
18597
+ trace: traceDetails,
18231
18598
  span: selectedSpan,
18232
18599
  isOpen: Boolean(dialogIsOpen && selectedSpanId && !combinedView),
18233
- onClose: () => setDialogIsOpen(false),
18600
+ onClose: () => {
18601
+ setDialogIsOpen(false);
18602
+ setSelectedSpanId(void 0);
18603
+ },
18234
18604
  onNext: thereIsNextSpan() ? toNextSpan : void 0,
18235
18605
  onPrevious: thereIsPreviousSpan() ? toPreviousSpan : void 0,
18236
18606
  onViewToggle: () => setCombinedView(!combinedView),
18237
- spanInfo: selectedSpanInfo
18607
+ spanInfo: selectedSpanInfo,
18608
+ onScorerTriggered
18238
18609
  }
18239
18610
  )
18240
18611
  ] });