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

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.es.js CHANGED
@@ -22,7 +22,7 @@ import * as DialogPrimitive from '@radix-ui/react-dialog';
22
22
  import { useDebouncedCallback } from 'use-debounce';
23
23
  import { create } from 'zustand';
24
24
  import { persist } from 'zustand/middleware';
25
- import { useQuery, QueryClient, QueryClientProvider } from '@tanstack/react-query';
25
+ import { useQuery, useMutation, QueryClient, QueryClientProvider } from '@tanstack/react-query';
26
26
  import './index.css';export * from '@tanstack/react-query';
27
27
  import { MarkerType, Handle, Position, useNodesState, useEdgesState, ReactFlow, Controls, Background, BackgroundVariant, ReactFlowProvider, useViewport, useReactFlow, Panel } from '@xyflow/react';
28
28
  import '@xyflow/react/dist/style.css';
@@ -63,6 +63,7 @@ import * as HoverCard from '@radix-ui/react-hover-card';
63
63
  import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
64
64
  import { RuntimeContext as RuntimeContext$2 } from '@mastra/core/runtime-context';
65
65
  import { format as format$1 } from 'date-fns/format';
66
+ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
66
67
 
67
68
  const createMastraClient = (baseUrl, mastraClientHeaders = {}) => {
68
69
  return new MastraClient({
@@ -4518,16 +4519,16 @@ const usePlaygroundStore = create()(
4518
4519
  )
4519
4520
  );
4520
4521
 
4521
- const useWorkflow = (workflowId, enabled = true) => {
4522
+ const useWorkflow = (workflowId) => {
4522
4523
  const client = useMastraClient();
4523
4524
  const { runtimeContext } = usePlaygroundStore();
4524
4525
  return useQuery({
4525
4526
  queryKey: ["workflow", workflowId],
4526
- queryFn: () => client.getWorkflow(workflowId).details(runtimeContext),
4527
+ queryFn: () => workflowId ? client.getWorkflow(workflowId).details(runtimeContext) : null,
4528
+ enabled: Boolean(workflowId),
4527
4529
  retry: false,
4528
4530
  refetchOnWindowFocus: false,
4529
- throwOnError: false,
4530
- enabled
4531
+ throwOnError: false
4531
4532
  });
4532
4533
  };
4533
4534
  const useLegacyWorkflow = (workflowId) => {
@@ -8258,7 +8259,7 @@ const Row = forwardRef(
8258
8259
  "tr",
8259
8260
  {
8260
8261
  className: clsx(
8261
- "border-b-sm border-border1 hover:bg-surface3 focus:bg-surface3 -outline-offset-2",
8262
+ "border-b-sm border-border1 hover:bg-surface3 focus:bg-surface3 -outline-offset-2 last:border-b-0",
8262
8263
  selected && "bg-surface4",
8263
8264
  onClick && "cursor-pointer",
8264
8265
  className
@@ -12913,13 +12914,13 @@ function KeyValueList({ data, LinkComponent, className, labelsAreHidden, isLoadi
12913
12914
  style: { width: `${Math.floor(Math.random() * (90 - 30 + 1)) + 50}%` },
12914
12915
  children: " "
12915
12916
  }
12916
- ) : /* @__PURE__ */ jsx(Fragment, { children: isValueItemArray ? value?.map((item) => {
12917
+ ) : isValueItemArray ? value?.map((item) => {
12917
12918
  return item.path ? /* @__PURE__ */ jsx(RelationWrapper, { description: item.description, children: /* @__PURE__ */ jsxs(Link, { href: item.path, children: [
12918
12919
  item?.name,
12919
12920
  " ",
12920
12921
  /* @__PURE__ */ jsx(ChevronRightIcon, {})
12921
12922
  ] }) }, item.id) : /* @__PURE__ */ jsx("span", { children: item?.name }, item.id);
12922
- }) : /* @__PURE__ */ jsx(Fragment, { children: value ? value : /* @__PURE__ */ jsx("span", { className: "text-icon3 text-[0.75rem]", children: "n/a" }) }) })
12923
+ }) : /* @__PURE__ */ jsx(Fragment, { children: value ? value : /* @__PURE__ */ jsx("span", { className: "text-icon3 text-[0.75rem]", children: "n/a" }) })
12923
12924
  }
12924
12925
  )
12925
12926
  ] }, label + index);
@@ -13615,7 +13616,7 @@ const DateTimePicker = ({
13615
13616
  /* @__PURE__ */ jsx(
13616
13617
  PopoverContent,
13617
13618
  {
13618
- className: "backdrop-blur-4xl w-auto p-0 bg-surface4 max-w-[16.5rem]",
13619
+ className: "backdrop-blur-4xl w-auto !p-0 bg-surface4 max-w-[16.5rem]",
13619
13620
  align: "start",
13620
13621
  "data-testid": "datepicker-calendar",
13621
13622
  children: /* @__PURE__ */ jsx(
@@ -13741,7 +13742,7 @@ const DateTimePickerContent = ({
13741
13742
  "div",
13742
13743
  {
13743
13744
  "aria-label": "Choose date",
13744
- className: cn("relative mt-2 flex flex-col ", className),
13745
+ className: cn("relative flex flex-col", className),
13745
13746
  onKeyDown: (e) => {
13746
13747
  e.stopPropagation();
13747
13748
  if (e.key === "Escape") {
@@ -13838,7 +13839,16 @@ function getShortId(id) {
13838
13839
  return id.slice(0, 8);
13839
13840
  }
13840
13841
 
13841
- function ScoreDialog({ scorer, score, isOpen, onClose, onNext, onPrevious }) {
13842
+ function ScoreDialog({
13843
+ scorer,
13844
+ score,
13845
+ isOpen,
13846
+ onClose,
13847
+ onNext,
13848
+ onPrevious,
13849
+ computeTraceLink
13850
+ }) {
13851
+ const { Link } = useLinkComponent();
13842
13852
  return /* @__PURE__ */ jsxs(
13843
13853
  SideDialog,
13844
13854
  {
@@ -13861,10 +13871,30 @@ function ScoreDialog({ scorer, score, isOpen, onClose, onNext, onPrevious }) {
13861
13871
  ] })
13862
13872
  ] }) }),
13863
13873
  /* @__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: [
13874
+ score?.traceId && /* @__PURE__ */ jsx(
13875
+ KeyValueList,
13876
+ {
13877
+ data: [
13878
+ {
13879
+ label: "Trace ID",
13880
+ value: /* @__PURE__ */ jsx(Link, { href: computeTraceLink(score?.traceId), children: score?.traceId }),
13881
+ key: "traceId"
13882
+ },
13883
+ ...score?.spanId ? [
13884
+ {
13885
+ label: "Span ID",
13886
+ value: /* @__PURE__ */ jsx(Link, { href: computeTraceLink(score?.traceId, score?.spanId), children: score?.spanId }),
13887
+ key: "spanId"
13888
+ }
13889
+ ] : []
13890
+ ],
13891
+ LinkComponent: Link
13892
+ }
13893
+ ),
13864
13894
  /* @__PURE__ */ jsx(
13865
13895
  SideDialogCodeSection,
13866
13896
  {
13867
- title: `Score: ${score?.score ? score?.score : "n/a"}`,
13897
+ title: `Score: ${Number.isNaN(score?.score) ? "n/a" : score?.score}`,
13868
13898
  codeStr: score?.reason,
13869
13899
  simplified: true
13870
13900
  }
@@ -13956,29 +13986,11 @@ const useScoresByEntityId = (entityId, entityType, page = 0) => {
13956
13986
  };
13957
13987
  const useScoresByScorerId = ({ scorerId, page = 0, entityId, entityType }) => {
13958
13988
  const client = useMastraClient();
13959
- const [scores, setScores] = useState(null);
13960
- const [isLoading, setIsLoading] = useState(true);
13961
- useEffect(() => {
13962
- const fetchScores = async () => {
13963
- setIsLoading(true);
13964
- try {
13965
- const res = await client.getScoresByScorerId({
13966
- scorerId,
13967
- page: page || 0,
13968
- entityId: entityId || void 0,
13969
- entityType: entityType || void 0,
13970
- perPage: 10
13971
- });
13972
- setScores(res);
13973
- setIsLoading(false);
13974
- } catch (error) {
13975
- setScores(null);
13976
- setIsLoading(false);
13977
- }
13978
- };
13979
- fetchScores();
13980
- }, [scorerId, page, entityId, entityType]);
13981
- return { scores, isLoading };
13989
+ return useQuery({
13990
+ queryKey: ["scores", scorerId, page, entityId, entityType],
13991
+ queryFn: () => client.getScoresByScorerId({ scorerId, page, entityId, entityType, perPage: 10 }),
13992
+ refetchInterval: 5e3
13993
+ });
13982
13994
  };
13983
13995
  const useScorer = (scorerId) => {
13984
13996
  const client = useMastraClient();
@@ -14004,25 +14016,12 @@ const useScorer = (scorerId) => {
14004
14016
  };
14005
14017
  const useScorers = () => {
14006
14018
  const client = useMastraClient();
14007
- const [scorers, setScorers] = useState({});
14008
- const [isLoading, setIsLoading] = useState(true);
14009
- useEffect(() => {
14010
- const fetchScorers = async () => {
14011
- setIsLoading(true);
14012
- try {
14013
- const res = await client.getScorers();
14014
- setScorers(res);
14015
- } catch (error) {
14016
- setScorers({});
14017
- console.error("Error fetching agents", error);
14018
- toast.error("Error fetching agents");
14019
- } finally {
14020
- setIsLoading(false);
14021
- }
14022
- };
14023
- fetchScorers();
14024
- }, []);
14025
- return { scorers, isLoading };
14019
+ return useQuery({
14020
+ queryKey: ["scorers"],
14021
+ queryFn: () => client.getScorers(),
14022
+ staleTime: 0,
14023
+ gcTime: 0
14024
+ });
14026
14025
  };
14027
14026
 
14028
14027
  const NameCell = ({ row }) => {
@@ -14269,7 +14268,9 @@ const AgentMetadataModelSwitcher = ({
14269
14268
  defaultModel,
14270
14269
  updateModel,
14271
14270
  closeEditor,
14272
- modelProviders
14271
+ modelProviders,
14272
+ autoSave = false,
14273
+ selectProviderPlaceholder = "Select provider"
14273
14274
  }) => {
14274
14275
  const [selectedModel, setSelectedModel] = useState(defaultModel);
14275
14276
  const [showSuggestions, setShowSuggestions] = useState(false);
@@ -14281,10 +14282,19 @@ const AgentMetadataModelSwitcher = ({
14281
14282
  return "";
14282
14283
  });
14283
14284
  const [loading, setLoading] = useState(false);
14285
+ const [infoMsg, setInfoMsg] = useState("");
14284
14286
  const modelsList = Object.entries(Models).filter(([provider]) => modelProviders.includes(provider));
14285
14287
  const allModels = modelsList.flatMap(([_, { models }]) => models);
14286
14288
  const providersList = modelsList.map(([provider, { icon }]) => ({ provider, icon }));
14287
14289
  const model = allModels.find((model2) => model2.model === selectedModel);
14290
+ useEffect(() => {
14291
+ const isValidModel = allModels.some((model2) => model2.model === selectedModel);
14292
+ if (selectedModel && !isValidModel) {
14293
+ setInfoMsg("Model not in suggestions—make sure the name is correct.");
14294
+ } else {
14295
+ setInfoMsg("");
14296
+ }
14297
+ }, [selectedModel, allModels]);
14288
14298
  const handleSave = async () => {
14289
14299
  setLoading(true);
14290
14300
  const providerToUse = model?.provider ?? selectedProvider;
@@ -14292,67 +14302,156 @@ const AgentMetadataModelSwitcher = ({
14292
14302
  setLoading(false);
14293
14303
  closeEditor();
14294
14304
  };
14295
- const filteredModels = allModels.filter((model2) => model2.model.includes(selectedModel));
14296
- return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
14305
+ const filteredModels = allModels.filter((model2) => {
14306
+ if (selectedProvider) {
14307
+ return model2.model.includes(selectedModel) && model2.provider === selectedProvider;
14308
+ }
14309
+ return model2.model.includes(selectedModel);
14310
+ });
14311
+ const handleProviderChange = (provider) => {
14312
+ setSelectedProvider(provider);
14313
+ setSelectedModel("");
14314
+ if (autoSave) {
14315
+ updateModel({
14316
+ provider,
14317
+ modelId: ""
14318
+ });
14319
+ }
14320
+ };
14321
+ const handleModelInputBlur = (e) => {
14322
+ setShowSuggestions(false);
14323
+ const isValidModel = allModels.some((model2) => model2.model === e.target.value);
14324
+ if (!isValidModel) {
14325
+ if (autoSave) {
14326
+ updateModel({
14327
+ provider: selectedProvider,
14328
+ modelId: e.target.value
14329
+ });
14330
+ }
14331
+ }
14332
+ };
14333
+ const handleModelClick = (model2) => {
14334
+ setSelectedModel(model2.model);
14335
+ const isValidModel = allModels.some((m) => m.model === model2.model);
14336
+ if (isValidModel) {
14337
+ setSelectedProvider(model2.provider);
14338
+ }
14339
+ if (autoSave) {
14340
+ updateModel({
14341
+ provider: model2.provider,
14342
+ modelId: model2.model
14343
+ });
14344
+ }
14345
+ setShowSuggestions(false);
14346
+ };
14347
+ const handleModelInputChange = (e) => {
14348
+ setSelectedModel(e.target.value);
14349
+ const isValidModel = allModels.some((m) => m.model === e.target.value);
14350
+ if (isValidModel) {
14351
+ const model2 = allModels.find((m) => m.model === e.target.value);
14352
+ if (model2) {
14353
+ setSelectedProvider(model2.provider);
14354
+ }
14355
+ }
14356
+ };
14357
+ const handleModelReset = () => {
14358
+ setSelectedModel("");
14359
+ setInfoMsg("");
14360
+ if (autoSave) {
14361
+ updateModel({
14362
+ provider: selectedProvider,
14363
+ modelId: ""
14364
+ });
14365
+ }
14366
+ };
14367
+ return /* @__PURE__ */ jsxs("div", { children: [
14297
14368
  /* @__PURE__ */ jsxs(
14298
- Select$1,
14369
+ "div",
14299
14370
  {
14300
- value: model?.provider ?? selectedProvider,
14301
- onValueChange: setSelectedProvider,
14302
- disabled: !!model?.provider,
14371
+ className: cn("grid items-center gap-2", {
14372
+ "xl:grid-cols-[auto_1fr_auto]": !autoSave,
14373
+ "xl:grid-cols-[auto_1fr]": autoSave
14374
+ }),
14303
14375
  children: [
14304
- /* @__PURE__ */ jsx(SelectTrigger, { className: "max-w-[150px]", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select provider" }) }),
14305
- /* @__PURE__ */ jsx(SelectContent, { children: providersList.map((provider) => /* @__PURE__ */ jsx(SelectItem, { value: provider.provider, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
14306
- /* @__PURE__ */ jsx(Icon, { children: providerMapToIcon[provider.icon] }),
14307
- provider.provider
14308
- ] }) }, provider.provider)) })
14376
+ /* @__PURE__ */ jsxs(Select$1, { value: selectedProvider, onValueChange: handleProviderChange, disabled: !!model?.provider, children: [
14377
+ /* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, { placeholder: selectProviderPlaceholder }) }),
14378
+ /* @__PURE__ */ jsx(SelectContent, { children: providersList.map((provider) => /* @__PURE__ */ jsx(SelectItem, { value: provider.provider, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
14379
+ /* @__PURE__ */ jsx(Icon, { children: providerMapToIcon[provider.icon] }),
14380
+ provider.provider
14381
+ ] }) }, provider.provider)) })
14382
+ ] }),
14383
+ /* @__PURE__ */ jsxs(Popover, { open: showSuggestions, children: [
14384
+ /* @__PURE__ */ jsxs("div", { className: "relative", children: [
14385
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
14386
+ Input,
14387
+ {
14388
+ id: "model-input",
14389
+ list: "model-suggestions",
14390
+ className: "flex-1 w-full h-[2.25rem] rounded-md min-w-[12rem]",
14391
+ type: "text",
14392
+ value: selectedModel,
14393
+ onChange: handleModelInputChange,
14394
+ onFocus: () => setShowSuggestions(true),
14395
+ onBlur: handleModelInputBlur,
14396
+ placeholder: "Enter model name or select from suggestions...",
14397
+ autoComplete: "off"
14398
+ }
14399
+ ) }),
14400
+ selectedModel && /* @__PURE__ */ jsx(
14401
+ "button",
14402
+ {
14403
+ 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",
14404
+ onClick: handleModelReset,
14405
+ children: /* @__PURE__ */ jsx(XIcon, {})
14406
+ }
14407
+ )
14408
+ ] }),
14409
+ filteredModels.length > 0 && /* @__PURE__ */ jsx(
14410
+ PopoverContent,
14411
+ {
14412
+ onOpenAutoFocus: (e) => e.preventDefault(),
14413
+ className: "flex flex-col w-[var(--radix-popover-trigger-width)] max-h-[calc(var(--radix-popover-content-available-height)-50px)] overflow-y-auto",
14414
+ children: filteredModels.map((model2) => /* @__PURE__ */ jsx(
14415
+ "button",
14416
+ {
14417
+ className: "flex items-center justify-start gap-2 cursor-pointer hover:bg-surface5 p-2 text-[0.875rem]",
14418
+ onClick: () => handleModelClick(model2),
14419
+ children: model2.model
14420
+ },
14421
+ model2.provider + model2.model
14422
+ ))
14423
+ }
14424
+ )
14425
+ ] }),
14426
+ !autoSave && /* @__PURE__ */ jsx(
14427
+ Button$2,
14428
+ {
14429
+ onClick: handleSave,
14430
+ variant: "secondary",
14431
+ size: "sm",
14432
+ disabled: loading || !selectedModel,
14433
+ className: "w-full",
14434
+ children: loading ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Spinner, {}) }) : "Save"
14435
+ }
14436
+ )
14309
14437
  ]
14310
14438
  }
14311
14439
  ),
14312
- /* @__PURE__ */ jsxs(Popover, { open: showSuggestions, children: [
14313
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
14314
- Input,
14315
- {
14316
- id: "model-input",
14317
- list: "model-suggestions",
14318
- className: "flex-1",
14319
- type: "text",
14320
- value: selectedModel,
14321
- onChange: (e) => {
14322
- setSelectedModel(e.target.value);
14323
- setShowSuggestions(true);
14324
- },
14325
- placeholder: "Enter model name or select from suggestions..."
14326
- }
14327
- ) }),
14328
- filteredModels.length > 0 && /* @__PURE__ */ jsx(
14329
- PopoverContent,
14330
- {
14331
- onOpenAutoFocus: (e) => e.preventDefault(),
14332
- 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",
14333
- children: filteredModels.map((model2) => /* @__PURE__ */ jsxs(
14334
- "div",
14335
- {
14336
- className: "flex items-center gap-2 cursor-pointer hover:bg-surface5 p-2",
14337
- onClick: () => {
14338
- setSelectedModel(model2.model);
14339
- setShowSuggestions(false);
14340
- },
14341
- children: [
14342
- /* @__PURE__ */ jsx(Icon, { children: providerMapToIcon[model2.icon] }),
14343
- model2.model
14344
- ]
14345
- },
14346
- model2.provider + model2.model
14347
- ))
14348
- }
14349
- )
14350
- ] }),
14351
- /* @__PURE__ */ jsxs(Tooltip, { children: [
14352
- /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx("button", { onClick: handleSave, className: "text-icon3 hover:text-icon6", children: /* @__PURE__ */ jsx(Icon, { children: loading ? /* @__PURE__ */ jsx(Spinner, {}) : /* @__PURE__ */ jsx(CircleCheck, {}) }) }) }),
14353
- /* @__PURE__ */ jsx(TooltipContent, { children: loading ? "Saving..." : "Save new model" })
14354
- ] })
14355
- ] }) });
14440
+ infoMsg && /* @__PURE__ */ jsxs(
14441
+ "div",
14442
+ {
14443
+ className: cn(
14444
+ "text-[0.75rem] text-icon3 flex gap-[.5rem] mt-[0.5rem] ml-[.5rem]",
14445
+ "[&>svg]:w-[1.1em] [&>svg]:h-[1.1em] [&>svg]:opacity-7 [&>svg]:flex-shrink-0 [&>svg]:mt-[0.1rem]"
14446
+ ),
14447
+ children: [
14448
+ /* @__PURE__ */ jsx(InfoIcon$1, {}),
14449
+ " ",
14450
+ infoMsg
14451
+ ]
14452
+ }
14453
+ )
14454
+ ] });
14356
14455
  };
