@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
|
@@ -1,25 +1,32 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
AGENT_MODEL_OPTIONS,
|
|
3
|
+
AgentLoadingState,
|
|
4
|
+
DEFAULT_AGENT_PICKER_MODEL_ID,
|
|
5
|
+
EmbedSessionManager,
|
|
3
6
|
PanelShell,
|
|
4
|
-
|
|
5
|
-
|
|
7
|
+
ShellConversation,
|
|
8
|
+
containsComposerFocus,
|
|
9
|
+
createSubmittedAgentShellHandoff,
|
|
6
10
|
isHeroUIAgentAttachmentContentType,
|
|
7
|
-
readAgentShellHandoff,
|
|
8
11
|
readSidebarWidth,
|
|
9
|
-
resizeComposerTextarea,
|
|
10
12
|
resolveOptions,
|
|
11
|
-
|
|
13
|
+
setFocus,
|
|
14
|
+
writeAgentShellAttachments,
|
|
12
15
|
writeAgentShellHandoff
|
|
13
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-W7SCMB3O.js";
|
|
17
|
+
import {
|
|
18
|
+
renderInlineMarkdown
|
|
19
|
+
} from "./chunk-Q7LGTVBL.js";
|
|
14
20
|
|
|
15
21
|
// src/embed/provider.tsx
|
|
16
22
|
import {
|
|
17
23
|
useCallback,
|
|
18
24
|
useEffect as useEffect2,
|
|
25
|
+
useEffectEvent,
|
|
19
26
|
useLayoutEffect,
|
|
20
27
|
useMemo,
|
|
21
28
|
useRef as useRef2,
|
|
22
|
-
useState
|
|
29
|
+
useState,
|
|
23
30
|
useSyncExternalStore
|
|
24
31
|
} from "react";
|
|
25
32
|
import { createRoot } from "react-dom/client";
|
|
@@ -288,17 +295,33 @@ function parseAgentRemoteConfig(value) {
|
|
|
288
295
|
function cacheKey(agentId) {
|
|
289
296
|
return `heroui-agent:config:${agentId}`;
|
|
290
297
|
}
|
|
291
|
-
|
|
298
|
+
var REMOTE_CONFIG_CACHE_VERSION = 1;
|
|
299
|
+
function readCachedRemoteConfigSnapshot(agentId) {
|
|
292
300
|
try {
|
|
293
301
|
const raw = window.localStorage.getItem(cacheKey(agentId));
|
|
294
|
-
|
|
302
|
+
if (!raw) return null;
|
|
303
|
+
const value = JSON.parse(raw);
|
|
304
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
305
|
+
const envelope = value;
|
|
306
|
+
if (envelope.cacheVersion === REMOTE_CONFIG_CACHE_VERSION && typeof envelope.cachedAt === "number" && Number.isFinite(envelope.cachedAt)) {
|
|
307
|
+
const config = parseAgentRemoteConfig(envelope.config);
|
|
308
|
+
return config ? { cachedAt: envelope.cachedAt, config, legacy: false } : null;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
const legacyConfig = parseAgentRemoteConfig(value);
|
|
312
|
+
return legacyConfig ? { cachedAt: 0, config: legacyConfig, legacy: true } : null;
|
|
295
313
|
} catch {
|
|
296
314
|
return null;
|
|
297
315
|
}
|
|
298
316
|
}
|
|
299
|
-
function writeCachedRemoteConfig(agentId, config) {
|
|
317
|
+
function writeCachedRemoteConfig(agentId, config, cachedAt = Date.now()) {
|
|
300
318
|
try {
|
|
301
|
-
|
|
319
|
+
const envelope = {
|
|
320
|
+
cacheVersion: REMOTE_CONFIG_CACHE_VERSION,
|
|
321
|
+
cachedAt,
|
|
322
|
+
config
|
|
323
|
+
};
|
|
324
|
+
window.localStorage.setItem(cacheKey(agentId), JSON.stringify(envelope));
|
|
302
325
|
} catch {
|
|
303
326
|
}
|
|
304
327
|
}
|
|
@@ -327,126 +350,125 @@ async function fetchRemoteConfig(apiBaseUrl, agentId, options = {}) {
|
|
|
327
350
|
}
|
|
328
351
|
}
|
|
329
352
|
|
|
330
|
-
// src/embed/shell-
|
|
331
|
-
import {
|
|
353
|
+
// src/embed/shell-composer-presentation.tsx
|
|
354
|
+
import { ChevronDown, Microphone, Plus, ShieldCheck } from "@gravity-ui/icons";
|
|
355
|
+
import { useEffect, useRef } from "react";
|
|
332
356
|
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
357
|
+
var PERMISSION_LABELS = {
|
|
358
|
+
ask: "Ask for approval",
|
|
359
|
+
auto: "Approve for me",
|
|
360
|
+
full: "Full access"
|
|
361
|
+
};
|
|
362
|
+
function createShellComposerPresentation({
|
|
363
|
+
onFileDialogActiveChange,
|
|
336
364
|
onIntent,
|
|
337
|
-
|
|
338
|
-
suggestedPrompts
|
|
365
|
+
options
|
|
339
366
|
}) {
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
writeAgentShellHandoff(agentId, { prompt: trimmed, submitted: true });
|
|
353
|
-
onIntent();
|
|
367
|
+
return {
|
|
368
|
+
end: /* @__PURE__ */ jsx3(ShellComposerControls, { options }),
|
|
369
|
+
footer: options.composerDisclaimer ? /* @__PURE__ */ jsx3("p", { className: "ha-footnote", children: renderInlineMarkdown(options.composerDisclaimer) }) : null,
|
|
370
|
+
start: options.composerAttachmentContentTypes.length > 0 ? /* @__PURE__ */ jsx3(
|
|
371
|
+
ShellAttachmentControl,
|
|
372
|
+
{
|
|
373
|
+
accept: options.composerAttachmentAccept,
|
|
374
|
+
agentId: options.agentId,
|
|
375
|
+
onFileDialogActiveChange,
|
|
376
|
+
onIntent
|
|
377
|
+
}
|
|
378
|
+
) : null
|
|
354
379
|
};
|
|
380
|
+
}
|
|
381
|
+
function ShellAttachmentControl({
|
|
382
|
+
accept,
|
|
383
|
+
agentId,
|
|
384
|
+
onFileDialogActiveChange,
|
|
385
|
+
onIntent
|
|
386
|
+
}) {
|
|
387
|
+
const inputRef = useRef(null);
|
|
388
|
+
useEffect(() => {
|
|
389
|
+
const input = inputRef.current;
|
|
390
|
+
let focusTimer;
|
|
391
|
+
const release = () => onFileDialogActiveChange(false);
|
|
392
|
+
const releaseAfterFocus = () => {
|
|
393
|
+
focusTimer = window.setTimeout(release, 0);
|
|
394
|
+
};
|
|
395
|
+
input?.addEventListener("cancel", release);
|
|
396
|
+
window.addEventListener("focus", releaseAfterFocus);
|
|
397
|
+
return () => {
|
|
398
|
+
input?.removeEventListener("cancel", release);
|
|
399
|
+
window.removeEventListener("focus", releaseAfterFocus);
|
|
400
|
+
window.clearTimeout(focusTimer);
|
|
401
|
+
};
|
|
402
|
+
}, [onFileDialogActiveChange]);
|
|
355
403
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
356
|
-
/* @__PURE__ */ jsx3(
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
404
|
+
/* @__PURE__ */ jsx3(
|
|
405
|
+
"input",
|
|
406
|
+
{
|
|
407
|
+
ref: inputRef,
|
|
408
|
+
multiple: true,
|
|
409
|
+
accept,
|
|
410
|
+
"aria-label": "Choose files to attach",
|
|
411
|
+
className: "ha-file-input",
|
|
412
|
+
type: "file",
|
|
413
|
+
onChange: (event) => {
|
|
414
|
+
writeAgentShellAttachments(agentId, Array.from(event.currentTarget.files ?? []));
|
|
415
|
+
event.currentTarget.value = "";
|
|
416
|
+
onFileDialogActiveChange(false);
|
|
417
|
+
onIntent();
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
),
|
|
421
|
+
/* @__PURE__ */ jsx3(
|
|
422
|
+
"button",
|
|
365
423
|
{
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
424
|
+
"aria-label": "Attach files",
|
|
425
|
+
className: "ha-attach",
|
|
426
|
+
type: "button",
|
|
427
|
+
onClick: () => {
|
|
428
|
+
onFileDialogActiveChange(true);
|
|
429
|
+
inputRef.current?.click();
|
|
370
430
|
},
|
|
371
|
-
children:
|
|
372
|
-
!submitted && suggestedPrompts.length > 0 ? /* @__PURE__ */ jsx3("div", { "aria-label": "Suggested prompts", className: "ha-suggestions", role: "group", children: suggestedPrompts.map((prompt) => /* @__PURE__ */ jsxs(
|
|
373
|
-
"button",
|
|
374
|
-
{
|
|
375
|
-
className: "ha-suggestion",
|
|
376
|
-
type: "button",
|
|
377
|
-
onClick: () => submit(prompt),
|
|
378
|
-
children: [
|
|
379
|
-
/* @__PURE__ */ jsx3("span", { children: prompt }),
|
|
380
|
-
/* @__PURE__ */ jsx3(ArrowUpRightGlyph, {})
|
|
381
|
-
]
|
|
382
|
-
},
|
|
383
|
-
prompt
|
|
384
|
-
)) }) : null,
|
|
385
|
-
/* @__PURE__ */ jsxs("div", { className: "@container ha-composer", children: [
|
|
386
|
-
/* @__PURE__ */ jsx3(
|
|
387
|
-
"textarea",
|
|
388
|
-
{
|
|
389
|
-
ref: textareaRef,
|
|
390
|
-
"aria-label": "Message the assistant",
|
|
391
|
-
placeholder,
|
|
392
|
-
rows: 1,
|
|
393
|
-
value: input,
|
|
394
|
-
onFocus: onIntent,
|
|
395
|
-
onChange: (event) => {
|
|
396
|
-
setInput(event.currentTarget.value);
|
|
397
|
-
resizeComposerTextarea(event.currentTarget);
|
|
398
|
-
onIntent();
|
|
399
|
-
},
|
|
400
|
-
onKeyDown: (event) => {
|
|
401
|
-
if (event.key !== "Enter" || event.shiftKey) return;
|
|
402
|
-
event.preventDefault();
|
|
403
|
-
submit(input);
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
),
|
|
407
|
-
/* @__PURE__ */ jsxs(
|
|
408
|
-
"button",
|
|
409
|
-
{
|
|
410
|
-
"aria-label": "Send message",
|
|
411
|
-
className: "ha-send",
|
|
412
|
-
"data-shortcut": "\u21B5",
|
|
413
|
-
"data-tooltip": "Send message",
|
|
414
|
-
disabled: !input.trim() || submitted,
|
|
415
|
-
type: "submit",
|
|
416
|
-
children: [
|
|
417
|
-
/* @__PURE__ */ jsx3(ArrowUpGlyph, {}),
|
|
418
|
-
/* @__PURE__ */ jsx3(ComposerControlTooltip, { shortcut: "\u21B5", children: "Send message" })
|
|
419
|
-
]
|
|
420
|
-
}
|
|
421
|
-
)
|
|
422
|
-
] }),
|
|
423
|
-
/* @__PURE__ */ jsx3(PoweredByHero, {})
|
|
424
|
-
]
|
|
431
|
+
children: /* @__PURE__ */ jsx3(Plus, { "aria-hidden": "true" })
|
|
425
432
|
}
|
|
426
433
|
)
|
|
427
434
|
] });
|
|
428
435
|
}
|
|
429
|
-
function
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
436
|
+
function ShellComposerControls({ options }) {
|
|
437
|
+
const modelId = options.composerDefaultModel ?? DEFAULT_AGENT_PICKER_MODEL_ID;
|
|
438
|
+
const modelLabel = AGENT_MODEL_OPTIONS.find((option) => option.id === modelId)?.label ?? modelId;
|
|
439
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
440
|
+
options.permissionShowPicker && options.tools.length > 0 ? /* @__PURE__ */ jsx3(
|
|
441
|
+
ShellPicker,
|
|
442
|
+
{
|
|
443
|
+
icon: /* @__PURE__ */ jsx3(ShieldCheck, { "aria-hidden": "true", className: "aui-permission-picker__trigger-icon" }),
|
|
444
|
+
kind: "permission",
|
|
445
|
+
label: PERMISSION_LABELS[options.permissionDefaultMode],
|
|
446
|
+
tone: options.permissionDefaultMode === "full" ? "warning" : void 0
|
|
447
|
+
}
|
|
448
|
+
) : null,
|
|
449
|
+
options.composerModelPicker ? /* @__PURE__ */ jsx3(ShellPicker, { kind: "model", label: modelLabel }) : null,
|
|
450
|
+
options.composerDictation ? /* @__PURE__ */ jsx3("button", { disabled: true, "aria-label": "Dictate message", className: "ha-dictation", type: "button", children: /* @__PURE__ */ jsx3(Microphone, { "aria-hidden": "true" }) }) : null
|
|
451
|
+
] });
|
|
440
452
|
}
|
|
441
|
-
function
|
|
442
|
-
|
|
443
|
-
|
|
453
|
+
function ShellPicker({
|
|
454
|
+
icon,
|
|
455
|
+
kind,
|
|
456
|
+
label,
|
|
457
|
+
tone
|
|
458
|
+
}) {
|
|
459
|
+
const name = `aui-${kind}-picker`;
|
|
460
|
+
return /* @__PURE__ */ jsx3("div", { className: `${name} ha-${kind}-picker`, "data-tone": tone, children: /* @__PURE__ */ jsxs(
|
|
461
|
+
"button",
|
|
444
462
|
{
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
463
|
+
disabled: true,
|
|
464
|
+
"aria-label": kind === "model" ? "AI model" : "Tool permissions",
|
|
465
|
+
className: `${name}__trigger ha-shell-picker-trigger`,
|
|
466
|
+
type: "button",
|
|
467
|
+
children: [
|
|
468
|
+
icon,
|
|
469
|
+
/* @__PURE__ */ jsx3("span", { className: `${name}__value`, children: label }),
|
|
470
|
+
/* @__PURE__ */ jsx3(ChevronDown, { "aria-hidden": "true", className: `${name}__indicator` })
|
|
471
|
+
]
|
|
450
472
|
}
|
|
451
473
|
) });
|
|
452
474
|
}
|
|
@@ -507,8 +529,8 @@ function loadAgentWebfont(font) {
|
|
|
507
529
|
|
|
508
530
|
// src/embed/provider.tsx
|
|
509
531
|
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
510
|
-
var
|
|
511
|
-
var
|
|
532
|
+
var REMOTE_CONFIG_RESOLUTION_TIMEOUT_MS = 600;
|
|
533
|
+
var REMOTE_CONFIG_PRESENTATION_MAX_AGE_MS = 5 * 6e4;
|
|
512
534
|
var OPEN_STATE_STORAGE_PREFIX = "heroui-agent:open:";
|
|
513
535
|
function openStateStorageKey(agentId) {
|
|
514
536
|
return `${OPEN_STATE_STORAGE_PREFIX}${agentId}`;
|
|
@@ -532,13 +554,24 @@ var embedRuntimePromise;
|
|
|
532
554
|
function loadEmbedRuntime() {
|
|
533
555
|
embedRuntimePromise ??= import(
|
|
534
556
|
/* webpackPrefetch: true */
|
|
535
|
-
"./embed-runtime-
|
|
557
|
+
"./embed-runtime-VVAGDPYY.js"
|
|
536
558
|
).then(
|
|
537
559
|
(module) => module.default
|
|
538
560
|
);
|
|
539
561
|
return embedRuntimePromise;
|
|
540
562
|
}
|
|
541
563
|
var controllers = /* @__PURE__ */ new Map();
|
|
564
|
+
var controllerListeners = /* @__PURE__ */ new Set();
|
|
565
|
+
function getController(agentId) {
|
|
566
|
+
return agentId ? controllers.get(agentId) : [...controllers.values()][controllers.size - 1];
|
|
567
|
+
}
|
|
568
|
+
function notifyControllerListeners() {
|
|
569
|
+
for (const listener of controllerListeners) listener();
|
|
570
|
+
}
|
|
571
|
+
function subscribeToControllers(listener) {
|
|
572
|
+
controllerListeners.add(listener);
|
|
573
|
+
return () => controllerListeners.delete(listener);
|
|
574
|
+
}
|
|
542
575
|
function subscribeToColorScheme(onChange) {
|
|
543
576
|
const media = window.matchMedia?.("(prefers-color-scheme: dark)");
|
|
544
577
|
media?.addEventListener?.("change", onChange);
|
|
@@ -547,68 +580,98 @@ function subscribeToColorScheme(onChange) {
|
|
|
547
580
|
function prefersDarkColorScheme() {
|
|
548
581
|
return window.matchMedia?.("(prefers-color-scheme: dark)").matches === true;
|
|
549
582
|
}
|
|
550
|
-
function dispatch(agentId, method) {
|
|
551
|
-
const controller =
|
|
583
|
+
function dispatch(agentId, method, ...args) {
|
|
584
|
+
const controller = getController(agentId);
|
|
552
585
|
if (!controller) {
|
|
553
586
|
console.warn("HeroUI Agent is not mounted yet. Add <HeroUIAgent /> to your layout.");
|
|
554
587
|
return;
|
|
555
588
|
}
|
|
556
|
-
controller[method]
|
|
589
|
+
const action = controller[method];
|
|
590
|
+
action(...args);
|
|
557
591
|
}
|
|
558
592
|
function useRemoteConfig(agentId, apiBaseUrl, enabled) {
|
|
559
|
-
const [
|
|
560
|
-
if (!enabled || typeof window === "undefined") return
|
|
561
|
-
|
|
562
|
-
|
|
593
|
+
const [cachedSnapshot] = useState(() => {
|
|
594
|
+
if (!enabled || typeof window === "undefined") return null;
|
|
595
|
+
return readCachedRemoteConfigSnapshot(agentId);
|
|
596
|
+
});
|
|
597
|
+
const [state, setState] = useState(() => {
|
|
598
|
+
if (!enabled) return { config: null, presentationReady: true };
|
|
599
|
+
const cacheAge = cachedSnapshot ? Date.now() - cachedSnapshot.cachedAt : Number.POSITIVE_INFINITY;
|
|
600
|
+
const fresh = cachedSnapshot !== null && !cachedSnapshot.legacy && cacheAge >= 0 && cacheAge <= REMOTE_CONFIG_PRESENTATION_MAX_AGE_MS;
|
|
601
|
+
return {
|
|
602
|
+
config: fresh ? cachedSnapshot.config : null,
|
|
603
|
+
presentationReady: fresh
|
|
604
|
+
};
|
|
563
605
|
});
|
|
564
606
|
useEffect2(() => {
|
|
565
607
|
if (!enabled) return;
|
|
566
|
-
const cached = readCachedRemoteConfig(agentId);
|
|
567
608
|
const controller = new AbortController();
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
609
|
+
let active = true;
|
|
610
|
+
const settle = (config) => {
|
|
611
|
+
setState(
|
|
612
|
+
(current) => current.presentationReady ? current : { config, presentationReady: true }
|
|
613
|
+
);
|
|
614
|
+
};
|
|
615
|
+
const budget = window.setTimeout(() => {
|
|
616
|
+
if (!active) return;
|
|
617
|
+
controller.abort();
|
|
618
|
+
settle(cachedSnapshot?.config ?? null);
|
|
619
|
+
}, REMOTE_CONFIG_RESOLUTION_TIMEOUT_MS);
|
|
572
620
|
void fetchRemoteConfig(apiBaseUrl, agentId, {
|
|
573
|
-
...
|
|
621
|
+
...cachedSnapshot?.config.revision ? { revision: cachedSnapshot.config.revision } : {},
|
|
574
622
|
signal: controller.signal
|
|
575
623
|
}).then((result) => {
|
|
576
|
-
if (controller.signal.aborted) return;
|
|
624
|
+
if (!active || controller.signal.aborted) return;
|
|
577
625
|
if (result.status === "ok") {
|
|
578
|
-
setState({ config: result.config, resolved: true });
|
|
579
626
|
writeCachedRemoteConfig(agentId, result.config);
|
|
627
|
+
settle(result.config);
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
if (result.status === "not-modified") {
|
|
631
|
+
if (cachedSnapshot) writeCachedRemoteConfig(agentId, cachedSnapshot.config);
|
|
632
|
+
settle(cachedSnapshot?.config ?? null);
|
|
633
|
+
return;
|
|
580
634
|
}
|
|
581
635
|
if (result.status === "missing") {
|
|
582
|
-
setState({ config: null, resolved: true });
|
|
583
636
|
clearCachedRemoteConfig(agentId);
|
|
637
|
+
settle(null);
|
|
638
|
+
return;
|
|
584
639
|
}
|
|
640
|
+
settle(cachedSnapshot?.config ?? null);
|
|
585
641
|
}).finally(() => {
|
|
586
|
-
if (controller.signal.aborted) return;
|
|
642
|
+
if (!active || controller.signal.aborted) return;
|
|
587
643
|
window.clearTimeout(budget);
|
|
588
|
-
setState((current) => ({ ...current, resolved: true }));
|
|
589
644
|
});
|
|
590
645
|
return () => {
|
|
646
|
+
active = false;
|
|
591
647
|
controller.abort();
|
|
592
648
|
window.clearTimeout(budget);
|
|
593
649
|
};
|
|
594
|
-
}, [apiBaseUrl, enabled, agentId]);
|
|
595
|
-
return enabled ? state : { config: null,
|
|
650
|
+
}, [apiBaseUrl, cachedSnapshot, enabled, agentId]);
|
|
651
|
+
return enabled ? state : { config: null, presentationReady: true };
|
|
596
652
|
}
|
|
597
653
|
function useAgent(agentId) {
|
|
654
|
+
const getReadySnapshot = useCallback(() => getController(agentId)?.ready ?? false, [agentId]);
|
|
655
|
+
const ready = useSyncExternalStore(subscribeToControllers, getReadySnapshot, () => false);
|
|
598
656
|
return useMemo(
|
|
599
657
|
() => ({
|
|
600
658
|
hide: () => dispatch(agentId, "hide"),
|
|
601
|
-
newConversation: () => dispatch(agentId, "newConversation"),
|
|
659
|
+
newConversation: (prompt) => dispatch(agentId, "newConversation", prompt),
|
|
602
660
|
preload: () => dispatch(agentId, "preload"),
|
|
661
|
+
ready,
|
|
603
662
|
refreshAuth: () => dispatch(agentId, "refreshAuth"),
|
|
604
663
|
show: () => dispatch(agentId, "show"),
|
|
605
664
|
shutdown: () => dispatch(agentId, "shutdown"),
|
|
606
665
|
toggle: () => dispatch(agentId, "toggle")
|
|
607
666
|
}),
|
|
608
|
-
[agentId]
|
|
667
|
+
[agentId, ready]
|
|
609
668
|
);
|
|
610
669
|
}
|
|
611
670
|
function HeroUIAgent(props) {
|
|
671
|
+
const remoteSourceKey = `${props.agentId}\0${props._api?.baseUrl ?? ""}\0${props.remoteConfig !== false}`;
|
|
672
|
+
return /* @__PURE__ */ jsx4(HeroUIAgentMount, { ...props }, remoteSourceKey);
|
|
673
|
+
}
|
|
674
|
+
function HeroUIAgentMount(props) {
|
|
612
675
|
const {
|
|
613
676
|
_api,
|
|
614
677
|
agentId,
|
|
@@ -620,6 +683,7 @@ function HeroUIAgent(props) {
|
|
|
620
683
|
getAuthToken,
|
|
621
684
|
markdown,
|
|
622
685
|
onFeedback,
|
|
686
|
+
onReady,
|
|
623
687
|
permissions,
|
|
624
688
|
preload: preloadEnabled,
|
|
625
689
|
remoteConfig: remoteConfigEnabled = true,
|
|
@@ -632,7 +696,7 @@ function HeroUIAgent(props) {
|
|
|
632
696
|
} = props;
|
|
633
697
|
const markdownPlugins = markdown?.plugins;
|
|
634
698
|
const apiBaseUrl = (_api?.baseUrl ?? "https://api.heroui.com").replace(/\/$/, "");
|
|
635
|
-
const { config: remoteConfig,
|
|
699
|
+
const { config: remoteConfig, presentationReady: remoteConfigPresentationReady } = useRemoteConfig(
|
|
636
700
|
agentId,
|
|
637
701
|
apiBaseUrl,
|
|
638
702
|
remoteConfigEnabled
|
|
@@ -668,26 +732,34 @@ function HeroUIAgent(props) {
|
|
|
668
732
|
tools
|
|
669
733
|
});
|
|
670
734
|
}, [context, getAuthToken, markdownPlugins, onFeedback, agentId, serializedConfig, tools]);
|
|
735
|
+
const tokenManager = useMemo(
|
|
736
|
+
() => new EmbedSessionManager(agentId, getAuthToken),
|
|
737
|
+
[agentId, getAuthToken]
|
|
738
|
+
);
|
|
671
739
|
const hostFont = hostSuppliesFont(props);
|
|
672
740
|
const remoteWebfont = remoteConfig?.webfont;
|
|
673
741
|
useEffect2(() => {
|
|
674
742
|
if (hostFont) return;
|
|
675
743
|
return loadAgentWebfont(remoteWebfont);
|
|
676
744
|
}, [hostFont, remoteWebfont]);
|
|
677
|
-
const [restoredOpenState] =
|
|
678
|
-
const [
|
|
679
|
-
const [conversationEpoch, setConversationEpoch] =
|
|
680
|
-
const [identityEpoch, setIdentityEpoch] =
|
|
681
|
-
const [identityReset, setIdentityReset] =
|
|
682
|
-
const [requestedConversationId, setRequestedConversationId] =
|
|
745
|
+
const [restoredOpenState] = useState(() => reopenOnRefresh === true && readOpenState(agentId));
|
|
746
|
+
const [openRequested, setOpenRequested] = useState(restoredOpenState);
|
|
747
|
+
const [conversationEpoch, setConversationEpoch] = useState(1);
|
|
748
|
+
const [identityEpoch, setIdentityEpoch] = useState(1);
|
|
749
|
+
const [identityReset, setIdentityReset] = useState(false);
|
|
750
|
+
const [requestedConversationId, setRequestedConversationId] = useState(
|
|
683
751
|
restoredOpenState || options.startNewConversationOnOpen ? null : void 0
|
|
684
752
|
);
|
|
685
|
-
const [portalRoot, setPortalRoot] =
|
|
686
|
-
const [EmbedRuntime, setEmbedRuntime] =
|
|
753
|
+
const [portalRoot, setPortalRoot] = useState(null);
|
|
754
|
+
const [EmbedRuntime, setEmbedRuntime] = useState(null);
|
|
755
|
+
const [hasCompletedInitialLoad, setHasCompletedInitialLoad] = useState(false);
|
|
756
|
+
const [hasUnreadMessages, setHasUnreadMessages] = useState(false);
|
|
757
|
+
const [runtimeReadyEpoch, setRuntimeReadyEpoch] = useState(null);
|
|
687
758
|
const conversationEpochRef = useRef2(1);
|
|
688
759
|
const launcherRef = useRef2(null);
|
|
760
|
+
const restoreLauncherFocusRef = useRef2(false);
|
|
689
761
|
const portalRootRef = useRef2(null);
|
|
690
|
-
const
|
|
762
|
+
const reportedReadyEpochRef = useRef2(null);
|
|
691
763
|
const shouldOpenRef = useRef2(restoredOpenState);
|
|
692
764
|
const hostRef = useRef2(null);
|
|
693
765
|
const embedReactRootRef = useRef2(null);
|
|
@@ -698,20 +770,39 @@ function HeroUIAgent(props) {
|
|
|
698
770
|
() => false
|
|
699
771
|
);
|
|
700
772
|
const designThemeClass = options.designTheme === "base" ? null : `${options.designTheme}-${options.colorScheme === "system" ? prefersDark ? "dark" : "light" : options.colorScheme}`;
|
|
701
|
-
const
|
|
773
|
+
const ready = remoteConfigPresentationReady && runtimeReadyEpoch === conversationEpoch && EmbedRuntime !== null;
|
|
774
|
+
const isOpen = remoteConfigPresentationReady && openRequested;
|
|
775
|
+
const [shouldLoadRuntime, setShouldLoadRuntime] = useState(restoredOpenState || options.preload);
|
|
702
776
|
const requestRuntime = useCallback(() => setShouldLoadRuntime(true), []);
|
|
703
|
-
const [
|
|
704
|
-
const
|
|
777
|
+
const [composerControlsRevealed, setComposerControlsRevealed] = useState(false);
|
|
778
|
+
const [composerFileDialogActive, setComposerFileDialogActive] = useState(false);
|
|
779
|
+
const revealComposerControls = useCallback(() => setComposerControlsRevealed(true), []);
|
|
705
780
|
useEffect2(() => {
|
|
706
|
-
if (
|
|
707
|
-
|
|
708
|
-
|
|
781
|
+
if (!composerControlsRevealed || !portalRoot) return;
|
|
782
|
+
const reconcileComposerFocus = () => {
|
|
783
|
+
queueMicrotask(() => {
|
|
784
|
+
const composer2 = portalRoot.querySelector(".ha-composer:not([hidden] *)");
|
|
785
|
+
if (composer2 && containsComposerFocus(composer2, document.activeElement)) return;
|
|
786
|
+
setComposerControlsRevealed(false);
|
|
787
|
+
});
|
|
788
|
+
};
|
|
789
|
+
portalRoot.addEventListener("focusout", reconcileComposerFocus);
|
|
790
|
+
return () => portalRoot.removeEventListener("focusout", reconcileComposerFocus);
|
|
791
|
+
}, [composerControlsRevealed, portalRoot]);
|
|
709
792
|
useEffect2(() => {
|
|
710
|
-
if (!
|
|
711
|
-
|
|
712
|
-
}, [
|
|
793
|
+
if (!shouldLoadRuntime) return;
|
|
794
|
+
void tokenManager.get().catch(() => void 0);
|
|
795
|
+
}, [shouldLoadRuntime, tokenManager]);
|
|
796
|
+
useEffect2(() => {
|
|
797
|
+
if (options.reopenOnRefresh) writeOpenState(options.agentId, openRequested);
|
|
798
|
+
else writeOpenState(options.agentId, false);
|
|
799
|
+
}, [openRequested, options.agentId, options.reopenOnRefresh]);
|
|
713
800
|
useEffect2(() => {
|
|
714
801
|
if (!shouldLoadRuntime) return;
|
|
802
|
+
if (!remoteConfigPresentationReady) {
|
|
803
|
+
void loadEmbedRuntime().catch(() => void 0);
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
715
806
|
let active = true;
|
|
716
807
|
void loadEmbedRuntime().then((runtime) => {
|
|
717
808
|
if (active) setEmbedRuntime(() => runtime);
|
|
@@ -719,7 +810,7 @@ function HeroUIAgent(props) {
|
|
|
719
810
|
return () => {
|
|
720
811
|
active = false;
|
|
721
812
|
};
|
|
722
|
-
}, [shouldLoadRuntime]);
|
|
813
|
+
}, [remoteConfigPresentationReady, shouldLoadRuntime]);
|
|
723
814
|
useEffect2(() => {
|
|
724
815
|
if (!isOpen || options.viewMode !== "sidebar") return;
|
|
725
816
|
if (window.innerWidth < 640) return;
|
|
@@ -755,6 +846,7 @@ function HeroUIAgent(props) {
|
|
|
755
846
|
});
|
|
756
847
|
return () => {
|
|
757
848
|
active = false;
|
|
849
|
+
setFocus(options.agentId, false);
|
|
758
850
|
const reactRoot = embedReactRootRef.current;
|
|
759
851
|
portalRootRef.current = null;
|
|
760
852
|
hostRef.current = null;
|
|
@@ -802,6 +894,7 @@ function HeroUIAgent(props) {
|
|
|
802
894
|
designThemeClass,
|
|
803
895
|
isOpen,
|
|
804
896
|
options.colorScheme,
|
|
897
|
+
options.agentId,
|
|
805
898
|
options.launcherOffset,
|
|
806
899
|
options.launcherPosition,
|
|
807
900
|
options.panelStyle,
|
|
@@ -809,43 +902,64 @@ function HeroUIAgent(props) {
|
|
|
809
902
|
options.viewMode,
|
|
810
903
|
portalRoot
|
|
811
904
|
]);
|
|
812
|
-
const prepareNextConversation = useCallback(
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
905
|
+
const prepareNextConversation = useCallback(
|
|
906
|
+
(conversationId) => {
|
|
907
|
+
setFocus(options.agentId, false);
|
|
908
|
+
setComposerFileDialogActive(false);
|
|
909
|
+
setRuntimeReadyEpoch(null);
|
|
910
|
+
setRequestedConversationId(conversationId);
|
|
911
|
+
const nextEpoch = conversationEpochRef.current + 1;
|
|
817
912
|
conversationEpochRef.current = nextEpoch;
|
|
818
|
-
|
|
819
|
-
}
|
|
820
|
-
|
|
913
|
+
setConversationEpoch(nextEpoch);
|
|
914
|
+
},
|
|
915
|
+
[options.agentId]
|
|
916
|
+
);
|
|
821
917
|
const handleRuntimeReady = useCallback((readyEpoch) => {
|
|
822
918
|
if (conversationEpochRef.current !== readyEpoch) return;
|
|
823
|
-
|
|
824
|
-
|
|
919
|
+
setHasCompletedInitialLoad(true);
|
|
920
|
+
setRuntimeReadyEpoch(readyEpoch);
|
|
825
921
|
}, []);
|
|
922
|
+
const emitReady = useEffectEvent(() => onReady?.());
|
|
923
|
+
useEffect2(() => {
|
|
924
|
+
if (!ready || reportedReadyEpochRef.current === conversationEpoch) return;
|
|
925
|
+
reportedReadyEpochRef.current = conversationEpoch;
|
|
926
|
+
emitReady();
|
|
927
|
+
}, [conversationEpoch, ready]);
|
|
826
928
|
const hide = useCallback(() => {
|
|
827
929
|
shouldOpenRef.current = false;
|
|
828
|
-
|
|
930
|
+
restoreLauncherFocusRef.current = true;
|
|
931
|
+
setOpenRequested(false);
|
|
932
|
+
setComposerControlsRevealed(false);
|
|
829
933
|
prepareNextConversation(options.startNewConversationOnOpen ? null : void 0);
|
|
830
|
-
requestAnimationFrame(() => launcherRef.current?.focus());
|
|
831
934
|
}, [options.startNewConversationOnOpen, prepareNextConversation]);
|
|
935
|
+
useEffect2(() => {
|
|
936
|
+
if (isOpen || !ready || !restoreLauncherFocusRef.current) return;
|
|
937
|
+
restoreLauncherFocusRef.current = false;
|
|
938
|
+
requestAnimationFrame(() => launcherRef.current?.focus());
|
|
939
|
+
}, [isOpen, ready]);
|
|
832
940
|
const show = useCallback(() => {
|
|
833
941
|
shouldOpenRef.current = true;
|
|
834
|
-
|
|
835
|
-
setIsOpen(true);
|
|
836
|
-
}, [requestRuntime]);
|
|
837
|
-
const preload = useCallback(() => {
|
|
838
|
-
setPreloadRequested(true);
|
|
942
|
+
setOpenRequested(true);
|
|
839
943
|
requestRuntime();
|
|
840
944
|
}, [requestRuntime]);
|
|
841
|
-
const
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
945
|
+
const preload = requestRuntime;
|
|
946
|
+
const newConversation = useCallback(
|
|
947
|
+
(prompt) => {
|
|
948
|
+
const submission = prompt ? createSubmittedAgentShellHandoff(prompt) : null;
|
|
949
|
+
if (submission) writeAgentShellHandoff(options.agentId, submission);
|
|
950
|
+
shouldOpenRef.current = true;
|
|
951
|
+
setOpenRequested(true);
|
|
952
|
+
setComposerControlsRevealed(false);
|
|
953
|
+
requestRuntime();
|
|
954
|
+
prepareNextConversation(null);
|
|
955
|
+
},
|
|
956
|
+
[options.agentId, prepareNextConversation, requestRuntime]
|
|
957
|
+
);
|
|
846
958
|
const selectConversation = useCallback(
|
|
847
959
|
(conversationId) => {
|
|
848
960
|
shouldOpenRef.current = true;
|
|
961
|
+
setOpenRequested(true);
|
|
962
|
+
setComposerControlsRevealed(false);
|
|
849
963
|
requestRuntime();
|
|
850
964
|
prepareNextConversation(conversationId);
|
|
851
965
|
},
|
|
@@ -856,6 +970,7 @@ function HeroUIAgent(props) {
|
|
|
856
970
|
else show();
|
|
857
971
|
}, [hide, isOpen, show]);
|
|
858
972
|
const refreshAuth = useCallback(() => {
|
|
973
|
+
setHasUnreadMessages(false);
|
|
859
974
|
setIdentityReset(false);
|
|
860
975
|
setIdentityEpoch((epoch) => epoch + 1);
|
|
861
976
|
}, []);
|
|
@@ -863,21 +978,24 @@ function HeroUIAgent(props) {
|
|
|
863
978
|
const prefixes = [
|
|
864
979
|
`heroui-agent:anonymous:${options.agentId}`,
|
|
865
980
|
`heroui-agent:conversation:${options.agentId}:`,
|
|
866
|
-
`heroui-agent:history:${options.agentId}
|
|
867
|
-
`heroui-agent:session:${options.agentId}:`
|
|
981
|
+
`heroui-agent:history:${options.agentId}:`
|
|
868
982
|
];
|
|
869
983
|
for (let index = localStorage.length - 1; index >= 0; index -= 1) {
|
|
870
984
|
const key = localStorage.key(index);
|
|
871
985
|
if (key && prefixes.some((prefix) => key.startsWith(prefix))) localStorage.removeItem(key);
|
|
872
986
|
}
|
|
873
987
|
shouldOpenRef.current = false;
|
|
874
|
-
|
|
988
|
+
setHasUnreadMessages(false);
|
|
989
|
+
setOpenRequested(false);
|
|
990
|
+
setComposerControlsRevealed(false);
|
|
875
991
|
writeOpenState(options.agentId, false);
|
|
876
992
|
setIdentityReset(true);
|
|
877
993
|
setIdentityEpoch((epoch) => epoch + 1);
|
|
878
994
|
prepareNextConversation();
|
|
879
995
|
window.setTimeout(() => {
|
|
880
|
-
void
|
|
996
|
+
void import("./composer-draft-DTQAEO5K.js").then(
|
|
997
|
+
({ clearAgentComposerDraftsForProject }) => clearAgentComposerDraftsForProject(options.agentId)
|
|
998
|
+
).catch(() => void 0);
|
|
881
999
|
}, 0);
|
|
882
1000
|
}, [options.agentId, prepareNextConversation]);
|
|
883
1001
|
useEffect2(() => {
|
|
@@ -885,53 +1003,68 @@ function HeroUIAgent(props) {
|
|
|
885
1003
|
hide,
|
|
886
1004
|
newConversation,
|
|
887
1005
|
preload,
|
|
1006
|
+
ready,
|
|
888
1007
|
refreshAuth,
|
|
889
1008
|
show,
|
|
890
1009
|
shutdown,
|
|
891
1010
|
toggle
|
|
892
1011
|
};
|
|
893
1012
|
controllers.set(options.agentId, controller);
|
|
1013
|
+
notifyControllerListeners();
|
|
894
1014
|
return () => {
|
|
895
1015
|
if (controllers.get(options.agentId) === controller) {
|
|
896
1016
|
controllers.delete(options.agentId);
|
|
1017
|
+
notifyControllerListeners();
|
|
897
1018
|
}
|
|
898
1019
|
};
|
|
899
|
-
}, [hide, newConversation, options.agentId, preload, refreshAuth, show, shutdown, toggle]);
|
|
1020
|
+
}, [hide, newConversation, options.agentId, preload, ready, refreshAuth, show, shutdown, toggle]);
|
|
900
1021
|
useLayoutEffect(() => {
|
|
901
1022
|
const reactRoot = embedReactRootRef.current;
|
|
902
1023
|
if (!portalRoot || !reactRoot) return;
|
|
1024
|
+
const shellComposer = createShellComposerPresentation({
|
|
1025
|
+
onFileDialogActiveChange: setComposerFileDialogActive,
|
|
1026
|
+
onIntent: requestRuntime,
|
|
1027
|
+
options
|
|
1028
|
+
});
|
|
903
1029
|
reactRoot.render(
|
|
904
1030
|
/* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
905
|
-
options.showLauncher &&
|
|
1031
|
+
remoteConfigPresentationReady && options.showLauncher && !isOpen ? /* @__PURE__ */ jsxs2(
|
|
906
1032
|
"button",
|
|
907
1033
|
{
|
|
908
1034
|
ref: launcherRef,
|
|
909
1035
|
"aria-expanded": false,
|
|
910
1036
|
"aria-haspopup": "dialog",
|
|
911
|
-
"aria-label": "Open data assistant",
|
|
912
1037
|
className: "ha-launcher",
|
|
913
1038
|
style: options.launcherStyle,
|
|
914
1039
|
type: "button",
|
|
1040
|
+
"aria-label": hasUnreadMessages ? "Open data assistant, unread messages" : "Open data assistant",
|
|
915
1041
|
onClick: show,
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
1042
|
+
children: [
|
|
1043
|
+
/* @__PURE__ */ jsx4(LauncherIcon, { icon: options.launcherIcon }),
|
|
1044
|
+
hasUnreadMessages ? /* @__PURE__ */ jsx4("span", { "aria-hidden": "true", className: "ha-launcher__unread" }) : null
|
|
1045
|
+
]
|
|
919
1046
|
}
|
|
920
1047
|
) : null,
|
|
921
|
-
EmbedRuntime ? /* @__PURE__ */ jsx4(
|
|
1048
|
+
EmbedRuntime && !composerFileDialogActive ? /* @__PURE__ */ jsx4(
|
|
922
1049
|
EmbedRuntime,
|
|
923
1050
|
{
|
|
1051
|
+
composerControlsRevealed,
|
|
924
1052
|
conversationEpoch,
|
|
925
1053
|
identityEpoch,
|
|
926
1054
|
identityReset,
|
|
927
1055
|
open: isOpen,
|
|
928
1056
|
options,
|
|
929
1057
|
requestedConversationId,
|
|
930
|
-
|
|
1058
|
+
shellComposerEndSlot: shellComposer.end,
|
|
1059
|
+
shellComposerFooterSlot: shellComposer.footer,
|
|
1060
|
+
showReadyLoader: !hasCompletedInitialLoad && requestedConversationId !== null,
|
|
1061
|
+
tokenManager,
|
|
931
1062
|
onClose: hide,
|
|
1063
|
+
onComposerControlsReveal: revealComposerControls,
|
|
932
1064
|
onNewConversation: newConversation,
|
|
933
1065
|
onReady: handleRuntimeReady,
|
|
934
|
-
onSelectConversation: selectConversation
|
|
1066
|
+
onSelectConversation: selectConversation,
|
|
1067
|
+
onUnreadChange: setHasUnreadMessages
|
|
935
1068
|
}
|
|
936
1069
|
) : /* @__PURE__ */ jsx4(
|
|
937
1070
|
PanelShell,
|
|
@@ -939,28 +1072,41 @@ function HeroUIAgent(props) {
|
|
|
939
1072
|
agentId: options.agentId,
|
|
940
1073
|
defaultExpanded: options.panelExpanded,
|
|
941
1074
|
expandable: options.panelExpandable,
|
|
1075
|
+
historySlot: /* @__PURE__ */ jsx4(Fragment2, {}),
|
|
942
1076
|
modal: options.viewMode !== "sidebar",
|
|
943
1077
|
name: "Data assistant",
|
|
944
1078
|
open: isOpen,
|
|
945
1079
|
onClose: hide,
|
|
946
|
-
children: /* @__PURE__ */ jsx4(
|
|
1080
|
+
children: requestedConversationId === null ? /* @__PURE__ */ jsx4(
|
|
947
1081
|
ShellConversation,
|
|
948
1082
|
{
|
|
1083
|
+
composerConnecting: true,
|
|
949
1084
|
agentId: options.agentId,
|
|
1085
|
+
composerControlsAvailable: options.composerControlsAvailable,
|
|
1086
|
+
composerControlsRevealed,
|
|
1087
|
+
composerEndSlot: shellComposer.end,
|
|
1088
|
+
composerFooterSlot: shellComposer.footer,
|
|
1089
|
+
composerStartSlot: shellComposer.start,
|
|
950
1090
|
greeting: options.greeting,
|
|
951
1091
|
placeholder: options.composerPlaceholder,
|
|
952
1092
|
suggestedPrompts: options.suggestedPrompts ?? [],
|
|
1093
|
+
onComposerControlsReveal: revealComposerControls,
|
|
953
1094
|
onIntent: requestRuntime
|
|
954
|
-
}
|
|
955
|
-
|
|
1095
|
+
},
|
|
1096
|
+
`shell-${conversationEpoch}`
|
|
1097
|
+
) : /* @__PURE__ */ jsx4(AgentLoadingState, {})
|
|
956
1098
|
}
|
|
957
1099
|
)
|
|
958
1100
|
] })
|
|
959
1101
|
);
|
|
960
1102
|
}, [
|
|
961
1103
|
EmbedRuntime,
|
|
1104
|
+
composerControlsRevealed,
|
|
1105
|
+
composerFileDialogActive,
|
|
962
1106
|
conversationEpoch,
|
|
963
1107
|
handleRuntimeReady,
|
|
1108
|
+
hasUnreadMessages,
|
|
1109
|
+
hasCompletedInitialLoad,
|
|
964
1110
|
hide,
|
|
965
1111
|
identityEpoch,
|
|
966
1112
|
identityReset,
|
|
@@ -968,12 +1114,14 @@ function HeroUIAgent(props) {
|
|
|
968
1114
|
newConversation,
|
|
969
1115
|
options,
|
|
970
1116
|
portalRoot,
|
|
971
|
-
|
|
972
|
-
|
|
1117
|
+
ready,
|
|
1118
|
+
remoteConfigPresentationReady,
|
|
973
1119
|
requestedConversationId,
|
|
1120
|
+
requestRuntime,
|
|
1121
|
+
revealComposerControls,
|
|
974
1122
|
selectConversation,
|
|
975
|
-
|
|
976
|
-
|
|
1123
|
+
show,
|
|
1124
|
+
tokenManager
|
|
977
1125
|
]);
|
|
978
1126
|
return null;
|
|
979
1127
|
}
|