@mastra/playground-ui 6.2.2-alpha.0 → 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({
@@ -4321,7 +4323,10 @@ const useCodemirrorTheme$2 = () => {
4321
4323
  []
4322
4324
  );
4323
4325
  };
4324
- const SyntaxHighlighter$2 = ({ data, className }) => {
4326
+ const SyntaxHighlighter$2 = ({
4327
+ data,
4328
+ className
4329
+ }) => {
4325
4330
  const formattedCode = JSON.stringify(data, null, 2);
4326
4331
  const theme = useCodemirrorTheme$2();
4327
4332
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx("rounded-md bg-surface4 p-1 font-mono relative", className), children: [
@@ -4494,7 +4499,7 @@ const NetworkChoiceMetadataDialogTrigger = ({
4494
4499
  ] });
4495
4500
  };
4496
4501
 
4497
- const ToolBadge = ({ toolName, args, result, networkMetadata }) => {
4502
+ const ToolBadge = ({ toolName, args, result, networkMetadata, toolOutput }) => {
4498
4503
  let argSlot = null;
4499
4504
  try {
4500
4505
  const { __mastraMetadata: _, ...formattedArgs } = typeof args === "object" ? args : JSON.parse(args);
@@ -4502,7 +4507,7 @@ const ToolBadge = ({ toolName, args, result, networkMetadata }) => {
4502
4507
  } catch {
4503
4508
  argSlot = /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap", children: args });
4504
4509
  }
4505
- let resultSlot = typeof result === "string" ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap", children: result }) : /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: result });
4510
+ let resultSlot = typeof result === "string" ? /* @__PURE__ */ jsxRuntime.jsx("pre", { className: "whitespace-pre-wrap bg-surface4 p-4 rounded-md", children: result }) : /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: result });
4506
4511
  return /* @__PURE__ */ jsxRuntime.jsx(
4507
4512
  BadgeWrapper,
4508
4513
  {
@@ -4520,9 +4525,13 @@ const ToolBadge = ({ toolName, args, result, networkMetadata }) => {
4520
4525
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium pb-2", children: "Tool arguments" }),
4521
4526
  argSlot
4522
4527
  ] }),
4523
- result !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4528
+ resultSlot !== void 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4524
4529
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium pb-2", children: "Tool result" }),
4525
4530
  resultSlot
4531
+ ] }),
4532
+ toolOutput.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
4533
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium pb-2", children: "Tool output" }),
4534
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-40 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsx(SyntaxHighlighter$2, { data: toolOutput }) })
4526
4535
  ] })
4527
4536
  ] })
4528
4537
  }
@@ -4545,16 +4554,16 @@ const usePlaygroundStore = zustand.create()(
4545
4554
  )
4546
4555
  );
4547
4556
 