14357
14456
 
14358
14457
  const AgentMetadataNetworkList = ({ agents }) => {
@@ -14465,11 +14564,11 @@ const AgentMetadataWorkflowList = ({ workflows }) => {
14465
14564
  };
14466
14565
  const AgentMetadataScorerList = ({ entityId, entityType }) => {
14467
14566
  const { Link, paths } = useLinkComponent();
14468
- const { scorers, isLoading } = useScorers();
14567
+ const { data: scorers = {}, isLoading } = useScorers();
14469
14568
  const scorerList = Object.keys(scorers).filter((scorerKey) => {
14470
14569
  const scorer = scorers[scorerKey];
14471
14570
  if (entityType === "AGENT") {
14472
- return scorer.agentIds.includes(entityId);
14571
+ return scorer.agentNames.includes(entityId);
14473
14572
  }
14474
14573
  return scorer.workflowIds.includes(entityId);
14475
14574
  }).map((scorerKey) => ({ ...scorers[scorerKey], id: scorerKey }));
@@ -15882,10 +15981,11 @@ const ToolListInner = ({ toolsWithAgents }) => {
15882
15981
  const ToolEntity = ({ tool }) => {
15883
15982
  const linkRef = useRef(null);
15884
15983
  const { Link, paths } = useLinkComponent();
15984
+ const toolLink = tool.agents.length > 0 ? paths.agentToolLink(tool.agents[0].id, tool.id) : paths.toolLink(tool.id);
15885
15985
  return /* @__PURE__ */ jsxs(Entity, { onClick: () => linkRef.current?.click(), children: [
15886
15986
  /* @__PURE__ */ jsx(EntityIcon, { children: /* @__PURE__ */ jsx(ToolsIcon, { className: "group-hover/entity:text-[#ECB047]" }) }),
15887
15987
  /* @__PURE__ */ jsxs(EntityContent, { children: [
15888
- /* @__PURE__ */ jsx(EntityName, { children: /* @__PURE__ */ jsx(Link, { ref: linkRef, href: paths.toolLink(tool.id), children: tool.id }) }),
15988
+ /* @__PURE__ */ jsx(EntityName, { children: /* @__PURE__ */ jsx(Link, { ref: linkRef, href: toolLink, children: tool.id }) }),
15889
15989
  /* @__PURE__ */ jsx(EntityDescription, { children: tool.description }),
15890
15990
  /* @__PURE__ */ jsx("div", { className: "inline-flex flex-wrap gap-2 pt-4", children: tool.agents.map((agent) => {
15891
15991
  return /* @__PURE__ */ jsx(
@@ -16258,7 +16358,7 @@ function TemplateForm({
16258
16358
  "h2",
16259
16359
  {
16260
16360
  className: cn(
16261
- "text-icon5 text-[1.125rem] font-semibold flex items-center gap-[0.5rem]",
16361
+ "text-icon4 text-[1.125rem] font-semibold flex items-center gap-[0.5rem]",
16262
16362
  "[&>svg]:w-[1.2em] [&_svg]:h-[1.2em] [&_svg]:opacity-70 "
16263
16363
  ),
16264
16364
  children: [
@@ -16271,29 +16371,13 @@ function TemplateForm({
16271
16371
  SelectField,
16272
16372
  {
16273
16373
  options: providerOptions,
16274
- label: "Provider",
16374
+ label: "Template AI Model Provider",
16275
16375
  onValueChange: onProviderChange,
16276
16376
  value: selectedProvider,
16277
- placeholder: "Select a provider"
16377
+ placeholder: "Select"
16278
16378
  }
16279
16379
  ),
16280
16380
  selectedProvider && Object.entries(variables || {}).length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
16281
- /* @__PURE__ */ jsxs("div", { className: "space-y-[0.5rem]", children: [
16282
- /* @__PURE__ */ jsx("h3", { className: "text-icon3 text-[0.875rem] font-medium", children: "Select AI Model for Template Installation *" }),
16283
- /* @__PURE__ */ jsx("p", { className: "text-icon4 text-[0.75rem]", children: "This model will be used by the workflow to process and install the template" }),
16284
- /* @__PURE__ */ jsx(
16285
- AgentMetadataModelSwitcher,
16286
- {
16287
- defaultProvider: defaultModelProvider || "",
16288
- defaultModel: defaultModelId || "",
16289
- updateModel: onModelUpdate || (() => Promise.resolve({ message: "Updated" })),
16290
- closeEditor: () => {
16291
- },
16292
- modelProviders: ["openai", "anthropic", "google", "xai", "groq"]
16293
- }
16294
- ),
16295
- (!defaultModelProvider || !defaultModelId) && /* @__PURE__ */ jsx("p", { className: "text-red-500 text-[0.75rem]", children: "Please select an AI model to continue" })
16296
- ] }),
16297
16381
  /* @__PURE__ */ jsx("h3", { className: "text-icon3 text-[0.875rem]", children: "Set required Environmental Variables" }),
16298
16382
  /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[1fr_1fr] gap-[1rem] items-start", children: isLoadingEnvVars ? /* @__PURE__ */ jsxs(
16299
16383
  "div",
@@ -16333,13 +16417,31 @@ function TemplateForm({
16333
16417
  className: "w-full"
16334
16418
  }
16335
16419
  )
16336
- ] }, key)) })
16420
+ ] }, key)) }),
16421
+ /* @__PURE__ */ jsxs("div", { className: "border-t border-border1 pt-[3rem] mt-[0.875rem] relative", children: [
16422
+ /* @__PURE__ */ 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" }),
16423
+ /* @__PURE__ */ jsx("h3", { className: "text-icon4 text-[1rem]", children: "Set AI Model for Template Installation" }),
16424
+ /* @__PURE__ */ 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" }),
16425
+ /* @__PURE__ */ jsx(
16426
+ AgentMetadataModelSwitcher,
16427
+ {
16428
+ defaultProvider: defaultModelProvider || "",
16429
+ defaultModel: defaultModelId || "",
16430
+ updateModel: onModelUpdate || (() => Promise.resolve({ message: "Updated" })),
16431
+ closeEditor: () => {
16432
+ },
16433
+ modelProviders: ["openai", "anthropic", "google", "xai", "groq"],
16434
+ autoSave: true,
16435
+ selectProviderPlaceholder: "Provider"
16436
+ }
16437
+ )
16438
+ ] })
16337
16439
  ] }),
16338
16440
  selectedProvider && !isLoadingEnvVars && /* @__PURE__ */ jsxs(
16339
- "button",
16441
+ Button,
16340
16442
  {
16341
16443
  className: cn(
16342
- "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",
16444
+ "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",
16343
16445
  "[&>svg]:w-[1.1em] [&_svg]:h-[1.1em] [&_svg]:text-icon5"
16344
16446
  ),
16345
16447
  onClick: handleInstallTemplate,
@@ -16578,7 +16680,7 @@ function TemplateFailure({ errorMsg, validationErrors }) {
16578
16680
  };
16579
16681
  };
16580
16682
  const { icon, title } = getIconAndTitle();
16581
- return /* @__PURE__ */ jsxs(Container, { className: "space-y-4 text-icon3 mb-[2rem] content-center max-w-2xl mx-auto", children: [
16683
+ return /* @__PURE__ */ jsxs(Container, { className: "space-y-4 text-icon3 mb-[2rem] content-center", children: [
16582
16684
  /* @__PURE__ */ jsxs(
16583
16685
  "div",
16584
16686
  {
@@ -17676,10 +17778,14 @@ function TraceTimeline({
17676
17778
  ) : /* @__PURE__ */ jsx(
17677
17779
  "div",
17678
17780
  {
17679
- className: cn("grid items-start content-start gap-y-[2px]", "xl:gap-x-[1rem] xl:py-[1rem]", {
17680
- "xl:grid-cols-[3fr_auto]": !overallEndTime,
17681
- "xl:grid-cols-[3fr_2fr]": overallEndTime
17682
- }),
17781
+ className: cn(
17782
+ "grid items-start content-start gap-y-[2px] bg-surface2 rounded-lg overflow-hidden pl-[1.5rem] py-[1.5rem]",
17783
+ "xl:gap-x-[1rem] xl:py-[1rem]",
17784
+ {
17785
+ "xl:grid-cols-[3fr_auto]": !overallEndTime,
17786
+ "xl:grid-cols-[3fr_2fr]": overallEndTime
17787
+ }
17788
+ ),
17683
17789
  children: hierarchicalSpans?.map((span) => /* @__PURE__ */ jsx(
17684
17790
  TraceTimelineSpan,
17685
17791
  {
@@ -17953,7 +18059,24 @@ function getSpanInfo({ span, withTraceId = true, withSpanId = true }) {
17953
18059
  return baseInfo;
17954
18060
  }
17955
18061
 
17956
- function SpanDetails({ span }) {
18062
+ const ScoreTable = ({ scores, onItemClick }) => {
18063
+ return /* @__PURE__ */ jsxs(Table$1, { children: [
18064
+ /* @__PURE__ */ jsxs(Thead, { children: [
18065
+ /* @__PURE__ */ jsx(Th, { children: "Type" }),
18066
+ /* @__PURE__ */ jsx(Th, { children: "Scorer" }),
18067
+ /* @__PURE__ */ jsx(Th, { children: "Score" }),
18068
+ /* @__PURE__ */ jsx(Th, { children: "Created At" })
18069
+ ] }),
18070
+ /* @__PURE__ */ jsx(Tbody, { children: scores.map((score) => /* @__PURE__ */ jsxs(Row, { onClick: () => onItemClick(score.scorerName), children: [
18071
+ /* @__PURE__ */ jsx(TxtCell, { children: /* @__PURE__ */ jsx(Badge$1, { children: score.type }) }),
18072
+ /* @__PURE__ */ jsx(TxtCell, { children: score.scorerName }),
18073
+ /* @__PURE__ */ jsx(TxtCell, { children: score.score }),
18074
+ /* @__PURE__ */ jsx(DateTimeCell, { dateTime: new Date(score.createdAt) })
18075
+ ] }, score.scoreId)) })
18076
+ ] });
18077
+ };
18078
+
18079
+ function SpanDetails({ span, onScorerTriggered }) {
17957
18080
  if (!span) {
17958
18081
  return null;
17959
18082
  }
@@ -17961,18 +18084,226 @@ function SpanDetails({ span }) {
17961
18084
  /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Input", codeStr: JSON.stringify(span.input || null, null, 2) }),
17962
18085
  /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Output", codeStr: JSON.stringify(span.output || null, null, 2) }),
17963
18086
  /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Metadata", codeStr: JSON.stringify(span.metadata || null, null, 2) }),
17964
- /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Attributes", codeStr: JSON.stringify(span.attributes || null, null, 2) })
18087
+ /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Attributes", codeStr: JSON.stringify(span.attributes || null, null, 2) }),
18088
+ span?.links?.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-[2.5rem] pr-[2.5rem]", children: [
18089
+ /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", className: "pb-[1rem]", children: [
18090
+ /* @__PURE__ */ jsx(GaugeIcon, {}),
18091
+ " Scores"
18092
+ ] }),
18093
+ /* @__PURE__ */ jsx("div", { className: "bg-surface2 rounded-lg overflow-hidden border-sm border-border1", children: /* @__PURE__ */ jsx(
18094
+ ScoreTable,
18095
+ {
18096
+ scores: span?.links,
18097
+ onItemClick: (scorerName) => onScorerTriggered(scorerName, span.traceId, span.spanId)
18098
+ }
18099
+ ) })
18100
+ ] })
17965
18101
  ] });
17966
18102
  }
17967
18103
 
18104
+ const DropdownMenu = DropdownMenuPrimitive.Root;
18105
+ const DropdownMenuGroup = DropdownMenuPrimitive.Group;
18106
+ const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
18107
+ const DropdownMenuSub = DropdownMenuPrimitive.Sub;
18108
+ const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
18109
+ const DropdownMenuTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Trigger, { ref, className: cn("cursor-pointer focus-visible:rounded", className), ...props, children }));
18110
+ DropdownMenuTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName;
18111
+ const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
18112
+ DropdownMenuPrimitive.SubTrigger,
18113
+ {
18114
+ ref,
18115
+ className: cn(
18116
+ "focus:bg-accent data-[state=open]:bg-accent flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm",
18117
+ inset && "pl-8",
18118
+ className
18119
+ ),
18120
+ ...props,
18121
+ children: [
18122
+ children,
18123
+ /* @__PURE__ */ jsx(ChevronDown, { className: "ml-auto -rotate-90" })
18124
+ ]
18125
+ }
18126
+ ));
18127
+ DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
18128
+ const DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
18129
+ DropdownMenuPrimitive.SubContent,
18130
+ {
18131
+ ref,
18132
+ className: cn(
18133
+ "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",
18134
+ className
18135
+ ),
18136
+ ...props
18137
+ }
18138
+ ));
18139
+ DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
18140
+ const DropdownMenuContent = React.forwardRef(({ className, container, sideOffset = 4, ...props }, ref) => {
18141
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { container, children: /* @__PURE__ */ jsx(
18142
+ DropdownMenuPrimitive.Content,
18143
+ {
18144
+ ref,
18145
+ sideOffset,
18146
+ className: clsx(
18147
+ "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",
18148
+ className
18149
+ ),
18150
+ ...props
18151
+ }
18152
+ ) });
18153
+ });
18154
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
18155
+ const DropdownMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
18156
+ DropdownMenuPrimitive.Item,
18157
+ {
18158
+ ref,
18159
+ className: cn(
18160
+ "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",
18161
+ inset && "pl-8",
18162
+ className
18163
+ ),
18164
+ ...props
18165
+ }
18166
+ ));
18167
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
18168
+ const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
18169
+ DropdownMenuPrimitive.CheckboxItem,
18170
+ {
18171
+ ref,
18172
+ className: cn(
18173
+ "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",
18174
+ className
18175
+ ),
18176
+ checked,
18177
+ ...props,
18178
+ children: [
18179
+ /* @__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, {}) }) }),
18180
+ children
18181
+ ]
18182
+ }
18183
+ ));
18184
+ DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
18185
+ const DropdownMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
18186
+ DropdownMenuPrimitive.RadioItem,
18187
+ {
18188
+ ref,
18189
+ className: cn(
18190
+ "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",
18191
+ className
18192
+ ),
18193
+ ...props,
18194
+ children: [
18195
+ /* @__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" }) }) }),
18196
+ children
18197
+ ]
18198
+ }
18199
+ ));
18200
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
18201
+ const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
18202
+ DropdownMenuPrimitive.Label,
18203
+ {
18204
+ ref,
18205
+ className: cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className),
18206
+ ...props
18207
+ }
18208
+ ));
18209
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
18210
+ const DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
18211
+ DropdownMenuPrimitive.Separator,
18212
+ {
18213
+ ref,
18214
+ className: cn("popover-dividers-bg -mx-1 my-1 h-px", className),
18215
+ ...props
18216
+ }
18217
+ ));
18218
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
18219
+ const DropdownMenuShortcut = ({ className, ...props }) => {
18220
+ return /* @__PURE__ */ jsx("span", { className: cn("ml-auto text-xs tracking-widest opacity-60", className), ...props });
18221
+ };
18222
+ DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
18223
+ function Dropdown({
18224
+ open,
18225
+ onOpenChange,
18226
+ children,
18227
+ modal
18228
+ }) {
18229
+ return /* @__PURE__ */ jsx(DropdownMenu, { modal, open, onOpenChange, children });
18230
+ }
18231
+ Dropdown.Trigger = DropdownMenuTrigger;
18232
+ Dropdown.Content = DropdownMenuContent;
18233
+ Dropdown.Group = DropdownMenuGroup;
18234
+ Dropdown.Portal = DropdownMenuPortal;
18235
+ Dropdown.Item = DropdownMenuItem;
18236
+ Dropdown.CheckboxItem = DropdownMenuCheckboxItem;
18237
+ Dropdown.RadioItem = DropdownMenuRadioItem;
18238
+ Dropdown.Label = DropdownMenuLabel;
18239
+ Dropdown.Separator = DropdownMenuSeparator;
18240
+ Dropdown.Shortcut = DropdownMenuShortcut;
18241
+ Dropdown.Sub = DropdownMenuSub;
18242
+ Dropdown.SubContent = DropdownMenuSubContent;
18243
+ Dropdown.SubTrigger = DropdownMenuSubTrigger;
18244
+ Dropdown.RadioGroup = DropdownMenuRadioGroup;
18245
+
18246
+ const useTriggerScorer = (onScorerTriggered) => {
18247
+ const client = useMastraClient();
18248
+ return useMutation({
18249
+ mutationFn: async ({ scorerName, traceId, spanId }) => {
18250
+ const response = await client.score({
18251
+ scorerName,
18252
+ targets: [{ traceId, spanId }]
18253
+ });
18254
+ return response;
18255
+ },
18256
+ onSuccess: (_, variables) => {
18257
+ toast.success("Scorer triggered successfully");
18258
+ onScorerTriggered(variables.scorerName, variables.traceId, variables.spanId);
18259
+ },
18260
+ onError: () => {
18261
+ toast.error("Error triggering scorer");
18262
+ }
18263
+ });
18264
+ };
18265
+
18266
+ const ScorersDropdown = ({ trace, spanId, onScorerTriggered, entityType }) => {
18267
+ const { data: scorers = {}, isLoading } = useScorers();
18268
+ const { mutate: triggerScorer, isPending } = useTriggerScorer(onScorerTriggered);
18269
+ let scorerList = Object.entries(scorers).map(([key, scorer]) => ({
18270
+ id: key,
18271
+ name: scorer.scorer.config.name,
18272
+ description: scorer.scorer.config.description,
18273
+ isRegistered: scorer.isRegistered,
18274
+ type: scorer.scorer.config.type
18275
+ })).filter((scorer) => scorer.isRegistered);
18276
+ if (entityType !== "Agent" || spanId) {
18277
+ scorerList = scorerList.filter((scorer) => scorer.type !== "agent");
18278
+ }
18279
+ const isWaiting = isPending || isLoading;
18280
+ return /* @__PURE__ */ jsxs(Dropdown, { children: [
18281
+ /* @__PURE__ */ jsx(Dropdown.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button$1, { variant: "light", disabled: isWaiting, children: [
18282
+ isWaiting ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Spinner, {}) }) : /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(GaugeIcon, {}) }),
18283
+ "Run scorer",
18284
+ /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronDown, {}) })
18285
+ ] }) }),
18286
+ /* @__PURE__ */ jsx(Dropdown.Content, { children: scorerList.map((scorer) => /* @__PURE__ */ jsx(
18287
+ Dropdown.Item,
18288
+ {
18289
+ onClick: () => triggerScorer({ scorerName: scorer.name, traceId: trace.traceId, spanId }),
18290
+ children: /* @__PURE__ */ jsx("span", { children: scorer.name })
18291
+ },
18292
+ scorer.id
18293
+ )) })
18294
+ ] });
18295
+ };
18296
+
17968
18297
  function SpanDialog({
18298
+ trace,
17969
18299
  span,
17970
18300
  isOpen,
17971
18301
  onClose,
17972
18302
  onNext,
17973
18303
  onPrevious,
17974
18304
  onViewToggle,
17975
- spanInfo = []
18305
+ spanInfo = [],
18306
+ onScorerTriggered
17976
18307
  }) {
17977
18308
  const { Link } = useLinkComponent();
17978
18309
  return /* @__PURE__ */ jsxs(
@@ -18001,21 +18332,24 @@ function SpanDialog({
18001
18332
  /* @__PURE__ */ jsx("button", { className: "flex items-center gap-1", onClick: onViewToggle, children: /* @__PURE__ */ jsx(PanelTopIcon, {}) })
18002
18333
  ] }),
18003
18334
  /* @__PURE__ */ jsxs("div", { className: "p-[1.5rem] px-[2.5rem] overflow-y-auto grid gap-[1.5rem] content-start", children: [
18004
- /* @__PURE__ */ jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
18005
- /* @__PURE__ */ jsxs(SideDialogHeading, { children: [
18006
- /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
18007
- " ",
18008
- span?.name
18335
+ /* @__PURE__ */ jsxs("div", { children: [
18336
+ /* @__PURE__ */ jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
18337
+ /* @__PURE__ */ jsxs(SideDialogHeading, { children: [
18338
+ /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
18339
+ " ",
18340
+ span?.name
18341
+ ] }),
18342
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
18343
+ /* @__PURE__ */ jsx(HashIcon, {}),
18344
+ " ",
18345
+ span?.spanId
18346
+ ] })
18009
18347
  ] }),
18010
- /* @__PURE__ */ jsxs(TextAndIcon, { children: [
18011
- /* @__PURE__ */ jsx(HashIcon, {}),
18012
- " ",
18013
- span?.spanId
18014
- ] })
18348
+ span?.traceId && span?.spanId && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ScorersDropdown, { trace, spanId: span?.spanId, onScorerTriggered }) })
18015
18349
  ] }),
