@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.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({
@@ -4287,7 +4288,10 @@ const useCodemirrorTheme$2 = () => {
4287
4288
  []
4288
4289
  );
4289
4290
  };
4290
- const SyntaxHighlighter$2 = ({ data, className }) => {
4291
+ const SyntaxHighlighter$2 = ({
4292
+ data,
4293
+ className
4294
+ }) => {
4291
4295
  const formattedCode = JSON.stringify(data, null, 2);
4292
4296
  const theme = useCodemirrorTheme$2();
4293
4297
  return /* @__PURE__ */ jsxs("div", { className: clsx("rounded-md bg-surface4 p-1 font-mono relative", className), children: [
@@ -4460,7 +4464,7 @@ const NetworkChoiceMetadataDialogTrigger = ({
4460
4464
  ] });
4461
4465
  };
4462
4466
 
4463
- const ToolBadge = ({ toolName, args, result, networkMetadata }) => {
4467
+ const ToolBadge = ({ toolName, args, result, networkMetadata, toolOutput }) => {
4464
4468
  let argSlot = null;
4465
4469
  try {
4466
4470
  const { __mastraMetadata: _, ...formattedArgs } = typeof args === "object" ? args : JSON.parse(args);
@@ -4468,7 +4472,7 @@ const ToolBadge = ({ toolName, args, result, networkMetadata }) => {
4468
4472
  } catch {
4469
4473
  argSlot = /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap", children: args });
4470
4474
  }
4471
- let resultSlot = typeof result === "string" ? /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap", children: result }) : /* @__PURE__ */ jsx(SyntaxHighlighter$2, { data: result });
4475
+ let resultSlot = typeof result === "string" ? /* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap bg-surface4 p-4 rounded-md", children: result }) : /* @__PURE__ */ jsx(SyntaxHighlighter$2, { data: result });
4472
4476
  return /* @__PURE__ */ jsx(
4473
4477
  BadgeWrapper,
4474
4478
  {
@@ -4486,9 +4490,13 @@ const ToolBadge = ({ toolName, args, result, networkMetadata }) => {
4486
4490
  /* @__PURE__ */ jsx("p", { className: "font-medium pb-2", children: "Tool arguments" }),
4487
4491
  argSlot
4488
4492
  ] }),
4489
- result !== void 0 && /* @__PURE__ */ jsxs("div", { children: [
4493
+ resultSlot !== void 0 && /* @__PURE__ */ jsxs("div", { children: [
4490
4494
  /* @__PURE__ */ jsx("p", { className: "font-medium pb-2", children: "Tool result" }),
4491
4495
  resultSlot
4496
+ ] }),
4497
+ toolOutput.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
4498
+ /* @__PURE__ */ jsx("p", { className: "font-medium pb-2", children: "Tool output" }),
4499
+ /* @__PURE__ */ jsx("div", { className: "h-40 overflow-y-auto", children: /* @__PURE__ */ jsx(SyntaxHighlighter$2, { data: toolOutput }) })
4492
4500
  ] })
4493
4501
  ] })
4494
4502
  }
@@ -4511,16 +4519,16 @@ const usePlaygroundStore = create()(
4511
4519
  )
4512
4520
  );
4513
4521
 
4514
- const useWorkflow = (workflowId, enabled = true) => {
4522
+ const useWorkflow = (workflowId) => {
4515
4523
  const client = useMastraClient();
4516
4524
  const { runtimeContext } = usePlaygroundStore();
4517
4525
  return useQuery({
4518
4526
  queryKey: ["workflow", workflowId],
4519
- queryFn: () => client.getWorkflow(workflowId).details(runtimeContext),
4527
+ queryFn: () => workflowId ? client.getWorkflow(workflowId).details(runtimeContext) : null,
4528
+ enabled: Boolean(workflowId),
4520
4529
  retry: false,
4521
4530
  refetchOnWindowFocus: false,
4522
- throwOnError: false,
4523
- enabled
4531
+ throwOnError: false
4524
4532
  });
4525
4533
  };
4526
4534
  const useLegacyWorkflow = (workflowId) => {
@@ -8251,7 +8259,7 @@ const Row = forwardRef(
8251
8259
  "tr",
8252
8260
  {
8253
8261
  className: clsx(
8254
- "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",
8255
8263
  selected && "bg-surface4",
8256
8264
  onClick && "cursor-pointer",
8257
8265
  className
@@ -8728,6 +8736,7 @@ const ToolFallbackInner = ({ toolName, result, args }) => {
8728
8736
  toolName,
8729
8737
  args,
8730
8738
  result,
8739
+ toolOutput: args?.__mastraMetadata?.toolOutput || [],
8731
8740
  networkMetadata: args?.__mastraMetadata?.networkMetadata
8732
8741
  }
8733
8742
  );
@@ -9876,6 +9885,34 @@ const handleStreamChunk = async ({
9876
9885
  case "tool-output": {
9877
9886
  if (chunk.payload.output?.type.startsWith("workflow-")) {
9878
9887
  handleWorkflowChunk({ workflowChunk: chunk.payload.output, setMessages, entityName: chunk.payload.toolName });
9888
+ } else {
9889
+ setMessages((currentConversation) => {
9890
+ const lastMessage = currentConversation[currentConversation.length - 1];
9891
+ if (lastMessage && lastMessage.role === "assistant" && Array.isArray(lastMessage.content)) {
9892
+ const updatedContent = lastMessage.content.map((part) => {
9893
+ if (typeof part === "object" && part.type === "tool-call" && part.toolCallId === chunk.payload.toolCallId) {
9894
+ const existingToolOutput = part.args?.__mastraMetadata?.toolOutput || [];
9895
+ return {
9896
+ ...part,
9897
+ args: {
9898
+ ...part.args,
9899
+ __mastraMetadata: {
9900
+ ...part.args?.__mastraMetadata,
9901
+ toolOutput: [...existingToolOutput, chunk?.payload?.output]
9902
+ }
9903
+ }
9904
+ };
9905
+ }
9906
+ return part;
9907
+ });
9908
+ const updatedMessage = {
9909
+ ...lastMessage,
9910
+ content: updatedContent
9911
+ };
9912
+ return [...currentConversation.slice(0, -1), updatedMessage];
9913
+ }
9914
+ return currentConversation;
9915
+ });
9879
9916
  }
9880
9917
  break;
9881
9918
  }
@@ -12877,13 +12914,13 @@ function KeyValueList({ data, LinkComponent, className, labelsAreHidden, isLoadi
12877
12914
  style: { width: `${Math.floor(Math.random() * (90 - 30 + 1)) + 50}%` },
12878
12915
  children: " "
12879
12916
  }
12880
- ) : /* @__PURE__ */ jsx(Fragment, { children: isValueItemArray ? value?.map((item) => {
12917
+ ) : isValueItemArray ? value?.map((item) => {
12881
12918
  return item.path ? /* @__PURE__ */ jsx(RelationWrapper, { description: item.description, children: /* @__PURE__ */ jsxs(Link, { href: item.path, children: [
12882
12919
  item?.name,
12883
12920
  " ",
12884
12921
  /* @__PURE__ */ jsx(ChevronRightIcon, {})
12885
12922
  ] }) }, item.id) : /* @__PURE__ */ jsx("span", { children: item?.name }, item.id);
12886
- }) : /* @__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" }) })
12887
12924
  }
12888
12925
  )
12889
12926
  ] }, label + index);
@@ -13579,7 +13616,7 @@ const DateTimePicker = ({
13579
13616
  /* @__PURE__ */ jsx(
13580
13617
  PopoverContent,
13581
13618
  {
13582
- 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]",
13583
13620
  align: "start",
13584
13621
  "data-testid": "datepicker-calendar",
13585
13622
  children: /* @__PURE__ */ jsx(
@@ -13705,7 +13742,7 @@ const DateTimePickerContent = ({
13705
13742
  "div",
13706
13743
  {
13707
13744
  "aria-label": "Choose date",
13708
- className: cn("relative mt-2 flex flex-col ", className),
13745
+ className: cn("relative flex flex-col", className),
13709
13746
  onKeyDown: (e) => {
13710
13747
  e.stopPropagation();
13711
13748
  if (e.key === "Escape") {
@@ -13802,7 +13839,16 @@ function getShortId(id) {
13802
13839
  return id.slice(0, 8);
13803
13840
  }
13804
13841
 
13805
- 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();
13806
13852
  return /* @__PURE__ */ jsxs(
13807
13853
  SideDialog,
13808
13854
  {
@@ -13825,10 +13871,30 @@ function ScoreDialog({ scorer, score, isOpen, onClose, onNext, onPrevious }) {
13825
13871
  ] })
13826
13872
  ] }) }),
13827
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
+ ),
13828
13894
  /* @__PURE__ */ jsx(
13829
13895
  SideDialogCodeSection,
13830
13896
  {
13831
- title: `Score: ${score?.score ? score?.score : "n/a"}`,
13897
+ title: `Score: ${Number.isNaN(score?.score) ? "n/a" : score?.score}`,
13832
13898
  codeStr: score?.reason,
13833
13899
  simplified: true
13834
13900
  }
@@ -13920,29 +13986,11 @@ const useScoresByEntityId = (entityId, entityType, page = 0) => {
13920
13986
  };
13921
13987
  const useScoresByScorerId = ({ scorerId, page = 0, entityId, entityType }) => {
13922
13988
  const client = useMastraClient();
13923
- const [scores, setScores] = useState(null);
13924
- const [isLoading, setIsLoading] = useState(true);
13925
- useEffect(() => {
13926
- const fetchScores = async () => {
13927
- setIsLoading(true);
13928
- try {
13929
- const res = await client.getScoresByScorerId({
13930
- scorerId,
13931
- page: page || 0,
13932
- entityId: entityId || void 0,
13933
- entityType: entityType || void 0,
13934
- perPage: 10
13935
- });
13936
- setScores(res);
13937
- setIsLoading(false);
13938
- } catch (error) {
13939
- setScores(null);
13940
- setIsLoading(false);
13941
- }
13942
- };
13943
- fetchScores();
13944
- }, [scorerId, page, entityId, entityType]);
13945
- 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
+ });
13946
13994
  };
13947
13995
  const useScorer = (scorerId) => {
13948
13996
  const client = useMastraClient();
@@ -13968,25 +14016,12 @@ const useScorer = (scorerId) => {
13968
14016
  };
13969
14017
  const useScorers = () => {
13970
14018
  const client = useMastraClient();
13971
- const [scorers, setScorers] = useState({});
13972
- const [isLoading, setIsLoading] = useState(true);
13973
- useEffect(() => {
13974
- const fetchScorers = async () => {
13975
- setIsLoading(true);
13976
- try {
13977
- const res = await client.getScorers();
13978
- setScorers(res);
13979
- } catch (error) {
13980
- setScorers({});
13981
- console.error("Error fetching agents", error);
13982
- toast.error("Error fetching agents");
13983
- } finally {
13984
- setIsLoading(false);
13985
- }
13986
- };
13987
- fetchScorers();
13988
- }, []);
13989
- return { scorers, isLoading };
14019
+ return useQuery({
14020
+ queryKey: ["scorers"],
14021
+ queryFn: () => client.getScorers(),
14022
+ staleTime: 0,
14023
+ gcTime: 0
14024
+ });
13990
14025
  };
13991
14026
 
13992
14027
  const NameCell = ({ row }) => {
@@ -14233,7 +14268,9 @@ const AgentMetadataModelSwitcher = ({
14233
14268
  defaultModel,
14234
14269
  updateModel,
14235
14270
  closeEditor,
14236
- modelProviders
14271
+ modelProviders,
14272
+ autoSave = false,
14273
+ selectProviderPlaceholder = "Select provider"
14237
14274
  }) => {
14238
14275
  const [selectedModel, setSelectedModel] = useState(defaultModel);
14239
14276
  const [showSuggestions, setShowSuggestions] = useState(false);
@@ -14245,10 +14282,19 @@ const AgentMetadataModelSwitcher = ({
14245
14282
  return "";
14246
14283
  });
14247
14284
  const [loading, setLoading] = useState(false);
14285
+ const [infoMsg, setInfoMsg] = useState("");
14248
14286
  const modelsList = Object.entries(Models).filter(([provider]) => modelProviders.includes(provider));
14249
14287
  const allModels = modelsList.flatMap(([_, { models }]) => models);
14250
14288
  const providersList = modelsList.map(([provider, { icon }]) => ({ provider, icon }));
14251
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]);
14252
14298
  const handleSave = async () => {
14253
14299
  setLoading(true);
14254
14300
  const providerToUse = model?.provider ?? selectedProvider;
@@ -14256,67 +14302,156 @@ const AgentMetadataModelSwitcher = ({
14256
14302
  setLoading(false);
14257
14303
  closeEditor();
14258
14304
  };
14259
- const filteredModels = allModels.filter((model2) => model2.model.includes(selectedModel));
14260
- 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: [
14261
14368
  /* @__PURE__ */ jsxs(
14262
- Select$1,
14369
+ "div",
14263
14370
  {
14264
- value: model?.provider ?? selectedProvider,
14265
- onValueChange: setSelectedProvider,
14266
- 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
+ }),
14267
14375
  children: [
14268
- /* @__PURE__ */ jsx(SelectTrigger, { className: "max-w-[150px]", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select provider" }) }),
14269
- /* @__PURE__ */ jsx(SelectContent, { children: providersList.map((provider) => /* @__PURE__ */ jsx(SelectItem, { value: provider.provider, children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
14270
- /* @__PURE__ */ jsx(Icon, { children: providerMapToIcon[provider.icon] }),
14271
- provider.provider
14272
- ] }) }, 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
+ )
14273
14437
  ]
14274
14438
  }
14275
14439
  ),
14276
- /* @__PURE__ */ jsxs(Popover, { open: showSuggestions, children: [
14277
- /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
14278
- Input,
14279
- {
14280
- id: "model-input",
14281
- list: "model-suggestions",
14282
- className: "flex-1",
14283
- type: "text",
14284
- value: selectedModel,
14285
- onChange: (e) => {
14286
- setSelectedModel(e.target.value);
14287
- setShowSuggestions(true);
14288
- },
14289
- placeholder: "Enter model name or select from suggestions..."
14290
- }
14291
- ) }),
14292
- filteredModels.length > 0 && /* @__PURE__ */ jsx(
14293
- PopoverContent,
14294
- {
14295
- onOpenAutoFocus: (e) => e.preventDefault(),
14296
- 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",
14297
- children: filteredModels.map((model2) => /* @__PURE__ */ jsxs(
14298
- "div",
14299
- {
14300
- className: "flex items-center gap-2 cursor-pointer hover:bg-surface5 p-2",
14301
- onClick: () => {
14302
- setSelectedModel(model2.model);
14303
- setShowSuggestions(false);
14304
- },
14305
- children: [
14306
- /* @__PURE__ */ jsx(Icon, { children: providerMapToIcon[model2.icon] }),
14307
- model2.model
14308
- ]
14309
- },
14310
- model2.provider + model2.model
14311
- ))
14312
- }
14313
- )
14314
- ] }),
14315
- /* @__PURE__ */ jsxs(Tooltip, { children: [
14316
- /* @__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, {}) }) }) }),
14317
- /* @__PURE__ */ jsx(TooltipContent, { children: loading ? "Saving..." : "Save new model" })
14318
- ] })
14319
- ] }) });
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
+ ] });
14320
14455
  };
14321
14456
 
14322
14457
  const AgentMetadataNetworkList = ({ agents }) => {
@@ -14429,11 +14564,11 @@ const AgentMetadataWorkflowList = ({ workflows }) => {
14429
14564
  };
14430
14565
  const AgentMetadataScorerList = ({ entityId, entityType }) => {
14431
14566
  const { Link, paths } = useLinkComponent();
14432
- const { scorers, isLoading } = useScorers();
14567
+ const { data: scorers = {}, isLoading } = useScorers();
14433
14568
  const scorerList = Object.keys(scorers).filter((scorerKey) => {
14434
14569
  const scorer = scorers[scorerKey];
14435
14570
  if (entityType === "AGENT") {
14436
- return scorer.agentIds.includes(entityId);
14571
+ return scorer.agentNames.includes(entityId);
14437
14572
  }
14438
14573
  return scorer.workflowIds.includes(entityId);
14439
14574
  }).map((scorerKey) => ({ ...scorers[scorerKey], id: scorerKey }));
@@ -16222,7 +16357,7 @@ function TemplateForm({
16222
16357
  "h2",
16223
16358
  {
16224
16359
  className: cn(
16225
- "text-icon5 text-[1.125rem] font-semibold flex items-center gap-[0.5rem]",
16360
+ "text-icon4 text-[1.125rem] font-semibold flex items-center gap-[0.5rem]",
16226
16361
  "[&>svg]:w-[1.2em] [&_svg]:h-[1.2em] [&_svg]:opacity-70 "
16227
16362
  ),
16228
16363
  children: [
@@ -16235,29 +16370,13 @@ function TemplateForm({
16235
16370
  SelectField,
16236
16371
  {
16237
16372
  options: providerOptions,
16238
- label: "Provider",
16373
+ label: "Template AI Model Provider",
16239
16374
  onValueChange: onProviderChange,
16240
16375
  value: selectedProvider,
16241
- placeholder: "Select a provider"
16376
+ placeholder: "Select"
16242
16377
  }
16243
16378
  ),
16244
16379
  selectedProvider && Object.entries(variables || {}).length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
16245
- /* @__PURE__ */ jsxs("div", { className: "space-y-[0.5rem]", children: [
16246
- /* @__PURE__ */ jsx("h3", { className: "text-icon3 text-[0.875rem] font-medium", children: "Select AI Model for Template Installation *" }),
16247
- /* @__PURE__ */ jsx("p", { className: "text-icon4 text-[0.75rem]", children: "This model will be used by the workflow to process and install the template" }),
16248
- /* @__PURE__ */ jsx(
16249
- AgentMetadataModelSwitcher,
16250
- {
16251
- defaultProvider: defaultModelProvider || "",
16252
- defaultModel: defaultModelId || "",
16253
- updateModel: onModelUpdate || (() => Promise.resolve({ message: "Updated" })),
16254
- closeEditor: () => {
16255
- },
16256
- modelProviders: ["openai", "anthropic", "google", "xai", "groq"]
16257
- }
16258
- ),
16259
- (!defaultModelProvider || !defaultModelId) && /* @__PURE__ */ jsx("p", { className: "text-red-500 text-[0.75rem]", children: "Please select an AI model to continue" })
16260
- ] }),
16261
16380
  /* @__PURE__ */ jsx("h3", { className: "text-icon3 text-[0.875rem]", children: "Set required Environmental Variables" }),
16262
16381
  /* @__PURE__ */ jsx("div", { className: "grid grid-cols-[1fr_1fr] gap-[1rem] items-start", children: isLoadingEnvVars ? /* @__PURE__ */ jsxs(
16263
16382
  "div",
@@ -16297,13 +16416,31 @@ function TemplateForm({
16297
16416
  className: "w-full"
16298
16417
  }
16299
16418
  )
16300
- ] }, key)) })
16419
+ ] }, key)) }),
16420
+ /* @__PURE__ */ jsxs("div", { className: "border-t border-border1 pt-[3rem] mt-[0.875rem] relative", children: [
16421
+ /* @__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" }),
16422
+ /* @__PURE__ */ jsx("h3", { className: "text-icon4 text-[1rem]", children: "Set AI Model for Template Installation" }),
16423
+ /* @__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" }),
16424
+ /* @__PURE__ */ jsx(
16425
+ AgentMetadataModelSwitcher,
16426
+ {
16427
+ defaultProvider: defaultModelProvider || "",
16428
+ defaultModel: defaultModelId || "",
16429
+ updateModel: onModelUpdate || (() => Promise.resolve({ message: "Updated" })),
16430
+ closeEditor: () => {
16431
+ },
16432
+ modelProviders: ["openai", "anthropic", "google", "xai", "groq"],
16433
+ autoSave: true,
16434
+ selectProviderPlaceholder: "Provider"
16435
+ }
16436
+ )
16437
+ ] })
16301
16438
  ] }),
