@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.
@@ -33,7 +33,7 @@ import {
33
33
  shouldRestoreActiveAgentPermissionMode,
34
34
  storeAgentPermissionMode,
35
35
  takeAgentShellHandoff
36
- } from "./chunk-XBYPU7PM.js";
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 useRef15,
1729
- useState as useState14
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.5";
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 images. Optional (not defaulted) so schema
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
- sources: part.data.sources
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
- if (labels.has(label)) continue;
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: toolPart.state === "input-available" || toolPart.state === "input-streaming",
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 useRef6, useState as useState4 } from "react";
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, useRef as useRef5 } from "react";
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 previousValueRef = useRef5(children);
2034
- const shouldAnimate = animateOnMount || previousValueRef.current !== children;
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
- previousValueRef.current = children;
2037
- }, [children]);
2038
- return /* @__PURE__ */ jsx7(
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: /* @__PURE__ */ jsx7(
2046
- "span",
2047
- {
2048
- "aria-hidden": "true",
2049
- className: shouldAnimate ? "ha-status-text__value ha-status-text__value--animated" : "ha-status-text__value",
2050
- "data-slot": "animated-text-value",
2051
- children: /* @__PURE__ */ jsx7(ShimmerText, { children })
2052
- },
2053
- children
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 jsxs5 } from "react/jsx-runtime";
2180
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
2115
2181
  var FOLLOW_THRESHOLD_PX = 24;
2116
- function useFollowNewestStep(ref, stepCount, isStreaming, isExpanded) {
2117
- const isFollowingRef = useRef6(true);
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
- const handleScroll = () => {
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
- return () => element.removeEventListener("scroll", handleScroll);
2127
- }, [isExpanded, ref]);
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
- const element = ref.current;
2130
- if (!element || !isExpanded || !isStreaming || !isFollowingRef.current) return;
2131
- element.scrollTop = element.scrollHeight;
2132
- }, [isExpanded, isStreaming, ref, stepCount]);
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 [isExpanded, setIsExpanded] = useState4(defaultOpen);
2163
- const panelRef = useRef6(null);
2164
- const activeItem = items.findLast((item) => item.active);
2165
- const latestItem = items.at(-1);
2166
- const activeLabel = activeItem?.label ?? latestItem?.label ?? progress ?? "Understanding your request\u2026";
2167
- const elapsedMs = startedAt !== void 0 && !isStreaming ? Math.max(0, (completedAt ?? Date.now()) - startedAt) : null;
2168
- const summary = isStreaming ? activeLabel : elapsedMs === null ? "Activity" : `Worked for ${formatActivityDuration(elapsedMs)}`;
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, items.length, isStreaming, isExpanded);
2171
- return /* @__PURE__ */ jsxs5(Disclosure2, { className: "ha-activity", isExpanded, onExpandedChange: setIsExpanded, children: [
2172
- /* @__PURE__ */ jsx8(Disclosure2.Heading, { children: /* @__PURE__ */ jsxs5(Disclosure2.Trigger, { className: "ha-activity-trigger", children: [
2173
- isStreaming ? /* @__PURE__ */ jsx8(
2174
- AnimatedStatusText,
2175
- {
2176
- animateOnMount: summary !== progress,
2177
- className: "ha-activity-summary-label ha-progress ha-progress-shimmer",
2178
- role: "status",
2179
- children: summary
2180
- }
2181
- ) : /* @__PURE__ */ jsx8("span", { className: "ha-progress", children: summary }),
2182
- /* @__PURE__ */ jsx8(Disclosure2.Indicator, { className: "ha-activity-chevron" })
2183
- ] }) }),
2184
- /* @__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__ */ jsxs5("ol", { "aria-label": "Thinking steps", children: [
2185
- items.map((item) => {
2186
- const Icon = activityIcons[item.kind ?? inferActivityKind(item.label)];
2187
- return /* @__PURE__ */ jsxs5(
2188
- "li",
2189
- {
2190
- "aria-current": item.active ? "step" : void 0,
2191
- className: "ha-activity-item",
2192
- "data-active": item.active || void 0,
2193
- children: [
2194
- /* @__PURE__ */ jsx8("span", { className: "ha-activity-icon", children: /* @__PURE__ */ jsx8(Icon, { "aria-hidden": "true" }) }),
2195
- /* @__PURE__ */ jsxs5("span", { className: "ha-activity-content", children: [
2196
- item.active ? /* @__PURE__ */ jsx8(AnimatedStatusText, { className: "ha-progress-shimmer", children: item.label }) : /* @__PURE__ */ jsx8("span", { children: item.label }),
2197
- item.detail ? /* @__PURE__ */ jsx8("small", { children: item.detail }) : null,
2198
- item.sources?.length ? /* @__PURE__ */ jsx8("span", { "aria-label": "Sources", className: "ha-activity-sources", children: item.sources.map((source) => /* @__PURE__ */ jsxs5("span", { className: "ha-activity-source", children: [
2199
- /* @__PURE__ */ jsx8(Globe, { "aria-hidden": "true" }),
2200
- source.label
2201
- ] }, source.label)) }) : null
2202
- ] })
2203
- ]
2204
- },
2205
- item.id
2206
- );
2207
- }),
2208
- !isStreaming ? /* @__PURE__ */ jsxs5("li", { className: "ha-activity-item", "data-complete": "true", children: [
2209
- /* @__PURE__ */ jsx8("span", { className: "ha-activity-icon", children: /* @__PURE__ */ jsx8(CircleCheck, { "aria-hidden": "true" }) }),
2210
- /* @__PURE__ */ jsx8("span", { className: "ha-activity-content", children: /* @__PURE__ */ jsx8("span", { children: "Done" }) })
2211
- ] }) : null
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 jsxs6 } from "react/jsx-runtime";
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__ */ jsxs6("span", { className: "ha-attachment", "data-kind": kind, children: [
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__ */ jsxs6("span", { className: "ha-attachment-copy", children: [
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 jsxs7 } from "react/jsx-runtime";
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__ */ jsxs7(
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__ */ jsxs7("span", { className: "ha-chip-title", title, children: [
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 useState5 } from "react";
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] = useState5(false);
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 jsxs8 } from "react/jsx-runtime";
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__ */ jsxs8(Table.Content, { "aria-label": "Markdown table", children: [
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?.messageId ?? activeTurnMessageId ?? conversationId : null;
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 useRef8 } from "react";
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 useRef7, useState as useState6 } from "react";
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 STREAM_ANCHOR_SELECTOR = '[data-stream-anchor="true"]';
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 = useRef7(0);
2954
- const attachedRef = useRef7(true);
2955
- const currentStreamKeyRef = useRef7(null);
2956
- const isAutoScrollingRef = useRef7(false);
2957
- const isPinnedTurnAnimatingRef = useRef7(false);
2958
- const lastScrollTopRef = useRef7(0);
2959
- const pinnedStreamKeyRef = useRef7(null);
2960
- const pinnedStreamTopRef = useRef7(null);
2961
- const shouldAnimatePinnedTurnRef = useRef7(false);
2962
- const [scrollState, setScrollState] = useState6(DEFAULT_SCROLL_STATE);
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 = element.querySelector(STREAM_ANCHOR_SELECTOR) ?? element.querySelector(TURN_ANCHOR_SELECTOR);
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
- isAutoScrollingRef.current = true;
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(STREAM_ANCHOR_SELECTOR);
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
- isPinnedTurnAnimatingRef.current = nativeBehavior === "smooth" && Math.abs(Math.max(0, element.scrollTop) - targetTop) > SCROLL_DIRECTION_THRESHOLD;
3030
- isAutoScrollingRef.current = true;
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
- const activeTurnSpacerHeight = updateActiveTurnSpacer(element);
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
- if (attachedRef.current) {
3068
- const pinnedStreamTop = getPinnedStreamTop(element);
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 && activeTurnSpacerHeight > BOTTOM_THRESHOLD) {
3080
- const behavior = shouldAnimatePinnedTurnRef.current ? "smooth" : "auto";
3260
+ if (pinnedStreamTop !== null && shouldAnimatePinnedTurnRef.current) {
3081
3261
  shouldAnimatePinnedTurnRef.current = false;
3082
- scrollToPinnedPosition(element, pinnedStreamTop, behavior);
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({ hasOverflow: measuredState.hasOverflow, isAtBottom: false });
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
- if (!hadActiveStream) {
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 = measuredState.isAtBottom;
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 jsxs9 } from "react/jsx-runtime";
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 = useRef8(null);
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__ */ jsxs9("div", { className: "ha-conversation", children: [
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-PTMCOJHE.js").then(
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 useRef9, useState as useState7 } from "react";
3277
- import { Fragment, jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
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] = useState7(false);
3296
- const [isFeedbackOpen, setIsFeedbackOpen] = useState7(false);
3297
- const [feedbackComment, setFeedbackComment] = useState7("");
3298
- const [feedbackReasons, setFeedbackReasons] = useState7([]);
3299
- const [feedbackPortalContainer, setFeedbackPortalContainer] = useState7();
3300
- const resetTimeoutRef = useRef9(null);
3301
- const feedbackOpenedAtRef = useRef9(0);
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__ */ jsxs10("div", { "aria-label": "Message actions", className: "ha-message-actions", role: "group", children: [
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__ */ jsxs10(Fragment, { children: [
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__ */ jsxs10(Popover, { isOpen: isFeedbackOpen, onOpenChange: handleFeedbackOpenChange, children: [
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__ */ jsxs10(Popover.Dialog, { className: "ha-feedback-dialog", children: [
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__ */ jsxs10("div", { className: "ha-feedback-footer", children: [
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 jsxs11 } from "react/jsx-runtime";
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__ */ jsxs11(
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__ */ jsxs11("span", { className: "ha-message-file-copy", children: [
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 useRef11 } from "react";
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 useRef10, useState as useState8 } from "react";
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 = useRef10(null);
3657
- const dropTargetRef = useRef10(null);
3658
- const positionPickerMessageIdRef = useRef10(null);
3659
- const suppressedClickMessageIdRef = useRef10(null);
3660
- const [announcement, setAnnouncement] = useState8("");
3661
- const [draggedMessageId, setDraggedMessageId] = useState8(null);
3662
- const [dropTarget, setDropTarget] = useState8(null);
3663
- const [positionPickerMessageId, setPositionPickerMessageId] = useState8(null);
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 jsxs12 } from "react/jsx-runtime";
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 = useRef11(null);
3832
- const listRef = useRef11(null);
3833
- const previousMessagesRef = useRef11(messages);
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__ */ jsxs12("section", { "aria-label": "Queued messages", className: "ha-message-queue", children: [
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__ */ jsxs12(
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__ */ jsxs12("option", { value: position, children: [
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__ */ jsxs12("span", { className: "ha-message-queue-content", children: [
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__ */ jsxs12("span", { className: "ha-message-queue-actions", children: [
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 useRef12, useState as useState9 } from "react";
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] = useState9();
4028
- const triggerRef = useRef12(null);
4029
- const isPointerInsideRef = useRef12(false);
4030
- const openTimerRef = useRef12(void 0);
4031
- const closeTimerRef = useRef12(void 0);
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 jsxs13 } from "react/jsx-runtime";
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__ */ jsxs13(Fragment2, { children: [
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__ */ jsxs13(Fragment2, { children: [
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__ */ jsxs13(Fragment2, { children: [
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__ */ jsxs13(
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__ */ jsxs13(
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__ */ jsxs13("div", { className: "aui-chat-source__preview-header", children: [
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__ */ jsxs13("div", { className: "aui-chat-source__preview-link", "data-source-type": "document", children: [
4459
- /* @__PURE__ */ jsxs13("div", { className: "aui-chat-source__preview-header", children: [
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 jsxs14 } from "react/jsx-runtime";
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__ */ jsxs14(
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 jsxs15 } from "react/jsx-runtime";
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__ */ jsxs15(ChatSources, { className: "ha-message-sources", "data-count": sources.length, children: [
4582
- /* @__PURE__ */ jsxs15(ChatSources.Trigger, { "aria-label": `${sources.length} sources`, children: [
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 useRef13, useState as useState10 } from "react";
4668
- import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
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] = useState10(false);
4685
- const [isDialogOpen, setIsDialogOpen] = useState10(false);
4686
- const [actionMenuId, setActionMenuId] = useState10(null);
4687
- const [dialog, setDialog] = useState10(null);
4688
- const [renameTitle, setRenameTitle] = useState10("");
4689
- const [mutationError, setMutationError] = useState10(null);
4690
- const [isPending, setIsPending] = useState10(false);
4691
- const [portalContainer, setPortalContainer] = useState10();
4692
- const pointerOpenAt = useRef13(0);
4693
- const actionPointerOpenAt = useRef13(0);
4694
- const sidebarHistoryRef = useRef13(null);
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__ */ jsxs16("section", { className: "ha-session-group", children: [
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__ */ jsxs16(
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__ */ jsxs16(
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__ */ jsxs16(
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__ */ jsxs16(
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__ */ jsxs16(Dropdown.Item, { id: RENAME_KEY, textValue: "Rename", children: [
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__ */ jsxs16(
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__ */ jsxs16(
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__ */ jsxs16(Fragment3, { children: [
4867
- /* @__PURE__ */ jsxs16("div", { className: "ha-session-sidebar-header", children: [
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__ */ jsxs16(
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__ */ jsxs16(Popover2, { isOpen, onOpenChange: handleOpenChange, children: [
4897
- /* @__PURE__ */ jsxs16(
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__ */ jsxs16(
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__ */ jsxs16(Modal.Body, { children: [
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__ */ jsxs16(Modal.Footer, { children: [
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__ */ jsxs16(Fragment3, { children: [
5237
+ return /* @__PURE__ */ jsxs17(Fragment3, { children: [
5033
5238
  /* @__PURE__ */ jsx24(Modal.Header, { children: /* @__PURE__ */ jsx24(Modal.Heading, { children: "Delete chat?" }) }),
5034
- /* @__PURE__ */ jsxs16(Modal.Body, { children: [
5035
- /* @__PURE__ */ jsxs16("p", { children: [
5239
+ /* @__PURE__ */ jsxs17(Modal.Body, { children: [
5240
+ /* @__PURE__ */ jsxs17("p", { children: [
5036
5241
  "Are you sure you want to delete ",
5037
- /* @__PURE__ */ jsxs16("strong", { children: [
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__ */ jsxs16(Modal.Footer, { children: [
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 useState11 } from "react";
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] = useState11(0);
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 useRef14, useState as useState12 } from "react";
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] = useState12(null);
5119
- const [restoredPromptDraftKey, setRestoredPromptDraftKey] = useState12(null);
5120
- const latestInputRef = useRef14(input);
5121
- const saveTimeoutRef = useRef14(null);
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 useState13 } from "react";
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] = useState13(
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 jsxs17 } from "react/jsx-runtime";
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] = useState14(null);
5359
- const [runtimeRoutes, setRuntimeRoutes] = useState14({});
5360
- const runtimeRoutesRef = useRef15(runtimeRoutes);
5361
- const activeConversationIdRef = useRef15(activeConversationId);
5362
- const [error, setError] = useState14(null);
5363
- const [history, setHistory] = useState14([]);
5364
- const [conversationActivity, setConversationActivity] = useState14(createConversationActivityState);
5365
- const [messageQueues, setMessageQueues] = useState14({});
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 = useRef15(null);
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 = useRef15(identityEpoch);
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 = useRef15(/* @__PURE__ */ new Set());
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 = useRef15(null);
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__ */ jsxs17(Fragment4, { children: [
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__ */ jsxs17(
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] = useState14(() => ({
6035
+ const [attachmentSelection, setAttachmentSelection] = useState15(() => ({
5831
6036
  files: [],
5832
6037
  policy: attachmentPolicy
5833
6038
  }));
5834
- const [attachmentErrorSelection, setAttachmentErrorSelection] = useState14(() => ({
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] = useState14(() => {
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] = useState14({});
5866
- const [feedbackByMessage, setFeedbackByMessage] = useState14({});
5867
- const [isComposerExpanded, setIsComposerExpanded] = useState14(false);
5868
- const [input, setInput] = useState14("");
5869
- const [permissionSelection, setPermissionSelection] = useState14(() => {
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] = useState14(false);
5886
- const [isReconciling, setIsReconciling] = useState14(false);
5887
- const [localPending, setLocalPending] = useState14(false);
5888
- const [pendingClientToolCallIds, setPendingClientToolCallIds] = useState14(
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] = useState14(true);
5892
- const [progress, setProgress] = useState14(null);
5893
- const [queueDrainVersion, setQueueDrainVersion] = useState14(0);
5894
- const [reconcileEpoch, setReconcileEpoch] = useState14(0);
5895
- const [recoveryError, setRecoveryError] = useState14(false);
5896
- const [selection, setSelection] = useState14(null);
5897
- const [toolDecisions, setToolDecisions] = useState14({});
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 = useRef15(clientToolManifest);
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 = useRef15(/* @__PURE__ */ new Set());
5945
- const activeMessageIdRef = useRef15(null);
5946
- const isBusyRef = useRef15(true);
5947
- const isQueueReorderingRef = useRef15(false);
5948
- const messageQueueRef = useRef15(messageQueue);
5949
- const pendingTurnAnchorRef = useRef15(null);
5950
- const reconciliationDeferredRef = useRef15(null);
5951
- const reconcileMessageIdRef = useRef15(void 0);
5952
- const resumePromiseRef = useRef15(null);
5953
- const manualStopRequestedRef = useRef15(false);
5954
- const sendAcknowledgedRef = useRef15(false);
5955
- const sendErrorRef = useRef15(null);
5956
- const streamedMessageIdsRef = useRef15(/* @__PURE__ */ new Set());
5957
- const timedMessageIdRef = useRef15(null);
5958
- const transportFailureRef = useRef15(null);
5959
- const turnStartedAtRef = useRef15(null);
5960
- const needsReconciliationRef = useRef15(false);
5961
- const clearChatErrorRef = useRef15(() => void 0);
5962
- const fileInputRef = useRef15(null);
5963
- const messageQueueListRef = useRef15(null);
5964
- const textareaRef = useRef15(null);
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
- messageId: message.id,
6463
- previousUserMessageId: previousUserMessageId ?? null
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
- conversationId,
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__ */ jsxs17(Fragment4, { children: [
6881
- /* @__PURE__ */ jsxs17(ConversationViewport, { streamKey: activeStreamKey, children: [
6882
- showHome ? /* @__PURE__ */ jsxs17("div", { className: "ha-empty", children: [
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__ */ jsxs17("div", { className: "ha-error", role: "alert", children: [
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__ */ jsxs17("form", { className: "ha-composer-wrap", onSubmit: submit, children: [
6918
- showHome && visibleSuggestedPrompts.length > 0 ? /* @__PURE__ */ jsx26("div", { "aria-label": "Suggested prompts", className: "ha-suggestions", role: "group", children: visibleSuggestedPrompts.map((prompt, index) => /* @__PURE__ */ jsxs17(
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__ */ jsxs17("span", { "aria-hidden": "true", className: "ha-suggestion-shortcut", children: [
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__ */ jsxs17(
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__ */ jsxs17(Fragment4, { children: [
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__ */ jsxs17(
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__ */ jsxs17(
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__ */ jsxs17(
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__ */ jsxs17(
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__ */ jsxs17("div", { className: "ha-message-body", children: [
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 = useRef15(false);
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,