18016
18350
  span?.attributes?.usage && /* @__PURE__ */ jsx(TraceSpanUsage, { spanUsage: span.attributes.usage, className: "mt-[1.5rem]" }),
18017
18351
  /* @__PURE__ */ jsx(KeyValueList, { data: spanInfo, LinkComponent: Link, className: "mt-[1.5rem]" }),
18018
- /* @__PURE__ */ jsx(SpanDetails, { span })
18352
+ /* @__PURE__ */ jsx(SpanDetails, { span, onScorerTriggered })
18019
18353
  ] })
18020
18354
  ]
18021
18355
  }
@@ -18030,11 +18364,15 @@ function TraceDialog({
18030
18364
  onClose,
18031
18365
  onNext,
18032
18366
  onPrevious,
18033
- isLoadingSpans
18367
+ isLoadingSpans,
18368
+ computeAgentsLink,
18369
+ computeWorkflowsLink,
18370
+ onScorerTriggered,
18371
+ initialSpanId
18034
18372
  }) {
18035
18373
  const { Link } = useLinkComponent();
18036
- const [dialogIsOpen, setDialogIsOpen] = useState(false);
18037
- const [selectedSpanId, setSelectedSpanId] = useState(void 0);
18374
+ const [dialogIsOpen, setDialogIsOpen] = useState(Boolean(initialSpanId));
18375
+ const [selectedSpanId, setSelectedSpanId] = useState(initialSpanId);
18038
18376
  const [combinedView, setCombinedView] = useState(false);
18039
18377
  const selectedSpan = traceSpans.find((span) => span.spanId === selectedSpanId);
18040
18378
  const traceInfo = useTraceInfo(traceDetails);
@@ -18082,6 +18420,12 @@ function TraceDialog({
18082
18420
  return currentIndex > 0;
18083
18421
  };
18084
18422
  const selectedSpanInfo = getSpanInfo({ span: selectedSpan, withTraceId: !combinedView, withSpanId: combinedView });
18423
+ let entityType;
18424
+ if (traceDetails?.attributes?.agentId) {
18425
+ entityType = "Agent";
18426
+ } else if (traceDetails?.attributes?.workflowId) {
18427
+ entityType = "Workflow";
18428
+ }
18085
18429
  return /* @__PURE__ */ jsxs(Fragment, { children: [
18086
18430
  /* @__PURE__ */ jsxs(
18087
18431
  SideDialog,
@@ -18105,7 +18449,7 @@ function TraceDialog({
18105
18449
  "grid-rows-[auto_1fr_1fr]": selectedSpan && combinedView
18106
18450
  }),
18107
18451
  children: [
18108
- /* @__PURE__ */ jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
18452
+ /* @__PURE__ */ jsxs(SideDialogHeader, { className: "pr-[2.5rem]", children: [
18109
18453
  /* @__PURE__ */ jsxs(SideDialogHeading, { children: [
18110
18454
  /* @__PURE__ */ jsx(EyeIcon, {}),
18111
18455
  " ",
@@ -18118,6 +18462,15 @@ function TraceDialog({
18118
18462
  ] })
18119
18463
  ] }),
18120
18464
  /* @__PURE__ */ jsxs("div", { className: cn("overflow-y-auto pb-[2.5rem]"), children: [
18465
+ traceDetails && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
18466
+ ScorersDropdown,
18467
+ {
18468
+ trace: traceDetails,
18469
+ spanId: selectedSpanId,
18470
+ onScorerTriggered,
18471
+ entityType
18472
+ }
18473
+ ) }),
18121
18474
  traceDetails?.metadata?.usage && /* @__PURE__ */ jsx(
18122
18475
  TraceSpanUsage,
18123
18476
  {
@@ -18137,7 +18490,20 @@ function TraceDialog({
18137
18490
  isLoading: isLoadingSpans,
18138
18491
  className: "pr-[2.5rem] pt-[2.5rem]"
18139
18492
  }
18140
- )
18493
+ ),
18494
+ traceDetails?.links?.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-[2.5rem] pr-[2.5rem]", children: [
18495
+ /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", className: "pb-[1rem]", children: [
18496
+ /* @__PURE__ */ jsx(GaugeIcon, {}),
18497
+ " Scores"
18498
+ ] }),
18499
+ /* @__PURE__ */ jsx("div", { className: "bg-surface2 rounded-lg overflow-hidden border-sm border-border1", children: /* @__PURE__ */ jsx(
18500
+ ScoreTable,
18501
+ {
18502
+ scores: traceDetails?.links,
18503
+ onItemClick: (scorerName) => onScorerTriggered(scorerName, traceDetails.traceId, selectedSpanId)
18504
+ }
18505
+ ) })
18506
+ ] })
18141
18507
  ] }),
18142
18508
  selectedSpan && combinedView && /* @__PURE__ */ jsxs("div", { className: "overflow-y-auto grid grid-rows-[auto_1fr] relative", children: [
18143
18509
  /* @__PURE__ */ jsx("div", { className: "absolute left-0 right-[2.5rem] h-[.5rem] bg-surface1 rounded-full top-0" }),
@@ -18168,11 +18534,11 @@ function TraceDialog({
18168
18534
  ] }),
18169
18535
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[20rem_1fr] gap-[1rem] overflow-y-auto", children: [
18170
18536
  /* @__PURE__ */ jsxs("div", { className: "overflow-y-auto grid content-start p-[1.5rem] pl-0 gap-[2rem]", children: [
18171
- /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", children: [
18537
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", children: [
18172
18538
  /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
18173
18539
  " ",
18174
18540
  selectedSpan?.name
18175
- ] }),
18541
+ ] }) }),
18176
18542
  selectedSpan?.attributes?.usage && /* @__PURE__ */ jsx(
18177
18543
  TraceSpanUsage,
18178
18544
  {
@@ -18182,7 +18548,7 @@ function TraceDialog({
18182
18548
  ),
18183
18549
  /* @__PURE__ */ jsx(KeyValueList, { data: selectedSpanInfo, LinkComponent: Link })
18184
18550
  ] }),