4548
- const useWorkflow = (workflowId, enabled = true) => {
4557
+ const useWorkflow = (workflowId) => {
4549
4558
  const client = useMastraClient();
4550
4559
  const { runtimeContext } = usePlaygroundStore();
4551
4560
  return reactQuery.useQuery({
4552
4561
  queryKey: ["workflow", workflowId],
4553
- queryFn: () => client.getWorkflow(workflowId).details(runtimeContext),
4562
+ queryFn: () => workflowId ? client.getWorkflow(workflowId).details(runtimeContext) : null,
4563
+ enabled: Boolean(workflowId),
4554
4564
  retry: false,
4555
4565
  refetchOnWindowFocus: false,
4556
- throwOnError: false,
4557
- enabled
4566
+ throwOnError: false
4558
4567
  });
4559
4568
  };
4560
4569
  const useLegacyWorkflow = (workflowId) => {
@@ -8285,7 +8294,7 @@ const Row = React.forwardRef(
8285
8294
  "tr",
8286
8295
  {
8287
8296
  className: clsx(
8288
- "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",
8289
8298
  selected && "bg-surface4",
8290
8299
  onClick && "cursor-pointer",
8291
8300
  className
@@ -8762,6 +8771,7 @@ const ToolFallbackInner = ({ toolName, result, args }) => {
8762
8771
  toolName,
8763
8772
  args,
8764
8773
  result,
8774
+ toolOutput: args?.__mastraMetadata?.toolOutput || [],
8765
8775
  networkMetadata: args?.__mastraMetadata?.networkMetadata
8766
8776
  }
8767
8777
  );
@@ -9910,6 +9920,34 @@ const handleStreamChunk = async ({
9910
9920
  case "tool-output": {
9911
9921
  if (chunk.payload.output?.type.startsWith("workflow-")) {
9912
9922
  handleWorkflowChunk({ workflowChunk: chunk.payload.output, setMessages, entityName: chunk.payload.toolName });
9923
+ } else {
9924
+ setMessages((currentConversation) => {
9925
+ const lastMessage = currentConversation[currentConversation.length - 1];
9926
+ if (lastMessage && lastMessage.role === "assistant" && Array.isArray(lastMessage.content)) {
9927
+ const updatedContent = lastMessage.content.map((part) => {
9928
+ if (typeof part === "object" && part.type === "tool-call" && part.toolCallId === chunk.payload.toolCallId) {
9929
+ const existingToolOutput = part.args?.__mastraMetadata?.toolOutput || [];
9930
+ return {
9931
+ ...part,
9932
+ args: {
9933
+ ...part.args,
9934
+ __mastraMetadata: {
9935
+ ...part.args?.__mastraMetadata,
9936
+ toolOutput: [...existingToolOutput, chunk?.payload?.output]
9937
+ }
9938
+ }
9939
+ };
9940
+ }
9941
+ return part;
9942
+ });
9943
+ const updatedMessage = {
9944
+ ...lastMessage,
9945
+ content: updatedContent
9946
+ };
9947
+ return [...currentConversation.slice(0, -1), updatedMessage];
9948
+ }
9949
+ return currentConversation;
9950
+ });
9913
9951
  }
9914
9952
  break;
9915
9953
  }
@@ -12911,13 +12949,13 @@ function KeyValueList({ data, LinkComponent, className, labelsAreHidden, isLoadi
12911
12949
  style: { width: `${Math.floor(Math.random() * (90 - 30 + 1)) + 50}%` },
12912
12950
  children: " "
12913
12951
  }
12914
- ) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: isValueItemArray ? value?.map((item) => {
12952
+ ) : isValueItemArray ? value?.map((item) => {
12915
12953
  return item.path ? /* @__PURE__ */ jsxRuntime.jsx(RelationWrapper, { description: item.description, children: /* @__PURE__ */ jsxRuntime.jsxs(Link, { href: item.path, children: [
12916
12954
  item?.name,
12917
12955
  " ",
12918
12956
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, {})
12919
12957
  ] }) }, item.id) : /* @__PURE__ */ jsxRuntime.jsx("span", { children: item?.name }, item.id);
12920
- }) : /* @__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" }) })
12921
12959
  }
12922
12960
  )
12923
12961
  ] }, label + index);
@@ -13613,7 +13651,7 @@ const DateTimePicker = ({
13613
13651
  /* @__PURE__ */ jsxRuntime.jsx(
13614
13652
  PopoverContent,
13615
13653
  {
13616
- 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]",
13617
13655
  align: "start",
13618
13656
  "data-testid": "datepicker-calendar",
13619
13657
  children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -13739,7 +13777,7 @@ const DateTimePickerContent = ({
13739
13777
  "div",
13740
13778
  {
13741
13779
  "aria-label": "Choose date",
13742
- className: cn("relative mt-2 flex flex-col ", className),
13780
+ className: cn("relative flex flex-col", className),
13743
13781
  onKeyDown: (e) => {
13744
13782
  e.stopPropagation();
13745
13783
  if (e.key === "Escape") {
@@ -13836,7 +13874,16 @@ function getShortId(id) {
13836
13874
  return id.slice(0, 8);
13837
13875
  }
13838
13876
 
13839
- 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();
13840
13887
  return /* @__PURE__ */ jsxRuntime.jsxs(
13841
13888
  SideDialog,
13842
13889
  {
@@ -13859,10 +13906,30 @@ function ScoreDialog({ scorer, score, isOpen, onClose, onNext, onPrevious }) {
13859
13906
  ] })
13860
13907
  ] }) }),
13861
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
+ ),
13862
13929
  /* @__PURE__ */ jsxRuntime.jsx(
13863
13930
  SideDialogCodeSection,
13864
13931
  {
13865
- title: `Score: ${score?.score ? score?.score : "n/a"}`,
13932
+ title: `Score: ${Number.isNaN(score?.score) ? "n/a" : score?.score}`,
13866
13933
  codeStr: score?.reason,
13867
13934
  simplified: true
13868
13935
  }
@@ -13954,29 +14021,11 @@ const useScoresByEntityId = (entityId, entityType, page = 0) => {
13954
14021
  };
13955
14022
  const useScoresByScorerId = ({ scorerId, page = 0, entityId, entityType }) => {
13956
14023
  const client = useMastraClient();
13957
- const [scores, setScores] = React.useState(null);
13958
- const [isLoading, setIsLoading] = React.useState(true);
13959
- React.useEffect(() => {
13960
- const fetchScores = async () => {
13961
- setIsLoading(true);
13962
- try {
13963
- const res = await client.getScoresByScorerId({
13964
- scorerId,
13965
- page: page || 0,
13966
- entityId: entityId || void 0,
13967
- entityType: entityType || void 0,
13968
- perPage: 10
13969
- });
13970
- setScores(res);
13971
- setIsLoading(false);
13972
- } catch (error) {
13973
- setScores(null);
13974
- setIsLoading(false);
13975
- }
13976
- };
13977
- fetchScores();
13978
- }, [scorerId, page, entityId, entityType]);
13979
- 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
+ });
13980
14029
  };
13981
14030
  const useScorer = (scorerId) => {
13982
14031
  const client = useMastraClient();
@@ -14002,25 +14051,12 @@ const useScorer = (scorerId) => {
14002
14051
  };
14003
14052
  const useScorers = () => {
14004
14053
  const client = useMastraClient();
14005
- const [scorers, setScorers] = React.useState({});
14006
- const [isLoading, setIsLoading] = React.useState(true);
14007
- React.useEffect(() => {
14008
- const fetchScorers = async () => {
14009
- setIsLoading(true);
14010
- try {
14011
- const res = await client.getScorers();
14012
- setScorers(res);
14013
- } catch (error) {
14014
- setScorers({});
14015
- console.error("Error fetching agents", error);
14016
- sonner.toast.error("Error fetching agents");
14017
- } finally {
14018
- setIsLoading(false);
14019
- }
14020
- };
14021
- fetchScorers();
14022
- }, []);
14023
- return { scorers, isLoading };
14054
+ return reactQuery.useQuery({
14055
+ queryKey: ["scorers"],
14056
+ queryFn: () => client.getScorers(),
14057
+ staleTime: 0,
14058
+ gcTime: 0
14059
+ });
14024
14060
  };
14025
14061
 
14026
14062
  const NameCell = ({ row }) => {
@@ -14267,7 +14303,9 @@ const AgentMetadataModelSwitcher = ({
14267
14303
  defaultModel,
14268
14304
  updateModel,
14269
14305
  closeEditor,
14270
- modelProviders
14306
+ modelProviders,
14307
+ autoSave = false,
14308
+ selectProviderPlaceholder = "Select provider"
14271
14309
  }) => {
14272
14310
  const [selectedModel, setSelectedModel] = React.useState(defaultModel);
14273
14311
  const [showSuggestions, setShowSuggestions] = React.useState(false);
@@ -14279,10 +14317,19 @@ const AgentMetadataModelSwitcher = ({
14279
14317
  return "";
14280
14318
  });
14281
14319
  const [loading, setLoading] = React.useState(false);
14320
+ const [infoMsg, setInfoMsg] = React.useState("");
14282
14321
  const modelsList = Object.entries(Models).filter(([provider]) => modelProviders.includes(provider));
14283
14322
  const allModels = modelsList.flatMap(([_, { models }]) => models);
14284
14323
  const providersList = modelsList.map(([provider, { icon }]) => ({ provider, icon }));
14285
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]);
14286
14333
  const handleSave = async () => {
14287
14334
  setLoading(true);
14288
14335
  const providerToUse = model?.provider ?? selectedProvider;
@@ -14290,67 +14337,156 @@ const AgentMetadataModelSwitcher = ({
14290
14337
  setLoading(false);
14291
14338
  closeEditor();
14292
14339
  };
14293
- const filteredModels = allModels.filter((model2) => model2.model.includes(selectedModel));
14294
- 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: [
14295
14403
  /* @__PURE__ */ jsxRuntime.jsxs(
14296
- Select$1,
14404
+ "div",
14297
14405
  {
14298
- value: model?.provider ?? selectedProvider,
14299
- onValueChange: setSelectedProvider,
14300
- 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
+ }),
14301
14410
  children: [
14302
- /* @__PURE__ */ jsxRuntime.jsx(SelectTrigger, { className: "max-w-[150px]", children: /* @__PURE__ */ jsxRuntime.jsx(SelectValue, { placeholder: "Select provider" }) }),
14303
- /* @__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: [
14304
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: providerMapToIcon[provider.icon] }),
14305
- provider.provider
14306
- ] }) }, 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
+ )
14307
14472
  ]
14308
14473
  }
14309
14474
  ),
14310
- /* @__PURE__ */ jsxRuntime.jsxs(Popover, { open: showSuggestions, children: [
14311
- /* @__PURE__ */ jsxRuntime.jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(
14312
- Input,
14313
- {
14314
- id: "model-input",
14315
- list: "model-suggestions",
14316
- className: "flex-1",
14317
- type: "text",
14318
- value: selectedModel,
14319
- onChange: (e) => {
14320
- setSelectedModel(e.target.value);
14321
- setShowSuggestions(true);
14322
- },
14323
- placeholder: "Enter model name or select from suggestions..."
14324
- }
14325
- ) }),
14326
- filteredModels.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
14327
- PopoverContent,
14328
- {
14329
- onOpenAutoFocus: (e) => e.preventDefault(),
14330
- 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",
14331
- children: filteredModels.map((model2) => /* @__PURE__ */ jsxRuntime.jsxs(
14332
- "div",
14333
- {
14334
- className: "flex items-center gap-2 cursor-pointer hover:bg-surface5 p-2",
14335
- onClick: () => {
14336
- setSelectedModel(model2.model);
14337
- setShowSuggestions(false);
14338
- },
14339
- children: [
14340
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { children: providerMapToIcon[model2.icon] }),
14341
- model2.model
14342
- ]
14343
- },
14344
- model2.provider + model2.model
14345
- ))
14346
- }
14347
- )
14348
- ] }),
14349
- /* @__PURE__ */ jsxRuntime.jsxs(Tooltip, { children: [
14350
- /* @__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, {}) }) }) }),
14351
- /* @__PURE__ */ jsxRuntime.jsx(TooltipContent, { children: loading ? "Saving..." : "Save new model" })
14352
- ] })
14353
- ] }) });
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
+ ] });
14354
14490
  };
