@agents24/chat-react 0.5.6 → 0.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +11 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +11 -6
- package/dist/index.js.map +1 -1
- package/dist/latest-thread-scroller.d.ts +2 -1
- package/dist/scaffold/components/chat/turn-outline.d.ts +1 -1
- package/dist/scaffold/index.cjs +144 -133
- package/dist/scaffold/index.cjs.map +1 -1
- package/dist/scaffold/index.js +154 -143
- package/dist/scaffold/index.js.map +1 -1
- package/dist/styles.css +12 -5
- package/dist/ui/agent-chat-message.d.ts +4 -0
- package/dist/ui/index.cjs +138 -52
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.js +137 -52
- package/dist/ui/index.js.map +1 -1
- package/package.json +1 -1
- package/scaffold/src/components/chat/chat-message.tsx +12 -2
- package/scaffold/src/components/chat/chat-shell.tsx +58 -30
- package/scaffold/src/components/chat/turn-outline.tsx +17 -59
- package/scaffold/src/components/ui/message-scroller.tsx +1 -1
- package/scaffold/src/components/ui/message.tsx +1 -1
- package/scaffold/src/components/ui/sidebar.tsx +1 -1
package/dist/scaffold/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
agentChatRuntimeErrorMessage
|
|
12
12
|
} from "@agents24/chat-react/runtime";
|
|
13
13
|
import { CircleAlert, LoaderCircle as LoaderCircle3, SquarePen as SquarePen2, X } from "lucide-react";
|
|
14
|
+
import * as React8 from "react";
|
|
14
15
|
|
|
15
16
|
// scaffold/src/components/chat/chat-composer.tsx
|
|
16
17
|
import { ArrowUp, ChevronDown, LoaderCircle, Mic, Square } from "lucide-react";
|
|
@@ -726,7 +727,7 @@ function ChatComposer({
|
|
|
726
727
|
}
|
|
727
728
|
|
|
728
729
|
// scaffold/src/components/chat/chat-message.tsx
|
|
729
|
-
import { AgentChatDefaultActions, ChatAttachmentRows as ChatAttachmentRows2 } from "@agents24/chat-react/ui";
|
|
730
|
+
import { AgentChatDefaultActions, AgentChatUserMessageActionRow, ChatAttachmentRows as ChatAttachmentRows2 } from "@agents24/chat-react/ui";
|
|
730
731
|
|
|
731
732
|
// scaffold/src/components/chat/message-parts.tsx
|
|
732
733
|
import {
|
|
@@ -1116,7 +1117,7 @@ function MessageFooter({ className, ...props }) {
|
|
|
1116
1117
|
{
|
|
1117
1118
|
"data-slot": "message-footer",
|
|
1118
1119
|
className: cn(
|
|
1119
|
-
"flex max-w-full min-w-0 items-center
|
|
1120
|
+
"flex max-w-full min-w-0 items-center pl-3.5 text-xs font-medium text-muted-foreground group-has-data-[variant=ghost]/message:px-0 group-data-[align=end]/message:justify-end",
|
|
1120
1121
|
className
|
|
1121
1122
|
),
|
|
1122
1123
|
...props
|
|
@@ -1138,7 +1139,7 @@ function ChatMessage({
|
|
|
1138
1139
|
Timeline
|
|
1139
1140
|
}) {
|
|
1140
1141
|
const isUser = message.role === "user";
|
|
1141
|
-
return /* @__PURE__ */ jsx14(Message, { align: isUser ? "end" : "start", children: /* @__PURE__ */ jsxs8(MessageContent, { children: [
|
|
1142
|
+
return /* @__PURE__ */ jsx14(Message, { align: isUser ? "end" : "start", children: /* @__PURE__ */ jsxs8(MessageContent, { className: isUser ? "gap-0" : void 0, children: [
|
|
1142
1143
|
isUser && message.attachments?.length ? /* @__PURE__ */ jsx14(
|
|
1143
1144
|
ChatAttachmentRows2,
|
|
1144
1145
|
{
|
|
@@ -1157,6 +1158,17 @@ function ChatMessage({
|
|
|
1157
1158
|
Timeline
|
|
1158
1159
|
}
|
|
1159
1160
|
) }) }),
|
|
1161
|
+
isUser && /* @__PURE__ */ jsx14(AgentChatUserMessageActionRow, { children: /* @__PURE__ */ jsx14(
|
|
1162
|
+
AgentChatDefaultActions,
|
|
1163
|
+
{
|
|
1164
|
+
handlers: {
|
|
1165
|
+
onCopy: (content) => {
|
|
1166
|
+
void navigator.clipboard.writeText(content).catch(() => void 0);
|
|
1167
|
+
}
|
|
1168
|
+
},
|
|
1169
|
+
message
|
|
1170
|
+
}
|
|
1171
|
+
) }),
|
|
1160
1172
|
!isUser && message.isFinal !== false && /* @__PURE__ */ jsx14(MessageFooter, { className: "gap-1 opacity-70 transition-opacity group-hover/message:opacity-100", children: /* @__PURE__ */ jsx14(
|
|
1161
1173
|
AgentChatDefaultActions,
|
|
1162
1174
|
{
|
|
@@ -1559,7 +1571,7 @@ function Sidebar({
|
|
|
1559
1571
|
className: cn(
|
|
1560
1572
|
"fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex",
|
|
1561
1573
|
// Adjust the padding for floating and inset variants.
|
|
1562
|
-
variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
|
|
1574
|
+
variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" : "border-border/50 group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l",
|
|
1563
1575
|
className
|
|
1564
1576
|
),
|
|
1565
1577
|
...props,
|
|
@@ -1958,7 +1970,47 @@ function ThreadSidebar({ activeThreadId, hasMore, identity, isLoading, isLoading
|
|
|
1958
1970
|
}
|
|
1959
1971
|
|
|
1960
1972
|
// scaffold/src/components/chat/turn-outline.tsx
|
|
1961
|
-
import {
|
|
1973
|
+
import { LatestThreadScroller } from "@agents24/chat-react";
|
|
1974
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1975
|
+
function turnsFromMessages(messages) {
|
|
1976
|
+
return messages.reduce((turns, message) => {
|
|
1977
|
+
if (message.role === "user") {
|
|
1978
|
+
turns.push({
|
|
1979
|
+
id: message.id,
|
|
1980
|
+
label: message.content.trim() || `Turn ${turns.length + 1}`,
|
|
1981
|
+
messageIds: [message.id],
|
|
1982
|
+
responsePreview: ""
|
|
1983
|
+
});
|
|
1984
|
+
} else if (turns.length) {
|
|
1985
|
+
const turn = turns[turns.length - 1];
|
|
1986
|
+
turn.messageIds?.push(message.id);
|
|
1987
|
+
if (!turn.responsePreview) turn.responsePreview = message.content.trim();
|
|
1988
|
+
}
|
|
1989
|
+
return turns;
|
|
1990
|
+
}, []);
|
|
1991
|
+
}
|
|
1992
|
+
function TurnOutline({ messages }) {
|
|
1993
|
+
return /* @__PURE__ */ jsx23(
|
|
1994
|
+
LatestThreadScroller.Outline,
|
|
1995
|
+
{
|
|
1996
|
+
items: turnsFromMessages(messages),
|
|
1997
|
+
minSideGutterForRail: 0,
|
|
1998
|
+
side: "left",
|
|
1999
|
+
verticalOffset: "3.5rem"
|
|
2000
|
+
}
|
|
2001
|
+
);
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
// scaffold/src/components/chat/timeline-loading.ts
|
|
2005
|
+
function isScaffoldTimelineLoading({
|
|
2006
|
+
activeRunId,
|
|
2007
|
+
message,
|
|
2008
|
+
runState,
|
|
2009
|
+
streamingMessageId
|
|
2010
|
+
}) {
|
|
2011
|
+
if (runState !== "streaming" && runState !== "reconnecting") return false;
|
|
2012
|
+
return message.id === streamingMessageId || Boolean(message.runId && message.runId === activeRunId);
|
|
2013
|
+
}
|
|
1962
2014
|
|
|
1963
2015
|
// scaffold/src/components/ui/message-scroller.tsx
|
|
1964
2016
|
import {
|
|
@@ -1968,15 +2020,15 @@ import {
|
|
|
1968
2020
|
useMessageScrollerVisibility
|
|
1969
2021
|
} from "@shadcn/react/message-scroller";
|
|
1970
2022
|
import { ArrowDownIcon } from "lucide-react";
|
|
1971
|
-
import { Fragment as Fragment3, jsx as
|
|
2023
|
+
import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1972
2024
|
function MessageScrollerProvider(props) {
|
|
1973
|
-
return /* @__PURE__ */
|
|
2025
|
+
return /* @__PURE__ */ jsx24(MessageScrollerPrimitive.Provider, { ...props });
|
|
1974
2026
|
}
|
|
1975
2027
|
function MessageScroller({
|
|
1976
2028
|
className,
|
|
1977
2029
|
...props
|
|
1978
2030
|
}) {
|
|
1979
|
-
return /* @__PURE__ */
|
|
2031
|
+
return /* @__PURE__ */ jsx24(
|
|
1980
2032
|
MessageScrollerPrimitive.Root,
|
|
1981
2033
|
{
|
|
1982
2034
|
"data-slot": "message-scroller",
|
|
@@ -1992,7 +2044,7 @@ function MessageScrollerViewport({
|
|
|
1992
2044
|
className,
|
|
1993
2045
|
...props
|
|
1994
2046
|
}) {
|
|
1995
|
-
return /* @__PURE__ */
|
|
2047
|
+
return /* @__PURE__ */ jsx24(
|
|
1996
2048
|
MessageScrollerPrimitive.Viewport,
|
|
1997
2049
|
{
|
|
1998
2050
|
"data-slot": "message-scroller-viewport",
|
|
@@ -2008,11 +2060,11 @@ function MessageScrollerContent({
|
|
|
2008
2060
|
className,
|
|
2009
2061
|
...props
|
|
2010
2062
|
}) {
|
|
2011
|
-
return /* @__PURE__ */
|
|
2063
|
+
return /* @__PURE__ */ jsx24(
|
|
2012
2064
|
MessageScrollerPrimitive.Content,
|
|
2013
2065
|
{
|
|
2014
2066
|
"data-slot": "message-scroller-content",
|
|
2015
|
-
className: cn("flex h-max min-h-full flex-col gap-
|
|
2067
|
+
className: cn("flex h-max min-h-full flex-col gap-3", className),
|
|
2016
2068
|
...props
|
|
2017
2069
|
}
|
|
2018
2070
|
);
|
|
@@ -2022,7 +2074,7 @@ function MessageScrollerItem({
|
|
|
2022
2074
|
scrollAnchor = false,
|
|
2023
2075
|
...props
|
|
2024
2076
|
}) {
|
|
2025
|
-
return /* @__PURE__ */
|
|
2077
|
+
return /* @__PURE__ */ jsx24(
|
|
2026
2078
|
MessageScrollerPrimitive.Item,
|
|
2027
2079
|
{
|
|
2028
2080
|
"data-slot": "message-scroller-item",
|
|
@@ -2044,7 +2096,7 @@ function MessageScrollerButton({
|
|
|
2044
2096
|
size = "icon-sm",
|
|
2045
2097
|
...props
|
|
2046
2098
|
}) {
|
|
2047
|
-
return /* @__PURE__ */
|
|
2099
|
+
return /* @__PURE__ */ jsx24(
|
|
2048
2100
|
MessageScrollerPrimitive.Button,
|
|
2049
2101
|
{
|
|
2050
2102
|
"data-slot": "message-scroller-button",
|
|
@@ -2056,88 +2108,21 @@ function MessageScrollerButton({
|
|
|
2056
2108
|
"absolute inset-s-1/2 -translate-x-1/2 border-border bg-background text-foreground transition-[translate,scale,opacity] duration-200 hover:bg-muted hover:text-foreground data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full rtl:translate-x-1/2 data-[direction=start]:[&_svg]:rotate-180",
|
|
2057
2109
|
className
|
|
2058
2110
|
),
|
|
2059
|
-
render: render ?? /* @__PURE__ */
|
|
2111
|
+
render: render ?? /* @__PURE__ */ jsx24(Button, { variant, size }),
|
|
2060
2112
|
...props,
|
|
2061
2113
|
children: children ?? /* @__PURE__ */ jsxs14(Fragment3, { children: [
|
|
2062
|
-
/* @__PURE__ */
|
|
2114
|
+
/* @__PURE__ */ jsx24(
|
|
2063
2115
|
ArrowDownIcon,
|
|
2064
2116
|
{}
|
|
2065
2117
|
),
|
|
2066
|
-
/* @__PURE__ */
|
|
2118
|
+
/* @__PURE__ */ jsx24("span", { className: "sr-only", children: direction === "end" ? "Scroll to end" : "Scroll to start" })
|
|
2067
2119
|
] })
|
|
2068
2120
|
}
|
|
2069
2121
|
);
|
|
2070
2122
|
}
|
|
2071
2123
|
|
|
2072
|
-
// scaffold/src/components/chat/turn-outline.tsx
|
|
2073
|
-
import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2074
|
-
function turnsFromMessages(messages) {
|
|
2075
|
-
return messages.reduce((turns, message) => {
|
|
2076
|
-
if (message.role === "user") {
|
|
2077
|
-
turns.push({ id: message.id, label: message.content.trim() || `Turn ${turns.length + 1}`, messageIds: [message.id], response: "" });
|
|
2078
|
-
} else if (turns.length) {
|
|
2079
|
-
const turn = turns[turns.length - 1];
|
|
2080
|
-
turn.messageIds.push(message.id);
|
|
2081
|
-
if (!turn.response) turn.response = message.content.trim();
|
|
2082
|
-
}
|
|
2083
|
-
return turns;
|
|
2084
|
-
}, []);
|
|
2085
|
-
}
|
|
2086
|
-
function TurnOutline({ messages }) {
|
|
2087
|
-
const turns = turnsFromMessages(messages);
|
|
2088
|
-
const { scrollToMessage } = useMessageScroller();
|
|
2089
|
-
const { currentAnchorId, visibleMessageIds } = useMessageScrollerVisibility();
|
|
2090
|
-
const visible = new Set(visibleMessageIds);
|
|
2091
|
-
const [hoveredIndex, setHoveredIndex] = useState8(null);
|
|
2092
|
-
const focusIndex = hoveredIndex ?? -1;
|
|
2093
|
-
if (turns.length < 2) return null;
|
|
2094
|
-
return /* @__PURE__ */ jsx24("nav", { "aria-label": "Transcript outline", className: "pointer-events-none absolute end-2 top-1/2 z-20 hidden max-h-72 w-14 -translate-y-1/2 md:block xl:end-5", children: /* @__PURE__ */ jsx24("div", { className: "pointer-events-auto flex flex-col items-end gap-0.5 py-2", children: turns.map((turn, index) => {
|
|
2095
|
-
const active = turn.messageIds.some((id) => visible.has(id) || currentAnchorId === id);
|
|
2096
|
-
const distance = focusIndex >= 0 ? Math.abs(index - focusIndex) : Number.POSITIVE_INFINITY;
|
|
2097
|
-
const barWidth = focusIndex < 0 ? 12 : distance === 0 ? 50 : distance === 1 ? 36 : distance === 2 ? 23 : 10;
|
|
2098
|
-
const barOpacity = focusIndex < 0 ? active ? 1 : 0.4 : distance === 0 ? 1 : distance === 1 ? 0.78 : distance === 2 ? 0.58 : 0.36;
|
|
2099
|
-
return /* @__PURE__ */ jsxs15(Tooltip, { children: [
|
|
2100
|
-
/* @__PURE__ */ jsx24(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx24(
|
|
2101
|
-
"button",
|
|
2102
|
-
{
|
|
2103
|
-
type: "button",
|
|
2104
|
-
"aria-label": `Jump to ${turn.label}`,
|
|
2105
|
-
className: "group relative flex h-2 w-14 items-center justify-end outline-none after:pointer-events-auto after:absolute after:-inset-y-0.5 after:inset-x-0 after:content-['']",
|
|
2106
|
-
onBlur: () => setHoveredIndex(null),
|
|
2107
|
-
onFocus: () => setHoveredIndex(index),
|
|
2108
|
-
onMouseEnter: () => setHoveredIndex(index),
|
|
2109
|
-
onMouseLeave: () => setHoveredIndex(null),
|
|
2110
|
-
onClick: () => scrollToMessage(turn.id, { align: "start", behavior: "smooth" }),
|
|
2111
|
-
children: /* @__PURE__ */ jsx24(
|
|
2112
|
-
"span",
|
|
2113
|
-
{
|
|
2114
|
-
className: cn("h-0.5 rounded-full bg-muted-foreground/40 transition-[width,background-color,opacity] duration-150 ease-out group-hover:bg-foreground group-focus-visible:bg-foreground", active && "bg-foreground"),
|
|
2115
|
-
style: { opacity: barOpacity, width: barWidth }
|
|
2116
|
-
}
|
|
2117
|
-
)
|
|
2118
|
-
}
|
|
2119
|
-
) }),
|
|
2120
|
-
/* @__PURE__ */ jsxs15(TooltipContent, { side: "left", className: "w-64 flex-col items-stretch gap-0 overflow-hidden p-3", children: [
|
|
2121
|
-
/* @__PURE__ */ jsx24("p", { className: "line-clamp-2 max-w-full wrap-break-word text-sm font-medium", children: turn.label }),
|
|
2122
|
-
turn.response && /* @__PURE__ */ jsx24("p", { className: "mt-1 line-clamp-2 max-w-full wrap-break-word text-xs opacity-70", children: turn.response })
|
|
2123
|
-
] })
|
|
2124
|
-
] }, turn.id);
|
|
2125
|
-
}) }) });
|
|
2126
|
-
}
|
|
2127
|
-
|
|
2128
|
-
// scaffold/src/components/chat/timeline-loading.ts
|
|
2129
|
-
function isScaffoldTimelineLoading({
|
|
2130
|
-
activeRunId,
|
|
2131
|
-
message,
|
|
2132
|
-
runState,
|
|
2133
|
-
streamingMessageId
|
|
2134
|
-
}) {
|
|
2135
|
-
if (runState !== "streaming" && runState !== "reconnecting") return false;
|
|
2136
|
-
return message.id === streamingMessageId || Boolean(message.runId && message.runId === activeRunId);
|
|
2137
|
-
}
|
|
2138
|
-
|
|
2139
2124
|
// scaffold/src/components/chat/chat-shell.tsx
|
|
2140
|
-
import { Fragment as Fragment4, jsx as jsx25, jsxs as
|
|
2125
|
+
import { Fragment as Fragment4, jsx as jsx25, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2141
2126
|
var LOADING_INPUT_CONTRACT = {
|
|
2142
2127
|
version: "agents24.runtime-inputs.v2",
|
|
2143
2128
|
modalities: {
|
|
@@ -2156,7 +2141,7 @@ function CollapsedHeaderActions({ onNew }) {
|
|
|
2156
2141
|
const { isMobile, openMobile, state } = useSidebar();
|
|
2157
2142
|
const sidebarVisible = isMobile ? openMobile : state === "expanded";
|
|
2158
2143
|
if (sidebarVisible) return null;
|
|
2159
|
-
return /* @__PURE__ */
|
|
2144
|
+
return /* @__PURE__ */ jsxs15(Fragment4, { children: [
|
|
2160
2145
|
/* @__PURE__ */ jsx25("div", { className: "h-8 w-17 shrink-0", "aria-hidden": "true" }),
|
|
2161
2146
|
/* @__PURE__ */ jsx25("div", { className: "pointer-events-none fixed start-12 top-0 z-[60] flex h-12 items-center", children: /* @__PURE__ */ jsx25(Button, { className: "pointer-events-auto", variant: "ghost", size: "icon-sm", "aria-label": "New chat", onClick: onNew, children: /* @__PURE__ */ jsx25(SquarePen2, {}) }) })
|
|
2162
2147
|
] });
|
|
@@ -2164,7 +2149,7 @@ function CollapsedHeaderActions({ onNew }) {
|
|
|
2164
2149
|
function OperationErrorNotice({ runtime }) {
|
|
2165
2150
|
const error = runtime.operationError || runtime.backgroundError;
|
|
2166
2151
|
if (!error) return null;
|
|
2167
|
-
return /* @__PURE__ */ jsx25("div", { className: "pointer-events-none absolute inset-x-0 top-3 z-40 flex justify-center px-4", children: /* @__PURE__ */
|
|
2152
|
+
return /* @__PURE__ */ jsx25("div", { className: "pointer-events-none absolute inset-x-0 top-3 z-40 flex justify-center px-4", children: /* @__PURE__ */ jsxs15("div", { className: "pointer-events-auto flex max-w-lg items-start gap-2 rounded-lg border border-destructive/20 bg-background px-3 py-2 text-sm shadow-md", role: "alert", children: [
|
|
2168
2153
|
/* @__PURE__ */ jsx25(CircleAlert, { className: "mt-0.5 size-4 shrink-0 text-destructive" }),
|
|
2169
2154
|
/* @__PURE__ */ jsx25("span", { className: "min-w-0 flex-1 wrap-break-word", children: agentChatRuntimeErrorMessage(error) || "The chat could not complete that action." }),
|
|
2170
2155
|
/* @__PURE__ */ jsx25(
|
|
@@ -2192,7 +2177,20 @@ function ChatShell({
|
|
|
2192
2177
|
const activeTitle = controller.threads.find((thread) => thread.id === controller.activeThreadId)?.title;
|
|
2193
2178
|
const hasBlockingError = Boolean(runtime.fatalError && controller.messages.length === 0);
|
|
2194
2179
|
const isEmptyState = controller.activeThreadId === null && controller.messages.length === 0 && !hasBlockingError;
|
|
2195
|
-
|
|
2180
|
+
const composerOverlayRef = React8.useRef(null);
|
|
2181
|
+
const [composerOverlayHeight, setComposerOverlayHeight] = React8.useState(192);
|
|
2182
|
+
React8.useEffect(() => {
|
|
2183
|
+
const overlay = composerOverlayRef.current;
|
|
2184
|
+
if (!overlay || isEmptyState) return;
|
|
2185
|
+
const updateHeight = () => {
|
|
2186
|
+
setComposerOverlayHeight(Math.ceil(overlay.getBoundingClientRect().height));
|
|
2187
|
+
};
|
|
2188
|
+
updateHeight();
|
|
2189
|
+
const resizeObserver = new ResizeObserver(updateHeight);
|
|
2190
|
+
resizeObserver.observe(overlay);
|
|
2191
|
+
return () => resizeObserver.disconnect();
|
|
2192
|
+
}, [isEmptyState]);
|
|
2193
|
+
return /* @__PURE__ */ jsxs15(
|
|
2196
2194
|
SidebarProvider,
|
|
2197
2195
|
{
|
|
2198
2196
|
className: "h-svh min-h-0 overflow-hidden",
|
|
@@ -2215,11 +2213,11 @@ function ChatShell({
|
|
|
2215
2213
|
onOpen: runtime.openThread
|
|
2216
2214
|
}
|
|
2217
2215
|
),
|
|
2218
|
-
/* @__PURE__ */
|
|
2219
|
-
/* @__PURE__ */
|
|
2216
|
+
/* @__PURE__ */ jsxs15(SidebarInset, { className: "h-svh min-h-0 overflow-hidden bg-background", children: [
|
|
2217
|
+
/* @__PURE__ */ jsxs15(
|
|
2220
2218
|
"header",
|
|
2221
2219
|
{
|
|
2222
|
-
className: "flex h-12 shrink-0 items-center gap-2 border-b border-border/
|
|
2220
|
+
className: "flex h-12 shrink-0 items-center gap-2 border-b border-border/50 px-3 sm:px-4",
|
|
2223
2221
|
"data-agents24-chat-header": "",
|
|
2224
2222
|
children: [
|
|
2225
2223
|
/* @__PURE__ */ jsx25(CollapsedHeaderActions, { onNew: runtime.newThread }),
|
|
@@ -2228,7 +2226,7 @@ function ChatShell({
|
|
|
2228
2226
|
]
|
|
2229
2227
|
}
|
|
2230
2228
|
),
|
|
2231
|
-
/* @__PURE__ */
|
|
2229
|
+
/* @__PURE__ */ jsxs15(
|
|
2232
2230
|
"section",
|
|
2233
2231
|
{
|
|
2234
2232
|
"aria-label": "Conversation",
|
|
@@ -2236,7 +2234,7 @@ function ChatShell({
|
|
|
2236
2234
|
"data-agents24-chat-transcript": "",
|
|
2237
2235
|
children: [
|
|
2238
2236
|
/* @__PURE__ */ jsx25(OperationErrorNotice, { runtime }),
|
|
2239
|
-
isEmptyState ? /* @__PURE__ */
|
|
2237
|
+
isEmptyState ? /* @__PURE__ */ jsxs15("div", { className: "absolute inset-0 flex min-h-0 flex-col justify-center pb-20", children: [
|
|
2240
2238
|
/* @__PURE__ */ jsx25("div", { className: "mx-auto mb-8 w-full max-w-3xl px-4 text-center sm:px-6", children: /* @__PURE__ */ jsx25("h2", { className: "text-3xl font-semibold tracking-tight sm:text-4xl", children: "Ready when you are." }) }),
|
|
2241
2239
|
/* @__PURE__ */ jsx25(
|
|
2242
2240
|
ChatComposer,
|
|
@@ -2270,29 +2268,30 @@ function ChatShell({
|
|
|
2270
2268
|
})
|
|
2271
2269
|
}
|
|
2272
2270
|
)
|
|
2273
|
-
] }) : /* @__PURE__ */
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
/* @__PURE__ */ jsx25(MessageScrollerViewport, { preserveScrollOnPrepend: true, children: /* @__PURE__ */
|
|
2271
|
+
] }) : /* @__PURE__ */ jsx25(Fragment4, { children: /* @__PURE__ */ jsxs15(
|
|
2272
|
+
MessageScrollerProvider,
|
|
2273
|
+
{
|
|
2274
|
+
autoScroll: true,
|
|
2275
|
+
defaultScrollPosition: "last-anchor",
|
|
2276
|
+
scrollPreviousItemPeek: 64,
|
|
2277
|
+
children: [
|
|
2278
|
+
/* @__PURE__ */ jsxs15(MessageScroller, { className: "relative min-h-0 flex-1", children: [
|
|
2279
|
+
/* @__PURE__ */ jsx25(MessageScrollerViewport, { preserveScrollOnPrepend: true, children: /* @__PURE__ */ jsxs15(
|
|
2282
2280
|
MessageScrollerContent,
|
|
2283
2281
|
{
|
|
2284
|
-
className: "mx-auto w-full max-w-3xl gap-
|
|
2282
|
+
className: "mx-auto w-full max-w-3xl gap-3 px-4 pt-8 pb-0 sm:px-6 sm:pt-12",
|
|
2283
|
+
style: { paddingBottom: composerOverlayHeight + 72 },
|
|
2285
2284
|
children: [
|
|
2286
|
-
controller.hasOlderTurns && /* @__PURE__ */
|
|
2285
|
+
controller.hasOlderTurns && /* @__PURE__ */ jsxs15(Button, { className: "self-center", variant: "ghost", size: "sm", disabled: controller.isLoadingOlder, onClick: () => {
|
|
2287
2286
|
void controller.loadOlder().catch(() => void 0);
|
|
2288
2287
|
}, children: [
|
|
2289
2288
|
controller.isLoadingOlder && /* @__PURE__ */ jsx25(LoaderCircle3, { className: "animate-spin" }),
|
|
2290
2289
|
" Load earlier messages"
|
|
2291
2290
|
] }),
|
|
2292
2291
|
runtime.isBootstrapping && /* @__PURE__ */ jsx25("div", { "aria-label": "Loading conversation", className: "flex flex-1 items-center justify-center py-24 text-muted-foreground", role: "status", children: /* @__PURE__ */ jsx25(LoaderCircle3, { className: "size-4 animate-spin" }) }),
|
|
2293
|
-
hasBlockingError && /* @__PURE__ */
|
|
2292
|
+
hasBlockingError && /* @__PURE__ */ jsxs15("div", { className: "flex flex-1 flex-col items-center justify-center gap-3 py-24 text-center", children: [
|
|
2294
2293
|
/* @__PURE__ */ jsx25(CircleAlert, { className: "size-5 text-destructive" }),
|
|
2295
|
-
/* @__PURE__ */
|
|
2294
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
2296
2295
|
/* @__PURE__ */ jsx25("h2", { className: "font-medium", children: "Couldn\u2019t connect" }),
|
|
2297
2296
|
/* @__PURE__ */ jsx25("p", { className: "mt-1 max-w-md text-sm text-muted-foreground", children: runtime.errorMessage })
|
|
2298
2297
|
] }),
|
|
@@ -2329,44 +2328,56 @@ function ChatShell({
|
|
|
2329
2328
|
]
|
|
2330
2329
|
}
|
|
2331
2330
|
) }),
|
|
2332
|
-
/* @__PURE__ */ jsx25(TurnOutline, { messages: controller.messages })
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2331
|
+
/* @__PURE__ */ jsx25(TurnOutline, { messages: controller.messages })
|
|
2332
|
+
] }),
|
|
2333
|
+
/* @__PURE__ */ jsxs15(
|
|
2334
|
+
"div",
|
|
2335
|
+
{
|
|
2336
|
+
ref: composerOverlayRef,
|
|
2337
|
+
className: "pointer-events-none absolute inset-x-0 bottom-0 z-30 overflow-visible pt-10",
|
|
2338
|
+
style: {
|
|
2339
|
+
background: "linear-gradient(to bottom, transparent 0%, color-mix(in oklch, var(--background) 85%, transparent) 45%, var(--background) 65%, var(--background) 100%)"
|
|
2340
|
+
},
|
|
2341
|
+
children: [
|
|
2342
|
+
/* @__PURE__ */ jsx25("div", { className: "pointer-events-auto absolute inset-x-0 top-0 flex -translate-y-full justify-center pb-3", children: /* @__PURE__ */ jsx25(MessageScrollerButton, { className: "!relative !inset-auto !translate-x-0 rtl:!translate-x-0" }) }),
|
|
2343
|
+
/* @__PURE__ */ jsx25("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsx25(
|
|
2344
|
+
ChatComposer,
|
|
2345
|
+
{
|
|
2346
|
+
inputContract: runtime.inputContract || LOADING_INPUT_CONTRACT,
|
|
2347
|
+
contextWindow: runtime.contextWindow,
|
|
2348
|
+
disabled: runtime.isBootstrapping || runtime.isChangingAgent || hasBlockingError || isUploading,
|
|
2349
|
+
focusKey: controller.activeThreadId,
|
|
2350
|
+
isCancelling,
|
|
2351
|
+
isRunning,
|
|
2352
|
+
agentId: runtime.agentId,
|
|
2353
|
+
agents: runtime.agents,
|
|
2354
|
+
onAgentChange: (agentId) => {
|
|
2355
|
+
void runtime.changeAgent(agentId);
|
|
2356
|
+
},
|
|
2357
|
+
onStop: () => {
|
|
2358
|
+
void controller.cancelRun().catch(() => void 0);
|
|
2359
|
+
},
|
|
2360
|
+
modelId: runtime.modelId,
|
|
2361
|
+
models: runtime.models,
|
|
2362
|
+
onModelChange: runtime.changeModel,
|
|
2363
|
+
onSubmit: (text, files) => runtime.submit({
|
|
2364
|
+
text,
|
|
2365
|
+
files: files.map((file) => ({
|
|
2366
|
+
data: file.source,
|
|
2367
|
+
mediaType: file.mediaType,
|
|
2368
|
+
name: file.filename
|
|
2369
|
+
})),
|
|
2370
|
+
attachments: files
|
|
2371
|
+
}),
|
|
2372
|
+
utilityRow: "below"
|
|
2373
|
+
}
|
|
2374
|
+
) })
|
|
2375
|
+
]
|
|
2376
|
+
}
|
|
2377
|
+
)
|
|
2378
|
+
]
|
|
2379
|
+
}
|
|
2380
|
+
) })
|
|
2370
2381
|
]
|
|
2371
2382
|
}
|
|
2372
2383
|
)
|