18185
- /* @__PURE__ */ jsx("div", { className: "overflow-y-auto pr-[2.5rem] pt-[2rem]", children: /* @__PURE__ */ jsx(SpanDetails, { span: selectedSpan }) })
18551
+ /* @__PURE__ */ jsx("div", { className: "overflow-y-auto pr-[2.5rem] pt-[2rem]", children: /* @__PURE__ */ jsx(SpanDetails, { span: selectedSpan, onScorerTriggered }) })
18186
18552
  ] })
18187
18553
  ] })
18188
18554
  ]
@@ -18191,16 +18557,21 @@ function TraceDialog({
18191
18557
  ]
18192
18558
  }
18193
18559
  ),
18194
- /* @__PURE__ */ jsx(
18560
+ traceDetails && /* @__PURE__ */ jsx(
18195
18561
  SpanDialog,
18196
18562
  {
18563
+ trace: traceDetails,
18197
18564
  span: selectedSpan,
18198
18565
  isOpen: Boolean(dialogIsOpen && selectedSpanId && !combinedView),
18199
- onClose: () => setDialogIsOpen(false),
18566
+ onClose: () => {
18567
+ setDialogIsOpen(false);
18568
+ setSelectedSpanId(void 0);
18569
+ },
18200
18570
  onNext: thereIsNextSpan() ? toNextSpan : void 0,
18201
18571
  onPrevious: thereIsPreviousSpan() ? toPreviousSpan : void 0,
18202
18572
  onViewToggle: () => setCombinedView(!combinedView),
18203
- spanInfo: selectedSpanInfo
18573
+ spanInfo: selectedSpanInfo,
18574
+ onScorerTriggered
18204
18575
  }
18205
18576
  )
18206
18577
  ] });