16302
16439
  selectedProvider && !isLoadingEnvVars && /* @__PURE__ */ jsxs(
16303
- "button",
16440
+ Button,
16304
16441
  {
16305
16442
  className: cn(
16306
- "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",
16443
+ "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",
16307
16444
  "[&>svg]:w-[1.1em] [&_svg]:h-[1.1em] [&_svg]:text-icon5"
16308
16445
  ),
16309
16446
  onClick: handleInstallTemplate,
@@ -16542,7 +16679,7 @@ function TemplateFailure({ errorMsg, validationErrors }) {
16542
16679
  };
16543
16680
  };
16544
16681
  const { icon, title } = getIconAndTitle();
16545
- return /* @__PURE__ */ jsxs(Container, { className: "space-y-4 text-icon3 mb-[2rem] content-center max-w-2xl mx-auto", children: [
16682
+ return /* @__PURE__ */ jsxs(Container, { className: "space-y-4 text-icon3 mb-[2rem] content-center", children: [
16546
16683
  /* @__PURE__ */ jsxs(
16547
16684
  "div",
16548
16685
  {
@@ -17640,10 +17777,14 @@ function TraceTimeline({
17640
17777
  ) : /* @__PURE__ */ jsx(
17641
17778
  "div",
17642
17779
  {
17643
- className: cn("grid items-start content-start gap-y-[2px]", "xl:gap-x-[1rem] xl:py-[1rem]", {
17644
- "xl:grid-cols-[3fr_auto]": !overallEndTime,
17645
- "xl:grid-cols-[3fr_2fr]": overallEndTime
17646
- }),
17780
+ className: cn(
17781
+ "grid items-start content-start gap-y-[2px] bg-surface2 rounded-lg overflow-hidden pl-[1.5rem] py-[1.5rem]",
17782
+ "xl:gap-x-[1rem] xl:py-[1rem]",
17783
+ {
17784
+ "xl:grid-cols-[3fr_auto]": !overallEndTime,
17785
+ "xl:grid-cols-[3fr_2fr]": overallEndTime
17786
+ }
17787
+ ),
17647
17788
  children: hierarchicalSpans?.map((span) => /* @__PURE__ */ jsx(
17648
17789
  TraceTimelineSpan,
17649
17790
  {
@@ -17917,7 +18058,24 @@ function getSpanInfo({ span, withTraceId = true, withSpanId = true }) {
17917
18058
  return baseInfo;
17918
18059
  }
17919
18060
 
17920
- function SpanDetails({ span }) {
18061
+ const ScoreTable = ({ scores, onItemClick }) => {
18062
+ return /* @__PURE__ */ jsxs(Table$1, { children: [
18063
+ /* @__PURE__ */ jsxs(Thead, { children: [
18064
+ /* @__PURE__ */ jsx(Th, { children: "Type" }),
18065
+ /* @__PURE__ */ jsx(Th, { children: "Scorer" }),
18066
+ /* @__PURE__ */ jsx(Th, { children: "Score" }),
18067
+ /* @__PURE__ */ jsx(Th, { children: "Created At" })
18068
+ ] }),
18069
+ /* @__PURE__ */ jsx(Tbody, { children: scores.map((score) => /* @__PURE__ */ jsxs(Row, { onClick: () => onItemClick(score.scorerName), children: [
18070
+ /* @__PURE__ */ jsx(TxtCell, { children: /* @__PURE__ */ jsx(Badge$1, { children: score.type }) }),
18071
+ /* @__PURE__ */ jsx(TxtCell, { children: score.scorerName }),
18072
+ /* @__PURE__ */ jsx(TxtCell, { children: score.score }),
18073
+ /* @__PURE__ */ jsx(DateTimeCell, { dateTime: new Date(score.createdAt) })
18074
+ ] }, score.scoreId)) })
18075
+ ] });
18076
+ };
18077
+
18078
+ function SpanDetails({ span, onScorerTriggered }) {
17921
18079
  if (!span) {
17922
18080
  return null;
17923
18081
  }
@@ -17925,18 +18083,226 @@ function SpanDetails({ span }) {
17925
18083
  /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Input", codeStr: JSON.stringify(span.input || null, null, 2) }),
17926
18084
  /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Output", codeStr: JSON.stringify(span.output || null, null, 2) }),
17927
18085
  /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Metadata", codeStr: JSON.stringify(span.metadata || null, null, 2) }),
17928
- /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Attributes", codeStr: JSON.stringify(span.attributes || null, null, 2) })
18086
+ /* @__PURE__ */ jsx(SideDialogCodeSection, { title: "Attributes", codeStr: JSON.stringify(span.attributes || null, null, 2) }),
18087
+ span?.links?.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-[2.5rem] pr-[2.5rem]", children: [
18088
+ /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", className: "pb-[1rem]", children: [
18089
+ /* @__PURE__ */ jsx(GaugeIcon, {}),
18090
+ " Scores"
18091
+ ] }),
18092
+ /* @__PURE__ */ jsx("div", { className: "bg-surface2 rounded-lg overflow-hidden border-sm border-border1", children: /* @__PURE__ */ jsx(
18093
+ ScoreTable,
18094
+ {
18095
+ scores: span?.links,
18096
+ onItemClick: (scorerName) => onScorerTriggered(scorerName, span.traceId, span.spanId)
18097
+ }
18098
+ ) })
18099
+ ] })
17929
18100
  ] });
17930
18101
  }
17931
18102
 
18103
+ const DropdownMenu = DropdownMenuPrimitive.Root;
18104
+ const DropdownMenuGroup = DropdownMenuPrimitive.Group;
18105
+ const DropdownMenuPortal = DropdownMenuPrimitive.Portal;
18106
+ const DropdownMenuSub = DropdownMenuPrimitive.Sub;
18107
+ const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup;
18108
+ const DropdownMenuTrigger = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(DropdownMenuPrimitive.Trigger, { ref, className: cn("cursor-pointer focus-visible:rounded", className), ...props, children }));
18109
+ DropdownMenuTrigger.displayName = DropdownMenuPrimitive.Trigger.displayName;
18110
+ const DropdownMenuSubTrigger = React.forwardRef(({ className, inset, children, ...props }, ref) => /* @__PURE__ */ jsxs(
18111
+ DropdownMenuPrimitive.SubTrigger,
18112
+ {
18113
+ ref,
18114
+ className: cn(
18115
+ "focus:bg-accent data-[state=open]:bg-accent flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm",
18116
+ inset && "pl-8",
18117
+ className
18118
+ ),
18119
+ ...props,
18120
+ children: [
18121
+ children,
18122
+ /* @__PURE__ */ jsx(ChevronDown, { className: "ml-auto -rotate-90" })
18123
+ ]
18124
+ }
18125
+ ));
18126
+ DropdownMenuSubTrigger.displayName = DropdownMenuPrimitive.SubTrigger.displayName;
18127
+ const DropdownMenuSubContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
18128
+ DropdownMenuPrimitive.SubContent,
18129
+ {
18130
+ ref,
18131
+ className: cn(
18132
+ "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",
18133
+ className
18134
+ ),
18135
+ ...props
18136
+ }
18137
+ ));
18138
+ DropdownMenuSubContent.displayName = DropdownMenuPrimitive.SubContent.displayName;
18139
+ const DropdownMenuContent = React.forwardRef(({ className, container, sideOffset = 4, ...props }, ref) => {
18140
+ return /* @__PURE__ */ jsx(DropdownMenuPrimitive.Portal, { container, children: /* @__PURE__ */ jsx(
18141
+ DropdownMenuPrimitive.Content,
18142
+ {
18143
+ ref,
18144
+ sideOffset,
18145
+ className: clsx(
18146
+ "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",
18147
+ className
18148
+ ),
18149
+ ...props
18150
+ }
18151
+ ) });
18152
+ });
18153
+ DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
18154
+ const DropdownMenuItem = React.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
18155
+ DropdownMenuPrimitive.Item,
18156
+ {
18157
+ ref,
18158
+ className: cn(
18159
+ "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",
18160
+ inset && "pl-8",
18161
+ className
18162
+ ),
18163
+ ...props
18164
+ }
18165
+ ));
18166
+ DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
18167
+ const DropdownMenuCheckboxItem = React.forwardRef(({ className, children, checked, ...props }, ref) => /* @__PURE__ */ jsxs(
18168
+ DropdownMenuPrimitive.CheckboxItem,
18169
+ {
18170
+ ref,
18171
+ className: cn(
18172
+ "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",
18173
+ className
18174
+ ),
18175
+ checked,
18176
+ ...props,
18177
+ children: [
18178
+ /* @__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, {}) }) }),
18179
+ children
18180
+ ]
18181
+ }
18182
+ ));
18183
+ DropdownMenuCheckboxItem.displayName = DropdownMenuPrimitive.CheckboxItem.displayName;
18184
+ const DropdownMenuRadioItem = React.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
18185
+ DropdownMenuPrimitive.RadioItem,
18186
+ {
18187
+ ref,
18188
+ className: cn(
18189
+ "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",
18190
+ className
18191
+ ),
18192
+ ...props,
18193
+ children: [
18194
+ /* @__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" }) }) }),
18195
+ children
18196
+ ]
18197
+ }
18198
+ ));
18199
+ DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName;
18200
+ const DropdownMenuLabel = React.forwardRef(({ className, inset, ...props }, ref) => /* @__PURE__ */ jsx(
18201
+ DropdownMenuPrimitive.Label,
18202
+ {
18203
+ ref,
18204
+ className: cn("px-2 py-1.5 text-sm font-semibold", inset && "pl-8", className),
18205
+ ...props
18206
+ }
18207
+ ));
18208
+ DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName;
18209
+ const DropdownMenuSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
18210
+ DropdownMenuPrimitive.Separator,
18211
+ {
18212
+ ref,
18213
+ className: cn("popover-dividers-bg -mx-1 my-1 h-px", className),
18214
+ ...props
18215
+ }
18216
+ ));
18217
+ DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
18218
+ const DropdownMenuShortcut = ({ className, ...props }) => {
18219
+ return /* @__PURE__ */ jsx("span", { className: cn("ml-auto text-xs tracking-widest opacity-60", className), ...props });
18220
+ };
18221
+ DropdownMenuShortcut.displayName = "DropdownMenuShortcut";
18222
+ function Dropdown({
18223
+ open,
18224
+ onOpenChange,
18225
+ children,
18226
+ modal
18227
+ }) {
18228
+ return /* @__PURE__ */ jsx(DropdownMenu, { modal, open, onOpenChange, children });
18229
+ }
18230
+ Dropdown.Trigger = DropdownMenuTrigger;
18231
+ Dropdown.Content = DropdownMenuContent;
18232
+ Dropdown.Group = DropdownMenuGroup;
18233
+ Dropdown.Portal = DropdownMenuPortal;
18234
+ Dropdown.Item = DropdownMenuItem;
18235
+ Dropdown.CheckboxItem = DropdownMenuCheckboxItem;
18236
+ Dropdown.RadioItem = DropdownMenuRadioItem;
18237
+ Dropdown.Label = DropdownMenuLabel;
18238
+ Dropdown.Separator = DropdownMenuSeparator;
18239
+ Dropdown.Shortcut = DropdownMenuShortcut;
18240
+ Dropdown.Sub = DropdownMenuSub;
18241
+ Dropdown.SubContent = DropdownMenuSubContent;
18242
+ Dropdown.SubTrigger = DropdownMenuSubTrigger;
18243
+ Dropdown.RadioGroup = DropdownMenuRadioGroup;
18244
+
18245
+ const useTriggerScorer = (onScorerTriggered) => {
18246
+ const client = useMastraClient();
18247
+ return useMutation({
18248
+ mutationFn: async ({ scorerName, traceId, spanId }) => {
18249
+ const response = await client.score({
18250
+ scorerName,
18251
+ targets: [{ traceId, spanId }]
18252
+ });
18253
+ return response;
18254
+ },
18255
+ onSuccess: (_, variables) => {
18256
+ toast.success("Scorer triggered successfully");
18257
+ onScorerTriggered(variables.scorerName, variables.traceId, variables.spanId);
18258
+ },
18259
+ onError: () => {
18260
+ toast.error("Error triggering scorer");
18261
+ }
18262
+ });
18263
+ };
18264
+
18265
+ const ScorersDropdown = ({ trace, spanId, onScorerTriggered, entityType }) => {
18266
+ const { data: scorers = {}, isLoading } = useScorers();
18267
+ const { mutate: triggerScorer, isPending } = useTriggerScorer(onScorerTriggered);
18268
+ let scorerList = Object.entries(scorers).map(([key, scorer]) => ({
18269
+ id: key,
18270
+ name: scorer.scorer.config.name,
18271
+ description: scorer.scorer.config.description,
18272
+ isRegistered: scorer.isRegistered,
18273
+ type: scorer.scorer.config.type
18274
+ })).filter((scorer) => scorer.isRegistered);
18275
+ if (entityType !== "Agent" || spanId) {
18276
+ scorerList = scorerList.filter((scorer) => scorer.type !== "agent");
18277
+ }
18278
+ const isWaiting = isPending || isLoading;
18279
+ return /* @__PURE__ */ jsxs(Dropdown, { children: [
18280
+ /* @__PURE__ */ jsx(Dropdown.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button$1, { variant: "light", disabled: isWaiting, children: [
18281
+ isWaiting ? /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(Spinner, {}) }) : /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(GaugeIcon, {}) }),
18282
+ "Run scorer",
18283
+ /* @__PURE__ */ jsx(Icon, { children: /* @__PURE__ */ jsx(ChevronDown, {}) })
18284
+ ] }) }),
18285
+ /* @__PURE__ */ jsx(Dropdown.Content, { children: scorerList.map((scorer) => /* @__PURE__ */ jsx(
18286
+ Dropdown.Item,
18287
+ {
18288
+ onClick: () => triggerScorer({ scorerName: scorer.name, traceId: trace.traceId, spanId }),
18289
+ children: /* @__PURE__ */ jsx("span", { children: scorer.name })
18290
+ },
18291
+ scorer.id
18292
+ )) })
18293
+ ] });
18294
+ };
18295
+
17932
18296
  function SpanDialog({
18297
+ trace,
17933
18298
  span,
17934
18299
  isOpen,
17935
18300
  onClose,
17936
18301
  onNext,
17937
18302
  onPrevious,
17938
18303
  onViewToggle,
17939
- spanInfo = []
18304
+ spanInfo = [],
18305
+ onScorerTriggered
17940
18306
  }) {
17941
18307
  const { Link } = useLinkComponent();
17942
18308
  return /* @__PURE__ */ jsxs(
@@ -17965,21 +18331,24 @@ function SpanDialog({
17965
18331
  /* @__PURE__ */ jsx("button", { className: "flex items-center gap-1", onClick: onViewToggle, children: /* @__PURE__ */ jsx(PanelTopIcon, {}) })
17966
18332
  ] }),
17967
18333
  /* @__PURE__ */ jsxs("div", { className: "p-[1.5rem] px-[2.5rem] overflow-y-auto grid gap-[1.5rem] content-start", children: [
17968
- /* @__PURE__ */ jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
17969
- /* @__PURE__ */ jsxs(SideDialogHeading, { children: [
17970
- /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
17971
- " ",
17972
- span?.name
18334
+ /* @__PURE__ */ jsxs("div", { children: [
18335
+ /* @__PURE__ */ jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
18336
+ /* @__PURE__ */ jsxs(SideDialogHeading, { children: [
18337
+ /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
18338
+ " ",
18339
+ span?.name
18340
+ ] }),
18341
+ /* @__PURE__ */ jsxs(TextAndIcon, { children: [
18342
+ /* @__PURE__ */ jsx(HashIcon, {}),
18343
+ " ",
18344
+ span?.spanId
18345
+ ] })
17973
18346
  ] }),
17974
- /* @__PURE__ */ jsxs(TextAndIcon, { children: [
17975
- /* @__PURE__ */ jsx(HashIcon, {}),
17976
- " ",
17977
- span?.spanId
17978
- ] })
18347
+ span?.traceId && span?.spanId && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ScorersDropdown, { trace, spanId: span?.spanId, onScorerTriggered }) })
17979
18348
  ] }),
17980
18349
  span?.attributes?.usage && /* @__PURE__ */ jsx(TraceSpanUsage, { spanUsage: span.attributes.usage, className: "mt-[1.5rem]" }),
17981
18350
  /* @__PURE__ */ jsx(KeyValueList, { data: spanInfo, LinkComponent: Link, className: "mt-[1.5rem]" }),
17982
- /* @__PURE__ */ jsx(SpanDetails, { span })
18351
+ /* @__PURE__ */ jsx(SpanDetails, { span, onScorerTriggered })
17983
18352
  ] })
