@mastra/playground-ui 5.0.2-alpha.1 → 5.0.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.
@@ -1,6 +1,11 @@
1
+ import { RefinedTrace } from '../../traces/types';
2
+
1
3
  export interface AgentTracesProps {
2
- agentName: string;
3
- baseUrl: string;
4
4
  className?: string;
5
+ traces: RefinedTrace[];
6
+ isLoading: boolean;
7
+ error: {
8
+ message: string;
9
+ } | null;
5
10
  }
6
- export declare function AgentTraces({ agentName, baseUrl, className }: AgentTracesProps): import("react/jsx-runtime").JSX.Element;
11
+ export declare function AgentTraces({ className, traces, isLoading, error }: AgentTracesProps): import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,10 @@
1
+ import { RefinedTrace } from '../../traces/types';
2
+
1
3
  export interface WorkflowTracesProps {
2
- workflowName: string;
3
- baseUrl: string;
4
+ traces: RefinedTrace[];
5
+ isLoading: boolean;
6
+ error: {
7
+ message: string;
8
+ } | null;
4
9
  }
5
- export declare function WorkflowTraces({ workflowName, baseUrl }: WorkflowTracesProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare function WorkflowTraces({ traces, isLoading, error }: WorkflowTracesProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export * from './use-traces';
package/dist/index.cjs.js CHANGED
@@ -4882,229 +4882,6 @@ function TraceProvider({ children }) {
4882
4882
  );
4883
4883
  }
4884
4884
 
4885
- function usePolling({
4886
- fetchFn,
4887
- interval = 3e3,
4888
- enabled = false,
4889
- onSuccess,
4890
- onError,
4891
- shouldContinue = () => true,
4892
- restartPolling = false
4893
- }) {
4894
- const [isPolling, setIsPolling] = React.useState(enabled);
4895
- const [error, setError] = React.useState(null);
4896
- const [data, setData] = React.useState(null);
4897
- const [isLoading, setIsLoading] = React.useState(false);
4898
- const [firstCallLoading, setFirstCallLoading] = React.useState(false);
4899
- const timeoutRef = React.useRef(null);
4900
- const mountedRef = React.useRef(true);
4901
- const [restart, setRestart] = React.useState(restartPolling);
4902
- const cleanup = React.useCallback(() => {
4903
- console.log("cleanup");
4904
- if (timeoutRef.current) {
4905
- clearTimeout(timeoutRef.current);
4906
- timeoutRef.current = null;
4907
- }
4908
- }, []);
4909
- const stopPolling = React.useCallback(() => {
4910
- console.log("stopPolling");
4911
- setIsPolling(false);
4912
- cleanup();
4913
- }, [cleanup]);
4914
- const startPolling = React.useCallback(() => {
4915
- console.log("startPolling");
4916
- setIsPolling(true);
4917
- setError(null);
4918
- }, []);
4919
- const executePoll = React.useCallback(
4920
- async (refetch2 = true) => {
4921
- if (!mountedRef.current) return;
4922
- setIsLoading(true);
4923
- try {
4924
- const result = await fetchFn();
4925
- setData(result);
4926
- setError(null);
4927
- onSuccess?.(result);
4928
- if (shouldContinue(result) && refetch2) {
4929
- timeoutRef.current = setTimeout(executePoll, interval);
4930
- } else {
4931
- stopPolling();
4932
- }
4933
- } catch (err) {
4934
- if (!mountedRef.current) return;
4935
- setError(err);
4936
- onError?.(err);
4937
- stopPolling();
4938
- } finally {
4939
- if (mountedRef.current) {
4940
- setFirstCallLoading(false);
4941
- setIsLoading(false);
4942
- }
4943
- }
4944
- },
4945
- [fetchFn, interval, onSuccess, onError, shouldContinue, stopPolling]
4946
- );
4947
- const refetch = React.useCallback(
4948
- (withPolling = false) => {
4949
- console.log("refetch", { withPolling });
4950
- if (withPolling) {
4951
- setIsPolling(true);
4952
- } else {
4953
- executePoll(false);
4954
- }
4955
- setError(null);
4956
- },
4957
- [executePoll]
4958
- );
4959
- React.useEffect(() => {
4960
- mountedRef.current = true;
4961
- if (enabled && isPolling) {
4962
- executePoll(true);
4963
- }
4964
- return () => {
4965
- console.log("cleanup poll");
4966
- mountedRef.current = false;
4967
- cleanup();
4968
- };
4969
- }, [enabled, isPolling, executePoll, cleanup]);
4970
- React.useEffect(() => {
4971
- setRestart(restartPolling);
4972
- }, [restartPolling]);
4973
- React.useEffect(() => {
4974
- if (restart && !isPolling) {
4975
- setIsPolling(true);
4976
- executePoll();
4977
- setRestart(false);
4978
- }
4979
- }, [restart]);
4980
- return {
4981
- isPolling,
4982
- isLoading,
4983
- error,
4984
- data,
4985
- startPolling,
4986
- stopPolling,
4987
- firstCallLoading,
4988
- refetch
4989
- };
4990
- }
4991
-
4992
- function formatOtelTimestamp(otelTimestamp) {
4993
- const date = new Date(otelTimestamp / 1e3);
4994
- return new Intl.DateTimeFormat("en-US", {
4995
- month: "numeric",
4996
- day: "numeric",
4997
- year: "numeric",
4998
- hour: "numeric",
4999
- minute: "numeric",
5000
- second: "numeric",
5001
- hour12: true
5002
- }).format(date);
5003
- }
5004
- function formatOtelTimestamp2(otelTimestamp) {
5005
- const date = new Date(otelTimestamp / 1e6);
5006
- return new Intl.DateTimeFormat("en-US", {
5007
- month: "numeric",
5008
- day: "numeric",
5009
- year: "numeric",
5010
- hour: "numeric",
5011
- minute: "numeric",
5012
- second: "numeric",
5013
- hour12: true
5014
- }).format(date);
5015
- }
5016
- function transformKey(key) {
5017
- if (key.includes(".argument.")) {
5018
- return `Input`;
5019
- }
5020
- if (key.includes(".result")) {
5021
- return "Output";
5022
- }
5023
- const newKey = key.split(".").join(" ").split("_").join(" ").replaceAll("ai", "AI");
5024
- return newKey.substring(0, 1).toUpperCase() + newKey.substring(1);
5025
- }
5026
- const refineTraces = (traces, isWorkflow = false) => {
5027
- const listOfSpanIds = /* @__PURE__ */ new Set();
5028
- const newName = (name) => {
5029
- if (name?.startsWith("workflow.") && isWorkflow) {
5030
- return name?.split(".")?.slice(2)?.join(".");
5031
- }
5032
- if (name?.startsWith("agent.") && !isWorkflow) {
5033
- return name?.split(".")?.slice(1)?.join(".");
5034
- }
5035
- return name;
5036
- };
5037
- const groupedTraces = traces?.reduce((acc, curr) => {
5038
- const newCurr = { ...curr, name: newName(curr.name), duration: curr.endTime - curr.startTime };
5039
- listOfSpanIds.add(curr.id);
5040
- return { ...acc, [curr.traceId]: [...acc[curr.traceId] || [], newCurr] };
5041
- }, {});
5042
- const tracesData = Object.entries(groupedTraces).map(([key, value]) => {
5043
- const parentSpan = value.find((span) => !span.parentSpanId || !listOfSpanIds.has(span.parentSpanId));
5044
- const enrichedSpans = value.map((span) => ({
5045
- ...span,
5046
- parentSpanId: parentSpan?.id === span.id ? null : span?.parentSpanId,
5047
- relativePercentage: parentSpan ? span.duration / parentSpan.duration : 0
5048
- }));
5049
- const failedStatus = value.find((span) => span.status.code !== 0)?.status;
5050
- return {
5051
- traceId: key,
5052
- serviceName: parentSpan?.name || key,
5053
- duration: parentSpan?.duration || value.reduce((acc, curr) => acc + curr.duration, 0),
5054
- status: failedStatus || parentSpan?.status || value[0].status,
5055
- started: value[0].startTime,
5056
- trace: enrichedSpans
5057
- };
5058
- });
5059
- return tracesData;
5060
- };
5061
-
5062
- const useTraces = (componentName, baseUrl, isWorkflow = false) => {
5063
- const [traces, setTraces] = React.useState([]);
5064
- const { setTraces: setTraceContextTraces } = React.useContext(TraceContext);
5065
- const client = React.useMemo(() => createMastraClient(baseUrl), [baseUrl]);
5066
- const fetchFn = React.useCallback(async () => {
5067
- try {
5068
- const res = await client.getTelemetry({
5069
- attribute: {
5070
- componentName
5071
- }
5072
- });
5073
- if (!res.traces) {
5074
- throw new Error("Error fetching traces");
5075
- }
5076
- const refinedTraces = refineTraces(res?.traces || [], isWorkflow);
5077
- return refinedTraces;
5078
- } catch (error2) {
5079
- throw error2;
5080
- }
5081
- }, [client, componentName, isWorkflow]);
5082
- const onSuccess = React.useCallback(
5083
- (newTraces) => {
5084
- if (newTraces.length > 0) {
5085
- setTraces(() => newTraces);
5086
- setTraceContextTraces(() => newTraces);
5087
- }
5088
- },
5089
- [setTraceContextTraces]
5090
- );
5091
- const onError = React.useCallback((error2) => {
5092
- sonner.toast.error(error2.message);
5093
- }, []);
5094
- const shouldContinue = React.useCallback(() => {
5095
- return true;
5096
- }, []);
5097
- const { firstCallLoading, error } = usePolling({
5098
- fetchFn,
5099
- interval: 3e3,
5100
- onSuccess,
5101
- onError,
5102
- shouldContinue,
5103
- enabled: true
5104
- });
5105
- return { traces, firstCallLoading, error };
5106
- };
5107
-
5108
4885
  const rowSize = {
5109
4886
  default: "[&>tbody>tr]:h-table-row",
5110
4887
  small: "[&>tbody>tr]:h-table-row-small"
@@ -5226,6 +5003,10 @@ const useOpenTrace = () => {
5226
5003
  return { openTrace };
5227
5004
  };
5228
5005
 
5006
+ const toSigFigs = (num, sigFigs) => {
5007
+ return Number(num.toPrecision(sigFigs));
5008
+ };
5009
+
5229
5010
  const TracesTableSkeleton = ({ colsCount }) => {
5230
5011
  return /* @__PURE__ */ jsxRuntime.jsx(Tbody, { children: /* @__PURE__ */ jsxRuntime.jsx(Row, { children: Array.from({ length: colsCount }).map((_, index) => /* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsx(Skeleton, { className: "w-1/2" }) }, index)) }) });
5231
5012
  };
@@ -5244,7 +5025,7 @@ const TraceRow = ({ trace, index, isActive }) => {
5244
5025
  trace.traceId.substring(0, 7),
5245
5026
  "..."
5246
5027
  ] }),
5247
- /* @__PURE__ */ jsxRuntime.jsx(UnitCell, { unit: "ms", children: Math.round(trace.duration / 1e3) }),
5028
+ /* @__PURE__ */ jsxRuntime.jsx(UnitCell, { unit: "ms", children: toSigFigs(trace.duration / 1e3, 3) }),
5248
5029
  /* @__PURE__ */ jsxRuntime.jsx(Cell, { children: /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => openTrace(trace.trace, index), children: /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { icon: /* @__PURE__ */ jsxRuntime.jsx(TraceIcon, {}), children: trace.trace.length }) }) }),
5249
5030
  /* @__PURE__ */ jsxRuntime.jsx(Cell, { children: hasFailure ? /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, {}), children: "Failed" }) : /* @__PURE__ */ jsxRuntime.jsx(Badge$1, { icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, {}), variant: "success", children: "Success" }) })
5250
5031
  ] });
