@mastra/playground-ui 36.0.0 → 36.1.0-alpha.1

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/components/ScatterPlotChart.cjs.js +13 -0
  3. package/dist/components/ScatterPlotChart.cjs.js.map +1 -0
  4. package/dist/components/ScatterPlotChart.d.ts +2 -0
  5. package/dist/components/ScatterPlotChart.es.js +2 -0
  6. package/dist/components/ScatterPlotChart.es.js.map +1 -0
  7. package/dist/components/ThreadList.cjs.js +15 -0
  8. package/dist/components/ThreadList.cjs.js.map +1 -0
  9. package/dist/components/ThreadList.d.ts +2 -0
  10. package/dist/components/ThreadList.es.js +2 -0
  11. package/dist/components/ThreadList.es.js.map +1 -0
  12. package/dist/index.cjs.js +789 -1
  13. package/dist/index.cjs.js.map +1 -1
  14. package/dist/index.css +80 -1
  15. package/dist/index.es.js +764 -8
  16. package/dist/index.es.js.map +1 -1
  17. package/dist/scatter-plot-chart-BDRQ77OX.js +162 -0
  18. package/dist/scatter-plot-chart-BDRQ77OX.js.map +1 -0
  19. package/dist/scatter-plot-chart-MLvMlaxH.cjs +167 -0
  20. package/dist/scatter-plot-chart-MLvMlaxH.cjs.map +1 -0
  21. package/dist/src/domains/logs/hooks/use-logs.d.ts +5 -0
  22. package/dist/src/ds/components/ScatterPlotChart/index.d.ts +2 -0
  23. package/dist/src/ds/components/ScatterPlotChart/scatter-plot-chart-tooltip.d.ts +16 -0
  24. package/dist/src/ds/components/ScatterPlotChart/scatter-plot-chart.d.ts +24 -0
  25. package/dist/src/ds/components/ScatterPlotChart/scatter-plot-chart.stories.d.ts +11 -0
  26. package/dist/src/ds/components/ThreadList/index.d.ts +1 -0
  27. package/dist/src/ds/components/ThreadList/thread-list.d.ts +39 -0
  28. package/dist/src/ee/index.d.ts +2 -0
  29. package/dist/src/ee/signals/components/index.d.ts +2 -0
  30. package/dist/src/ee/signals/components/signal-details-page.d.ts +45 -0
  31. package/dist/src/ee/signals/components/signals-overview-page.d.ts +16 -0
  32. package/dist/src/ee/signals/index.d.ts +4 -0
  33. package/dist/src/ee/signals/signals-chart-data.d.ts +10 -0
  34. package/dist/src/ee/signals/signals-data.d.ts +2 -0
  35. package/dist/src/ee/signals/types.d.ts +13 -0
  36. package/dist/src/ee/topics/components/index.d.ts +6 -0
  37. package/dist/src/ee/topics/components/topic-trace-details-panel.d.ts +7 -0
  38. package/dist/src/ee/topics/components/topic-trace-summary-list.d.ts +8 -0
  39. package/dist/src/ee/topics/components/topics-layout.d.ts +7 -0
  40. package/dist/src/ee/topics/index.d.ts +3 -0
  41. package/dist/src/ee/topics/types.d.ts +40 -0
  42. package/dist/src/ee/topics/utils.d.ts +18 -0
  43. package/dist/src/index.d.ts +3 -0
  44. package/dist/src/lib/query-utils.d.ts +10 -0
  45. package/dist/thread-list-CX4UNk2L.cjs +79 -0
  46. package/dist/thread-list-CX4UNk2L.cjs.map +1 -0
  47. package/dist/thread-list-CkgV4nYA.js +72 -0
  48. package/dist/thread-list-CkgV4nYA.js.map +1 -0
  49. package/package.json +6 -6
package/dist/index.es.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import './index.css';/* empty css */
2
2
  export { A as Avatar } from './Avatar-Dcmi3-pN.js';
3
- export { B as Badge } from './Badge-DdJC6M08.js';
3
+ import { B as Badge } from './Badge-DdJC6M08.js';
4
4
  export { B as Breadcrumb, C as Crumb, S as SlashIcon } from './Breadcrumb-CxbCgAij.js';
5
5
  import { B as Button } from './Button-DoOEJwa_.js';
6
6
  export { b as buttonVariants } from './Button-DoOEJwa_.js';
@@ -50,7 +50,8 @@ export { P as PickMultiPanel, c as PropertyFilterCreator } from './property-filt
50
50
  export { R as RadioGroup, a as RadioGroupItem } from './radio-group-DIbajvIk.js';
51
51
  export { S as ScrollArea, a as ScrollBar } from './scroll-area-DjZ6nTm5.js';
52
52
  export { P as PendingIndicator } from './pending-indicator-DmowRHLo.js';
53
- export { S as Searchbar, a as SearchbarWrapper } from './searchbar-HmTfVgXd.js';
53
+ import { S as Searchbar } from './searchbar-HmTfVgXd.js';
54
+ export { a as SearchbarWrapper } from './searchbar-HmTfVgXd.js';
54
55
  import { S as Select, d as SelectTrigger, e as SelectValue, a as SelectContent, c as SelectItem } from './select-D2w0zRz4.js';
55
56
  export { b as SelectGroup } from './select-D2w0zRz4.js';
56
57
  export { S as Shimmer } from './shimmer-CTVYNDBn.js';
@@ -64,6 +65,7 @@ export { T as ThemeToggle } from './theme-toggle-AzjABhTN.js';
64
65
  import { T as Tooltip, c as TooltipTrigger, a as TooltipContent } from './tooltip-DehuxlSR.js';
65
66
  export { b as TooltipProvider } from './tooltip-DehuxlSR.js';
66
67
  export { T as Truncate } from './truncate-B8_8wx-G.js';
68
+ export { T as ThreadList, a as ThreadListEmpty, b as ThreadListItem, c as ThreadListItems, d as ThreadListNewItem, e as ThreadListSeparator } from './thread-list-CkgV4nYA.js';
67
69
  import { B as ButtonsGroup } from './buttons-group-BAU7uXE9.js';
68
70
  export { a as ButtonsGroupSeparator, b as ButtonsGroupText, c as buttonsGroupVariants } from './buttons-group-BAU7uXE9.js';
69
71
  export { M as MainContentContent, a as MainContentLayout, g as getMainContentContentClassName } from './main-content-CR0j00N1.js';
@@ -91,8 +93,8 @@ export { C as Chip } from './chip-Dgrpa03p.js';
91
93
  export { C as ChipsGroup } from './chips-group-DgaAmiHe.js';
92
94
  export { T as Tree } from './tree-CfOzTCxs.js';
93
95
  export { S as SelectDataFilter } from './select-data-filter-BFGZYkQ_.js';
94
- import { T as TracesDataList } from './traces-data-list-DRyI45Ke.js';
95
- export { D as DataList, S as ScoresDataList } from './traces-data-list-DRyI45Ke.js';
96
+ import { T as TracesDataList, D as DataList } from './traces-data-list-DRyI45Ke.js';
97
+ export { S as ScoresDataList } from './traces-data-list-DRyI45Ke.js';
96
98
  import { W as WorkflowIcon, A as AgentIcon, D as DataListSkeleton } from './data-list-skeleton-DD7ljjgS.js';
97
99
  import { T as ToolsIcon, L as LogsDataList } from './logs-data-list-Dh6c7URj.js';
98
100
  export { N as NoDataPageLayout, P as PageLayout } from './no-data-page-layout-CZzEj0NE.js';
@@ -110,6 +112,8 @@ import { H as HorizontalBars } from './horizontal-bars-r1aEIHUc.js';
110
112
  import { M as MetricsDataTable } from './metrics-data-table-hSmtDNck.js';
111
113
  import { M as MetricsLineChart } from './metrics-line-chart-BUUqDQPW.js';
112
114
  export { a as MetricsLineChartTooltip } from './metrics-line-chart-BUUqDQPW.js';
115
+ import { S as ScatterPlotChart } from './scatter-plot-chart-BDRQ77OX.js';
116
+ export { a as ScatterPlotChartTooltip, g as getScatterPlotClickedPoint, b as getScatterPlotPointColor } from './scatter-plot-chart-BDRQ77OX.js';
113
117
  export { S as StatusBadge } from './StatusBadge-DLLmQ85P.js';