17984
18353
  ]
17985
18354
  }
@@ -17994,11 +18363,15 @@ function TraceDialog({
17994
18363
  onClose,
17995
18364
  onNext,
17996
18365
  onPrevious,
17997
- isLoadingSpans
18366
+ isLoadingSpans,
18367
+ computeAgentsLink,
18368
+ computeWorkflowsLink,
18369
+ onScorerTriggered,
18370
+ initialSpanId
17998
18371
  }) {
17999
18372
  const { Link } = useLinkComponent();
18000
- const [dialogIsOpen, setDialogIsOpen] = useState(false);
18001
- const [selectedSpanId, setSelectedSpanId] = useState(void 0);
18373
+ const [dialogIsOpen, setDialogIsOpen] = useState(Boolean(initialSpanId));
18374
+ const [selectedSpanId, setSelectedSpanId] = useState(initialSpanId);
18002
18375
  const [combinedView, setCombinedView] = useState(false);
18003
18376
  const selectedSpan = traceSpans.find((span) => span.spanId === selectedSpanId);
18004
18377
  const traceInfo = useTraceInfo(traceDetails);
@@ -18046,6 +18419,12 @@ function TraceDialog({
18046
18419
  return currentIndex > 0;
18047
18420
  };
18048
18421
  const selectedSpanInfo = getSpanInfo({ span: selectedSpan, withTraceId: !combinedView, withSpanId: combinedView });
18422
+ let entityType;
18423
+ if (traceDetails?.attributes?.agentId) {
18424
+ entityType = "Agent";
18425
+ } else if (traceDetails?.attributes?.workflowId) {
18426
+ entityType = "Workflow";
18427
+ }
18049
18428
  return /* @__PURE__ */ jsxs(Fragment, { children: [
18050
18429
  /* @__PURE__ */ jsxs(
18051
18430
  SideDialog,
@@ -18069,7 +18448,7 @@ function TraceDialog({
18069
18448
  "grid-rows-[auto_1fr_1fr]": selectedSpan && combinedView
18070
18449
  }),
18071
18450
  children: [
18072
- /* @__PURE__ */ jsxs(SideDialogHeader, { className: "flex gap-[1rem] items-baseline pr-[2.5rem]", children: [
18451
+ /* @__PURE__ */ jsxs(SideDialogHeader, { className: "pr-[2.5rem]", children: [
18073
18452
  /* @__PURE__ */ jsxs(SideDialogHeading, { children: [
18074
18453
  /* @__PURE__ */ jsx(EyeIcon, {}),
18075
18454
  " ",
@@ -18082,6 +18461,15 @@ function TraceDialog({
18082
18461
  ] })
18083
18462
  ] }),
18084
18463
  /* @__PURE__ */ jsxs("div", { className: cn("overflow-y-auto pb-[2.5rem]"), children: [
18464
+ traceDetails && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
18465
+ ScorersDropdown,
18466
+ {
18467
+ trace: traceDetails,
18468
+ spanId: selectedSpanId,
18469
+ onScorerTriggered,
18470
+ entityType
18471
+ }
18472
+ ) }),
18085
18473
  traceDetails?.metadata?.usage && /* @__PURE__ */ jsx(
18086
18474
  TraceSpanUsage,
18087
18475
  {
@@ -18101,7 +18489,20 @@ function TraceDialog({
18101
18489
  isLoading: isLoadingSpans,
18102
18490
  className: "pr-[2.5rem] pt-[2.5rem]"
18103
18491
  }
18104
- )
18492
+ ),
18493
+ traceDetails?.links?.length > 0 && /* @__PURE__ */ jsxs("div", { className: "pt-[2.5rem] pr-[2.5rem]", children: [
18494
+ /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", className: "pb-[1rem]", children: [
18495
+ /* @__PURE__ */ jsx(GaugeIcon, {}),
18496
+ " Scores"
18497
+ ] }),
18498
+ /* @__PURE__ */ jsx("div", { className: "bg-surface2 rounded-lg overflow-hidden border-sm border-border1", children: /* @__PURE__ */ jsx(
18499
+ ScoreTable,
18500
+ {
18501
+ scores: traceDetails?.links,
18502
+ onItemClick: (scorerName) => onScorerTriggered(scorerName, traceDetails.traceId, selectedSpanId)
18503
+ }
18504
+ ) })
18505
+ ] })
18105
18506
  ] }),
18106
18507
  selectedSpan && combinedView && /* @__PURE__ */ jsxs("div", { className: "overflow-y-auto grid grid-rows-[auto_1fr] relative", children: [
18107
18508
  /* @__PURE__ */ jsx("div", { className: "absolute left-0 right-[2.5rem] h-[.5rem] bg-surface1 rounded-full top-0" }),
@@ -18132,11 +18533,11 @@ function TraceDialog({
18132
18533
  ] }),
18133
18534
  /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[20rem_1fr] gap-[1rem] overflow-y-auto", children: [
18134
18535
  /* @__PURE__ */ jsxs("div", { className: "overflow-y-auto grid content-start p-[1.5rem] pl-0 gap-[2rem]", children: [
18135
- /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", children: [
18536
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsxs(SideDialogHeading, { as: "h2", children: [
18136
18537
  /* @__PURE__ */ jsx(ChevronsLeftRightEllipsisIcon, {}),
18137
18538
  " ",
18138
18539
  selectedSpan?.name
18139
- ] }),
18540
+ ] }) }),
18140
18541
  selectedSpan?.attributes?.usage && /* @__PURE__ */ jsx(
18141
18542
  TraceSpanUsage,
18142
18543
  {
@@ -18146,7 +18547,7 @@ function TraceDialog({
18146
18547
  ),
18147
18548
  /* @__PURE__ */ jsx(KeyValueList, { data: selectedSpanInfo, LinkComponent: Link })
18148
18549
  ] }),
18149
- /* @__PURE__ */ jsx("div", { className: "overflow-y-auto pr-[2.5rem] pt-[2rem]", children: /* @__PURE__ */ jsx(SpanDetails, { span: selectedSpan }) })
18550
+ /* @__PURE__ */ jsx("div", { className: "overflow-y-auto pr-[2.5rem] pt-[2rem]", children: /* @__PURE__ */ jsx(SpanDetails, { span: selectedSpan, onScorerTriggered }) })
18150
18551
  ] })
18151
18552
  ] })
18152
18553
  ]
@@ -18155,16 +18556,21 @@ function TraceDialog({
18155
18556
  ]
18156
18557
  }
18157
18558
  ),
18158
- /* @__PURE__ */ jsx(
18559
+ traceDetails && /* @__PURE__ */ jsx(
18159
18560
  SpanDialog,
18160
18561
  {
18562
+ trace: traceDetails,
18161
18563
  span: selectedSpan,
18162
18564
  isOpen: Boolean(dialogIsOpen && selectedSpanId && !combinedView),
18163
- onClose: () => setDialogIsOpen(false),
18565
+ onClose: () => {
18566
+ setDialogIsOpen(false);
18567
+ setSelectedSpanId(void 0);
18568
+ },
18164
18569
  onNext: thereIsNextSpan() ? toNextSpan : void 0,
18165
18570
  onPrevious: thereIsPreviousSpan() ? toPreviousSpan : void 0,
18166
18571
  onViewToggle: () => setCombinedView(!combinedView),
18167
- spanInfo: selectedSpanInfo
18572
+ spanInfo: selectedSpanInfo,
18573
+ onScorerTriggered
18168
18574
  }
18169
18575
  )
18170
18576
  ] });