@@ -5381,11 +5162,12 @@ const variantClasses = {
5381
5162
  };
5382
5163
  const Time = ({ durationMs, tokenCount, variant, progressPercent }) => {
5383
5164
  const variantClass = variant ? variantClasses[variant] : "bg-accent3";
5165
+ const percent = Math.min(100, progressPercent);
5384
5166
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-[80px] xl:w-[166px] shrink-0", children: [
5385
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface4 relative h-[6px] w-full rounded-full p-px overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx("absolute h-1 rounded-full", variantClass), style: { width: `${progressPercent}%` } }) }),
5167
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "bg-surface4 relative h-[6px] w-full rounded-full p-px overflow-hidden", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: clsx("absolute h-1 rounded-full", variantClass), style: { width: `${percent}%` } }) }),
5386
5168
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 pt-0.5", children: [
5387
5169
  /* @__PURE__ */ jsxRuntime.jsxs(Txt, { variant: "ui-sm", className: "text-icon2 font-medium", children: [
5388
- Math.round(durationMs),
5170
+ toSigFigs(durationMs, 3),
5389
5171
  "ms"
5390
5172
  ] }),
5391
5173
  tokenCount && /* @__PURE__ */ jsxRuntime.jsxs(Txt, { variant: "ui-sm", className: "text-icon2 font-medium", children: [
@@ -5620,6 +5402,76 @@ const SyntaxHighlighter = ({ data }) => {
5620
5402
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md bg-[#1a1a1a] p-1 font-mono", children: /* @__PURE__ */ jsxRuntime.jsx(CodeMirror, { value: formattedCode, theme, extensions: [langJson.jsonLanguage] }) });
5621
5403
  };
5622
5404
 
5405
+ function formatOtelTimestamp(otelTimestamp) {
5406
+ const date = new Date(otelTimestamp / 1e3);
5407
+ return new Intl.DateTimeFormat("en-US", {
5408
+ month: "numeric",
5409
+ day: "numeric",
5410
+ year: "numeric",
5411
+ hour: "numeric",
5412
+ minute: "numeric",
5413
+ second: "numeric",
5414
+ hour12: true
5415
+ }).format(date);
5416
+ }
5417
+ function formatOtelTimestamp2(otelTimestamp) {
5418
+ const date = new Date(otelTimestamp / 1e6);
5419
+ return new Intl.DateTimeFormat("en-US", {
5420
+ month: "numeric",
5421
+ day: "numeric",
5422
+ year: "numeric",
5423
+ hour: "numeric",
5424
+ minute: "numeric",
5425
+ second: "numeric",
5426
+ hour12: true
5427
+ }).format(date);
5428
+ }
5429
+ function transformKey(key) {
5430
+ if (key.includes(".argument.")) {
5431
+ return `Input`;
5432
+ }
5433
+ if (key.includes(".result")) {
5434
+ return "Output";
5435
+ }
5436
+ const newKey = key.split(".").join(" ").split("_").join(" ").replaceAll("ai", "AI");
5437
+ return newKey.substring(0, 1).toUpperCase() + newKey.substring(1);
5438
+ }
5439
+ const refineTraces = (traces, isWorkflow = false) => {
5440
+ const listOfSpanIds = /* @__PURE__ */ new Set();
5441
+ const newName = (name) => {
5442
+ if (name?.startsWith("workflow.") && isWorkflow) {
5443
+ return name?.split(".")?.slice(2)?.join(".");
5444
+ }
5445
+ if (name?.startsWith("agent.") && !isWorkflow) {
5446
+ return name?.split(".")?.slice(1)?.join(".");
5447
+ }
5448
+ return name;
5449
+ };
5450
+ const groupedTraces = traces?.reduce((acc, curr) => {
5451
+ const newCurr = { ...curr, name: newName(curr.name), duration: curr.endTime - curr.startTime };
5452
+ listOfSpanIds.add(curr.id);
5453
+ return { ...acc, [curr.traceId]: [...acc[curr.traceId] || [], newCurr] };
5454
+ }, {});
5455
+ const tracesData = Object.entries(groupedTraces).map(([key, value]) => {
5456
+ const parentSpan = value.find((span) => !span.parentSpanId || !listOfSpanIds.has(span.parentSpanId));
5457
+ const enrichedSpans = value.map((span) => ({
5458
+ ...span,
5459
+ parentSpanId: parentSpan?.id === span.id ? null : span?.parentSpanId,
5460
+ relativePercentage: parentSpan ? span.duration / parentSpan.duration : 0
5461
+ }));
5462
+ const failedStatus = value.find((span) => span.status.code !== 0)?.status;
5463
+ return {
5464
+ traceId: key,
5465
+ serviceName: parentSpan?.name || key,
5466
+ duration: parentSpan?.duration || value.reduce((acc, curr) => acc + curr.duration, 0),
5467
+ status: failedStatus || parentSpan?.status || value[0].status,
5468
+ started: value[0].startTime,
5469
+ trace: enrichedSpans
5470
+ };
5471
+ });
5472
+ return tracesData;
5473
+ };
5474
+
5623
5475
  function SpanDetail() {
5624
5476
  const { span, setSpan, trace, setIsOpen } = React.useContext(TraceContext);
5625
5477
  if (!span || !trace) return null;
@@ -5655,11 +5507,11 @@ function SpanDetail() {
5655
5507
  span.name
5656
5508
  ] }),
5657
5509
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-row gap-2 items-center", children: span.status.code === 0 ? /* @__PURE__ */ jsxRuntime.jsxs(Badge$1, { icon: /* @__PURE__ */ jsxRuntime.jsx(LatencyIcon, {}), variant: "success", children: [
5658
- Math.round(span.duration / 1e3),
5510
+ toSigFigs(span.duration / 1e3, 3),
5659
5511
  "ms"
5660
5512
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, {}), children: [
5661
5513
  "Failed in ",
5662
- Math.round(span.duration / 1e3),
5514
+ toSigFigs(span.duration / 1e3, 3),
5663
5515
  "ms"
5664
5516
  ] }) }),