114
118
  export { Animations } from './tokens.es.js';
115
119
  export { B as BorderColors, b as BorderRadius, C as Colors, F as FontSizes, G as Glows, L as LineHeights, S as Shadows, a as Sizes, c as Spacings } from './spacings-0Zbr65EW.js';
@@ -124,10 +128,10 @@ export { useIsMobile } from './hooks/use-is-mobile.es.js';
124
128
  export { useIsApplePlatform, useKeyboardShortcutLabel } from './hooks/use-keyboard-shortcut-label.es.js';
125
129
  import { c as cn } from './utils-CzYGxqbG.js';
126
130
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
127
- import { Wand2, Type, ToggleLeft, Hash, List, Braces, Ban, Check, ListX, ChevronsLeft, ChevronsRight, ChevronLeft, ChevronRight, Text, TextSearch, EqualNot, Equal, X, Plus, Component, LogsIcon as LogsIcon$1, EyeIcon, GaugeIcon, BrainIcon, ChevronUpIcon, ChevronDownIcon, ChevronsUpIcon, ChevronsDownIcon, FoldVerticalIcon, UnfoldVerticalIcon, ChevronsDownUpIcon, ChevronsUpDownIcon, Link2Icon, CircleGaugeIcon, SaveIcon, WrenchIcon, Loader2Icon, DownloadIcon, FileInputIcon, FileOutputIcon, BracesIcon, ExternalLinkIcon, CircleSlashIcon, ArrowUpIcon, ArrowDownIcon, ArrowRightIcon } from 'lucide-react';
131
+ import { Wand2, Type, ToggleLeft, Hash, List, Braces, Ban, Check, ListX, ChevronsLeft, ChevronsRight, ChevronLeft, ChevronRight, Text, TextSearch, EqualNot, Equal, X, Plus, Component, LogsIcon as LogsIcon$1, EyeIcon, GaugeIcon, BrainIcon, ChevronUpIcon, ChevronDownIcon, ChevronsUpIcon, ChevronsDownIcon, FoldVerticalIcon, UnfoldVerticalIcon, ChevronsDownUpIcon, ChevronsUpDownIcon, Link2Icon, CircleGaugeIcon, SaveIcon, WrenchIcon, Loader2Icon, DownloadIcon, FileInputIcon, FileOutputIcon, BracesIcon, ExternalLinkIcon, CircleSlashIcon, ArrowUpIcon, ArrowDownIcon, ArrowRightIcon, ArrowUpRight } from 'lucide-react';
128
132
  import * as React from 'react';
129
133
  import { useRef, useCallback, useState, useEffect, useMemo, useContext, createContext, Fragment as Fragment$1 } from 'react';
130
- import { usePanelRef, Panel, Separator } from 'react-resizable-panels';
134
+ import { usePanelRef, Panel, Separator, Group } from 'react-resizable-panels';
131
135
  import { I as Icon } from './Icon-CJEjdbjB.js';
132
136
  import { create } from 'zustand';
133
137
  import { persist } from 'zustand/middleware';
@@ -1541,6 +1545,12 @@ function isBranchesNotSupportedError(error) {
1541
1545
  if (typeof message !== "string") return false;
1542
1546
  return message.includes("does not support listing trace branches");
1543
1547
  }
