@heroui/agent 0.2.0-beta.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 +64 -0
- package/LICENSE +21 -0
- package/README.md +205 -0
- package/dist/chart-content-VZ66GD22.js +1391 -0
- package/dist/chunk-3FG5NRTX.js +9 -0
- package/dist/chunk-CU6MPKAJ.js +359 -0
- package/dist/chunk-DW4AQRM5.js +297 -0
- package/dist/chunk-GDDNN2XY.js +954 -0
- package/dist/chunk-RQCTC4JB.js +1084 -0
- package/dist/chunk-TOOT6SZ2.js +74 -0
- package/dist/chunk-VJA52U5P.js +137 -0
- package/dist/component-renderer-IBJDNXSO.js +9780 -0
- package/dist/contracts.d.ts +1293 -0
- package/dist/contracts.js +2325 -0
- package/dist/css/index.css +2 -0
- package/dist/embed-runtime-XOPQY7Z5.js +7254 -0
- package/dist/identity-NYCXY1mT.d.ts +164 -0
- package/dist/index.d.ts +594 -0
- package/dist/index.js +28 -0
- package/dist/interactive-map-surface-67KHT3VB.js +362 -0
- package/dist/next.d.ts +4 -0
- package/dist/next.js +22 -0
- package/dist/server.d.ts +31 -0
- package/dist/server.js +256 -0
- package/package.json +133 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mergeClassNames
|
|
3
|
+
} from "./chunk-3FG5NRTX.js";
|
|
4
|
+
|
|
5
|
+
// ../agent-ui/src/components/component-renderer/component-skeleton.tsx
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
function skeletonCategory(kind) {
|
|
8
|
+
if (kind === "dashboard" || kind === "product-signals" || kind === "card" || kind === "col" || kind === "grid" || kind === "item-card" || kind === "item-card-group" || kind === "row")
|
|
9
|
+
return "dashboard";
|
|
10
|
+
if (kind === "metric-grid" || kind === "kpi-grid") return "metrics";
|
|
11
|
+
if (kind === "map") return "map";
|
|
12
|
+
if (kind === "data-table") return "table";
|
|
13
|
+
if (kind === "record-card" || kind === "channel-message" || kind === "create-event" || kind === "enable-notification" || kind === "event-session" || kind === "flight-tracker" || kind === "player-card" || kind === "playlist" || kind === "purchase-complete" || kind === "purchase-items" || kind === "ride-status" || kind === "view-event" || kind === "weather-current" || kind === "weather-forecast")
|
|
14
|
+
return "record";
|
|
15
|
+
return "chart";
|
|
16
|
+
}
|
|
17
|
+
function ComponentSkeleton({ className, kind, title }) {
|
|
18
|
+
const category = skeletonCategory(kind);
|
|
19
|
+
return /* @__PURE__ */ jsxs(
|
|
20
|
+
"section",
|
|
21
|
+
{
|
|
22
|
+
"aria-busy": "true",
|
|
23
|
+
"aria-label": title ? `Loading ${title}` : "Loading data view",
|
|
24
|
+
className: mergeClassNames("aui-skeleton", className),
|
|
25
|
+
"data-component-kind": kind,
|
|
26
|
+
"data-skeleton-category": category,
|
|
27
|
+
"data-slot": "agent-ui-skeleton",
|
|
28
|
+
role: "status",
|
|
29
|
+
children: [
|
|
30
|
+
/* @__PURE__ */ jsx("div", { className: "aui-skeleton__header", "data-slot": "agent-ui-skeleton-header" }),
|
|
31
|
+
/* @__PURE__ */ jsx("div", { className: "aui-skeleton__content", "data-slot": "agent-ui-skeleton-content", children: category === "metrics" || category === "dashboard" ? Array.from({ length: category === "dashboard" ? 2 : 4 }, (_, index) => /* @__PURE__ */ jsx("span", { className: "aui-skeleton__panel" }, index)) : category === "table" || category === "record" ? Array.from({ length: category === "table" ? 5 : 4 }, (_, index) => /* @__PURE__ */ jsx("span", { className: "aui-skeleton__row" }, index)) : /* @__PURE__ */ jsx("span", { className: "aui-skeleton__chart" }) }),
|
|
32
|
+
/* @__PURE__ */ jsx("span", { className: "aui-sr-only", "data-slot": "agent-ui-skeleton-label", children: "Loading data view\u2026" })
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ../agent-ui/src/components/display-information/scroll-shadow/scroll-shadow.tsx
|
|
39
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
40
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
41
|
+
function ScrollShadow({
|
|
42
|
+
children,
|
|
43
|
+
className,
|
|
44
|
+
offset = 0,
|
|
45
|
+
size = 32,
|
|
46
|
+
style,
|
|
47
|
+
...props
|
|
48
|
+
}) {
|
|
49
|
+
const ref = useRef(null);
|
|
50
|
+
const previousVisibility = useRef(null);
|
|
51
|
+
const frame = useRef(null);
|
|
52
|
+
const updateVisibility = useCallback(() => {
|
|
53
|
+
const element = ref.current;
|
|
54
|
+
if (!element) return;
|
|
55
|
+
const hasScrollBefore = element.scrollLeft > offset;
|
|
56
|
+
const hasScrollAfter = element.scrollLeft + element.clientWidth + offset < element.scrollWidth;
|
|
57
|
+
const visibility = hasScrollBefore && hasScrollAfter ? "both" : hasScrollBefore ? "left" : hasScrollAfter ? "right" : "none";
|
|
58
|
+
if (previousVisibility.current === visibility) return;
|
|
59
|
+
previousVisibility.current = visibility;
|
|
60
|
+
if (frame.current !== null) cancelAnimationFrame(frame.current);
|
|
61
|
+
frame.current = requestAnimationFrame(() => {
|
|
62
|
+
frame.current = null;
|
|
63
|
+
delete element.dataset["leftScroll"];
|
|
64
|
+
delete element.dataset["rightScroll"];
|
|
65
|
+
delete element.dataset["leftRightScroll"];
|
|
66
|
+
if (visibility === "both") element.dataset["leftRightScroll"] = "true";
|
|
67
|
+
else if (visibility !== "none") element.dataset[`${visibility}Scroll`] = "true";
|
|
68
|
+
});
|
|
69
|
+
}, [offset]);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
const element = ref.current;
|
|
72
|
+
if (!element) return;
|
|
73
|
+
updateVisibility();
|
|
74
|
+
element.addEventListener("scroll", updateVisibility, { passive: true });
|
|
75
|
+
const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(updateVisibility);
|
|
76
|
+
observer?.observe(element);
|
|
77
|
+
return () => {
|
|
78
|
+
element.removeEventListener("scroll", updateVisibility);
|
|
79
|
+
observer?.disconnect();
|
|
80
|
+
if (frame.current !== null) cancelAnimationFrame(frame.current);
|
|
81
|
+
frame.current = null;
|
|
82
|
+
previousVisibility.current = null;
|
|
83
|
+
};
|
|
84
|
+
}, [updateVisibility]);
|
|
85
|
+
return /* @__PURE__ */ jsx2(
|
|
86
|
+
"div",
|
|
87
|
+
{
|
|
88
|
+
ref,
|
|
89
|
+
className: mergeClassNames("aui-scroll-shadow", className),
|
|
90
|
+
"data-slot": "agent-ui-scroll-shadow",
|
|
91
|
+
style: { "--scroll-shadow-size": `${size}px`, ...style },
|
|
92
|
+
...props,
|
|
93
|
+
children
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ../agent-ui/src/utils/inline-markdown.tsx
|
|
99
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
100
|
+
var INLINE_TOKEN = /(\*\*[^*\n]+\*\*|\*[^*\s][^*\n]*\*|_[^_\s][^_\n]*_|`[^`\n]+`|\[[^\]\n]+\]\([^\s)\n]+\))/g;
|
|
101
|
+
var LINK_TOKEN = /^\[([^\]]+)\]\(([^\s)]+)\)$/;
|
|
102
|
+
var BARE_DOMAIN = /^(?:[a-z\d](?:[a-z\d-]{0,61}[a-z\d])?\.)+[a-z]{2,63}(?::\d{1,5})?(?:[/?#][^\s]*)?$/i;
|
|
103
|
+
function resolveLinkHref(target) {
|
|
104
|
+
const href = /^https?:\/\//i.test(target) ? target : BARE_DOMAIN.test(target) ? `https://${target}` : void 0;
|
|
105
|
+
if (!href) return void 0;
|
|
106
|
+
try {
|
|
107
|
+
const url = new URL(href);
|
|
108
|
+
return url.protocol === "http:" || url.protocol === "https:" ? href : void 0;
|
|
109
|
+
} catch {
|
|
110
|
+
return void 0;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function renderInlineMarkdown(text) {
|
|
114
|
+
const parts = text.split(INLINE_TOKEN);
|
|
115
|
+
if (parts.length === 1) return text;
|
|
116
|
+
const occurrences = /* @__PURE__ */ new Map();
|
|
117
|
+
return parts.map((part) => {
|
|
118
|
+
const occurrence = (occurrences.get(part) ?? 0) + 1;
|
|
119
|
+
const key = `${part}:${occurrence}`;
|
|
120
|
+
occurrences.set(part, occurrence);
|
|
121
|
+
if (part.startsWith("**") && part.endsWith("**") && part.length > 4)
|
|
122
|
+
return /* @__PURE__ */ jsx3("strong", { children: part.slice(2, -2) }, key);
|
|
123
|
+
if (part.startsWith("*") && part.endsWith("*") && part.length > 2)
|
|
124
|
+
return /* @__PURE__ */ jsx3("em", { children: part.slice(1, -1) }, key);
|
|
125
|
+
if (part.startsWith("_") && part.endsWith("_") && part.length > 2)
|
|
126
|
+
return /* @__PURE__ */ jsx3("em", { children: part.slice(1, -1) }, key);
|
|
127
|
+
if (part.startsWith("`") && part.endsWith("`") && part.length > 2)
|
|
128
|
+
return /* @__PURE__ */ jsx3("code", { children: part.slice(1, -1) }, key);
|
|
129
|
+
const link = LINK_TOKEN.exec(part);
|
|
130
|
+
const target = link?.[2];
|
|
131
|
+
const href = target ? resolveLinkHref(target) : void 0;
|
|
132
|
+
if (link && href)
|
|
133
|
+
return /* @__PURE__ */ jsx3("a", { href, rel: "noopener noreferrer", target: "_blank", children: link[1] }, key);
|
|
134
|
+
return part;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ../agent-ui/src/components/actions/action-button.tsx
|
|
139
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
140
|
+
function ActionButton({
|
|
141
|
+
className,
|
|
142
|
+
size = "sm",
|
|
143
|
+
variant = "secondary",
|
|
144
|
+
...props
|
|
145
|
+
}) {
|
|
146
|
+
return /* @__PURE__ */ jsx4(
|
|
147
|
+
"button",
|
|
148
|
+
{
|
|
149
|
+
className: mergeClassNames("aui-button", className),
|
|
150
|
+
"data-size": size,
|
|
151
|
+
"data-slot": "agent-ui-action-button",
|
|
152
|
+
"data-variant": variant,
|
|
153
|
+
type: "button",
|
|
154
|
+
...props
|
|
155
|
+
}
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ../agent-ui/src/components/display-information/code-block.tsx
|
|
160
|
+
import { Button } from "@heroui/react";
|
|
161
|
+
import { useEffect as useEffect2, useRef as useRef2, useState } from "react";
|
|
162
|
+
import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
163
|
+
var COPY_RESET_DELAY = 2e3;
|
|
164
|
+
var DEFAULT_DARK_THEME = "github-dark";
|
|
165
|
+
var DEFAULT_LIGHT_THEME = "github-light";
|
|
166
|
+
var languageLoaders = {
|
|
167
|
+
bash: () => import("shiki/langs/bash.mjs"),
|
|
168
|
+
css: () => import("shiki/langs/css.mjs"),
|
|
169
|
+
html: () => import("shiki/langs/html.mjs"),
|
|
170
|
+
javascript: () => import("shiki/langs/javascript.mjs"),
|
|
171
|
+
json: () => import("shiki/langs/json.mjs"),
|
|
172
|
+
jsx: () => import("shiki/langs/jsx.mjs"),
|
|
173
|
+
markdown: () => import("shiki/langs/markdown.mjs"),
|
|
174
|
+
python: () => import("shiki/langs/python.mjs"),
|
|
175
|
+
shellscript: () => import("shiki/langs/shellscript.mjs"),
|
|
176
|
+
sql: () => import("shiki/langs/sql.mjs"),
|
|
177
|
+
tsx: () => import("shiki/langs/tsx.mjs"),
|
|
178
|
+
typescript: () => import("shiki/langs/typescript.mjs")
|
|
179
|
+
};
|
|
180
|
+
var highlighters = /* @__PURE__ */ new Map();
|
|
181
|
+
function normalizeLanguage(language) {
|
|
182
|
+
const aliases = {
|
|
183
|
+
js: "javascript",
|
|
184
|
+
md: "markdown",
|
|
185
|
+
py: "python",
|
|
186
|
+
sh: "shellscript",
|
|
187
|
+
shell: "shellscript",
|
|
188
|
+
ts: "typescript"
|
|
189
|
+
};
|
|
190
|
+
const normalized = language.toLowerCase();
|
|
191
|
+
if (normalized in languageLoaders) return normalized;
|
|
192
|
+
return aliases[normalized] ?? null;
|
|
193
|
+
}
|
|
194
|
+
async function createLanguageHighlighter(language) {
|
|
195
|
+
const [{ createHighlighterCore }, { createJavaScriptRegexEngine }, lightTheme, darkTheme, grammar] = await Promise.all([
|
|
196
|
+
import("shiki/core"),
|
|
197
|
+
import("shiki/engine/javascript"),
|
|
198
|
+
import("shiki/themes/github-light.mjs"),
|
|
199
|
+
import("shiki/themes/github-dark.mjs"),
|
|
200
|
+
languageLoaders[language]()
|
|
201
|
+
]);
|
|
202
|
+
return createHighlighterCore({
|
|
203
|
+
engine: createJavaScriptRegexEngine(),
|
|
204
|
+
langs: [grammar.default],
|
|
205
|
+
themes: [lightTheme.default, darkTheme.default]
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
async function highlightCode(code, language) {
|
|
209
|
+
const normalized = normalizeLanguage(language);
|
|
210
|
+
if (!normalized) return null;
|
|
211
|
+
const existing = highlighters.get(normalized);
|
|
212
|
+
const highlighterPromise = existing ?? createLanguageHighlighter(normalized);
|
|
213
|
+
if (!existing) highlighters.set(normalized, highlighterPromise);
|
|
214
|
+
const highlighter = await highlighterPromise;
|
|
215
|
+
return highlighter.codeToHtml(code, {
|
|
216
|
+
defaultColor: false,
|
|
217
|
+
lang: normalized,
|
|
218
|
+
themes: { dark: DEFAULT_DARK_THEME, light: DEFAULT_LIGHT_THEME }
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
async function copyText(text) {
|
|
222
|
+
try {
|
|
223
|
+
await navigator.clipboard.writeText(text);
|
|
224
|
+
return true;
|
|
225
|
+
} catch {
|
|
226
|
+
const textarea = document.createElement("textarea");
|
|
227
|
+
textarea.value = text;
|
|
228
|
+
textarea.setAttribute("readonly", "");
|
|
229
|
+
textarea.style.position = "fixed";
|
|
230
|
+
textarea.style.opacity = "0";
|
|
231
|
+
document.body.append(textarea);
|
|
232
|
+
textarea.select();
|
|
233
|
+
try {
|
|
234
|
+
return document.execCommand?.("copy") ?? false;
|
|
235
|
+
} catch {
|
|
236
|
+
return false;
|
|
237
|
+
} finally {
|
|
238
|
+
textarea.remove();
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function CodeGlyph() {
|
|
243
|
+
return /* @__PURE__ */ jsx5("svg", { "aria-hidden": "true", fill: "none", viewBox: "0 0 16 16", children: /* @__PURE__ */ jsx5(
|
|
244
|
+
"path",
|
|
245
|
+
{
|
|
246
|
+
clipRule: "evenodd",
|
|
247
|
+
d: "M10.218 3.216a.75.75 0 0 0-1.436-.431l-3 10a.75.75 0 0 0 1.436.43zM4.53 4.97a.75.75 0 0 1 0 1.06L2.56 8l1.97 1.97a.75.75 0 0 1-1.06 1.06l-2.5-2.5a.75.75 0 0 1 0-1.06l2.5-2.5a.75.75 0 0 1 1.06 0m6.94 6.06a.75.75 0 0 1 0-1.06L13.44 8l-1.97-1.97a.75.75 0 0 1 1.06-1.06l2.5 2.5a.75.75 0 0 1 0 1.06l-2.5 2.5a.75.75 0 0 1-1.06 0",
|
|
248
|
+
fill: "currentColor",
|
|
249
|
+
fillRule: "evenodd"
|
|
250
|
+
}
|
|
251
|
+
) });
|
|
252
|
+
}
|
|
253
|
+
function CopyGlyph() {
|
|
254
|
+
return /* @__PURE__ */ jsx5("svg", { "aria-hidden": "true", fill: "none", viewBox: "0 0 16 16", children: /* @__PURE__ */ jsx5(
|
|
255
|
+
"path",
|
|
256
|
+
{
|
|
257
|
+
clipRule: "evenodd",
|
|
258
|
+
d: "M12 2.5H8A1.5 1.5 0 0 0 6.5 4v1H8a3 3 0 0 1 3 3v1.5h1A1.5 1.5 0 0 0 13.5 8V4A1.5 1.5 0 0 0 12 2.5M11 11h1a3 3 0 0 0 3-3V4a3 3 0 0 0-3-3H8a3 3 0 0 0-3 3v1H4a3 3 0 0 0-3 3v4a3 3 0 0 0 3 3h4a3 3 0 0 0 3-3zM4 6.5h4A1.5 1.5 0 0 1 9.5 8v4A1.5 1.5 0 0 1 8 13.5H4A1.5 1.5 0 0 1 2.5 12V8A1.5 1.5 0 0 1 4 6.5",
|
|
259
|
+
fill: "currentColor",
|
|
260
|
+
fillRule: "evenodd"
|
|
261
|
+
}
|
|
262
|
+
) });
|
|
263
|
+
}
|
|
264
|
+
function CheckGlyph() {
|
|
265
|
+
return /* @__PURE__ */ jsx5("svg", { "aria-hidden": "true", fill: "none", viewBox: "0 0 16 16", children: /* @__PURE__ */ jsx5(
|
|
266
|
+
"path",
|
|
267
|
+
{
|
|
268
|
+
clipRule: "evenodd",
|
|
269
|
+
d: "M13.488 3.43a.75.75 0 0 1 .081 1.058l-6 7a.75.75 0 0 1-1.1.042l-3.5-3.5A.75.75 0 0 1 4.03 6.97l2.928 2.927 5.473-6.385a.75.75 0 0 1 1.057-.081",
|
|
270
|
+
fill: "currentColor",
|
|
271
|
+
fillRule: "evenodd"
|
|
272
|
+
}
|
|
273
|
+
) });
|
|
274
|
+
}
|
|
275
|
+
function CodeBlock({ code, language = "text" }) {
|
|
276
|
+
const highlightKey = `${language}:${code}`;
|
|
277
|
+
const [highlighted, setHighlighted] = useState(null);
|
|
278
|
+
const [copied, setCopied] = useState(false);
|
|
279
|
+
const resetTimeout = useRef2(null);
|
|
280
|
+
useEffect2(() => {
|
|
281
|
+
let cancelled = false;
|
|
282
|
+
async function highlight() {
|
|
283
|
+
try {
|
|
284
|
+
const html = await highlightCode(code, language);
|
|
285
|
+
if (!cancelled) setHighlighted(html ? { html, key: highlightKey } : null);
|
|
286
|
+
} catch {
|
|
287
|
+
if (!cancelled) setHighlighted(null);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
void highlight();
|
|
291
|
+
return () => {
|
|
292
|
+
cancelled = true;
|
|
293
|
+
};
|
|
294
|
+
}, [code, highlightKey, language]);
|
|
295
|
+
useEffect2(
|
|
296
|
+
() => () => {
|
|
297
|
+
if (resetTimeout.current !== null) window.clearTimeout(resetTimeout.current);
|
|
298
|
+
},
|
|
299
|
+
[]
|
|
300
|
+
);
|
|
301
|
+
const copy = async () => {
|
|
302
|
+
if (await copyText(code)) {
|
|
303
|
+
setCopied(true);
|
|
304
|
+
if (resetTimeout.current !== null) window.clearTimeout(resetTimeout.current);
|
|
305
|
+
resetTimeout.current = window.setTimeout(() => {
|
|
306
|
+
setCopied(false);
|
|
307
|
+
resetTimeout.current = null;
|
|
308
|
+
}, COPY_RESET_DELAY);
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
return /* @__PURE__ */ jsxs2("div", { className: "aui-code", "data-slot": "agent-ui-code-block", children: [
|
|
312
|
+
/* @__PURE__ */ jsxs2("header", { className: "aui-code__header", "data-slot": "agent-ui-code-header", children: [
|
|
313
|
+
/* @__PURE__ */ jsxs2("span", { className: "aui-code__language", children: [
|
|
314
|
+
/* @__PURE__ */ jsx5(CodeGlyph, {}),
|
|
315
|
+
/* @__PURE__ */ jsx5("span", { children: language.toUpperCase() })
|
|
316
|
+
] }),
|
|
317
|
+
/* @__PURE__ */ jsx5(
|
|
318
|
+
Button,
|
|
319
|
+
{
|
|
320
|
+
isIconOnly: true,
|
|
321
|
+
"aria-label": copied ? "Code copied" : "Copy code",
|
|
322
|
+
className: "aui-code__copy",
|
|
323
|
+
"data-slot": "agent-ui-code-copy",
|
|
324
|
+
size: "sm",
|
|
325
|
+
variant: "ghost",
|
|
326
|
+
onPress: copy,
|
|
327
|
+
children: /* @__PURE__ */ jsxs2(
|
|
328
|
+
"span",
|
|
329
|
+
{
|
|
330
|
+
className: "aui-code__copy-swap",
|
|
331
|
+
"data-copied": copied || void 0,
|
|
332
|
+
"data-slot": "agent-ui-code-copy-icon",
|
|
333
|
+
children: [
|
|
334
|
+
/* @__PURE__ */ jsx5("span", { className: "aui-code__copy-icon aui-code__copy-icon--copy", children: /* @__PURE__ */ jsx5(CopyGlyph, {}) }),
|
|
335
|
+
/* @__PURE__ */ jsx5("span", { className: "aui-code__copy-icon aui-code__copy-icon--check", children: /* @__PURE__ */ jsx5(CheckGlyph, {}) })
|
|
336
|
+
]
|
|
337
|
+
}
|
|
338
|
+
)
|
|
339
|
+
}
|
|
340
|
+
)
|
|
341
|
+
] }),
|
|
342
|
+
highlighted?.key === highlightKey ? /* @__PURE__ */ jsx5(
|
|
343
|
+
"div",
|
|
344
|
+
{
|
|
345
|
+
className: "aui-code__content",
|
|
346
|
+
dangerouslySetInnerHTML: { __html: highlighted.html },
|
|
347
|
+
"data-slot": "agent-ui-code"
|
|
348
|
+
}
|
|
349
|
+
) : /* @__PURE__ */ jsx5("div", { className: "aui-code__content", "data-slot": "agent-ui-code", children: /* @__PURE__ */ jsx5("pre", { children: /* @__PURE__ */ jsx5("code", { children: code }) }) })
|
|
350
|
+
] });
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export {
|
|
354
|
+
ActionButton,
|
|
355
|
+
ComponentSkeleton,
|
|
356
|
+
ScrollShadow,
|
|
357
|
+
renderInlineMarkdown,
|
|
358
|
+
CodeBlock
|
|
359
|
+
};
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
import {
|
|
2
|
+
resolveOverlayPortalContainer
|
|
3
|
+
} from "./chunk-TOOT6SZ2.js";
|
|
4
|
+
|
|
5
|
+
// ../agent-ui/src/types.ts
|
|
6
|
+
function componentActionFromSpec(componentId, action) {
|
|
7
|
+
if (action.toolCall) {
|
|
8
|
+
return {
|
|
9
|
+
actionId: action.id,
|
|
10
|
+
args: action.toolCall.arguments,
|
|
11
|
+
componentId,
|
|
12
|
+
label: action.label,
|
|
13
|
+
prompt: action.prompt,
|
|
14
|
+
toolName: action.toolCall.name,
|
|
15
|
+
type: "tool"
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
if (action.prompt) {
|
|
19
|
+
return { componentId, label: action.label, prompt: action.prompt, type: "followup" };
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
function createComponentSelection(component, datum) {
|
|
24
|
+
return { componentId: component.id, componentTitle: component.title, datum };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// ../agent-ui/src/utils/formatters.ts
|
|
28
|
+
var numberFormatters = /* @__PURE__ */ new Map();
|
|
29
|
+
function supportedLocale(locale) {
|
|
30
|
+
try {
|
|
31
|
+
return Intl.NumberFormat.supportedLocalesOf([locale])[0] ?? "en";
|
|
32
|
+
} catch {
|
|
33
|
+
return "en";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function formatNumber(value, format, locale = "en") {
|
|
37
|
+
const resolvedLocale = supportedLocale(locale);
|
|
38
|
+
if (!format) return value.toLocaleString(resolvedLocale);
|
|
39
|
+
const options = {
|
|
40
|
+
...format.style === "currency" ? { currency: format.currency, style: "currency" } : {},
|
|
41
|
+
...format.style === "percent" ? { style: "percent" } : {},
|
|
42
|
+
...format.style === "percent" && format.maximumFractionDigits !== void 0 ? { maximumFractionDigits: format.maximumFractionDigits } : {},
|
|
43
|
+
...format.style !== "percent" && format.compact ? { notation: "compact" } : {}
|
|
44
|
+
};
|
|
45
|
+
const cacheKey = `${resolvedLocale}:${JSON.stringify(options)}`;
|
|
46
|
+
let formatter = numberFormatters.get(cacheKey);
|
|
47
|
+
if (!formatter) {
|
|
48
|
+
formatter = new Intl.NumberFormat(resolvedLocale, options);
|
|
49
|
+
numberFormatters.set(cacheKey, formatter);
|
|
50
|
+
}
|
|
51
|
+
return formatter.format(value);
|
|
52
|
+
}
|
|
53
|
+
function formatAxisValue(value, locale = "en") {
|
|
54
|
+
const resolvedLocale = supportedLocale(locale);
|
|
55
|
+
const absolute = Math.abs(value);
|
|
56
|
+
if (absolute >= 1e6)
|
|
57
|
+
return `${(value / 1e6).toLocaleString(resolvedLocale, { maximumFractionDigits: 1 })}M`;
|
|
58
|
+
if (absolute >= 1e3)
|
|
59
|
+
return `${(value / 1e3).toLocaleString(resolvedLocale, { maximumFractionDigits: 1 })}K`;
|
|
60
|
+
return value.toLocaleString(resolvedLocale, { maximumFractionDigits: 1 });
|
|
61
|
+
}
|
|
62
|
+
function formatDelta(value, options = {}, locale = "en") {
|
|
63
|
+
const formatter = new Intl.NumberFormat(supportedLocale(locale), {
|
|
64
|
+
maximumFractionDigits: options.maximumFractionDigits ?? 2,
|
|
65
|
+
signDisplay: "always",
|
|
66
|
+
style: options.style === "percent" ? "percent" : "decimal"
|
|
67
|
+
});
|
|
68
|
+
return formatter.format(value);
|
|
69
|
+
}
|
|
70
|
+
function formatCell(value, format, locale = "en") {
|
|
71
|
+
return typeof value === "number" ? formatNumber(value, format, locale) : String(value ?? "");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ../agent-ui/src/components/component-actions/export-actions.tsx
|
|
75
|
+
import { Ellipsis } from "@gravity-ui/icons";
|
|
76
|
+
import { Button, Dropdown, Label } from "@heroui/react";
|
|
77
|
+
import { useCallback, useRef, useState } from "react";
|
|
78
|
+
|
|
79
|
+
// ../agent-ui/src/components/component-actions/export-utils.ts
|
|
80
|
+
function filename(title, extension) {
|
|
81
|
+
const stem = title.trim().toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 80);
|
|
82
|
+
return `${stem || "agent-ui"}.${extension}`;
|
|
83
|
+
}
|
|
84
|
+
function download(data, type, name) {
|
|
85
|
+
if (typeof document === "undefined" || typeof URL.createObjectURL !== "function") return;
|
|
86
|
+
const url = URL.createObjectURL(new Blob([data], { type }));
|
|
87
|
+
const anchor = document.createElement("a");
|
|
88
|
+
anchor.download = name;
|
|
89
|
+
anchor.href = url;
|
|
90
|
+
anchor.click();
|
|
91
|
+
URL.revokeObjectURL(url);
|
|
92
|
+
}
|
|
93
|
+
function csvCell(value) {
|
|
94
|
+
const text = String(value ?? "");
|
|
95
|
+
return /[",\r\n]/.test(text) ? `"${text.replaceAll('"', '""')}"` : text;
|
|
96
|
+
}
|
|
97
|
+
function componentToCsv(component) {
|
|
98
|
+
let rows;
|
|
99
|
+
let keys;
|
|
100
|
+
if (component.kind === "data-table") {
|
|
101
|
+
rows = component.rows;
|
|
102
|
+
keys = component.columns.map((column) => column.key);
|
|
103
|
+
} else if (component.kind === "line-chart" || component.kind === "area-chart" || component.kind === "bar-chart" || component.kind === "composed-chart" || component.kind === "pie-chart" || component.kind === "donut-chart" || component.kind === "radar-chart" || component.kind === "radial-chart" || component.kind === "scatter-chart" || component.kind === "heatmap") {
|
|
104
|
+
rows = component.data;
|
|
105
|
+
keys = [...new Set(rows.flatMap((row) => Object.keys(row)))];
|
|
106
|
+
}
|
|
107
|
+
if (!rows || !keys?.length) return null;
|
|
108
|
+
return [
|
|
109
|
+
keys.map(csvCell).join(","),
|
|
110
|
+
...rows.map((row) => keys.map((key) => csvCell(row[key])).join(","))
|
|
111
|
+
].join("\n");
|
|
112
|
+
}
|
|
113
|
+
var SVG_STYLE_TOKENS = [
|
|
114
|
+
"--accent",
|
|
115
|
+
"--border",
|
|
116
|
+
"--chart-1",
|
|
117
|
+
"--chart-2",
|
|
118
|
+
"--chart-3",
|
|
119
|
+
"--chart-4",
|
|
120
|
+
"--chart-5",
|
|
121
|
+
"--foreground",
|
|
122
|
+
"--muted",
|
|
123
|
+
"--surface"
|
|
124
|
+
];
|
|
125
|
+
function svgMarkup(button) {
|
|
126
|
+
const card = button.closest('[data-slot="agent-ui-card"]');
|
|
127
|
+
const svg = card?.querySelector("svg");
|
|
128
|
+
if (!(card instanceof HTMLElement) || !(svg instanceof SVGElement)) return null;
|
|
129
|
+
const clone = svg.cloneNode(true);
|
|
130
|
+
const styles = getComputedStyle(card);
|
|
131
|
+
const variables = SVG_STYLE_TOKENS.map((token) => `${token}:${styles.getPropertyValue(token)}`).filter((entry) => !entry.endsWith(":")).join(";");
|
|
132
|
+
clone.setAttribute("xmlns", "http://www.w3.org/2000/svg");
|
|
133
|
+
clone.setAttribute("style", [clone.getAttribute("style"), variables].filter(Boolean).join(";"));
|
|
134
|
+
return new XMLSerializer().serializeToString(clone);
|
|
135
|
+
}
|
|
136
|
+
async function exportPng(button, title) {
|
|
137
|
+
const markup = svgMarkup(button);
|
|
138
|
+
if (!markup || typeof Image === "undefined" || typeof URL.createObjectURL !== "function") return;
|
|
139
|
+
const source = URL.createObjectURL(new Blob([markup], { type: "image/svg+xml;charset=utf-8" }));
|
|
140
|
+
const image = new Image();
|
|
141
|
+
await new Promise((resolve, reject) => {
|
|
142
|
+
image.onload = () => resolve();
|
|
143
|
+
image.onerror = () => reject(new Error("Unable to render component image"));
|
|
144
|
+
image.src = source;
|
|
145
|
+
});
|
|
146
|
+
const canvas = document.createElement("canvas");
|
|
147
|
+
const scale = Math.max(1, window.devicePixelRatio || 1);
|
|
148
|
+
canvas.width = Math.max(1, image.width) * scale;
|
|
149
|
+
canvas.height = Math.max(1, image.height) * scale;
|
|
150
|
+
const context = canvas.getContext("2d");
|
|
151
|
+
context?.scale(scale, scale);
|
|
152
|
+
context?.drawImage(image, 0, 0);
|
|
153
|
+
URL.revokeObjectURL(source);
|
|
154
|
+
const blob = await new Promise((resolve) => canvas.toBlob(resolve, "image/png"));
|
|
155
|
+
if (blob) download(blob, "image/png", filename(title, "png"));
|
|
156
|
+
}
|
|
157
|
+
function exportComponent(button, component, format) {
|
|
158
|
+
if (format === "csv") {
|
|
159
|
+
const csv = componentToCsv(component);
|
|
160
|
+
if (csv) download(csv, "text/csv;charset=utf-8", filename(component.title, "csv"));
|
|
161
|
+
} else if (format === "svg") {
|
|
162
|
+
const markup = svgMarkup(button);
|
|
163
|
+
if (markup) download(markup, "image/svg+xml;charset=utf-8", filename(component.title, "svg"));
|
|
164
|
+
} else {
|
|
165
|
+
void exportPng(button, component.title);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// ../agent-ui/src/components/component-actions/export-actions.tsx
|
|
170
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
171
|
+
var FORMAT_LABELS = {
|
|
172
|
+
csv: "Export as CSV",
|
|
173
|
+
png: "Export as PNG",
|
|
174
|
+
svg: "Export as SVG"
|
|
175
|
+
};
|
|
176
|
+
function ComponentExportActions({
|
|
177
|
+
component,
|
|
178
|
+
formats = [],
|
|
179
|
+
onAction
|
|
180
|
+
}) {
|
|
181
|
+
const triggerRef = useRef(null);
|
|
182
|
+
const [portalContainer, setPortalContainer] = useState();
|
|
183
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
184
|
+
const pointerOpenAt = useRef(0);
|
|
185
|
+
const handleOpenChange = (nextOpen) => {
|
|
186
|
+
if (!nextOpen && Date.now() - pointerOpenAt.current < 350) return;
|
|
187
|
+
setIsOpen(nextOpen);
|
|
188
|
+
};
|
|
189
|
+
const captureTrigger = useCallback((node) => {
|
|
190
|
+
triggerRef.current = node;
|
|
191
|
+
setPortalContainer(resolveOverlayPortalContainer(node));
|
|
192
|
+
}, []);
|
|
193
|
+
const supported = formats.filter((format) => format !== "csv" || componentToCsv(component));
|
|
194
|
+
if (supported.length === 0) return null;
|
|
195
|
+
return /* @__PURE__ */ jsx("div", { className: "aui-export-actions", "data-slot": "agent-ui-export-actions", children: /* @__PURE__ */ jsxs(Dropdown, { isOpen, onOpenChange: handleOpenChange, children: [
|
|
196
|
+
/* @__PURE__ */ jsx(
|
|
197
|
+
Button,
|
|
198
|
+
{
|
|
199
|
+
ref: captureTrigger,
|
|
200
|
+
isIconOnly: true,
|
|
201
|
+
"aria-label": `Export options for ${component.title}`,
|
|
202
|
+
size: "sm",
|
|
203
|
+
variant: "ghost",
|
|
204
|
+
onPointerDown: () => {
|
|
205
|
+
pointerOpenAt.current = Date.now();
|
|
206
|
+
},
|
|
207
|
+
children: /* @__PURE__ */ jsx(Ellipsis, {})
|
|
208
|
+
}
|
|
209
|
+
),
|
|
210
|
+
/* @__PURE__ */ jsx(Dropdown.Popover, { placement: "bottom end", UNSTABLE_portalContainer: portalContainer, children: /* @__PURE__ */ jsx(
|
|
211
|
+
Dropdown.Menu,
|
|
212
|
+
{
|
|
213
|
+
onAction: (key) => {
|
|
214
|
+
const format = key;
|
|
215
|
+
if (triggerRef.current) exportComponent(triggerRef.current, component, format);
|
|
216
|
+
onAction?.({ componentId: component.id, format, type: "export" });
|
|
217
|
+
setIsOpen(false);
|
|
218
|
+
},
|
|
219
|
+
children: supported.map((format) => /* @__PURE__ */ jsx(Dropdown.Item, { id: format, textValue: FORMAT_LABELS[format], children: /* @__PURE__ */ jsx(Label, { children: FORMAT_LABELS[format] }) }, format))
|
|
220
|
+
}
|
|
221
|
+
) })
|
|
222
|
+
] }) });
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// ../agent-ui/src/components/data-visualization/trend-change/trend-change.tsx
|
|
226
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
227
|
+
function TrendArrow({ direction }) {
|
|
228
|
+
return /* @__PURE__ */ jsx2(
|
|
229
|
+
"svg",
|
|
230
|
+
{
|
|
231
|
+
"aria-hidden": "true",
|
|
232
|
+
className: "aui-change__indicator",
|
|
233
|
+
fill: "none",
|
|
234
|
+
stroke: "currentColor",
|
|
235
|
+
strokeLinecap: "round",
|
|
236
|
+
strokeLinejoin: "round",
|
|
237
|
+
strokeWidth: "2",
|
|
238
|
+
viewBox: "0 0 24 24",
|
|
239
|
+
children: direction === "up" ? /* @__PURE__ */ jsx2("path", { d: "M12 19V5m-5 5 5-5 5 5" }) : /* @__PURE__ */ jsx2("path", { d: "M12 5v14m5-5-5 5-5-5" })
|
|
240
|
+
}
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
function TrendChange({ slot, value }) {
|
|
244
|
+
return /* @__PURE__ */ jsxs2(
|
|
245
|
+
"span",
|
|
246
|
+
{
|
|
247
|
+
className: "aui-change",
|
|
248
|
+
"data-slot": slot,
|
|
249
|
+
"data-trend": value > 0 ? "up" : value < 0 ? "down" : "neutral",
|
|
250
|
+
children: [
|
|
251
|
+
value === 0 ? null : /* @__PURE__ */ jsx2(TrendArrow, { direction: value > 0 ? "up" : "down" }),
|
|
252
|
+
formatDelta(value),
|
|
253
|
+
"%"
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// ../agent-ui/src/components/data-visualization/charts/chart-colors.ts
|
|
260
|
+
var COLORS = [
|
|
261
|
+
"var(--chart-3, var(--accent))",
|
|
262
|
+
"var(--chart-1, oklch(from var(--accent) calc(l - 0.24) c h))",
|
|
263
|
+
"var(--chart-4, oklch(from var(--accent) calc(l + 0.12) c h))",
|
|
264
|
+
"var(--chart-2, oklch(from var(--accent) calc(l - 0.12) c h))",
|
|
265
|
+
"var(--chart-5, oklch(from var(--accent) calc(l + 0.24) c h))"
|
|
266
|
+
];
|
|
267
|
+
var CHART_COLOR_TOKENS = {
|
|
268
|
+
accent: "var(--accent)",
|
|
269
|
+
"chart-1": "var(--chart-1, oklch(from var(--accent) calc(l - 0.24) c h))",
|
|
270
|
+
"chart-2": "var(--chart-2, oklch(from var(--accent) calc(l - 0.12) c h))",
|
|
271
|
+
"chart-3": "var(--chart-3, var(--accent))",
|
|
272
|
+
"chart-4": "var(--chart-4, oklch(from var(--accent) calc(l + 0.12) c h))",
|
|
273
|
+
"chart-5": "var(--chart-5, oklch(from var(--accent) calc(l + 0.24) c h))",
|
|
274
|
+
danger: "var(--danger)",
|
|
275
|
+
default: "var(--default-foreground, var(--foreground))",
|
|
276
|
+
success: "var(--success)",
|
|
277
|
+
warning: "var(--warning)"
|
|
278
|
+
};
|
|
279
|
+
function resolveChartColor(color, index) {
|
|
280
|
+
return color ? CHART_COLOR_TOKENS[color] : COLORS[index % COLORS.length];
|
|
281
|
+
}
|
|
282
|
+
function paletteChartColor(index) {
|
|
283
|
+
return COLORS[index % COLORS.length];
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
export {
|
|
287
|
+
componentActionFromSpec,
|
|
288
|
+
createComponentSelection,
|
|
289
|
+
formatNumber,
|
|
290
|
+
formatAxisValue,
|
|
291
|
+
formatCell,
|
|
292
|
+
ComponentExportActions,
|
|
293
|
+
TrendChange,
|
|
294
|
+
CHART_COLOR_TOKENS,
|
|
295
|
+
resolveChartColor,
|
|
296
|
+
paletteChartColor
|
|
297
|
+
};
|