@mastra/playground-ui 5.0.2-alpha.0 → 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.
- package/dist/components/assistant-ui/thread.d.ts +5 -1
- package/dist/domains/agents/agent/agent-traces.d.ts +8 -3
- package/dist/domains/workflows/workflow/workflow-traces.d.ts +8 -3
- package/dist/hooks/index.d.ts +1 -0
- package/dist/index.cjs.js +271 -244
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.es.js +269 -246
- package/dist/index.es.js.map +1 -1
- package/dist/lib/number.d.ts +1 -0
- package/package.json +3 -3
|
@@ -2,5 +2,9 @@ import { ToolCallContentPartComponent } from '@assistant-ui/react';
|
|
|
2
2
|
|
|
3
3
|
export interface ThreadProps {
|
|
4
4
|
ToolFallback?: ToolCallContentPartComponent;
|
|
5
|
+
agentName?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare const Thread: ({ ToolFallback, agentName }: ThreadProps) => import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export interface ThreadWelcomeProps {
|
|
9
|
+
agentName?: string;
|
|
5
10
|
}
|
|
6
|
-
export declare const Thread: ({ ToolFallback }: ThreadProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -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({
|
|
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
|
-
|
|
3
|
-
|
|
4
|
+
traces: RefinedTrace[];
|
|
5
|
+
isLoading: boolean;
|
|
6
|
+
error: {
|
|
7
|
+
message: string;
|
|
8
|
+
} | null;
|
|
4
9
|
}
|
|
5
|
-
export declare function WorkflowTraces({
|
|
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
|
@@ -3948,7 +3948,7 @@ const useAutoscroll = (ref, { enabled = true }) => {
|
|
|
3948
3948
|
}, [enabled, ref]);
|
|
3949
3949
|
};
|
|
3950
3950
|
|
|
3951
|
-
const Thread = ({ ToolFallback }) => {
|
|
3951
|
+
const Thread = ({ ToolFallback, agentName }) => {
|
|
3952
3952
|
const areaRef = React.useRef(null);
|
|
3953
3953
|
useAutoscroll(areaRef, { enabled: true });
|
|
3954
3954
|
const WrappedAssistantMessage = (props) => {
|
|
@@ -3957,7 +3957,7 @@ const Thread = ({ ToolFallback }) => {
|
|
|
3957
3957
|
return /* @__PURE__ */ jsxRuntime.jsxs(react.ThreadPrimitive.Root, { className: "max-w-[568px] w-full mx-auto h-[calc(100%-100px)] px-4", children: [
|
|
3958
3958
|
/* @__PURE__ */ jsxRuntime.jsxs(react.ThreadPrimitive.Viewport, { className: "py-10 overflow-y-auto scroll-smooth h-full", ref: areaRef, autoScroll: false, children: [
|
|
3959
3959
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
3960
|
-
/* @__PURE__ */ jsxRuntime.jsx(ThreadWelcome, {}),
|
|
3960
|
+
/* @__PURE__ */ jsxRuntime.jsx(ThreadWelcome, { agentName }),
|
|
3961
3961
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3962
3962
|
react.ThreadPrimitive.Messages,
|
|
3963
3963
|
{
|
|
@@ -3974,9 +3974,19 @@ const Thread = ({ ToolFallback }) => {
|
|
|
3974
3974
|
/* @__PURE__ */ jsxRuntime.jsx(Composer, {})
|
|
3975
3975
|
] });
|
|
3976
3976
|
};
|
|
3977
|
-
const ThreadWelcome = () => {
|
|
3977
|
+
const ThreadWelcome = ({ agentName }) => {
|
|
3978
|
+
const safeAgentName = agentName ?? "";
|
|
3979
|
+
const words = safeAgentName.split(" ") ?? [];
|
|
3980
|
+
let initials = "A";
|
|
3981
|
+
if (words.length === 2) {
|
|
3982
|
+
initials = `${words[0][0]}${words[1][0]}`;
|
|
3983
|
+
} else if (safeAgentName.length > 0) {
|
|
3984
|
+
initials = `${safeAgentName[0]}`;
|
|
3985
|
+
} else {
|
|
3986
|
+
initials = "A";
|
|
3987
|
+
}
|
|
3978
3988
|
return /* @__PURE__ */ jsxRuntime.jsx(react.ThreadPrimitive.Empty, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full flex-grow flex-col items-center justify-center", children: [
|
|
3979
|
-
/* @__PURE__ */ jsxRuntime.jsx(Avatar, { children: /* @__PURE__ */ jsxRuntime.jsx(AvatarFallback, { children:
|
|
3989
|
+
/* @__PURE__ */ jsxRuntime.jsx(Avatar, { children: /* @__PURE__ */ jsxRuntime.jsx(AvatarFallback, { children: initials }) }),
|
|
3980
3990
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-4 font-medium", children: "How can I help you today?" })
|
|
3981
3991
|
] }) });
|
|
3982
3992
|
};
|
|
@@ -4367,7 +4377,7 @@ const AgentChat = ({
|
|
|
4367
4377
|
refreshThreadList,
|
|
4368
4378
|
modelSettings,
|
|
4369
4379
|
chatWithGenerate,
|
|
4370
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full pb-4", children: /* @__PURE__ */ jsxRuntime.jsx(Thread, {}) })
|
|
4380
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full pb-4", children: /* @__PURE__ */ jsxRuntime.jsx(Thread, { agentName: agentName ?? "" }) })
|
|
4371
4381
|
}
|
|
4372
4382
|
);
|
|
4373
4383
|
};
|
|
@@ -4872,229 +4882,6 @@ function TraceProvider({ children }) {
|
|
|
4872
4882
|
);
|
|
4873
4883
|
}
|
|
4874
4884
|
|
|
4875
|
-
function usePolling({
|
|
4876
|
-
fetchFn,
|
|
4877
|
-
interval = 3e3,
|
|
4878
|
-
enabled = false,
|
|
4879
|
-
onSuccess,
|
|
4880
|
-
onError,
|
|
4881
|
-
shouldContinue = () => true,
|
|
4882
|
-
restartPolling = false
|
|
4883
|
-
}) {
|
|
4884
|
-
const [isPolling, setIsPolling] = React.useState(enabled);
|
|
4885
|
-
const [error, setError] = React.useState(null);
|
|
4886
|
-
const [data, setData] = React.useState(null);
|
|
4887
|
-
const [isLoading, setIsLoading] = React.useState(false);
|
|
4888
|
-
const [firstCallLoading, setFirstCallLoading] = React.useState(false);
|
|
4889
|
-
const timeoutRef = React.useRef(null);
|
|
4890
|
-
const mountedRef = React.useRef(true);
|
|
4891
|
-
const [restart, setRestart] = React.useState(restartPolling);
|
|
4892
|
-
const cleanup = React.useCallback(() => {
|
|
4893
|
-
console.log("cleanup");
|
|
4894
|
-
if (timeoutRef.current) {
|
|
4895
|
-
clearTimeout(timeoutRef.current);
|
|
4896
|
-
timeoutRef.current = null;
|
|
4897
|
-
}
|
|
4898
|
-
}, []);
|
|
4899
|
-
const stopPolling = React.useCallback(() => {
|
|
4900
|
-
console.log("stopPolling");
|
|
4901
|
-
setIsPolling(false);
|
|
4902
|
-
cleanup();
|
|
4903
|
-
}, [cleanup]);
|
|
4904
|
-
const startPolling = React.useCallback(() => {
|
|
4905
|
-
console.log("startPolling");
|
|
4906
|
-
setIsPolling(true);
|
|
4907
|
-
setError(null);
|
|
4908
|
-
}, []);
|
|
4909
|
-
const executePoll = React.useCallback(
|
|
4910
|
-
async (refetch2 = true) => {
|
|
4911
|
-
if (!mountedRef.current) return;
|
|
4912
|
-
setIsLoading(true);
|
|
4913
|
-
try {
|
|
4914
|
-
const result = await fetchFn();
|
|
4915
|
-
setData(result);
|
|
4916
|
-
setError(null);
|
|
4917
|
-
onSuccess?.(result);
|
|
4918
|
-
if (shouldContinue(result) && refetch2) {
|
|
4919
|
-
timeoutRef.current = setTimeout(executePoll, interval);
|
|
4920
|
-
} else {
|
|
4921
|
-
stopPolling();
|
|
4922
|
-
}
|
|
4923
|
-
} catch (err) {
|
|
4924
|
-
if (!mountedRef.current) return;
|
|
4925
|
-
setError(err);
|
|
4926
|
-
onError?.(err);
|
|
4927
|
-
stopPolling();
|
|
4928
|
-
} finally {
|
|
4929
|
-
if (mountedRef.current) {
|
|
4930
|
-
setFirstCallLoading(false);
|
|
4931
|
-
setIsLoading(false);
|
|
4932
|
-
}
|
|
4933
|
-
}
|
|
4934
|
-
},
|
|
4935
|
-
[fetchFn, interval, onSuccess, onError, shouldContinue, stopPolling]
|
|
4936
|
-
);
|
|
4937
|
-
const refetch = React.useCallback(
|
|
4938
|
-
(withPolling = false) => {
|
|
4939
|
-
console.log("refetch", { withPolling });
|
|
4940
|
-
if (withPolling) {
|
|
4941
|
-
setIsPolling(true);
|
|
4942
|
-
} else {
|
|
4943
|
-
executePoll(false);
|
|
4944
|
-
}
|
|
4945
|
-
setError(null);
|
|
4946
|
-
},
|
|
4947
|
-
[executePoll]
|
|
4948
|
-
);
|
|
4949
|
-
React.useEffect(() => {
|
|
4950
|
-
mountedRef.current = true;
|
|
4951
|
-
if (enabled && isPolling) {
|
|
4952
|
-
executePoll(true);
|
|
4953
|
-
}
|
|
4954
|
-
return () => {
|
|
4955
|
-
console.log("cleanup poll");
|
|
4956
|
-
mountedRef.current = false;
|
|
4957
|
-
cleanup();
|
|
4958
|
-
};
|
|
4959
|
-
}, [enabled, isPolling, executePoll, cleanup]);
|
|
4960
|
-
React.useEffect(() => {
|
|
4961
|
-
setRestart(restartPolling);
|
|
4962
|
-
}, [restartPolling]);
|
|
4963
|
-
React.useEffect(() => {
|
|
4964
|
-
if (restart && !isPolling) {
|
|
4965
|
-
setIsPolling(true);
|
|
4966
|
-
executePoll();
|
|
4967
|
-
setRestart(false);
|
|
4968
|
-
}
|
|
4969
|
-
}, [restart]);
|
|
4970
|
-
return {
|
|
4971
|
-
isPolling,
|
|
4972
|
-
isLoading,
|
|
4973
|
-
error,
|
|
4974
|
-
data,
|
|
4975
|
-
startPolling,
|
|
4976
|
-
stopPolling,
|
|
4977
|
-
firstCallLoading,
|
|
4978
|
-
refetch
|
|
4979
|
-
};
|
|
4980
|
-
}
|
|
4981
|
-
|
|
4982
|
-
function formatOtelTimestamp(otelTimestamp) {
|
|
4983
|
-
const date = new Date(otelTimestamp / 1e3);
|
|
4984
|
-
return new Intl.DateTimeFormat("en-US", {
|
|
4985
|
-
month: "numeric",
|
|
4986
|
-
day: "numeric",
|
|
4987
|
-
year: "numeric",
|
|
4988
|
-
hour: "numeric",
|
|
4989
|
-
minute: "numeric",
|
|
4990
|
-
second: "numeric",
|
|
4991
|
-
hour12: true
|
|
4992
|
-
}).format(date);
|
|
4993
|
-
}
|
|
4994
|
-
function formatOtelTimestamp2(otelTimestamp) {
|
|
4995
|
-
const date = new Date(otelTimestamp / 1e6);
|
|
4996
|
-
return new Intl.DateTimeFormat("en-US", {
|
|
4997
|
-
month: "numeric",
|
|
4998
|
-
day: "numeric",
|
|
4999
|
-
year: "numeric",
|
|
5000
|
-
hour: "numeric",
|
|
5001
|
-
minute: "numeric",
|
|
5002
|
-
second: "numeric",
|
|
5003
|
-
hour12: true
|
|
5004
|
-
}).format(date);
|
|
5005
|
-
}
|
|
5006
|
-
function transformKey(key) {
|
|
5007
|
-
if (key.includes(".argument.")) {
|
|
5008
|
-
return `Input`;
|
|
5009
|
-
}
|
|
5010
|
-
if (key.includes(".result")) {
|
|
5011
|
-
return "Output";
|
|
5012
|
-
}
|
|
5013
|
-
const newKey = key.split(".").join(" ").split("_").join(" ").replaceAll("ai", "AI");
|
|
5014
|
-
return newKey.substring(0, 1).toUpperCase() + newKey.substring(1);
|
|
5015
|
-
}
|
|
5016
|
-
const refineTraces = (traces, isWorkflow = false) => {
|
|
5017
|
-
const listOfSpanIds = /* @__PURE__ */ new Set();
|
|
5018
|
-
const newName = (name) => {
|
|
5019
|
-
if (name?.startsWith("workflow.") && isWorkflow) {
|
|
5020
|
-
return name?.split(".")?.slice(2)?.join(".");
|
|
5021
|
-
}
|
|
5022
|
-
if (name?.startsWith("agent.") && !isWorkflow) {
|
|
5023
|
-
return name?.split(".")?.slice(1)?.join(".");
|
|
5024
|
-
}
|
|
5025
|
-
return name;
|
|
5026
|
-
};
|
|
5027
|
-
const groupedTraces = traces?.reduce((acc, curr) => {
|
|
5028
|
-
const newCurr = { ...curr, name: newName(curr.name), duration: curr.endTime - curr.startTime };
|
|
5029
|
-
listOfSpanIds.add(curr.id);
|
|
5030
|
-
return { ...acc, [curr.traceId]: [...acc[curr.traceId] || [], newCurr] };
|
|
5031
|
-
}, {});
|
|
5032
|
-
const tracesData = Object.entries(groupedTraces).map(([key, value]) => {
|
|
5033
|
-
const parentSpan = value.find((span) => !span.parentSpanId || !listOfSpanIds.has(span.parentSpanId));
|
|
5034
|
-
const enrichedSpans = value.map((span) => ({
|
|
5035
|
-
...span,
|
|
5036
|
-
parentSpanId: parentSpan?.id === span.id ? null : span?.parentSpanId,
|
|
5037
|
-
relativePercentage: parentSpan ? span.duration / parentSpan.duration : 0
|
|
5038
|
-
}));
|
|
5039
|
-
const failedStatus = value.find((span) => span.status.code !== 0)?.status;
|
|
5040
|
-
return {
|
|
5041
|
-
traceId: key,
|
|
5042
|
-
serviceName: parentSpan?.name || key,
|
|
5043
|
-
duration: parentSpan?.duration || value.reduce((acc, curr) => acc + curr.duration, 0),
|
|
5044
|
-
status: failedStatus || parentSpan?.status || value[0].status,
|
|
5045
|
-
started: value[0].startTime,
|
|
5046
|
-
trace: enrichedSpans
|
|
5047
|
-
};
|
|
5048
|
-
});
|
|
5049
|
-
return tracesData;
|
|
5050
|
-
};
|
|
5051
|
-
|
|
5052
|
-
const useTraces = (componentName, baseUrl, isWorkflow = false) => {
|
|
5053
|
-
const [traces, setTraces] = React.useState([]);
|
|
5054
|
-
const { setTraces: setTraceContextTraces } = React.useContext(TraceContext);
|
|
5055
|
-
const client = React.useMemo(() => createMastraClient(baseUrl), [baseUrl]);
|
|
5056
|
-
const fetchFn = React.useCallback(async () => {
|
|
5057
|
-
try {
|
|
5058
|
-
const res = await client.getTelemetry({
|
|
5059
|
-
attribute: {
|
|
5060
|
-
componentName
|
|
5061
|
-
}
|
|
5062
|
-
});
|
|
5063
|
-
if (!res.traces) {
|
|
5064
|
-
throw new Error("Error fetching traces");
|
|
5065
|
-
}
|
|
5066
|
-
const refinedTraces = refineTraces(res?.traces || [], isWorkflow);
|
|
5067
|
-
return refinedTraces;
|
|
5068
|
-
} catch (error2) {
|
|
5069
|
-
throw error2;
|
|
5070
|
-
}
|
|
5071
|
-
}, [client, componentName, isWorkflow]);
|
|
5072
|
-
const onSuccess = React.useCallback(
|
|
5073
|
-
(newTraces) => {
|
|
5074
|
-
if (newTraces.length > 0) {
|
|
5075
|
-
setTraces(() => newTraces);
|
|
5076
|
-
setTraceContextTraces(() => newTraces);
|
|
5077
|
-
}
|
|
5078
|
-
},
|
|
5079
|
-
[setTraceContextTraces]
|
|
5080
|
-
);
|
|
5081
|
-
const onError = React.useCallback((error2) => {
|
|
5082
|
-
sonner.toast.error(error2.message);
|
|
5083
|
-
}, []);
|
|
5084
|
-
const shouldContinue = React.useCallback(() => {
|
|
5085
|
-
return true;
|
|
5086
|
-
}, []);
|
|
5087
|
-
const { firstCallLoading, error } = usePolling({
|
|
5088
|
-
fetchFn,
|
|
5089
|
-
interval: 3e3,
|
|
5090
|
-
onSuccess,
|
|
5091
|
-
onError,
|
|
5092
|
-
shouldContinue,
|
|
5093
|
-
enabled: true
|
|
5094
|
-
});
|
|
5095
|
-
return { traces, firstCallLoading, error };
|
|
5096
|
-
};
|
|
5097
|
-
|
|
5098
4885
|
const rowSize = {
|
|
5099
4886
|
default: "[&>tbody>tr]:h-table-row",
|
|
5100
4887
|
small: "[&>tbody>tr]:h-table-row-small"
|
|
@@ -5216,6 +5003,10 @@ const useOpenTrace = () => {
|
|
|
5216
5003
|
return { openTrace };
|
|
5217
5004
|
};
|
|
5218
5005
|
|
|
5006
|
+
const toSigFigs = (num, sigFigs) => {
|
|
5007
|
+
return Number(num.toPrecision(sigFigs));
|
|
5008
|
+
};
|
|
5009
|
+
|
|
5219
5010
|
const TracesTableSkeleton = ({ colsCount }) => {
|
|
5220
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)) }) });
|
|
5221
5012
|
};
|
|
@@ -5234,7 +5025,7 @@ const TraceRow = ({ trace, index, isActive }) => {
|
|
|
5234
5025
|
trace.traceId.substring(0, 7),
|
|
5235
5026
|
"..."
|
|
5236
5027
|
] }),
|
|
5237
|
-
/* @__PURE__ */ jsxRuntime.jsx(UnitCell, { unit: "ms", children:
|
|
5028
|
+
/* @__PURE__ */ jsxRuntime.jsx(UnitCell, { unit: "ms", children: toSigFigs(trace.duration / 1e3, 3) }),
|
|
5238
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 }) }) }),
|
|
5239
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" }) })
|
|
5240
5031
|
] });
|
|
@@ -5371,11 +5162,12 @@ const variantClasses = {
|
|
|
5371
5162
|
};
|
|
5372
5163
|
const Time = ({ durationMs, tokenCount, variant, progressPercent }) => {
|
|
5373
5164
|
const variantClass = variant ? variantClasses[variant] : "bg-accent3";
|
|
5165
|
+
const percent = Math.min(100, progressPercent);
|
|
5374
5166
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-[80px] xl:w-[166px] shrink-0", children: [
|
|
5375
|
-
/* @__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: `${
|
|
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}%` } }) }),
|
|
5376
5168
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 pt-0.5", children: [
|
|
5377
5169
|
/* @__PURE__ */ jsxRuntime.jsxs(Txt, { variant: "ui-sm", className: "text-icon2 font-medium", children: [
|
|
5378
|
-
|
|
5170
|
+
toSigFigs(durationMs, 3),
|
|
5379
5171
|
"ms"
|
|
5380
5172
|
] }),
|
|
5381
5173
|
tokenCount && /* @__PURE__ */ jsxRuntime.jsxs(Txt, { variant: "ui-sm", className: "text-icon2 font-medium", children: [
|
|
@@ -5610,6 +5402,76 @@ const SyntaxHighlighter = ({ data }) => {
|
|
|
5610
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] }) });
|
|
5611
5403
|
};
|
|
5612
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
|
+
|
|
5613
5475
|
function SpanDetail() {
|
|
5614
5476
|
const { span, setSpan, trace, setIsOpen } = React.useContext(TraceContext);
|
|
5615
5477
|
if (!span || !trace) return null;
|
|
@@ -5645,11 +5507,11 @@ function SpanDetail() {
|
|
|
5645
5507
|
span.name
|
|
5646
5508
|
] }),
|
|
5647
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: [
|
|
5648
|
-
|
|
5510
|
+
toSigFigs(span.duration / 1e3, 3),
|
|
5649
5511
|
"ms"
|
|
5650
5512
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(Badge$1, { variant: "error", icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, {}), children: [
|
|
5651
5513
|
"Failed in ",
|
|
5652
|
-
|
|
5514
|
+
toSigFigs(span.duration / 1e3, 3),
|
|
5653
5515
|
"ms"
|
|
5654
5516
|
] }) }),
|
|
5655
5517
|
/* @__PURE__ */ jsxRuntime.jsx("hr", { className: "border-border1 border-sm my-5" }),
|
|
@@ -5735,15 +5597,14 @@ const TracesSidebar = ({ onResize }) => {
|
|
|
5735
5597
|
);
|
|
5736
5598
|
};
|
|
5737
5599
|
|
|
5738
|
-
function AgentTraces({
|
|
5739
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5600
|
+
function AgentTraces({ className, traces, isLoading, error }) {
|
|
5601
|
+
return /* @__PURE__ */ jsxRuntime.jsx(AgentTracesInner, { className, traces, isLoading, error });
|
|
5740
5602
|
}
|
|
5741
|
-
function AgentTracesInner({
|
|
5603
|
+
function AgentTracesInner({ className, traces, isLoading, error }) {
|
|
5742
5604
|
const [sidebarWidth, setSidebarWidth] = React.useState(100);
|
|
5743
|
-
const { traces, firstCallLoading, error } = useTraces(agentName, baseUrl);
|
|
5744
5605
|
const { isOpen: open } = React.useContext(TraceContext);
|
|
5745
5606
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx("h-full relative overflow-hidden flex", className), children: [
|
|
5746
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsxRuntime.jsx(TracesTable, { traces, isLoading
|
|
5607
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsxRuntime.jsx(TracesTable, { traces, isLoading, error }) }),
|
|
5747
5608
|
open && /* @__PURE__ */ jsxRuntime.jsx(TracesSidebar, { width: sidebarWidth, onResize: setSidebarWidth })
|
|
5748
5609
|
] });
|
|
5749
5610
|
}
|
|
@@ -6195,15 +6056,14 @@ const NetworkChat = ({ agentId, memory }) => {
|
|
|
6195
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 }) }) });
|
|
6196
6057
|
};
|
|
6197
6058
|
|
|
6198
|
-
function WorkflowTraces({
|
|
6199
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6059
|
+
function WorkflowTraces({ traces, isLoading, error }) {
|
|
6060
|
+
return /* @__PURE__ */ jsxRuntime.jsx(WorkflowTracesInner, { traces, isLoading, error });
|
|
6200
6061
|
}
|
|
6201
|
-
function WorkflowTracesInner({
|
|
6062
|
+
function WorkflowTracesInner({ traces, isLoading, error }) {
|
|
6202
6063
|
const [sidebarWidth, setSidebarWidth] = React.useState(100);
|
|
6203
|
-
const { traces, error, firstCallLoading } = useTraces(workflowName, baseUrl, true);
|
|
6204
6064
|
const { isOpen: open } = React.useContext(TraceContext);
|
|
6205
6065
|
return /* @__PURE__ */ jsxRuntime.jsxs("main", { className: "h-full relative overflow-hidden flex", children: [
|
|
6206
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsxRuntime.jsx(TracesTable, { traces, isLoading
|
|
6066
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full overflow-y-scroll w-full", children: /* @__PURE__ */ jsxRuntime.jsx(TracesTable, { traces, isLoading, error }) }),
|
|
6207
6067
|
open && /* @__PURE__ */ jsxRuntime.jsx(TracesSidebar, { width: sidebarWidth, onResize: setSidebarWidth })
|
|
6208
6068
|
] });
|
|
6209
6069
|
}
|
|
@@ -8230,6 +8090,12 @@ class CustomZodProvider extends zod.ZodProvider {
|
|
|
8230
8090
|
}
|
|
8231
8091
|
}
|
|
8232
8092
|
|
|
8093
|
+
function isEmptyZodObject(schema) {
|
|
8094
|
+
if (schema instanceof z.ZodObject) {
|
|
8095
|
+
return Object.keys(schema.shape).length === 0;
|
|
8096
|
+
}
|
|
8097
|
+
return false;
|
|
8098
|
+
}
|
|
8233
8099
|
function DynamicForm({
|
|
8234
8100
|
schema,
|
|
8235
8101
|
onSubmit,
|
|
@@ -8242,6 +8108,9 @@ function DynamicForm({
|
|
|
8242
8108
|
return null;
|
|
8243
8109
|
}
|
|
8244
8110
|
const normalizedSchema = (schema2) => {
|
|
8111
|
+
if (isEmptyZodObject(schema2)) {
|
|
8112
|
+
return z.object({});
|
|
8113
|
+
}
|
|
8245
8114
|
return z.object({
|
|
8246
8115
|
"": schema2
|
|
8247
8116
|
});
|
|
@@ -8250,7 +8119,7 @@ function DynamicForm({
|
|
|
8250
8119
|
const formProps = {
|
|
8251
8120
|
schema: schemaProvider,
|
|
8252
8121
|
onSubmit: async (values) => {
|
|
8253
|
-
await onSubmit(values[""]);
|
|
8122
|
+
await onSubmit(values?.[""] || {});
|
|
8254
8123
|
},
|
|
8255
8124
|
defaultValues: defaultValues ? { "": defaultValues } : void 0,
|
|
8256
8125
|
formProps: {
|
|
@@ -8932,6 +8801,160 @@ const DarkLogo = (props) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "100
|
|
|
8932
8801
|
)
|
|
8933
8802
|
] });
|
|
8934
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
|
+
|
|
8935
8958
|
exports.AgentChat = AgentChat;
|
|
8936
8959
|
exports.AgentCoinIcon = AgentCoinIcon;
|
|
8937
8960
|
exports.AgentContext = AgentContext;
|
|
@@ -8994,7 +9017,9 @@ exports.Tbody = Tbody;
|
|
|
8994
9017
|
exports.Th = Th;
|
|
8995
9018
|
exports.Thead = Thead;
|
|
8996
9019
|
exports.ToolsIcon = ToolsIcon;
|
|
9020
|
+
exports.TraceContext = TraceContext;
|
|
8997
9021
|
exports.TraceIcon = TraceIcon;
|
|
9022
|
+
exports.TraceProvider = TraceProvider;
|
|
8998
9023
|
exports.TsIcon = TsIcon;
|
|
8999
9024
|
exports.Txt = Txt;
|
|
9000
9025
|
exports.TxtCell = TxtCell;
|
|
@@ -9009,4 +9034,6 @@ exports.WorkflowRunContext = WorkflowRunContext;
|
|
|
9009
9034
|
exports.WorkflowRunProvider = WorkflowRunProvider;
|
|
9010
9035
|
exports.WorkflowTraces = WorkflowTraces;
|
|
9011
9036
|
exports.WorkflowTrigger = WorkflowTrigger;
|
|
9037
|
+
exports.refineTraces = refineTraces;
|
|
9038
|
+
exports.useTraces = useTraces;
|
|
9012
9039
|
//# sourceMappingURL=index.cjs.js.map
|