@mastra/playground-ui 48.0.0 → 48.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.
- package/CHANGELOG.md +51 -0
- package/dist/Composer.css +2 -2
- package/dist/{code-C5KVVzOZ.js → code-Cj09LVys.js} +2 -2
- package/dist/{code-C5KVVzOZ.js.map → code-Cj09LVys.js.map} +1 -1
- package/dist/{code-B3WONxnA.cjs → code-FZwLnf_f.cjs} +2 -2
- package/dist/{code-B3WONxnA.cjs.map → code-FZwLnf_f.cjs.map} +1 -1
- package/dist/code-block-Dn0K3DkE.cjs +88 -0
- package/dist/code-block-Dn0K3DkE.cjs.map +1 -0
- package/dist/code-block-DqKXZajq.js +86 -0
- package/dist/code-block-DqKXZajq.js.map +1 -0
- package/dist/components/Code.cjs.js +1 -1
- package/dist/components/Code.es.js +1 -1
- package/dist/components/CodeBlock.cjs.js +3 -83
- package/dist/components/CodeBlock.cjs.js.map +1 -1
- package/dist/components/CodeBlock.es.js +1 -85
- package/dist/components/CodeBlock.es.js.map +1 -1
- package/dist/components/CodeEditor.cjs.js +2 -2
- package/dist/components/CodeEditor.es.js +2 -2
- package/dist/components/CopyButton.cjs.js +1 -1
- package/dist/components/CopyButton.es.js +1 -1
- package/dist/components/DataCodeSection.cjs.js +1 -1
- package/dist/components/DataCodeSection.es.js +1 -1
- package/dist/components/DataDetailsPanel.cjs.js +1 -1
- package/dist/components/DataDetailsPanel.es.js +1 -1
- package/dist/components/DataPanel.cjs.js +1 -1
- package/dist/components/DataPanel.es.js +1 -1
- package/dist/components/MarkdownRenderer.cjs.js +1 -1
- package/dist/components/MarkdownRenderer.es.js +1 -1
- package/dist/components/SideDialog.cjs.js +1 -1
- package/dist/components/SideDialog.es.js +1 -1
- package/dist/components/Truncate.cjs.js +1 -1
- package/dist/components/Truncate.es.js +1 -1
- package/dist/components/ai/plan.cjs.js +2 -2
- package/dist/components/ai/plan.cjs.js.map +1 -1
- package/dist/components/ai/plan.es.js +2 -2
- package/dist/components/ai/plan.es.js.map +1 -1
- package/dist/components/ai/task-list.cjs.js +44 -18
- package/dist/components/ai/task-list.cjs.js.map +1 -1
- package/dist/components/ai/task-list.es.js +47 -21
- package/dist/components/ai/task-list.es.js.map +1 -1
- package/dist/{copy-button-B1GWIQ-x.js → copy-button-BLGUkVE8.js} +4 -2
- package/dist/copy-button-BLGUkVE8.js.map +1 -0
- package/dist/{copy-button-DwZ3c7D4.cjs → copy-button-BfawWA4t.cjs} +4 -2
- package/dist/copy-button-BfawWA4t.cjs.map +1 -0
- package/dist/{data-code-section-PJM5l3aS.js → data-code-section-DHbytoQ2.js} +2 -2
- package/dist/{data-code-section-PJM5l3aS.js.map → data-code-section-DHbytoQ2.js.map} +1 -1
- package/dist/{data-code-section-BjmFgJpC.cjs → data-code-section-bqvIovEN.cjs} +2 -2
- package/dist/{data-code-section-BjmFgJpC.cjs.map → data-code-section-bqvIovEN.cjs.map} +1 -1
- package/dist/{data-panel-BQqPr6ew.js → data-panel-BX_78wCj.js} +2 -2
- package/dist/{data-panel-BQqPr6ew.js.map → data-panel-BX_78wCj.js.map} +1 -1
- package/dist/{data-panel-C85h9XvH.cjs → data-panel-DT6LgTVX.cjs} +2 -2
- package/dist/{data-panel-C85h9XvH.cjs.map → data-panel-DT6LgTVX.cjs.map} +1 -1
- package/dist/domains/logs/components/log-details-view.cjs.js +1 -1
- package/dist/domains/logs/components/log-details-view.es.js +1 -1
- package/dist/domains/traces/components/span-data-panel-view.cjs.js +1 -1
- package/dist/domains/traces/components/span-data-panel-view.es.js +1 -1
- package/dist/domains/traces/components/trace-data-panel-view.cjs.js +1 -1
- package/dist/domains/traces/components/trace-data-panel-view.es.js +1 -1
- package/dist/ee/signals/entity-learning-api.cjs.js +8 -2
- package/dist/ee/signals/entity-learning-api.cjs.js.map +1 -1
- package/dist/ee/signals/entity-learning-api.es.js +8 -3
- package/dist/ee/signals/entity-learning-api.es.js.map +1 -1
- package/dist/ee/signals/hooks/use-noise-examples.cjs.js +5 -3
- package/dist/ee/signals/hooks/use-noise-examples.cjs.js.map +1 -1
- package/dist/ee/signals/hooks/use-noise-examples.es.js +6 -4
- package/dist/ee/signals/hooks/use-noise-examples.es.js.map +1 -1
- package/dist/ee/signals/hooks/use-theme-examples.cjs.js +6 -3
- package/dist/ee/signals/hooks/use-theme-examples.cjs.js.map +1 -1
- package/dist/ee/signals/hooks/use-theme-examples.es.js +7 -4
- package/dist/ee/signals/hooks/use-theme-examples.es.js.map +1 -1
- package/dist/ee/signals/hooks/use-theme-paths.cjs.js +2 -2
- package/dist/ee/signals/hooks/use-theme-paths.cjs.js.map +1 -1
- package/dist/ee/signals/hooks/use-theme-paths.es.js +3 -3
- package/dist/ee/signals/hooks/use-theme-paths.es.js.map +1 -1
- package/dist/ee/signals/lifeline-row.cjs.js +1 -1
- package/dist/ee/signals/lifeline-row.cjs.js.map +1 -1
- package/dist/ee/signals/lifeline-row.es.js +1 -1
- package/dist/ee/signals/lifeline-row.es.js.map +1 -1
- package/dist/ee/signals/noise-detail-panel.cjs.js +18 -5
- package/dist/ee/signals/noise-detail-panel.cjs.js.map +1 -1
- package/dist/ee/signals/noise-detail-panel.es.js +18 -5
- package/dist/ee/signals/noise-detail-panel.es.js.map +1 -1
- package/dist/ee/signals/sankey-signals.cjs.js +50 -34
- package/dist/ee/signals/sankey-signals.cjs.js.map +1 -1
- package/dist/ee/signals/sankey-signals.es.js +52 -36
- package/dist/ee/signals/sankey-signals.es.js.map +1 -1
- package/dist/ee/signals/signal-delta-column.cjs.js +1 -1
- package/dist/ee/signals/signal-delta-column.cjs.js.map +1 -1
- package/dist/ee/signals/signal-delta-column.es.js +1 -1
- package/dist/ee/signals/signal-delta-column.es.js.map +1 -1
- package/dist/ee/signals/theme-detail-panel.cjs.js +11 -4
- package/dist/ee/signals/theme-detail-panel.cjs.js.map +1 -1
- package/dist/ee/signals/theme-detail-panel.es.js +11 -4
- package/dist/ee/signals/theme-detail-panel.es.js.map +1 -1
- package/dist/ee/signals/theme-drilldown-data.cjs.js +41 -13
- package/dist/ee/signals/theme-drilldown-data.cjs.js.map +1 -1
- package/dist/ee/signals/theme-drilldown-data.es.js +40 -14
- package/dist/ee/signals/theme-drilldown-data.es.js.map +1 -1
- package/dist/ee/signals/theme-filter-banner.cjs.js +53 -28
- package/dist/ee/signals/theme-filter-banner.cjs.js.map +1 -1
- package/dist/ee/signals/theme-filter-banner.es.js +53 -28
- package/dist/ee/signals/theme-filter-banner.es.js.map +1 -1
- package/dist/{highlight-C2uRVhiA.cjs → highlight-CEt2vhD8.cjs} +20 -3
- package/dist/highlight-CEt2vhD8.cjs.map +1 -0
- package/dist/{highlight-Dis62bkj.js → highlight-CSJjjoqh.js} +20 -3
- package/dist/highlight-CSJjjoqh.js.map +1 -0
- package/dist/markdown-renderer-D1vSFfp9.cjs +86 -0
- package/dist/markdown-renderer-D1vSFfp9.cjs.map +1 -0
- package/dist/markdown-renderer-DmYYQHxu.js +84 -0
- package/dist/markdown-renderer-DmYYQHxu.js.map +1 -0
- package/dist/markdown-renderer.css +182 -0
- package/dist/src/ds/components/CopyButton/copy-button.d.ts +2 -1
- package/dist/src/ds/components/MarkdownRenderer/markdown-renderer.d.ts +9 -5
- package/dist/src/ds/components/ai/task-list/task-list.d.ts +4 -2
- package/dist/src/ds/components/ai/task-list/task-list.stories.d.ts +2 -0
- package/dist/src/ee/signals/entity-learning-api.d.ts +4 -2
- package/dist/src/ee/signals/hooks/use-noise-examples.d.ts +2 -1
- package/dist/src/ee/signals/hooks/use-theme-examples.d.ts +2 -1
- package/dist/src/ee/signals/hooks/use-theme-paths.d.ts +1 -1
- package/dist/src/ee/signals/noise-detail-panel.d.ts +4 -1
- package/dist/src/ee/signals/theme-detail-panel.d.ts +5 -3
- package/dist/src/ee/signals/theme-drilldown-data.d.ts +17 -4
- package/dist/src/ee/signals/theme-filter-banner.d.ts +5 -3
- package/dist/style.css +5 -98
- package/package.json +7 -7
- package/dist/copy-button-B1GWIQ-x.js.map +0 -1
- package/dist/copy-button-DwZ3c7D4.cjs.map +0 -1
- package/dist/highlight-C2uRVhiA.cjs.map +0 -1
- package/dist/highlight-Dis62bkj.js.map +0 -1
- package/dist/markdown-renderer-DszxuuNM.js +0 -117
- package/dist/markdown-renderer-DszxuuNM.js.map +0 -1
- package/dist/markdown-renderer-g8xNLOc0.cjs +0 -119
- package/dist/markdown-renderer-g8xNLOc0.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-filter-banner.cjs.js","sources":["../../../src/ee/signals/theme-filter-banner.tsx"],"sourcesContent":["import { X } from 'lucide-react';\nimport { getSignalHue } from './signal-colors';\nimport { formatSignalName } from './signal-formatting';\nimport type { ThemeSelection } from './theme-drilldown-data';\nimport { Button } from '@/ds/components/Button';\nimport { nodeColor } from '@/ds/components/SankeyChart';\n\nexport function ThemeFilterBanner({\n
|
|
1
|
+
{"version":3,"file":"theme-filter-banner.cjs.js","sources":["../../../src/ee/signals/theme-filter-banner.tsx"],"sourcesContent":["import { X } from 'lucide-react';\nimport { getSignalHue } from './signal-colors';\nimport { formatSignalName } from './signal-formatting';\nimport type { ThemeSelection } from './theme-drilldown-data';\nimport { Button } from '@/ds/components/Button';\nimport { nodeColor } from '@/ds/components/SankeyChart';\n\nfunction selectionLabel(selection: ThemeSelection) {\n return `${formatSignalName(selection.signalName)} · ${selection.kind === 'theme' ? selection.label : 'Noise'}`;\n}\n\nfunction filterSummary({\n selections,\n filteredTraceCount,\n totalTraceCount,\n isUnavailable,\n}: {\n selections: ThemeSelection[];\n filteredTraceCount?: number;\n totalTraceCount: number;\n isUnavailable?: boolean;\n}) {\n if (isUnavailable) return 'Filters unavailable for this snapshot';\n if (filteredTraceCount === undefined) return 'Loading matching traces…';\n const onlySelection = selections.length === 1 ? selections[0] : undefined;\n if (onlySelection?.kind === 'noise') {\n return `Showing the ${filteredTraceCount} of ${totalTraceCount} traces assigned to Noise`;\n }\n if (onlySelection) {\n return `Showing the ${filteredTraceCount} of ${totalTraceCount} traces that flow through this theme`;\n }\n return `Showing the ${filteredTraceCount} of ${totalTraceCount} traces that match these filters`;\n}\n\nexport function ThemeFilterBanner({\n selections,\n filteredTraceCount,\n totalTraceCount,\n isUnavailable,\n onViewDetails,\n onRemove,\n onClear,\n}: {\n selections: ThemeSelection[];\n filteredTraceCount?: number;\n totalTraceCount: number;\n isUnavailable?: boolean;\n onViewDetails: (selection: ThemeSelection) => void;\n onRemove: (signalName: ThemeSelection['signalName']) => void;\n onClear: () => void;\n}) {\n const colors = selections.map(selection => nodeColor(getSignalHue(selection.signalName)));\n const latestSelection = selections.at(-1);\n const backgroundGradient = `linear-gradient(90deg, ${colors\n .map(color => `color-mix(in srgb, ${color} 8%, transparent)`)\n .join(', ')})`;\n const borderGradient = `linear-gradient(90deg, ${colors\n .map(color => `color-mix(in srgb, ${color} 35%, transparent)`)\n .join(', ')})`;\n\n return (\n <section\n aria-label=\"Active theme drill-in\"\n className=\"relative flex flex-wrap items-center gap-x-4 gap-y-2 rounded-lg border border-transparent px-3 py-2\"\n style={{ backgroundImage: `${backgroundGradient}, ${borderGradient}`, backgroundClip: 'padding-box, border-box' }}\n >\n {selections.map((selection, index) => {\n const color = colors[index];\n return (\n <button\n key={selection.signalName}\n aria-label={\n selections.length === 1 ? `Clear ${selection.kind} filter` : `Clear filter ${selectionLabel(selection)}`\n }\n className=\"border-border1 bg-surface2 text-neutral6 hover:bg-surface4 flex items-center gap-1.5 rounded-full border py-1 pr-2 pl-2.5 text-xs font-medium transition-colors\"\n onClick={() => onRemove(selection.signalName)}\n type=\"button\"\n >\n <span aria-hidden=\"true\" className=\"rounded-0.5 size-2\" style={{ backgroundColor: color }} />\n {selectionLabel(selection)}\n <X aria-hidden=\"true\" className=\"size-3.5\" />\n </button>\n );\n })}\n <span className=\"text-neutral4 text-xs\">\n {filterSummary({ selections, filteredTraceCount, totalTraceCount, isUnavailable })}\n </span>\n {!isUnavailable && filteredTraceCount !== undefined && latestSelection ? (\n <Button\n aria-label={\n latestSelection.kind === 'theme'\n ? `View theme details for ${latestSelection.label}`\n : `View noise details for ${formatSignalName(latestSelection.signalName)}`\n }\n onClick={() => onViewDetails(latestSelection)}\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n >\n Details →\n </Button>\n ) : null}\n {selections.length > 1 ? (\n <Button onClick={onClear} size=\"sm\" type=\"button\" variant=\"ghost\">\n Clear all\n </Button>\n ) : null}\n </section>\n );\n}\n"],"names":["formatSignalName","nodeColor","getSignalHue","jsxs","jsx","X","Button"],"mappings":"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"}
|
|
@@ -5,52 +5,77 @@ import { formatSignalName } from './signal-formatting.es.js';
|
|
|
5
5
|
import { B as Button } from '../../Button-C-9Pzy-Z.js';
|
|
6
6
|
import { n as nodeColor } from '../../sankeyColor-CQ5nkgtL.js';
|
|
7
7
|
|
|
8
|
+
function selectionLabel(selection) {
|
|
9
|
+
return `${formatSignalName(selection.signalName)} · ${selection.kind === "theme" ? selection.label : "Noise"}`;
|
|
10
|
+
}
|
|
11
|
+
function filterSummary({
|
|
12
|
+
selections,
|
|
13
|
+
filteredTraceCount,
|
|
14
|
+
totalTraceCount,
|
|
15
|
+
isUnavailable
|
|
16
|
+
}) {
|
|
17
|
+
if (isUnavailable) return "Filters unavailable for this snapshot";
|
|
18
|
+
if (filteredTraceCount === void 0) return "Loading matching traces…";
|
|
19
|
+
const onlySelection = selections.length === 1 ? selections[0] : void 0;
|
|
20
|
+
if (onlySelection?.kind === "noise") {
|
|
21
|
+
return `Showing the ${filteredTraceCount} of ${totalTraceCount} traces assigned to Noise`;
|
|
22
|
+
}
|
|
23
|
+
if (onlySelection) {
|
|
24
|
+
return `Showing the ${filteredTraceCount} of ${totalTraceCount} traces that flow through this theme`;
|
|
25
|
+
}
|
|
26
|
+
return `Showing the ${filteredTraceCount} of ${totalTraceCount} traces that match these filters`;
|
|
27
|
+
}
|
|
8
28
|
function ThemeFilterBanner({
|
|
9
|
-
|
|
29
|
+
selections,
|
|
10
30
|
filteredTraceCount,
|
|
11
31
|
totalTraceCount,
|
|
32
|
+
isUnavailable,
|
|
12
33
|
onViewDetails,
|
|
34
|
+
onRemove,
|
|
13
35
|
onClear
|
|
14
36
|
}) {
|
|
15
|
-
const
|
|
37
|
+
const colors = selections.map((selection) => nodeColor(getSignalHue(selection.signalName)));
|
|
38
|
+
const latestSelection = selections.at(-1);
|
|
39
|
+
const backgroundGradient = `linear-gradient(90deg, ${colors.map((color) => `color-mix(in srgb, ${color} 8%, transparent)`).join(", ")})`;
|
|
40
|
+
const borderGradient = `linear-gradient(90deg, ${colors.map((color) => `color-mix(in srgb, ${color} 35%, transparent)`).join(", ")})`;
|
|
16
41
|
return /* @__PURE__ */ jsxs(
|
|
17
42
|
"section",
|
|
18
43
|
{
|
|
19
44
|
"aria-label": "Active theme drill-in",
|
|
20
|
-
className: "flex flex-wrap items-center gap-x-4 gap-y-2 rounded-lg border px-3 py-2",
|
|
21
|
-
style: {
|
|
22
|
-
borderColor: `color-mix(in srgb, ${color} 35%, transparent)`,
|
|
23
|
-
backgroundColor: `color-mix(in srgb, ${color} 8%, transparent)`
|
|
24
|
-
},
|
|
45
|
+
className: "relative flex flex-wrap items-center gap-x-4 gap-y-2 rounded-lg border border-transparent px-3 py-2",
|
|
46
|
+
style: { backgroundImage: `${backgroundGradient}, ${borderGradient}`, backgroundClip: "padding-box, border-box" },
|
|
25
47
|
children: [
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
48
|
+
selections.map((selection, index) => {
|
|
49
|
+
const color = colors[index];
|
|
50
|
+
return /* @__PURE__ */ jsxs(
|
|
51
|
+
"button",
|
|
52
|
+
{
|
|
53
|
+
"aria-label": selections.length === 1 ? `Clear ${selection.kind} filter` : `Clear filter ${selectionLabel(selection)}`,
|
|
54
|
+
className: "border-border1 bg-surface2 text-neutral6 hover:bg-surface4 flex items-center gap-1.5 rounded-full border py-1 pr-2 pl-2.5 text-xs font-medium transition-colors",
|
|
55
|
+
onClick: () => onRemove(selection.signalName),
|
|
56
|
+
type: "button",
|
|
57
|
+
children: [
|
|
58
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "rounded-0.5 size-2", style: { backgroundColor: color } }),
|
|
59
|
+
selectionLabel(selection),
|
|
60
|
+
/* @__PURE__ */ jsx(X, { "aria-hidden": "true", className: "size-3.5" })
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
selection.signalName
|
|
64
|
+
);
|
|
65
|
+
}),
|
|
66
|
+
/* @__PURE__ */ jsx("span", { className: "text-neutral4 text-xs", children: filterSummary({ selections, filteredTraceCount, totalTraceCount, isUnavailable }) }),
|
|
67
|
+
!isUnavailable && filteredTraceCount !== void 0 && latestSelection ? /* @__PURE__ */ jsx(
|
|
44
68
|
Button,
|
|
45
69
|
{
|
|
46
|
-
"aria-label": `View theme details for ${
|
|
47
|
-
onClick: onViewDetails,
|
|
70
|
+
"aria-label": latestSelection.kind === "theme" ? `View theme details for ${latestSelection.label}` : `View noise details for ${formatSignalName(latestSelection.signalName)}`,
|
|
71
|
+
onClick: () => onViewDetails(latestSelection),
|
|
48
72
|
size: "sm",
|
|
49
73
|
type: "button",
|
|
50
74
|
variant: "ghost",
|
|
51
75
|
children: "Details →"
|
|
52
76
|
}
|
|
53
|
-
)
|
|
77
|
+
) : null,
|
|
78
|
+
selections.length > 1 ? /* @__PURE__ */ jsx(Button, { onClick: onClear, size: "sm", type: "button", variant: "ghost", children: "Clear all" }) : null
|
|
54
79
|
]
|
|
55
80
|
}
|
|
56
81
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-filter-banner.es.js","sources":["../../../src/ee/signals/theme-filter-banner.tsx"],"sourcesContent":["import { X } from 'lucide-react';\nimport { getSignalHue } from './signal-colors';\nimport { formatSignalName } from './signal-formatting';\nimport type { ThemeSelection } from './theme-drilldown-data';\nimport { Button } from '@/ds/components/Button';\nimport { nodeColor } from '@/ds/components/SankeyChart';\n\nexport function ThemeFilterBanner({\n
|
|
1
|
+
{"version":3,"file":"theme-filter-banner.es.js","sources":["../../../src/ee/signals/theme-filter-banner.tsx"],"sourcesContent":["import { X } from 'lucide-react';\nimport { getSignalHue } from './signal-colors';\nimport { formatSignalName } from './signal-formatting';\nimport type { ThemeSelection } from './theme-drilldown-data';\nimport { Button } from '@/ds/components/Button';\nimport { nodeColor } from '@/ds/components/SankeyChart';\n\nfunction selectionLabel(selection: ThemeSelection) {\n return `${formatSignalName(selection.signalName)} · ${selection.kind === 'theme' ? selection.label : 'Noise'}`;\n}\n\nfunction filterSummary({\n selections,\n filteredTraceCount,\n totalTraceCount,\n isUnavailable,\n}: {\n selections: ThemeSelection[];\n filteredTraceCount?: number;\n totalTraceCount: number;\n isUnavailable?: boolean;\n}) {\n if (isUnavailable) return 'Filters unavailable for this snapshot';\n if (filteredTraceCount === undefined) return 'Loading matching traces…';\n const onlySelection = selections.length === 1 ? selections[0] : undefined;\n if (onlySelection?.kind === 'noise') {\n return `Showing the ${filteredTraceCount} of ${totalTraceCount} traces assigned to Noise`;\n }\n if (onlySelection) {\n return `Showing the ${filteredTraceCount} of ${totalTraceCount} traces that flow through this theme`;\n }\n return `Showing the ${filteredTraceCount} of ${totalTraceCount} traces that match these filters`;\n}\n\nexport function ThemeFilterBanner({\n selections,\n filteredTraceCount,\n totalTraceCount,\n isUnavailable,\n onViewDetails,\n onRemove,\n onClear,\n}: {\n selections: ThemeSelection[];\n filteredTraceCount?: number;\n totalTraceCount: number;\n isUnavailable?: boolean;\n onViewDetails: (selection: ThemeSelection) => void;\n onRemove: (signalName: ThemeSelection['signalName']) => void;\n onClear: () => void;\n}) {\n const colors = selections.map(selection => nodeColor(getSignalHue(selection.signalName)));\n const latestSelection = selections.at(-1);\n const backgroundGradient = `linear-gradient(90deg, ${colors\n .map(color => `color-mix(in srgb, ${color} 8%, transparent)`)\n .join(', ')})`;\n const borderGradient = `linear-gradient(90deg, ${colors\n .map(color => `color-mix(in srgb, ${color} 35%, transparent)`)\n .join(', ')})`;\n\n return (\n <section\n aria-label=\"Active theme drill-in\"\n className=\"relative flex flex-wrap items-center gap-x-4 gap-y-2 rounded-lg border border-transparent px-3 py-2\"\n style={{ backgroundImage: `${backgroundGradient}, ${borderGradient}`, backgroundClip: 'padding-box, border-box' }}\n >\n {selections.map((selection, index) => {\n const color = colors[index];\n return (\n <button\n key={selection.signalName}\n aria-label={\n selections.length === 1 ? `Clear ${selection.kind} filter` : `Clear filter ${selectionLabel(selection)}`\n }\n className=\"border-border1 bg-surface2 text-neutral6 hover:bg-surface4 flex items-center gap-1.5 rounded-full border py-1 pr-2 pl-2.5 text-xs font-medium transition-colors\"\n onClick={() => onRemove(selection.signalName)}\n type=\"button\"\n >\n <span aria-hidden=\"true\" className=\"rounded-0.5 size-2\" style={{ backgroundColor: color }} />\n {selectionLabel(selection)}\n <X aria-hidden=\"true\" className=\"size-3.5\" />\n </button>\n );\n })}\n <span className=\"text-neutral4 text-xs\">\n {filterSummary({ selections, filteredTraceCount, totalTraceCount, isUnavailable })}\n </span>\n {!isUnavailable && filteredTraceCount !== undefined && latestSelection ? (\n <Button\n aria-label={\n latestSelection.kind === 'theme'\n ? `View theme details for ${latestSelection.label}`\n : `View noise details for ${formatSignalName(latestSelection.signalName)}`\n }\n onClick={() => onViewDetails(latestSelection)}\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n >\n Details →\n </Button>\n ) : null}\n {selections.length > 1 ? (\n <Button onClick={onClear} size=\"sm\" type=\"button\" variant=\"ghost\">\n Clear all\n </Button>\n ) : null}\n </section>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -21,7 +21,18 @@ const langAliases = {
|
|
|
21
21
|
sh: "bash",
|
|
22
22
|
bash: "bash",
|
|
23
23
|
shell: "bash",
|
|
24
|
-
zsh: "bash"
|
|
24
|
+
zsh: "bash",
|
|
25
|
+
yml: "yaml",
|
|
26
|
+
yaml: "yaml",
|
|
27
|
+
diff: "diff",
|
|
28
|
+
patch: "diff",
|
|
29
|
+
css: "css",
|
|
30
|
+
scss: "css",
|
|
31
|
+
html: "html",
|
|
32
|
+
htm: "html",
|
|
33
|
+
xml: "xml",
|
|
34
|
+
svg: "xml",
|
|
35
|
+
sql: "sql"
|
|
25
36
|
};
|
|
26
37
|
let highlighterPromise = null;
|
|
27
38
|
function getHighlighter() {
|
|
@@ -41,7 +52,13 @@ function getHighlighter() {
|
|
|
41
52
|
import('shiki/langs/json.mjs'),
|
|
42
53
|
import('shiki/langs/bash.mjs'),
|
|
43
54
|
import('shiki/langs/markdown.mjs'),
|
|
44
|
-
import('shiki/langs/python.mjs')
|
|
55
|
+
import('shiki/langs/python.mjs'),
|
|
56
|
+
import('shiki/langs/yaml.mjs'),
|
|
57
|
+
import('shiki/langs/diff.mjs'),
|
|
58
|
+
import('shiki/langs/css.mjs'),
|
|
59
|
+
import('shiki/langs/html.mjs'),
|
|
60
|
+
import('shiki/langs/xml.mjs'),
|
|
61
|
+
import('shiki/langs/sql.mjs')
|
|
45
62
|
],
|
|
46
63
|
engine: createJavaScriptRegexEngine()
|
|
47
64
|
});
|
|
@@ -65,4 +82,4 @@ async function highlight(code, language) {
|
|
|
65
82
|
}
|
|
66
83
|
|
|
67
84
|
exports.highlight = highlight;
|
|
68
|
-
//# sourceMappingURL=highlight-
|
|
85
|
+
//# sourceMappingURL=highlight-CEt2vhD8.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight-CEt2vhD8.cjs","sources":["../src/ds/components/CodeEditor/highlight.ts"],"sourcesContent":["import type { HighlighterCore, ThemedToken } from 'shiki/core';\n\n/**\n * Languages we support for syntax highlighting in code blocks. A superset of\n * the editable CodeMirror `codeLanguages` set: read-only blocks (markdown\n * fences, chat output) also carry yaml, diff, css, html, xml and sql. Using\n * fine-grained Shiki imports (rather than the full `shiki` bundle) means only\n * these grammars are bundled, instead of a chunk for every language Shiki\n * knows about.\n */\nconst langAliases: Record<string, string> = {\n js: 'javascript',\n javascript: 'javascript',\n mjs: 'javascript',\n cjs: 'javascript',\n node: 'javascript',\n ts: 'typescript',\n typescript: 'typescript',\n mts: 'typescript',\n cts: 'typescript',\n tsx: 'tsx',\n jsx: 'jsx',\n json: 'json',\n json5: 'json',\n md: 'markdown',\n markdown: 'markdown',\n py: 'python',\n python: 'python',\n sh: 'bash',\n bash: 'bash',\n shell: 'bash',\n zsh: 'bash',\n yml: 'yaml',\n yaml: 'yaml',\n diff: 'diff',\n patch: 'diff',\n css: 'css',\n scss: 'css',\n html: 'html',\n htm: 'html',\n xml: 'xml',\n svg: 'xml',\n sql: 'sql',\n};\n\nlet highlighterPromise: Promise<HighlighterCore> | null = null;\n\nfunction getHighlighter(): Promise<HighlighterCore> {\n if (!highlighterPromise) {\n highlighterPromise = (async () => {\n const [{ createHighlighterCore }, { createJavaScriptRegexEngine }] = await Promise.all([\n import('shiki/core'),\n import('shiki/engine/javascript'),\n ]);\n\n return createHighlighterCore({\n themes: [import('shiki/themes/github-light.mjs'), import('shiki/themes/github-dark.mjs')],\n langs: [\n import('shiki/langs/javascript.mjs'),\n import('shiki/langs/typescript.mjs'),\n import('shiki/langs/tsx.mjs'),\n import('shiki/langs/jsx.mjs'),\n import('shiki/langs/json.mjs'),\n import('shiki/langs/bash.mjs'),\n import('shiki/langs/markdown.mjs'),\n import('shiki/langs/python.mjs'),\n import('shiki/langs/yaml.mjs'),\n import('shiki/langs/diff.mjs'),\n import('shiki/langs/css.mjs'),\n import('shiki/langs/html.mjs'),\n import('shiki/langs/xml.mjs'),\n import('shiki/langs/sql.mjs'),\n ],\n engine: createJavaScriptRegexEngine(),\n });\n })();\n }\n\n return highlighterPromise;\n}\n\nexport async function highlight(code: string, language: string): Promise<ThemedToken[][] | null> {\n const lang = langAliases[language?.toLowerCase()];\n if (!lang) return null;\n\n const highlighter = await getHighlighter();\n\n const { tokens } = highlighter.codeToTokens(code, {\n lang,\n defaultColor: false,\n themes: {\n light: 'github-light',\n dark: 'github-dark',\n },\n });\n\n return tokens;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -19,7 +19,18 @@ const langAliases = {
|
|
|
19
19
|
sh: "bash",
|
|
20
20
|
bash: "bash",
|
|
21
21
|
shell: "bash",
|
|
22
|
-
zsh: "bash"
|
|
22
|
+
zsh: "bash",
|
|
23
|
+
yml: "yaml",
|
|
24
|
+
yaml: "yaml",
|
|
25
|
+
diff: "diff",
|
|
26
|
+
patch: "diff",
|
|
27
|
+
css: "css",
|
|
28
|
+
scss: "css",
|
|
29
|
+
html: "html",
|
|
30
|
+
htm: "html",
|
|
31
|
+
xml: "xml",
|
|
32
|
+
svg: "xml",
|
|
33
|
+
sql: "sql"
|
|
23
34
|
};
|
|
24
35
|
let highlighterPromise = null;
|
|
25
36
|
function getHighlighter() {
|
|
@@ -39,7 +50,13 @@ function getHighlighter() {
|
|
|
39
50
|
import('shiki/langs/json.mjs'),
|
|
40
51
|
import('shiki/langs/bash.mjs'),
|
|
41
52
|
import('shiki/langs/markdown.mjs'),
|
|
42
|
-
import('shiki/langs/python.mjs')
|
|
53
|
+
import('shiki/langs/python.mjs'),
|
|
54
|
+
import('shiki/langs/yaml.mjs'),
|
|
55
|
+
import('shiki/langs/diff.mjs'),
|
|
56
|
+
import('shiki/langs/css.mjs'),
|
|
57
|
+
import('shiki/langs/html.mjs'),
|
|
58
|
+
import('shiki/langs/xml.mjs'),
|
|
59
|
+
import('shiki/langs/sql.mjs')
|
|
43
60
|
],
|
|
44
61
|
engine: createJavaScriptRegexEngine()
|
|
45
62
|
});
|
|
@@ -63,4 +80,4 @@ async function highlight(code, language) {
|
|
|
63
80
|
}
|
|
64
81
|
|
|
65
82
|
export { highlight as h };
|
|
66
|
-
//# sourceMappingURL=highlight-
|
|
83
|
+
//# sourceMappingURL=highlight-CSJjjoqh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"highlight-CSJjjoqh.js","sources":["../src/ds/components/CodeEditor/highlight.ts"],"sourcesContent":["import type { HighlighterCore, ThemedToken } from 'shiki/core';\n\n/**\n * Languages we support for syntax highlighting in code blocks. A superset of\n * the editable CodeMirror `codeLanguages` set: read-only blocks (markdown\n * fences, chat output) also carry yaml, diff, css, html, xml and sql. Using\n * fine-grained Shiki imports (rather than the full `shiki` bundle) means only\n * these grammars are bundled, instead of a chunk for every language Shiki\n * knows about.\n */\nconst langAliases: Record<string, string> = {\n js: 'javascript',\n javascript: 'javascript',\n mjs: 'javascript',\n cjs: 'javascript',\n node: 'javascript',\n ts: 'typescript',\n typescript: 'typescript',\n mts: 'typescript',\n cts: 'typescript',\n tsx: 'tsx',\n jsx: 'jsx',\n json: 'json',\n json5: 'json',\n md: 'markdown',\n markdown: 'markdown',\n py: 'python',\n python: 'python',\n sh: 'bash',\n bash: 'bash',\n shell: 'bash',\n zsh: 'bash',\n yml: 'yaml',\n yaml: 'yaml',\n diff: 'diff',\n patch: 'diff',\n css: 'css',\n scss: 'css',\n html: 'html',\n htm: 'html',\n xml: 'xml',\n svg: 'xml',\n sql: 'sql',\n};\n\nlet highlighterPromise: Promise<HighlighterCore> | null = null;\n\nfunction getHighlighter(): Promise<HighlighterCore> {\n if (!highlighterPromise) {\n highlighterPromise = (async () => {\n const [{ createHighlighterCore }, { createJavaScriptRegexEngine }] = await Promise.all([\n import('shiki/core'),\n import('shiki/engine/javascript'),\n ]);\n\n return createHighlighterCore({\n themes: [import('shiki/themes/github-light.mjs'), import('shiki/themes/github-dark.mjs')],\n langs: [\n import('shiki/langs/javascript.mjs'),\n import('shiki/langs/typescript.mjs'),\n import('shiki/langs/tsx.mjs'),\n import('shiki/langs/jsx.mjs'),\n import('shiki/langs/json.mjs'),\n import('shiki/langs/bash.mjs'),\n import('shiki/langs/markdown.mjs'),\n import('shiki/langs/python.mjs'),\n import('shiki/langs/yaml.mjs'),\n import('shiki/langs/diff.mjs'),\n import('shiki/langs/css.mjs'),\n import('shiki/langs/html.mjs'),\n import('shiki/langs/xml.mjs'),\n import('shiki/langs/sql.mjs'),\n ],\n engine: createJavaScriptRegexEngine(),\n });\n })();\n }\n\n return highlighterPromise;\n}\n\nexport async function highlight(code: string, language: string): Promise<ThemedToken[][] | null> {\n const lang = langAliases[language?.toLowerCase()];\n if (!lang) return null;\n\n const highlighter = await getHighlighter();\n\n const { tokens } = highlighter.codeToTokens(code, {\n lang,\n defaultColor: false,\n themes: {\n light: 'github-light',\n dark: 'github-dark',\n },\n });\n\n return tokens;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('./markdown-renderer.css');const jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
const Markdown = require('react-markdown');
|
|
5
|
+
const remarkGfm = require('remark-gfm');
|
|
6
|
+
const codeBlock = require('./code-block-Dn0K3DkE.cjs');
|
|
7
|
+
const utils_cn = require('./cn-vA5sWo9W.cjs');
|
|
8
|
+
|
|
9
|
+
function MarkdownRenderer({ children, className, externalLinkTarget = "tab" }) {
|
|
10
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
11
|
+
Markdown,
|
|
12
|
+
{
|
|
13
|
+
remarkPlugins: [remarkGfm],
|
|
14
|
+
components: externalLinkTarget === "window" ? WINDOW_COMPONENTS : COMPONENTS,
|
|
15
|
+
className: utils_cn.cn("mastra-markdown", className),
|
|
16
|
+
children: decodeEscapedNewlines(children)
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
function decodeEscapedNewlines(text) {
|
|
21
|
+
return text.includes("\n") ? text : text.replace(/\\n/g, "\n");
|
|
22
|
+
}
|
|
23
|
+
function languageOf(node) {
|
|
24
|
+
const classNames = node.properties.className;
|
|
25
|
+
if (!Array.isArray(classNames)) return void 0;
|
|
26
|
+
const language = classNames.find((entry) => typeof entry === "string" && entry.startsWith("language-"));
|
|
27
|
+
return typeof language === "string" ? language.slice("language-".length) : void 0;
|
|
28
|
+
}
|
|
29
|
+
function fencedCode(node) {
|
|
30
|
+
const child = node?.children.find((entry) => entry.type === "element" && entry.tagName === "code");
|
|
31
|
+
if (child?.type !== "element") return void 0;
|
|
32
|
+
const code = child.children.map((entry) => entry.type === "text" ? entry.value : "").join("");
|
|
33
|
+
return { code: code.replace(/\n$/, ""), language: languageOf(child) };
|
|
34
|
+
}
|
|
35
|
+
function MarkdownCodeBlock({ node, children }) {
|
|
36
|
+
const fenced = fencedCode(node);
|
|
37
|
+
if (!fenced) return /* @__PURE__ */ jsxRuntime.jsx("pre", { children });
|
|
38
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
39
|
+
codeBlock.CodeBlock,
|
|
40
|
+
{
|
|
41
|
+
code: fenced.code,
|
|
42
|
+
lang: fenced.language,
|
|
43
|
+
overflow: "scroll",
|
|
44
|
+
className: "bg-surface1 my-3",
|
|
45
|
+
copyMessage: "Copied code to clipboard"
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
const POPUP_WINDOW_FEATURES = "popup=yes,width=720,height=800,resizable=yes,scrollbars=yes";
|
|
50
|
+
function isPlainLeftClick(event) {
|
|
51
|
+
return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;
|
|
52
|
+
}
|
|
53
|
+
function markdownLink(externalLinkTarget) {
|
|
54
|
+
return function MarkdownLink({ href, title, children }) {
|
|
55
|
+
const isExternal = /^https?:\/\//i.test(href ?? "");
|
|
56
|
+
const openInPopup = (event) => {
|
|
57
|
+
if (!isExternal || externalLinkTarget !== "window" || !isPlainLeftClick(event)) return;
|
|
58
|
+
const popup = window.open(href, "_blank", POPUP_WINDOW_FEATURES);
|
|
59
|
+
if (!popup) return;
|
|
60
|
+
popup.opener = null;
|
|
61
|
+
event.preventDefault();
|
|
62
|
+
};
|
|
63
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
64
|
+
"a",
|
|
65
|
+
{
|
|
66
|
+
href,
|
|
67
|
+
title,
|
|
68
|
+
onClick: openInPopup,
|
|
69
|
+
target: isExternal ? "_blank" : void 0,
|
|
70
|
+
rel: isExternal ? "noopener noreferrer" : void 0,
|
|
71
|
+
children
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const COMPONENTS = {
|
|
77
|
+
pre: MarkdownCodeBlock,
|
|
78
|
+
a: markdownLink("tab")
|
|
79
|
+
};
|
|
80
|
+
const WINDOW_COMPONENTS = {
|
|
81
|
+
...COMPONENTS,
|
|
82
|
+
a: markdownLink("window")
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
exports.MarkdownRenderer = MarkdownRenderer;
|
|
86
|
+
//# sourceMappingURL=markdown-renderer-D1vSFfp9.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-renderer-D1vSFfp9.cjs","sources":["../src/ds/components/MarkdownRenderer/markdown-renderer.tsx"],"sourcesContent":["import type { MouseEvent, MouseEventHandler, ReactNode } from 'react';\nimport Markdown from 'react-markdown';\nimport type { Components, ExtraProps } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport { CodeBlock } from '@/ds/components/CodeBlock';\nimport { cn } from '@/lib/utils';\n\nimport './markdown-renderer.css';\n\nexport type MarkdownExternalLinkTarget = 'tab' | 'window';\n\nexport interface MarkdownRendererProps {\n children: string;\n className?: string;\n externalLinkTarget?: MarkdownExternalLinkTarget;\n}\n\n/**\n * Renders a markdown string. Agent output can carry attacker-influenced text\n * (file contents, tool output, web pages): react-markdown escapes raw HTML and\n * drops dangerous link schemes, so nothing here reaches the DOM as markup.\n */\nexport function MarkdownRenderer({ children, className, externalLinkTarget = 'tab' }: MarkdownRendererProps) {\n return (\n <Markdown\n remarkPlugins={[remarkGfm]}\n components={externalLinkTarget === 'window' ? WINDOW_COMPONENTS : COMPONENTS}\n className={cn('mastra-markdown', className)}\n >\n {decodeEscapedNewlines(children)}\n </Markdown>\n );\n}\n\n// Agent networks emit their text with literal `\\n`. Only unescape when the text\n// has no real newline, otherwise a `\"a\\nb\"` inside a code fence gets shredded.\nfunction decodeEscapedNewlines(text: string): string {\n return text.includes('\\n') ? text : text.replace(/\\\\n/g, '\\n');\n}\n\ntype MarkdownNode = NonNullable<ExtraProps['node']>;\n\nfunction languageOf(node: MarkdownNode): string | undefined {\n const classNames = node.properties.className;\n if (!Array.isArray(classNames)) return undefined;\n\n const language = classNames.find(entry => typeof entry === 'string' && entry.startsWith('language-'));\n return typeof language === 'string' ? language.slice('language-'.length) : undefined;\n}\n\nfunction fencedCode(node: MarkdownNode | undefined): { code: string; language?: string } | undefined {\n const child = node?.children.find(entry => entry.type === 'element' && entry.tagName === 'code');\n if (child?.type !== 'element') return undefined;\n\n const code = child.children.map(entry => (entry.type === 'text' ? entry.value : '')).join('');\n return { code: code.replace(/\\n$/, ''), language: languageOf(child) };\n}\n\nfunction MarkdownCodeBlock({ node, children }: { node?: MarkdownNode; children?: ReactNode }) {\n const fenced = fencedCode(node);\n if (!fenced) return <pre>{children}</pre>;\n\n return (\n <CodeBlock\n code={fenced.code}\n lang={fenced.language}\n overflow=\"scroll\"\n className=\"bg-surface1 my-3\"\n copyMessage=\"Copied code to clipboard\"\n />\n );\n}\n\nconst POPUP_WINDOW_FEATURES = 'popup=yes,width=720,height=800,resizable=yes,scrollbars=yes';\n\nfunction isPlainLeftClick(event: MouseEvent): boolean {\n return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;\n}\n\nfunction markdownLink(externalLinkTarget: MarkdownExternalLinkTarget): NonNullable<Components['a']> {\n return function MarkdownLink({ href, title, children }) {\n const isExternal = /^https?:\\/\\//i.test(href ?? '');\n\n const openInPopup: MouseEventHandler<HTMLAnchorElement> = event => {\n if (!isExternal || externalLinkTarget !== 'window' || !isPlainLeftClick(event)) return;\n\n const popup = window.open(href, '_blank', POPUP_WINDOW_FEATURES);\n if (!popup) return;\n\n popup.opener = null;\n event.preventDefault();\n };\n\n return (\n <a\n href={href}\n title={title}\n onClick={openInPopup}\n target={isExternal ? '_blank' : undefined}\n rel={isExternal ? 'noopener noreferrer' : undefined}\n >\n {children}\n </a>\n );\n };\n}\n\n// Elements are listed one by one: react-markdown also passes its `node`, which\n// React would forward to the DOM as a stray attribute. Everything else is\n// styled from markdown-renderer.css.\nconst COMPONENTS: Components = {\n pre: MarkdownCodeBlock,\n a: markdownLink('tab'),\n};\n\nconst WINDOW_COMPONENTS: Components = {\n ...COMPONENTS,\n a: markdownLink('window'),\n};\n"],"names":["jsx","cn","CodeBlock"],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import Markdown from 'react-markdown';
|
|
3
|
+
import remarkGfm from 'remark-gfm';
|
|
4
|
+
import { C as CodeBlock } from './code-block-DqKXZajq.js';
|
|
5
|
+
import { c as cn } from './cn-BakJzhuv.js';
|
|
6
|
+
|
|
7
|
+
import './markdown-renderer.css';function MarkdownRenderer({ children, className, externalLinkTarget = "tab" }) {
|
|
8
|
+
return /* @__PURE__ */ jsx(
|
|
9
|
+
Markdown,
|
|
10
|
+
{
|
|
11
|
+
remarkPlugins: [remarkGfm],
|
|
12
|
+
components: externalLinkTarget === "window" ? WINDOW_COMPONENTS : COMPONENTS,
|
|
13
|
+
className: cn("mastra-markdown", className),
|
|
14
|
+
children: decodeEscapedNewlines(children)
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
function decodeEscapedNewlines(text) {
|
|
19
|
+
return text.includes("\n") ? text : text.replace(/\\n/g, "\n");
|
|
20
|
+
}
|
|
21
|
+
function languageOf(node) {
|
|
22
|
+
const classNames = node.properties.className;
|
|
23
|
+
if (!Array.isArray(classNames)) return void 0;
|
|
24
|
+
const language = classNames.find((entry) => typeof entry === "string" && entry.startsWith("language-"));
|
|
25
|
+
return typeof language === "string" ? language.slice("language-".length) : void 0;
|
|
26
|
+
}
|
|
27
|
+
function fencedCode(node) {
|
|
28
|
+
const child = node?.children.find((entry) => entry.type === "element" && entry.tagName === "code");
|
|
29
|
+
if (child?.type !== "element") return void 0;
|
|
30
|
+
const code = child.children.map((entry) => entry.type === "text" ? entry.value : "").join("");
|
|
31
|
+
return { code: code.replace(/\n$/, ""), language: languageOf(child) };
|
|
32
|
+
}
|
|
33
|
+
function MarkdownCodeBlock({ node, children }) {
|
|
34
|
+
const fenced = fencedCode(node);
|
|
35
|
+
if (!fenced) return /* @__PURE__ */ jsx("pre", { children });
|
|
36
|
+
return /* @__PURE__ */ jsx(
|
|
37
|
+
CodeBlock,
|
|
38
|
+
{
|
|
39
|
+
code: fenced.code,
|
|
40
|
+
lang: fenced.language,
|
|
41
|
+
overflow: "scroll",
|
|
42
|
+
className: "bg-surface1 my-3",
|
|
43
|
+
copyMessage: "Copied code to clipboard"
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
const POPUP_WINDOW_FEATURES = "popup=yes,width=720,height=800,resizable=yes,scrollbars=yes";
|
|
48
|
+
function isPlainLeftClick(event) {
|
|
49
|
+
return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;
|
|
50
|
+
}
|
|
51
|
+
function markdownLink(externalLinkTarget) {
|
|
52
|
+
return function MarkdownLink({ href, title, children }) {
|
|
53
|
+
const isExternal = /^https?:\/\//i.test(href ?? "");
|
|
54
|
+
const openInPopup = (event) => {
|
|
55
|
+
if (!isExternal || externalLinkTarget !== "window" || !isPlainLeftClick(event)) return;
|
|
56
|
+
const popup = window.open(href, "_blank", POPUP_WINDOW_FEATURES);
|
|
57
|
+
if (!popup) return;
|
|
58
|
+
popup.opener = null;
|
|
59
|
+
event.preventDefault();
|
|
60
|
+
};
|
|
61
|
+
return /* @__PURE__ */ jsx(
|
|
62
|
+
"a",
|
|
63
|
+
{
|
|
64
|
+
href,
|
|
65
|
+
title,
|
|
66
|
+
onClick: openInPopup,
|
|
67
|
+
target: isExternal ? "_blank" : void 0,
|
|
68
|
+
rel: isExternal ? "noopener noreferrer" : void 0,
|
|
69
|
+
children
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const COMPONENTS = {
|
|
75
|
+
pre: MarkdownCodeBlock,
|
|
76
|
+
a: markdownLink("tab")
|
|
77
|
+
};
|
|
78
|
+
const WINDOW_COMPONENTS = {
|
|
79
|
+
...COMPONENTS,
|
|
80
|
+
a: markdownLink("window")
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export { MarkdownRenderer as M };
|
|
84
|
+
//# sourceMappingURL=markdown-renderer-DmYYQHxu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown-renderer-DmYYQHxu.js","sources":["../src/ds/components/MarkdownRenderer/markdown-renderer.tsx"],"sourcesContent":["import type { MouseEvent, MouseEventHandler, ReactNode } from 'react';\nimport Markdown from 'react-markdown';\nimport type { Components, ExtraProps } from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\n\nimport { CodeBlock } from '@/ds/components/CodeBlock';\nimport { cn } from '@/lib/utils';\n\nimport './markdown-renderer.css';\n\nexport type MarkdownExternalLinkTarget = 'tab' | 'window';\n\nexport interface MarkdownRendererProps {\n children: string;\n className?: string;\n externalLinkTarget?: MarkdownExternalLinkTarget;\n}\n\n/**\n * Renders a markdown string. Agent output can carry attacker-influenced text\n * (file contents, tool output, web pages): react-markdown escapes raw HTML and\n * drops dangerous link schemes, so nothing here reaches the DOM as markup.\n */\nexport function MarkdownRenderer({ children, className, externalLinkTarget = 'tab' }: MarkdownRendererProps) {\n return (\n <Markdown\n remarkPlugins={[remarkGfm]}\n components={externalLinkTarget === 'window' ? WINDOW_COMPONENTS : COMPONENTS}\n className={cn('mastra-markdown', className)}\n >\n {decodeEscapedNewlines(children)}\n </Markdown>\n );\n}\n\n// Agent networks emit their text with literal `\\n`. Only unescape when the text\n// has no real newline, otherwise a `\"a\\nb\"` inside a code fence gets shredded.\nfunction decodeEscapedNewlines(text: string): string {\n return text.includes('\\n') ? text : text.replace(/\\\\n/g, '\\n');\n}\n\ntype MarkdownNode = NonNullable<ExtraProps['node']>;\n\nfunction languageOf(node: MarkdownNode): string | undefined {\n const classNames = node.properties.className;\n if (!Array.isArray(classNames)) return undefined;\n\n const language = classNames.find(entry => typeof entry === 'string' && entry.startsWith('language-'));\n return typeof language === 'string' ? language.slice('language-'.length) : undefined;\n}\n\nfunction fencedCode(node: MarkdownNode | undefined): { code: string; language?: string } | undefined {\n const child = node?.children.find(entry => entry.type === 'element' && entry.tagName === 'code');\n if (child?.type !== 'element') return undefined;\n\n const code = child.children.map(entry => (entry.type === 'text' ? entry.value : '')).join('');\n return { code: code.replace(/\\n$/, ''), language: languageOf(child) };\n}\n\nfunction MarkdownCodeBlock({ node, children }: { node?: MarkdownNode; children?: ReactNode }) {\n const fenced = fencedCode(node);\n if (!fenced) return <pre>{children}</pre>;\n\n return (\n <CodeBlock\n code={fenced.code}\n lang={fenced.language}\n overflow=\"scroll\"\n className=\"bg-surface1 my-3\"\n copyMessage=\"Copied code to clipboard\"\n />\n );\n}\n\nconst POPUP_WINDOW_FEATURES = 'popup=yes,width=720,height=800,resizable=yes,scrollbars=yes';\n\nfunction isPlainLeftClick(event: MouseEvent): boolean {\n return event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;\n}\n\nfunction markdownLink(externalLinkTarget: MarkdownExternalLinkTarget): NonNullable<Components['a']> {\n return function MarkdownLink({ href, title, children }) {\n const isExternal = /^https?:\\/\\//i.test(href ?? '');\n\n const openInPopup: MouseEventHandler<HTMLAnchorElement> = event => {\n if (!isExternal || externalLinkTarget !== 'window' || !isPlainLeftClick(event)) return;\n\n const popup = window.open(href, '_blank', POPUP_WINDOW_FEATURES);\n if (!popup) return;\n\n popup.opener = null;\n event.preventDefault();\n };\n\n return (\n <a\n href={href}\n title={title}\n onClick={openInPopup}\n target={isExternal ? '_blank' : undefined}\n rel={isExternal ? 'noopener noreferrer' : undefined}\n >\n {children}\n </a>\n );\n };\n}\n\n// Elements are listed one by one: react-markdown also passes its `node`, which\n// React would forward to the DOM as a stray attribute. Everything else is\n// styled from markdown-renderer.css.\nconst COMPONENTS: Components = {\n pre: MarkdownCodeBlock,\n a: markdownLink('tab'),\n};\n\nconst WINDOW_COMPONENTS: Components = {\n ...COMPONENTS,\n a: markdownLink('window'),\n};\n"],"names":[],"mappings":"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"}
|