14355
14491
 
14356
14492
  const AgentMetadataNetworkList = ({ agents }) => {
@@ -14463,11 +14599,11 @@ const AgentMetadataWorkflowList = ({ workflows }) => {
14463
14599
  };
14464
14600
  const AgentMetadataScorerList = ({ entityId, entityType }) => {
14465
14601
  const { Link, paths } = useLinkComponent();
14466
- const { scorers, isLoading } = useScorers();
14602
+ const { data: scorers = {}, isLoading } = useScorers();
14467
14603
  const scorerList = Object.keys(scorers).filter((scorerKey) => {
14468
14604
  const scorer = scorers[scorerKey];
14469
14605
  if (entityType === "AGENT") {
14470
- return scorer.agentIds.includes(entityId);
14606
+ return scorer.agentNames.includes(entityId);
14471
14607
  }
14472
14608
  return scorer.workflowIds.includes(entityId);
14473
14609
  }).map((scorerKey) => ({ ...scorers[scorerKey], id: scorerKey }));
@@ -16256,7 +16392,7 @@ function TemplateForm({
16256
16392
  "h2",
16257
16393
  {
16258
16394
  className: cn(
16259
- "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]",
16260
16396
  "[&>svg]:w-[1.2em] [&_svg]:h-[1.2em] [&_svg]:opacity-70 "
16261
16397
  ),
16262
16398
  children: [
@@ -16269,29 +16405,13 @@ function TemplateForm({
16269
16405
  SelectField,
16270
16406
  {
16271
16407
  options: providerOptions,
16272
- label: "Provider",
16408
+ label: "Template AI Model Provider",
16273
16409
  onValueChange: onProviderChange,
16274
16410
  value: selectedProvider,
16275
- placeholder: "Select a provider"
16411
+ placeholder: "Select"
16276
16412
  }
16277
16413
  ),
16278
16414
  selectedProvider && Object.entries(variables || {}).length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
16279
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-[0.5rem]", children: [
16280
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-icon3 text-[0.875rem] font-medium", children: "Select AI Model for Template Installation *" }),
16281
- /* @__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" }),
16282
- /* @__PURE__ */ jsxRuntime.jsx(
16283
- AgentMetadataModelSwitcher,
16284
- {
16285
- defaultProvider: defaultModelProvider || "",
16286
- defaultModel: defaultModelId || "",
16287
- updateModel: onModelUpdate || (() => Promise.resolve({ message: "Updated" })),
16288
- closeEditor: () => {
16289
- },
16290
- modelProviders: ["openai", "anthropic", "google", "xai", "groq"]
16291
- }
16292
- ),
16293
- (!defaultModelProvider || !defaultModelId) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-red-500 text-[0.75rem]", children: "Please select an AI model to continue" })
16294
- ] }),
16295
16415
  /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-icon3 text-[0.875rem]", children: "Set required Environmental Variables" }),
16296
16416
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-[1fr_1fr] gap-[1rem] items-start", children: isLoadingEnvVars ? /* @__PURE__ */ jsxRuntime.jsxs(
16297
16417
  "div",
@@ -16331,13 +16451,31 @@ function TemplateForm({
16331
16451
  className: "w-full"
16332
16452
  }
16333
16453
  )
16334
- ] }, 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
+ ] })
16335
16473
  ] }),
