@heroui/agent 0.2.0-beta.8 → 0.2.0-beta.9
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 +5 -0
- package/dist/chart-content-BBHQVMP4.js +1 -0
- package/dist/chunk-2XBFFSW2.js +1 -0
- package/dist/chunk-64RI74L5.js +1 -0
- package/dist/chunk-6ZJJN322.js +1 -0
- package/dist/chunk-7KCGPNEN.js +1 -0
- package/dist/chunk-BBB5EHDN.js +5 -0
- package/dist/chunk-CR3H7AVI.js +1 -0
- package/dist/chunk-HCLXS4HQ.js +1 -0
- package/dist/chunk-MXLGM4WV.js +1 -0
- package/dist/chunk-OA3TG5CS.js +1 -0
- package/dist/chunk-PZJ4NC3J.js +1 -0
- package/dist/chunk-RNNGE7KM.js +1 -0
- package/dist/chunk-S6OIAJSC.js +1 -0
- package/dist/chunk-SUDHJNTJ.js +2 -0
- package/dist/chunk-WUAFMD7Z.js +2 -0
- package/dist/component-renderer-GG6JVRUG.js +1 -0
- package/dist/composer-draft-NSKK65F3.js +1 -0
- package/dist/composer-image-draft-KAGTNQR7.js +1 -0
- package/dist/contracts.d.ts +1 -1
- package/dist/contracts.js +2 -2445
- package/dist/embed-runtime-GYXK7V6N.js +5 -0
- package/dist/index.js +1 -31
- package/dist/interactive-map-surface-WC2LPCR7.js +1 -0
- package/dist/internal/client-tools.js +1 -0
- package/dist/internal/models.js +1 -0
- package/dist/internal/runtime.js +1 -0
- package/dist/internal/theme.js +1 -0
- package/dist/next.js +1 -25
- package/dist/server.js +1 -136
- package/package.json +4 -4
- package/dist/chart-content-E4NPTUPR.js +0 -2696
- package/dist/chunk-3FG5NRTX.js +0 -9
- package/dist/chunk-CMZDZGUZ.js +0 -1132
- package/dist/chunk-DS4X5K2R.js +0 -56
- package/dist/chunk-FNGGMHVR.js +0 -625
- package/dist/chunk-G6GFNSG4.js +0 -284
- package/dist/chunk-Q7LGTVBL.js +0 -43
- package/dist/chunk-TOOT6SZ2.js +0 -74
- package/dist/chunk-UUPU3MYB.js +0 -42
- package/dist/chunk-VJA52U5P.js +0 -137
- package/dist/chunk-W7SCMB3O.js +0 -1285
- package/dist/component-renderer-MDDQMQTU.js +0 -10629
- package/dist/composer-draft-DTQAEO5K.js +0 -20
- package/dist/composer-image-draft-IVJ352E6.js +0 -174
- package/dist/embed-runtime-VVAGDPYY.js +0 -9422
- package/dist/interactive-map-surface-67KHT3VB.js +0 -362
package/dist/chunk-W7SCMB3O.js
DELETED
|
@@ -1,1285 +0,0 @@
|
|
|
1
|
-
// src/embed/client-tools.ts
|
|
2
|
-
function createToolHelper() {
|
|
3
|
-
return function defineClientTool(definition) {
|
|
4
|
-
return definition;
|
|
5
|
-
};
|
|
6
|
-
}
|
|
7
|
-
function isZodSchema(value) {
|
|
8
|
-
return Boolean(
|
|
9
|
-
value && typeof value === "object" && typeof value.safeParse === "function"
|
|
10
|
-
);
|
|
11
|
-
}
|
|
12
|
-
function parseClientToolArgs(tool, input) {
|
|
13
|
-
return isZodSchema(tool.parameters) ? tool.parameters.parse(input) : input;
|
|
14
|
-
}
|
|
15
|
-
function resolveDirectToolAction(tools, toolName) {
|
|
16
|
-
const tool = tools.get(toolName);
|
|
17
|
-
if (!tool || tool.needsApproval) return null;
|
|
18
|
-
return tool;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// src/embed/agent-loading-state.tsx
|
|
22
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
23
|
-
function AgentLoadingState({
|
|
24
|
-
indicator,
|
|
25
|
-
label = "Loading agent\u2026"
|
|
26
|
-
}) {
|
|
27
|
-
return /* @__PURE__ */ jsxs("div", { "aria-live": "polite", className: "ha-agent-loading", role: "status", children: [
|
|
28
|
-
indicator,
|
|
29
|
-
/* @__PURE__ */ jsx("span", { children: label })
|
|
30
|
-
] });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// src/embed/composer-control-tooltip.tsx
|
|
34
|
-
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
35
|
-
function ComposerControlTooltip({
|
|
36
|
-
children,
|
|
37
|
-
shortcut
|
|
38
|
-
}) {
|
|
39
|
-
return /* @__PURE__ */ jsxs2("span", { "aria-hidden": "true", className: "ha-control-tooltip", children: [
|
|
40
|
-
/* @__PURE__ */ jsx2("span", { children }),
|
|
41
|
-
shortcut ? /* @__PURE__ */ jsx2("kbd", { className: "ha-control-tooltip__shortcut", children: shortcut }) : null
|
|
42
|
-
] });
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// src/embed/panel-shell.tsx
|
|
46
|
-
import { ChevronsCollapseUpRight, ChevronsExpandUpRight } from "@gravity-ui/icons";
|
|
47
|
-
import { useCallback, useEffect, useEffectEvent, useRef, useState } from "react";
|
|
48
|
-
|
|
49
|
-
// src/embed/sidebar-width.ts
|
|
50
|
-
var SIDEBAR_DEFAULT_WIDTH = 420;
|
|
51
|
-
var SIDEBAR_MIN_WIDTH = 320;
|
|
52
|
-
var SIDEBAR_MAX_WIDTH = 720;
|
|
53
|
-
function sidebarWidthStorageKey(agentId) {
|
|
54
|
-
return `heroui-agent:sidebar-width:${agentId}`;
|
|
55
|
-
}
|
|
56
|
-
function clampSidebarWidth(width, viewportWidth) {
|
|
57
|
-
const viewportMax = Math.min(SIDEBAR_MAX_WIDTH, Math.floor(viewportWidth * 0.9));
|
|
58
|
-
const max = Math.max(viewportMax, SIDEBAR_MIN_WIDTH);
|
|
59
|
-
return Math.min(Math.max(Math.round(width), SIDEBAR_MIN_WIDTH), max);
|
|
60
|
-
}
|
|
61
|
-
function readSidebarWidth(agentId, viewportWidth) {
|
|
62
|
-
let stored = Number.NaN;
|
|
63
|
-
try {
|
|
64
|
-
stored = Number(localStorage.getItem(sidebarWidthStorageKey(agentId)) ?? Number.NaN);
|
|
65
|
-
} catch {
|
|
66
|
-
}
|
|
67
|
-
return clampSidebarWidth(Number.isFinite(stored) ? stored : SIDEBAR_DEFAULT_WIDTH, viewportWidth);
|
|
68
|
-
}
|
|
69
|
-
function persistSidebarWidth(agentId, width) {
|
|
70
|
-
try {
|
|
71
|
-
localStorage.setItem(sidebarWidthStorageKey(agentId), String(Math.round(width)));
|
|
72
|
-
} catch {
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// src/embed/panel-shell.tsx
|
|
77
|
-
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
78
|
-
function PanelShell({
|
|
79
|
-
actionsSlot,
|
|
80
|
-
agentId,
|
|
81
|
-
children,
|
|
82
|
-
defaultExpanded = false,
|
|
83
|
-
expandable = true,
|
|
84
|
-
expandedSidebarSlot,
|
|
85
|
-
expandedTitle,
|
|
86
|
-
historySlot,
|
|
87
|
-
keepMounted = false,
|
|
88
|
-
modal,
|
|
89
|
-
name,
|
|
90
|
-
onClose,
|
|
91
|
-
onNewConversation,
|
|
92
|
-
open
|
|
93
|
-
}) {
|
|
94
|
-
const panelRef = useRef(null);
|
|
95
|
-
const overlayEscapeAt = useRef(0);
|
|
96
|
-
const [isMobileViewport, setIsMobileViewport] = useState(
|
|
97
|
-
() => typeof window !== "undefined" && window.matchMedia?.("(max-width: 639px)").matches === true
|
|
98
|
-
);
|
|
99
|
-
const closePanel = useEffectEvent(onClose);
|
|
100
|
-
const [isExpanded, setIsExpanded] = useState(defaultExpanded);
|
|
101
|
-
const isDesktopSidebar = !modal && !isMobileViewport;
|
|
102
|
-
const effectiveModal = modal || isMobileViewport || isDesktopSidebar && isExpanded;
|
|
103
|
-
const [isResizing, setIsResizing] = useState(false);
|
|
104
|
-
const canExpand = !isMobileViewport && expandable;
|
|
105
|
-
const showExpandedSidebar = isDesktopSidebar && isExpanded && expandedSidebarSlot;
|
|
106
|
-
useEffect(() => {
|
|
107
|
-
const query = window.matchMedia?.("(max-width: 639px)");
|
|
108
|
-
if (!query) return;
|
|
109
|
-
const updateViewport = () => setIsMobileViewport(query.matches);
|
|
110
|
-
updateViewport();
|
|
111
|
-
query.addEventListener?.("change", updateViewport);
|
|
112
|
-
return () => query.removeEventListener?.("change", updateViewport);
|
|
113
|
-
}, []);
|
|
114
|
-
useEffect(() => {
|
|
115
|
-
if (!isResizing) return;
|
|
116
|
-
const panel = panelRef.current;
|
|
117
|
-
if (!panel) return;
|
|
118
|
-
const settle = () => setIsResizing(false);
|
|
119
|
-
const onTransitionEnd = (event) => {
|
|
120
|
-
const { propertyName, target } = event;
|
|
121
|
-
if (target !== panel) return;
|
|
122
|
-
if (propertyName !== "width" && propertyName !== "height") return;
|
|
123
|
-
settle();
|
|
124
|
-
};
|
|
125
|
-
const timer = window.setTimeout(settle, 600);
|
|
126
|
-
panel.addEventListener("transitionend", onTransitionEnd);
|
|
127
|
-
return () => {
|
|
128
|
-
window.clearTimeout(timer);
|
|
129
|
-
panel.removeEventListener("transitionend", onTransitionEnd);
|
|
130
|
-
};
|
|
131
|
-
}, [isResizing]);
|
|
132
|
-
useEffect(() => {
|
|
133
|
-
if (!open) return;
|
|
134
|
-
const panel = panelRef.current;
|
|
135
|
-
if (!panel) return;
|
|
136
|
-
const previous = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
137
|
-
if (!panel.open) {
|
|
138
|
-
if (effectiveModal && typeof panel.showModal === "function") panel.showModal();
|
|
139
|
-
else if (!effectiveModal && typeof panel.show === "function") panel.show();
|
|
140
|
-
else panel.open = true;
|
|
141
|
-
}
|
|
142
|
-
const documentRoot = document.documentElement;
|
|
143
|
-
const scrollX = window.scrollX;
|
|
144
|
-
const scrollY = window.scrollY;
|
|
145
|
-
const previousRootOverflow = documentRoot.style.overflow;
|
|
146
|
-
const previousBodyOverflow = document.body.style.overflow;
|
|
147
|
-
const previousBodyPosition = document.body.style.position;
|
|
148
|
-
const previousBodyTop = document.body.style.top;
|
|
149
|
-
const previousBodyLeft = document.body.style.left;
|
|
150
|
-
const previousBodyRight = document.body.style.right;
|
|
151
|
-
const previousBodyWidth = document.body.style.width;
|
|
152
|
-
if (effectiveModal) {
|
|
153
|
-
documentRoot.style.overflow = "hidden";
|
|
154
|
-
document.body.style.overflow = "hidden";
|
|
155
|
-
document.body.style.position = "fixed";
|
|
156
|
-
document.body.style.top = `${-scrollY}px`;
|
|
157
|
-
document.body.style.left = `${-scrollX}px`;
|
|
158
|
-
document.body.style.right = "0";
|
|
159
|
-
document.body.style.width = "100%";
|
|
160
|
-
}
|
|
161
|
-
const first = panel.querySelector(
|
|
162
|
-
"button,textarea,input,[tabindex]:not([tabindex='-1'])"
|
|
163
|
-
);
|
|
164
|
-
if (!panel.contains(document.activeElement)) first?.focus();
|
|
165
|
-
const handleKeyDown = (event) => {
|
|
166
|
-
if (!effectiveModal && event.key === "Escape") {
|
|
167
|
-
if (dismissOpenPanelOverlay(panel)) {
|
|
168
|
-
overlayEscapeAt.current = Date.now();
|
|
169
|
-
event.preventDefault();
|
|
170
|
-
event.stopPropagation();
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
event.preventDefault();
|
|
174
|
-
closePanel();
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
if (!effectiveModal || event.key !== "Tab") return;
|
|
178
|
-
const focusable = Array.from(
|
|
179
|
-
panel.querySelectorAll(
|
|
180
|
-
"button:not(:disabled),textarea:not(:disabled),input:not(:disabled),[tabindex]:not([tabindex='-1'])"
|
|
181
|
-
)
|
|
182
|
-
);
|
|
183
|
-
if (focusable.length === 0) return;
|
|
184
|
-
const firstElement = focusable[0];
|
|
185
|
-
const lastElement = focusable[focusable.length - 1];
|
|
186
|
-
const root = panel.getRootNode();
|
|
187
|
-
const activeElement = root instanceof ShadowRoot ? root.activeElement : document.activeElement;
|
|
188
|
-
if (event.shiftKey && activeElement === firstElement) {
|
|
189
|
-
event.preventDefault();
|
|
190
|
-
lastElement.focus();
|
|
191
|
-
} else if (!event.shiftKey && activeElement === lastElement) {
|
|
192
|
-
event.preventDefault();
|
|
193
|
-
firstElement.focus();
|
|
194
|
-
}
|
|
195
|
-
};
|
|
196
|
-
panel.addEventListener("keydown", handleKeyDown);
|
|
197
|
-
return () => {
|
|
198
|
-
panel.removeEventListener("keydown", handleKeyDown);
|
|
199
|
-
if (typeof panel.close === "function") panel.close();
|
|
200
|
-
else panel.open = false;
|
|
201
|
-
documentRoot.style.overflow = previousRootOverflow;
|
|
202
|
-
document.body.style.overflow = previousBodyOverflow;
|
|
203
|
-
document.body.style.position = previousBodyPosition;
|
|
204
|
-
document.body.style.top = previousBodyTop;
|
|
205
|
-
document.body.style.left = previousBodyLeft;
|
|
206
|
-
document.body.style.right = previousBodyRight;
|
|
207
|
-
document.body.style.width = previousBodyWidth;
|
|
208
|
-
if (effectiveModal) window.scrollTo(scrollX, scrollY);
|
|
209
|
-
if (document.activeElement === document.body) previous?.focus();
|
|
210
|
-
};
|
|
211
|
-
}, [effectiveModal, open]);
|
|
212
|
-
if (!open && !keepMounted) return null;
|
|
213
|
-
return /* @__PURE__ */ jsxs3(
|
|
214
|
-
"dialog",
|
|
215
|
-
{
|
|
216
|
-
ref: panelRef,
|
|
217
|
-
"aria-label": name,
|
|
218
|
-
"aria-modal": effectiveModal,
|
|
219
|
-
className: "ha-panel",
|
|
220
|
-
"data-agent-overlay-root": "",
|
|
221
|
-
"data-expanded": !isMobileViewport && isExpanded ? "true" : void 0,
|
|
222
|
-
"data-expanded-sidebar": showExpandedSidebar ? "true" : void 0,
|
|
223
|
-
"data-resizing": isResizing ? "true" : void 0,
|
|
224
|
-
hidden: !open,
|
|
225
|
-
onCancel: (event) => {
|
|
226
|
-
event.preventDefault();
|
|
227
|
-
if (Date.now() - overlayEscapeAt.current < 350 || dismissOpenPanelOverlay(panelRef.current)) {
|
|
228
|
-
overlayEscapeAt.current = Date.now();
|
|
229
|
-
return;
|
|
230
|
-
}
|
|
231
|
-
onClose();
|
|
232
|
-
},
|
|
233
|
-
children: [
|
|
234
|
-
isDesktopSidebar && !isExpanded ? /* @__PURE__ */ jsx3(SidebarResizeHandle, { agentId, panelRef }) : null,
|
|
235
|
-
showExpandedSidebar ? /* @__PURE__ */ jsx3("aside", { "aria-label": "Chat history", className: "ha-expanded-sidebar", children: expandedSidebarSlot }) : null,
|
|
236
|
-
/* @__PURE__ */ jsxs3("div", { className: "ha-panel-main", children: [
|
|
237
|
-
/* @__PURE__ */ jsxs3("header", { className: "ha-header", children: [
|
|
238
|
-
showExpandedSidebar ? /* @__PURE__ */ jsx3("span", { className: "ha-session-title ha-expanded-chat-title", children: expandedTitle ?? name }) : historySlot ?? /* @__PURE__ */ jsx3("strong", { children: name }),
|
|
239
|
-
/* @__PURE__ */ jsxs3("div", { className: "ha-header-actions", children: [
|
|
240
|
-
showExpandedSidebar ? null : actionsSlot ?? (onNewConversation ? /* @__PURE__ */ jsx3(
|
|
241
|
-
"button",
|
|
242
|
-
{
|
|
243
|
-
"aria-label": "New chat",
|
|
244
|
-
className: "ha-icon-button ha-new-chat-button",
|
|
245
|
-
type: "button",
|
|
246
|
-
onClick: onNewConversation,
|
|
247
|
-
children: /* @__PURE__ */ jsx3(PlusGlyph, {})
|
|
248
|
-
}
|
|
249
|
-
) : null),
|
|
250
|
-
canExpand ? /* @__PURE__ */ jsx3(
|
|
251
|
-
"button",
|
|
252
|
-
{
|
|
253
|
-
"aria-expanded": isExpanded,
|
|
254
|
-
"aria-label": isExpanded ? "Collapse assistant" : "Expand assistant",
|
|
255
|
-
className: "ha-expand-button ha-icon-button",
|
|
256
|
-
type: "button",
|
|
257
|
-
onClick: () => {
|
|
258
|
-
setIsResizing(true);
|
|
259
|
-
setIsExpanded((expanded) => !expanded);
|
|
260
|
-
},
|
|
261
|
-
children: isExpanded ? /* @__PURE__ */ jsx3(ChevronsCollapseUpRight, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx3(ChevronsExpandUpRight, { "aria-hidden": "true" })
|
|
262
|
-
}
|
|
263
|
-
) : null,
|
|
264
|
-
/* @__PURE__ */ jsxs3(
|
|
265
|
-
"button",
|
|
266
|
-
{
|
|
267
|
-
"aria-keyshortcuts": "Escape",
|
|
268
|
-
"aria-label": "Close assistant",
|
|
269
|
-
className: "ha-close-button ha-icon-button",
|
|
270
|
-
"data-shortcut": "ESC",
|
|
271
|
-
"data-tooltip": "Close assistant",
|
|
272
|
-
type: "button",
|
|
273
|
-
onClick: onClose,
|
|
274
|
-
children: [
|
|
275
|
-
/* @__PURE__ */ jsx3(CloseGlyph, {}),
|
|
276
|
-
/* @__PURE__ */ jsx3(ComposerControlTooltip, { shortcut: "ESC", children: "Close assistant" })
|
|
277
|
-
]
|
|
278
|
-
}
|
|
279
|
-
)
|
|
280
|
-
] })
|
|
281
|
-
] }),
|
|
282
|
-
children,
|
|
283
|
-
/* @__PURE__ */ jsx3("div", { className: "ha-overlay-portal", "data-agent-overlay-portal": "" })
|
|
284
|
-
] })
|
|
285
|
-
]
|
|
286
|
-
}
|
|
287
|
-
);
|
|
288
|
-
}
|
|
289
|
-
function dismissOpenPanelOverlay(panel) {
|
|
290
|
-
const overlay = panel?.querySelector(
|
|
291
|
-
[
|
|
292
|
-
'[data-slot$="-popover"]',
|
|
293
|
-
'[data-slot="agent-ui-image-modal"]',
|
|
294
|
-
'[data-slot="modal-dialog"]',
|
|
295
|
-
".ha-feedback-popover"
|
|
296
|
-
].join(",")
|
|
297
|
-
);
|
|
298
|
-
if (!overlay) return false;
|
|
299
|
-
overlay.querySelector('button[aria-label="Dismiss"]')?.click();
|
|
300
|
-
return true;
|
|
301
|
-
}
|
|
302
|
-
function SidebarResizeHandle({
|
|
303
|
-
agentId,
|
|
304
|
-
panelRef
|
|
305
|
-
}) {
|
|
306
|
-
const [width, setWidth] = useState(() => readSidebarWidth(agentId, window.innerWidth));
|
|
307
|
-
const dragRef = useRef(null);
|
|
308
|
-
const applyWidth = useCallback(
|
|
309
|
-
(nextWidth) => {
|
|
310
|
-
const panel = panelRef.current;
|
|
311
|
-
const root = panel?.getRootNode();
|
|
312
|
-
const host = root instanceof ShadowRoot ? root.host : panel?.closest("[data-heroui-agent]");
|
|
313
|
-
host?.style.setProperty("--ha-sidebar-width", `${nextWidth}px`);
|
|
314
|
-
if (window.innerWidth >= 640) {
|
|
315
|
-
document.documentElement.style.marginRight = `${Math.min(nextWidth, window.innerWidth)}px`;
|
|
316
|
-
}
|
|
317
|
-
setWidth(nextWidth);
|
|
318
|
-
},
|
|
319
|
-
[panelRef]
|
|
320
|
-
);
|
|
321
|
-
const resizeTo = useCallback(
|
|
322
|
-
(nextWidth, persist) => {
|
|
323
|
-
const clamped = clampSidebarWidth(nextWidth, window.innerWidth);
|
|
324
|
-
applyWidth(clamped);
|
|
325
|
-
if (persist) persistSidebarWidth(agentId, clamped);
|
|
326
|
-
return clamped;
|
|
327
|
-
},
|
|
328
|
-
[applyWidth, agentId]
|
|
329
|
-
);
|
|
330
|
-
return (
|
|
331
|
-
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- A focusable separator is the WAI-ARIA "window splitter" pattern: it is interactive by specification even though jsx-a11y does not model it.
|
|
332
|
-
/* @__PURE__ */ jsx3(
|
|
333
|
-
"div",
|
|
334
|
-
{
|
|
335
|
-
"aria-label": "Resize assistant panel",
|
|
336
|
-
"aria-orientation": "vertical",
|
|
337
|
-
"aria-valuemax": SIDEBAR_MAX_WIDTH,
|
|
338
|
-
"aria-valuemin": SIDEBAR_MIN_WIDTH,
|
|
339
|
-
"aria-valuenow": width,
|
|
340
|
-
className: "ha-resize-handle",
|
|
341
|
-
role: "separator",
|
|
342
|
-
tabIndex: 0,
|
|
343
|
-
onKeyDown: (event) => {
|
|
344
|
-
const delta = event.key === "ArrowLeft" ? 24 : event.key === "ArrowRight" ? -24 : 0;
|
|
345
|
-
if (delta === 0) return;
|
|
346
|
-
event.preventDefault();
|
|
347
|
-
resizeTo(width + delta, true);
|
|
348
|
-
},
|
|
349
|
-
onPointerCancel: (event) => {
|
|
350
|
-
const drag = dragRef.current;
|
|
351
|
-
if (!drag) return;
|
|
352
|
-
dragRef.current = null;
|
|
353
|
-
delete event.currentTarget.dataset["resizing"];
|
|
354
|
-
if (panelRef.current) delete panelRef.current.dataset["dragResizing"];
|
|
355
|
-
document.documentElement.style.transition = drag.pageTransition;
|
|
356
|
-
resizeTo(drag.startWidth, false);
|
|
357
|
-
},
|
|
358
|
-
onPointerDown: (event) => {
|
|
359
|
-
if (event.button !== 0 && event.pointerType === "mouse") return;
|
|
360
|
-
event.preventDefault();
|
|
361
|
-
event.currentTarget.setPointerCapture(event.pointerId);
|
|
362
|
-
event.currentTarget.dataset["resizing"] = "true";
|
|
363
|
-
dragRef.current = {
|
|
364
|
-
currentWidth: width,
|
|
365
|
-
pageTransition: document.documentElement.style.transition,
|
|
366
|
-
startWidth: width,
|
|
367
|
-
startX: event.clientX
|
|
368
|
-
};
|
|
369
|
-
document.documentElement.style.transition = "none";
|
|
370
|
-
if (panelRef.current) panelRef.current.dataset["dragResizing"] = "true";
|
|
371
|
-
},
|
|
372
|
-
onPointerMove: (event) => {
|
|
373
|
-
const drag = dragRef.current;
|
|
374
|
-
if (!drag) return;
|
|
375
|
-
drag.currentWidth = resizeTo(drag.startWidth + (drag.startX - event.clientX), false);
|
|
376
|
-
},
|
|
377
|
-
onPointerUp: (event) => {
|
|
378
|
-
const drag = dragRef.current;
|
|
379
|
-
if (!drag) return;
|
|
380
|
-
dragRef.current = null;
|
|
381
|
-
delete event.currentTarget.dataset["resizing"];
|
|
382
|
-
if (panelRef.current) delete panelRef.current.dataset["dragResizing"];
|
|
383
|
-
event.currentTarget.releasePointerCapture(event.pointerId);
|
|
384
|
-
document.documentElement.style.transition = drag.pageTransition;
|
|
385
|
-
persistSidebarWidth(agentId, drag.currentWidth);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
)
|
|
389
|
-
);
|
|
390
|
-
}
|
|
391
|
-
function CloseGlyph() {
|
|
392
|
-
return /* @__PURE__ */ jsx3("svg", { "aria-hidden": "true", fill: "none", height: "18", viewBox: "0 0 18 18", width: "18", children: /* @__PURE__ */ jsx3(
|
|
393
|
-
"path",
|
|
394
|
-
{
|
|
395
|
-
d: "m4.25 4.25 9.5 9.5m0-9.5-9.5 9.5",
|
|
396
|
-
stroke: "currentColor",
|
|
397
|
-
strokeLinecap: "round",
|
|
398
|
-
strokeWidth: "1.6"
|
|
399
|
-
}
|
|
400
|
-
) });
|
|
401
|
-
}
|
|
402
|
-
function PlusGlyph() {
|
|
403
|
-
return /* @__PURE__ */ jsx3("svg", { "aria-hidden": "true", fill: "none", height: "18", viewBox: "0 0 18 18", width: "18", children: /* @__PURE__ */ jsx3("path", { d: "M9 4v10M4 9h10", stroke: "currentColor", strokeLinecap: "round", strokeWidth: "1.6" }) });
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
// src/contracts/models.ts
|
|
407
|
-
var AGENT_MODEL_IDS = [
|
|
408
|
-
"moonshotai/Kimi-K3",
|
|
409
|
-
"openai/gpt-5.6-luna",
|
|
410
|
-
"openai/gpt-5.6-terra",
|
|
411
|
-
"openai/gpt-5.6-sol",
|
|
412
|
-
"google/gemini-3.6-flash",
|
|
413
|
-
"anthropic/claude-sonnet-5",
|
|
414
|
-
"anthropic/claude-opus-4.8"
|
|
415
|
-
];
|
|
416
|
-
var LEGACY_AGENT_MODEL_IDS = {
|
|
417
|
-
"google/gemini-3.5-flash": "google/gemini-3.6-flash"
|
|
418
|
-
};
|
|
419
|
-
function resolveAgentModelId(value) {
|
|
420
|
-
return LEGACY_AGENT_MODEL_IDS[value] ?? value;
|
|
421
|
-
}
|
|
422
|
-
var DEFAULT_AGENT_PICKER_MODEL_ID = "openai/gpt-5.6-luna";
|
|
423
|
-
var AGENT_MODEL_OPTIONS = [
|
|
424
|
-
{
|
|
425
|
-
description: "Flagship model for coding, reasoning, and knowledge work",
|
|
426
|
-
id: "moonshotai/Kimi-K3",
|
|
427
|
-
label: "Kimi K3",
|
|
428
|
-
provider: "Moonshot AI",
|
|
429
|
-
tier: "light"
|
|
430
|
-
},
|
|
431
|
-
{
|
|
432
|
-
description: "Fast answers and lightweight agent workflows",
|
|
433
|
-
id: "openai/gpt-5.6-luna",
|
|
434
|
-
label: "GPT-5.6 Luna",
|
|
435
|
-
provider: "OpenAI",
|
|
436
|
-
tier: "light"
|
|
437
|
-
},
|
|
438
|
-
{
|
|
439
|
-
description: "Balanced reasoning for everyday agent tasks",
|
|
440
|
-
id: "openai/gpt-5.6-terra",
|
|
441
|
-
label: "GPT-5.6 Terra",
|
|
442
|
-
provider: "OpenAI",
|
|
443
|
-
tier: "codegen"
|
|
444
|
-
},
|
|
445
|
-
{
|
|
446
|
-
description: "Deep reasoning for complex, multi-step analysis",
|
|
447
|
-
id: "openai/gpt-5.6-sol",
|
|
448
|
-
label: "GPT-5.6 Sol",
|
|
449
|
-
provider: "OpenAI",
|
|
450
|
-
tier: "complex"
|
|
451
|
-
},
|
|
452
|
-
{
|
|
453
|
-
description: "Fast multimodal analysis with a large context window",
|
|
454
|
-
id: "google/gemini-3.6-flash",
|
|
455
|
-
label: "Gemini 3.6 Flash",
|
|
456
|
-
provider: "Google",
|
|
457
|
-
tier: "light"
|
|
458
|
-
},
|
|
459
|
-
{
|
|
460
|
-
description: "Strong agentic reasoning and polished UI decisions",
|
|
461
|
-
id: "anthropic/claude-sonnet-5",
|
|
462
|
-
label: "Claude Sonnet 5",
|
|
463
|
-
provider: "Anthropic",
|
|
464
|
-
tier: "codegen"
|
|
465
|
-
},
|
|
466
|
-
{
|
|
467
|
-
description: "Highest-capability Claude for difficult research and analysis",
|
|
468
|
-
id: "anthropic/claude-opus-4.8",
|
|
469
|
-
label: "Claude Opus 4.8",
|
|
470
|
-
provider: "Anthropic",
|
|
471
|
-
tier: "complex"
|
|
472
|
-
}
|
|
473
|
-
];
|
|
474
|
-
var AGENT_MODEL_ID_SET = new Set(AGENT_MODEL_IDS);
|
|
475
|
-
function isAgentModelId(value) {
|
|
476
|
-
return typeof value === "string" && AGENT_MODEL_ID_SET.has(value);
|
|
477
|
-
}
|
|
478
|
-
function getAgentModelTier(modelId) {
|
|
479
|
-
const resolved = modelId ? resolveAgentModelId(modelId) : void 0;
|
|
480
|
-
return AGENT_MODEL_OPTIONS.find((option) => option.id === resolved)?.tier ?? "light";
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// src/embed/shell-handoff.ts
|
|
484
|
-
function createSubmittedAgentShellHandoff(prompt) {
|
|
485
|
-
const startedAt = performance.now();
|
|
486
|
-
const startedAtWallClock = Date.now();
|
|
487
|
-
const trimmedPrompt = prompt.trim();
|
|
488
|
-
if (!trimmedPrompt) return null;
|
|
489
|
-
return {
|
|
490
|
-
messageId: crypto.randomUUID(),
|
|
491
|
-
prompt: trimmedPrompt,
|
|
492
|
-
startedAt,
|
|
493
|
-
startedAtWallClock,
|
|
494
|
-
submitted: true
|
|
495
|
-
};
|
|
496
|
-
}
|
|
497
|
-
var handoffs = /* @__PURE__ */ new Map();
|
|
498
|
-
var attachmentHandoffs = /* @__PURE__ */ new Map();
|
|
499
|
-
var SHELL_DRAFT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
500
|
-
var focus = /* @__PURE__ */ new Map();
|
|
501
|
-
function shellDraftStorageKey(agentId) {
|
|
502
|
-
return `heroui-agent:shell-draft:${agentId}:composer-draft:v1`;
|
|
503
|
-
}
|
|
504
|
-
function saveShellDraft(agentId, prompt) {
|
|
505
|
-
try {
|
|
506
|
-
const key = shellDraftStorageKey(agentId);
|
|
507
|
-
if (prompt.trim()) localStorage.setItem(key, JSON.stringify({ prompt, savedAt: Date.now() }));
|
|
508
|
-
else localStorage.removeItem(key);
|
|
509
|
-
} catch {
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
function readShellDraft(agentId) {
|
|
513
|
-
const key = shellDraftStorageKey(agentId);
|
|
514
|
-
try {
|
|
515
|
-
const draft = JSON.parse(localStorage.getItem(key) ?? "null");
|
|
516
|
-
if (draft && typeof draft.prompt === "string" && draft.prompt.trim() && typeof draft.savedAt === "number" && Date.now() - draft.savedAt <= SHELL_DRAFT_MAX_AGE_MS) {
|
|
517
|
-
return draft.prompt;
|
|
518
|
-
}
|
|
519
|
-
localStorage.removeItem(key);
|
|
520
|
-
} catch {
|
|
521
|
-
}
|
|
522
|
-
return "";
|
|
523
|
-
}
|
|
524
|
-
function writeAgentShellHandoff(agentId, handoff) {
|
|
525
|
-
if (!handoff.prompt.trim() && !handoff.submitted) {
|
|
526
|
-
handoffs.delete(agentId);
|
|
527
|
-
saveShellDraft(agentId, "");
|
|
528
|
-
return;
|
|
529
|
-
}
|
|
530
|
-
handoffs.set(agentId, handoff);
|
|
531
|
-
if (!handoff.submitted) {
|
|
532
|
-
saveShellDraft(agentId, handoff.prompt);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
function readAgentShellHandoff(agentId) {
|
|
536
|
-
const buffered = handoffs.get(agentId);
|
|
537
|
-
if (buffered) return buffered;
|
|
538
|
-
const persisted = readShellDraft(agentId);
|
|
539
|
-
return persisted ? { prompt: persisted, submitted: false } : void 0;
|
|
540
|
-
}
|
|
541
|
-
function markAgentShellFeedbackPainted(agentId, messageId, paintedAt) {
|
|
542
|
-
const handoff = handoffs.get(agentId);
|
|
543
|
-
if (!handoff?.submitted || handoff.messageId !== messageId || handoff.firstFeedbackPaintedAt !== void 0) {
|
|
544
|
-
return;
|
|
545
|
-
}
|
|
546
|
-
handoffs.set(agentId, { ...handoff, firstFeedbackPaintedAt: paintedAt });
|
|
547
|
-
}
|
|
548
|
-
function takeAgentShellHandoff(agentId) {
|
|
549
|
-
const handoff = readAgentShellHandoff(agentId);
|
|
550
|
-
handoffs.delete(agentId);
|
|
551
|
-
saveShellDraft(agentId, "");
|
|
552
|
-
return handoff;
|
|
553
|
-
}
|
|
554
|
-
function setFocus(agentId, focused, textarea) {
|
|
555
|
-
if (focused) {
|
|
556
|
-
focus.set(agentId, [
|
|
557
|
-
textarea?.selectionStart ?? 0,
|
|
558
|
-
textarea?.selectionEnd ?? 0,
|
|
559
|
-
textarea?.selectionDirection ?? "none"
|
|
560
|
-
]);
|
|
561
|
-
} else {
|
|
562
|
-
focus.delete(agentId);
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
function restoreFocus(agentId, textarea) {
|
|
566
|
-
const selection = focus.get(agentId);
|
|
567
|
-
if (!selection || !textarea) return;
|
|
568
|
-
textarea.focus({ preventScroll: true });
|
|
569
|
-
const start = Math.min(selection[0], textarea.value.length);
|
|
570
|
-
const end = Math.min(selection[1], textarea.value.length);
|
|
571
|
-
textarea.setSelectionRange(start, end, selection[2]);
|
|
572
|
-
focus.set(agentId, [start, end, selection[2]]);
|
|
573
|
-
}
|
|
574
|
-
function containsComposerFocus(composer, target) {
|
|
575
|
-
if (!(target instanceof Node)) return false;
|
|
576
|
-
return composer.contains(target) || composer.closest(".ha-composer-wrap")?.querySelector(".ha-footnote")?.contains(target) === true || composer.closest(".ha-root")?.querySelector(".ha-overlay-portal")?.contains(target) === true;
|
|
577
|
-
}
|
|
578
|
-
function writeAgentShellAttachments(agentId, files) {
|
|
579
|
-
if (files.length === 0) attachmentHandoffs.delete(agentId);
|
|
580
|
-
else attachmentHandoffs.set(agentId, files);
|
|
581
|
-
}
|
|
582
|
-
function readAgentShellAttachments(agentId) {
|
|
583
|
-
return attachmentHandoffs.get(agentId) ?? [];
|
|
584
|
-
}
|
|
585
|
-
function takeAgentShellAttachments(agentId) {
|
|
586
|
-
const files = readAgentShellAttachments(agentId);
|
|
587
|
-
attachmentHandoffs.delete(agentId);
|
|
588
|
-
return files;
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
// src/embed/composer-textarea.ts
|
|
592
|
-
function getCssPixelValue(value) {
|
|
593
|
-
const parsed = Number.parseFloat(value);
|
|
594
|
-
return Number.isFinite(parsed) ? parsed : 0;
|
|
595
|
-
}
|
|
596
|
-
function getComposerLineHeight(element) {
|
|
597
|
-
const styles = getComputedStyle(element);
|
|
598
|
-
const lineHeight = Number.parseFloat(styles.lineHeight);
|
|
599
|
-
if (Number.isFinite(lineHeight) && lineHeight > 0) return lineHeight;
|
|
600
|
-
const fontSize = Number.parseFloat(styles.fontSize);
|
|
601
|
-
if (Number.isFinite(fontSize) && fontSize > 0) return fontSize * 1.2;
|
|
602
|
-
return 20;
|
|
603
|
-
}
|
|
604
|
-
function getComposerPaddingBlock(element) {
|
|
605
|
-
const styles = getComputedStyle(element);
|
|
606
|
-
return getCssPixelValue(styles.paddingTop) + getCssPixelValue(styles.paddingBottom);
|
|
607
|
-
}
|
|
608
|
-
function measureComposerScrollHeight(element) {
|
|
609
|
-
const previousHeight = element.style.height;
|
|
610
|
-
const previousMinHeight = element.style.minHeight;
|
|
611
|
-
const previousMaxHeight = element.style.maxHeight;
|
|
612
|
-
element.style.height = "0px";
|
|
613
|
-
element.style.minHeight = "0px";
|
|
614
|
-
element.style.maxHeight = "none";
|
|
615
|
-
const scrollHeight = element.scrollHeight;
|
|
616
|
-
element.style.height = previousHeight;
|
|
617
|
-
element.style.minHeight = previousMinHeight;
|
|
618
|
-
element.style.maxHeight = previousMaxHeight;
|
|
619
|
-
return scrollHeight;
|
|
620
|
-
}
|
|
621
|
-
function isComposerTextAreaExpanded(element) {
|
|
622
|
-
if (element.value.includes("\n")) return true;
|
|
623
|
-
if (element.clientWidth === 0) return false;
|
|
624
|
-
const scrollHeight = measureComposerScrollHeight(element);
|
|
625
|
-
const paddingBlock = getComposerPaddingBlock(element);
|
|
626
|
-
const lineHeight = getComposerLineHeight(element);
|
|
627
|
-
const contentHeight = Math.max(0, scrollHeight - paddingBlock);
|
|
628
|
-
return contentHeight > lineHeight * 1.5;
|
|
629
|
-
}
|
|
630
|
-
function resizeComposerTextarea(textarea, {
|
|
631
|
-
hasAttachments = false,
|
|
632
|
-
maxHeight = 120
|
|
633
|
-
} = {}) {
|
|
634
|
-
if (!textarea) return false;
|
|
635
|
-
const hasValue = textarea.value.length > 0;
|
|
636
|
-
const shouldExpand = hasAttachments || hasValue && isComposerTextAreaExpanded(textarea);
|
|
637
|
-
if (!shouldExpand) {
|
|
638
|
-
textarea.style.height = "auto";
|
|
639
|
-
return false;
|
|
640
|
-
}
|
|
641
|
-
textarea.style.height = "auto";
|
|
642
|
-
textarea.style.height = `${Math.min(textarea.scrollHeight, maxHeight)}px`;
|
|
643
|
-
return true;
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
// src/embed/powered-by-hero.tsx
|
|
647
|
-
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
648
|
-
var POWERED_BY_HERO_URL = "https://heroui.pro/?utm_source=heroui-agent&utm_medium=referral&utm_campaign=powered-by-hero";
|
|
649
|
-
function PoweredByHero() {
|
|
650
|
-
return /* @__PURE__ */ jsxs4(
|
|
651
|
-
"a",
|
|
652
|
-
{
|
|
653
|
-
"aria-label": "Powered by HeroUI Pro (opens in a new tab)",
|
|
654
|
-
className: "ha-powered-by",
|
|
655
|
-
href: POWERED_BY_HERO_URL,
|
|
656
|
-
rel: "noopener noreferrer",
|
|
657
|
-
target: "_blank",
|
|
658
|
-
children: [
|
|
659
|
-
/* @__PURE__ */ jsx4("span", { children: "Powered by" }),
|
|
660
|
-
/* @__PURE__ */ jsxs4("svg", { "aria-hidden": "true", className: "ha-powered-by-logo", fill: "none", viewBox: "0 0 140 44", children: [
|
|
661
|
-
/* @__PURE__ */ jsx4(
|
|
662
|
-
"path",
|
|
663
|
-
{
|
|
664
|
-
d: "M.678 11.385V24.04c0 .599.307 1.155.813 1.471l8.628 5.396c1.15.719 2.639-.11 2.639-1.47V18.798c0-.612.322-1.18.847-1.491l5.263-3.13v27.267c0 1.355 1.48 2.186 2.63 1.476l8.905-5.497a1.72 1.72 0 0 0 .822-1.476V9.765c0-1.349-1.467-2.18-2.618-1.484l-9.74 5.897V2.556c0-1.345-1.46-2.177-2.61-1.488L1.52 9.897a1.72 1.72 0 0 0-.842 1.488Z",
|
|
665
|
-
fill: "currentColor"
|
|
666
|
-
}
|
|
667
|
-
),
|
|
668
|
-
/* @__PURE__ */ jsx4(
|
|
669
|
-
"path",
|
|
670
|
-
{
|
|
671
|
-
d: "M63.876 24.071c0-3.59-1.468-5.246-4.405-5.246-3.363 0-5.732 2.255-5.732 7.316v11.595h-6.063V5.528h6.063v11.779c1.468-2.393 3.884-3.59 7.2-3.59 5.637 0 8.953 3.451 8.953 9.25v14.769h-6.016V24.071ZM84.9 38.473c-7.533 0-12.317-4.877-12.317-12.378 0-7.408 4.737-12.378 12.317-12.378 8.195 0 12.648 5.798 11.416 13.942H78.647c.331 3.865 2.605 6.075 6.253 6.075 2.984 0 4.784-1.52 5.258-3.037h6.016c-.947 4.509-5.115 7.776-11.274 7.776ZM78.789 23.657h11.653c-.047-3.175-2.132-5.338-5.685-5.338-3.174 0-5.4 1.84-5.968 5.338ZM99.623 20.344c0-3.82 2.131-5.89 6.205-5.89h7.77v4.97h-7.912v18.312h-6.063V20.344ZM126.863 38.473c-7.674 0-12.553-4.924-12.553-12.378 0-7.454 4.879-12.378 12.553-12.378 7.58 0 12.459 4.924 12.459 12.378 0 7.454-4.88 12.378-12.46 12.378Zm0-5.016c3.79 0 6.3-2.898 6.3-7.362 0-4.463-2.51-7.408-6.3-7.408-3.838 0-6.348 2.945-6.348 7.408 0 4.464 2.51 7.362 6.348 7.362Z",
|
|
672
|
-
fill: "currentColor"
|
|
673
|
-
}
|
|
674
|
-
)
|
|
675
|
-
] })
|
|
676
|
-
]
|
|
677
|
-
}
|
|
678
|
-
);
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
// src/embed/permissions.ts
|
|
682
|
-
var AGENT_PERMISSION_MODES = /* @__PURE__ */ new Set(["ask", "auto", "full"]);
|
|
683
|
-
function resolveAgentPermissionMode(value) {
|
|
684
|
-
return AGENT_PERMISSION_MODES.has(value) ? value : "auto";
|
|
685
|
-
}
|
|
686
|
-
function agentPermissionModeStorageKey(conversationStorageKey, conversationId) {
|
|
687
|
-
return `${conversationStorageKey}:permission-mode:${conversationId}:v1`;
|
|
688
|
-
}
|
|
689
|
-
function agentActivePermissionModeStorageKey(conversationStorageKey, conversationId) {
|
|
690
|
-
return `${conversationStorageKey}:active-permission-mode:${conversationId}:v1`;
|
|
691
|
-
}
|
|
692
|
-
function readStoredAgentPermissionMode(key) {
|
|
693
|
-
try {
|
|
694
|
-
const stored = localStorage.getItem(key);
|
|
695
|
-
return stored !== null && AGENT_PERMISSION_MODES.has(stored) ? resolveAgentPermissionMode(stored) : void 0;
|
|
696
|
-
} catch {
|
|
697
|
-
return void 0;
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
function storeAgentPermissionMode(key, mode) {
|
|
701
|
-
try {
|
|
702
|
-
localStorage.setItem(key, mode);
|
|
703
|
-
} catch {
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
function clearStoredAgentPermissionMode(key) {
|
|
707
|
-
try {
|
|
708
|
-
localStorage.removeItem(key);
|
|
709
|
-
} catch {
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
function applyAgentPermissionMode(tools, mode) {
|
|
713
|
-
const resolvedMode = resolveAgentPermissionMode(mode);
|
|
714
|
-
if (resolvedMode === "auto") return tools;
|
|
715
|
-
const needsApproval = resolvedMode === "ask";
|
|
716
|
-
return tools.map(
|
|
717
|
-
(tool) => Boolean(tool.needsApproval) === needsApproval ? tool : { ...tool, needsApproval }
|
|
718
|
-
);
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
// src/embed/theme.ts
|
|
722
|
-
var AGENT_DESIGN_THEMES = [
|
|
723
|
-
"base",
|
|
724
|
-
"brutalism",
|
|
725
|
-
"glass",
|
|
726
|
-
"mouve"
|
|
727
|
-
];
|
|
728
|
-
function resolveAgentDesignTheme(value) {
|
|
729
|
-
return AGENT_DESIGN_THEMES.includes(value) ? value : "base";
|
|
730
|
-
}
|
|
731
|
-
var COLOR_VARIABLES = {
|
|
732
|
-
accent: "accent",
|
|
733
|
-
background: "background",
|
|
734
|
-
foreground: "foreground",
|
|
735
|
-
overlay: "overlay",
|
|
736
|
-
surface: "surface",
|
|
737
|
-
surfaceSecondary: "surface-secondary",
|
|
738
|
-
tooltip: "tooltip"
|
|
739
|
-
};
|
|
740
|
-
var ACCENT_FOREGROUND_CSS = "oklch(from var(--ha-accent) clamp(0, (0.7 - l) * 1000, 1) 0 h)";
|
|
741
|
-
var LAUNCHER_FOREGROUND_CSS = "oklch(from var(--ha-launcher-bg) clamp(0, (0.7 - l) * 1000, 1) 0 h)";
|
|
742
|
-
function buildLauncherStyle(background) {
|
|
743
|
-
const style = {};
|
|
744
|
-
const light = schemeValue(background, "light");
|
|
745
|
-
const dark = schemeValue(background, "dark");
|
|
746
|
-
if (light) {
|
|
747
|
-
style["--ha-theme-launcher-background-light"] = light;
|
|
748
|
-
style["--ha-theme-launcher-foreground-light"] = LAUNCHER_FOREGROUND_CSS;
|
|
749
|
-
}
|
|
750
|
-
if (dark) {
|
|
751
|
-
style["--ha-theme-launcher-background-dark"] = dark;
|
|
752
|
-
style["--ha-theme-launcher-foreground-dark"] = LAUNCHER_FOREGROUND_CSS;
|
|
753
|
-
}
|
|
754
|
-
return style;
|
|
755
|
-
}
|
|
756
|
-
var SURFACE_TERTIARY_LIGHT_CSS = "oklch(from var(--ha-card-secondary) calc(l - 0.0151) c h)";
|
|
757
|
-
var SURFACE_TERTIARY_DARK_CSS = "oklch(from var(--ha-card-secondary) calc(l + 0.017) c h)";
|
|
758
|
-
var RADIUS_VALUES = {
|
|
759
|
-
pill: "0.875rem",
|
|
760
|
-
round: "0.5rem",
|
|
761
|
-
sharp: "0.125rem",
|
|
762
|
-
soft: "0.375rem"
|
|
763
|
-
};
|
|
764
|
-
var MIN_FONT_SIZE = 12;
|
|
765
|
-
var MAX_FONT_SIZE = 18;
|
|
766
|
-
function safeCssValue(value) {
|
|
767
|
-
const trimmed = value?.trim();
|
|
768
|
-
if (!trimmed || trimmed.length > 256 || /[;{}]/.test(trimmed)) return void 0;
|
|
769
|
-
return trimmed;
|
|
770
|
-
}
|
|
771
|
-
function schemeValue(color, scheme) {
|
|
772
|
-
if (color === void 0) return void 0;
|
|
773
|
-
return safeCssValue(typeof color === "string" ? color : color[scheme]);
|
|
774
|
-
}
|
|
775
|
-
function buildThemeStyle(theme) {
|
|
776
|
-
if (!theme) return {};
|
|
777
|
-
const style = {};
|
|
778
|
-
if (theme.radius && theme.radius in RADIUS_VALUES) {
|
|
779
|
-
style["--radius"] = RADIUS_VALUES[theme.radius];
|
|
780
|
-
}
|
|
781
|
-
const fontFamily = safeCssValue(theme.typography?.fontFamily);
|
|
782
|
-
if (fontFamily) style["--ha-font-family"] = fontFamily;
|
|
783
|
-
const baseSize = theme.typography?.baseSize;
|
|
784
|
-
if (typeof baseSize === "number" && Number.isFinite(baseSize)) {
|
|
785
|
-
const size = Math.min(Math.max(Math.round(baseSize), MIN_FONT_SIZE), MAX_FONT_SIZE);
|
|
786
|
-
style["--ha-font-size"] = `${size}px`;
|
|
787
|
-
}
|
|
788
|
-
for (const [token, variableName] of Object.entries(COLOR_VARIABLES)) {
|
|
789
|
-
const color = theme.colors?.[token];
|
|
790
|
-
const light = schemeValue(color, "light");
|
|
791
|
-
const darkValue = schemeValue(color, "dark");
|
|
792
|
-
if (light) style[`--ha-theme-${variableName}-light`] = light;
|
|
793
|
-
if (darkValue) style[`--ha-theme-${variableName}-dark`] = darkValue;
|
|
794
|
-
}
|
|
795
|
-
if (schemeValue(theme.colors?.accent, "light")) {
|
|
796
|
-
style["--ha-theme-accent-foreground-light"] = ACCENT_FOREGROUND_CSS;
|
|
797
|
-
}
|
|
798
|
-
if (schemeValue(theme.colors?.accent, "dark")) {
|
|
799
|
-
style["--ha-theme-accent-foreground-dark"] = ACCENT_FOREGROUND_CSS;
|
|
800
|
-
}
|
|
801
|
-
if (schemeValue(theme.colors?.surfaceSecondary, "light")) {
|
|
802
|
-
style["--ha-theme-surface-tertiary-light"] = SURFACE_TERTIARY_LIGHT_CSS;
|
|
803
|
-
}
|
|
804
|
-
if (schemeValue(theme.colors?.surfaceSecondary, "dark")) {
|
|
805
|
-
style["--ha-theme-surface-tertiary-dark"] = SURFACE_TERTIARY_DARK_CSS;
|
|
806
|
-
}
|
|
807
|
-
return style;
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
// src/contracts/runtime.ts
|
|
811
|
-
var HEROUI_AGENT_RUNTIME_TIMING_EVENT = "heroui-agent:runtime-timing";
|
|
812
|
-
var HEROUI_AGENT_TURN_ADMITTED_FRAME_TYPE = "heroui_agent_turn_admitted";
|
|
813
|
-
var HEROUI_AGENT_TURN_ADMISSION_STATUS_METHOD = "getTurnAdmissionStatuses";
|
|
814
|
-
var HEROUI_AGENT_TURN_ADMISSION_STATUS_MAX_IDS = 50;
|
|
815
|
-
|
|
816
|
-
// ../agent-client/src/token-manager.ts
|
|
817
|
-
function anonymousStorageKey(agentId) {
|
|
818
|
-
return `heroui-agent:anonymous:${agentId}`;
|
|
819
|
-
}
|
|
820
|
-
var EmbedSessionManager = class {
|
|
821
|
-
constructor(agentId, getAuthToken) {
|
|
822
|
-
this.agentId = agentId;
|
|
823
|
-
this.getAuthToken = getAuthToken;
|
|
824
|
-
}
|
|
825
|
-
cached = null;
|
|
826
|
-
generation = 0;
|
|
827
|
-
pending = null;
|
|
828
|
-
clear() {
|
|
829
|
-
this.generation += 1;
|
|
830
|
-
this.cached = null;
|
|
831
|
-
this.pending = null;
|
|
832
|
-
}
|
|
833
|
-
/**
|
|
834
|
-
* Forgets both the cached credential and the browser's anonymous id, so the
|
|
835
|
-
* next request represents a brand-new person. Used on logout to stop a
|
|
836
|
-
* shared device from attributing the next visitor to the previous user.
|
|
837
|
-
*/
|
|
838
|
-
reset() {
|
|
839
|
-
this.clear();
|
|
840
|
-
try {
|
|
841
|
-
localStorage.removeItem(anonymousStorageKey(this.agentId));
|
|
842
|
-
} catch {
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
async get() {
|
|
846
|
-
if (this.cached && this.expiresAt(this.cached) > Date.now() + 6e4) {
|
|
847
|
-
return this.cached.token;
|
|
848
|
-
}
|
|
849
|
-
const generation = this.generation;
|
|
850
|
-
const pending = this.pending ?? this.refresh();
|
|
851
|
-
if (!this.pending) this.pending = pending;
|
|
852
|
-
try {
|
|
853
|
-
const result = await pending;
|
|
854
|
-
if (generation !== this.generation) return this.get();
|
|
855
|
-
this.cached = result;
|
|
856
|
-
return result.token;
|
|
857
|
-
} finally {
|
|
858
|
-
if (this.pending === pending) this.pending = null;
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
async subjectHash() {
|
|
862
|
-
const token = await this.get();
|
|
863
|
-
const payload = decodeTokenPayload(token);
|
|
864
|
-
const subject = typeof payload["sub"] === "string" ? payload["sub"] : "anonymous";
|
|
865
|
-
const digest = await crypto.subtle.digest(
|
|
866
|
-
"SHA-256",
|
|
867
|
-
new TextEncoder().encode(`${this.agentId}:${subject}`)
|
|
868
|
-
);
|
|
869
|
-
return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, 24);
|
|
870
|
-
}
|
|
871
|
-
anonymousId() {
|
|
872
|
-
const key = anonymousStorageKey(this.agentId);
|
|
873
|
-
try {
|
|
874
|
-
const existing = localStorage.getItem(key);
|
|
875
|
-
if (existing) return existing;
|
|
876
|
-
const created = crypto.randomUUID();
|
|
877
|
-
localStorage.setItem(key, created);
|
|
878
|
-
return created;
|
|
879
|
-
} catch {
|
|
880
|
-
return crypto.randomUUID();
|
|
881
|
-
}
|
|
882
|
-
}
|
|
883
|
-
expiresAt(response) {
|
|
884
|
-
return response.expiresAt;
|
|
885
|
-
}
|
|
886
|
-
async refresh() {
|
|
887
|
-
const result = await this.getAuthToken({
|
|
888
|
-
agentId: this.agentId,
|
|
889
|
-
anonymousId: this.anonymousId()
|
|
890
|
-
});
|
|
891
|
-
if (!result || typeof result.token !== "string" || !result.token.trim() || typeof result.expiresAt !== "number" || !Number.isFinite(result.expiresAt) || result.expiresAt <= 0) {
|
|
892
|
-
throw new Error("Auth token callback returned invalid data");
|
|
893
|
-
}
|
|
894
|
-
return { expiresAt: result.expiresAt, token: result.token };
|
|
895
|
-
}
|
|
896
|
-
};
|
|
897
|
-
function decodeTokenPayload(token) {
|
|
898
|
-
try {
|
|
899
|
-
const payload = token.split(".")[1];
|
|
900
|
-
if (!payload) return {};
|
|
901
|
-
const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
902
|
-
const padded = normalized.padEnd(Math.ceil(normalized.length / 4) * 4, "=");
|
|
903
|
-
return JSON.parse(atob(padded));
|
|
904
|
-
} catch {
|
|
905
|
-
return {};
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
|
|
909
|
-
// src/contracts/attachments.ts
|
|
910
|
-
var HEROUI_AGENT_MAX_ATTACHMENTS = 5;
|
|
911
|
-
var HEROUI_AGENT_ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024;
|
|
912
|
-
var HEROUI_AGENT_ATTACHMENT_EXTENSION_BY_CONTENT_TYPE = {
|
|
913
|
-
"application/json": "json",
|
|
914
|
-
"application/pdf": "pdf",
|
|
915
|
-
"image/gif": "gif",
|
|
916
|
-
"image/jpeg": "jpg",
|
|
917
|
-
"image/png": "png",
|
|
918
|
-
"image/webp": "webp",
|
|
919
|
-
"text/csv": "csv",
|
|
920
|
-
"text/markdown": "md",
|
|
921
|
-
"text/plain": "txt",
|
|
922
|
-
"text/tab-separated-values": "tsv"
|
|
923
|
-
};
|
|
924
|
-
var HEROUI_AGENT_ATTACHMENT_CONTENT_TYPES = Object.freeze(
|
|
925
|
-
Object.keys(
|
|
926
|
-
HEROUI_AGENT_ATTACHMENT_EXTENSION_BY_CONTENT_TYPE
|
|
927
|
-
)
|
|
928
|
-
);
|
|
929
|
-
var HEROUI_AGENT_ATTACHMENT_ACCEPT = HEROUI_AGENT_ATTACHMENT_CONTENT_TYPES.join(",");
|
|
930
|
-
var HEROUI_AGENT_ATTACHMENT_CONTENT_TYPE_SET = new Set(
|
|
931
|
-
HEROUI_AGENT_ATTACHMENT_CONTENT_TYPES
|
|
932
|
-
);
|
|
933
|
-
function isHeroUIAgentAttachmentContentType(value) {
|
|
934
|
-
return HEROUI_AGENT_ATTACHMENT_CONTENT_TYPE_SET.has(value.trim().toLowerCase());
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
// src/embed/shell-conversation.tsx
|
|
938
|
-
import { useEffect as useEffect2, useLayoutEffect, useRef as useRef2, useState as useState2 } from "react";
|
|
939
|
-
import { Fragment, jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
940
|
-
function ShellConversation({
|
|
941
|
-
agentId,
|
|
942
|
-
composerConnecting = false,
|
|
943
|
-
composerControlsAvailable,
|
|
944
|
-
composerControlsRevealed,
|
|
945
|
-
composerEndSlot,
|
|
946
|
-
composerFooterSlot,
|
|
947
|
-
composerStartSlot,
|
|
948
|
-
greeting,
|
|
949
|
-
onComposerControlsReveal,
|
|
950
|
-
onIntent,
|
|
951
|
-
placeholder,
|
|
952
|
-
suggestedPrompts
|
|
953
|
-
}) {
|
|
954
|
-
const [initialHandoff] = useState2(() => readAgentShellHandoff(agentId));
|
|
955
|
-
const [input, setInput] = useState2(() => initialHandoff?.prompt ?? "");
|
|
956
|
-
const [submission, setSubmission] = useState2(
|
|
957
|
-
() => initialHandoff?.submitted ? initialHandoff : null
|
|
958
|
-
);
|
|
959
|
-
const [locallyRevealedControls, setLocallyRevealedControls] = useState2(false);
|
|
960
|
-
const textareaRef = useRef2(null);
|
|
961
|
-
const controlsAvailable = composerControlsAvailable ?? Boolean(composerStartSlot || composerEndSlot);
|
|
962
|
-
const controlsRevealed = composerControlsRevealed ?? (controlsAvailable && locallyRevealedControls);
|
|
963
|
-
const revealComposerControls = (event) => {
|
|
964
|
-
setFocus(agentId, true, event.currentTarget);
|
|
965
|
-
setLocallyRevealedControls(controlsAvailable);
|
|
966
|
-
if (controlsAvailable) onComposerControlsReveal?.();
|
|
967
|
-
onIntent();
|
|
968
|
-
};
|
|
969
|
-
const handleComposerBlur = (event) => {
|
|
970
|
-
const composer = event.currentTarget.querySelector(".ha-composer");
|
|
971
|
-
if (composer && containsComposerFocus(composer, event.relatedTarget)) return;
|
|
972
|
-
setLocallyRevealedControls(false);
|
|
973
|
-
setFocus(agentId, false);
|
|
974
|
-
};
|
|
975
|
-
useLayoutEffect(() => {
|
|
976
|
-
restoreFocus(agentId, textareaRef.current);
|
|
977
|
-
resizeComposerTextarea(textareaRef.current);
|
|
978
|
-
}, [agentId]);
|
|
979
|
-
useEffect2(() => {
|
|
980
|
-
if (submission) return;
|
|
981
|
-
writeAgentShellHandoff(agentId, { prompt: input, submitted: false });
|
|
982
|
-
}, [input, agentId, submission]);
|
|
983
|
-
useLayoutEffect(() => {
|
|
984
|
-
if (!submission) return;
|
|
985
|
-
const frame = requestAnimationFrame((paintedAt) => {
|
|
986
|
-
markAgentShellFeedbackPainted(agentId, submission.messageId, paintedAt);
|
|
987
|
-
});
|
|
988
|
-
return () => cancelAnimationFrame(frame);
|
|
989
|
-
}, [agentId, submission]);
|
|
990
|
-
const submit = (prompt) => {
|
|
991
|
-
if (submission) return;
|
|
992
|
-
const nextSubmission = createSubmittedAgentShellHandoff(prompt);
|
|
993
|
-
if (!nextSubmission) return;
|
|
994
|
-
setSubmission(nextSubmission);
|
|
995
|
-
setInput("");
|
|
996
|
-
textareaRef.current.style.height = "auto";
|
|
997
|
-
writeAgentShellHandoff(agentId, nextSubmission);
|
|
998
|
-
onIntent();
|
|
999
|
-
};
|
|
1000
|
-
return /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1001
|
-
/* @__PURE__ */ jsx5("div", { className: "ha-conversation", children: /* @__PURE__ */ jsx5("div", { "aria-live": "polite", className: "ha-messages", role: "log", children: submission ? /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
1002
|
-
/* @__PURE__ */ jsx5("div", { className: "ha-message", "data-role": "user", children: /* @__PURE__ */ jsx5("div", { className: "ha-message-body", children: submission.prompt }) }),
|
|
1003
|
-
/* @__PURE__ */ jsx5(
|
|
1004
|
-
"div",
|
|
1005
|
-
{
|
|
1006
|
-
className: "ha-message",
|
|
1007
|
-
"data-role": "assistant",
|
|
1008
|
-
"data-stream-anchor": "true",
|
|
1009
|
-
"data-turn-feedback-id": submission.messageId,
|
|
1010
|
-
children: /* @__PURE__ */ jsx5("div", { className: "ha-message-body", children: /* @__PURE__ */ jsx5(
|
|
1011
|
-
"div",
|
|
1012
|
-
{
|
|
1013
|
-
"aria-label": "Working on your request\u2026",
|
|
1014
|
-
className: "ha-progress ha-activity-status ha-progress-shimmer",
|
|
1015
|
-
role: "status",
|
|
1016
|
-
children: /* @__PURE__ */ jsx5("span", { "aria-hidden": "true", className: "ha-shimmer", children: "Thinking\u2026" })
|
|
1017
|
-
}
|
|
1018
|
-
) })
|
|
1019
|
-
}
|
|
1020
|
-
)
|
|
1021
|
-
] }) : /* @__PURE__ */ jsxs5("div", { className: "ha-empty", children: [
|
|
1022
|
-
/* @__PURE__ */ jsx5("h2", { children: greeting }),
|
|
1023
|
-
/* @__PURE__ */ jsx5("p", { children: "Live answers with charts, metrics, and tables." })
|
|
1024
|
-
] }) }) }),
|
|
1025
|
-
/* @__PURE__ */ jsxs5(
|
|
1026
|
-
"form",
|
|
1027
|
-
{
|
|
1028
|
-
className: "ha-composer-wrap",
|
|
1029
|
-
onBlur: handleComposerBlur,
|
|
1030
|
-
onSubmit: (event) => {
|
|
1031
|
-
event.preventDefault();
|
|
1032
|
-
submit(input);
|
|
1033
|
-
},
|
|
1034
|
-
children: [
|
|
1035
|
-
!submission && suggestedPrompts.length > 0 ? /* @__PURE__ */ jsx5("div", { "aria-label": "Suggested prompts", className: "ha-suggestions", role: "group", children: suggestedPrompts.map((prompt) => /* @__PURE__ */ jsxs5(
|
|
1036
|
-
"button",
|
|
1037
|
-
{
|
|
1038
|
-
className: "ha-suggestion",
|
|
1039
|
-
type: "button",
|
|
1040
|
-
onClick: () => submit(prompt),
|
|
1041
|
-
children: [
|
|
1042
|
-
/* @__PURE__ */ jsx5("span", { children: prompt }),
|
|
1043
|
-
/* @__PURE__ */ jsx5(ArrowUpRightGlyph, {})
|
|
1044
|
-
]
|
|
1045
|
-
},
|
|
1046
|
-
prompt
|
|
1047
|
-
)) }) : null,
|
|
1048
|
-
/* @__PURE__ */ jsxs5(
|
|
1049
|
-
"div",
|
|
1050
|
-
{
|
|
1051
|
-
className: "@container ha-composer",
|
|
1052
|
-
"data-connecting": composerConnecting || void 0,
|
|
1053
|
-
"data-controls-revealed": controlsRevealed || void 0,
|
|
1054
|
-
children: [
|
|
1055
|
-
composerStartSlot,
|
|
1056
|
-
/* @__PURE__ */ jsx5(
|
|
1057
|
-
"textarea",
|
|
1058
|
-
{
|
|
1059
|
-
ref: textareaRef,
|
|
1060
|
-
"aria-label": "Message the assistant",
|
|
1061
|
-
placeholder,
|
|
1062
|
-
readOnly: Boolean(submission),
|
|
1063
|
-
rows: 1,
|
|
1064
|
-
value: input,
|
|
1065
|
-
onFocus: revealComposerControls,
|
|
1066
|
-
onSelect: (event) => setFocus(agentId, true, event.currentTarget),
|
|
1067
|
-
onChange: (event) => {
|
|
1068
|
-
const nextInput = event.currentTarget.value;
|
|
1069
|
-
writeAgentShellHandoff(agentId, { prompt: nextInput, submitted: false });
|
|
1070
|
-
setFocus(agentId, true, event.currentTarget);
|
|
1071
|
-
setInput(nextInput);
|
|
1072
|
-
resizeComposerTextarea(event.currentTarget);
|
|
1073
|
-
onIntent();
|
|
1074
|
-
},
|
|
1075
|
-
onKeyDown: (event) => {
|
|
1076
|
-
if (event.key !== "Enter" || event.shiftKey) return;
|
|
1077
|
-
event.preventDefault();
|
|
1078
|
-
submit(input);
|
|
1079
|
-
}
|
|
1080
|
-
}
|
|
1081
|
-
),
|
|
1082
|
-
composerEndSlot,
|
|
1083
|
-
/* @__PURE__ */ jsxs5(
|
|
1084
|
-
"button",
|
|
1085
|
-
{
|
|
1086
|
-
"aria-label": "Send message",
|
|
1087
|
-
className: "ha-send",
|
|
1088
|
-
disabled: !input.trim() || Boolean(submission),
|
|
1089
|
-
type: "submit",
|
|
1090
|
-
children: [
|
|
1091
|
-
/* @__PURE__ */ jsx5(ArrowUpGlyph, {}),
|
|
1092
|
-
/* @__PURE__ */ jsx5(ComposerControlTooltip, { shortcut: "\u21B5", children: "Send message" })
|
|
1093
|
-
]
|
|
1094
|
-
}
|
|
1095
|
-
)
|
|
1096
|
-
]
|
|
1097
|
-
}
|
|
1098
|
-
),
|
|
1099
|
-
/* @__PURE__ */ jsx5(
|
|
1100
|
-
"div",
|
|
1101
|
-
{
|
|
1102
|
-
className: "ha-composer-footer",
|
|
1103
|
-
"data-revealed": Boolean(composerFooterSlot) || void 0,
|
|
1104
|
-
children: /* @__PURE__ */ jsx5("div", { className: "ha-composer-footer-content", children: composerFooterSlot })
|
|
1105
|
-
}
|
|
1106
|
-
),
|
|
1107
|
-
/* @__PURE__ */ jsx5(PoweredByHero, {})
|
|
1108
|
-
]
|
|
1109
|
-
}
|
|
1110
|
-
)
|
|
1111
|
-
] });
|
|
1112
|
-
}
|
|
1113
|
-
function ArrowUpGlyph() {
|
|
1114
|
-
return /* @__PURE__ */ jsx5("svg", { "aria-hidden": "true", fill: "none", height: "18", viewBox: "0 0 18 18", width: "18", children: /* @__PURE__ */ jsx5(
|
|
1115
|
-
"path",
|
|
1116
|
-
{
|
|
1117
|
-
d: "M9 14.5V3.5m0 0L4.5 8M9 3.5 13.5 8",
|
|
1118
|
-
stroke: "currentColor",
|
|
1119
|
-
strokeLinecap: "round",
|
|
1120
|
-
strokeLinejoin: "round",
|
|
1121
|
-
strokeWidth: "1.6"
|
|
1122
|
-
}
|
|
1123
|
-
) });
|
|
1124
|
-
}
|
|
1125
|
-
function ArrowUpRightGlyph() {
|
|
1126
|
-
return /* @__PURE__ */ jsx5("svg", { "aria-hidden": "true", fill: "none", height: "16", viewBox: "0 0 16 16", width: "16", children: /* @__PURE__ */ jsx5(
|
|
1127
|
-
"path",
|
|
1128
|
-
{
|
|
1129
|
-
d: "M5 11 11 5m0 0H6m5 0v5",
|
|
1130
|
-
stroke: "currentColor",
|
|
1131
|
-
strokeLinecap: "round",
|
|
1132
|
-
strokeLinejoin: "round",
|
|
1133
|
-
strokeWidth: "1.5"
|
|
1134
|
-
}
|
|
1135
|
-
) });
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
// src/embed/types.ts
|
|
1139
|
-
var DEFAULT_MARKDOWN_ANIMATION = {
|
|
1140
|
-
animation: "fadeIn",
|
|
1141
|
-
duration: 160,
|
|
1142
|
-
easing: "ease-out",
|
|
1143
|
-
sep: "word",
|
|
1144
|
-
stagger: 18
|
|
1145
|
-
};
|
|
1146
|
-
function panelLength(value) {
|
|
1147
|
-
if (typeof value === "number")
|
|
1148
|
-
return Number.isFinite(value) ? `${Math.round(value)}px` : void 0;
|
|
1149
|
-
return value?.trim() || void 0;
|
|
1150
|
-
}
|
|
1151
|
-
function buildPanelStyle(panel) {
|
|
1152
|
-
const width = panelLength(panel?.initialWidth);
|
|
1153
|
-
const height = panelLength(panel?.initialHeight);
|
|
1154
|
-
return {
|
|
1155
|
-
...width ? { "--ha-panel-width": width } : {},
|
|
1156
|
-
...height ? { "--ha-panel-height": height } : {}
|
|
1157
|
-
};
|
|
1158
|
-
}
|
|
1159
|
-
function clampLauncherOffset(value) {
|
|
1160
|
-
if (value === void 0 || !Number.isFinite(value)) return 24;
|
|
1161
|
-
return Math.min(Math.max(Math.round(value), 0), 200);
|
|
1162
|
-
}
|
|
1163
|
-
function resolveComposerAttachmentContentTypes(value) {
|
|
1164
|
-
if (value === void 0) return [...HEROUI_AGENT_ATTACHMENT_CONTENT_TYPES];
|
|
1165
|
-
if (value === false || !Array.isArray(value)) return [];
|
|
1166
|
-
const contentTypes = /* @__PURE__ */ new Set();
|
|
1167
|
-
for (const item of value) {
|
|
1168
|
-
if (typeof item !== "string") continue;
|
|
1169
|
-
const contentType = item.trim().toLowerCase();
|
|
1170
|
-
if (isHeroUIAgentAttachmentContentType(contentType)) contentTypes.add(contentType);
|
|
1171
|
-
}
|
|
1172
|
-
return [...contentTypes];
|
|
1173
|
-
}
|
|
1174
|
-
function resolveOptions(props) {
|
|
1175
|
-
if (!props.agentId.trim()) throw new Error("HeroUI Agent agentId is required");
|
|
1176
|
-
if (typeof props.getAuthToken !== "function") {
|
|
1177
|
-
throw new Error("HeroUI Agent getAuthToken is required");
|
|
1178
|
-
}
|
|
1179
|
-
const composerAttachmentContentTypes = resolveComposerAttachmentContentTypes(
|
|
1180
|
-
props.composer?.attachments
|
|
1181
|
-
);
|
|
1182
|
-
const composerDisclaimer = typeof props.composer?.disclaimer === "string" ? props.composer.disclaimer.trim().slice(0, 240) || void 0 : void 0;
|
|
1183
|
-
return {
|
|
1184
|
-
apiBaseUrl: (props._api?.baseUrl ?? "https://api.heroui.com").replace(/\/$/, ""),
|
|
1185
|
-
colorScheme: props.appearance?.theme?.colorScheme ?? "system",
|
|
1186
|
-
componentExportFormats: props.componentExports === false ? [] : props.componentExports ?? ["csv", "svg", "png"],
|
|
1187
|
-
composerAttachmentAccept: composerAttachmentContentTypes.join(","),
|
|
1188
|
-
composerAttachmentContentTypes,
|
|
1189
|
-
composerControlsAvailable: composerAttachmentContentTypes.length > 0 || props.permissions?.showPicker === true && !!props.tools?.length || props.composer?.modelPicker === true || (props.composer?.dictation ?? true),
|
|
1190
|
-
composerDefaultModel: props.composer?.defaultModel,
|
|
1191
|
-
composerDictation: props.composer?.dictation ?? true,
|
|
1192
|
-
designTheme: resolveAgentDesignTheme(props.appearance?.theme?.designTheme),
|
|
1193
|
-
...composerDisclaimer ? { composerDisclaimer } : {},
|
|
1194
|
-
agentId: props.agentId,
|
|
1195
|
-
composerModelPicker: props.composer?.modelPicker ?? false,
|
|
1196
|
-
composerPlaceholder: props.composer?.placeholder?.trim().slice(0, 120) || "Ask anything\u2026",
|
|
1197
|
-
context: props.context,
|
|
1198
|
-
getAuthToken: props.getAuthToken,
|
|
1199
|
-
greeting: props.startScreen?.greeting?.trim().slice(0, 120) || "Ask about your data",
|
|
1200
|
-
launcherPosition: props.appearance?.launcher?.position ?? "bottom-right",
|
|
1201
|
-
markdownAnimation: props.markdown?.animated ?? DEFAULT_MARKDOWN_ANIMATION,
|
|
1202
|
-
markdownCaret: props.markdown?.caret ?? "block",
|
|
1203
|
-
markdownPlugins: props.markdown?.plugins,
|
|
1204
|
-
messageActions: props.responseActions === false ? [] : props.responseActions ?? ["copy", "feedback", "retry"],
|
|
1205
|
-
onFeedback: props.onFeedback,
|
|
1206
|
-
panelExpandable: props.appearance?.panel?.expandable ?? true,
|
|
1207
|
-
panelExpanded: props.appearance?.panel?.expanded ?? false,
|
|
1208
|
-
panelStyle: buildPanelStyle(props.appearance?.panel),
|
|
1209
|
-
permissionDefaultMode: resolveAgentPermissionMode(props.permissions?.defaultMode),
|
|
1210
|
-
permissionShowPicker: props.permissions?.showPicker === true,
|
|
1211
|
-
preload: props.preload ?? true,
|
|
1212
|
-
reopenOnRefresh: props.reopenOnRefresh ?? false,
|
|
1213
|
-
showLauncher: props.showLauncher ?? true,
|
|
1214
|
-
startNewConversationOnOpen: props.startNewConversationOnOpen ?? false,
|
|
1215
|
-
suggestedPromptShortcuts: props.startScreen?.promptShortcuts ?? false,
|
|
1216
|
-
...props.appearance?.launcher?.icon?.trim() ? { launcherIcon: props.appearance.launcher.icon.trim() } : {},
|
|
1217
|
-
...props.appearance?.launcher?.style ? { launcherStyle: props.appearance.launcher.style } : {},
|
|
1218
|
-
...props.appearance?.launcher?.offset ? {
|
|
1219
|
-
launcherOffset: {
|
|
1220
|
-
x: clampLauncherOffset(props.appearance.launcher.offset.x),
|
|
1221
|
-
y: clampLauncherOffset(props.appearance.launcher.offset.y)
|
|
1222
|
-
}
|
|
1223
|
-
} : {},
|
|
1224
|
-
imageSearch: (props.capabilities?.webSearch ?? false) && (props.capabilities?.imageSearch ?? true),
|
|
1225
|
-
newsSearch: (props.capabilities?.webSearch ?? false) && (props.capabilities?.newsSearch ?? false),
|
|
1226
|
-
suggestedPrompts: props.startScreen?.prompts?.map((prompt) => prompt.trim()).filter(Boolean).slice(0, 5),
|
|
1227
|
-
themeStyle: {
|
|
1228
|
-
...buildThemeStyle(props.appearance?.theme),
|
|
1229
|
-
...buildLauncherStyle(props.appearance?.launcher?.background)
|
|
1230
|
-
},
|
|
1231
|
-
tools: props.tools ?? [],
|
|
1232
|
-
viewMode: props.appearance?.viewMode ?? "floating",
|
|
1233
|
-
webSearch: props.capabilities?.webSearch ?? false
|
|
1234
|
-
};
|
|
1235
|
-
}
|
|
1236
|
-
|
|
1237
|
-
export {
|
|
1238
|
-
createToolHelper,
|
|
1239
|
-
isZodSchema,
|
|
1240
|
-
parseClientToolArgs,
|
|
1241
|
-
resolveDirectToolAction,
|
|
1242
|
-
EmbedSessionManager,
|
|
1243
|
-
AgentLoadingState,
|
|
1244
|
-
ComposerControlTooltip,
|
|
1245
|
-
readSidebarWidth,
|
|
1246
|
-
PanelShell,
|
|
1247
|
-
HEROUI_AGENT_MAX_ATTACHMENTS,
|
|
1248
|
-
HEROUI_AGENT_ATTACHMENT_MAX_BYTES,
|
|
1249
|
-
HEROUI_AGENT_ATTACHMENT_EXTENSION_BY_CONTENT_TYPE,
|
|
1250
|
-
HEROUI_AGENT_ATTACHMENT_CONTENT_TYPES,
|
|
1251
|
-
isHeroUIAgentAttachmentContentType,
|
|
1252
|
-
AGENT_MODEL_IDS,
|
|
1253
|
-
LEGACY_AGENT_MODEL_IDS,
|
|
1254
|
-
resolveAgentModelId,
|
|
1255
|
-
DEFAULT_AGENT_PICKER_MODEL_ID,
|
|
1256
|
-
AGENT_MODEL_OPTIONS,
|
|
1257
|
-
isAgentModelId,
|
|
1258
|
-
getAgentModelTier,
|
|
1259
|
-
createSubmittedAgentShellHandoff,
|
|
1260
|
-
writeAgentShellHandoff,
|
|
1261
|
-
readAgentShellHandoff,
|
|
1262
|
-
takeAgentShellHandoff,
|
|
1263
|
-
setFocus,
|
|
1264
|
-
restoreFocus,
|
|
1265
|
-
containsComposerFocus,
|
|
1266
|
-
writeAgentShellAttachments,
|
|
1267
|
-
readAgentShellAttachments,
|
|
1268
|
-
takeAgentShellAttachments,
|
|
1269
|
-
resizeComposerTextarea,
|
|
1270
|
-
PoweredByHero,
|
|
1271
|
-
ShellConversation,
|
|
1272
|
-
agentPermissionModeStorageKey,
|
|
1273
|
-
agentActivePermissionModeStorageKey,
|
|
1274
|
-
readStoredAgentPermissionMode,
|
|
1275
|
-
storeAgentPermissionMode,
|
|
1276
|
-
clearStoredAgentPermissionMode,
|
|
1277
|
-
applyAgentPermissionMode,
|
|
1278
|
-
AGENT_DESIGN_THEMES,
|
|
1279
|
-
DEFAULT_MARKDOWN_ANIMATION,
|
|
1280
|
-
resolveOptions,
|
|
1281
|
-
HEROUI_AGENT_RUNTIME_TIMING_EVENT,
|
|
1282
|
-
HEROUI_AGENT_TURN_ADMITTED_FRAME_TYPE,
|
|
1283
|
-
HEROUI_AGENT_TURN_ADMISSION_STATUS_METHOD,
|
|
1284
|
-
HEROUI_AGENT_TURN_ADMISSION_STATUS_MAX_IDS
|
|
1285
|
-
};
|