5665
5517
  /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "border-border1 border-sm my-5" }),
@@ -5745,15 +5597,14 @@ const TracesSidebar = ({ onResize }) => {
5745
5597
  );
5746
5598
  };
5747
5599
 
5748
- function AgentTraces({ agentName, baseUrl, className }) {
5749
- return /* @__PURE__ */ jsxRuntime.jsx(TraceProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(AgentTracesInner, { agentName, baseUrl, className }) });
5600
+ function AgentTraces({ className, traces, isLoading, error }) {
5601
+ return /* @__PURE__ */ jsxRuntime.jsx(AgentTracesInner, { className, traces, isLoading, error });
5750
5602
  }
5751
- function AgentTracesInner({ agentName, baseUrl, className }) {
5603
+ function AgentTracesInner({ className, traces, isLoading, error }) {
5752
5604
  const [sidebarWidth, setSidebarWidth] = React.useState(100);
5753
- const { traces, firstCallLoading, error } = useTraces(agentName, baseUrl);
5754
5605
  const { isOpen: open } = React.useContext(TraceContext);
5755
5606
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx("h-full relative overflow-hidden flex", className), children: [
5756
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsxRuntime.jsx(TracesTable, { traces, isLoading: firstCallLoading, error }) }),
5607
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsxRuntime.jsx(TracesTable, { traces, isLoading, error }) }),
5757
5608
  open && /* @__PURE__ */ jsxRuntime.jsx(TracesSidebar, { width: sidebarWidth, onResize: setSidebarWidth })