16336
16474
  selectedProvider && !isLoadingEnvVars && /* @__PURE__ */ jsxRuntime.jsxs(
16337
- "button",
16475
+ Button,
16338
16476
  {
16339
16477
  className: cn(
16340
- "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",
16341
16479
  "[&>svg]:w-[1.1em] [&_svg]:h-[1.1em] [&_svg]:text-icon5"
16342
16480
  ),
16343
16481
  onClick: handleInstallTemplate,
@@ -16576,7 +16714,7 @@ function TemplateFailure({ errorMsg, validationErrors }) {
16576
16714
  };
16577
16715
  };
16578
16716
  const { icon, title } = getIconAndTitle();
16579
- 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: [
16580
16718
  /* @__PURE__ */ jsxRuntime.jsxs(
16581
16719
  "div",
16582
16720
  {
@@ -17674,10 +17812,14 @@ function TraceTimeline({
17674
17812
  ) : /* @__PURE__ */ jsxRuntime.jsx(
17675
17813
  "div",
17676
17814
  {
17677
- className: cn("grid items-start content-start gap-y-[2px]", "xl:gap-x-[1rem] xl:py-[1rem]", {
17678
- "xl:grid-cols-[3fr_auto]": !overallEndTime,
17679
- "xl:grid-cols-[3fr_2fr]": overallEndTime
17680
- }),
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
+ ),
17681
17823
  children: hierarchicalSpans?.map((span) => /* @__PURE__ */ jsxRuntime.jsx(
17682
17824
  TraceTimelineSpan,
17683
17825
  {
@@ -17951,7 +18093,24 @@ function getSpanInfo({ span, withTraceId = true, withSpanId = true }) {
17951
18093
  return baseInfo;
17952
18094
  }
17953
18095
 
17954
- 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 }) {
17955
18114
  if (!span) {
17956
18115
  return null;
17957
18116
  }
@@ -17959,18 +18118,226 @@ function SpanDetails({ span }) {
17959
18118
  /* @__PURE__ */ jsxRuntime.jsx(SideDialogCodeSection, { title: "Input", codeStr: JSON.stringify(span.input || null, null, 2) }),
17960
18119
  /* @__PURE__ */ jsxRuntime.jsx(SideDialogCodeSection, { title: "Output", codeStr: JSON.stringify(span.output || null, null, 2) }),
17961
18120
  /* @__PURE__ */ jsxRuntime.jsx(SideDialogCodeSection, { title: "Metadata", codeStr: JSON.stringify(span.metadata || null, null, 2) }),
17962
- /* @__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
+ ] })
17963
18135
  ] });
17964
18136
  }
17965
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
+
17966
18331
  function SpanDialog({
18332
+ trace,
17967
18333
  span,
17968
18334
  isOpen,
17969
18335
  onClose,
17970
18336
  onNext,
17971
18337
  onPrevious,
17972
18338
  onViewToggle,
17973
- spanInfo = []
18339
+ spanInfo = [],
18340
+ onScorerTriggered
17974
18341
  }) {
17975
18342
  const { Link } = useLinkComponent();
17976
18343
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -17999,21 +18366,24 @@ function SpanDialog({
17999
18366
  /* @__PURE__ */ jsxRuntime.jsx("button", { className: "flex items-center gap-1", onClick: onViewToggle, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.PanelTopIcon, {}) })
18000
18367
  ] }),
18001
18368
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-[1.5rem] px-[2.5rem] overflow-y-auto grid gap-[1.5rem] content-start", children: [
18002
- /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
18003
- /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeading, { children: [
18004
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsLeftRightEllipsisIcon, {}),
18005
- " ",
18006
- 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
+ ] })
18007
18381
  ] }),
