@heroui/agent 0.2.0-beta.5 → 0.2.0-beta.7
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 +18 -0
- package/README.md +7 -2
- package/dist/{chart-content-7PZT4YWI.js → chart-content-E4NPTUPR.js} +1 -1
- package/dist/{chunk-XBYPU7PM.js → chunk-OQGXZY5L.js} +10 -4
- package/dist/{chunk-UUHEF6LC.js → chunk-V5S5FRGV.js} +3 -2
- package/dist/{component-renderer-PTMCOJHE.js → component-renderer-46EJDPTB.js} +2103 -1619
- package/dist/contracts.d.ts +4 -3
- package/dist/contracts.js +8 -2
- package/dist/css/index.css +1 -1
- package/dist/{embed-runtime-36S6KLDB.js → embed-runtime-UF7XJIFA.js} +535 -315
- package/dist/{identity-CuhZgpvp.d.ts → identity-Z6i6pL0F.d.ts} +2 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.js +2 -2
- package/dist/next.js +2 -2
- package/dist/server.d.ts +1 -1
- package/dist/server.js +7 -2
- package/package.json +2 -2
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
shouldRestoreActiveAgentPermissionMode,
|
|
34
34
|
storeAgentPermissionMode,
|
|
35
35
|
takeAgentShellHandoff
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-OQGXZY5L.js";
|
|
37
37
|
import {
|
|
38
38
|
ActionButton,
|
|
39
39
|
CodeBlock,
|
|
@@ -1725,8 +1725,8 @@ import {
|
|
|
1725
1725
|
useEffectEvent,
|
|
1726
1726
|
useLayoutEffect as useLayoutEffect4,
|
|
1727
1727
|
useMemo as useMemo4,
|
|
1728
|
-
useRef as
|
|
1729
|
-
useState as
|
|
1728
|
+
useRef as useRef14,
|
|
1729
|
+
useState as useState15
|
|
1730
1730
|
} from "react";
|
|
1731
1731
|
|
|
1732
1732
|
// src/contracts/identity.ts
|
|
@@ -1777,7 +1777,7 @@ var agentModelIdSchema = z2.preprocess(
|
|
|
1777
1777
|
|
|
1778
1778
|
// src/contracts/version.ts
|
|
1779
1779
|
var HEROUI_AGENT_PROTOCOL_VERSION = 5;
|
|
1780
|
-
var HEROUI_AGENT_SDK_VERSION = "0.2.0-beta.
|
|
1780
|
+
var HEROUI_AGENT_SDK_VERSION = "0.2.0-beta.7";
|
|
1781
1781
|
var HEROUI_AGENT_TASK_ID = "heroui-agents-runtime";
|
|
1782
1782
|
|
|
1783
1783
|
// src/contracts/identity.ts
|
|
@@ -1875,6 +1875,11 @@ var trustedAgentClientDataSchema = z3.object({
|
|
|
1875
1875
|
* fixed agent allowlist and signs the value before the runtime sees it.
|
|
1876
1876
|
*/
|
|
1877
1877
|
modelId: agentModelIdSchema.optional(),
|
|
1878
|
+
/**
|
|
1879
|
+
* When web search is enabled, allow recent news results via `includeNews`.
|
|
1880
|
+
* Optional and disabled when omitted so older signed payloads remain valid.
|
|
1881
|
+
*/
|
|
1882
|
+
newsSearch: z3.boolean().optional(),
|
|
1878
1883
|
pageContext: pageContextSchema.default({}),
|
|
1879
1884
|
/**
|
|
1880
1885
|
* Set by the API when the session was authorized by a dashboard preview
|
|
@@ -1891,7 +1896,7 @@ var trustedAgentClientDataSchema = z3.object({
|
|
|
1891
1896
|
/**
|
|
1892
1897
|
* Host-enabled public web search. When true the runtime registers the
|
|
1893
1898
|
* `searchWeb` tool (if the search backend is configured) so the agent can
|
|
1894
|
-
* look up public information and
|
|
1899
|
+
* look up public information, images, and optionally news. Optional (not defaulted) so schema
|
|
1895
1900
|
* parsing never injects a field into an already-signed payload.
|
|
1896
1901
|
*/
|
|
1897
1902
|
webSearch: z3.boolean().optional()
|
|
@@ -1952,6 +1957,14 @@ function inferActivityKind(label) {
|
|
|
1952
1957
|
if (/data|query|load|fetch|metric|table|account/.test(normalized)) return "data";
|
|
1953
1958
|
return "thinking";
|
|
1954
1959
|
}
|
|
1960
|
+
function hasResponseAfterLatestActivity(items, options) {
|
|
1961
|
+
if (!options.hasContent) return false;
|
|
1962
|
+
const latestActivityPartIndex = items.reduce(
|
|
1963
|
+
(latest, item) => Math.max(latest, item.messagePartIndex ?? -1),
|
|
1964
|
+
-1
|
|
1965
|
+
);
|
|
1966
|
+
return options.latestContentPartIndex >= latestActivityPartIndex;
|
|
1967
|
+
}
|
|
1955
1968
|
function collectActivity(message, clientTools, options = {}) {
|
|
1956
1969
|
if (message.role !== "assistant") return [];
|
|
1957
1970
|
const items = [];
|
|
@@ -1967,7 +1980,9 @@ function collectActivity(message, clientTools, options = {}) {
|
|
|
1967
1980
|
id: part.id ?? `${message.id}-activity-${index}`,
|
|
1968
1981
|
kind: part.data.kind ?? inferActivityKind(label2),
|
|
1969
1982
|
label: label2,
|
|
1970
|
-
|
|
1983
|
+
messagePartIndex: index,
|
|
1984
|
+
sources: part.data.sources,
|
|
1985
|
+
stateKnown: false
|
|
1971
1986
|
});
|
|
1972
1987
|
}
|
|
1973
1988
|
continue;
|
|
@@ -1988,16 +2003,38 @@ function collectActivity(message, clientTools, options = {}) {
|
|
|
1988
2003
|
toolPart.output && typeof toolPart.output === "object" && "rejected" in toolPart.output && toolPart.output.rejected
|
|
1989
2004
|
);
|
|
1990
2005
|
const label = rejected ? `Skipped ${baseLabel}` : toolPart.state === "output-error" ? `Couldn\u2019t complete ${baseLabel}` : baseLabel;
|
|
1991
|
-
|
|
2006
|
+
const active = toolPart.state === "input-available" || toolPart.state === "input-streaming";
|
|
2007
|
+
const existingIndex = items.findIndex((item) => item.label === label);
|
|
2008
|
+
if (existingIndex >= 0) {
|
|
2009
|
+
const existing = items[existingIndex];
|
|
2010
|
+
if (existing) {
|
|
2011
|
+
items[existingIndex] = {
|
|
2012
|
+
...existing,
|
|
2013
|
+
active,
|
|
2014
|
+
messagePartIndex: index,
|
|
2015
|
+
stateKnown: true
|
|
2016
|
+
};
|
|
2017
|
+
}
|
|
2018
|
+
continue;
|
|
2019
|
+
}
|
|
1992
2020
|
labels.add(label);
|
|
1993
2021
|
items.push({
|
|
1994
|
-
active
|
|
2022
|
+
active,
|
|
1995
2023
|
id: toolPart.toolCallId || `${message.id}-tool-${index}`,
|
|
1996
2024
|
kind: renderTool ? "chart" : toolName === "executeSandbox" ? "code" : toolName === "getComponentSchema" ? "thinking" : inferActivityKind(label),
|
|
1997
|
-
label
|
|
2025
|
+
label,
|
|
2026
|
+
messagePartIndex: index,
|
|
2027
|
+
stateKnown: true
|
|
1998
2028
|
});
|
|
1999
2029
|
}
|
|
2000
|
-
return items;
|
|
2030
|
+
if (!options.isStreaming || items.length === 0) return items;
|
|
2031
|
+
if (items.some((item) => item.active)) return items;
|
|
2032
|
+
const activeIndex = items.length - 1;
|
|
2033
|
+
if (items[activeIndex]?.stateKnown) return items;
|
|
2034
|
+
return items.map((item, index) => ({
|
|
2035
|
+
...item,
|
|
2036
|
+
active: index === activeIndex
|
|
2037
|
+
}));
|
|
2001
2038
|
}
|
|
2002
2039
|
|
|
2003
2040
|
// src/embed/activity-trail.tsx
|
|
@@ -2011,10 +2048,10 @@ import {
|
|
|
2011
2048
|
Wrench
|
|
2012
2049
|
} from "@gravity-ui/icons";
|
|
2013
2050
|
import { Disclosure as Disclosure2 } from "@heroui/react";
|
|
2014
|
-
import { useEffect as useEffect7, useRef as
|
|
2051
|
+
import { useEffect as useEffect7, useRef as useRef5, useState as useState5 } from "react";
|
|
2015
2052
|
|
|
2016
2053
|
// src/embed/animated-status-text.tsx
|
|
2017
|
-
import { useEffect as useEffect5,
|
|
2054
|
+
import { useEffect as useEffect5, useState as useState4 } from "react";
|
|
2018
2055
|
|
|
2019
2056
|
// src/embed/shimmer-text.tsx
|
|
2020
2057
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
@@ -2023,35 +2060,64 @@ function ShimmerText({ children, className, ...props }) {
|
|
|
2023
2060
|
}
|
|
2024
2061
|
|
|
2025
2062
|
// src/embed/animated-status-text.tsx
|
|
2026
|
-
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
2063
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2064
|
+
var STATUS_SWAP_MS = 280;
|
|
2027
2065
|
function AnimatedStatusText({
|
|
2028
2066
|
animateOnMount = true,
|
|
2029
2067
|
children,
|
|
2030
2068
|
className,
|
|
2031
2069
|
...props
|
|
2032
2070
|
}) {
|
|
2033
|
-
const
|
|
2034
|
-
|
|
2071
|
+
const [transition, setTransition] = useState4(() => ({
|
|
2072
|
+
current: { animate: animateOnMount, id: 0, text: children },
|
|
2073
|
+
previous: null
|
|
2074
|
+
}));
|
|
2075
|
+
if (transition.current.text !== children) {
|
|
2076
|
+
setTransition({
|
|
2077
|
+
current: { animate: true, id: transition.current.id + 1, text: children },
|
|
2078
|
+
previous: transition.current
|
|
2079
|
+
});
|
|
2080
|
+
}
|
|
2081
|
+
const currentId = transition.current.id;
|
|
2082
|
+
const previous = transition.previous;
|
|
2035
2083
|
useEffect5(() => {
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2084
|
+
if (!previous) return;
|
|
2085
|
+
const timer = window.setTimeout(() => {
|
|
2086
|
+
setTransition(
|
|
2087
|
+
(current) => current.current.id === currentId ? { ...current, previous: null } : current
|
|
2088
|
+
);
|
|
2089
|
+
}, STATUS_SWAP_MS);
|
|
2090
|
+
return () => window.clearTimeout(timer);
|
|
2091
|
+
}, [currentId, previous]);
|
|
2092
|
+
return /* @__PURE__ */ jsxs5(
|
|
2039
2093
|
"span",
|
|
2040
2094
|
{
|
|
2041
2095
|
...props,
|
|
2042
2096
|
"aria-label": props["aria-label"] ?? children,
|
|
2043
2097
|
className: `ha-status-text${className ? ` ${className}` : ""}`,
|
|
2044
2098
|
"data-slot": "animated-text",
|
|
2045
|
-
children:
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2099
|
+
children: [
|
|
2100
|
+
/* @__PURE__ */ jsx7(
|
|
2101
|
+
"span",
|
|
2102
|
+
{
|
|
2103
|
+
"aria-hidden": "true",
|
|
2104
|
+
"data-slot": "animated-text-value",
|
|
2105
|
+
className: transition.current.animate ? "ha-status-text__value ha-status-text__value--animated" : "ha-status-text__value",
|
|
2106
|
+
children: /* @__PURE__ */ jsx7(ShimmerText, { children: transition.current.text })
|
|
2107
|
+
},
|
|
2108
|
+
transition.current.id
|
|
2109
|
+
),
|
|
2110
|
+
transition.previous ? /* @__PURE__ */ jsx7(
|
|
2111
|
+
"span",
|
|
2112
|
+
{
|
|
2113
|
+
"aria-hidden": "true",
|
|
2114
|
+
className: "ha-status-text__value ha-status-text__value--exiting",
|
|
2115
|
+
"data-slot": "animated-text-previous-value",
|
|
2116
|
+
children: /* @__PURE__ */ jsx7(ShimmerText, { children: transition.previous.text })
|
|
2117
|
+
},
|
|
2118
|
+
transition.previous.id
|
|
2119
|
+
) : null
|
|
2120
|
+
]
|
|
2055
2121
|
}
|
|
2056
2122
|
);
|
|
2057
2123
|
}
|
|
@@ -2111,25 +2177,87 @@ function useScrollShadow(ref, offset = 1) {
|
|
|
2111
2177
|
}
|
|
2112
2178
|
|
|
2113
2179
|
// src/embed/activity-trail.tsx
|
|
2114
|
-
import { jsx as jsx8, jsxs as
|
|
2180
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2115
2181
|
var FOLLOW_THRESHOLD_PX = 24;
|
|
2116
|
-
|
|
2117
|
-
|
|
2182
|
+
var ACTIVITY_FADE_MS = 160;
|
|
2183
|
+
var ACTIVITY_COLLAPSE_MS = 220;
|
|
2184
|
+
function useFollowNewestStep(ref, contentVersion, isStreaming, isExpanded) {
|
|
2185
|
+
const isFollowingRef = useRef5(true);
|
|
2118
2186
|
useEffect7(() => {
|
|
2119
2187
|
const element = ref.current;
|
|
2120
2188
|
if (!element) return;
|
|
2121
|
-
|
|
2189
|
+
let autoScrollTimer;
|
|
2190
|
+
let isAutoScrolling = false;
|
|
2191
|
+
const updateFollowing = () => {
|
|
2122
2192
|
const distanceFromBottom = element.scrollHeight - element.scrollTop - element.clientHeight;
|
|
2123
2193
|
isFollowingRef.current = distanceFromBottom <= FOLLOW_THRESHOLD_PX;
|
|
2124
2194
|
};
|
|
2195
|
+
const handleScroll = () => {
|
|
2196
|
+
if (isAutoScrolling) return;
|
|
2197
|
+
updateFollowing();
|
|
2198
|
+
};
|
|
2199
|
+
const handleUserScrollIntent = () => {
|
|
2200
|
+
isAutoScrolling = false;
|
|
2201
|
+
window.clearTimeout(autoScrollTimer);
|
|
2202
|
+
requestAnimationFrame(updateFollowing);
|
|
2203
|
+
};
|
|
2204
|
+
const followNewest = () => {
|
|
2205
|
+
if (!isExpanded || !isStreaming || !isFollowingRef.current) return;
|
|
2206
|
+
const shouldReduceMotion = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
2207
|
+
const top = element.scrollHeight;
|
|
2208
|
+
if (typeof element.scrollTo !== "function") {
|
|
2209
|
+
element.scrollTop = top;
|
|
2210
|
+
return;
|
|
2211
|
+
}
|
|
2212
|
+
isAutoScrolling = !shouldReduceMotion;
|
|
2213
|
+
element.scrollTo({ behavior: shouldReduceMotion ? "auto" : "smooth", top });
|
|
2214
|
+
window.clearTimeout(autoScrollTimer);
|
|
2215
|
+
autoScrollTimer = window.setTimeout(() => {
|
|
2216
|
+
isAutoScrolling = false;
|
|
2217
|
+
updateFollowing();
|
|
2218
|
+
}, 360);
|
|
2219
|
+
};
|
|
2125
2220
|
element.addEventListener("scroll", handleScroll, { passive: true });
|
|
2126
|
-
|
|
2127
|
-
|
|
2221
|
+
element.addEventListener("pointerdown", handleUserScrollIntent, { passive: true });
|
|
2222
|
+
element.addEventListener("touchstart", handleUserScrollIntent, { passive: true });
|
|
2223
|
+
element.addEventListener("wheel", handleUserScrollIntent, { passive: true });
|
|
2224
|
+
followNewest();
|
|
2225
|
+
const list = element.querySelector("ol");
|
|
2226
|
+
const resizeObserver = list && typeof ResizeObserver !== "undefined" ? new ResizeObserver(followNewest) : null;
|
|
2227
|
+
if (list) resizeObserver?.observe(list);
|
|
2228
|
+
return () => {
|
|
2229
|
+
element.removeEventListener("scroll", handleScroll);
|
|
2230
|
+
element.removeEventListener("pointerdown", handleUserScrollIntent);
|
|
2231
|
+
element.removeEventListener("touchstart", handleUserScrollIntent);
|
|
2232
|
+
element.removeEventListener("wheel", handleUserScrollIntent);
|
|
2233
|
+
resizeObserver?.disconnect();
|
|
2234
|
+
window.clearTimeout(autoScrollTimer);
|
|
2235
|
+
};
|
|
2236
|
+
}, [contentVersion, isExpanded, isStreaming, ref]);
|
|
2237
|
+
}
|
|
2238
|
+
function useActivityPhase(isStreaming) {
|
|
2239
|
+
const [phaseState, setPhaseState] = useState5(() => ({
|
|
2240
|
+
isStreaming,
|
|
2241
|
+
phase: isStreaming ? "expanded" : "collapsed"
|
|
2242
|
+
}));
|
|
2243
|
+
let phase = phaseState.phase;
|
|
2244
|
+
if (phaseState.isStreaming !== isStreaming) {
|
|
2245
|
+
phase = isStreaming ? "expanded" : "fading";
|
|
2246
|
+
setPhaseState({ isStreaming, phase });
|
|
2247
|
+
}
|
|
2128
2248
|
useEffect7(() => {
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2249
|
+
if (isStreaming || phase === "collapsed" || phase === "expanded") return;
|
|
2250
|
+
const shouldReduceMotion = typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
2251
|
+
const nextPhase = shouldReduceMotion ? "collapsed" : phase === "fading" ? "collapsing" : "collapsed";
|
|
2252
|
+
const delay = shouldReduceMotion ? 0 : phase === "fading" ? ACTIVITY_FADE_MS : ACTIVITY_COLLAPSE_MS;
|
|
2253
|
+
const timer = window.setTimeout(() => {
|
|
2254
|
+
setPhaseState(
|
|
2255
|
+
(current) => current.isStreaming === isStreaming && current.phase === phase ? { ...current, phase: nextPhase } : current
|
|
2256
|
+
);
|
|
2257
|
+
}, delay);
|
|
2258
|
+
return () => window.clearTimeout(timer);
|
|
2259
|
+
}, [isStreaming, phase]);
|
|
2260
|
+
return phase;
|
|
2133
2261
|
}
|
|
2134
2262
|
var activityIcons = {
|
|
2135
2263
|
browse: Globe,
|
|
@@ -2139,6 +2267,12 @@ var activityIcons = {
|
|
|
2139
2267
|
search: Magnifier,
|
|
2140
2268
|
thinking: Wrench
|
|
2141
2269
|
};
|
|
2270
|
+
function ActivityStateIcon({ active }) {
|
|
2271
|
+
return /* @__PURE__ */ jsxs6("span", { className: "ha-activity-icon", "data-state": active ? "active" : "complete", children: [
|
|
2272
|
+
/* @__PURE__ */ jsx8("span", { "aria-hidden": "true", className: "ha-activity-icon-state ha-activity-icon-state--active", children: /* @__PURE__ */ jsx8("span", { className: "ha-activity-spinner" }) }),
|
|
2273
|
+
/* @__PURE__ */ jsx8("span", { "aria-hidden": "true", className: "ha-activity-icon-state ha-activity-icon-state--complete", children: /* @__PURE__ */ jsx8(CircleCheck, {}) })
|
|
2274
|
+
] });
|
|
2275
|
+
}
|
|
2142
2276
|
function formatActivityDuration(durationMs) {
|
|
2143
2277
|
const totalSeconds = Math.max(1, Math.round(durationMs / 1e3));
|
|
2144
2278
|
const hours = Math.floor(totalSeconds / 3600);
|
|
@@ -2154,63 +2288,101 @@ function ActivityStatus({ ariaLabel, label }) {
|
|
|
2154
2288
|
function ActivityTrail({
|
|
2155
2289
|
completedAt,
|
|
2156
2290
|
defaultOpen = false,
|
|
2291
|
+
hasResponseStarted = false,
|
|
2157
2292
|
isStreaming,
|
|
2158
2293
|
items,
|
|
2159
2294
|
progress,
|
|
2160
2295
|
startedAt
|
|
2161
2296
|
}) {
|
|
2162
|
-
const
|
|
2163
|
-
const
|
|
2164
|
-
const
|
|
2165
|
-
const
|
|
2166
|
-
const
|
|
2167
|
-
const
|
|
2168
|
-
const
|
|
2297
|
+
const isActivityStreaming = isStreaming && !hasResponseStarted;
|
|
2298
|
+
const phase = useActivityPhase(isActivityStreaming);
|
|
2299
|
+
const [expandedOverride, setExpandedOverride] = useState5(null);
|
|
2300
|
+
const panelRef = useRef5(null);
|
|
2301
|
+
const activityStoppedAtRef = useRef5(null);
|
|
2302
|
+
const requestedActiveIndex = items.findLastIndex((item) => item.active);
|
|
2303
|
+
const fallbackActiveIndex = items.at(-1)?.stateKnown ? -1 : items.length - 1;
|
|
2304
|
+
const activeIndex = isActivityStreaming ? requestedActiveIndex >= 0 ? requestedActiveIndex : fallbackActiveIndex : -1;
|
|
2305
|
+
const visibleItems = items.map((item, index) => ({
|
|
2306
|
+
...item,
|
|
2307
|
+
active: index === activeIndex
|
|
2308
|
+
}));
|
|
2309
|
+
const activeItem = activeIndex >= 0 ? visibleItems[activeIndex] : void 0;
|
|
2310
|
+
const latestItem = visibleItems.at(-1);
|
|
2311
|
+
const liveSummary = progress ?? activeItem?.label ?? latestItem?.label ?? "Understanding your request\u2026";
|
|
2312
|
+
const isAutoSettling = expandedOverride === null && !defaultOpen && !isActivityStreaming && (phase === "fading" || phase === "collapsing");
|
|
2313
|
+
const autoExpanded = defaultOpen || phase === "expanded" || phase === "fading";
|
|
2314
|
+
const isExpanded = expandedOverride ?? autoExpanded;
|
|
2315
|
+
const visualPhase = expandedOverride !== null || defaultOpen ? isExpanded ? "expanded" : "collapsed" : phase;
|
|
2316
|
+
useEffect7(() => {
|
|
2317
|
+
if (!isStreaming) return;
|
|
2318
|
+
if (!hasResponseStarted) {
|
|
2319
|
+
activityStoppedAtRef.current = null;
|
|
2320
|
+
return;
|
|
2321
|
+
}
|
|
2322
|
+
activityStoppedAtRef.current ??= Date.now();
|
|
2323
|
+
}, [hasResponseStarted, isStreaming]);
|
|
2324
|
+
const elapsedMs = startedAt !== void 0 && !isActivityStreaming ? Math.max(0, (activityStoppedAtRef.current ?? completedAt ?? Date.now()) - startedAt) : null;
|
|
2325
|
+
const completedSummary = elapsedMs === null ? "Activity" : `Worked for ${formatActivityDuration(elapsedMs)}`;
|
|
2326
|
+
const summary = isActivityStreaming || isAutoSettling ? liveSummary : elapsedMs === null ? "Activity" : completedSummary;
|
|
2327
|
+
const summaryItem = activeItem ?? latestItem;
|
|
2328
|
+
const summaryKind = summaryItem?.kind ?? inferActivityKind(summaryItem?.label ?? liveSummary);
|
|
2329
|
+
const SummaryIcon = activityIcons[summaryKind];
|
|
2330
|
+
const contentVersion = visibleItems.map(
|
|
2331
|
+
(item) => `${item.id}:${item.active ? 1 : 0}:${item.detail ?? ""}:${item.sources?.map((source) => source.label).join(",")}`
|
|
2332
|
+
).join("|");
|
|
2169
2333
|
useScrollShadow(panelRef);
|
|
2170
|
-
useFollowNewestStep(panelRef,
|
|
2171
|
-
return /* @__PURE__ */
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
{
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2334
|
+
useFollowNewestStep(panelRef, contentVersion, isActivityStreaming, isExpanded);
|
|
2335
|
+
return /* @__PURE__ */ jsxs6(
|
|
2336
|
+
Disclosure2,
|
|
2337
|
+
{
|
|
2338
|
+
className: "ha-activity",
|
|
2339
|
+
"data-phase": visualPhase,
|
|
2340
|
+
isExpanded,
|
|
2341
|
+
onExpandedChange: setExpandedOverride,
|
|
2342
|
+
children: [
|
|
2343
|
+
/* @__PURE__ */ jsx8(Disclosure2.Heading, { children: /* @__PURE__ */ jsxs6(Disclosure2.Trigger, { className: "ha-activity-trigger", children: [
|
|
2344
|
+
/* @__PURE__ */ jsx8("span", { "aria-hidden": "true", className: "ha-activity-summary-icon", children: /* @__PURE__ */ jsx8("span", { children: /* @__PURE__ */ jsx8(SummaryIcon, {}) }, summaryKind) }),
|
|
2345
|
+
isActivityStreaming || isAutoSettling ? /* @__PURE__ */ jsx8(
|
|
2346
|
+
AnimatedStatusText,
|
|
2347
|
+
{
|
|
2348
|
+
animateOnMount: liveSummary !== progress,
|
|
2349
|
+
className: "ha-activity-summary-label ha-progress ha-progress-shimmer",
|
|
2350
|
+
role: "status",
|
|
2351
|
+
children: summary
|
|
2352
|
+
}
|
|
2353
|
+
) : /* @__PURE__ */ jsx8("span", { className: "ha-activity-summary-label ha-activity-summary-label--complete ha-progress", children: summary }),
|
|
2354
|
+
/* @__PURE__ */ jsx8(Disclosure2.Indicator, { className: "ha-activity-chevron" })
|
|
2355
|
+
] }) }),
|
|
2356
|
+
/* @__PURE__ */ jsx8(Disclosure2.Content, { className: "ha-activity-disclosure-content", children: /* @__PURE__ */ jsx8(Disclosure2.Body, { children: /* @__PURE__ */ jsx8("div", { ref: panelRef, className: "ha-activity-panel", children: /* @__PURE__ */ jsxs6("ol", { "aria-label": "Thinking steps", children: [
|
|
2357
|
+
visibleItems.map((item) => /* @__PURE__ */ jsxs6(
|
|
2358
|
+
"li",
|
|
2359
|
+
{
|
|
2360
|
+
"aria-current": item.active ? "step" : void 0,
|
|
2361
|
+
className: "ha-activity-item",
|
|
2362
|
+
"data-active": item.active || void 0,
|
|
2363
|
+
"data-state": item.active ? "active" : "complete",
|
|
2364
|
+
children: [
|
|
2365
|
+
/* @__PURE__ */ jsx8(ActivityStateIcon, { active: item.active }),
|
|
2366
|
+
/* @__PURE__ */ jsxs6("span", { className: "ha-activity-content", children: [
|
|
2367
|
+
item.active ? /* @__PURE__ */ jsx8(AnimatedStatusText, { className: "ha-progress-shimmer", children: item.label }) : /* @__PURE__ */ jsx8("span", { children: item.label }),
|
|
2368
|
+
item.detail ? /* @__PURE__ */ jsx8("small", { className: "ha-activity-detail", "data-visible": item.active || void 0, children: /* @__PURE__ */ jsx8("span", { children: item.detail }) }) : null,
|
|
2369
|
+
item.sources?.length ? /* @__PURE__ */ jsx8("span", { "aria-label": "Sources", className: "ha-activity-sources", children: item.sources.map((source) => /* @__PURE__ */ jsxs6("span", { className: "ha-activity-source", children: [
|
|
2370
|
+
/* @__PURE__ */ jsx8(Globe, { "aria-hidden": "true" }),
|
|
2371
|
+
source.label
|
|
2372
|
+
] }, source.label)) }) : null
|
|
2373
|
+
] })
|
|
2374
|
+
]
|
|
2375
|
+
},
|
|
2376
|
+
item.id
|
|
2377
|
+
)),
|
|
2378
|
+
!isActivityStreaming ? /* @__PURE__ */ jsxs6("li", { className: "ha-activity-item", "data-complete": "true", "data-state": "complete", children: [
|
|
2379
|
+
/* @__PURE__ */ jsx8(ActivityStateIcon, { active: false }),
|
|
2380
|
+
/* @__PURE__ */ jsx8("span", { className: "ha-activity-content", children: /* @__PURE__ */ jsx8("span", { children: "Final response ready" }) })
|
|
2381
|
+
] }) : null
|
|
2382
|
+
] }) }) }) })
|
|
2383
|
+
]
|
|
2384
|
+
}
|
|
2385
|
+
);
|
|
2214
2386
|
}
|
|
2215
2387
|
|
|
2216
2388
|
// src/embed/agent-api.ts
|
|
@@ -2279,6 +2451,7 @@ async function preloadAgentSession(options, tokenManager, conversationId, client
|
|
|
2279
2451
|
body: JSON.stringify({
|
|
2280
2452
|
clientTools,
|
|
2281
2453
|
imageSearch: options.imageSearch,
|
|
2454
|
+
newsSearch: options.newsSearch,
|
|
2282
2455
|
preload: true,
|
|
2283
2456
|
protocolVersion: HEROUI_AGENT_PROTOCOL_VERSION,
|
|
2284
2457
|
sdkVersion: HEROUI_AGENT_SDK_VERSION,
|
|
@@ -2559,12 +2732,12 @@ function getComposerAttachmentMetadata(file) {
|
|
|
2559
2732
|
}
|
|
2560
2733
|
|
|
2561
2734
|
// src/embed/composer-attachment.tsx
|
|
2562
|
-
import { jsx as jsx9, jsxs as
|
|
2735
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2563
2736
|
function ComposerAttachment({ file, onRemove }) {
|
|
2564
2737
|
const { Icon, kind, label } = getComposerAttachmentMetadata(file);
|
|
2565
|
-
return /* @__PURE__ */
|
|
2738
|
+
return /* @__PURE__ */ jsxs7("span", { className: "ha-attachment", "data-kind": kind, children: [
|
|
2566
2739
|
/* @__PURE__ */ jsx9("span", { "aria-hidden": "true", className: "ha-attachment-icon", children: /* @__PURE__ */ jsx9(Icon, {}) }),
|
|
2567
|
-
/* @__PURE__ */
|
|
2740
|
+
/* @__PURE__ */ jsxs7("span", { className: "ha-attachment-copy", children: [
|
|
2568
2741
|
/* @__PURE__ */ jsx9("span", { className: "ha-attachment-name", title: file.name, children: file.name }),
|
|
2569
2742
|
/* @__PURE__ */ jsx9("span", { className: "ha-attachment-type", children: label })
|
|
2570
2743
|
] }),
|
|
@@ -2574,9 +2747,9 @@ function ComposerAttachment({ file, onRemove }) {
|
|
|
2574
2747
|
|
|
2575
2748
|
// src/embed/composer-context.tsx
|
|
2576
2749
|
import { Globe as Globe2, Xmark as Xmark2 } from "@gravity-ui/icons";
|
|
2577
|
-
import { jsx as jsx10, jsxs as
|
|
2750
|
+
import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2578
2751
|
function ComposerContext({ onRemove, title }) {
|
|
2579
|
-
return /* @__PURE__ */ jsx10("div", { className: "ha-context", children: /* @__PURE__ */
|
|
2752
|
+
return /* @__PURE__ */ jsx10("div", { className: "ha-context", children: /* @__PURE__ */ jsxs8(
|
|
2580
2753
|
"button",
|
|
2581
2754
|
{
|
|
2582
2755
|
"aria-label": `Remove Ask about this: ${title}`,
|
|
@@ -2585,7 +2758,7 @@ function ComposerContext({ onRemove, title }) {
|
|
|
2585
2758
|
onClick: onRemove,
|
|
2586
2759
|
children: [
|
|
2587
2760
|
/* @__PURE__ */ jsx10(Globe2, { "aria-hidden": "true", className: "ha-chip-leading" }),
|
|
2588
|
-
/* @__PURE__ */
|
|
2761
|
+
/* @__PURE__ */ jsxs8("span", { className: "ha-chip-title", title, children: [
|
|
2589
2762
|
"Ask about this: ",
|
|
2590
2763
|
title
|
|
2591
2764
|
] }),
|
|
@@ -2596,7 +2769,7 @@ function ComposerContext({ onRemove, title }) {
|
|
|
2596
2769
|
}
|
|
2597
2770
|
|
|
2598
2771
|
// src/embed/composer-file-dropzone.tsx
|
|
2599
|
-
import { useCallback as useCallback4, useState as
|
|
2772
|
+
import { useCallback as useCallback4, useState as useState6 } from "react";
|
|
2600
2773
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
2601
2774
|
function hasFileTransfer(event) {
|
|
2602
2775
|
return event.dataTransfer?.types?.includes("Files") ?? false;
|
|
@@ -2609,7 +2782,7 @@ function ComposerFileDropzone({
|
|
|
2609
2782
|
disabled = false,
|
|
2610
2783
|
onFilesSelected
|
|
2611
2784
|
}) {
|
|
2612
|
-
const [isDragging, setIsDragging] =
|
|
2785
|
+
const [isDragging, setIsDragging] = useState6(false);
|
|
2613
2786
|
const handleDragEnter = useCallback4(
|
|
2614
2787
|
(event) => {
|
|
2615
2788
|
if (disabled || !hasFileTransfer(event)) return;
|
|
@@ -2726,7 +2899,7 @@ function removeConversationActivity(current, conversationId) {
|
|
|
2726
2899
|
// src/embed/conversation-markdown.tsx
|
|
2727
2900
|
import { Code as Code2, Heading, Link, Paragraph, Separator, Table } from "@heroui/react";
|
|
2728
2901
|
import { Children, Suspense, isValidElement, lazy, memo, useMemo } from "react";
|
|
2729
|
-
import { jsx as jsx12, jsxs as
|
|
2902
|
+
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2730
2903
|
var LazyStreamdown = lazy(
|
|
2731
2904
|
() => import("streamdown").then((module) => ({ default: module.Streamdown }))
|
|
2732
2905
|
);
|
|
@@ -2754,7 +2927,7 @@ function MarkdownTable({ children }) {
|
|
|
2754
2927
|
const headerRow = findElementByTag(tableHead?.props.children, "tr");
|
|
2755
2928
|
const headerCells = getElementChildren(headerRow);
|
|
2756
2929
|
const rows = getElementChildren(tableBody);
|
|
2757
|
-
return /* @__PURE__ */ jsx12(Table, { "data-slot": "markdown-table", variant: "secondary", children: /* @__PURE__ */ jsx12(Table.ScrollContainer, { children: /* @__PURE__ */
|
|
2930
|
+
return /* @__PURE__ */ jsx12(Table, { "data-slot": "markdown-table", variant: "secondary", children: /* @__PURE__ */ jsx12(Table.ScrollContainer, { children: /* @__PURE__ */ jsxs9(Table.Content, { "aria-label": "Markdown table", children: [
|
|
2758
2931
|
/* @__PURE__ */ jsx12(Table.Header, { children: headerCells.map((cell, index) => /* @__PURE__ */ jsx12(Table.Column, { id: `column-${index}`, children: cell.props.children }, String(cell.key))) }),
|
|
2759
2932
|
/* @__PURE__ */ jsx12(Table.Body, { children: rows.map((row, rowIndex) => /* @__PURE__ */ jsx12(Table.Row, { id: `row-${rowIndex}`, children: getElementChildren(row).map((cell) => /* @__PURE__ */ jsx12(Table.Cell, { children: cell.props.children }, String(cell.key))) }, String(row.key))) })
|
|
2760
2933
|
] }) }) });
|
|
@@ -2898,7 +3071,6 @@ function ConversationRouteStack({
|
|
|
2898
3071
|
|
|
2899
3072
|
// src/embed/conversation-turn-anchor.ts
|
|
2900
3073
|
function resolveConversationTurnAnchor({
|
|
2901
|
-
conversationId,
|
|
2902
3074
|
isActive,
|
|
2903
3075
|
lastUserMessageId,
|
|
2904
3076
|
pendingTurn
|
|
@@ -2906,22 +3078,21 @@ function resolveConversationTurnAnchor({
|
|
|
2906
3078
|
const normalizedLastUserMessageId = lastUserMessageId ?? null;
|
|
2907
3079
|
const hasActiveOptimisticUser = pendingTurn ? normalizedLastUserMessageId !== pendingTurn.previousUserMessageId : normalizedLastUserMessageId !== null;
|
|
2908
3080
|
const activeTurnMessageId = isActive ? hasActiveOptimisticUser ? normalizedLastUserMessageId : null : normalizedLastUserMessageId;
|
|
2909
|
-
const activeStreamKey = isActive ? pendingTurn?.
|
|
3081
|
+
const activeStreamKey = isActive ? pendingTurn?.scrollKey ?? null : null;
|
|
2910
3082
|
return { activeStreamKey, activeTurnMessageId };
|
|
2911
3083
|
}
|
|
2912
3084
|
|
|
2913
3085
|
// src/embed/conversation-viewport.tsx
|
|
2914
3086
|
import { ChevronDown } from "@gravity-ui/icons";
|
|
2915
3087
|
import { Button } from "@heroui/react";
|
|
2916
|
-
import { useLayoutEffect as useLayoutEffect2, useRef as
|
|
3088
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef7 } from "react";
|
|
2917
3089
|
|
|
2918
3090
|
// src/embed/use-conversation-scroll.ts
|
|
2919
|
-
import { useCallback as useCallback5, useEffect as useEffect9, useLayoutEffect, useRef as
|
|
3091
|
+
import { useCallback as useCallback5, useEffect as useEffect9, useLayoutEffect, useRef as useRef6, useState as useState7 } from "react";
|
|
2920
3092
|
var BOTTOM_THRESHOLD = 4;
|
|
2921
3093
|
var SCROLL_DIRECTION_THRESHOLD = 1;
|
|
2922
3094
|
var ACTIVE_TURN_SPACER_PROPERTY = "--ha-active-turn-spacer-height";
|
|
2923
|
-
var
|
|
2924
|
-
var TURN_ANCHOR_SELECTOR = '[data-turn-anchor="true"]';
|
|
3095
|
+
var USER_STREAM_ANCHOR_SELECTOR = '[data-role="user"][data-stream-anchor="true"]';
|
|
2925
3096
|
var DEFAULT_SCROLL_STATE = {
|
|
2926
3097
|
hasOverflow: false,
|
|
2927
3098
|
isAtBottom: true
|
|
@@ -2950,23 +3121,25 @@ function getNativeScrollBehavior(behavior) {
|
|
|
2950
3121
|
return "auto";
|
|
2951
3122
|
}
|
|
2952
3123
|
function useConversationScroll(ref) {
|
|
2953
|
-
const activeTurnSpacerHeightRef =
|
|
2954
|
-
const attachedRef =
|
|
2955
|
-
const
|
|
2956
|
-
const
|
|
2957
|
-
const
|
|
2958
|
-
const
|
|
2959
|
-
const
|
|
2960
|
-
const
|
|
2961
|
-
const
|
|
2962
|
-
const
|
|
3124
|
+
const activeTurnSpacerHeightRef = useRef6(0);
|
|
3125
|
+
const attachedRef = useRef6(true);
|
|
3126
|
+
const automaticFollowSuppressedRef = useRef6(false);
|
|
3127
|
+
const currentStreamKeyRef = useRef6(null);
|
|
3128
|
+
const isAutoScrollingRef = useRef6(false);
|
|
3129
|
+
const isPinnedTurnAnimatingRef = useRef6(false);
|
|
3130
|
+
const lastPinnedStreamKeyRef = useRef6(null);
|
|
3131
|
+
const lastScrollTopRef = useRef6(0);
|
|
3132
|
+
const pinnedStreamKeyRef = useRef6(null);
|
|
3133
|
+
const pinnedStreamTopRef = useRef6(null);
|
|
3134
|
+
const shouldAnimatePinnedTurnRef = useRef6(false);
|
|
3135
|
+
const [scrollState, setScrollState] = useState7(DEFAULT_SCROLL_STATE);
|
|
2963
3136
|
const setNextScrollState = useCallback5((nextState) => {
|
|
2964
3137
|
setScrollState(
|
|
2965
3138
|
(currentState) => isSameScrollState(currentState, nextState) ? currentState : nextState
|
|
2966
3139
|
);
|
|
2967
3140
|
}, []);
|
|
2968
3141
|
const updateActiveTurnSpacer = useCallback5((element) => {
|
|
2969
|
-
const anchor =
|
|
3142
|
+
const anchor = pinnedStreamKeyRef.current ? element.querySelector(USER_STREAM_ANCHOR_SELECTOR) : null;
|
|
2970
3143
|
let nextHeight = 0;
|
|
2971
3144
|
if (anchor) {
|
|
2972
3145
|
const containerRect = element.getBoundingClientRect();
|
|
@@ -2995,14 +3168,17 @@ function useConversationScroll(ref) {
|
|
|
2995
3168
|
pinnedStreamTopRef.current = null;
|
|
2996
3169
|
isPinnedTurnAnimatingRef.current = false;
|
|
2997
3170
|
shouldAnimatePinnedTurnRef.current = false;
|
|
3171
|
+
updateActiveTurnSpacer(element);
|
|
2998
3172
|
attachedRef.current = true;
|
|
2999
|
-
|
|
3173
|
+
automaticFollowSuppressedRef.current = false;
|
|
3000
3174
|
lastScrollTopRef.current = element.scrollTop;
|
|
3001
3175
|
setNextScrollState({
|
|
3002
3176
|
hasOverflow: getConversationScrollState(element).hasOverflow,
|
|
3003
3177
|
isAtBottom: true
|
|
3004
3178
|
});
|
|
3005
3179
|
const top = element.scrollHeight;
|
|
3180
|
+
const targetTop = Math.max(0, top - element.clientHeight);
|
|
3181
|
+
isAutoScrollingRef.current = Math.abs(Math.max(0, element.scrollTop) - targetTop) > SCROLL_DIRECTION_THRESHOLD;
|
|
3006
3182
|
if (typeof element.scrollTo === "function") {
|
|
3007
3183
|
element.scrollTo({ behavior: getNativeScrollBehavior(behavior), top });
|
|
3008
3184
|
} else {
|
|
@@ -3010,11 +3186,11 @@ function useConversationScroll(ref) {
|
|
|
3010
3186
|
}
|
|
3011
3187
|
lastScrollTopRef.current = Math.max(0, element.scrollTop);
|
|
3012
3188
|
},
|
|
3013
|
-
[ref, setNextScrollState]
|
|
3189
|
+
[ref, setNextScrollState, updateActiveTurnSpacer]
|
|
3014
3190
|
);
|
|
3015
3191
|
const getPinnedStreamTop = useCallback5((element) => {
|
|
3016
3192
|
if (!pinnedStreamKeyRef.current) return null;
|
|
3017
|
-
const anchor = element.querySelector(
|
|
3193
|
+
const anchor = element.querySelector(USER_STREAM_ANCHOR_SELECTOR);
|
|
3018
3194
|
if (anchor) {
|
|
3019
3195
|
const paddingTop = Number.parseFloat(window.getComputedStyle(element).paddingTop) || 0;
|
|
3020
3196
|
pinnedStreamTopRef.current = Math.max(0, anchor.offsetTop - paddingTop);
|
|
@@ -3026,8 +3202,9 @@ function useConversationScroll(ref) {
|
|
|
3026
3202
|
const maximumScrollTop = Math.max(0, element.scrollHeight - element.clientHeight);
|
|
3027
3203
|
const targetTop = Math.min(top, maximumScrollTop);
|
|
3028
3204
|
const nativeBehavior = getNativeScrollBehavior(behavior);
|
|
3029
|
-
|
|
3030
|
-
|
|
3205
|
+
const hasMovement = Math.abs(Math.max(0, element.scrollTop) - targetTop) > SCROLL_DIRECTION_THRESHOLD;
|
|
3206
|
+
isPinnedTurnAnimatingRef.current = nativeBehavior === "smooth" && hasMovement;
|
|
3207
|
+
isAutoScrollingRef.current = hasMovement;
|
|
3031
3208
|
lastScrollTopRef.current = element.scrollTop;
|
|
3032
3209
|
setNextScrollState({
|
|
3033
3210
|
hasOverflow: maximumScrollTop > BOTTOM_THRESHOLD,
|
|
@@ -3046,26 +3223,30 @@ function useConversationScroll(ref) {
|
|
|
3046
3223
|
const maintainScrollPosition = useCallback5(() => {
|
|
3047
3224
|
const element = ref.current;
|
|
3048
3225
|
if (!element) return;
|
|
3049
|
-
|
|
3226
|
+
updateActiveTurnSpacer(element);
|
|
3050
3227
|
const measuredState = getConversationScrollState(element);
|
|
3051
3228
|
const scrollTop = Math.max(0, element.scrollTop);
|
|
3052
3229
|
const scrolledUp = scrollTop < lastScrollTopRef.current - SCROLL_DIRECTION_THRESHOLD;
|
|
3053
3230
|
lastScrollTopRef.current = scrollTop;
|
|
3054
3231
|
if (scrolledUp && !measuredState.isAtBottom) {
|
|
3055
3232
|
attachedRef.current = false;
|
|
3233
|
+
automaticFollowSuppressedRef.current = true;
|
|
3056
3234
|
isAutoScrollingRef.current = false;
|
|
3057
3235
|
isPinnedTurnAnimatingRef.current = false;
|
|
3058
3236
|
pinnedStreamKeyRef.current = null;
|
|
3059
3237
|
pinnedStreamTopRef.current = null;
|
|
3060
3238
|
shouldAnimatePinnedTurnRef.current = false;
|
|
3239
|
+
updateActiveTurnSpacer(element);
|
|
3061
3240
|
setNextScrollState(measuredState);
|
|
3062
3241
|
return;
|
|
3063
3242
|
}
|
|
3064
|
-
if (!measuredState.hasOverflow || measuredState.isAtBottom) {
|
|
3243
|
+
if (!automaticFollowSuppressedRef.current && (!measuredState.hasOverflow || measuredState.isAtBottom)) {
|
|
3065
3244
|
attachedRef.current = true;
|
|
3066
3245
|
}
|
|
3067
|
-
|
|
3068
|
-
|
|
3246
|
+
const hasPinnedStream = pinnedStreamKeyRef.current !== null;
|
|
3247
|
+
const pinnedStreamTop = getPinnedStreamTop(element);
|
|
3248
|
+
if (hasPinnedStream) {
|
|
3249
|
+
automaticFollowSuppressedRef.current = true;
|
|
3069
3250
|
if (pinnedStreamTop !== null && isPinnedTurnAnimatingRef.current) {
|
|
3070
3251
|
const maximumScrollTop = Math.max(0, element.scrollHeight - element.clientHeight);
|
|
3071
3252
|
const targetTop = Math.min(pinnedStreamTop, maximumScrollTop);
|
|
@@ -3076,16 +3257,20 @@ function useConversationScroll(ref) {
|
|
|
3076
3257
|
isAutoScrollingRef.current = false;
|
|
3077
3258
|
isPinnedTurnAnimatingRef.current = false;
|
|
3078
3259
|
}
|
|
3079
|
-
if (pinnedStreamTop !== null &&
|
|
3080
|
-
const behavior = shouldAnimatePinnedTurnRef.current ? "smooth" : "auto";
|
|
3260
|
+
if (pinnedStreamTop !== null && shouldAnimatePinnedTurnRef.current) {
|
|
3081
3261
|
shouldAnimatePinnedTurnRef.current = false;
|
|
3082
|
-
scrollToPinnedPosition(element, pinnedStreamTop,
|
|
3262
|
+
scrollToPinnedPosition(element, pinnedStreamTop, "smooth");
|
|
3083
3263
|
return;
|
|
3084
3264
|
}
|
|
3265
|
+
attachedRef.current = false;
|
|
3266
|
+
setNextScrollState(measuredState);
|
|
3267
|
+
return;
|
|
3268
|
+
}
|
|
3269
|
+
if (attachedRef.current && !automaticFollowSuppressedRef.current) {
|
|
3085
3270
|
scrollToBottom("auto");
|
|
3086
3271
|
return;
|
|
3087
3272
|
}
|
|
3088
|
-
setNextScrollState(
|
|
3273
|
+
setNextScrollState(measuredState);
|
|
3089
3274
|
}, [
|
|
3090
3275
|
getPinnedStreamTop,
|
|
3091
3276
|
ref,
|
|
@@ -3100,29 +3285,43 @@ function useConversationScroll(ref) {
|
|
|
3100
3285
|
if (!element || currentStreamKeyRef.current === streamKey) return;
|
|
3101
3286
|
const hadActiveStream = currentStreamKeyRef.current !== null;
|
|
3102
3287
|
currentStreamKeyRef.current = streamKey;
|
|
3103
|
-
pinnedStreamKeyRef.current = streamKey;
|
|
3104
|
-
pinnedStreamTopRef.current = null;
|
|
3105
3288
|
if (streamKey) {
|
|
3106
|
-
|
|
3289
|
+
const startsNewUserTurn = lastPinnedStreamKeyRef.current !== streamKey;
|
|
3290
|
+
if (startsNewUserTurn) {
|
|
3291
|
+
lastPinnedStreamKeyRef.current = streamKey;
|
|
3292
|
+
pinnedStreamKeyRef.current = streamKey;
|
|
3293
|
+
pinnedStreamTopRef.current = null;
|
|
3107
3294
|
shouldAnimatePinnedTurnRef.current = true;
|
|
3295
|
+
automaticFollowSuppressedRef.current = true;
|
|
3296
|
+
attachedRef.current = true;
|
|
3297
|
+
} else {
|
|
3298
|
+
pinnedStreamKeyRef.current = null;
|
|
3299
|
+
pinnedStreamTopRef.current = null;
|
|
3300
|
+
shouldAnimatePinnedTurnRef.current = false;
|
|
3301
|
+
updateActiveTurnSpacer(element);
|
|
3108
3302
|
}
|
|
3109
|
-
attachedRef.current = true;
|
|
3110
3303
|
} else if (hadActiveStream) {
|
|
3304
|
+
pinnedStreamKeyRef.current = null;
|
|
3305
|
+
pinnedStreamTopRef.current = null;
|
|
3111
3306
|
isAutoScrollingRef.current = false;
|
|
3112
3307
|
isPinnedTurnAnimatingRef.current = false;
|
|
3113
3308
|
shouldAnimatePinnedTurnRef.current = false;
|
|
3309
|
+
automaticFollowSuppressedRef.current = true;
|
|
3310
|
+
updateActiveTurnSpacer(element);
|
|
3114
3311
|
const measuredState = getConversationScrollState(element);
|
|
3115
|
-
attachedRef.current =
|
|
3312
|
+
attachedRef.current = false;
|
|
3116
3313
|
setNextScrollState(measuredState);
|
|
3117
3314
|
}
|
|
3118
3315
|
},
|
|
3119
|
-
[ref, setNextScrollState]
|
|
3316
|
+
[ref, setNextScrollState, updateActiveTurnSpacer]
|
|
3120
3317
|
);
|
|
3121
3318
|
useLayoutEffect(() => {
|
|
3122
3319
|
const element = ref.current;
|
|
3123
3320
|
if (!element) return;
|
|
3124
3321
|
lastScrollTopRef.current = element.scrollTop;
|
|
3125
3322
|
maintainScrollPosition();
|
|
3323
|
+
automaticFollowSuppressedRef.current = true;
|
|
3324
|
+
attachedRef.current = false;
|
|
3126
3325
|
}, [maintainScrollPosition, ref]);
|
|
3127
3326
|
useEffect9(() => {
|
|
3128
3327
|
const element = ref.current;
|
|
@@ -3141,9 +3340,13 @@ function useConversationScroll(ref) {
|
|
|
3141
3340
|
if (reachedAutomaticTarget) {
|
|
3142
3341
|
isAutoScrollingRef.current = false;
|
|
3143
3342
|
isPinnedTurnAnimatingRef.current = false;
|
|
3343
|
+
if (pinnedStreamTop !== null) {
|
|
3344
|
+
automaticFollowSuppressedRef.current = true;
|
|
3345
|
+
attachedRef.current = false;
|
|
3346
|
+
}
|
|
3144
3347
|
}
|
|
3145
3348
|
setNextScrollState(
|
|
3146
|
-
wasPinnedTurnAnimating && !reachedAutomaticTarget ? { hasOverflow: measuredState.hasOverflow, isAtBottom: true } : pinnedStreamTop === null ? { hasOverflow: measuredState.hasOverflow, isAtBottom: attachedRef.current } : measuredState
|
|
3349
|
+
wasPinnedTurnAnimating && !reachedAutomaticTarget ? { hasOverflow: measuredState.hasOverflow, isAtBottom: true } : pinnedStreamTop === null ? automaticFollowSuppressedRef.current ? measuredState : { hasOverflow: measuredState.hasOverflow, isAtBottom: attachedRef.current } : measuredState
|
|
3147
3350
|
);
|
|
3148
3351
|
return;
|
|
3149
3352
|
}
|
|
@@ -3152,7 +3355,9 @@ function useConversationScroll(ref) {
|
|
|
3152
3355
|
pinnedStreamKeyRef.current = null;
|
|
3153
3356
|
pinnedStreamTopRef.current = null;
|
|
3154
3357
|
shouldAnimatePinnedTurnRef.current = false;
|
|
3358
|
+
updateActiveTurnSpacer(element);
|
|
3155
3359
|
attachedRef.current = measuredState.isAtBottom;
|
|
3360
|
+
automaticFollowSuppressedRef.current = !measuredState.isAtBottom;
|
|
3156
3361
|
setNextScrollState(measuredState);
|
|
3157
3362
|
};
|
|
3158
3363
|
element.addEventListener("scroll", handleScroll, { passive: true });
|
|
@@ -3195,7 +3400,7 @@ function useConversationScroll(ref) {
|
|
|
3195
3400
|
resizeObserver.disconnect();
|
|
3196
3401
|
}
|
|
3197
3402
|
};
|
|
3198
|
-
}, [getPinnedStreamTop, maintainScrollPosition, ref, setNextScrollState]);
|
|
3403
|
+
}, [getPinnedStreamTop, maintainScrollPosition, ref, setNextScrollState, updateActiveTurnSpacer]);
|
|
3199
3404
|
return {
|
|
3200
3405
|
hasOverflow: scrollState.hasOverflow,
|
|
3201
3406
|
isAtBottom: scrollState.isAtBottom,
|
|
@@ -3206,12 +3411,12 @@ function useConversationScroll(ref) {
|
|
|
3206
3411
|
}
|
|
3207
3412
|
|
|
3208
3413
|
// src/embed/conversation-viewport.tsx
|
|
3209
|
-
import { jsx as jsx14, jsxs as
|
|
3414
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3210
3415
|
function ConversationViewport({
|
|
3211
3416
|
children,
|
|
3212
3417
|
streamKey = null
|
|
3213
3418
|
}) {
|
|
3214
|
-
const scrollRef =
|
|
3419
|
+
const scrollRef = useRef7(null);
|
|
3215
3420
|
const { hasOverflow, isAtBottom, maintainScrollPosition, scrollToBottom, setPinnedStream } = useConversationScroll(scrollRef);
|
|
3216
3421
|
const isScrollButtonVisible = hasOverflow && !isAtBottom;
|
|
3217
3422
|
useScrollShadow(scrollRef);
|
|
@@ -3219,7 +3424,7 @@ function ConversationViewport({
|
|
|
3219
3424
|
setPinnedStream(streamKey);
|
|
3220
3425
|
maintainScrollPosition();
|
|
3221
3426
|
}, [children, maintainScrollPosition, setPinnedStream, streamKey]);
|
|
3222
|
-
return /* @__PURE__ */
|
|
3427
|
+
return /* @__PURE__ */ jsxs10("div", { className: "ha-conversation", children: [
|
|
3223
3428
|
/* @__PURE__ */ jsx14("div", { ref: scrollRef, "aria-live": "polite", className: "ha-messages", role: "log", children }),
|
|
3224
3429
|
/* @__PURE__ */ jsx14(
|
|
3225
3430
|
"div",
|
|
@@ -3252,7 +3457,7 @@ import { Suspense as Suspense2, lazy as lazy2 } from "react";
|
|
|
3252
3457
|
// src/embed/genui-renderer-loader.ts
|
|
3253
3458
|
var componentRendererPromise;
|
|
3254
3459
|
function loadGenUIRenderer() {
|
|
3255
|
-
componentRendererPromise ??= import("./component-renderer-
|
|
3460
|
+
componentRendererPromise ??= import("./component-renderer-46EJDPTB.js").then(
|
|
3256
3461
|
(module) => ({ default: module.ComponentRenderer })
|
|
3257
3462
|
);
|
|
3258
3463
|
return componentRendererPromise;
|
|
@@ -3273,8 +3478,8 @@ function GenUIRenderer(props) {
|
|
|
3273
3478
|
// src/embed/message-actions.tsx
|
|
3274
3479
|
import { ArrowsRotateLeft, Check, Copy, ThumbsDown, ThumbsUp } from "@gravity-ui/icons";
|
|
3275
3480
|
import { Button as Button2, Popover, TextArea } from "@heroui/react";
|
|
3276
|
-
import { useCallback as useCallback6, useEffect as useEffect10, useRef as
|
|
3277
|
-
import { Fragment, jsx as jsx16, jsxs as
|
|
3481
|
+
import { useCallback as useCallback6, useEffect as useEffect10, useRef as useRef8, useState as useState8 } from "react";
|
|
3482
|
+
import { Fragment, jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3278
3483
|
var COPY_RESET_DELAY = 2e3;
|
|
3279
3484
|
var FEEDBACK_COMMENT_MAX_LENGTH = 1e3;
|
|
3280
3485
|
var NEGATIVE_FEEDBACK_REASONS = [
|
|
@@ -3292,13 +3497,13 @@ function MessageActions({
|
|
|
3292
3497
|
onFeedback,
|
|
3293
3498
|
onRetry
|
|
3294
3499
|
}) {
|
|
3295
|
-
const [isCopied, setIsCopied] =
|
|
3296
|
-
const [isFeedbackOpen, setIsFeedbackOpen] =
|
|
3297
|
-
const [feedbackComment, setFeedbackComment] =
|
|
3298
|
-
const [feedbackReasons, setFeedbackReasons] =
|
|
3299
|
-
const [feedbackPortalContainer, setFeedbackPortalContainer] =
|
|
3300
|
-
const resetTimeoutRef =
|
|
3301
|
-
const feedbackOpenedAtRef =
|
|
3500
|
+
const [isCopied, setIsCopied] = useState8(false);
|
|
3501
|
+
const [isFeedbackOpen, setIsFeedbackOpen] = useState8(false);
|
|
3502
|
+
const [feedbackComment, setFeedbackComment] = useState8("");
|
|
3503
|
+
const [feedbackReasons, setFeedbackReasons] = useState8([]);
|
|
3504
|
+
const [feedbackPortalContainer, setFeedbackPortalContainer] = useState8();
|
|
3505
|
+
const resetTimeoutRef = useRef8(null);
|
|
3506
|
+
const feedbackOpenedAtRef = useRef8(0);
|
|
3302
3507
|
const feedbackTriggerRef = useCallback6((node) => {
|
|
3303
3508
|
setFeedbackPortalContainer(node?.closest(".ha-panel") ?? void 0);
|
|
3304
3509
|
}, []);
|
|
@@ -3337,7 +3542,7 @@ function MessageActions({
|
|
|
3337
3542
|
});
|
|
3338
3543
|
setIsFeedbackOpen(false);
|
|
3339
3544
|
};
|
|
3340
|
-
return /* @__PURE__ */
|
|
3545
|
+
return /* @__PURE__ */ jsxs11("div", { "aria-label": "Message actions", className: "ha-message-actions", role: "group", children: [
|
|
3341
3546
|
showCopy ? /* @__PURE__ */ jsx16(
|
|
3342
3547
|
"button",
|
|
3343
3548
|
{
|
|
@@ -3349,7 +3554,7 @@ function MessageActions({
|
|
|
3349
3554
|
children: /* @__PURE__ */ jsx16("span", { className: "ha-message-action-icon", children: isCopied ? /* @__PURE__ */ jsx16(Check, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx16(Copy, { "aria-hidden": "true" }) }, isCopied ? "check" : "copy")
|
|
3350
3555
|
}
|
|
3351
3556
|
) : null,
|
|
3352
|
-
showFeedback ? /* @__PURE__ */
|
|
3557
|
+
showFeedback ? /* @__PURE__ */ jsxs11(Fragment, { children: [
|
|
3353
3558
|
/* @__PURE__ */ jsx16(
|
|
3354
3559
|
"button",
|
|
3355
3560
|
{
|
|
@@ -3362,7 +3567,7 @@ function MessageActions({
|
|
|
3362
3567
|
children: /* @__PURE__ */ jsx16(ThumbsUp, { "aria-hidden": "true" })
|
|
3363
3568
|
}
|
|
3364
3569
|
),
|
|
3365
|
-
/* @__PURE__ */
|
|
3570
|
+
/* @__PURE__ */ jsxs11(Popover, { isOpen: isFeedbackOpen, onOpenChange: handleFeedbackOpenChange, children: [
|
|
3366
3571
|
/* @__PURE__ */ jsx16(
|
|
3367
3572
|
Button2,
|
|
3368
3573
|
{
|
|
@@ -3388,7 +3593,7 @@ function MessageActions({
|
|
|
3388
3593
|
offset: 8,
|
|
3389
3594
|
placement: "top start",
|
|
3390
3595
|
UNSTABLE_portalContainer: feedbackPortalContainer,
|
|
3391
|
-
children: /* @__PURE__ */
|
|
3596
|
+
children: /* @__PURE__ */ jsxs11(Popover.Dialog, { className: "ha-feedback-dialog", children: [
|
|
3392
3597
|
/* @__PURE__ */ jsx16(Popover.Heading, { className: "ha-feedback-heading", children: "Help us improve" }),
|
|
3393
3598
|
/* @__PURE__ */ jsx16("p", { className: "ha-feedback-description", children: "What could be better?" }),
|
|
3394
3599
|
/* @__PURE__ */ jsx16("div", { "aria-label": "Feedback reasons", className: "ha-feedback-reasons", role: "group", children: NEGATIVE_FEEDBACK_REASONS.map((reason) => {
|
|
@@ -3421,7 +3626,7 @@ function MessageActions({
|
|
|
3421
3626
|
}
|
|
3422
3627
|
),
|
|
3423
3628
|
/* @__PURE__ */ jsx16("p", { className: "ha-feedback-privacy", children: "Avoid sharing sensitive information." }),
|
|
3424
|
-
/* @__PURE__ */
|
|
3629
|
+
/* @__PURE__ */ jsxs11("div", { className: "ha-feedback-footer", children: [
|
|
3425
3630
|
/* @__PURE__ */ jsx16(
|
|
3426
3631
|
Button2,
|
|
3427
3632
|
{
|
|
@@ -3462,7 +3667,7 @@ function MessageActions({
|
|
|
3462
3667
|
}
|
|
3463
3668
|
|
|
3464
3669
|
// src/embed/message-attachment.tsx
|
|
3465
|
-
import { jsx as jsx17, jsxs as
|
|
3670
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3466
3671
|
function MessageAttachment({ file }) {
|
|
3467
3672
|
const name = file.filename?.trim() || "Attachment";
|
|
3468
3673
|
const type = file.mediaType?.trim() || "";
|
|
@@ -3482,7 +3687,7 @@ function MessageAttachment({ file }) {
|
|
|
3482
3687
|
}
|
|
3483
3688
|
);
|
|
3484
3689
|
}
|
|
3485
|
-
return /* @__PURE__ */
|
|
3690
|
+
return /* @__PURE__ */ jsxs12(
|
|
3486
3691
|
"a",
|
|
3487
3692
|
{
|
|
3488
3693
|
className: "ha-message-file",
|
|
@@ -3493,7 +3698,7 @@ function MessageAttachment({ file }) {
|
|
|
3493
3698
|
target: "_blank",
|
|
3494
3699
|
children: [
|
|
3495
3700
|
/* @__PURE__ */ jsx17("span", { "aria-hidden": "true", className: "ha-message-file-icon", children: /* @__PURE__ */ jsx17(Icon, {}) }),
|
|
3496
|
-
/* @__PURE__ */
|
|
3701
|
+
/* @__PURE__ */ jsxs12("span", { className: "ha-message-file-copy", children: [
|
|
3497
3702
|
/* @__PURE__ */ jsx17("span", { className: "ha-message-file-name", title: name, children: name }),
|
|
3498
3703
|
/* @__PURE__ */ jsx17("span", { className: "ha-message-file-type", children: label })
|
|
3499
3704
|
] })
|
|
@@ -3644,23 +3849,23 @@ function handleMessageQueueComposerKeyDown(event, queue) {
|
|
|
3644
3849
|
|
|
3645
3850
|
// src/embed/message-queue-list.tsx
|
|
3646
3851
|
import { ArrowUp, CircleExclamation, Clock, Grip, Pencil, TrashBin } from "@gravity-ui/icons";
|
|
3647
|
-
import { useImperativeHandle, useLayoutEffect as useLayoutEffect3, useRef as
|
|
3852
|
+
import { useImperativeHandle, useLayoutEffect as useLayoutEffect3, useRef as useRef10 } from "react";
|
|
3648
3853
|
|
|
3649
3854
|
// src/embed/use-message-queue-reorder.ts
|
|
3650
|
-
import { useRef as
|
|
3855
|
+
import { useRef as useRef9, useState as useState9 } from "react";
|
|
3651
3856
|
function useMessageQueueReorder({
|
|
3652
3857
|
messages,
|
|
3653
3858
|
onReorder,
|
|
3654
3859
|
onReorderStateChange
|
|
3655
3860
|
}) {
|
|
3656
|
-
const dragStateRef =
|
|
3657
|
-
const dropTargetRef =
|
|
3658
|
-
const positionPickerMessageIdRef =
|
|
3659
|
-
const suppressedClickMessageIdRef =
|
|
3660
|
-
const [announcement, setAnnouncement] =
|
|
3661
|
-
const [draggedMessageId, setDraggedMessageId] =
|
|
3662
|
-
const [dropTarget, setDropTarget] =
|
|
3663
|
-
const [positionPickerMessageId, setPositionPickerMessageId] =
|
|
3861
|
+
const dragStateRef = useRef9(null);
|
|
3862
|
+
const dropTargetRef = useRef9(null);
|
|
3863
|
+
const positionPickerMessageIdRef = useRef9(null);
|
|
3864
|
+
const suppressedClickMessageIdRef = useRef9(null);
|
|
3865
|
+
const [announcement, setAnnouncement] = useState9("");
|
|
3866
|
+
const [draggedMessageId, setDraggedMessageId] = useState9(null);
|
|
3867
|
+
const [dropTarget, setDropTarget] = useState9(null);
|
|
3868
|
+
const [positionPickerMessageId, setPositionPickerMessageId] = useState9(null);
|
|
3664
3869
|
const updateDropTarget = (nextTarget) => {
|
|
3665
3870
|
dropTargetRef.current = nextTarget;
|
|
3666
3871
|
setDropTarget(nextTarget);
|
|
@@ -3808,7 +4013,7 @@ function useMessageQueueReorder({
|
|
|
3808
4013
|
}
|
|
3809
4014
|
|
|
3810
4015
|
// src/embed/message-queue-list.tsx
|
|
3811
|
-
import { jsx as jsx18, jsxs as
|
|
4016
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3812
4017
|
function focusQueueMessageAt(list, index) {
|
|
3813
4018
|
const item = list?.querySelectorAll("[data-queue-message-id]")[index];
|
|
3814
4019
|
if (!item) return false;
|
|
@@ -3828,9 +4033,9 @@ function MessageQueueList({
|
|
|
3828
4033
|
onSendNow,
|
|
3829
4034
|
ref
|
|
3830
4035
|
}) {
|
|
3831
|
-
const focusedMessageIdRef =
|
|
3832
|
-
const listRef =
|
|
3833
|
-
const previousMessagesRef =
|
|
4036
|
+
const focusedMessageIdRef = useRef10(null);
|
|
4037
|
+
const listRef = useRef10(null);
|
|
4038
|
+
const previousMessagesRef = useRef10(messages);
|
|
3834
4039
|
const {
|
|
3835
4040
|
announcement,
|
|
3836
4041
|
closePositionPicker,
|
|
@@ -3872,7 +4077,7 @@ function MessageQueueList({
|
|
|
3872
4077
|
}
|
|
3873
4078
|
if (!focusQueueMessageAt(listRef.current, index + 1)) onFocusComposer();
|
|
3874
4079
|
};
|
|
3875
|
-
return /* @__PURE__ */
|
|
4080
|
+
return /* @__PURE__ */ jsxs13("section", { "aria-label": "Queued messages", className: "ha-message-queue", children: [
|
|
3876
4081
|
/* @__PURE__ */ jsx18("div", { className: "ha-message-queue-header", children: "Queued" }),
|
|
3877
4082
|
/* @__PURE__ */ jsx18("ol", { ref: listRef, className: "ha-message-queue-list", children: messages.map((message, index) => {
|
|
3878
4083
|
const isBlocked = blockedMessageId === message.id;
|
|
@@ -3880,7 +4085,7 @@ function MessageQueueList({
|
|
|
3880
4085
|
const statusId = isBlocked ? `ha-queued-message-status-${message.id}` : void 0;
|
|
3881
4086
|
return (
|
|
3882
4087
|
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- Queue rows are programmatically focused for arrow-key navigation; nested controls keep their own key handling.
|
|
3883
|
-
/* @__PURE__ */
|
|
4088
|
+
/* @__PURE__ */ jsxs13(
|
|
3884
4089
|
"li",
|
|
3885
4090
|
{
|
|
3886
4091
|
"aria-describedby": statusId,
|
|
@@ -3930,18 +4135,18 @@ function MessageQueueList({
|
|
|
3930
4135
|
value: index,
|
|
3931
4136
|
onBlur: () => closePositionPicker(message.id),
|
|
3932
4137
|
onChange: (event) => moveMessageToPosition(message.id, index, Number(event.currentTarget.value)),
|
|
3933
|
-
children: messages.map((queuedMessage, position) => /* @__PURE__ */
|
|
4138
|
+
children: messages.map((queuedMessage, position) => /* @__PURE__ */ jsxs13("option", { value: position, children: [
|
|
3934
4139
|
"Position ",
|
|
3935
4140
|
position + 1,
|
|
3936
4141
|
position === index ? " (current)" : ""
|
|
3937
4142
|
] }, queuedMessage.id))
|
|
3938
4143
|
}
|
|
3939
4144
|
) : /* @__PURE__ */ jsx18("span", { "aria-hidden": "true", className: "ha-message-queue-icon", children: isBlocked ? /* @__PURE__ */ jsx18(CircleExclamation, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx18(Clock, { "aria-hidden": "true" }) }),
|
|
3940
|
-
/* @__PURE__ */
|
|
4145
|
+
/* @__PURE__ */ jsxs13("span", { className: "ha-message-queue-content", children: [
|
|
3941
4146
|
/* @__PURE__ */ jsx18("span", { className: "ha-message-queue-preview", children: getQueuedAgentMessagePreview(message) }),
|
|
3942
4147
|
isBlocked ? /* @__PURE__ */ jsx18("span", { className: "ha-message-queue-status", id: statusId, role: "status", children: "Could not send" }) : null
|
|
3943
4148
|
] }),
|
|
3944
|
-
/* @__PURE__ */
|
|
4149
|
+
/* @__PURE__ */ jsxs13("span", { className: "ha-message-queue-actions", children: [
|
|
3945
4150
|
/* @__PURE__ */ jsx18(
|
|
3946
4151
|
"button",
|
|
3947
4152
|
{
|
|
@@ -3995,7 +4200,7 @@ import { composeRenderProps as composeRenderProps2 } from "react-aria-components
|
|
|
3995
4200
|
// ../agent-ui/src/components/hover-card/hover-card.tsx
|
|
3996
4201
|
import { mergeRefs } from "@react-aria/utils";
|
|
3997
4202
|
import { useControlledState } from "@react-stately/utils";
|
|
3998
|
-
import { createContext, useCallback as useCallback7, useContext, useEffect as useEffect11, useMemo as useMemo2, useRef as
|
|
4203
|
+
import { createContext, useCallback as useCallback7, useContext, useEffect as useEffect11, useMemo as useMemo2, useRef as useRef11, useState as useState10 } from "react";
|
|
3999
4204
|
import {
|
|
4000
4205
|
OverlayArrow as OverlayArrowPrimitive,
|
|
4001
4206
|
Popover as PopoverPrimitive,
|
|
@@ -4024,11 +4229,11 @@ var HoverCardRoot = ({
|
|
|
4024
4229
|
openDelay = 700
|
|
4025
4230
|
}) => {
|
|
4026
4231
|
const [isOpen, setOpen] = useControlledState(open, defaultOpen, onOpenChange);
|
|
4027
|
-
const [portalContainer, setPortalContainer] =
|
|
4028
|
-
const triggerRef =
|
|
4029
|
-
const isPointerInsideRef =
|
|
4030
|
-
const openTimerRef =
|
|
4031
|
-
const closeTimerRef =
|
|
4232
|
+
const [portalContainer, setPortalContainer] = useState10();
|
|
4233
|
+
const triggerRef = useRef11(null);
|
|
4234
|
+
const isPointerInsideRef = useRef11(false);
|
|
4235
|
+
const openTimerRef = useRef11(void 0);
|
|
4236
|
+
const closeTimerRef = useRef11(void 0);
|
|
4032
4237
|
const clearTimers = useCallback7(() => {
|
|
4033
4238
|
clearTimeout(openTimerRef.current);
|
|
4034
4239
|
clearTimeout(closeTimerRef.current);
|
|
@@ -4245,7 +4450,7 @@ function extractSourceDomain(href) {
|
|
|
4245
4450
|
}
|
|
4246
4451
|
|
|
4247
4452
|
// ../agent-ui/src/components/chat-source/chat-source.tsx
|
|
4248
|
-
import { Fragment as Fragment2, jsx as jsx20, jsxs as
|
|
4453
|
+
import { Fragment as Fragment2, jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4249
4454
|
var ChatSourceContext = createContext2({ sourceType: "url" });
|
|
4250
4455
|
var useChatSourceContext = () => useContext2(ChatSourceContext);
|
|
4251
4456
|
function getSourceInitial(label) {
|
|
@@ -4270,7 +4475,7 @@ var ChatSourceRoot = ({
|
|
|
4270
4475
|
() => ({ description, domain, enablePreview, faviconUrl, href, locator, sourceType, title }),
|
|
4271
4476
|
[description, domain, enablePreview, faviconUrl, href, locator, sourceType, title]
|
|
4272
4477
|
);
|
|
4273
|
-
const body = children ?? /* @__PURE__ */
|
|
4478
|
+
const body = children ?? /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
4274
4479
|
/* @__PURE__ */ jsx20(ChatSourceTrigger, {}),
|
|
4275
4480
|
enablePreview ? /* @__PURE__ */ jsx20(ChatSourcePreview, { description, title }) : null
|
|
4276
4481
|
] });
|
|
@@ -4290,11 +4495,11 @@ var ChatSourceRoot = ({
|
|
|
4290
4495
|
var ChatSourceTrigger = ({ children, className, label, ...props }) => {
|
|
4291
4496
|
const { domain, enablePreview, href, locator, sourceType, title } = useChatSourceContext();
|
|
4292
4497
|
const isUrl = sourceType === "url" && href;
|
|
4293
|
-
const triggerBody = children ?? label ?? (isUrl ? /* @__PURE__ */
|
|
4498
|
+
const triggerBody = children ?? label ?? (isUrl ? /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
4294
4499
|
/* @__PURE__ */ jsx20(ChatSourceIcon, {}),
|
|
4295
4500
|
/* @__PURE__ */ jsx20(ChatSourceTitle, { children: title ?? domain }),
|
|
4296
4501
|
locator ? /* @__PURE__ */ jsx20(ChatSourceLocator, { children: locator }) : null
|
|
4297
|
-
] }) : /* @__PURE__ */
|
|
4502
|
+
] }) : /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
4298
4503
|
/* @__PURE__ */ jsx20(ChatSourceDocumentIcon, {}),
|
|
4299
4504
|
/* @__PURE__ */ jsx20(ChatSourceTitle, { children: title }),
|
|
4300
4505
|
locator ? /* @__PURE__ */ jsx20(ChatSourceLocator, { children: locator }) : null
|
|
@@ -4372,7 +4577,7 @@ var ChatSourceIcon = ({ children, className, faviconUrl }) => {
|
|
|
4372
4577
|
"data-slot": "chat-source-icon"
|
|
4373
4578
|
});
|
|
4374
4579
|
}
|
|
4375
|
-
return /* @__PURE__ */
|
|
4580
|
+
return /* @__PURE__ */ jsxs14(
|
|
4376
4581
|
"span",
|
|
4377
4582
|
{
|
|
4378
4583
|
"aria-hidden": "true",
|
|
@@ -4439,7 +4644,7 @@ var ChatSourcePreview = ({
|
|
|
4439
4644
|
if (!enablePreview) return null;
|
|
4440
4645
|
const resolvedTitle = title ?? contextTitle;
|
|
4441
4646
|
const resolvedDescription = description ?? contextDescription;
|
|
4442
|
-
const body = sourceType === "url" && href ? /* @__PURE__ */
|
|
4647
|
+
const body = sourceType === "url" && href ? /* @__PURE__ */ jsxs14(
|
|
4443
4648
|
"a",
|
|
4444
4649
|
{
|
|
4445
4650
|
className: "aui-chat-source__preview-link",
|
|
@@ -4447,7 +4652,7 @@ var ChatSourcePreview = ({
|
|
|
4447
4652
|
rel: "noopener noreferrer",
|
|
4448
4653
|
target: "_blank",
|
|
4449
4654
|
children: [
|
|
4450
|
-
/* @__PURE__ */
|
|
4655
|
+
/* @__PURE__ */ jsxs14("div", { className: "aui-chat-source__preview-header", children: [
|
|
4451
4656
|
/* @__PURE__ */ jsx20(ChatSourceIcon, {}),
|
|
4452
4657
|
/* @__PURE__ */ jsx20("span", { className: "aui-chat-source__preview-domain", children: domain })
|
|
4453
4658
|
] }),
|
|
@@ -4455,8 +4660,8 @@ var ChatSourcePreview = ({
|
|
|
4455
4660
|
resolvedDescription ? /* @__PURE__ */ jsx20("div", { className: "aui-chat-source__preview-description", children: resolvedDescription }) : null
|
|
4456
4661
|
]
|
|
4457
4662
|
}
|
|
4458
|
-
) : /* @__PURE__ */
|
|
4459
|
-
/* @__PURE__ */
|
|
4663
|
+
) : /* @__PURE__ */ jsxs14("div", { className: "aui-chat-source__preview-link", "data-source-type": "document", children: [
|
|
4664
|
+
/* @__PURE__ */ jsxs14("div", { className: "aui-chat-source__preview-header", children: [
|
|
4460
4665
|
/* @__PURE__ */ jsx20(ChatSourceDocumentIcon, {}),
|
|
4461
4666
|
/* @__PURE__ */ jsx20("span", { className: "aui-chat-source__preview-domain", children: resolvedTitle ?? "Document" })
|
|
4462
4667
|
] }),
|
|
@@ -4482,7 +4687,7 @@ var ChatSourcePreview = ({
|
|
|
4482
4687
|
// ../agent-ui/src/components/chat-source/chat-sources.tsx
|
|
4483
4688
|
import { Disclosure as Disclosure3 } from "@heroui/react";
|
|
4484
4689
|
import { composeRenderProps as composeRenderProps3 } from "react-aria-components";
|
|
4485
|
-
import { jsx as jsx21, jsxs as
|
|
4690
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4486
4691
|
var ChatSourcesRoot = ({ children, className, ...props }) => /* @__PURE__ */ jsx21(
|
|
4487
4692
|
Disclosure3,
|
|
4488
4693
|
{
|
|
@@ -4495,7 +4700,7 @@ var ChatSourcesRoot = ({ children, className, ...props }) => /* @__PURE__ */ jsx
|
|
|
4495
4700
|
children
|
|
4496
4701
|
}
|
|
4497
4702
|
);
|
|
4498
|
-
var ChatSourcesTrigger = ({ children, className, ...props }) => /* @__PURE__ */ jsx21(Disclosure3.Heading, { children: /* @__PURE__ */
|
|
4703
|
+
var ChatSourcesTrigger = ({ children, className, ...props }) => /* @__PURE__ */ jsx21(Disclosure3.Heading, { children: /* @__PURE__ */ jsxs15(
|
|
4499
4704
|
Disclosure3.Trigger,
|
|
4500
4705
|
{
|
|
4501
4706
|
"data-slot": "chat-sources-trigger",
|
|
@@ -4551,7 +4756,7 @@ var ChatSources = Object.assign(ChatSourcesRoot, {
|
|
|
4551
4756
|
});
|
|
4552
4757
|
|
|
4553
4758
|
// src/embed/message-sources.tsx
|
|
4554
|
-
import { jsx as jsx22, jsxs as
|
|
4759
|
+
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4555
4760
|
function sourceFaviconUrl(url) {
|
|
4556
4761
|
return `https://www.google.com/s2/favicons?domain_url=${encodeURIComponent(url)}&sz=64`;
|
|
4557
4762
|
}
|
|
@@ -4578,8 +4783,8 @@ function MessageSources({ sources }) {
|
|
|
4578
4783
|
if (sources.length === 1) {
|
|
4579
4784
|
return /* @__PURE__ */ jsx22("div", { "aria-label": "Sources", className: "ha-message-sources", "data-count": "1", role: "group", children: /* @__PURE__ */ jsx22(SourceLink, { source: sources[0] }) });
|
|
4580
4785
|
}
|
|
4581
|
-
return /* @__PURE__ */
|
|
4582
|
-
/* @__PURE__ */
|
|
4786
|
+
return /* @__PURE__ */ jsxs16(ChatSources, { className: "ha-message-sources", "data-count": sources.length, children: [
|
|
4787
|
+
/* @__PURE__ */ jsxs16(ChatSources.Trigger, { "aria-label": `${sources.length} sources`, children: [
|
|
4583
4788
|
/* @__PURE__ */ jsx22("span", { className: "ha-sources-label", children: "Sources" }),
|
|
4584
4789
|
/* @__PURE__ */ jsx22("span", { "aria-hidden": "true", className: "ha-sources-count", children: sources.length })
|
|
4585
4790
|
] }),
|
|
@@ -4664,8 +4869,8 @@ function writeCachedProjectConfig(agentId, config) {
|
|
|
4664
4869
|
// src/embed/session-picker.tsx
|
|
4665
4870
|
import { ChevronDown as ChevronDown2, Ellipsis, Pencil as Pencil2, Plus as Plus2, TrashBin as TrashBin2 } from "@gravity-ui/icons";
|
|
4666
4871
|
import { Button as Button4, Dropdown, Input, Label as Label3, Modal, Popover as Popover2, TextField } from "@heroui/react";
|
|
4667
|
-
import { useCallback as useCallback8, useRef as
|
|
4668
|
-
import { Fragment as Fragment3, jsx as jsx24, jsxs as
|
|
4872
|
+
import { useCallback as useCallback8, useRef as useRef12, useState as useState11 } from "react";
|
|
4873
|
+
import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4669
4874
|
var RENAME_KEY = "rename";
|
|
4670
4875
|
var DELETE_KEY = "delete";
|
|
4671
4876
|
var MAX_TITLE_LENGTH = 80;
|
|
@@ -4681,17 +4886,17 @@ function SessionPicker({
|
|
|
4681
4886
|
onSelectConversation,
|
|
4682
4887
|
variant = "popover"
|
|
4683
4888
|
}) {
|
|
4684
|
-
const [isOpen, setIsOpen] =
|
|
4685
|
-
const [isDialogOpen, setIsDialogOpen] =
|
|
4686
|
-
const [actionMenuId, setActionMenuId] =
|
|
4687
|
-
const [dialog, setDialog] =
|
|
4688
|
-
const [renameTitle, setRenameTitle] =
|
|
4689
|
-
const [mutationError, setMutationError] =
|
|
4690
|
-
const [isPending, setIsPending] =
|
|
4691
|
-
const [portalContainer, setPortalContainer] =
|
|
4692
|
-
const pointerOpenAt =
|
|
4693
|
-
const actionPointerOpenAt =
|
|
4694
|
-
const sidebarHistoryRef =
|
|
4889
|
+
const [isOpen, setIsOpen] = useState11(false);
|
|
4890
|
+
const [isDialogOpen, setIsDialogOpen] = useState11(false);
|
|
4891
|
+
const [actionMenuId, setActionMenuId] = useState11(null);
|
|
4892
|
+
const [dialog, setDialog] = useState11(null);
|
|
4893
|
+
const [renameTitle, setRenameTitle] = useState11("");
|
|
4894
|
+
const [mutationError, setMutationError] = useState11(null);
|
|
4895
|
+
const [isPending, setIsPending] = useState11(false);
|
|
4896
|
+
const [portalContainer, setPortalContainer] = useState11();
|
|
4897
|
+
const pointerOpenAt = useRef12(0);
|
|
4898
|
+
const actionPointerOpenAt = useRef12(0);
|
|
4899
|
+
const sidebarHistoryRef = useRef12(null);
|
|
4695
4900
|
useScrollShadow(sidebarHistoryRef);
|
|
4696
4901
|
const activeConversation = groups.flatMap((group) => group.items).find((conversation) => conversation.id === activeConversationId);
|
|
4697
4902
|
const activeTitle = activeConversation?.title ?? "New chat";
|
|
@@ -4763,13 +4968,13 @@ function SessionPicker({
|
|
|
4763
4968
|
setIsPending(false);
|
|
4764
4969
|
}
|
|
4765
4970
|
};
|
|
4766
|
-
const history = groups.length ? groups.map((group) => /* @__PURE__ */
|
|
4971
|
+
const history = groups.length ? groups.map((group) => /* @__PURE__ */ jsxs17("section", { className: "ha-session-group", children: [
|
|
4767
4972
|
/* @__PURE__ */ jsx24("h3", { children: group.label }),
|
|
4768
4973
|
/* @__PURE__ */ jsx24("div", { className: "ha-session-list", children: group.items.map((conversation) => {
|
|
4769
4974
|
const isActive = conversation.id === activeConversationId;
|
|
4770
4975
|
const isBusy = busyConversationIds.has(conversation.id);
|
|
4771
4976
|
const hasCompletedUpdate = !isBusy && completedConversationIds.has(conversation.id);
|
|
4772
|
-
return /* @__PURE__ */
|
|
4977
|
+
return /* @__PURE__ */ jsxs17(
|
|
4773
4978
|
"div",
|
|
4774
4979
|
{
|
|
4775
4980
|
className: "ha-session-row",
|
|
@@ -4777,7 +4982,7 @@ function SessionPicker({
|
|
|
4777
4982
|
"data-active": isActive || void 0,
|
|
4778
4983
|
"data-completed": hasCompletedUpdate || void 0,
|
|
4779
4984
|
children: [
|
|
4780
|
-
/* @__PURE__ */
|
|
4985
|
+
/* @__PURE__ */ jsxs17(
|
|
4781
4986
|
"button",
|
|
4782
4987
|
{
|
|
4783
4988
|
"aria-current": isActive ? "page" : void 0,
|
|
@@ -4794,7 +4999,7 @@ function SessionPicker({
|
|
|
4794
4999
|
]
|
|
4795
5000
|
}
|
|
4796
5001
|
),
|
|
4797
|
-
/* @__PURE__ */
|
|
5002
|
+
/* @__PURE__ */ jsxs17(
|
|
4798
5003
|
Dropdown,
|
|
4799
5004
|
{
|
|
4800
5005
|
isOpen: actionMenuId === conversation.id,
|
|
@@ -4820,17 +5025,17 @@ function SessionPicker({
|
|
|
4820
5025
|
className: "ha-session-actions-menu",
|
|
4821
5026
|
placement: "bottom end",
|
|
4822
5027
|
UNSTABLE_portalContainer: portalContainer,
|
|
4823
|
-
children: /* @__PURE__ */
|
|
5028
|
+
children: /* @__PURE__ */ jsxs17(
|
|
4824
5029
|
Dropdown.Menu,
|
|
4825
5030
|
{
|
|
4826
5031
|
"aria-label": `Actions for ${conversation.title}`,
|
|
4827
5032
|
onAction: (key) => handleConversationAction(conversation, key),
|
|
4828
5033
|
children: [
|
|
4829
|
-
/* @__PURE__ */
|
|
5034
|
+
/* @__PURE__ */ jsxs17(Dropdown.Item, { id: RENAME_KEY, textValue: "Rename", children: [
|
|
4830
5035
|
/* @__PURE__ */ jsx24(Pencil2, { "aria-hidden": "true" }),
|
|
4831
5036
|
/* @__PURE__ */ jsx24(Label3, { children: "Rename" })
|
|
4832
5037
|
] }),
|
|
4833
|
-
/* @__PURE__ */
|
|
5038
|
+
/* @__PURE__ */ jsxs17(
|
|
4834
5039
|
Dropdown.Item,
|
|
4835
5040
|
{
|
|
4836
5041
|
id: DELETE_KEY,
|
|
@@ -4857,16 +5062,16 @@ function SessionPicker({
|
|
|
4857
5062
|
);
|
|
4858
5063
|
}) })
|
|
4859
5064
|
] }, group.label)) : /* @__PURE__ */ jsx24("p", { className: "ha-session-empty", children: "Your recent chats will appear here." });
|
|
4860
|
-
return /* @__PURE__ */
|
|
5065
|
+
return /* @__PURE__ */ jsxs17(
|
|
4861
5066
|
"div",
|
|
4862
5067
|
{
|
|
4863
5068
|
"data-variant": variant,
|
|
4864
5069
|
className: variant === "sidebar" ? "ha-session-picker ha-session-sidebar" : "ha-session-picker",
|
|
4865
5070
|
children: [
|
|
4866
|
-
variant === "sidebar" ? /* @__PURE__ */
|
|
4867
|
-
/* @__PURE__ */
|
|
5071
|
+
variant === "sidebar" ? /* @__PURE__ */ jsxs17(Fragment3, { children: [
|
|
5072
|
+
/* @__PURE__ */ jsxs17("div", { className: "ha-session-sidebar-header", children: [
|
|
4868
5073
|
/* @__PURE__ */ jsx24("h2", { children: "Chats" }),
|
|
4869
|
-
/* @__PURE__ */
|
|
5074
|
+
/* @__PURE__ */ jsxs17(
|
|
4870
5075
|
Button4,
|
|
4871
5076
|
{
|
|
4872
5077
|
fullWidth: true,
|
|
@@ -4893,8 +5098,8 @@ function SessionPicker({
|
|
|
4893
5098
|
children: history
|
|
4894
5099
|
}
|
|
4895
5100
|
)
|
|
4896
|
-
] }) : /* @__PURE__ */
|
|
4897
|
-
/* @__PURE__ */
|
|
5101
|
+
] }) : /* @__PURE__ */ jsxs17(Popover2, { isOpen, onOpenChange: handleOpenChange, children: [
|
|
5102
|
+
/* @__PURE__ */ jsxs17(
|
|
4898
5103
|
Button4,
|
|
4899
5104
|
{
|
|
4900
5105
|
"aria-label": "Choose a chat",
|
|
@@ -4979,7 +5184,7 @@ function SessionDialogContent({
|
|
|
4979
5184
|
renameTitle
|
|
4980
5185
|
}) {
|
|
4981
5186
|
if (dialog?.type === "rename") {
|
|
4982
|
-
return /* @__PURE__ */
|
|
5187
|
+
return /* @__PURE__ */ jsxs17(
|
|
4983
5188
|
"form",
|
|
4984
5189
|
{
|
|
4985
5190
|
onSubmit: (event) => {
|
|
@@ -4988,7 +5193,7 @@ function SessionDialogContent({
|
|
|
4988
5193
|
},
|
|
4989
5194
|
children: [
|
|
4990
5195
|
/* @__PURE__ */ jsx24(Modal.Header, { children: /* @__PURE__ */ jsx24(Modal.Heading, { children: "Rename chat" }) }),
|
|
4991
|
-
/* @__PURE__ */
|
|
5196
|
+
/* @__PURE__ */ jsxs17(Modal.Body, { children: [
|
|
4992
5197
|
/* @__PURE__ */ jsx24(
|
|
4993
5198
|
TextField,
|
|
4994
5199
|
{
|
|
@@ -5010,7 +5215,7 @@ function SessionDialogContent({
|
|
|
5010
5215
|
),
|
|
5011
5216
|
/* @__PURE__ */ jsx24(SessionDialogError, { message: mutationError })
|
|
5012
5217
|
] }),
|
|
5013
|
-
/* @__PURE__ */
|
|
5218
|
+
/* @__PURE__ */ jsxs17(Modal.Footer, { children: [
|
|
5014
5219
|
/* @__PURE__ */ jsx24(
|
|
5015
5220
|
Button4,
|
|
5016
5221
|
{
|
|
@@ -5029,12 +5234,12 @@ function SessionDialogContent({
|
|
|
5029
5234
|
);
|
|
5030
5235
|
}
|
|
5031
5236
|
if (dialog?.type !== "delete") return null;
|
|
5032
|
-
return /* @__PURE__ */
|
|
5237
|
+
return /* @__PURE__ */ jsxs17(Fragment3, { children: [
|
|
5033
5238
|
/* @__PURE__ */ jsx24(Modal.Header, { children: /* @__PURE__ */ jsx24(Modal.Heading, { children: "Delete chat?" }) }),
|
|
5034
|
-
/* @__PURE__ */
|
|
5035
|
-
/* @__PURE__ */
|
|
5239
|
+
/* @__PURE__ */ jsxs17(Modal.Body, { children: [
|
|
5240
|
+
/* @__PURE__ */ jsxs17("p", { children: [
|
|
5036
5241
|
"Are you sure you want to delete ",
|
|
5037
|
-
/* @__PURE__ */
|
|
5242
|
+
/* @__PURE__ */ jsxs17("strong", { children: [
|
|
5038
5243
|
"\u201C",
|
|
5039
5244
|
dialog.item.title,
|
|
5040
5245
|
"\u201D"
|
|
@@ -5043,7 +5248,7 @@ function SessionDialogContent({
|
|
|
5043
5248
|
] }),
|
|
5044
5249
|
/* @__PURE__ */ jsx24(SessionDialogError, { message: mutationError })
|
|
5045
5250
|
] }),
|
|
5046
|
-
/* @__PURE__ */
|
|
5251
|
+
/* @__PURE__ */ jsxs17(Modal.Footer, { children: [
|
|
5047
5252
|
/* @__PURE__ */ jsx24(Button4, { fullWidth: true, isDisabled: isPending, variant: "outline", onPress: onClose, children: "Cancel" }),
|
|
5048
5253
|
/* @__PURE__ */ jsx24(Button4, { fullWidth: true, isPending, variant: "danger", onPress: () => void onDelete(), children: isPending ? "Deleting\u2026" : "Delete" })
|
|
5049
5254
|
] })
|
|
@@ -5054,7 +5259,7 @@ function SessionDialogError({ message }) {
|
|
|
5054
5259
|
}
|
|
5055
5260
|
|
|
5056
5261
|
// src/embed/startup-activity-status.tsx
|
|
5057
|
-
import { useEffect as useEffect12, useState as
|
|
5262
|
+
import { useEffect as useEffect12, useState as useState12 } from "react";
|
|
5058
5263
|
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
5059
5264
|
var STARTUP_ACTIVITY_STATUSES = [
|
|
5060
5265
|
"Thinking\u2026",
|
|
@@ -5063,7 +5268,7 @@ var STARTUP_ACTIVITY_STATUSES = [
|
|
|
5063
5268
|
];
|
|
5064
5269
|
var STARTUP_ACTIVITY_STATUS_INTERVAL_MS = 1600;
|
|
5065
5270
|
function StartupActivityStatus() {
|
|
5066
|
-
const [statusIndex, setStatusIndex] =
|
|
5271
|
+
const [statusIndex, setStatusIndex] = useState12(0);
|
|
5067
5272
|
useEffect12(() => {
|
|
5068
5273
|
const timers = STARTUP_ACTIVITY_STATUSES.slice(1).map(
|
|
5069
5274
|
(_, index) => window.setTimeout(
|
|
@@ -5106,7 +5311,7 @@ function restoreTriggerSession(stored, bootstrapStatus) {
|
|
|
5106
5311
|
}
|
|
5107
5312
|
|
|
5108
5313
|
// src/embed/use-composer-draft.ts
|
|
5109
|
-
import { useCallback as useCallback9, useEffect as useEffect13, useRef as
|
|
5314
|
+
import { useCallback as useCallback9, useEffect as useEffect13, useRef as useRef13, useState as useState13 } from "react";
|
|
5110
5315
|
var AGENT_COMPOSER_DRAFT_SAVE_DEBOUNCE_MS = 300;
|
|
5111
5316
|
function useComposerDraft({
|
|
5112
5317
|
attachments,
|
|
@@ -5115,10 +5320,10 @@ function useComposerDraft({
|
|
|
5115
5320
|
setAttachments,
|
|
5116
5321
|
setInput
|
|
5117
5322
|
}) {
|
|
5118
|
-
const [restoredImageDraftKey, setRestoredImageDraftKey] =
|
|
5119
|
-
const [restoredPromptDraftKey, setRestoredPromptDraftKey] =
|
|
5120
|
-
const latestInputRef =
|
|
5121
|
-
const saveTimeoutRef =
|
|
5323
|
+
const [restoredImageDraftKey, setRestoredImageDraftKey] = useState13(null);
|
|
5324
|
+
const [restoredPromptDraftKey, setRestoredPromptDraftKey] = useState13(null);
|
|
5325
|
+
const latestInputRef = useRef13(input);
|
|
5326
|
+
const saveTimeoutRef = useRef13(null);
|
|
5122
5327
|
useEffect13(() => {
|
|
5123
5328
|
latestInputRef.current = input;
|
|
5124
5329
|
}, [input]);
|
|
@@ -5169,7 +5374,7 @@ function useComposerDraft({
|
|
|
5169
5374
|
}
|
|
5170
5375
|
|
|
5171
5376
|
// src/embed/use-persisted-model-selection.ts
|
|
5172
|
-
import { useCallback as useCallback10, useState as
|
|
5377
|
+
import { useCallback as useCallback10, useState as useState14 } from "react";
|
|
5173
5378
|
function agentModelPreferenceStorageKey(identityStorageKey) {
|
|
5174
5379
|
return `${identityStorageKey}:model`;
|
|
5175
5380
|
}
|
|
@@ -5197,7 +5402,7 @@ function storeModelPreference(identityStorageKey, modelId) {
|
|
|
5197
5402
|
}
|
|
5198
5403
|
}
|
|
5199
5404
|
function usePersistedModelSelection(identityStorageKey, configuredDefaultModelId) {
|
|
5200
|
-
const [preferredModelId, setPreferredModelId] =
|
|
5405
|
+
const [preferredModelId, setPreferredModelId] = useState14(
|
|
5201
5406
|
() => readStoredModelPreference(identityStorageKey)
|
|
5202
5407
|
);
|
|
5203
5408
|
const selectedModelId = preferredModelId ?? configuredDefaultModelId ?? DEFAULT_AGENT_PICKER_MODEL_ID;
|
|
@@ -5312,7 +5517,7 @@ async function transcribeVoiceRecording({
|
|
|
5312
5517
|
}
|
|
5313
5518
|
|
|
5314
5519
|
// src/embed/embed-runtime.tsx
|
|
5315
|
-
import { Fragment as Fragment4, jsx as jsx26, jsxs as
|
|
5520
|
+
import { Fragment as Fragment4, jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
5316
5521
|
var TRANSPORT_COMPLETION_WATCHDOG_MS = 3e4;
|
|
5317
5522
|
function createReconciliationDeferred() {
|
|
5318
5523
|
let resolve;
|
|
@@ -5355,14 +5560,14 @@ function EmbedRuntime({
|
|
|
5355
5560
|
() => new EmbedSessionManager(options.agentId, options.getAuthToken),
|
|
5356
5561
|
[options.getAuthToken, options.agentId]
|
|
5357
5562
|
);
|
|
5358
|
-
const [activeConversationId, setActiveConversationId] =
|
|
5359
|
-
const [runtimeRoutes, setRuntimeRoutes] =
|
|
5360
|
-
const runtimeRoutesRef =
|
|
5361
|
-
const activeConversationIdRef =
|
|
5362
|
-
const [error, setError] =
|
|
5363
|
-
const [history, setHistory] =
|
|
5364
|
-
const [conversationActivity, setConversationActivity] =
|
|
5365
|
-
const [messageQueues, setMessageQueues] =
|
|
5563
|
+
const [activeConversationId, setActiveConversationId] = useState15(null);
|
|
5564
|
+
const [runtimeRoutes, setRuntimeRoutes] = useState15({});
|
|
5565
|
+
const runtimeRoutesRef = useRef14(runtimeRoutes);
|
|
5566
|
+
const activeConversationIdRef = useRef14(activeConversationId);
|
|
5567
|
+
const [error, setError] = useState15(null);
|
|
5568
|
+
const [history, setHistory] = useState15([]);
|
|
5569
|
+
const [conversationActivity, setConversationActivity] = useState15(createConversationActivityState);
|
|
5570
|
+
const [messageQueues, setMessageQueues] = useState15({});
|
|
5366
5571
|
const runtime = activeConversationId ? runtimeRoutes[activeConversationId] ?? null : null;
|
|
5367
5572
|
useLayoutEffect4(() => {
|
|
5368
5573
|
runtimeRoutesRef.current = runtimeRoutes;
|
|
@@ -5405,7 +5610,7 @@ function EmbedRuntime({
|
|
|
5405
5610
|
},
|
|
5406
5611
|
[]
|
|
5407
5612
|
);
|
|
5408
|
-
const bootstrapCacheRef =
|
|
5613
|
+
const bootstrapCacheRef = useRef14(null);
|
|
5409
5614
|
const apiBaseUrl = options.apiBaseUrl;
|
|
5410
5615
|
const agentId = options.agentId;
|
|
5411
5616
|
const notifyReady = useEffectEvent(onReady);
|
|
@@ -5423,7 +5628,7 @@ function EmbedRuntime({
|
|
|
5423
5628
|
const reportEmbedLoaded = useEffectEvent((conversationId) => {
|
|
5424
5629
|
void reportEvent(options, tokenManager, conversationId, "embed_loaded");
|
|
5425
5630
|
});
|
|
5426
|
-
const appliedIdentityEpochRef =
|
|
5631
|
+
const appliedIdentityEpochRef = useRef14(identityEpoch);
|
|
5427
5632
|
useLayoutEffect4(() => {
|
|
5428
5633
|
if (appliedIdentityEpochRef.current === identityEpoch) return;
|
|
5429
5634
|
appliedIdentityEpochRef.current = identityEpoch;
|
|
@@ -5584,7 +5789,7 @@ function EmbedRuntime({
|
|
|
5584
5789
|
),
|
|
5585
5790
|
[clientToolValidationError, options.permissionDefaultMode, options.tools]
|
|
5586
5791
|
);
|
|
5587
|
-
const preloadedConversationIds =
|
|
5792
|
+
const preloadedConversationIds = useRef14(/* @__PURE__ */ new Set());
|
|
5588
5793
|
const warmAgentSession = useEffectEvent((conversationId) => {
|
|
5589
5794
|
preloadedConversationIds.current.add(conversationId);
|
|
5590
5795
|
void preloadAgentSession(options, tokenManager, conversationId, preloadClientTools);
|
|
@@ -5700,7 +5905,7 @@ function EmbedRuntime({
|
|
|
5700
5905
|
);
|
|
5701
5906
|
}, [options.suggestedPrompts, runtimeRoutes]);
|
|
5702
5907
|
const runtimeConfig = activeConversationId ? configuredRuntimeRoutes[activeConversationId]?.config ?? null : null;
|
|
5703
|
-
const openedConversationRef =
|
|
5908
|
+
const openedConversationRef = useRef14(null);
|
|
5704
5909
|
useEffect14(() => {
|
|
5705
5910
|
if (!open || !runtime || openedConversationRef.current === runtime.conversationId) return;
|
|
5706
5911
|
openedConversationRef.current = runtime.conversationId;
|
|
@@ -5710,7 +5915,7 @@ function EmbedRuntime({
|
|
|
5710
5915
|
const conversationGroups = useMemo4(() => groupConversationHistory(history), [history]);
|
|
5711
5916
|
const activeConversationTitle = history.find((conversation) => conversation.id === activeConversationId)?.title ?? "New chat";
|
|
5712
5917
|
const loadingMessage = bootstrapCacheRef.current ? "Loading chat\u2026" : "Loading assistant\u2026";
|
|
5713
|
-
return /* @__PURE__ */
|
|
5918
|
+
return /* @__PURE__ */ jsxs18(Fragment4, { children: [
|
|
5714
5919
|
open && runtime?.config.presence ? /* @__PURE__ */ jsx26(
|
|
5715
5920
|
AgentConversationPresence,
|
|
5716
5921
|
{
|
|
@@ -5720,7 +5925,7 @@ function EmbedRuntime({
|
|
|
5720
5925
|
userId: runtime.presenceUserId
|
|
5721
5926
|
}
|
|
5722
5927
|
) : null,
|
|
5723
|
-
/* @__PURE__ */
|
|
5928
|
+
/* @__PURE__ */ jsxs18(
|
|
5724
5929
|
PanelShell,
|
|
5725
5930
|
{
|
|
5726
5931
|
actionsSlot: /* @__PURE__ */ jsx26(NewChatButton, { onPress: onNewConversation }),
|
|
@@ -5827,11 +6032,11 @@ function ChatRuntime({
|
|
|
5827
6032
|
const permissionStorageKey = agentPermissionModeStorageKey(storageKey, conversationId);
|
|
5828
6033
|
const attachmentPolicyKey = options.composerAttachmentAccept;
|
|
5829
6034
|
const attachmentPolicy = useMemo4(() => ({ key: attachmentPolicyKey }), [attachmentPolicyKey]);
|
|
5830
|
-
const [attachmentSelection, setAttachmentSelection] =
|
|
6035
|
+
const [attachmentSelection, setAttachmentSelection] = useState15(() => ({
|
|
5831
6036
|
files: [],
|
|
5832
6037
|
policy: attachmentPolicy
|
|
5833
6038
|
}));
|
|
5834
|
-
const [attachmentErrorSelection, setAttachmentErrorSelection] =
|
|
6039
|
+
const [attachmentErrorSelection, setAttachmentErrorSelection] = useState15(() => ({
|
|
5835
6040
|
error: null,
|
|
5836
6041
|
policy: attachmentPolicy
|
|
5837
6042
|
}));
|
|
@@ -5857,16 +6062,16 @@ function ChatRuntime({
|
|
|
5857
6062
|
(error) => setAttachmentErrorSelection({ error, policy: attachmentPolicy }),
|
|
5858
6063
|
[attachmentPolicy]
|
|
5859
6064
|
);
|
|
5860
|
-
const [activeTurnSelection, setActiveTurnSelectionState] =
|
|
6065
|
+
const [activeTurnSelection, setActiveTurnSelectionState] = useState15(() => {
|
|
5861
6066
|
const storedMode = shouldRestoreActivePermission ? readStoredAgentPermissionMode(activePermissionStorageKey) : void 0;
|
|
5862
6067
|
const restoredMode = storedMode ?? (shouldRestoreActivePermission ? "ask" : void 0);
|
|
5863
6068
|
return restoredMode ? { modelId: void 0, permissionMode: restoredMode } : void 0;
|
|
5864
6069
|
});
|
|
5865
|
-
const [activityTimings, setActivityTimings] =
|
|
5866
|
-
const [feedbackByMessage, setFeedbackByMessage] =
|
|
5867
|
-
const [isComposerExpanded, setIsComposerExpanded] =
|
|
5868
|
-
const [input, setInput] =
|
|
5869
|
-
const [permissionSelection, setPermissionSelection] =
|
|
6070
|
+
const [activityTimings, setActivityTimings] = useState15({});
|
|
6071
|
+
const [feedbackByMessage, setFeedbackByMessage] = useState15({});
|
|
6072
|
+
const [isComposerExpanded, setIsComposerExpanded] = useState15(false);
|
|
6073
|
+
const [input, setInput] = useState15("");
|
|
6074
|
+
const [permissionSelection, setPermissionSelection] = useState15(() => {
|
|
5870
6075
|
const storedMode = options.permissionShowPicker ? readStoredAgentPermissionMode(permissionStorageKey) : void 0;
|
|
5871
6076
|
const hasUnresolvedClientTool = options.permissionShowPicker && initialMessages.some(
|
|
5872
6077
|
(message) => message.role === "assistant" && message.parts.some((part) => {
|
|
@@ -5882,19 +6087,19 @@ function ChatRuntime({
|
|
|
5882
6087
|
selectedMode: storedMode ?? (hasUnresolvedClientTool ? "ask" : options.permissionDefaultMode)
|
|
5883
6088
|
};
|
|
5884
6089
|
});
|
|
5885
|
-
const [isQueueReordering, setIsQueueReordering] =
|
|
5886
|
-
const [isReconciling, setIsReconciling] =
|
|
5887
|
-
const [localPending, setLocalPending] =
|
|
5888
|
-
const [pendingClientToolCallIds, setPendingClientToolCallIds] =
|
|
6090
|
+
const [isQueueReordering, setIsQueueReordering] = useState15(false);
|
|
6091
|
+
const [isReconciling, setIsReconciling] = useState15(false);
|
|
6092
|
+
const [localPending, setLocalPending] = useState15(false);
|
|
6093
|
+
const [pendingClientToolCallIds, setPendingClientToolCallIds] = useState15(
|
|
5889
6094
|
() => /* @__PURE__ */ new Set()
|
|
5890
6095
|
);
|
|
5891
|
-
const [isResuming, setIsResuming] =
|
|
5892
|
-
const [progress, setProgress] =
|
|
5893
|
-
const [queueDrainVersion, setQueueDrainVersion] =
|
|
5894
|
-
const [reconcileEpoch, setReconcileEpoch] =
|
|
5895
|
-
const [recoveryError, setRecoveryError] =
|
|
5896
|
-
const [selection, setSelection] =
|
|
5897
|
-
const [toolDecisions, setToolDecisions] =
|
|
6096
|
+
const [isResuming, setIsResuming] = useState15(true);
|
|
6097
|
+
const [progress, setProgress] = useState15(null);
|
|
6098
|
+
const [queueDrainVersion, setQueueDrainVersion] = useState15(0);
|
|
6099
|
+
const [reconcileEpoch, setReconcileEpoch] = useState15(0);
|
|
6100
|
+
const [recoveryError, setRecoveryError] = useState15(false);
|
|
6101
|
+
const [selection, setSelection] = useState15(null);
|
|
6102
|
+
const [toolDecisions, setToolDecisions] = useState15({});
|
|
5898
6103
|
useEffect14(() => {
|
|
5899
6104
|
if (!shouldRestoreActivePermission) {
|
|
5900
6105
|
clearStoredAgentPermissionMode(activePermissionStorageKey);
|
|
@@ -5932,7 +6137,7 @@ function ChatRuntime({
|
|
|
5932
6137
|
() => serializeClientTools(effectiveClientTools),
|
|
5933
6138
|
[effectiveClientTools]
|
|
5934
6139
|
);
|
|
5935
|
-
const clientToolManifestRef =
|
|
6140
|
+
const clientToolManifestRef = useRef14(clientToolManifest);
|
|
5936
6141
|
useLayoutEffect4(() => {
|
|
5937
6142
|
clientToolManifestRef.current = clientToolManifest;
|
|
5938
6143
|
}, [clientToolManifest]);
|
|
@@ -5941,27 +6146,27 @@ function ChatRuntime({
|
|
|
5941
6146
|
() => new Map(effectiveClientTools.map((tool) => [tool.name, tool])),
|
|
5942
6147
|
[effectiveClientTools]
|
|
5943
6148
|
);
|
|
5944
|
-
const executedToolCallsRef =
|
|
5945
|
-
const activeMessageIdRef =
|
|
5946
|
-
const isBusyRef =
|
|
5947
|
-
const isQueueReorderingRef =
|
|
5948
|
-
const messageQueueRef =
|
|
5949
|
-
const pendingTurnAnchorRef =
|
|
5950
|
-
const reconciliationDeferredRef =
|
|
5951
|
-
const reconcileMessageIdRef =
|
|
5952
|
-
const resumePromiseRef =
|
|
5953
|
-
const manualStopRequestedRef =
|
|
5954
|
-
const sendAcknowledgedRef =
|
|
5955
|
-
const sendErrorRef =
|
|
5956
|
-
const streamedMessageIdsRef =
|
|
5957
|
-
const timedMessageIdRef =
|
|
5958
|
-
const transportFailureRef =
|
|
5959
|
-
const turnStartedAtRef =
|
|
5960
|
-
const needsReconciliationRef =
|
|
5961
|
-
const clearChatErrorRef =
|
|
5962
|
-
const fileInputRef =
|
|
5963
|
-
const messageQueueListRef =
|
|
5964
|
-
const textareaRef =
|
|
6149
|
+
const executedToolCallsRef = useRef14(/* @__PURE__ */ new Set());
|
|
6150
|
+
const activeMessageIdRef = useRef14(null);
|
|
6151
|
+
const isBusyRef = useRef14(true);
|
|
6152
|
+
const isQueueReorderingRef = useRef14(false);
|
|
6153
|
+
const messageQueueRef = useRef14(messageQueue);
|
|
6154
|
+
const pendingTurnAnchorRef = useRef14(null);
|
|
6155
|
+
const reconciliationDeferredRef = useRef14(null);
|
|
6156
|
+
const reconcileMessageIdRef = useRef14(void 0);
|
|
6157
|
+
const resumePromiseRef = useRef14(null);
|
|
6158
|
+
const manualStopRequestedRef = useRef14(false);
|
|
6159
|
+
const sendAcknowledgedRef = useRef14(false);
|
|
6160
|
+
const sendErrorRef = useRef14(null);
|
|
6161
|
+
const streamedMessageIdsRef = useRef14(/* @__PURE__ */ new Set());
|
|
6162
|
+
const timedMessageIdRef = useRef14(null);
|
|
6163
|
+
const transportFailureRef = useRef14(null);
|
|
6164
|
+
const turnStartedAtRef = useRef14(null);
|
|
6165
|
+
const needsReconciliationRef = useRef14(false);
|
|
6166
|
+
const clearChatErrorRef = useRef14(() => void 0);
|
|
6167
|
+
const fileInputRef = useRef14(null);
|
|
6168
|
+
const messageQueueListRef = useRef14(null);
|
|
6169
|
+
const textareaRef = useRef14(null);
|
|
5965
6170
|
const composerDraftKey = useMemo4(
|
|
5966
6171
|
() => agentComposerDraftStorageKey(storageKey, conversationId),
|
|
5967
6172
|
[conversationId, storageKey]
|
|
@@ -6459,8 +6664,11 @@ function ChatRuntime({
|
|
|
6459
6664
|
turnStartedAtRef.current = Date.now();
|
|
6460
6665
|
prepareTransportSend();
|
|
6461
6666
|
pendingTurnAnchorRef.current = {
|
|
6462
|
-
|
|
6463
|
-
|
|
6667
|
+
previousUserMessageId: previousUserMessageId ?? null,
|
|
6668
|
+
// A failed queued message can be sent again with the same message id.
|
|
6669
|
+
// Use a fresh key per actual send attempt so each user-triggered send
|
|
6670
|
+
// receives its one permitted viewport movement.
|
|
6671
|
+
scrollKey: crypto.randomUUID()
|
|
6464
6672
|
};
|
|
6465
6673
|
setLocalPending(true);
|
|
6466
6674
|
setRecoveryError(false);
|
|
@@ -6481,6 +6689,7 @@ function ChatRuntime({
|
|
|
6481
6689
|
clientTools: messageClientToolManifest,
|
|
6482
6690
|
...message.modelId ? { modelId: message.modelId } : {},
|
|
6483
6691
|
imageSearch: options.imageSearch,
|
|
6692
|
+
newsSearch: options.newsSearch,
|
|
6484
6693
|
pageContext,
|
|
6485
6694
|
webSearch: options.webSearch
|
|
6486
6695
|
};
|
|
@@ -6836,6 +7045,7 @@ function ChatRuntime({
|
|
|
6836
7045
|
clientTools: retryClientToolManifest,
|
|
6837
7046
|
...composerModelId ? { modelId: composerModelId } : {},
|
|
6838
7047
|
imageSearch: options.imageSearch,
|
|
7048
|
+
newsSearch: options.newsSearch,
|
|
6839
7049
|
pageContext,
|
|
6840
7050
|
webSearch: options.webSearch
|
|
6841
7051
|
}
|
|
@@ -6860,8 +7070,7 @@ function ChatRuntime({
|
|
|
6860
7070
|
)?.id;
|
|
6861
7071
|
const lastUserMessageId = chatState.messages.findLast((message) => message.role === "user")?.id;
|
|
6862
7072
|
const { activeStreamKey, activeTurnMessageId } = resolveConversationTurnAnchor({
|
|
6863
|
-
|
|
6864
|
-
isActive: localPending || isRunning,
|
|
7073
|
+
isActive: hasActiveTurn,
|
|
6865
7074
|
lastUserMessageId,
|
|
6866
7075
|
pendingTurn: pendingTurnAnchorRef.current
|
|
6867
7076
|
});
|
|
@@ -6877,9 +7086,9 @@ function ChatRuntime({
|
|
|
6877
7086
|
const dictationButtonLabel = isDictationTranscribing ? "Cancel transcription" : isDictating ? "Stop dictation" : "Dictate message";
|
|
6878
7087
|
const dictationButtonTitle = isDictationSupported ? dictationButtonLabel : "Voice dictation is not supported in this browser";
|
|
6879
7088
|
const sendButtonLabel = isRunning && !hasComposerDraft ? "Stop answering" : isBusy ? "Queue message" : "Send message";
|
|
6880
|
-
return /* @__PURE__ */
|
|
6881
|
-
/* @__PURE__ */
|
|
6882
|
-
showHome ? /* @__PURE__ */
|
|
7089
|
+
return /* @__PURE__ */ jsxs18(Fragment4, { children: [
|
|
7090
|
+
/* @__PURE__ */ jsxs18(ConversationViewport, { streamKey: activeStreamKey, children: [
|
|
7091
|
+
showHome ? /* @__PURE__ */ jsxs18("div", { className: "ha-empty", children: [
|
|
6883
7092
|
/* @__PURE__ */ jsx26("h2", { children: options.greeting }),
|
|
6884
7093
|
/* @__PURE__ */ jsx26("p", { children: "Live answers with charts, metrics, and tables." })
|
|
6885
7094
|
] }) : chatState.messages.map((message) => /* @__PURE__ */ jsx26(
|
|
@@ -6909,13 +7118,13 @@ function ChatRuntime({
|
|
|
6909
7118
|
message.id
|
|
6910
7119
|
)),
|
|
6911
7120
|
standaloneStatus && (active || standaloneStatus !== DEFAULT_ACTIVITY_STATUS) ? /* @__PURE__ */ jsx26("div", { className: "ha-message", "data-role": "assistant", "data-stream-anchor": "true", children: /* @__PURE__ */ jsx26("div", { className: "ha-message-body", children: standaloneStatus === DEFAULT_ACTIVITY_STATUS ? /* @__PURE__ */ jsx26(StartupActivityStatus, {}, activeStreamKey ?? conversationId) : /* @__PURE__ */ jsx26(ActivityStatus, { label: standaloneStatus }) }) }) : null,
|
|
6912
|
-
chatState.error || recoveryError ? /* @__PURE__ */
|
|
7121
|
+
chatState.error || recoveryError ? /* @__PURE__ */ jsxs18("div", { className: "ha-error", role: "alert", children: [
|
|
6913
7122
|
/* @__PURE__ */ jsx26("span", { children: "The request could not be completed." }),
|
|
6914
7123
|
/* @__PURE__ */ jsx26("button", { type: "button", onClick: retryLastResponse, children: "Retry" })
|
|
6915
7124
|
] }) : null
|
|
6916
7125
|
] }),
|
|
6917
|
-
/* @__PURE__ */
|
|
6918
|
-
showHome && visibleSuggestedPrompts.length > 0 ? /* @__PURE__ */ jsx26("div", { "aria-label": "Suggested prompts", className: "ha-suggestions", role: "group", children: visibleSuggestedPrompts.map((prompt, index) => /* @__PURE__ */
|
|
7126
|
+
/* @__PURE__ */ jsxs18("form", { className: "ha-composer-wrap", onSubmit: submit, children: [
|
|
7127
|
+
showHome && visibleSuggestedPrompts.length > 0 ? /* @__PURE__ */ jsx26("div", { "aria-label": "Suggested prompts", className: "ha-suggestions", role: "group", children: visibleSuggestedPrompts.map((prompt, index) => /* @__PURE__ */ jsxs18(
|
|
6919
7128
|
"button",
|
|
6920
7129
|
{
|
|
6921
7130
|
className: "ha-suggestion",
|
|
@@ -6924,7 +7133,7 @@ function ChatRuntime({
|
|
|
6924
7133
|
onClick: () => submitComposerMessage(prompt),
|
|
6925
7134
|
children: [
|
|
6926
7135
|
/* @__PURE__ */ jsx26("span", { children: prompt }),
|
|
6927
|
-
options.suggestedPromptShortcuts ? /* @__PURE__ */
|
|
7136
|
+
options.suggestedPromptShortcuts ? /* @__PURE__ */ jsxs18("span", { "aria-hidden": "true", className: "ha-suggestion-shortcut", children: [
|
|
6928
7137
|
/* @__PURE__ */ jsx26("kbd", { children: "Ctrl" }),
|
|
6929
7138
|
/* @__PURE__ */ jsx26("kbd", { children: index + 1 })
|
|
6930
7139
|
] }) : /* @__PURE__ */ jsx26(ArrowUpRight, { "aria-hidden": "true" })
|
|
@@ -6948,7 +7157,7 @@ function ChatRuntime({
|
|
|
6948
7157
|
onSendNow: sendQueuedMessageNow
|
|
6949
7158
|
}
|
|
6950
7159
|
),
|
|
6951
|
-
/* @__PURE__ */
|
|
7160
|
+
/* @__PURE__ */ jsxs18(
|
|
6952
7161
|
ComposerFileDropzone,
|
|
6953
7162
|
{
|
|
6954
7163
|
className: "@container ha-composer",
|
|
@@ -7030,7 +7239,7 @@ function ChatRuntime({
|
|
|
7030
7239
|
}
|
|
7031
7240
|
}
|
|
7032
7241
|
),
|
|
7033
|
-
isDictating ? /* @__PURE__ */ jsx26("div", { className: "ha-dictation-session", children: isDictationTranscribing ? /* @__PURE__ */ jsx26("span", { className: "ha-dictation-status", role: "status", children: "Transcribing\u2026" }) : /* @__PURE__ */
|
|
7242
|
+
isDictating ? /* @__PURE__ */ jsx26("div", { className: "ha-dictation-session", children: isDictationTranscribing ? /* @__PURE__ */ jsx26("span", { className: "ha-dictation-status", role: "status", children: "Transcribing\u2026" }) : /* @__PURE__ */ jsxs18(Fragment4, { children: [
|
|
7034
7243
|
/* @__PURE__ */ jsx26(
|
|
7035
7244
|
VoiceLiveWaveform,
|
|
7036
7245
|
{
|
|
@@ -7072,7 +7281,7 @@ function ChatRuntime({
|
|
|
7072
7281
|
onChange: setSelectedModelId
|
|
7073
7282
|
}
|
|
7074
7283
|
) : null,
|
|
7075
|
-
options.composerDictation ? /* @__PURE__ */
|
|
7284
|
+
options.composerDictation ? /* @__PURE__ */ jsxs18(
|
|
7076
7285
|
"button",
|
|
7077
7286
|
{
|
|
7078
7287
|
"aria-keyshortcuts": isDictationSupported ? DICTATION_KEYBOARD_SHORTCUT : void 0,
|
|
@@ -7097,7 +7306,7 @@ function ChatRuntime({
|
|
|
7097
7306
|
}
|
|
7098
7307
|
) : null,
|
|
7099
7308
|
attachmentError || options.composerDictation && dictationError ? /* @__PURE__ */ jsx26("span", { className: "ha-dictation-error", role: "alert", children: attachmentError ?? dictationError }) : null,
|
|
7100
|
-
isRunning && !hasComposerDraft ? /* @__PURE__ */
|
|
7309
|
+
isRunning && !hasComposerDraft ? /* @__PURE__ */ jsxs18(
|
|
7101
7310
|
"button",
|
|
7102
7311
|
{
|
|
7103
7312
|
"aria-keyshortcuts": COMPOSER_ACTION_KEYBOARD_SHORTCUT,
|
|
@@ -7112,7 +7321,7 @@ function ChatRuntime({
|
|
|
7112
7321
|
/* @__PURE__ */ jsx26(ComposerControlTooltip, { shortcut: COMPOSER_ACTION_SHORTCUT_LABEL, children: sendButtonLabel })
|
|
7113
7322
|
]
|
|
7114
7323
|
}
|
|
7115
|
-
) : /* @__PURE__ */
|
|
7324
|
+
) : /* @__PURE__ */ jsxs18(
|
|
7116
7325
|
"button",
|
|
7117
7326
|
{
|
|
7118
7327
|
"aria-keyshortcuts": COMPOSER_ACTION_KEYBOARD_SHORTCUT,
|
|
@@ -7168,9 +7377,11 @@ function Message({
|
|
|
7168
7377
|
const userAttachments = message.role === "user" ? message.parts.flatMap(
|
|
7169
7378
|
(part, index) => part.type === "file" ? [/* @__PURE__ */ jsx26(MessageAttachment, { file: part }, `${message.id}-attachment-${index}`)] : []
|
|
7170
7379
|
) : [];
|
|
7380
|
+
let latestContentPartIndex = -1;
|
|
7171
7381
|
const content = message.parts.reduce((items, part, index) => {
|
|
7172
7382
|
if (part.type === "text") {
|
|
7173
7383
|
if (!part.text.trim()) return items;
|
|
7384
|
+
latestContentPartIndex = index;
|
|
7174
7385
|
return [
|
|
7175
7386
|
...items,
|
|
7176
7387
|
message.role === "assistant" ? /* @__PURE__ */ jsx26(
|
|
@@ -7188,9 +7399,11 @@ function Message({
|
|
|
7188
7399
|
}
|
|
7189
7400
|
if (part.type === "file") {
|
|
7190
7401
|
if (message.role === "user") return items;
|
|
7402
|
+
latestContentPartIndex = index;
|
|
7191
7403
|
return [...items, /* @__PURE__ */ jsx26(MessageAttachment, { file: part }, `${message.id}-file-${index}`)];
|
|
7192
7404
|
}
|
|
7193
7405
|
if (part.type === "data-component") {
|
|
7406
|
+
latestContentPartIndex = index;
|
|
7194
7407
|
return [
|
|
7195
7408
|
...items,
|
|
7196
7409
|
/* @__PURE__ */ jsx26(
|
|
@@ -7211,6 +7424,7 @@ function Message({
|
|
|
7211
7424
|
if (clientToolName && clientTool?.needsApproval) {
|
|
7212
7425
|
const toolPart = part;
|
|
7213
7426
|
if (toolPart.state !== "input-available" || toolDecisions[toolPart.toolCallId]) return items;
|
|
7427
|
+
latestContentPartIndex = index;
|
|
7214
7428
|
return [
|
|
7215
7429
|
...items,
|
|
7216
7430
|
/* @__PURE__ */ jsx26(
|
|
@@ -7227,6 +7441,10 @@ function Message({
|
|
|
7227
7441
|
}
|
|
7228
7442
|
return items;
|
|
7229
7443
|
}, []);
|
|
7444
|
+
const hasResponseStartedAfterLatestActivity = hasResponseAfterLatestActivity(activity, {
|
|
7445
|
+
hasContent: content.length > 0,
|
|
7446
|
+
latestContentPartIndex
|
|
7447
|
+
});
|
|
7230
7448
|
const visibleSources = getVisibleMessageSources(sources, {
|
|
7231
7449
|
hasContent: content.length > 0,
|
|
7232
7450
|
isStreaming
|
|
@@ -7235,7 +7453,7 @@ function Message({
|
|
|
7235
7453
|
return null;
|
|
7236
7454
|
}
|
|
7237
7455
|
if (message.role === "user") {
|
|
7238
|
-
return /* @__PURE__ */
|
|
7456
|
+
return /* @__PURE__ */ jsxs18(
|
|
7239
7457
|
"div",
|
|
7240
7458
|
{
|
|
7241
7459
|
className: "ha-message",
|
|
@@ -7258,11 +7476,12 @@ function Message({
|
|
|
7258
7476
|
className: "ha-message",
|
|
7259
7477
|
"data-role": "assistant",
|
|
7260
7478
|
"data-stream-anchor": isStreaming ? true : void 0,
|
|
7261
|
-
children: /* @__PURE__ */
|
|
7479
|
+
children: /* @__PURE__ */ jsxs18("div", { className: "ha-message-body", children: [
|
|
7262
7480
|
activity.length > 0 ? /* @__PURE__ */ jsx26(
|
|
7263
7481
|
ActivityTrail,
|
|
7264
7482
|
{
|
|
7265
7483
|
completedAt: activityTiming?.completedAt,
|
|
7484
|
+
hasResponseStarted: hasResponseStartedAfterLatestActivity,
|
|
7266
7485
|
isStreaming,
|
|
7267
7486
|
items: activity,
|
|
7268
7487
|
progress,
|
|
@@ -7326,7 +7545,7 @@ function useAgentTransport({
|
|
|
7326
7545
|
const session = restoreTriggerSession(stored, bootstrapStatus);
|
|
7327
7546
|
return session ? { [conversationId]: session } : void 0;
|
|
7328
7547
|
}, [bootstrapStatus, conversationId, sessionKey]);
|
|
7329
|
-
const reportedReconnectRef =
|
|
7548
|
+
const reportedReconnectRef = useRef14(false);
|
|
7330
7549
|
const authorizedFetch = useCallback11(
|
|
7331
7550
|
(url, init = {}) => fetchWithAgentAuthorization(tokenManager, url, init),
|
|
7332
7551
|
[tokenManager]
|
|
@@ -7370,6 +7589,7 @@ function useAgentTransport({
|
|
|
7370
7589
|
clientTools: getClientToolManifest(),
|
|
7371
7590
|
...requestedModelId ? { modelId: requestedModelId } : {},
|
|
7372
7591
|
imageSearch: options.imageSearch,
|
|
7592
|
+
newsSearch: options.newsSearch,
|
|
7373
7593
|
pageContext,
|
|
7374
7594
|
protocolVersion: HEROUI_AGENT_PROTOCOL_VERSION,
|
|
7375
7595
|
sdkVersion: HEROUI_AGENT_SDK_VERSION,
|