@heroui/agent 0.2.0-beta.7 → 0.2.0-beta.8
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 +15 -2
- package/README.md +15 -10
- package/dist/{chunk-V5S5FRGV.js → chunk-CMZDZGUZ.js} +354 -206
- package/dist/chunk-DS4X5K2R.js +56 -0
- package/dist/{chunk-6O3SFXJK.js → chunk-G6GFNSG4.js} +13 -54
- package/dist/chunk-Q7LGTVBL.js +43 -0
- package/dist/chunk-UUPU3MYB.js +42 -0
- package/dist/{chunk-OQGXZY5L.js → chunk-W7SCMB3O.js} +552 -358
- package/dist/{component-renderer-46EJDPTB.js → component-renderer-MDDQMQTU.js} +4 -2
- package/dist/composer-draft-DTQAEO5K.js +20 -0
- package/dist/composer-image-draft-IVJ352E6.js +174 -0
- package/dist/contracts.d.ts +50 -19
- package/dist/contracts.js +130 -230
- package/dist/css/index.css +1 -1
- package/dist/{embed-runtime-UF7XJIFA.js → embed-runtime-VVAGDPYY.js} +3415 -1643
- package/dist/identity-3P8-17km.d.ts +95 -0
- package/dist/index.d.ts +46 -10
- package/dist/index.js +5 -2
- package/dist/next.d.ts +2 -1
- package/dist/next.js +5 -2
- package/dist/server.d.ts +1 -1
- package/dist/server.js +35 -159
- package/package.json +3 -3
- package/dist/identity-Z6i6pL0F.d.ts +0 -166
|
@@ -18,218 +18,27 @@ function resolveDirectToolAction(tools, toolName) {
|
|
|
18
18
|
return tool;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
// src/embed/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
function readAgentComposerPromptDraft(key, now = Date.now()) {
|
|
32
|
-
if (typeof window === "undefined") return "";
|
|
33
|
-
try {
|
|
34
|
-
const raw = window.localStorage.getItem(key);
|
|
35
|
-
if (!raw) return "";
|
|
36
|
-
const parsed = JSON.parse(raw);
|
|
37
|
-
const isFresh = typeof parsed.savedAt === "number" && now - parsed.savedAt <= AGENT_COMPOSER_DRAFT_MAX_AGE_MS;
|
|
38
|
-
if (!isFresh || typeof parsed.prompt !== "string" || !parsed.prompt.trim()) {
|
|
39
|
-
window.localStorage.removeItem(key);
|
|
40
|
-
return "";
|
|
41
|
-
}
|
|
42
|
-
return parsed.prompt;
|
|
43
|
-
} catch {
|
|
44
|
-
try {
|
|
45
|
-
window.localStorage.removeItem(key);
|
|
46
|
-
} catch {
|
|
47
|
-
}
|
|
48
|
-
return "";
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
function saveAgentComposerPromptDraft(key, prompt, now = Date.now()) {
|
|
52
|
-
if (typeof window === "undefined") return;
|
|
53
|
-
try {
|
|
54
|
-
if (!prompt.trim()) {
|
|
55
|
-
window.localStorage.removeItem(key);
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
window.localStorage.setItem(
|
|
59
|
-
key,
|
|
60
|
-
JSON.stringify({ prompt, savedAt: now })
|
|
61
|
-
);
|
|
62
|
-
} catch {
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
async function readAgentComposerImageDraft(key, now = Date.now()) {
|
|
66
|
-
await pendingImageDraftMutations.get(key);
|
|
67
|
-
const stored = await readImageDraftRecord(key);
|
|
68
|
-
if (!stored) return [];
|
|
69
|
-
const isFresh = now - stored.savedAt <= AGENT_COMPOSER_DRAFT_MAX_AGE_MS;
|
|
70
|
-
const files = stored.files.filter(isPersistableImageFile);
|
|
71
|
-
if (!isFresh || files.length === 0) {
|
|
72
|
-
await queueImageDraftMutation(key, () => deleteImageDraftRecord(key));
|
|
73
|
-
return [];
|
|
74
|
-
}
|
|
75
|
-
return files;
|
|
76
|
-
}
|
|
77
|
-
function saveAgentComposerImageDraft(key, files, now = Date.now()) {
|
|
78
|
-
const images = files.filter(isPersistableImageFile);
|
|
79
|
-
return queueImageDraftMutation(
|
|
80
|
-
key,
|
|
81
|
-
() => images.length > 0 ? writeImageDraftRecord({ files: images, key, savedAt: now }) : deleteImageDraftRecord(key)
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
function clearAgentComposerDraft(key) {
|
|
85
|
-
if (typeof window !== "undefined") {
|
|
86
|
-
try {
|
|
87
|
-
window.localStorage.removeItem(key);
|
|
88
|
-
} catch {
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return queueImageDraftMutation(key, () => deleteImageDraftRecord(key));
|
|
92
|
-
}
|
|
93
|
-
async function clearAgentComposerDraftsForProject(agentId) {
|
|
94
|
-
const prefix = `heroui-agent:conversation:${agentId}:`;
|
|
95
|
-
if (typeof window !== "undefined") {
|
|
96
|
-
try {
|
|
97
|
-
for (let index = window.localStorage.length - 1; index >= 0; index -= 1) {
|
|
98
|
-
const key = window.localStorage.key(index);
|
|
99
|
-
if (key?.startsWith(prefix) && key.includes(AGENT_COMPOSER_DRAFT_MARKER)) {
|
|
100
|
-
window.localStorage.removeItem(key);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
} catch {
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
const pending = [...pendingImageDraftMutations.entries()].filter(([key]) => key.startsWith(prefix)).map(([, mutation]) => mutation);
|
|
107
|
-
await Promise.all(pending);
|
|
108
|
-
await deleteImageDraftRecordsByPrefix(prefix);
|
|
109
|
-
}
|
|
110
|
-
function isPersistableImageFile(value) {
|
|
111
|
-
return typeof File !== "undefined" && value instanceof File && typeof value.type === "string" && value.type.startsWith("image/");
|
|
112
|
-
}
|
|
113
|
-
function queueImageDraftMutation(key, mutation) {
|
|
114
|
-
const previous = pendingImageDraftMutations.get(key) ?? Promise.resolve();
|
|
115
|
-
const next = previous.catch(() => void 0).then(mutation).catch(() => void 0);
|
|
116
|
-
pendingImageDraftMutations.set(key, next);
|
|
117
|
-
void next.finally(() => {
|
|
118
|
-
if (pendingImageDraftMutations.get(key) === next) pendingImageDraftMutations.delete(key);
|
|
119
|
-
});
|
|
120
|
-
return next;
|
|
121
|
-
}
|
|
122
|
-
function openImageDraftDatabase() {
|
|
123
|
-
if (typeof indexedDB === "undefined") return Promise.resolve(null);
|
|
124
|
-
return new Promise((resolve) => {
|
|
125
|
-
const request = indexedDB.open(AGENT_COMPOSER_DRAFT_DB_NAME, AGENT_COMPOSER_DRAFT_DB_VERSION);
|
|
126
|
-
request.onerror = () => resolve(null);
|
|
127
|
-
request.onupgradeneeded = () => {
|
|
128
|
-
const database = request.result;
|
|
129
|
-
if (!database.objectStoreNames.contains(AGENT_COMPOSER_IMAGE_DRAFT_STORE)) {
|
|
130
|
-
database.createObjectStore(AGENT_COMPOSER_IMAGE_DRAFT_STORE, { keyPath: "key" });
|
|
131
|
-
}
|
|
132
|
-
};
|
|
133
|
-
request.onsuccess = () => resolve(request.result);
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
async function withImageDraftStore(mode, run) {
|
|
137
|
-
let database;
|
|
138
|
-
try {
|
|
139
|
-
database = await openImageDraftDatabase();
|
|
140
|
-
} catch {
|
|
141
|
-
return null;
|
|
142
|
-
}
|
|
143
|
-
if (!database) return null;
|
|
144
|
-
try {
|
|
145
|
-
const transaction = database.transaction(AGENT_COMPOSER_IMAGE_DRAFT_STORE, mode);
|
|
146
|
-
const completion = waitForTransaction(transaction);
|
|
147
|
-
const [result] = await Promise.all([
|
|
148
|
-
run(transaction.objectStore(AGENT_COMPOSER_IMAGE_DRAFT_STORE)),
|
|
149
|
-
completion
|
|
150
|
-
]);
|
|
151
|
-
return result;
|
|
152
|
-
} catch {
|
|
153
|
-
return null;
|
|
154
|
-
} finally {
|
|
155
|
-
database.close();
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
async function readImageDraftRecord(key) {
|
|
159
|
-
const result = await withImageDraftStore(
|
|
160
|
-
"readonly",
|
|
161
|
-
(store) => waitForRequest(store.get(key))
|
|
162
|
-
);
|
|
163
|
-
if (typeof result !== "object" || result === null) return null;
|
|
164
|
-
const draft = result;
|
|
165
|
-
if (draft.key !== key || typeof draft.savedAt !== "number" || !Array.isArray(draft.files)) {
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
return { files: draft.files.filter(isPersistableImageFile), key, savedAt: draft.savedAt };
|
|
169
|
-
}
|
|
170
|
-
async function writeImageDraftRecord(draft) {
|
|
171
|
-
await withImageDraftStore("readwrite", async (store) => {
|
|
172
|
-
await waitForRequest(store.put(draft));
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
async function deleteImageDraftRecord(key) {
|
|
176
|
-
await withImageDraftStore("readwrite", async (store) => {
|
|
177
|
-
await waitForRequest(store.delete(key));
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
|
-
async function deleteImageDraftRecordsByPrefix(prefix) {
|
|
181
|
-
await withImageDraftStore(
|
|
182
|
-
"readwrite",
|
|
183
|
-
(store) => new Promise((resolve, reject) => {
|
|
184
|
-
const request = store.openCursor();
|
|
185
|
-
request.onerror = () => reject(request.error ?? new Error("Unable to clear image drafts"));
|
|
186
|
-
request.onsuccess = () => {
|
|
187
|
-
const cursor = request.result;
|
|
188
|
-
if (!cursor) {
|
|
189
|
-
resolve();
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
if (typeof cursor.key === "string" && cursor.key.startsWith(prefix)) cursor.delete();
|
|
193
|
-
cursor.continue();
|
|
194
|
-
};
|
|
195
|
-
})
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
function waitForRequest(request) {
|
|
199
|
-
return new Promise((resolve, reject) => {
|
|
200
|
-
request.onerror = () => reject(request.error ?? new Error("IndexedDB request failed"));
|
|
201
|
-
request.onsuccess = () => resolve(request.result);
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
function waitForTransaction(transaction) {
|
|
205
|
-
return new Promise((resolve, reject) => {
|
|
206
|
-
transaction.onabort = () => reject(transaction.error ?? new Error("IndexedDB aborted"));
|
|
207
|
-
transaction.onerror = () => reject(transaction.error ?? new Error("IndexedDB failed"));
|
|
208
|
-
transaction.oncomplete = () => resolve();
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// src/embed/idle.ts
|
|
213
|
-
function scheduleIdleTask(task, timeoutMs = 3e3) {
|
|
214
|
-
if (typeof window === "undefined") return () => void 0;
|
|
215
|
-
const idle = window.requestIdleCallback;
|
|
216
|
-
if (!idle) {
|
|
217
|
-
const timeout = window.setTimeout(task, Math.min(timeoutMs, 1500));
|
|
218
|
-
return () => window.clearTimeout(timeout);
|
|
219
|
-
}
|
|
220
|
-
const handle = idle(() => task(), { timeout: timeoutMs });
|
|
221
|
-
return () => window.cancelIdleCallback?.(handle);
|
|
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
|
+
] });
|
|
222
31
|
}
|
|
223
32
|
|
|
224
33
|
// src/embed/composer-control-tooltip.tsx
|
|
225
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
34
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
226
35
|
function ComposerControlTooltip({
|
|
227
36
|
children,
|
|
228
37
|
shortcut
|
|
229
38
|
}) {
|
|
230
|
-
return /* @__PURE__ */
|
|
231
|
-
/* @__PURE__ */
|
|
232
|
-
shortcut ? /* @__PURE__ */
|
|
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
|
|
233
42
|
] });
|
|
234
43
|
}
|
|
235
44
|
|
|
@@ -265,7 +74,7 @@ function persistSidebarWidth(agentId, width) {
|
|
|
265
74
|
}
|
|
266
75
|
|
|
267
76
|
// src/embed/panel-shell.tsx
|
|
268
|
-
import { jsx as
|
|
77
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
269
78
|
function PanelShell({
|
|
270
79
|
actionsSlot,
|
|
271
80
|
agentId,
|
|
@@ -275,6 +84,7 @@ function PanelShell({
|
|
|
275
84
|
expandedSidebarSlot,
|
|
276
85
|
expandedTitle,
|
|
277
86
|
historySlot,
|
|
87
|
+
keepMounted = false,
|
|
278
88
|
modal,
|
|
279
89
|
name,
|
|
280
90
|
onClose,
|
|
@@ -351,7 +161,7 @@ function PanelShell({
|
|
|
351
161
|
const first = panel.querySelector(
|
|
352
162
|
"button,textarea,input,[tabindex]:not([tabindex='-1'])"
|
|
353
163
|
);
|
|
354
|
-
first?.focus();
|
|
164
|
+
if (!panel.contains(document.activeElement)) first?.focus();
|
|
355
165
|
const handleKeyDown = (event) => {
|
|
356
166
|
if (!effectiveModal && event.key === "Escape") {
|
|
357
167
|
if (dismissOpenPanelOverlay(panel)) {
|
|
@@ -396,11 +206,11 @@ function PanelShell({
|
|
|
396
206
|
document.body.style.right = previousBodyRight;
|
|
397
207
|
document.body.style.width = previousBodyWidth;
|
|
398
208
|
if (effectiveModal) window.scrollTo(scrollX, scrollY);
|
|
399
|
-
previous?.focus();
|
|
209
|
+
if (document.activeElement === document.body) previous?.focus();
|
|
400
210
|
};
|
|
401
211
|
}, [effectiveModal, open]);
|
|
402
|
-
if (!open) return null;
|
|
403
|
-
return /* @__PURE__ */
|
|
212
|
+
if (!open && !keepMounted) return null;
|
|
213
|
+
return /* @__PURE__ */ jsxs3(
|
|
404
214
|
"dialog",
|
|
405
215
|
{
|
|
406
216
|
ref: panelRef,
|
|
@@ -411,6 +221,7 @@ function PanelShell({
|
|
|
411
221
|
"data-expanded": !isMobileViewport && isExpanded ? "true" : void 0,
|
|
412
222
|
"data-expanded-sidebar": showExpandedSidebar ? "true" : void 0,
|
|
413
223
|
"data-resizing": isResizing ? "true" : void 0,
|
|
224
|
+
hidden: !open,
|
|
414
225
|
onCancel: (event) => {
|
|
415
226
|
event.preventDefault();
|
|
416
227
|
if (Date.now() - overlayEscapeAt.current < 350 || dismissOpenPanelOverlay(panelRef.current)) {
|
|
@@ -420,23 +231,23 @@ function PanelShell({
|
|
|
420
231
|
onClose();
|
|
421
232
|
},
|
|
422
233
|
children: [
|
|
423
|
-
isDesktopSidebar && !isExpanded ? /* @__PURE__ */
|
|
424
|
-
showExpandedSidebar ? /* @__PURE__ */
|
|
425
|
-
/* @__PURE__ */
|
|
426
|
-
/* @__PURE__ */
|
|
427
|
-
showExpandedSidebar ? /* @__PURE__ */
|
|
428
|
-
/* @__PURE__ */
|
|
429
|
-
showExpandedSidebar ? null : actionsSlot ?? (onNewConversation ? /* @__PURE__ */
|
|
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(
|
|
430
241
|
"button",
|
|
431
242
|
{
|
|
432
243
|
"aria-label": "New chat",
|
|
433
244
|
className: "ha-icon-button ha-new-chat-button",
|
|
434
245
|
type: "button",
|
|
435
246
|
onClick: onNewConversation,
|
|
436
|
-
children: /* @__PURE__ */
|
|
247
|
+
children: /* @__PURE__ */ jsx3(PlusGlyph, {})
|
|
437
248
|
}
|
|
438
249
|
) : null),
|
|
439
|
-
canExpand ? /* @__PURE__ */
|
|
250
|
+
canExpand ? /* @__PURE__ */ jsx3(
|
|
440
251
|
"button",
|
|
441
252
|
{
|
|
442
253
|
"aria-expanded": isExpanded,
|
|
@@ -447,10 +258,10 @@ function PanelShell({
|
|
|
447
258
|
setIsResizing(true);
|
|
448
259
|
setIsExpanded((expanded) => !expanded);
|
|
449
260
|
},
|
|
450
|
-
children: isExpanded ? /* @__PURE__ */
|
|
261
|
+
children: isExpanded ? /* @__PURE__ */ jsx3(ChevronsCollapseUpRight, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx3(ChevronsExpandUpRight, { "aria-hidden": "true" })
|
|
451
262
|
}
|
|
452
263
|
) : null,
|
|
453
|
-
/* @__PURE__ */
|
|
264
|
+
/* @__PURE__ */ jsxs3(
|
|
454
265
|
"button",
|
|
455
266
|
{
|
|
456
267
|
"aria-keyshortcuts": "Escape",
|
|
@@ -461,15 +272,15 @@ function PanelShell({
|
|
|
461
272
|
type: "button",
|
|
462
273
|
onClick: onClose,
|
|
463
274
|
children: [
|
|
464
|
-
/* @__PURE__ */
|
|
465
|
-
/* @__PURE__ */
|
|
275
|
+
/* @__PURE__ */ jsx3(CloseGlyph, {}),
|
|
276
|
+
/* @__PURE__ */ jsx3(ComposerControlTooltip, { shortcut: "ESC", children: "Close assistant" })
|
|
466
277
|
]
|
|
467
278
|
}
|
|
468
279
|
)
|
|
469
280
|
] })
|
|
470
281
|
] }),
|
|
471
282
|
children,
|
|
472
|
-
/* @__PURE__ */
|
|
283
|
+
/* @__PURE__ */ jsx3("div", { className: "ha-overlay-portal", "data-agent-overlay-portal": "" })
|
|
473
284
|
] })
|
|
474
285
|
]
|
|
475
286
|
}
|
|
@@ -518,7 +329,7 @@ function SidebarResizeHandle({
|
|
|
518
329
|
);
|
|
519
330
|
return (
|
|
520
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.
|
|
521
|
-
/* @__PURE__ */
|
|
332
|
+
/* @__PURE__ */ jsx3(
|
|
522
333
|
"div",
|
|
523
334
|
{
|
|
524
335
|
"aria-label": "Resize assistant panel",
|
|
@@ -578,7 +389,7 @@ function SidebarResizeHandle({
|
|
|
578
389
|
);
|
|
579
390
|
}
|
|
580
391
|
function CloseGlyph() {
|
|
581
|
-
return /* @__PURE__ */
|
|
392
|
+
return /* @__PURE__ */ jsx3("svg", { "aria-hidden": "true", fill: "none", height: "18", viewBox: "0 0 18 18", width: "18", children: /* @__PURE__ */ jsx3(
|
|
582
393
|
"path",
|
|
583
394
|
{
|
|
584
395
|
d: "m4.25 4.25 9.5 9.5m0-9.5-9.5 9.5",
|
|
@@ -589,7 +400,192 @@ function CloseGlyph() {
|
|
|
589
400
|
) });
|
|
590
401
|
}
|
|
591
402
|
function PlusGlyph() {
|
|
592
|
-
return /* @__PURE__ */
|
|
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;
|
|
593
589
|
}
|
|
594
590
|
|
|
595
591
|
// src/embed/composer-textarea.ts
|
|
@@ -648,10 +644,10 @@ function resizeComposerTextarea(textarea, {
|
|
|
648
644
|
}
|
|
649
645
|
|
|
650
646
|
// src/embed/powered-by-hero.tsx
|
|
651
|
-
import { jsx as
|
|
647
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
652
648
|
var POWERED_BY_HERO_URL = "https://heroui.pro/?utm_source=heroui-agent&utm_medium=referral&utm_campaign=powered-by-hero";
|
|
653
649
|
function PoweredByHero() {
|
|
654
|
-
return /* @__PURE__ */
|
|
650
|
+
return /* @__PURE__ */ jsxs4(
|
|
655
651
|
"a",
|
|
656
652
|
{
|
|
657
653
|
"aria-label": "Powered by HeroUI Pro (opens in a new tab)",
|
|
@@ -660,16 +656,16 @@ function PoweredByHero() {
|
|
|
660
656
|
rel: "noopener noreferrer",
|
|
661
657
|
target: "_blank",
|
|
662
658
|
children: [
|
|
663
|
-
/* @__PURE__ */
|
|
664
|
-
/* @__PURE__ */
|
|
665
|
-
/* @__PURE__ */
|
|
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(
|
|
666
662
|
"path",
|
|
667
663
|
{
|
|
668
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",
|
|
669
665
|
fill: "currentColor"
|
|
670
666
|
}
|
|
671
667
|
),
|
|
672
|
-
/* @__PURE__ */
|
|
668
|
+
/* @__PURE__ */ jsx4(
|
|
673
669
|
"path",
|
|
674
670
|
{
|
|
675
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",
|
|
@@ -682,43 +678,11 @@ function PoweredByHero() {
|
|
|
682
678
|
);
|
|
683
679
|
}
|
|
684
680
|
|
|
685
|
-
// src/embed/shell-handoff.ts
|
|
686
|
-
var handoffs = /* @__PURE__ */ new Map();
|
|
687
|
-
function shellDraftStorageKey(agentId) {
|
|
688
|
-
return `heroui-agent:shell-draft:${agentId}:composer-draft:v1`;
|
|
689
|
-
}
|
|
690
|
-
function writeAgentShellHandoff(agentId, handoff) {
|
|
691
|
-
if (!handoff.prompt.trim() && !handoff.submitted) {
|
|
692
|
-
handoffs.delete(agentId);
|
|
693
|
-
saveAgentComposerPromptDraft(shellDraftStorageKey(agentId), "");
|
|
694
|
-
return;
|
|
695
|
-
}
|
|
696
|
-
handoffs.set(agentId, handoff);
|
|
697
|
-
if (!handoff.submitted) {
|
|
698
|
-
saveAgentComposerPromptDraft(shellDraftStorageKey(agentId), handoff.prompt);
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
function readAgentShellHandoff(agentId) {
|
|
702
|
-
const buffered = handoffs.get(agentId);
|
|
703
|
-
if (buffered) return buffered;
|
|
704
|
-
const persisted = readAgentComposerPromptDraft(shellDraftStorageKey(agentId));
|
|
705
|
-
return persisted ? { prompt: persisted, submitted: false } : void 0;
|
|
706
|
-
}
|
|
707
|
-
function takeAgentShellHandoff(agentId) {
|
|
708
|
-
const handoff = readAgentShellHandoff(agentId);
|
|
709
|
-
handoffs.delete(agentId);
|
|
710
|
-
saveAgentComposerPromptDraft(shellDraftStorageKey(agentId), "");
|
|
711
|
-
return handoff;
|
|
712
|
-
}
|
|
713
|
-
|
|
714
681
|
// src/embed/permissions.ts
|
|
715
682
|
var AGENT_PERMISSION_MODES = /* @__PURE__ */ new Set(["ask", "auto", "full"]);
|
|
716
683
|
function resolveAgentPermissionMode(value) {
|
|
717
684
|
return AGENT_PERMISSION_MODES.has(value) ? value : "auto";
|
|
718
685
|
}
|
|
719
|
-
function shouldRestoreActiveAgentPermissionMode(bootstrapStatus, hasUnresolvedClientTool) {
|
|
720
|
-
return hasUnresolvedClientTool || bootstrapStatus === "pending" || bootstrapStatus === "streaming";
|
|
721
|
-
}
|
|
722
686
|
function agentPermissionModeStorageKey(conversationStorageKey, conversationId) {
|
|
723
687
|
return `${conversationStorageKey}:permission-mode:${conversationId}:v1`;
|
|
724
688
|
}
|
|
@@ -843,81 +807,103 @@ function buildThemeStyle(theme) {
|
|
|
843
807
|
return style;
|
|
844
808
|
}
|
|
845
809
|
|
|
846
|
-
// src/contracts/
|
|
847
|
-
var
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
var
|
|
857
|
-
|
|
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
|
+
}
|
|
858
896
|
};
|
|
859
|
-
function
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
provider: "Moonshot AI",
|
|
869
|
-
tier: "light"
|
|
870
|
-
},
|
|
871
|
-
{
|
|
872
|
-
description: "Fast answers and lightweight agent workflows",
|
|
873
|
-
id: "openai/gpt-5.6-luna",
|
|
874
|
-
label: "GPT-5.6 Luna",
|
|
875
|
-
provider: "OpenAI",
|
|
876
|
-
tier: "light"
|
|
877
|
-
},
|
|
878
|
-
{
|
|
879
|
-
description: "Balanced reasoning for everyday agent tasks",
|
|
880
|
-
id: "openai/gpt-5.6-terra",
|
|
881
|
-
label: "GPT-5.6 Terra",
|
|
882
|
-
provider: "OpenAI",
|
|
883
|
-
tier: "codegen"
|
|
884
|
-
},
|
|
885
|
-
{
|
|
886
|
-
description: "Deep reasoning for complex, multi-step analysis",
|
|
887
|
-
id: "openai/gpt-5.6-sol",
|
|
888
|
-
label: "GPT-5.6 Sol",
|
|
889
|
-
provider: "OpenAI",
|
|
890
|
-
tier: "complex"
|
|
891
|
-
},
|
|
892
|
-
{
|
|
893
|
-
description: "Fast multimodal analysis with a large context window",
|
|
894
|
-
id: "google/gemini-3.6-flash",
|
|
895
|
-
label: "Gemini 3.6 Flash",
|
|
896
|
-
provider: "Google",
|
|
897
|
-
tier: "light"
|
|
898
|
-
},
|
|
899
|
-
{
|
|
900
|
-
description: "Strong agentic reasoning and polished UI decisions",
|
|
901
|
-
id: "anthropic/claude-sonnet-5",
|
|
902
|
-
label: "Claude Sonnet 5",
|
|
903
|
-
provider: "Anthropic",
|
|
904
|
-
tier: "codegen"
|
|
905
|
-
},
|
|
906
|
-
{
|
|
907
|
-
description: "Highest-capability Claude for difficult research and analysis",
|
|
908
|
-
id: "anthropic/claude-opus-4.8",
|
|
909
|
-
label: "Claude Opus 4.8",
|
|
910
|
-
provider: "Anthropic",
|
|
911
|
-
tier: "complex"
|
|
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 {};
|
|
912
906
|
}
|
|
913
|
-
];
|
|
914
|
-
var AGENT_MODEL_ID_SET = new Set(AGENT_MODEL_IDS);
|
|
915
|
-
function isAgentModelId(value) {
|
|
916
|
-
return typeof value === "string" && AGENT_MODEL_ID_SET.has(value);
|
|
917
|
-
}
|
|
918
|
-
function getAgentModelTier(modelId) {
|
|
919
|
-
const resolved = modelId ? resolveAgentModelId(modelId) : void 0;
|
|
920
|
-
return AGENT_MODEL_OPTIONS.find((option) => option.id === resolved)?.tier ?? "light";
|
|
921
907
|
}
|
|
922
908
|
|
|
923
909
|
// src/contracts/attachments.ts
|
|
@@ -948,9 +934,210 @@ function isHeroUIAgentAttachmentContentType(value) {
|
|
|
948
934
|
return HEROUI_AGENT_ATTACHMENT_CONTENT_TYPE_SET.has(value.trim().toLowerCase());
|
|
949
935
|
}
|
|
950
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
|
+
|
|
951
1138
|
// src/embed/types.ts
|
|
952
1139
|
var DEFAULT_MARKDOWN_ANIMATION = {
|
|
953
|
-
animation: "
|
|
1140
|
+
animation: "fadeIn",
|
|
954
1141
|
duration: 160,
|
|
955
1142
|
easing: "ease-out",
|
|
956
1143
|
sep: "word",
|
|
@@ -992,16 +1179,18 @@ function resolveOptions(props) {
|
|
|
992
1179
|
const composerAttachmentContentTypes = resolveComposerAttachmentContentTypes(
|
|
993
1180
|
props.composer?.attachments
|
|
994
1181
|
);
|
|
1182
|
+
const composerDisclaimer = typeof props.composer?.disclaimer === "string" ? props.composer.disclaimer.trim().slice(0, 240) || void 0 : void 0;
|
|
995
1183
|
return {
|
|
996
1184
|
apiBaseUrl: (props._api?.baseUrl ?? "https://api.heroui.com").replace(/\/$/, ""),
|
|
997
1185
|
colorScheme: props.appearance?.theme?.colorScheme ?? "system",
|
|
998
1186
|
componentExportFormats: props.componentExports === false ? [] : props.componentExports ?? ["csv", "svg", "png"],
|
|
999
1187
|
composerAttachmentAccept: composerAttachmentContentTypes.join(","),
|
|
1000
1188
|
composerAttachmentContentTypes,
|
|
1189
|
+
composerControlsAvailable: composerAttachmentContentTypes.length > 0 || props.permissions?.showPicker === true && !!props.tools?.length || props.composer?.modelPicker === true || (props.composer?.dictation ?? true),
|
|
1001
1190
|
composerDefaultModel: props.composer?.defaultModel,
|
|
1002
1191
|
composerDictation: props.composer?.dictation ?? true,
|
|
1003
1192
|
designTheme: resolveAgentDesignTheme(props.appearance?.theme?.designTheme),
|
|
1004
|
-
...
|
|
1193
|
+
...composerDisclaimer ? { composerDisclaimer } : {},
|
|
1005
1194
|
agentId: props.agentId,
|
|
1006
1195
|
composerModelPicker: props.composer?.modelPicker ?? false,
|
|
1007
1196
|
composerPlaceholder: props.composer?.placeholder?.trim().slice(0, 120) || "Ask anything\u2026",
|
|
@@ -1050,14 +1239,8 @@ export {
|
|
|
1050
1239
|
isZodSchema,
|
|
1051
1240
|
parseClientToolArgs,
|
|
1052
1241
|
resolveDirectToolAction,
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
saveAgentComposerPromptDraft,
|
|
1056
|
-
readAgentComposerImageDraft,
|
|
1057
|
-
saveAgentComposerImageDraft,
|
|
1058
|
-
clearAgentComposerDraft,
|
|
1059
|
-
clearAgentComposerDraftsForProject,
|
|
1060
|
-
scheduleIdleTask,
|
|
1242
|
+
EmbedSessionManager,
|
|
1243
|
+
AgentLoadingState,
|
|
1061
1244
|
ComposerControlTooltip,
|
|
1062
1245
|
readSidebarWidth,
|
|
1063
1246
|
PanelShell,
|
|
@@ -1066,12 +1249,26 @@ export {
|
|
|
1066
1249
|
HEROUI_AGENT_ATTACHMENT_EXTENSION_BY_CONTENT_TYPE,
|
|
1067
1250
|
HEROUI_AGENT_ATTACHMENT_CONTENT_TYPES,
|
|
1068
1251
|
isHeroUIAgentAttachmentContentType,
|
|
1069
|
-
|
|
1070
|
-
|
|
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,
|
|
1071
1260
|
writeAgentShellHandoff,
|
|
1072
1261
|
readAgentShellHandoff,
|
|
1073
1262
|
takeAgentShellHandoff,
|
|
1074
|
-
|
|
1263
|
+
setFocus,
|
|
1264
|
+
restoreFocus,
|
|
1265
|
+
containsComposerFocus,
|
|
1266
|
+
writeAgentShellAttachments,
|
|
1267
|
+
readAgentShellAttachments,
|
|
1268
|
+
takeAgentShellAttachments,
|
|
1269
|
+
resizeComposerTextarea,
|
|
1270
|
+
PoweredByHero,
|
|
1271
|
+
ShellConversation,
|
|
1075
1272
|
agentPermissionModeStorageKey,
|
|
1076
1273
|
agentActivePermissionModeStorageKey,
|
|
1077
1274
|
readStoredAgentPermissionMode,
|
|
@@ -1081,11 +1278,8 @@ export {
|
|
|
1081
1278
|
AGENT_DESIGN_THEMES,
|
|
1082
1279
|
DEFAULT_MARKDOWN_ANIMATION,
|
|
1083
1280
|
resolveOptions,
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
AGENT_MODEL_OPTIONS,
|
|
1089
|
-
isAgentModelId,
|
|
1090
|
-
getAgentModelTier
|
|
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
|
|
1091
1285
|
};
|