18008
- /* @__PURE__ */ jsxRuntime.jsxs(TextAndIcon, { children: [
18009
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.HashIcon, {}),
18010
- " ",
18011
- span?.spanId
18012
- ] })
18382
+ span?.traceId && span?.spanId && /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsx(ScorersDropdown, { trace, spanId: span?.spanId, onScorerTriggered }) })
18013
18383
  ] }),
18014
18384
  span?.attributes?.usage && /* @__PURE__ */ jsxRuntime.jsx(TraceSpanUsage, { spanUsage: span.attributes.usage, className: "mt-[1.5rem]" }),
18015
18385
  /* @__PURE__ */ jsxRuntime.jsx(KeyValueList, { data: spanInfo, LinkComponent: Link, className: "mt-[1.5rem]" }),
18016
- /* @__PURE__ */ jsxRuntime.jsx(SpanDetails, { span })
18386
+ /* @__PURE__ */ jsxRuntime.jsx(SpanDetails, { span, onScorerTriggered })
18017
18387
  ] })
18018
18388
  ]
18019
18389
  }
@@ -18028,11 +18398,15 @@ function TraceDialog({
18028
18398
  onClose,
18029
18399
  onNext,
18030
18400
  onPrevious,
18031
- isLoadingSpans
18401
+ isLoadingSpans,
18402
+ computeAgentsLink,
18403
+ computeWorkflowsLink,
18404
+ onScorerTriggered,
18405
+ initialSpanId
18032
18406
  }) {
18033
18407
  const { Link } = useLinkComponent();
18034
- const [dialogIsOpen, setDialogIsOpen] = React.useState(false);
18035
- const [selectedSpanId, setSelectedSpanId] = React.useState(void 0);
18408
+ const [dialogIsOpen, setDialogIsOpen] = React.useState(Boolean(initialSpanId));
18409
+ const [selectedSpanId, setSelectedSpanId] = React.useState(initialSpanId);
18036
18410
  const [combinedView, setCombinedView] = React.useState(false);
18037
18411
  const selectedSpan = traceSpans.find((span) => span.spanId === selectedSpanId);
18038
18412
  const traceInfo = useTraceInfo(traceDetails);
@@ -18080,6 +18454,12 @@ function TraceDialog({
18080
18454
  return currentIndex > 0;
18081
18455
  };
18082
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
+ }
18083
18463
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
18084
18464
  /* @__PURE__ */ jsxRuntime.jsxs(
18085
18465
  SideDialog,
@@ -18103,7 +18483,7 @@ function TraceDialog({
18103
18483
  "grid-rows-[auto_1fr_1fr]": selectedSpan && combinedView
18104
18484
  }),
18105
18485
  children: [
18106
- /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
18486
+ /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeader, { className: "pr-[2.5rem]", children: [
18107
18487
  /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeading, { children: [
18108
18488
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.EyeIcon, {}),
18109
18489
  " ",
@@ -18116,6 +18496,15 @@ function TraceDialog({
18116
18496
  ] })
18117
18497
  ] }),
18118
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
+ ) }),
18119
18508
  traceDetails?.metadata?.usage && /* @__PURE__ */ jsxRuntime.jsx(
18120
18509
  TraceSpanUsage,
18121
18510
  {
@@ -18135,7 +18524,20 @@ function TraceDialog({
18135
18524
  isLoading: isLoadingSpans,
18136
18525
  className: "pr-[2.5rem] pt-[2.5rem]"
18137
18526
  }
18138
- )
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
+ ] })
18139
18541
  ] }),
