@agent-native/core 0.128.2 → 0.128.4
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/corpus/core/CHANGELOG.md +13 -0
- package/corpus/core/package.json +1 -1
- package/corpus/core/src/client/chat/legacy-chart-shorthand.tsx +479 -0
- package/corpus/core/src/client/chat/markdown-renderer.tsx +23 -3
- package/corpus/core/src/extensions/actions.ts +1 -1
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +12 -0
- package/corpus/templates/analytics/actions/generate-chart.ts +2 -2
- package/corpus/templates/chat/README.md +2 -0
- package/dist/client/chat/legacy-chart-shorthand.d.ts +29 -0
- package/dist/client/chat/legacy-chart-shorthand.d.ts.map +1 -0
- package/dist/client/chat/legacy-chart-shorthand.js +330 -0
- package/dist/client/chat/legacy-chart-shorthand.js.map +1 -0
- package/dist/client/chat/markdown-renderer.d.ts.map +1 -1
- package/dist/client/chat/markdown-renderer.js +8 -2
- package/dist/client/chat/markdown-renderer.js.map +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/extensions/actions.js +1 -1
- package/dist/extensions/actions.js.map +1 -1
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/observability/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/templates/chat/README.md +2 -0
- package/package.json +3 -3
- package/src/client/chat/legacy-chart-shorthand.tsx +479 -0
- package/src/client/chat/markdown-renderer.tsx +23 -3
- package/src/extensions/actions.ts +1 -1
- package/src/templates/chat/README.md +2 -0
- package/corpus/core/src/cli/sync-builder-starter-manifest.ts +0 -631
- package/dist/cli/sync-builder-starter-manifest.d.ts +0 -79
- package/dist/cli/sync-builder-starter-manifest.d.ts.map +0 -1
- package/dist/cli/sync-builder-starter-manifest.js +0 -426
- package/dist/cli/sync-builder-starter-manifest.js.map +0 -1
- package/src/cli/sync-builder-starter-manifest.ts +0 -631
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// Some tool schemas expose chart parameters named `type`/`title`/`labels`/
|
|
3
|
+
// `data` (e.g. a chart-generation action). Models occasionally regress to
|
|
4
|
+
// typing those parameter names as a bare chat line instead of calling the
|
|
5
|
+
// tool or emitting a real ```embed fence, e.g.:
|
|
6
|
+
// /chart type=bar title="..." labels=["Mon","Tue"] data=[5,8]
|
|
7
|
+
// That has no real markdown syntax and would otherwise render as inert text.
|
|
8
|
+
// This module detects that generic shape (any "/word ... labels=[...]
|
|
9
|
+
// data=[...]" line) and renders a best-effort inline chart so the user still
|
|
10
|
+
// sees something useful, without hardcoding any single template's tool name.
|
|
11
|
+
import React from "react";
|
|
12
|
+
export const LEGACY_CHART_SHORTHAND_LANG = "chart-shorthand";
|
|
13
|
+
const LEGACY_CHART_PALETTE = [
|
|
14
|
+
"#6366f1",
|
|
15
|
+
"#22c55e",
|
|
16
|
+
"#f59e0b",
|
|
17
|
+
"#ef4444",
|
|
18
|
+
"#0ea5e9",
|
|
19
|
+
"#a855f7",
|
|
20
|
+
];
|
|
21
|
+
const SAFE_HEX_COLOR = /^#[0-9a-fA-F]{3,8}$/;
|
|
22
|
+
const BACKSLASH = String.fromCharCode(92);
|
|
23
|
+
const MAX_LINE_LENGTH = 20_000;
|
|
24
|
+
const MAX_LABELS = 60;
|
|
25
|
+
const MAX_SERIES = 6;
|
|
26
|
+
// Extracts a balanced JSON array/object starting exactly at `startIndex`
|
|
27
|
+
// (which must point at "["), tracking string/escape state so brackets or
|
|
28
|
+
// braces inside JSON string values don't confuse the boundary.
|
|
29
|
+
function extractBalancedArrayAt(text, startIndex) {
|
|
30
|
+
if (text[startIndex] !== "[")
|
|
31
|
+
return null;
|
|
32
|
+
let depth = 0;
|
|
33
|
+
let inString = false;
|
|
34
|
+
for (let idx = startIndex; idx < text.length; idx++) {
|
|
35
|
+
const ch = text[idx];
|
|
36
|
+
if (inString) {
|
|
37
|
+
if (ch === "\\")
|
|
38
|
+
idx++; // skip escaped character, including \"
|
|
39
|
+
else if (ch === '"')
|
|
40
|
+
inString = false;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (ch === '"')
|
|
44
|
+
inString = true;
|
|
45
|
+
else if (ch === "[" || ch === "{")
|
|
46
|
+
depth++;
|
|
47
|
+
else if (ch === "]" || ch === "}") {
|
|
48
|
+
depth--;
|
|
49
|
+
if (depth === 0)
|
|
50
|
+
return text.slice(startIndex, idx + 1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
// Marks which character indices fall inside a JSON/quoted-string literal so
|
|
56
|
+
// key-token scanning can ignore false matches such as a key= that's part of
|
|
57
|
+
// a title string, or embedded in a label's own text, rather than a real
|
|
58
|
+
// assignment in the line.
|
|
59
|
+
function computeStringMask(text) {
|
|
60
|
+
const mask = new Array(text.length).fill(false);
|
|
61
|
+
let inString = false;
|
|
62
|
+
for (let i = 0; i < text.length; i++) {
|
|
63
|
+
mask[i] = inString;
|
|
64
|
+
const ch = text[i];
|
|
65
|
+
if (inString) {
|
|
66
|
+
if (ch === BACKSLASH) {
|
|
67
|
+
i++;
|
|
68
|
+
if (i < text.length)
|
|
69
|
+
mask[i] = true;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (ch === '"')
|
|
73
|
+
inString = false;
|
|
74
|
+
}
|
|
75
|
+
else if (ch === '"') {
|
|
76
|
+
inString = true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return mask;
|
|
80
|
+
}
|
|
81
|
+
// Finds the array value immediately following a `key=` token, scanning every
|
|
82
|
+
// occurrence of `key=` outside of quoted strings (not just the first) so a
|
|
83
|
+
// `key=` that appears inside an unrelated quoted string (e.g.
|
|
84
|
+
// title="data=quality", or a label literally containing "data=[1,2]") is
|
|
85
|
+
// skipped in favor of the real one. Only whitespace is allowed between
|
|
86
|
+
// `key=` and the `[`.
|
|
87
|
+
function extractArrayForKey(text, key) {
|
|
88
|
+
const mask = computeStringMask(text);
|
|
89
|
+
const re = new RegExp(`\\b${key}=`, "g");
|
|
90
|
+
let match;
|
|
91
|
+
while ((match = re.exec(text))) {
|
|
92
|
+
if (mask[match.index])
|
|
93
|
+
continue; // this key= is inside a string literal
|
|
94
|
+
let idx = match.index + match[0].length;
|
|
95
|
+
while (idx < text.length && /\s/.test(text[idx]))
|
|
96
|
+
idx++;
|
|
97
|
+
const arr = extractBalancedArrayAt(text, idx);
|
|
98
|
+
if (arr)
|
|
99
|
+
return arr;
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
// Extracts the value of a `title="..."`/`title='...'` token, honoring
|
|
104
|
+
// backslash-escaped quotes and backslashes inside the string (e.g.
|
|
105
|
+
// title="Sales \"Metrics\"") instead of stopping at the first escaped quote.
|
|
106
|
+
function extractLegacyChartTitle(text) {
|
|
107
|
+
const match = /\btitle=/.exec(text);
|
|
108
|
+
if (!match)
|
|
109
|
+
return "";
|
|
110
|
+
let idx = match.index + match[0].length;
|
|
111
|
+
const quoteChar = text[idx];
|
|
112
|
+
if (quoteChar !== '"' && quoteChar !== "'")
|
|
113
|
+
return "";
|
|
114
|
+
idx++;
|
|
115
|
+
let result = "";
|
|
116
|
+
while (idx < text.length) {
|
|
117
|
+
const ch = text[idx];
|
|
118
|
+
if (ch === BACKSLASH && idx + 1 < text.length) {
|
|
119
|
+
const next = text[idx + 1];
|
|
120
|
+
if (next === quoteChar || next === BACKSLASH) {
|
|
121
|
+
result += next;
|
|
122
|
+
idx += 2;
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (ch === quoteChar)
|
|
127
|
+
return result;
|
|
128
|
+
result += ch;
|
|
129
|
+
idx++;
|
|
130
|
+
}
|
|
131
|
+
return "";
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Cheap-ish pre-check so callers can skip the full parse on ordinary text.
|
|
135
|
+
* Requires `labels=`/`data=` to actually resolve to bracketed arrays (not
|
|
136
|
+
* just appear as substrings) so unrelated slash commands or API paths that
|
|
137
|
+
* happen to mention both words aren't diverted out of normal markdown
|
|
138
|
+
* rendering.
|
|
139
|
+
*/
|
|
140
|
+
export function looksLikeLegacyChartShorthand(line) {
|
|
141
|
+
const trimmed = line.trim();
|
|
142
|
+
if (trimmed.length === 0 || trimmed.length > MAX_LINE_LENGTH)
|
|
143
|
+
return false;
|
|
144
|
+
if (!/^\/[a-zA-Z][\w-]*\b/.test(trimmed))
|
|
145
|
+
return false;
|
|
146
|
+
if (!/\blabels=/.test(trimmed) || !/\bdata=/.test(trimmed))
|
|
147
|
+
return false;
|
|
148
|
+
return (extractArrayForKey(trimmed, "labels") !== null &&
|
|
149
|
+
extractArrayForKey(trimmed, "data") !== null);
|
|
150
|
+
}
|
|
151
|
+
export function parseLegacyChartShorthand(rawLine) {
|
|
152
|
+
const trimmed = rawLine.trim();
|
|
153
|
+
if (!looksLikeLegacyChartShorthand(trimmed))
|
|
154
|
+
return null;
|
|
155
|
+
const typeMatch = trimmed.match(/\btype=(bar|line|area)\b/i);
|
|
156
|
+
const chartType = typeMatch?.[1].toLowerCase() || "bar";
|
|
157
|
+
const chartTitle = extractLegacyChartTitle(trimmed);
|
|
158
|
+
const labelsRaw = extractArrayForKey(trimmed, "labels");
|
|
159
|
+
const dataRaw = extractArrayForKey(trimmed, "data");
|
|
160
|
+
if (!labelsRaw || !dataRaw)
|
|
161
|
+
return null;
|
|
162
|
+
let parsedLabels;
|
|
163
|
+
let parsedData;
|
|
164
|
+
try {
|
|
165
|
+
parsedLabels = JSON.parse(labelsRaw);
|
|
166
|
+
parsedData = JSON.parse(dataRaw);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
if (!Array.isArray(parsedLabels) ||
|
|
172
|
+
parsedLabels.length === 0 ||
|
|
173
|
+
parsedLabels.length > MAX_LABELS ||
|
|
174
|
+
// Reject nested arrays/objects as labels — String(nestedArray) recurses
|
|
175
|
+
// through Array.prototype.join and can throw on deeply nested input.
|
|
176
|
+
!parsedLabels.every((l) => ["string", "number", "boolean"].includes(typeof l))) {
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
const safeLabels = parsedLabels.map((l) => String(l));
|
|
180
|
+
const isValidSeriesData = (values) => Array.isArray(values) &&
|
|
181
|
+
values.length === safeLabels.length &&
|
|
182
|
+
values.every((v) => typeof v === "number" && Number.isFinite(v) && v >= 0);
|
|
183
|
+
const colorMatch = trimmed.match(/(?:^|\s)color=(#[0-9a-fA-F]{3,8})\b/);
|
|
184
|
+
const topLevelColor = colorMatch && SAFE_HEX_COLOR.test(colorMatch[1])
|
|
185
|
+
? colorMatch[1]
|
|
186
|
+
: undefined;
|
|
187
|
+
let chartSeries;
|
|
188
|
+
if (isValidSeriesData(parsedData)) {
|
|
189
|
+
chartSeries = [
|
|
190
|
+
{ label: chartTitle || "Value", data: parsedData, color: topLevelColor },
|
|
191
|
+
];
|
|
192
|
+
}
|
|
193
|
+
else if (Array.isArray(parsedData) &&
|
|
194
|
+
parsedData.length > 0 &&
|
|
195
|
+
// Reject rather than silently truncate an over-limit series count:
|
|
196
|
+
// presenting a partial chart as complete is worse than plain text.
|
|
197
|
+
parsedData.length <= MAX_SERIES &&
|
|
198
|
+
parsedData.every((d) => d &&
|
|
199
|
+
typeof d === "object" &&
|
|
200
|
+
isValidSeriesData(d.data))) {
|
|
201
|
+
chartSeries = parsedData.map((d, idx) => ({
|
|
202
|
+
label: typeof d.label === "string" ? d.label : `Series ${idx + 1}`,
|
|
203
|
+
data: d.data,
|
|
204
|
+
color: typeof d.color === "string" && SAFE_HEX_COLOR.test(d.color)
|
|
205
|
+
? d.color
|
|
206
|
+
: undefined,
|
|
207
|
+
}));
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
if (chartSeries.length === 0)
|
|
213
|
+
return null;
|
|
214
|
+
return {
|
|
215
|
+
type: chartType,
|
|
216
|
+
title: chartTitle,
|
|
217
|
+
labels: safeLabels,
|
|
218
|
+
series: chartSeries,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
// Wraps any line matching the legacy shorthand shape in a fenced code block
|
|
222
|
+
// tagged `chart-shorthand`, so it routes through markdownComponents.pre()
|
|
223
|
+
// like any other language fence instead of rendering as inert prose.
|
|
224
|
+
// Fence/indented-code tracking mirrors ../../shared/markdown-block-split.ts
|
|
225
|
+
// (marker char + length, indented-code detection) so real code blocks —
|
|
226
|
+
// including ~~~ fences, longer-than-3 fences, and 4-space/tab indented code —
|
|
227
|
+
// are never mistaken for chat prose and rewritten.
|
|
228
|
+
export function wrapLegacyChartShorthandLines(markdown) {
|
|
229
|
+
if (!markdown.includes("labels=") || !markdown.includes("data=")) {
|
|
230
|
+
return markdown;
|
|
231
|
+
}
|
|
232
|
+
let fenceMarker = ""; // non-empty while inside a ``` or ~~~ fence
|
|
233
|
+
const lines = markdown.split("\n");
|
|
234
|
+
const out = [];
|
|
235
|
+
for (const line of lines) {
|
|
236
|
+
// CommonMark: a line indented 4+ spaces (or a tab) is an indented code
|
|
237
|
+
// block, not a fence marker. Check this first so a literal four-space
|
|
238
|
+
// " ```" example in a message doesn't toggle fence state.
|
|
239
|
+
if (/^(?: {4}|\t)/.test(line)) {
|
|
240
|
+
out.push(line);
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
const trimmed = line.trimStart();
|
|
244
|
+
if (fenceMarker) {
|
|
245
|
+
out.push(line);
|
|
246
|
+
const closeMatch = /^(`{3,}|~{3,})\s*$/.exec(trimmed);
|
|
247
|
+
if (closeMatch &&
|
|
248
|
+
closeMatch[1].charAt(0) === fenceMarker.charAt(0) &&
|
|
249
|
+
closeMatch[1].length >= fenceMarker.length) {
|
|
250
|
+
fenceMarker = "";
|
|
251
|
+
}
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
const openMatch = /^(`{3,}|~{3,})/.exec(trimmed);
|
|
255
|
+
if (openMatch) {
|
|
256
|
+
fenceMarker = openMatch[1].charAt(0).repeat(openMatch[1].length);
|
|
257
|
+
out.push(line);
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
if (looksLikeLegacyChartShorthand(line)) {
|
|
261
|
+
// Preserve the line's own indentation on the emitted fence so
|
|
262
|
+
// shorthand inside a list item or blockquote continuation stays part
|
|
263
|
+
// of that container instead of being dedented to a top-level block.
|
|
264
|
+
const leadingWs = line.match(/^\s*/)?.[0] ?? "";
|
|
265
|
+
out.push(leadingWs + "```" + LEGACY_CHART_SHORTHAND_LANG, leadingWs + line.trim(), leadingWs + "```");
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
out.push(line);
|
|
269
|
+
}
|
|
270
|
+
return out.join("\n");
|
|
271
|
+
}
|
|
272
|
+
export function LegacyChartShorthandFallback({ text }) {
|
|
273
|
+
return _jsx("span", { style: { whiteSpace: "pre-wrap" }, children: text });
|
|
274
|
+
}
|
|
275
|
+
export function LegacyChartShorthandChart({ parsed, }) {
|
|
276
|
+
const { title, labels, series, type } = parsed;
|
|
277
|
+
const width = 640;
|
|
278
|
+
const height = 280;
|
|
279
|
+
const padding = { top: 16, right: 16, bottom: 44, left: 48 };
|
|
280
|
+
const innerW = width - padding.left - padding.right;
|
|
281
|
+
const innerH = height - padding.top - padding.bottom;
|
|
282
|
+
const maxVal = Math.max(1, series.reduce((acc, s) => s.data.reduce((seriesAcc, v) => Math.max(seriesAcc, v), acc), 0));
|
|
283
|
+
const groupW = innerW / labels.length;
|
|
284
|
+
const gridLineCount = 4;
|
|
285
|
+
const gridLines = Array.from({ length: gridLineCount + 1 }, (_, g) => {
|
|
286
|
+
const y = padding.top + (innerH * g) / gridLineCount;
|
|
287
|
+
const val = Math.round(maxVal - (maxVal * g) / gridLineCount);
|
|
288
|
+
return { y, val };
|
|
289
|
+
});
|
|
290
|
+
const colorFor = (s, si) => s.color || LEGACY_CHART_PALETTE[si % LEGACY_CHART_PALETTE.length];
|
|
291
|
+
return (_jsxs("div", { className: "my-4 rounded-lg border border-border bg-muted/20 p-3", children: [title && (_jsx("div", { className: "mb-1 text-sm font-medium text-foreground", children: title })), _jsxs("svg", { viewBox: `0 0 ${width} ${height}`, className: "w-full text-muted-foreground", role: "img", "aria-label": title || "Chart", children: [gridLines.map(({ y, val }, i) => (_jsxs(React.Fragment, { children: [_jsx("line", { x1: padding.left, y1: y, x2: width - padding.right, y2: y, stroke: "currentColor", strokeOpacity: 0.1 }), _jsx("text", { x: padding.left - 8, y: y + 4, textAnchor: "end", fontSize: 10, fill: "currentColor", fillOpacity: 0.6, children: val })] }, i))), type === "bar" &&
|
|
292
|
+
labels.map((_, li) => {
|
|
293
|
+
const groupPad = groupW * 0.15;
|
|
294
|
+
const barsW = groupW - groupPad * 2;
|
|
295
|
+
const barW = barsW / series.length;
|
|
296
|
+
return series.map((s, si) => {
|
|
297
|
+
const value = s.data[li] ?? 0;
|
|
298
|
+
const barH = (Math.max(0, value) / maxVal) * innerH;
|
|
299
|
+
const x = padding.left + li * groupW + groupPad + si * barW;
|
|
300
|
+
const y = padding.top + (innerH - barH);
|
|
301
|
+
return (_jsx("rect", { x: x, y: y, width: Math.max(1, barW - 2), height: Math.max(0, barH), fill: colorFor(s, si), rx: 2 }, `${li}-${si}`));
|
|
302
|
+
});
|
|
303
|
+
}), type !== "bar" &&
|
|
304
|
+
series.map((s, si) => {
|
|
305
|
+
const coords = labels.map((_, li) => {
|
|
306
|
+
const value = s.data[li] ?? 0;
|
|
307
|
+
const x = padding.left + groupW * li + groupW / 2;
|
|
308
|
+
const y = padding.top + innerH - (Math.max(0, value) / maxVal) * innerH;
|
|
309
|
+
return { x, y };
|
|
310
|
+
});
|
|
311
|
+
if (coords.length === 1) {
|
|
312
|
+
// A single point has no line segment to draw — render a marker
|
|
313
|
+
// instead of an invisible zero-length polyline.
|
|
314
|
+
return (_jsx("circle", { cx: coords[0].x, cy: coords[0].y, r: 4, fill: colorFor(s, si) }, si));
|
|
315
|
+
}
|
|
316
|
+
const points = coords
|
|
317
|
+
.map(({ x, y }) => `${x.toFixed(1)},${y.toFixed(1)}`)
|
|
318
|
+
.join(" ");
|
|
319
|
+
const baseY = padding.top + innerH;
|
|
320
|
+
const firstX = padding.left + groupW / 2;
|
|
321
|
+
const lastX = padding.left + groupW * (labels.length - 1) + groupW / 2;
|
|
322
|
+
return (_jsxs(React.Fragment, { children: [type === "area" && (_jsx("polygon", { points: `${firstX.toFixed(1)},${baseY.toFixed(1)} ${points} ${lastX.toFixed(1)},${baseY.toFixed(1)}`, fill: colorFor(s, si), fillOpacity: 0.15 })), _jsx("polyline", { points: points, fill: "none", stroke: colorFor(s, si), strokeWidth: 2 })] }, si));
|
|
323
|
+
}), labels.map((label, li) => {
|
|
324
|
+
const x = padding.left + groupW * li + groupW / 2;
|
|
325
|
+
const y = height - padding.bottom + 16;
|
|
326
|
+
const truncated = label.length > 12 ? `${label.slice(0, 11)}...` : label;
|
|
327
|
+
return (_jsx("text", { x: x, y: y, textAnchor: "middle", fontSize: 10, fill: "currentColor", fillOpacity: 0.7, children: truncated }, li));
|
|
328
|
+
})] }), series.length > 1 && (_jsx("div", { className: "mt-2 flex flex-wrap gap-3 text-xs text-muted-foreground", children: series.map((s, si) => (_jsxs("span", { className: "inline-flex items-center gap-1", children: [_jsx("span", { className: "inline-block h-2 w-2 rounded-full", style: { background: colorFor(s, si) } }), s.label] }, si))) }))] }));
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=legacy-chart-shorthand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-chart-shorthand.js","sourceRoot":"","sources":["../../../src/client/chat/legacy-chart-shorthand.tsx"],"names":[],"mappings":"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","sourcesContent":["// Some tool schemas expose chart parameters named `type`/`title`/`labels`/\n// `data` (e.g. a chart-generation action). Models occasionally regress to\n// typing those parameter names as a bare chat line instead of calling the\n// tool or emitting a real ```embed fence, e.g.:\n// /chart type=bar title=\"...\" labels=[\"Mon\",\"Tue\"] data=[5,8]\n// That has no real markdown syntax and would otherwise render as inert text.\n// This module detects that generic shape (any \"/word ... labels=[...]\n// data=[...]\" line) and renders a best-effort inline chart so the user still\n// sees something useful, without hardcoding any single template's tool name.\n\nimport React from \"react\";\n\nexport const LEGACY_CHART_SHORTHAND_LANG = \"chart-shorthand\";\n\nconst LEGACY_CHART_PALETTE = [\n \"#6366f1\",\n \"#22c55e\",\n \"#f59e0b\",\n \"#ef4444\",\n \"#0ea5e9\",\n \"#a855f7\",\n];\n\nconst SAFE_HEX_COLOR = /^#[0-9a-fA-F]{3,8}$/;\nconst BACKSLASH = String.fromCharCode(92);\nconst MAX_LINE_LENGTH = 20_000;\nconst MAX_LABELS = 60;\nconst MAX_SERIES = 6;\n\nexport interface LegacyChartShorthand {\n type: \"bar\" | \"line\" | \"area\";\n title: string;\n labels: string[];\n series: { label: string; data: number[]; color?: string }[];\n}\n\n// Extracts a balanced JSON array/object starting exactly at `startIndex`\n// (which must point at \"[\"), tracking string/escape state so brackets or\n// braces inside JSON string values don't confuse the boundary.\nfunction extractBalancedArrayAt(\n text: string,\n startIndex: number,\n): string | null {\n if (text[startIndex] !== \"[\") return null;\n let depth = 0;\n let inString = false;\n for (let idx = startIndex; idx < text.length; idx++) {\n const ch = text[idx];\n if (inString) {\n if (ch === \"\\\\\")\n idx++; // skip escaped character, including \\\"\n else if (ch === '\"') inString = false;\n continue;\n }\n if (ch === '\"') inString = true;\n else if (ch === \"[\" || ch === \"{\") depth++;\n else if (ch === \"]\" || ch === \"}\") {\n depth--;\n if (depth === 0) return text.slice(startIndex, idx + 1);\n }\n }\n return null;\n}\n\n// Marks which character indices fall inside a JSON/quoted-string literal so\n// key-token scanning can ignore false matches such as a key= that's part of\n// a title string, or embedded in a label's own text, rather than a real\n// assignment in the line.\nfunction computeStringMask(text: string): boolean[] {\n const mask = new Array<boolean>(text.length).fill(false);\n let inString = false;\n for (let i = 0; i < text.length; i++) {\n mask[i] = inString;\n const ch = text[i];\n if (inString) {\n if (ch === BACKSLASH) {\n i++;\n if (i < text.length) mask[i] = true;\n continue;\n }\n if (ch === '\"') inString = false;\n } else if (ch === '\"') {\n inString = true;\n }\n }\n return mask;\n}\n\n// Finds the array value immediately following a `key=` token, scanning every\n// occurrence of `key=` outside of quoted strings (not just the first) so a\n// `key=` that appears inside an unrelated quoted string (e.g.\n// title=\"data=quality\", or a label literally containing \"data=[1,2]\") is\n// skipped in favor of the real one. Only whitespace is allowed between\n// `key=` and the `[`.\nfunction extractArrayForKey(\n text: string,\n key: \"labels\" | \"data\",\n): string | null {\n const mask = computeStringMask(text);\n const re = new RegExp(`\\\\b${key}=`, \"g\");\n let match: RegExpExecArray | null;\n while ((match = re.exec(text))) {\n if (mask[match.index]) continue; // this key= is inside a string literal\n let idx = match.index + match[0].length;\n while (idx < text.length && /\\s/.test(text[idx])) idx++;\n const arr = extractBalancedArrayAt(text, idx);\n if (arr) return arr;\n }\n return null;\n}\n\n// Extracts the value of a `title=\"...\"`/`title='...'` token, honoring\n// backslash-escaped quotes and backslashes inside the string (e.g.\n// title=\"Sales \\\"Metrics\\\"\") instead of stopping at the first escaped quote.\nfunction extractLegacyChartTitle(text: string): string {\n const match = /\\btitle=/.exec(text);\n if (!match) return \"\";\n let idx = match.index + match[0].length;\n const quoteChar = text[idx];\n if (quoteChar !== '\"' && quoteChar !== \"'\") return \"\";\n idx++;\n let result = \"\";\n while (idx < text.length) {\n const ch = text[idx];\n if (ch === BACKSLASH && idx + 1 < text.length) {\n const next = text[idx + 1];\n if (next === quoteChar || next === BACKSLASH) {\n result += next;\n idx += 2;\n continue;\n }\n }\n if (ch === quoteChar) return result;\n result += ch;\n idx++;\n }\n return \"\";\n}\n\n/**\n * Cheap-ish pre-check so callers can skip the full parse on ordinary text.\n * Requires `labels=`/`data=` to actually resolve to bracketed arrays (not\n * just appear as substrings) so unrelated slash commands or API paths that\n * happen to mention both words aren't diverted out of normal markdown\n * rendering.\n */\nexport function looksLikeLegacyChartShorthand(line: string): boolean {\n const trimmed = line.trim();\n if (trimmed.length === 0 || trimmed.length > MAX_LINE_LENGTH) return false;\n if (!/^\\/[a-zA-Z][\\w-]*\\b/.test(trimmed)) return false;\n if (!/\\blabels=/.test(trimmed) || !/\\bdata=/.test(trimmed)) return false;\n return (\n extractArrayForKey(trimmed, \"labels\") !== null &&\n extractArrayForKey(trimmed, \"data\") !== null\n );\n}\n\nexport function parseLegacyChartShorthand(\n rawLine: string,\n): LegacyChartShorthand | null {\n const trimmed = rawLine.trim();\n if (!looksLikeLegacyChartShorthand(trimmed)) return null;\n\n const typeMatch = trimmed.match(/\\btype=(bar|line|area)\\b/i);\n const chartType =\n (typeMatch?.[1].toLowerCase() as LegacyChartShorthand[\"type\"]) || \"bar\";\n\n const chartTitle = extractLegacyChartTitle(trimmed);\n\n const labelsRaw = extractArrayForKey(trimmed, \"labels\");\n const dataRaw = extractArrayForKey(trimmed, \"data\");\n if (!labelsRaw || !dataRaw) return null;\n\n let parsedLabels: unknown;\n let parsedData: unknown;\n try {\n parsedLabels = JSON.parse(labelsRaw);\n parsedData = JSON.parse(dataRaw);\n } catch {\n return null;\n }\n if (\n !Array.isArray(parsedLabels) ||\n parsedLabels.length === 0 ||\n parsedLabels.length > MAX_LABELS ||\n // Reject nested arrays/objects as labels — String(nestedArray) recurses\n // through Array.prototype.join and can throw on deeply nested input.\n !parsedLabels.every((l) =>\n [\"string\", \"number\", \"boolean\"].includes(typeof l),\n )\n ) {\n return null;\n }\n const safeLabels = parsedLabels.map((l) => String(l));\n\n const isValidSeriesData = (values: unknown): values is number[] =>\n Array.isArray(values) &&\n values.length === safeLabels.length &&\n values.every((v) => typeof v === \"number\" && Number.isFinite(v) && v >= 0);\n\n const colorMatch = trimmed.match(/(?:^|\\s)color=(#[0-9a-fA-F]{3,8})\\b/);\n const topLevelColor =\n colorMatch && SAFE_HEX_COLOR.test(colorMatch[1])\n ? colorMatch[1]\n : undefined;\n\n let chartSeries: LegacyChartShorthand[\"series\"];\n if (isValidSeriesData(parsedData)) {\n chartSeries = [\n { label: chartTitle || \"Value\", data: parsedData, color: topLevelColor },\n ];\n } else if (\n Array.isArray(parsedData) &&\n parsedData.length > 0 &&\n // Reject rather than silently truncate an over-limit series count:\n // presenting a partial chart as complete is worse than plain text.\n parsedData.length <= MAX_SERIES &&\n parsedData.every(\n (d) =>\n d &&\n typeof d === \"object\" &&\n isValidSeriesData((d as { data?: unknown }).data),\n )\n ) {\n chartSeries = (\n parsedData as { label?: unknown; data: number[]; color?: unknown }[]\n ).map((d, idx) => ({\n label: typeof d.label === \"string\" ? d.label : `Series ${idx + 1}`,\n data: d.data,\n color:\n typeof d.color === \"string\" && SAFE_HEX_COLOR.test(d.color)\n ? d.color\n : undefined,\n }));\n } else {\n return null;\n }\n if (chartSeries.length === 0) return null;\n return {\n type: chartType,\n title: chartTitle,\n labels: safeLabels,\n series: chartSeries,\n };\n}\n\n// Wraps any line matching the legacy shorthand shape in a fenced code block\n// tagged `chart-shorthand`, so it routes through markdownComponents.pre()\n// like any other language fence instead of rendering as inert prose.\n// Fence/indented-code tracking mirrors ../../shared/markdown-block-split.ts\n// (marker char + length, indented-code detection) so real code blocks —\n// including ~~~ fences, longer-than-3 fences, and 4-space/tab indented code —\n// are never mistaken for chat prose and rewritten.\nexport function wrapLegacyChartShorthandLines(markdown: string): string {\n if (!markdown.includes(\"labels=\") || !markdown.includes(\"data=\")) {\n return markdown;\n }\n let fenceMarker = \"\"; // non-empty while inside a ``` or ~~~ fence\n const lines = markdown.split(\"\\n\");\n const out: string[] = [];\n for (const line of lines) {\n // CommonMark: a line indented 4+ spaces (or a tab) is an indented code\n // block, not a fence marker. Check this first so a literal four-space\n // \" ```\" example in a message doesn't toggle fence state.\n if (/^(?: {4}|\\t)/.test(line)) {\n out.push(line);\n continue;\n }\n const trimmed = line.trimStart();\n if (fenceMarker) {\n out.push(line);\n const closeMatch = /^(`{3,}|~{3,})\\s*$/.exec(trimmed);\n if (\n closeMatch &&\n closeMatch[1].charAt(0) === fenceMarker.charAt(0) &&\n closeMatch[1].length >= fenceMarker.length\n ) {\n fenceMarker = \"\";\n }\n continue;\n }\n const openMatch = /^(`{3,}|~{3,})/.exec(trimmed);\n if (openMatch) {\n fenceMarker = openMatch[1].charAt(0).repeat(openMatch[1].length);\n out.push(line);\n continue;\n }\n if (looksLikeLegacyChartShorthand(line)) {\n // Preserve the line's own indentation on the emitted fence so\n // shorthand inside a list item or blockquote continuation stays part\n // of that container instead of being dedented to a top-level block.\n const leadingWs = line.match(/^\\s*/)?.[0] ?? \"\";\n out.push(\n leadingWs + \"```\" + LEGACY_CHART_SHORTHAND_LANG,\n leadingWs + line.trim(),\n leadingWs + \"```\",\n );\n continue;\n }\n out.push(line);\n }\n return out.join(\"\\n\");\n}\n\nexport function LegacyChartShorthandFallback({ text }: { text: string }) {\n return <span style={{ whiteSpace: \"pre-wrap\" }}>{text}</span>;\n}\n\nexport function LegacyChartShorthandChart({\n parsed,\n}: {\n parsed: LegacyChartShorthand;\n}) {\n const { title, labels, series, type } = parsed;\n const width = 640;\n const height = 280;\n const padding = { top: 16, right: 16, bottom: 44, left: 48 };\n const innerW = width - padding.left - padding.right;\n const innerH = height - padding.top - padding.bottom;\n const maxVal = Math.max(\n 1,\n series.reduce(\n (acc, s) => s.data.reduce((seriesAcc, v) => Math.max(seriesAcc, v), acc),\n 0,\n ),\n );\n const groupW = innerW / labels.length;\n const gridLineCount = 4;\n const gridLines = Array.from({ length: gridLineCount + 1 }, (_, g) => {\n const y = padding.top + (innerH * g) / gridLineCount;\n const val = Math.round(maxVal - (maxVal * g) / gridLineCount);\n return { y, val };\n });\n\n const colorFor = (s: LegacyChartShorthand[\"series\"][number], si: number) =>\n s.color || LEGACY_CHART_PALETTE[si % LEGACY_CHART_PALETTE.length];\n\n return (\n <div className=\"my-4 rounded-lg border border-border bg-muted/20 p-3\">\n {title && (\n <div className=\"mb-1 text-sm font-medium text-foreground\">{title}</div>\n )}\n <svg\n viewBox={`0 0 ${width} ${height}`}\n className=\"w-full text-muted-foreground\"\n role=\"img\"\n aria-label={title || \"Chart\"}\n >\n {gridLines.map(({ y, val }, i) => (\n <React.Fragment key={i}>\n <line\n x1={padding.left}\n y1={y}\n x2={width - padding.right}\n y2={y}\n stroke=\"currentColor\"\n strokeOpacity={0.1}\n />\n <text\n x={padding.left - 8}\n y={y + 4}\n textAnchor=\"end\"\n fontSize={10}\n fill=\"currentColor\"\n fillOpacity={0.6}\n >\n {val}\n </text>\n </React.Fragment>\n ))}\n\n {type === \"bar\" &&\n labels.map((_, li) => {\n const groupPad = groupW * 0.15;\n const barsW = groupW - groupPad * 2;\n const barW = barsW / series.length;\n return series.map((s, si) => {\n const value = s.data[li] ?? 0;\n const barH = (Math.max(0, value) / maxVal) * innerH;\n const x = padding.left + li * groupW + groupPad + si * barW;\n const y = padding.top + (innerH - barH);\n return (\n <rect\n key={`${li}-${si}`}\n x={x}\n y={y}\n width={Math.max(1, barW - 2)}\n height={Math.max(0, barH)}\n fill={colorFor(s, si)}\n rx={2}\n />\n );\n });\n })}\n\n {type !== \"bar\" &&\n series.map((s, si) => {\n const coords = labels.map((_, li) => {\n const value = s.data[li] ?? 0;\n const x = padding.left + groupW * li + groupW / 2;\n const y =\n padding.top + innerH - (Math.max(0, value) / maxVal) * innerH;\n return { x, y };\n });\n if (coords.length === 1) {\n // A single point has no line segment to draw — render a marker\n // instead of an invisible zero-length polyline.\n return (\n <circle\n key={si}\n cx={coords[0].x}\n cy={coords[0].y}\n r={4}\n fill={colorFor(s, si)}\n />\n );\n }\n const points = coords\n .map(({ x, y }) => `${x.toFixed(1)},${y.toFixed(1)}`)\n .join(\" \");\n const baseY = padding.top + innerH;\n const firstX = padding.left + groupW / 2;\n const lastX =\n padding.left + groupW * (labels.length - 1) + groupW / 2;\n return (\n <React.Fragment key={si}>\n {type === \"area\" && (\n <polygon\n points={`${firstX.toFixed(1)},${baseY.toFixed(1)} ${points} ${lastX.toFixed(1)},${baseY.toFixed(1)}`}\n fill={colorFor(s, si)}\n fillOpacity={0.15}\n />\n )}\n <polyline\n points={points}\n fill=\"none\"\n stroke={colorFor(s, si)}\n strokeWidth={2}\n />\n </React.Fragment>\n );\n })}\n\n {labels.map((label, li) => {\n const x = padding.left + groupW * li + groupW / 2;\n const y = height - padding.bottom + 16;\n const truncated =\n label.length > 12 ? `${label.slice(0, 11)}...` : label;\n return (\n <text\n key={li}\n x={x}\n y={y}\n textAnchor=\"middle\"\n fontSize={10}\n fill=\"currentColor\"\n fillOpacity={0.7}\n >\n {truncated}\n </text>\n );\n })}\n </svg>\n {series.length > 1 && (\n <div className=\"mt-2 flex flex-wrap gap-3 text-xs text-muted-foreground\">\n {series.map((s, si) => (\n <span key={si} className=\"inline-flex items-center gap-1\">\n <span\n className=\"inline-block h-2 w-2 rounded-full\"\n style={{ background: colorFor(s, si) }}\n />\n {s.label}\n </span>\n ))}\n </div>\n )}\n </div>\n );\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown-renderer.d.ts","sourceRoot":"","sources":["../../../src/client/chat/markdown-renderer.tsx"],"names":[],"mappings":"AAUA,OAAO,KAMN,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,IAAI,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,KAAK,aAAa,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"markdown-renderer.d.ts","sourceRoot":"","sources":["../../../src/client/chat/markdown-renderer.tsx"],"names":[],"mappings":"AAUA,OAAO,KAMN,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,IAAI,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACrF,OAAO,KAAK,aAAa,MAAM,YAAY,CAAC;AA4B5C,KAAK,mBAAmB,GAAG;IACzB,OAAO,EAAE,OAAO,iBAAiB,CAAC;IAClC,mBAAmB,EAAE,OAAO,uBAAuB,CAAC;CACrD,CAAC;AAIF,eAAO,IAAI,cAAc,EAAE,mBAAmB,GAAG,IAAW,CAAC;AAC7D,eAAO,IAAI,WAAW,EAAE,OAAO,aAAa,GAAG,IAAW,CAAC;AAI3D,wBAAgB,YAAY,IAAI,IAAI,CAiBnC;AAED,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAO1D;AASD,KAAK,gBAAgB,GAAG;IACtB,UAAU,EAAE,CACV,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC;QACxC,YAAY,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;KACzC,KACE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9B,kBAAkB,EAAE,MAAM,MAAM,EAAE,CAAC;CACpC,CAAC;AAGF,wBAAgB,eAAe,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAwC3D;AAOD,eAAO,MAAM,oBAAoB,wBAA6B,CAAC;AAM/D,wBAAgB,oBAAoB,CAAC,EACnC,IAAI,EACJ,IAAI,GACL,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,qBAWA;AAgCD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAI1D;AAID,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,GAAG,MAAM,CAQ9D;AAID,eAAO,MAAM,kBAAkB;IAC7B,CAAC,QAAQ,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC;IA+CtD,GAAG,QAAQ,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;CAoChD,CAAC;AAsBF,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc7E;AAwCD,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,OAAO,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CA0LR;AAID,wBAAgB,gBAAgB,IAAI,OAAO,CAO1C;AAMD,eAAO,MAAM,qBAAqB,6CAE/B;IACD,SAAS,EAAE,MAAM,CAAC;CACnB,8BAaC,CAAC;AAIH,wBAAgB,kBAAkB,CAAC,EACjC,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,UAAuB,GACxB,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,qBA0DA;AAID,wBAAgB,YAAY,sBAoB3B"}
|
|
@@ -11,6 +11,7 @@ import { NEW_CHAT_ACTION_HREF } from "../error-format.js";
|
|
|
11
11
|
import { HighlightedCodeBlock as SharedHighlightedCodeBlock } from "../HighlightedCodeBlock.js";
|
|
12
12
|
import { IframeEmbed, parseEmbedBody } from "../IframeEmbed.js";
|
|
13
13
|
import { cn } from "../utils.js";
|
|
14
|
+
import { LEGACY_CHART_SHORTHAND_LANG, LegacyChartShorthandChart, LegacyChartShorthandFallback, parseLegacyChartShorthand, wrapLegacyChartShorthandLines, } from "./legacy-chart-shorthand.js";
|
|
14
15
|
export let markdownModule = null;
|
|
15
16
|
export let remarkGfmFn = null;
|
|
16
17
|
let renderToStaticMarkupFn = null;
|
|
@@ -167,6 +168,11 @@ export const markdownComponents = {
|
|
|
167
168
|
const parsed = parseEmbedBody(body);
|
|
168
169
|
return (_jsx(IframeEmbed, { ...parsed }));
|
|
169
170
|
}
|
|
171
|
+
if (new RegExp(`\\blanguage-${LEGACY_CHART_SHORTHAND_LANG}\\b`).test(className)) {
|
|
172
|
+
const body = extractCodeText(childProps.children).replace(/\n$/, "");
|
|
173
|
+
const parsed = parseLegacyChartShorthand(body);
|
|
174
|
+
return parsed ? (_jsx(LegacyChartShorthandChart, { parsed: parsed })) : (_jsx(LegacyChartShorthandFallback, { text: body }));
|
|
175
|
+
}
|
|
170
176
|
const langMatch = className.match(/\blanguage-([\w+-]+)\b/);
|
|
171
177
|
if (langMatch) {
|
|
172
178
|
const code = extractCodeText(childProps.children).replace(/\n$/, "");
|
|
@@ -396,7 +402,7 @@ export const MemoizedMarkdownBlock = React.memo(function MemoizedMarkdownBlock({
|
|
|
396
402
|
const gfm = remarkGfmFn;
|
|
397
403
|
if (!ReactMarkdown || !gfm)
|
|
398
404
|
return null;
|
|
399
|
-
return (_jsx(ReactMarkdown, { remarkPlugins: [gfm], components: markdownComponents, urlTransform: markdownUrlTransform, children: blockText }));
|
|
405
|
+
return (_jsx(ReactMarkdown, { remarkPlugins: [gfm], components: markdownComponents, urlTransform: markdownUrlTransform, children: wrapLegacyChartShorthandLines(blockText) }));
|
|
400
406
|
});
|
|
401
407
|
// ─── SmoothMarkdownText ────────────────────────────────────────────────────────
|
|
402
408
|
export function SmoothMarkdownText({ text, streaming, resetKey, statusType = "complete", }) {
|
|
@@ -411,7 +417,7 @@ export function SmoothMarkdownText({ text, streaming, resetKey, statusType = "co
|
|
|
411
417
|
// On completion we fall through to a single ReactMarkdown pass to guarantee
|
|
412
418
|
// byte-identical final output (no block-split artifacts).
|
|
413
419
|
const split = useMemo(() => (isVisuallyStreaming ? splitMarkdownBlocks(visibleText) : null), [isVisuallyStreaming, visibleText]);
|
|
414
|
-
return (_jsx("div", { className: "agent-markdown break-words", "data-status": statusType, "data-streaming": isVisuallyStreaming ? "true" : undefined, children: mdReady && ReactMarkdown && gfm ? (split ? (_jsxs(_Fragment, { children: [split.completedBlocks.map((block, i) => (_jsx(MemoizedMarkdownBlock, { blockText: block }, i))), split.tail ? (_jsx(ReactMarkdown, { remarkPlugins: [gfm], components: markdownComponents, urlTransform: markdownUrlTransform, children: split.tail })) : null] })) : (_jsx(ReactMarkdown, { remarkPlugins: [gfm], components: markdownComponents, urlTransform: markdownUrlTransform, children: visibleText }))) : (_jsx("span", { style: { whiteSpace: "pre-wrap" }, children: visibleText })) }));
|
|
420
|
+
return (_jsx("div", { className: "agent-markdown break-words", "data-status": statusType, "data-streaming": isVisuallyStreaming ? "true" : undefined, children: mdReady && ReactMarkdown && gfm ? (split ? (_jsxs(_Fragment, { children: [split.completedBlocks.map((block, i) => (_jsx(MemoizedMarkdownBlock, { blockText: block }, i))), split.tail ? (_jsx(ReactMarkdown, { remarkPlugins: [gfm], components: markdownComponents, urlTransform: markdownUrlTransform, children: wrapLegacyChartShorthandLines(split.tail) })) : null] })) : (_jsx(ReactMarkdown, { remarkPlugins: [gfm], components: markdownComponents, urlTransform: markdownUrlTransform, children: wrapLegacyChartShorthandLines(visibleText) }))) : (_jsx("span", { style: { whiteSpace: "pre-wrap" }, children: visibleText })) }));
|
|
415
421
|
}
|
|
416
422
|
// ─── MarkdownText ──────────────────────────────────────────────────────────────
|
|
417
423
|
export function MarkdownText() {
|