5758
5609
  ] });
5759
5610
  }
@@ -6205,15 +6056,14 @@ const NetworkChat = ({ agentId, memory }) => {
6205
6056
  return /* @__PURE__ */ jsxRuntime.jsx(MastraNetworkRuntimeProvider, { agentId, memory, modelSettings, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full pb-4", children: /* @__PURE__ */ jsxRuntime.jsx(Thread, { ToolFallback }) }) });
6206
6057
  };
6207
6058
 
6208
- function WorkflowTraces({ workflowName, baseUrl }) {
6209
- return /* @__PURE__ */ jsxRuntime.jsx(TraceProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(WorkflowTracesInner, { workflowName, baseUrl }) });
6059
+ function WorkflowTraces({ traces, isLoading, error }) {
6060
+ return /* @__PURE__ */ jsxRuntime.jsx(WorkflowTracesInner, { traces, isLoading, error });
6210
6061
  }
6211
- function WorkflowTracesInner({ workflowName, baseUrl }) {
6062
+ function WorkflowTracesInner({ traces, isLoading, error }) {
6212
6063
  const [sidebarWidth, setSidebarWidth] = React.useState(100);
6213
- const { traces, error, firstCallLoading } = useTraces(workflowName, baseUrl, true);
6214
6064
  const { isOpen: open } = React.useContext(TraceContext);
6215
6065
  return /* @__PURE__ */ jsxRuntime.jsxs("main", { className: "h-full relative overflow-hidden flex", children: [
6216
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsxRuntime.jsx(TracesTable, { traces, isLoading: firstCallLoading, error }) }),
6066
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsxRuntime.jsx(TracesTable, { traces, isLoading, error }) }),
6217
6067
  open && /* @__PURE__ */ jsxRuntime.jsx(TracesSidebar, { width: sidebarWidth, onResize: setSidebarWidth })
6218
6068
  ] });