18140
18542
  selectedSpan && combinedView && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-y-auto grid grid-rows-[auto_1fr] relative", children: [
18141
18543
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute left-0 right-[2.5rem] h-[.5rem] bg-surface1 rounded-full top-0" }),
@@ -18166,11 +18568,11 @@ function TraceDialog({
18166
18568
  ] }),
18167
18569
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[20rem_1fr] gap-[1rem] overflow-y-auto", children: [
18168
18570
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "overflow-y-auto grid content-start p-[1.5rem] pl-0 gap-[2rem]", children: [
18169
- /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeading, { as: "h2", children: [
18571
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(SideDialogHeading, { as: "h2", children: [
18170
18572
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronsLeftRightEllipsisIcon, {}),
18171
18573
  " ",
18172
18574
  selectedSpan?.name
18173
- ] }),
18575
+ ] }) }),
18174
18576
  selectedSpan?.attributes?.usage && /* @__PURE__ */ jsxRuntime.jsx(
18175
18577
  TraceSpanUsage,
18176
18578
  {
@@ -18180,7 +18582,7 @@ function TraceDialog({
18180
18582
  ),
18181
18583
  /* @__PURE__ */ jsxRuntime.jsx(KeyValueList, { data: selectedSpanInfo, LinkComponent: Link })
18182
18584
  ] }),