1548
+ function isUnsupportedObservabilityOperationError(error, operation) {
1549
+ if (!error || typeof error !== "object" || !("message" in error)) return false;
1550
+ const message = error.message;
1551
+ if (typeof message !== "string") return false;
1552
+ return message.includes(`does not support listing ${operation}`);
1553
+ }
1544
1554
  function isNonRetryableError(error) {
1545
1555
  if (!error || typeof error !== "object") return false;
1546
1556
  if ("status" in error) {
@@ -7853,6 +7863,16 @@ function LogDetailsView({
7853
7863
  function LogsErrorContent({ error, resource, errorTitle }) {
7854
7864
  if (is401UnauthorizedError(error)) return /* @__PURE__ */ jsx(SessionExpired, {});
7855
7865
  if (is403ForbiddenError(error)) return /* @__PURE__ */ jsx(PermissionDenied, { resource });
7866
+ if (isUnsupportedObservabilityOperationError(error, "logs")) {
7867
+ return /* @__PURE__ */ jsx(
7868
+ EmptyState,
7869
+ {
7870
+ iconSlot: /* @__PURE__ */ jsx(CircleSlashIcon, {}),
7871
+ titleSlot: "Logs are not available with your current storage",
7872
+ descriptionSlot: "The configured observability storage provider does not support listing logs. Switch to a storage provider with logs support to view runtime logs in Studio."
7873
+ }
7874
+ );
7875
+ }
7856
7876
  const message = error instanceof Error ? error.message : void 0;
7857
7877
  return /* @__PURE__ */ jsx(ErrorState, { title: errorTitle, message: message ?? "Unknown error" });
7858
7878
  }
@@ -8080,6 +8100,7 @@ const NoLogsInfo = ({ datePreset, dateFrom, dateTo } = {}) => {
8080
8100
  };
8081
8101
 
8082
8102
  const LOGS_PER_PAGE = 20;
8103
+ const LOGS_REFETCH_INTERVAL_MS = 1e4;
8083
8104
  function getNextPageParam(lastPage, _allPages, lastPageParam) {
8084
8105
  if (lastPage?.pagination?.hasMore) {
8085
8106
  return lastPageParam + 1;
@@ -8099,6 +8120,12 @@ function selectLogs(data) {
8099
8120
  }
8100
8121
  return result;
8101
8122
  }
8123
+ function getLogsRefetchInterval(query) {
8124
+ if (isUnsupportedObservabilityOperationError(query.state.error, "logs")) {
8125
+ return false;
8126
+ }
8127
+ return LOGS_REFETCH_INTERVAL_MS;
8128
+ }
8102
8129
  const useLogs = ({ filters } = {}) => {
8103
8130
  const client = useMastraClient();
8104
8131
  const { inView: isEndOfListInView, setRef: setEndOfListElement } = useInView();
@@ -8113,7 +8140,7 @@ const useLogs = ({ filters } = {}) => {
8113
8140
  getNextPageParam,
8114
8141
  select: selectLogs,
8115
8142
  retry: false,
8116
- refetchInterval: 1e4
8143
+ refetchInterval: getLogsRefetchInterval
8117
8144
  });
8118
8145
  const { hasNextPage, isFetchingNextPage, fetchNextPage, data, isLoading, isError, error } = query;
8119
8146
  useEffect(() => {
@@ -8429,5 +8456,734 @@ function useLogsListNavigation(logs, featuredLogId, onFeaturedChange, featuredTr
8429
8456
  };
8430
8457
  }
8431
8458
 
8432
- export { AgentCoinIcon, AgentIcon, AgentNetworkCoinIcon, AiIcon, AmazonIcon, AnthropicChatIcon, AnthropicMessagesIcon, ApiIcon, AzureIcon, BROWSER_FETCHABLE_SCHEMES, BarListContent, BranchIcon, Button, ButtonsGroup, CHART_COLORS, CONTEXT_FIELD_IDS, CheckIcon, ChevronIcon, CohereIcon, CollapsiblePanel, CommitIcon, CopyButton, CrossIcon, DATE_PRESETS, DEFAULT_LOGS_FILTERS_STORAGE_KEY, DEFAULT_TRACE_FILTERS_STORAGE_KEY, DataDetailsPanel, DataKeysAndValues, DataListSkeleton, DataPanel, DatasetsIcon, DateRangeSelector, DateTimeRangePicker, DbIcon, DebugIcon, DeploymentIcon, DividerIcon, DocsIcon, Drawer, DrawerBackdrop, DrawerPopup, DrawerPortal, DrawerTitle, DrawerTrigger, DrawerViewport, DropdownMenu, EXTENSION_TO_MIME, EmptyState, EnvIcon, ErrorState, ExperimentsIcon, FiltersIcon, FolderIcon, GithubCoinIcon, GithubIcon, GoogleIcon, GroqIcon, HomeIcon, HorizontalBars, HoverCard, HoverCardContent, HoverCardTrigger, Icon, InfoIcon, Input, JudgeIcon, KpiCardView, LOGS_DATE_FROM_PARAM, LOGS_DATE_PRESET_PARAM, LOGS_DATE_PRESET_VALUES, LOGS_DATE_TO_PARAM, LOGS_PROPERTY_FILTER_FIELD_IDS, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD, LOGS_ROOT_ENTITY_TYPES, LOGS_ROOT_ENTITY_TYPE_OPTIONS, LOGS_ROOT_ENTITY_TYPE_PARAM, LOG_LEVEL_OPTIONS, LOG_LEVEL_VALUES, LatencyCardView, LatencyIcon, LogDetailsView, LogsDataList, DataListSkeleton as LogsDataListSkeleton, LogsErrorContent, LogsIcon, LogsLayout, LogsListView, LogsToolbar, MastraIcon, McpCoinIcon, McpServerIcon, MemoryCardView, MemoryIcon, MetricsCard, MetricsDataTable, MetricsIcon, MetricsLineChart, MetricsProvider, MistralIcon, ModelUsageCostCardView, NON_FETCHABLE_REMOTE_SCHEMES, NetlifyIcon, NoLogsInfo, NoTracesInfo, Notice, OPERATORS, OPERATOR_LABELS, OpenAIIcon, OpenErrorsInLogsButton, OpenInTracesButton, OpenaiChatIcon, PanelDrawer, PanelSeparator, PermissionDenied, ProcessorIcon, PromptIcon, PropertyFilterActions, PropertyFilterApplied, REMOTE_URL_SCHEMES, ROOT_ENTITY_TYPES, ROOT_ENTITY_TYPE_OPTIONS, RepoIcon, RequestContextIcon, RuleBuilder, RuleFieldSelect, RuleOperatorSelect, RuleRow, RuleValueInput, ScorersIcon, ScoresCardView, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SessionExpired, SettingsIcon, SkillIcon, SpanDataPanelView, SpanDetailsView, SpanTokenUsage, Spinner, StackedRunsBars, TRACE_ANCHOR_SPAN_ID_PARAM, TRACE_DATE_FROM_PARAM, TRACE_DATE_PRESET_PARAM, TRACE_DATE_PRESET_VALUES, TRACE_DATE_TO_PARAM, TRACE_LIST_MODE_OPTIONS, TRACE_LIST_MODE_PARAM, TRACE_LIST_MODE_VALUES, TRACE_PROPERTY_FILTER_FIELD_IDS, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD, TRACE_ROOT_ENTITY_TYPE_PARAM, TRACE_STATUS_OPTIONS, TRACE_STATUS_PARAM, TRACE_STATUS_VALUES, TRACE_SYNTHETIC_FILTER_FIELD_IDS, Tab, TabContent, TabList, Tabs, TimelineExpandCol, TimelineNameCol, TimelineStructureSign, TimelineTimingCol, TokenUsageByAgentCardView, TokenUsageTimelineCardView, ToolCoinIcon, ToolsIcon, Tooltip, TooltipContent, TooltipTrigger, TraceDataPanelView, TraceDetailsView, TraceIcon, TraceKeysAndValues, TraceTimeline, TraceTimelineSpan, TracesDataList, TracesErrorContent, TracesLayout, TracesListModeToggle, TracesListView, TracesToolbar, TracesVolumeCardView, TsIcon, VariablesIcon, WorkflowCoinIcon, WorkflowIcon, WorkspacesIcon, XGroqIcon, applyLogsPropertyFilterTokens, applyMetricsPropertyFilterTokens, applyTracePropertyFilterTokens, buildLogsDrilldownUrl, buildLogsListFilters, buildMetricsDimensionalFilter, buildTraceListFilters, buildTracesDrilldownUrl, clearSavedLogsFilters, clearSavedMetricsFilters, clearSavedTraceFilters, cn, countLeafRules, createDefaultRule, createDefaultRuleGroup, createLogsPropertyFilterFields, createMetricsPropertyFilterFields, createTracePropertyFilterFields, downloadJson, fileToBase64, formatCompact, formatCost, formatHierarchicalSpans, formatJSON, formatTypeScript, generateDefaultValues, getAllSpanIds, getChildFieldOptions, getFieldOptionAtPath, getFieldOptionsFromSchema, getFileContentType, getInputPreview, getLogsPropertyFilterTokens, getMetricsPropertyFilterTokens, getPreservedLogsFilterParams, getPreservedTraceFilterParams, getSpanDescendantIds, getSpanTypeUi, getTokenLimitMessage, getTracePropertyFilterTokens, hasAnyLogsFilterParams, hasAnyMetricsFilterParams, hasAnyTraceFilterParams, is401UnauthorizedError, is403ForbiddenError, is404NotFoundError, isBranchesNotSupportedError, isBrowserFetchableUrl, isNonFetchableRemoteUrl, isNonRetryableError, isObjectEmpty, isRemoteUrl, isRule, isRuleGroup, isTokenLimitExceeded, isValidJson, isValidPreset, loadLogsFiltersFromStorage, loadMetricsFiltersFromStorage, loadTraceFiltersFromStorage, lodashTitleCase, narrowWindowToBucket, neutralizeFilterTokens, neutralizeLogsFilterTokens, parseError, parseFieldPath, saveLogsFiltersToStorage, saveMetricsFiltersToStorage, saveTraceFiltersToStorage, shouldRetryQuery, spanTypePrefixes, stringToColor, toSigFigs, toast, truncateString, useActiveResourcesKpiMetrics, useActiveThreadsKpiMetrics, useAgentRunsKpiMetrics, useBranch, useDownloadTraceJson, useDrilldown, useEntityNames, useEnvironments, useInView, useLatencyMetrics, useLogs, useLogsFilterPersistence, useLogsListNavigation, useLogsUrlState, useMetrics, useMetricsFilters, useModelCostKpiMetrics, useModelUsageCostMetrics, usePlaygroundStore, useScoresMetrics, useServiceNames, useSpanDetail, useTags, useTokenUsageByAgentMetrics, useTokenUsageTimeSeries, useTopActiveThreadsMetrics, useTopResourcesByThreadsMetrics, useTotalTokensKpiMetrics, useTraceFilterPersistence, useTraceLightSpans, useTraceListNavigation, useTraceOrBranchSpans, useTraceSpanNavigation, useTraceSpans, useTraceUrlState, useTraceVolumeMetrics, useTraces };
8459
+ function TopicsLayout({ sidebar, children, tracePanel, contentPadding = true }) {
8460
+ const hasContent = Boolean(children || tracePanel);
8461
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 bg-surface2 text-neutral4", children: [
8462
+ sidebar ? /* @__PURE__ */ jsx("aside", { className: "min-h-0 w-[22rem] shrink-0 border-r border-border1", children: sidebar }) : null,
8463
+ hasContent ? /* @__PURE__ */ jsx("main", { className: contentPadding ? "min-w-0 flex-1 p-4" : "min-w-0 flex-1", children: /* @__PURE__ */ jsxs(Group, { className: "h-full min-h-0 w-full min-w-0", direction: "horizontal", children: [
8464
+ children ? /* @__PURE__ */ jsx(Panel, { id: "topic-main", className: "min-w-0 pr-2", minSize: 35, children }) : null,
8465
+ tracePanel ? /* @__PURE__ */ jsxs(Fragment, { children: [
8466
+ children ? /* @__PURE__ */ jsx(PanelSeparator, {}) : null,
8467
+ /* @__PURE__ */ jsx(
8468
+ CollapsiblePanel,
8469
+ {
8470
+ direction: "right",
8471
+ id: "topic-trace-details",
8472
+ minSize: 300,
8473
+ maxSize: "70%",
8474
+ defaultSize: children ? "40%" : "100%",
8475
+ collapsedSize: 60,
8476
+ collapsible: true,
8477
+ className: "min-w-0 pl-2",
8478
+ children: tracePanel
8479
+ }
8480
+ )
8481
+ ] }) : null
8482
+ ] }) }) : null
8483
+ ] });
8484
+ }
8485
+
8486
+ const TOPIC_COLORS = ["#7C3AED", "#2563EB", "#0891B2", "#059669", "#CA8A04", "#EA580C", "#DC2626", "#DB2777"];
8487
+ function hashString(value) {
8488
+ let hash = 0;
8489
+ for (let index = 0; index < value.length; index += 1) {
8490
+ hash = (hash << 5) - hash + value.charCodeAt(index);
8491
+ hash |= 0;
8492
+ }
8493
+ return Math.abs(hash);
8494
+ }
8495
+ function getTopicColor(id) {
8496
+ return TOPIC_COLORS[hashString(id) % TOPIC_COLORS.length];
8497
+ }
8498
+ function getTraceCount(subtopic) {
8499
+ return subtopic.traceSummaries.length;
8500
+ }
8501
+ function getTopicTraceCount(topic) {
8502
+ return topic.subtopics.reduce((total, subtopic) => total + getTraceCount(subtopic), 0);
8503
+ }
8504
+ function getTraceShare$1(count, total) {
8505
+ return {
8506
+ count,
8507
+ total,
8508
+ percentage: total > 0 ? Math.round(count / total * 100) : 0
8509
+ };
8510
+ }
8511
+ function aggregateTopics(topics) {
8512
+ const totalTraceCount = topics.reduce((total, topic) => total + getTopicTraceCount(topic), 0);
8513
+ return topics.map((topic) => ({
8514
+ ...topic,
8515
+ color: topic.color ?? getTopicColor(topic.id),
8516
+ traceCount: getTopicTraceCount(topic),
8517
+ subtopics: topic.subtopics.map((subtopic) => {
8518
+ const traceCount = getTraceCount(subtopic);
8519
+ return {
8520
+ ...subtopic,
8521
+ color: subtopic.color ?? topic.color ?? getTopicColor(subtopic.id),
8522
+ traceCount,
8523
+ traceShare: getTraceShare$1(traceCount, totalTraceCount)
8524
+ };
8525
+ })
8526
+ }));
8527
+ }
8528
+ function toTime(value) {
8529
+ if (!value) return 0;
8530
+ const time = value instanceof Date ? value.getTime() : new Date(value).getTime();
8531
+ return Number.isNaN(time) ? 0 : time;
8532
+ }
8533
+ function filterTraceSummaries(traces, search) {
8534
+ const normalizedSearch = search.trim().toLowerCase();
8535
+ if (!normalizedSearch) return traces;
8536
+ return traces.filter(
8537
+ (trace) => [trace.id, trace.name, trace.entityName, trace.status].some(
8538
+ (value) => value?.toLowerCase().includes(normalizedSearch)
8539
+ )
8540
+ );
8541
+ }
8542
+ function sortTraceSummaries(traces, sort) {
8543
+ return traces.toSorted((left, right) => {
8544
+ switch (sort) {
8545
+ case "oldest":
8546
+ return toTime(left.startedAt) - toTime(right.startedAt);
8547
+ case "duration-desc":
8548
+ return (right.durationMs ?? 0) - (left.durationMs ?? 0);
8549
+ case "duration-asc":
8550
+ return (left.durationMs ?? 0) - (right.durationMs ?? 0);
8551
+ case "newest":
8552
+ default:
8553
+ return toTime(right.startedAt) - toTime(left.startedAt);
8554
+ }
8555
+ });
8556
+ }
8557
+ function getVisibleTraceSummaries(traces, options) {
8558
+ const filtered = filterTraceSummaries(traces, options.search);
8559
+ const sorted = sortTraceSummaries(filtered, options.sort);
8560
+ const end = options.page * options.pageSize;
8561
+ return {
8562
+ traces: sorted.slice(0, end),
8563
+ total: sorted.length,
8564
+ hasMore: end < sorted.length
8565
+ };
8566
+ }
8567
+
8568
+ function TopicTraceSummaryList({
8569
+ traces,
8570
+ selectedTraceId,
8571
+ onTraceSelect,
8572
+ pageSize = 25
8573
+ }) {
8574
+ const [search, setSearch] = useState("");
8575
+ const [page, setPage] = useState(1);
8576
+ const visible = useMemo(
8577
+ () => getVisibleTraceSummaries(traces, { search, sort: "newest", page, pageSize }),
8578
+ [page, pageSize, search, traces]
8579
+ );
8580
+ return /* @__PURE__ */ jsxs("section", { className: "flex min-h-0 flex-1 flex-col gap-4", "aria-label": "Topic trace summaries", children: [
8581
+ /* @__PURE__ */ jsx(
8582
+ Searchbar,
8583
+ {
8584
+ label: "Search traces",
8585
+ placeholder: "Search traces",
8586
+ onSearch: (value) => {
8587
+ setSearch(value);
8588
+ setPage(1);
8589
+ }
8590
+ }
8591
+ ),
8592
+ /* @__PURE__ */ jsxs(DataList, { columns: "minmax(12rem,1fr)", className: "min-h-0 flex-1", children: [
8593
+ /* @__PURE__ */ jsx(DataList.Top, { children: /* @__PURE__ */ jsx(DataList.TopCells, { children: /* @__PURE__ */ jsx(DataList.TopCell, { children: "Trace summary" }) }) }),
8594
+ visible.traces.length === 0 ? /* @__PURE__ */ jsx(DataList.NoMatch, { message: "No traces match this subtopic." }) : visible.traces.map((trace) => /* @__PURE__ */ jsx(
8595
+ DataList.RowButton,
8596
+ {
8597
+ featured: selectedTraceId === trace.id,
8598
+ onClick: () => onTraceSelect(trace),
8599
+ "aria-pressed": selectedTraceId === trace.id,
8600
+ children: /* @__PURE__ */ jsx(DataList.TextCell, { children: trace.name ?? trace.id })
8601
+ },
8602
+ trace.id
8603
+ ))
8604
+ ] }),
8605
+ visible.hasMore ? /* @__PURE__ */ jsxs(Button, { variant: "outline", size: "sm", onClick: () => setPage((currentPage) => currentPage + 1), children: [
8606
+ "Load more traces (",
8607
+ visible.traces.length,
8608
+ " of ",
8609
+ visible.total,
8610
+ ")"
8611
+ ] }) : null
8612
+ ] });
8613
+ }
8614
+
8615
+ function TopicTraceDetailsPanel({
8616
+ traceId,
8617
+ selectedSpanId,
8618
+ onSpanSelect,
8619
+ onClose
8620
+ }) {
8621
+ const traceSpans = useTraceLightSpans(traceId);
8622
+ const spanDetail = useSpanDetail(traceId, selectedSpanId);
8623
+ const { handlePreviousSpan, handleNextSpan } = useTraceSpanNavigation(
8624
+ traceSpans.data?.spans,
8625
+ selectedSpanId,
8626
+ (spanId) => onSpanSelect?.(spanId)
8627
+ );
8628
+ if (!traceId) return null;
8629
+ return /* @__PURE__ */ jsxs(
8630
+ "div",
8631
+ {
8632
+ className: cn(
8633
+ "grid h-full min-h-0 overflow-auto",
8634
+ selectedSpanId ? "grid-rows-[minmax(0,1fr)_minmax(0,1fr)] gap-4" : "grid-rows-[minmax(0,1fr)]"
8635
+ ),
8636
+ children: [
8637
+ /* @__PURE__ */ jsx(
8638
+ TraceDetailsView,
8639
+ {
8640
+ traceId,
8641
+ spans: traceSpans.data?.spans,
8642
+ isLoading: traceSpans.isLoading,
8643
+ selectedSpanId,
8644
+ onSpanSelect,
8645
+ onClose
8646
+ }
8647
+ ),
8648
+ selectedSpanId ? /* @__PURE__ */ jsx(
8649
+ SpanDataPanelView,
8650
+ {
8651
+ traceId,
8652
+ spanId: selectedSpanId,
8653
+ span: spanDetail.data?.span,
8654
+ isLoading: spanDetail.isLoading,
8655
+ onClose: () => onSpanSelect?.(void 0),
8656
+ onPrevious: handlePreviousSpan,
8657
+ onNext: handleNextSpan
8658
+ }
8659
+ ) : null
8660
+ ]
8661
+ }
8662
+ );
8663
+ }
8664
+
8665
+ const SIGNAL_CHART_CLUSTERS = [
8666
+ { label: "Fast paths", count: 27, duration: 120, spans: 5 },
8667
+ { label: "Standard paths", count: 27, duration: 620, spans: 14 },
8668
+ { label: "Complex paths", count: 26, duration: 1280, spans: 28 }
8669
+ ];
8670
+ function getSignalChartData(clusters) {
8671
+ return clusters.flatMap(
8672
+ (cluster, clusterIndex) => SIGNAL_CHART_CLUSTERS.flatMap(
8673
+ (path) => Array.from({ length: path.count }, (_, index) => {
8674
+ const offset = index - (path.count - 1) / 2;
8675
+ const durationJitter = (index * 37 + clusterIndex * 19) % 90 - 45;
8676
+ const durationScatter = Math.sin((index + 1 + clusterIndex) * 1.7) * 34 + Math.cos((index + 3) * 0.9) * 21;
8677
+ const spanJitter = (index * 11 + clusterIndex * 3) % 7 - 3;
8678
+ return {
8679
+ id: `${cluster.id}-${path.label.toLowerCase().replaceAll(" ", "-")}-${index + 1}`,
8680
+ name: `${cluster.name} · ${path.label} ${index + 1}`,
8681
+ cluster: path.label,
8682
+ duration: Math.max(0, Math.round(path.duration + offset * 8 + durationJitter + durationScatter)),
8683
+ spans: Math.max(1, path.spans + spanJitter),
8684
+ color: stringToColor(`${cluster.name}-${path.label}`)
8685
+ };
8686
+ })
8687
+ )
8688
+ );
8689
+ }
8690
+
8691
+ const signals = [
8692
+ {
8693
+ id: "tasks",
8694
+ name: "Tasks",
8695
+ description: "Operational work patterns inferred from agent traces and user requests.",
8696
+ clusters: [
8697
+ {
8698
+ id: "refunds",
8699
+ name: "Refunds",
8700
+ description: "Refund requests, policy checks, and payment reversals.",
8701
+ traceSummaries: [
8702
+ {
8703
+ id: "trace-refund-1",
8704
+ name: "Refund eligibility check",
8705
+ status: "success",
8706
+ startedAt: "2026-06-15T10:00:00.000Z",
8707
+ durationMs: 1240,
8708
+ entityName: "support-agent",
8709
+ spanCount: 8
8710
+ },
8711
+ {
8712
+ id: "trace-refund-2",
8713
+ name: "Refund escalation",
8714
+ status: "error",
8715
+ startedAt: "2026-06-15T09:40:00.000Z",
8716
+ durationMs: 3180,
8717
+ entityName: "support-agent",
8718
+ spanCount: 12
8719
+ }
8720
+ ]
8721
+ },
8722
+ {
8723
+ id: "shipping",
8724
+ name: "Shipping",
8725
+ description: "Shipment lookup, carrier updates, and delivery exceptions.",
8726
+ traceSummaries: [
8727
+ {
8728
+ id: "trace-shipping-1",
8729
+ name: "Track delayed package",
8730
+ status: "success",
8731
+ startedAt: "2026-06-15T08:30:00.000Z",
8732
+ durationMs: 980,
8733
+ entityName: "support-agent",
8734
+ spanCount: 6
8735
+ }
8736
+ ]
8737
+ },
8738
+ {
8739
+ id: "account-updates",
8740
+ name: "Account updates",
8741
+ description: "Profile edits, plan changes, and account recovery requests.",
8742
+ traceSummaries: [
8743
+ {
8744
+ id: "trace-account-1",
8745
+ name: "Update billing contact",
8746
+ status: "success",
8747
+ startedAt: "2026-06-15T07:45:00.000Z",
8748
+ durationMs: 1420,
8749
+ entityName: "support-agent",
8750
+ spanCount: 7
8751
+ },
8752
+ {
8753
+ id: "trace-account-2",
8754
+ name: "Recover locked account",
8755
+ status: "success",
8756
+ startedAt: "2026-06-15T07:10:00.000Z",
8757
+ durationMs: 2640,
8758
+ entityName: "support-agent",
8759
+ spanCount: 11
8760
+ }
8761
+ ]
8762
+ },
8763
+ {
8764
+ id: "subscription-changes",
8765
+ name: "Subscription changes",
8766
+ description: "Upgrade, downgrade, pause, and renewal intent across plans.",
8767
+ traceSummaries: [
8768
+ {
8769
+ id: "trace-subscription-1",
8770
+ name: "Downgrade plan request",
8771
+ status: "success",
8772
+ startedAt: "2026-06-15T06:50:00.000Z",
8773
+ durationMs: 1880,
8774
+ entityName: "support-agent",
8775
+ spanCount: 9
8776
+ }
8777
+ ]
8778
+ }
8779
+ ]
8780
+ },
8781
+ {
8782
+ id: "sentiment",
8783
+ name: "Sentiment",
8784
+ description: "Conversation tone and confidence shifts that affect user outcomes.",
8785
+ clusters: [
8786
+ {
8787
+ id: "negative-feedback",
8788
+ name: "Negative feedback",
8789
+ description: "Escalations, frustration signals, and unresolved customer intent.",
8790
+ traceSummaries: [
8791
+ {
8792
+ id: "trace-sentiment-1",
8793
+ name: "De-escalate frustrated customer",
8794
+ status: "success",
8795
+ startedAt: "2026-06-15T12:30:00.000Z",
8796
+ durationMs: 2150,
8797
+ entityName: "support-agent",
8798
+ spanCount: 10
8799
+ }
8800
+ ]
8801
+ },
8802
+ {
8803
+ id: "positive-feedback",
8804
+ name: "Positive feedback",
8805
+ description: "Gratitude, satisfaction, and confirmation that the user outcome was met.",
8806
+ traceSummaries: [
8807
+ {
8808
+ id: "trace-sentiment-2",
8809
+ name: "Capture satisfied customer outcome",
8810
+ status: "success",
8811
+ startedAt: "2026-06-15T12:05:00.000Z",
8812
+ durationMs: 1320,
8813
+ entityName: "support-agent",
8814
+ spanCount: 5
8815
+ }
8816
+ ]
8817
+ },
8818
+ {
8819
+ id: "uncertain-feedback",
8820
+ name: "Uncertain feedback",
8821
+ description: "Ambiguous responses where sentiment or next best action needs clarification.",
8822
+ traceSummaries: [
8823
+ {
8824
+ id: "trace-sentiment-3",
8825
+ name: "Clarify ambiguous response",
8826
+ status: "running",
8827
+ startedAt: "2026-06-15T11:35:00.000Z",
8828
+ durationMs: 1760,
8829
+ entityName: "support-agent",
8830
+ spanCount: 8
8831
+ }
8832
+ ]
8833
+ }
8834
+ ]
8835
+ },
8836
+ {
8837
+ id: "issue",
8838
+ name: "Issue",
8839
+ description: "Recurring issue families found across support, research, and workflow traces.",
8840
+ clusters: [
8841
+ {
8842
+ id: "revenue-analysis",
8843
+ name: "Revenue analysis",
8844
+ description: "Revenue-impacting requests, market scans, and financial summaries.",
8845
+ traceSummaries: [
8846
+ {
8847
+ id: "trace-revenue-1",
8848
+ name: "Summarize revenue movement",
8849
+ status: "running",
8850
+ startedAt: "2026-06-15T11:05:00.000Z",
8851
+ durationMs: 4520,
8852
+ entityName: "research-agent",
8853
+ spanCount: 15
8854
+ }
8855
+ ]
8856
+ }
8857
+ ]
8858
+ },
8859
+ {
8860
+ id: "severity",
8861
+ name: "Severity",
8862
+ description: "Risk and urgency bands inferred from trace paths and intervention needs.",
8863
+ clusters: [
8864
+ {
8865
+ id: "urgent-escalations",
8866
+ name: "Urgent escalations",
8867
+ description: "High-priority paths that require faster handoff or deeper inspection.",
8868
+ traceSummaries: [
8869
+ {
8870
+ id: "trace-severity-1",
8871
+ name: "Escalate urgent account issue",
8872
+ status: "error",
8873
+ startedAt: "2026-06-15T13:10:00.000Z",
8874
+ durationMs: 3880,
8875
+ entityName: "support-agent",
8876
+ spanCount: 18
8877
+ }
8878
+ ]
8879
+ }
8880
+ ]
8881
+ }
8882
+ ];
8883
+
8884
+ const SignalTraceSummaryList = TopicTraceSummaryList;
8885
+ const SignalTraceDetailsPanel = TopicTraceDetailsPanel;
8886
+ const SignalsLayout = TopicsLayout;
8887
+ function findClusterByTraceId(signal, traceId) {
8888
+ if (!signal || !traceId) return void 0;
8889
+ return signal.clusters.find((cluster) => cluster.traceSummaries.some((trace) => trace.id === traceId));
8890
+ }
8891
+ function getSignalName(signalId) {
8892
+ return signals.find((signal) => signal.id === signalId)?.name ?? signalId;
8893
+ }
8894
+ function SignalClusterSidebar({
8895
+ signal,
8896
+ selectedClusterIds,
8897
+ onClusterSelect,
8898
+ multiple = false,
8899
+ ariaLabel = "Signal clusters"
8900
+ }) {
8901
+ return /* @__PURE__ */ jsx(
8902
+ "aside",
8903
+ {
8904
+ className: "min-h-0 w-72 shrink-0 overflow-y-auto border-r border-border1/60 pr-4 py-4",
8905
+ "aria-label": ariaLabel,
8906
+ children: /* @__PURE__ */ jsx("ul", { className: "space-y-1", role: multiple ? "group" : void 0, children: signal.clusters.map((cluster) => {
8907
+ const selected = selectedClusterIds.includes(cluster.id);
8908
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
8909
+ "button",
8910
+ {
8911
+ type: "button",
8912
+ role: multiple ? "checkbox" : void 0,
8913
+ "aria-checked": multiple ? selected : void 0,
8914
+ "aria-pressed": multiple ? void 0 : selected,
8915
+ className: "group cursor-pointer w-full rounded-xl px-3 py-2 text-left transition-colors hover:bg-surface3 aria-pressed:bg-surface3 aria-checked:bg-surface3 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent1",
8916
+ onClick: () => onClusterSelect(cluster.id),
8917
+ children: /* @__PURE__ */ jsxs("span", { className: "flex items-start gap-2", children: [
8918
+ /* @__PURE__ */ jsx(
8919
+ "span",
8920
+ {
8921
+ className: cn("mt-1.5 h-2 w-2 shrink-0 rounded-full", multiple && !selected && "invisible"),
8922
+ style: { backgroundColor: stringToColor(cluster.name) }
8923
+ }
8924
+ ),
8925
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 space-y-1", children: [
8926
+ /* @__PURE__ */ jsx(
8927
+ "span",
8928
+ {
8929
+ className: cn(
8930
+ "block text-sm font-medium",
8931
+ multiple && !selected ? "text-neutral3" : "text-neutral5"
8932
+ ),
8933
+ children: cluster.name
8934
+ }
8935
+ ),
8936
+ /* @__PURE__ */ jsx(
8937
+ "span",
8938
+ {
8939
+ className: cn(
8940
+ "line-clamp-2 block text-sm",
8941
+ multiple && !selected ? "text-neutral1" : "text-neutral2"
8942
+ ),
8943
+ children: cluster.description
8944
+ }
8945
+ )
8946
+ ] })
8947
+ ] })
8948
+ }
8949
+ ) }, cluster.id);
8950
+ }) })
8951
+ }
8952
+ );
8953
+ }
8954
+ function SignalTraceListTab({
8955
+ cluster,
8956
+ selectedTraceId,
8957
+ onTraceSelect
8958
+ }) {
8959
+ return /* @__PURE__ */ jsx(
8960
+ SignalTraceSummaryList,
8961
+ {
8962
+ traces: cluster.traceSummaries,
8963
+ selectedTraceId,
8964
+ onTraceSelect
8965
+ }
8966
+ );
8967
+ }
8968
+ function SignalChartTab({ signal, selectedClusterIds, onClusterToggle }) {
8969
+ const selectedClusters = useMemo(
8970
+ () => signal.clusters.filter((cluster) => selectedClusterIds.includes(cluster.id)),
8971
+ [signal.clusters, selectedClusterIds]
8972
+ );
8973
+ const chartData = useMemo(() => getSignalChartData(selectedClusters), [selectedClusters]);
8974
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-w-0 gap-6", children: [
8975
+ /* @__PURE__ */ jsx(
8976
+ SignalClusterSidebar,
8977
+ {
8978
+ signal,
8979
+ selectedClusterIds,
8980
+ onClusterSelect: onClusterToggle,
8981
+ multiple: true,
8982
+ ariaLabel: "Chart cluster filters"
8983
+ }
8984
+ ),
8985
+ /* @__PURE__ */ jsx("div", { className: "min-h-0 min-w-0 flex-1 py-4", children: /* @__PURE__ */ jsx(
8986
+ ScatterPlotChart,
8987
+ {
8988
+ data: chartData,
8989
+ xKey: "duration",
8990
+ yKey: "spans",
8991
+ nameKey: "name",
8992
+ colorKey: "color",
8993
+ height: "100%",
8994
+ className: "h-full",
8995
+ xLabel: "Duration",
8996
+ yLabel: "Spans",
8997
+ formatX: (value) => `${value}ms`,
8998
+ formatY: (value) => `${value} spans`
8999
+ }
9000
+ ) })
9001
+ ] });
9002
+ }
9003
+ function SignalClusterTabs({
9004
+ signal,
9005
+ selectedCluster,
9006
+ selectedTraceId,
9007
+ selectedChartClusterIds,
9008
+ activeTab,
9009
+ onActiveTabChange,
9010
+ onClusterSelect,
9011
+ onChartClusterToggle,
9012
+ onTraceSelect
9013
+ }) {
9014
+ return /* @__PURE__ */ jsxs(
9015
+ Tabs,
9016
+ {
9017
+ defaultTab: "trace-list",
9018
+ value: activeTab,
9019
+ onValueChange: onActiveTabChange,
9020
+ className: "flex h-full min-h-0 flex-col overflow-hidden",
9021
+ children: [
9022
+ /* @__PURE__ */ jsxs(TabList, { variant: "line", children: [
9023
+ /* @__PURE__ */ jsx(Tab, { value: "trace-list", children: "Trace list" }),
9024
+ /* @__PURE__ */ jsx(Tab, { value: "chart", children: "Chart" })
9025
+ ] }),
9026
+ /* @__PURE__ */ jsx(TabContent, { value: "trace-list", className: "min-h-0 flex-1 overflow-hidden py-0", children: /* @__PURE__ */ jsxs("div", { className: "flex h-full min-w-0 gap-6", children: [
9027
+ /* @__PURE__ */ jsx(
9028
+ SignalClusterSidebar,
9029
+ {
9030
+ signal,
9031
+ selectedClusterIds: [selectedCluster.id],
9032
+ onClusterSelect
9033
+ }
9034
+ ),
9035
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1 overflow-hidden py-4", children: /* @__PURE__ */ jsx(
9036
+ SignalTraceListTab,
9037
+ {
9038
+ cluster: selectedCluster,
9039
+ selectedTraceId,
9040
+ onTraceSelect
9041
+ }
9042
+ ) })
9043
+ ] }) }),
9044
+ /* @__PURE__ */ jsx(TabContent, { value: "chart", className: "min-h-0 flex-1 overflow-hidden py-0", children: /* @__PURE__ */ jsx(
9045
+ SignalChartTab,
9046
+ {
9047
+ signal,
9048
+ selectedClusterIds: selectedChartClusterIds,
9049
+ onClusterToggle: onChartClusterToggle
9050
+ }
9051
+ ) })
9052
+ ]
9053
+ }
9054
+ );
9055
+ }
9056
+ function SignalDetailsPage({ signalId, selectedTraceId, tracePanel, onTraceSelect }) {
9057
+ const selectedSignal = useMemo(() => signals.find((signal) => signal.id === signalId), [signalId]);
9058
+ const initialCluster = findClusterByTraceId(selectedSignal, selectedTraceId ?? void 0) ?? selectedSignal?.clusters[0];
9059
+ const [selectedClusterId, setSelectedClusterId] = useState(() => initialCluster?.id ?? null);
9060
+ const [selectedChartClusterIds, setSelectedChartClusterIds] = useState(
9061
+ () => selectedSignal?.clusters.map((cluster) => cluster.id) ?? []
9062
+ );
9063
+ const [activeTab, setActiveTab] = useState("trace-list");
9064
+ const selectedCluster = selectedSignal?.clusters.find((cluster) => cluster.id === selectedClusterId) ?? initialCluster;
9065
+ const { data: tracesData } = useTraces({});
9066
+ const resolvedTraceId = tracesData?.spans[0]?.traceId ?? null;
9067
+ const handleTraceSelect = () => {
9068
+ if (!selectedSignal || !resolvedTraceId) return;
9069
+ onTraceSelect(selectedSignal.id, resolvedTraceId);
9070
+ };
9071
+ const handleChartClusterToggle = (clusterId) => {
9072
+ setSelectedChartClusterIds(
9073
+ (current) => current.includes(clusterId) ? current.filter((id) => id !== clusterId) : [...current, clusterId]
9074
+ );
9075
+ };
9076
+ if (!selectedSignal || !selectedCluster) {
9077
+ return /* @__PURE__ */ jsx(SignalsLayout, { sidebar: null, children: "Signal not found" });
9078
+ }
9079
+ return /* @__PURE__ */ jsx(SignalsLayout, { sidebar: null, tracePanel: activeTab === "trace-list" ? tracePanel : void 0, children: /* @__PURE__ */ jsxs("section", { className: "flex h-full min-w-0 flex-col gap-4", children: [
9080
+ /* @__PURE__ */ jsxs("header", { className: "space-y-1", children: [
9081
+ /* @__PURE__ */ jsx("h1", { className: "text-icon-xl font-semibold text-neutral6", children: selectedSignal.name }),
9082
+ /* @__PURE__ */ jsx("p", { className: "text-ui-sm text-neutral3", children: "Explore trace patterns by cluster." })
9083
+ ] }),
9084
+ /* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-hidden", children: /* @__PURE__ */ jsx(
9085
+ SignalClusterTabs,
9086
+ {
9087
+ signal: selectedSignal,
9088
+ selectedCluster,
9089
+ selectedTraceId,
9090
+ selectedChartClusterIds,
9091
+ activeTab,
9092
+ onActiveTabChange: setActiveTab,
9093
+ onClusterSelect: setSelectedClusterId,
9094
+ onChartClusterToggle: handleChartClusterToggle,
9095
+ onTraceSelect: handleTraceSelect
9096
+ }
9097
+ ) })
9098
+ ] }) });
9099
+ }
9100
+
9101
+ const getTraceShare = (traceCount, totalTraceCount) => {
9102
+ if (totalTraceCount === 0) return 0;
9103
+ return Math.round(traceCount / totalTraceCount * 100);
9104
+ };
9105
+ function SignalClusterCard({ cluster, totalTraceCount }) {
9106
+ const traceCount = cluster.traceSummaries.length;
9107
+ const traceShare = getTraceShare(traceCount, totalTraceCount);
9108
+ const traceLabel = traceCount === 1 ? "trace" : "traces";
9109
+ const clusterColor = stringToColor(cluster.name);
9110
+ return /* @__PURE__ */ jsx("article", { className: "rounded-2xl border border-border1/70 bg-surface2 p-5 shadow-sm", children: /* @__PURE__ */ jsxs("div", { className: "flex h-full min-w-0 flex-col", children: [
9111
+ /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-start gap-2", children: [
9112
+ /* @__PURE__ */ jsx("span", { className: "mt-2 h-2.5 w-2.5 shrink-0 rounded-full", style: { backgroundColor: clusterColor } }),
9113
+ /* @__PURE__ */ jsxs("div", { children: [
9114
+ /* @__PURE__ */ jsx("h3", { className: "text-md font-semibold text-neutral6", children: cluster.name }),
9115
+ /* @__PURE__ */ jsx("p", { className: "line-clamp-2 text-sm text-neutral3", children: cluster.description })
9116
+ ] })
9117
+ ] }),
9118
+ /* @__PURE__ */ jsxs("div", { className: "space-y-1 pt-4 pl-4", children: [
9119
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
9120
+ /* @__PURE__ */ jsx("p", { className: "font-mono text-xs uppercase text-neutral3", children: "Trace share" }),
9121
+ /* @__PURE__ */ jsxs("p", { className: "font-mono text-xs text-neutral3", children: [
9122
+ traceCount,
9123
+ " ",
9124
+ traceLabel
9125
+ ] })
9126
+ ] }),
9127
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[minmax(0,1fr)_4rem] items-center gap-4", children: [
9128
+ /* @__PURE__ */ jsx(
9129
+ "div",
9130
+ {
9131
+ className: "h-3 overflow-hidden rounded-full bg-surface4",
9132
+ role: "progressbar",
9133
+ "aria-label": `${cluster.name} trace share`,
9134
+ "aria-valuemin": 0,
9135
+ "aria-valuemax": 100,
9136
+ "aria-valuenow": traceShare,
9137
+ children: /* @__PURE__ */ jsx("div", { className: "h-full rounded-full", style: { width: `${traceShare}%`, backgroundColor: clusterColor } })
9138
+ }
9139
+ ),
9140
+ /* @__PURE__ */ jsxs("p", { className: "text-right text-ui-md font-semibold text-neutral6", children: [
9141
+ traceShare,
9142
+ "%"
9143
+ ] })
9144
+ ] })
9145
+ ] })
9146
+ ] }) });
9147
+ }
9148
+ function SignalSection({ signal, onSeeDetails }) {
9149
+ const totalTraceCount = useMemo(
9150
+ () => signal.clusters.reduce((total, cluster) => total + cluster.traceSummaries.length, 0),
9151
+ [signal.clusters]
9152
+ );
9153
+ return /* @__PURE__ */ jsxs("section", { className: "space-y-4", children: [
9154
+ /* @__PURE__ */ jsxs("header", { className: "flex items-start justify-between gap-6 px-1", children: [
9155
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
9156
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
9157
+ /* @__PURE__ */ jsx("h2", { className: "text-ui-2xl font-semibold text-neutral6", children: signal.name }),
9158
+ /* @__PURE__ */ jsxs(Badge, { variant: "default", children: [
9159
+ signal.clusters.length,
9160
+ " ",
9161
+ signal.clusters.length === 1 ? "cluster" : "clusters"
9162
+ ] })
9163
+ ] }),
9164
+ /* @__PURE__ */ jsx("p", { className: "text-ui-lg text-neutral3", children: signal.description })
9165
+ ] }),
9166
+ /* @__PURE__ */ jsxs(
9167
+ Button,
9168
+ {
9169
+ type: "button",
9170
+ variant: "outline",
9171
+ size: "lg",
9172
+ className: "shrink-0 gap-2 rounded-xl px-5",
9173
+ onClick: () => onSeeDetails(signal),
9174
+ children: [
9175
+ "See details",
9176
+ /* @__PURE__ */ jsx(ArrowUpRight, { className: "h-4 w-4", "aria-hidden": "true" })
9177
+ ]
9178
+ }
9179
+ )
9180
+ ] }),
9181
+ /* @__PURE__ */ jsx("div", { className: "grid gap-6 md:grid-cols-2", children: signal.clusters.map((cluster) => /* @__PURE__ */ jsx(SignalClusterCard, { cluster, totalTraceCount }, cluster.id)) })
9182
+ ] });
9183
+ }
9184
+ function SignalsOverviewPage({ onSignalSelect }) {
9185
+ return /* @__PURE__ */ jsx(TopicsLayout, { sidebar: null, contentPadding: false, children: /* @__PURE__ */ jsx("nav", { className: "h-full min-w-0 overflow-y-auto p-6", "aria-label": "Signals", children: /* @__PURE__ */ jsx("div", { className: "mx-auto flex max-w-6xl flex-col gap-12", children: signals.map((signal) => /* @__PURE__ */ jsx(SignalSection, { signal, onSeeDetails: onSignalSelect }, signal.id)) }) }) });
9186
+ }
9187
+
9188
+ export { AgentCoinIcon, AgentIcon, AgentNetworkCoinIcon, AiIcon, AmazonIcon, AnthropicChatIcon, AnthropicMessagesIcon, ApiIcon, AzureIcon, BROWSER_FETCHABLE_SCHEMES, Badge, BarListContent, BranchIcon, Button, ButtonsGroup, CHART_COLORS, CONTEXT_FIELD_IDS, CheckIcon, ChevronIcon, CohereIcon, CollapsiblePanel, CommitIcon, CopyButton, CrossIcon, DATE_PRESETS, DEFAULT_LOGS_FILTERS_STORAGE_KEY, DEFAULT_TRACE_FILTERS_STORAGE_KEY, DataDetailsPanel, DataKeysAndValues, DataList, DataListSkeleton, DataPanel, DatasetsIcon, DateRangeSelector, DateTimeRangePicker, DbIcon, DebugIcon, DeploymentIcon, DividerIcon, DocsIcon, Drawer, DrawerBackdrop, DrawerPopup, DrawerPortal, DrawerTitle, DrawerTrigger, DrawerViewport, DropdownMenu, EXTENSION_TO_MIME, EmptyState, EnvIcon, ErrorState, ExperimentsIcon, FiltersIcon, FolderIcon, GithubCoinIcon, GithubIcon, GoogleIcon, GroqIcon, HomeIcon, HorizontalBars, HoverCard, HoverCardContent, HoverCardTrigger, Icon, InfoIcon, Input, JudgeIcon, KpiCardView, LOGS_DATE_FROM_PARAM, LOGS_DATE_PRESET_PARAM, LOGS_DATE_PRESET_VALUES, LOGS_DATE_TO_PARAM, LOGS_PROPERTY_FILTER_FIELD_IDS, LOGS_PROPERTY_FILTER_PARAM_BY_FIELD, LOGS_ROOT_ENTITY_TYPES, LOGS_ROOT_ENTITY_TYPE_OPTIONS, LOGS_ROOT_ENTITY_TYPE_PARAM, LOG_LEVEL_OPTIONS, LOG_LEVEL_VALUES, LatencyCardView, LatencyIcon, LogDetailsView, LogsDataList, DataListSkeleton as LogsDataListSkeleton, LogsErrorContent, LogsIcon, LogsLayout, LogsListView, LogsToolbar, MastraIcon, McpCoinIcon, McpServerIcon, MemoryCardView, MemoryIcon, MetricsCard, MetricsDataTable, MetricsIcon, MetricsLineChart, MetricsProvider, MistralIcon, ModelUsageCostCardView, NON_FETCHABLE_REMOTE_SCHEMES, NetlifyIcon, NoLogsInfo, NoTracesInfo, Notice, OPERATORS, OPERATOR_LABELS, OpenAIIcon, OpenErrorsInLogsButton, OpenInTracesButton, OpenaiChatIcon, PanelDrawer, PanelSeparator, PermissionDenied, ProcessorIcon, PromptIcon, PropertyFilterActions, PropertyFilterApplied, REMOTE_URL_SCHEMES, ROOT_ENTITY_TYPES, ROOT_ENTITY_TYPE_OPTIONS, RepoIcon, RequestContextIcon, RuleBuilder, RuleFieldSelect, RuleOperatorSelect, RuleRow, RuleValueInput, ScatterPlotChart, ScorersIcon, ScoresCardView, Searchbar, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SessionExpired, SettingsIcon, SignalChartTab, SignalClusterCard, SignalClusterSidebar, SignalClusterTabs, SignalDetailsPage, SignalSection, SignalTraceDetailsPanel, SignalTraceListTab, SignalsOverviewPage, SkillIcon, SpanDataPanelView, SpanDetailsView, SpanTokenUsage, Spinner, StackedRunsBars, TRACE_ANCHOR_SPAN_ID_PARAM, TRACE_DATE_FROM_PARAM, TRACE_DATE_PRESET_PARAM, TRACE_DATE_PRESET_VALUES, TRACE_DATE_TO_PARAM, TRACE_LIST_MODE_OPTIONS, TRACE_LIST_MODE_PARAM, TRACE_LIST_MODE_VALUES, TRACE_PROPERTY_FILTER_FIELD_IDS, TRACE_PROPERTY_FILTER_PARAM_BY_FIELD, TRACE_ROOT_ENTITY_TYPE_PARAM, TRACE_STATUS_OPTIONS, TRACE_STATUS_PARAM, TRACE_STATUS_VALUES, TRACE_SYNTHETIC_FILTER_FIELD_IDS, Tab, TabContent, TabList, Tabs, TimelineExpandCol, TimelineNameCol, TimelineStructureSign, TimelineTimingCol, TokenUsageByAgentCardView, TokenUsageTimelineCardView, ToolCoinIcon, ToolsIcon, Tooltip, TooltipContent, TooltipTrigger, TopicTraceDetailsPanel, TopicTraceSummaryList, TopicsLayout, TraceDataPanelView, TraceDetailsView, TraceIcon, TraceKeysAndValues, TraceTimeline, TraceTimelineSpan, TracesDataList, TracesErrorContent, TracesLayout, TracesListModeToggle, TracesListView, TracesToolbar, TracesVolumeCardView, TsIcon, VariablesIcon, WorkflowCoinIcon, WorkflowIcon, WorkspacesIcon, XGroqIcon, aggregateTopics, applyLogsPropertyFilterTokens, applyMetricsPropertyFilterTokens, applyTracePropertyFilterTokens, buildLogsDrilldownUrl, buildLogsListFilters, buildMetricsDimensionalFilter, buildTraceListFilters, buildTracesDrilldownUrl, clearSavedLogsFilters, clearSavedMetricsFilters, clearSavedTraceFilters, cn, countLeafRules, createDefaultRule, createDefaultRuleGroup, createLogsPropertyFilterFields, createMetricsPropertyFilterFields, createTracePropertyFilterFields, downloadJson, fileToBase64, filterTraceSummaries, formatCompact, formatCost, formatHierarchicalSpans, formatJSON, formatTypeScript, generateDefaultValues, getAllSpanIds, getChildFieldOptions, getFieldOptionAtPath, getFieldOptionsFromSchema, getFileContentType, getInputPreview, getLogsPropertyFilterTokens, getMetricsPropertyFilterTokens, getPreservedLogsFilterParams, getPreservedTraceFilterParams, getSignalChartData, getSignalName, getSpanDescendantIds, getSpanTypeUi, getTokenLimitMessage, getTopicColor, getTopicTraceCount, getTraceCount, getTracePropertyFilterTokens, getTraceShare$1 as getTraceShare, getVisibleTraceSummaries, hasAnyLogsFilterParams, hasAnyMetricsFilterParams, hasAnyTraceFilterParams, is401UnauthorizedError, is403ForbiddenError, is404NotFoundError, isBranchesNotSupportedError, isBrowserFetchableUrl, isNonFetchableRemoteUrl, isNonRetryableError, isObjectEmpty, isRemoteUrl, isRule, isRuleGroup, isTokenLimitExceeded, isUnsupportedObservabilityOperationError, isValidJson, isValidPreset, loadLogsFiltersFromStorage, loadMetricsFiltersFromStorage, loadTraceFiltersFromStorage, lodashTitleCase, narrowWindowToBucket, neutralizeFilterTokens, neutralizeLogsFilterTokens, parseError, parseFieldPath, saveLogsFiltersToStorage, saveMetricsFiltersToStorage, saveTraceFiltersToStorage, shouldRetryQuery, signals, sortTraceSummaries, spanTypePrefixes, stringToColor, toSigFigs, toast, truncateString, useActiveResourcesKpiMetrics, useActiveThreadsKpiMetrics, useAgentRunsKpiMetrics, useBranch, useDownloadTraceJson, useDrilldown, useEntityNames, useEnvironments, useInView, useLatencyMetrics, useLogs, useLogsFilterPersistence, useLogsListNavigation, useLogsUrlState, useMetrics, useMetricsFilters, useModelCostKpiMetrics, useModelUsageCostMetrics, usePlaygroundStore, useScoresMetrics, useServiceNames, useSpanDetail, useTags, useTokenUsageByAgentMetrics, useTokenUsageTimeSeries, useTopActiveThreadsMetrics, useTopResourcesByThreadsMetrics, useTotalTokensKpiMetrics, useTraceFilterPersistence, useTraceLightSpans, useTraceListNavigation, useTraceOrBranchSpans, useTraceSpanNavigation, useTraceSpans, useTraceUrlState, useTraceVolumeMetrics, useTraces };
8433
9189
  //# sourceMappingURL=index.es.js.map