6219
6069
  }
@@ -8240,6 +8090,12 @@ class CustomZodProvider extends zod.ZodProvider {
8240
8090
  }
8241
8091
  }
8242
8092
 
8093
+ function isEmptyZodObject(schema) {
8094
+ if (schema instanceof z.ZodObject) {
8095
+ return Object.keys(schema.shape).length === 0;
8096
+ }
8097
+ return false;
8098
+ }
8243
8099
  function DynamicForm({
8244
8100
  schema,
8245
8101
  onSubmit,
@@ -8252,6 +8108,9 @@ function DynamicForm({
8252
8108
  return null;
8253
8109
  }
8254
8110
  const normalizedSchema = (schema2) => {
8111
+ if (isEmptyZodObject(schema2)) {
8112
+ return z.object({});
8113
+ }
8255
8114
  return z.object({
8256
8115
  "​": schema2
8257
8116
  });
@@ -8260,7 +8119,7 @@ function DynamicForm({
8260
8119
  const formProps = {
8261
8120
  schema: schemaProvider,
8262
8121
  onSubmit: async (values) => {
8263
- await onSubmit(values["​"]);
8122
+ await onSubmit(values?.["​"] || {});
8264
8123
  },
8265
8124
  defaultValues: defaultValues ? { "​": defaultValues } : void 0,
8266
8125
  formProps: {
@@ -8942,6 +8801,160 @@ const DarkLogo = (props) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "100
8942
8801
  )
8943
8802
  ] });
8944
8803
 
8804
+ function usePolling({
8805
+ fetchFn,
8806
+ interval = 3e3,
8807
+ enabled = false,
8808
+ onSuccess,
8809
+ onError,
8810
+ shouldContinue = () => true,
8811
+ restartPolling = false
8812
+ }) {
8813
+ const [isPolling, setIsPolling] = React.useState(enabled);
8814
+ const [error, setError] = React.useState(null);
8815
+ const [data, setData] = React.useState(null);
8816
+ const [isLoading, setIsLoading] = React.useState(false);
8817
+ const [firstCallLoading, setFirstCallLoading] = React.useState(false);
8818
+ const timeoutRef = React.useRef(null);
8819
+ const mountedRef = React.useRef(true);
8820
+ const [restart, setRestart] = React.useState(restartPolling);
8821
+ const cleanup = React.useCallback(() => {
8822
+ console.log("cleanup");
8823
+ if (timeoutRef.current) {
8824
+ clearTimeout(timeoutRef.current);
8825
+ timeoutRef.current = null;
8826
+ }
8827
+ }, []);
8828
+ const stopPolling = React.useCallback(() => {
8829
+ console.log("stopPolling");
8830
+ setIsPolling(false);
8831
+ cleanup();
8832
+ }, [cleanup]);
8833
+ const startPolling = React.useCallback(() => {
8834
+ console.log("startPolling");
8835
+ setIsPolling(true);
8836
+ setError(null);
8837
+ }, []);
8838
+ const executePoll = React.useCallback(
8839
+ async (refetch2 = true) => {
8840
+ if (!mountedRef.current) return;
8841
+ setIsLoading(true);
8842
+ try {
8843
+ const result = await fetchFn();
8844
+ setData(result);
8845
+ setError(null);
8846
+ onSuccess?.(result);
8847
+ if (shouldContinue(result) && refetch2) {
8848
+ timeoutRef.current = setTimeout(executePoll, interval);
8849
+ } else {
8850
+ stopPolling();
8851
+ }
8852
+ } catch (err) {
8853
+ if (!mountedRef.current) return;
8854
+ setError(err);
8855
+ onError?.(err);
8856
+ stopPolling();
8857
+ } finally {
8858
+ if (mountedRef.current) {
8859
+ setFirstCallLoading(false);
8860
+ setIsLoading(false);
8861
+ }
8862
+ }
8863
+ },
8864
+ [fetchFn, interval, onSuccess, onError, shouldContinue, stopPolling]
8865
+ );
8866
+ const refetch = React.useCallback(
8867
+ (withPolling = false) => {
8868
+ console.log("refetch", { withPolling });
8869
+ if (withPolling) {
8870
+ setIsPolling(true);
8871
+ } else {
8872
+ executePoll(false);
8873
+ }
8874
+ setError(null);
8875
+ },
8876
+ [executePoll]
8877
+ );
8878
+ React.useEffect(() => {
8879
+ mountedRef.current = true;
8880
+ if (enabled && isPolling) {
8881
+ executePoll(true);
8882
+ }
8883
+ return () => {
8884
+ console.log("cleanup poll");
8885
+ mountedRef.current = false;
8886
+ cleanup();
8887
+ };
8888
+ }, [enabled, isPolling, executePoll, cleanup]);
8889
+ React.useEffect(() => {
8890
+ setRestart(restartPolling);
8891
+ }, [restartPolling]);
8892
+ React.useEffect(() => {
8893
+ if (restart && !isPolling) {
8894
+ setIsPolling(true);
8895
+ executePoll();
8896
+ setRestart(false);
8897
+ }
8898
+ }, [restart]);
8899
+ return {
8900
+ isPolling,
8901
+ isLoading,
8902
+ error,
8903
+ data,
8904
+ startPolling,
8905
+ stopPolling,
8906
+ firstCallLoading,
8907
+ refetch
8908
+ };
8909
+ }
8910
+
8911
+ const useTraces = (componentName, baseUrl, isWorkflow = false) => {
8912
+ const [traces, setTraces] = React.useState([]);
8913
+ const { setTraces: setTraceContextTraces } = React.useContext(TraceContext);
8914
+ const client = React.useMemo(() => createMastraClient(baseUrl), [baseUrl]);
8915
+ const fetchFn = React.useCallback(async () => {
8916
+ try {
8917
+ const res = await client.getTelemetry({
8918
+ attribute: {
8919
+ componentName
8920
+ }
8921
+ });
8922
+ if (!res.traces) {
8923
+ throw new Error("Error fetching traces");
8924
+ }
8925
+ const refinedTraces = refineTraces(res?.traces || [], isWorkflow);
8926
+ return refinedTraces;
8927
+ } catch (error2) {
8928
+ throw error2;
8929
+ }
8930
+ }, [client, componentName, isWorkflow]);
8931
+ const onSuccess = React.useCallback(
8932
+ (newTraces) => {
8933
+ if (newTraces.length > 0) {
8934
+ setTraces(() => newTraces);
8935
+ setTraceContextTraces(() => newTraces);
8936
+ }
8937
+ },
8938
+ [setTraceContextTraces]
8939
+ );
8940
+ const onError = React.useCallback((error2) => {
8941
+ console.log(`error, onError`, error2);
8942
+ sonner.toast.error(error2.message);
8943
+ }, []);
8944
+ const shouldContinue = React.useCallback(() => {
8945
+ return true;
8946
+ }, []);
8947
+ const { firstCallLoading, error } = usePolling({
8948
+ fetchFn,
8949
+ interval: 3e3,
8950
+ onSuccess,
8951
+ onError,
8952
+ shouldContinue,
8953
+ enabled: true
8954
+ });
8955
+ return { traces, firstCallLoading, error };
8956
+ };
8957
+
8945
8958
  exports.AgentChat = AgentChat;
8946
8959
  exports.AgentCoinIcon = AgentCoinIcon;
8947
8960
  exports.AgentContext = AgentContext;
@@ -9004,7 +9017,9 @@ exports.Tbody = Tbody;
9004
9017
  exports.Th = Th;
9005
9018
  exports.Thead = Thead;
9006
9019
  exports.ToolsIcon = ToolsIcon;
9020
+ exports.TraceContext = TraceContext;
9007
9021
  exports.TraceIcon = TraceIcon;
9022
+ exports.TraceProvider = TraceProvider;
9008
9023
  exports.TsIcon = TsIcon;
9009
9024
  exports.Txt = Txt;
9010
9025
  exports.TxtCell = TxtCell;
@@ -9019,4 +9034,6 @@ exports.WorkflowRunContext = WorkflowRunContext;
9019
9034
  exports.WorkflowRunProvider = WorkflowRunProvider;
9020
9035
  exports.WorkflowTraces = WorkflowTraces;
9021
9036
  exports.WorkflowTrigger = WorkflowTrigger;
9037
+ exports.refineTraces = refineTraces;
9038
+ exports.useTraces = useTraces;
9022
9039
  //# sourceMappingURL=index.cjs.js.map