18183
- /* @__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 }) })
18184
18586
  ] })
18185
18587
  ] })
18186
18588
  ]
@@ -18189,16 +18591,21 @@ function TraceDialog({
18189
18591
  ]
18190
18592
  }
18191
18593
  ),
18192
- /* @__PURE__ */ jsxRuntime.jsx(
18594
+ traceDetails && /* @__PURE__ */ jsxRuntime.jsx(
18193
18595
  SpanDialog,
18194
18596
  {
18597
+ trace: traceDetails,
18195
18598
  span: selectedSpan,
18196
18599
  isOpen: Boolean(dialogIsOpen && selectedSpanId && !combinedView),
18197
- onClose: () => setDialogIsOpen(false),
18600
+ onClose: () => {
18601
+ setDialogIsOpen(false);
18602
+ setSelectedSpanId(void 0);
18603
+ },
18198
18604
  onNext: thereIsNextSpan() ? toNextSpan : void 0,
18199
18605
  onPrevious: thereIsPreviousSpan() ? toPreviousSpan : void 0,
18200
18606
  onViewToggle: () => setCombinedView(!combinedView),
18201
- spanInfo: selectedSpanInfo
18607
+ spanInfo: selectedSpanInfo,
18608
+ onScorerTriggered
18202
18609
  }
18203
18610
  )
18204
18611
  ] });