@page-speed/agent-everywhere 0.3.1 → 0.5.0
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/README.md +110 -3
- package/dist/index.cjs +520 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +326 -9
- package/dist/index.d.ts +326 -9
- package/dist/index.js +513 -41
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { createContext, forwardRef, useRef, useImperativeHandle, useCallback, us
|
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import { AnimatePresence, motion } from 'motion/react';
|
|
8
8
|
import { Markdown } from '@page-speed/markdown-to-jsx';
|
|
9
|
-
import { SendIcon, PaperclipIcon, FileTextIcon, MicIcon, ImageIcon, XIcon, SearchIcon, UploadIcon, FileIcon, UserCircleIcon, CheckIcon, SparklesIcon, BookmarkIcon, InfoIcon, CheckCircle2Icon, AlertTriangleIcon, LightbulbIcon, BrainIcon, ChevronDownIcon, ZapIcon, CopyIcon, ThumbsUpIcon, ThumbsDownIcon, BotIcon, UserIcon, DownloadIcon, MinusIcon, TrendingDownIcon, TrendingUpIcon, ChevronUpIcon, ArrowUpDownIcon, LinkIcon, PlayIcon, ExternalLinkIcon, WandIcon, LayoutGridIcon, Grid3X3Icon, ArrowUpRightIcon, ShuffleIcon, SkipForwardIcon, ChevronLeftIcon, ChevronRightIcon, XCircleIcon, HelpCircleIcon, Minimize2Icon, Maximize2Icon, RotateCcwIcon, MessageSquareIcon, GripVerticalIcon, PanelLeftOpenIcon, PanelLeftCloseIcon, CheckCircleIcon, AlertCircleIcon, MoreHorizontalIcon, ArrowLeftIcon, MoreVerticalIcon, Loader2Icon, ArrowRightIcon, AlignLeftIcon, ListIcon, HashIcon, TypeIcon, ClockIcon, CoinsIcon, ActivityIcon, ArrowUpIcon, ArrowDownIcon } from 'lucide-react';
|
|
9
|
+
import { SendIcon, PaperclipIcon, FileTextIcon, MicIcon, ImageIcon, XIcon, SearchIcon, UploadIcon, FileIcon, UserCircleIcon, CheckIcon, SparklesIcon, BookmarkIcon, InfoIcon, CheckCircle2Icon, AlertTriangleIcon, LightbulbIcon, BrainIcon, ChevronDownIcon, ZapIcon, CopyIcon, ThumbsUpIcon, ThumbsDownIcon, BotIcon, UserIcon, DownloadIcon, MinusIcon, TrendingDownIcon, TrendingUpIcon, ChevronUpIcon, ArrowUpDownIcon, LinkIcon, PlayIcon, ExternalLinkIcon, WandIcon, LayoutGridIcon, Grid3X3Icon, ArrowUpRightIcon, ShuffleIcon, SkipForwardIcon, ChevronLeftIcon, ChevronRightIcon, XCircleIcon, HelpCircleIcon, Minimize2Icon, Maximize2Icon, RotateCcwIcon, MessageSquareIcon, GripVerticalIcon, PanelLeftOpenIcon, PanelLeftCloseIcon, CheckCircleIcon, AlertCircleIcon, MoreHorizontalIcon, ClipboardListIcon, ArrowLeftIcon, MoreVerticalIcon, Loader2Icon, ArrowRightIcon, AlignLeftIcon, ListIcon, HashIcon, TypeIcon, ClockIcon, CoinsIcon, ActivityIcon, ArrowUpIcon, ArrowDownIcon } from 'lucide-react';
|
|
10
10
|
import { Slot } from '@radix-ui/react-slot';
|
|
11
11
|
import { cva } from 'class-variance-authority';
|
|
12
12
|
import * as AvatarPrimitive from '@radix-ui/react-avatar';
|
|
@@ -1212,7 +1212,7 @@ var PromptInput = forwardRef(
|
|
|
1212
1212
|
[handleSubmit]
|
|
1213
1213
|
);
|
|
1214
1214
|
const variantStyles = {
|
|
1215
|
-
default: "
|
|
1215
|
+
default: "px-3 py-2.5",
|
|
1216
1216
|
minimal: "px-3 py-2",
|
|
1217
1217
|
bordered: "border rounded-lg px-3 py-2.5"
|
|
1218
1218
|
};
|
|
@@ -1221,41 +1221,48 @@ var PromptInput = forwardRef(
|
|
|
1221
1221
|
minimal: "bg-transparent px-0",
|
|
1222
1222
|
bordered: "bg-muted/50"
|
|
1223
1223
|
};
|
|
1224
|
-
return /* @__PURE__ */ jsx(
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1224
|
+
return /* @__PURE__ */ jsx(
|
|
1225
|
+
"form",
|
|
1226
|
+
{
|
|
1227
|
+
onSubmit: handleSubmit,
|
|
1228
|
+
className: cn(variantStyles[variant], className),
|
|
1229
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-2", children: [
|
|
1230
|
+
leftActions,
|
|
1231
|
+
/* @__PURE__ */ jsx(
|
|
1232
|
+
"textarea",
|
|
1233
|
+
{
|
|
1234
|
+
ref: textareaRef,
|
|
1235
|
+
value,
|
|
1236
|
+
onChange: (e) => onChange(e.target.value),
|
|
1237
|
+
onKeyDown: handleKeyDown,
|
|
1238
|
+
placeholder,
|
|
1239
|
+
disabled: disabled || loading,
|
|
1240
|
+
autoFocus,
|
|
1241
|
+
rows: minRows,
|
|
1242
|
+
className: cn(
|
|
1243
|
+
"flex-1 resize-none border-0 px-0 py-1 text-sm leading-5 shadow-none",
|
|
1244
|
+
"placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0",
|
|
1245
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
1246
|
+
inputVariantStyles[variant],
|
|
1247
|
+
inputClassName
|
|
1248
|
+
)
|
|
1249
|
+
}
|
|
1250
|
+
),
|
|
1251
|
+
rightActions,
|
|
1252
|
+
showSendButton && /* @__PURE__ */ jsx(
|
|
1253
|
+
Button,
|
|
1254
|
+
{
|
|
1255
|
+
type: "submit",
|
|
1256
|
+
size: "sm",
|
|
1257
|
+
variant: variant === "minimal" ? "ghost" : "outline",
|
|
1258
|
+
disabled: !value.trim() || disabled || loading,
|
|
1259
|
+
className: "size-8 shrink-0 p-0",
|
|
1260
|
+
children: sendButtonContent || /* @__PURE__ */ jsx(SendIcon, { className: "size-4" })
|
|
1261
|
+
}
|
|
1243
1262
|
)
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
showSendButton && /* @__PURE__ */ jsx(
|
|
1248
|
-
Button,
|
|
1249
|
-
{
|
|
1250
|
-
type: "submit",
|
|
1251
|
-
size: "sm",
|
|
1252
|
-
variant: variant === "minimal" ? "ghost" : "outline",
|
|
1253
|
-
disabled: !value.trim() || disabled || loading,
|
|
1254
|
-
className: "size-8 shrink-0 p-0",
|
|
1255
|
-
children: sendButtonContent || /* @__PURE__ */ jsx(SendIcon, { className: "size-4" })
|
|
1256
|
-
}
|
|
1257
|
-
)
|
|
1258
|
-
] }) });
|
|
1263
|
+
] })
|
|
1264
|
+
}
|
|
1265
|
+
);
|
|
1259
1266
|
}
|
|
1260
1267
|
);
|
|
1261
1268
|
PromptInput.displayName = "PromptInput";
|
|
@@ -7189,6 +7196,7 @@ function useSemanticBuilder({
|
|
|
7189
7196
|
onGeneratedBlocks,
|
|
7190
7197
|
onUndoRequest,
|
|
7191
7198
|
buildWelcomeMessage,
|
|
7199
|
+
seedWelcomeMessage = true,
|
|
7192
7200
|
webSocketImpl
|
|
7193
7201
|
}) {
|
|
7194
7202
|
const [messages, setMessages] = useState([]);
|
|
@@ -7222,6 +7230,7 @@ function useSemanticBuilder({
|
|
|
7222
7230
|
resolveSocketUrlRef.current = resolveSocketUrl;
|
|
7223
7231
|
}, [resolveSocketUrl]);
|
|
7224
7232
|
useEffect(() => {
|
|
7233
|
+
if (!seedWelcomeMessage) return;
|
|
7225
7234
|
const hasContentBrief = !!contentBrief;
|
|
7226
7235
|
const content = buildWelcomeMessage?.({ pageName, hasContentBrief }) ?? (hasContentBrief ? `Connected to ${pageName}. The page brief is loaded and ready. Describe the page you want and I'll stream back layout guidance and design reasoning.` : `Connected to ${pageName}. There is no saved content brief yet, so I'll work from the current page structure and brand context.`);
|
|
7227
7236
|
setMessages([
|
|
@@ -7232,7 +7241,7 @@ function useSemanticBuilder({
|
|
|
7232
7241
|
createdAt: Date.now()
|
|
7233
7242
|
}
|
|
7234
7243
|
]);
|
|
7235
|
-
}, [contentBrief, pageName, pageSlug]);
|
|
7244
|
+
}, [contentBrief, pageName, pageSlug, seedWelcomeMessage]);
|
|
7236
7245
|
const handleEnvelope = useCallback((envelope) => {
|
|
7237
7246
|
switch (envelope.type) {
|
|
7238
7247
|
case "connection_ready":
|
|
@@ -7444,6 +7453,14 @@ function useSemanticBuilder({
|
|
|
7444
7453
|
const retry = useCallback(() => {
|
|
7445
7454
|
clientRef.current?.retry();
|
|
7446
7455
|
}, []);
|
|
7456
|
+
const reset = useCallback(() => {
|
|
7457
|
+
pendingHiddenRequestsRef.current = 0;
|
|
7458
|
+
hiddenAssistantMessageIdsRef.current.clear();
|
|
7459
|
+
clientRef.current?.close();
|
|
7460
|
+
setConnectionState("idle");
|
|
7461
|
+
setConnectionError(null);
|
|
7462
|
+
setMessages([]);
|
|
7463
|
+
}, []);
|
|
7447
7464
|
const isConnected = connectionState === "ready" || connectionState === "streaming";
|
|
7448
7465
|
const isStreaming = connectionState === "streaming";
|
|
7449
7466
|
const statusLabel = useMemo(() => {
|
|
@@ -7470,7 +7487,8 @@ function useSemanticBuilder({
|
|
|
7470
7487
|
isConnected,
|
|
7471
7488
|
isStreaming,
|
|
7472
7489
|
sendMessage,
|
|
7473
|
-
retry
|
|
7490
|
+
retry,
|
|
7491
|
+
reset
|
|
7474
7492
|
};
|
|
7475
7493
|
}
|
|
7476
7494
|
var ScrollArea = React4.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs(
|
|
@@ -7691,10 +7709,58 @@ function ReportView({ report, className }) {
|
|
|
7691
7709
|
))
|
|
7692
7710
|
] });
|
|
7693
7711
|
}
|
|
7712
|
+
function ConfirmationPanel({
|
|
7713
|
+
title = "Proposed plan",
|
|
7714
|
+
summary,
|
|
7715
|
+
body,
|
|
7716
|
+
markdown = true,
|
|
7717
|
+
icon,
|
|
7718
|
+
actions,
|
|
7719
|
+
onAction,
|
|
7720
|
+
ariaLabel,
|
|
7721
|
+
className
|
|
7722
|
+
}) {
|
|
7723
|
+
const hasBody = body !== void 0 && body !== null && body !== "";
|
|
7724
|
+
return /* @__PURE__ */ jsxs(
|
|
7725
|
+
motion.section,
|
|
7726
|
+
{
|
|
7727
|
+
initial: { opacity: 0, y: 6 },
|
|
7728
|
+
animate: { opacity: 1, y: 0 },
|
|
7729
|
+
transition: { duration: 0.2 },
|
|
7730
|
+
"aria-label": ariaLabel ?? title,
|
|
7731
|
+
className: cn(
|
|
7732
|
+
"flex w-full min-w-0 flex-col rounded-lg border bg-card p-4",
|
|
7733
|
+
className
|
|
7734
|
+
),
|
|
7735
|
+
children: [
|
|
7736
|
+
/* @__PURE__ */ jsxs("header", { className: "flex items-center gap-2", children: [
|
|
7737
|
+
/* @__PURE__ */ jsx("span", { className: "flex size-6 shrink-0 items-center justify-center rounded-md bg-muted/60 text-muted-foreground", children: icon ?? /* @__PURE__ */ jsx(ClipboardListIcon, { className: "size-3.5" }) }),
|
|
7738
|
+
/* @__PURE__ */ jsx("h4", { className: "min-w-0 flex-1 truncate font-medium text-sm", children: title }),
|
|
7739
|
+
summary && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "shrink-0 text-[10px] font-normal", children: summary })
|
|
7740
|
+
] }),
|
|
7741
|
+
hasBody && /* @__PURE__ */ jsx("div", { className: "mt-2 min-w-0", children: typeof body === "string" ? /* @__PURE__ */ jsx(MessageContent, { markdown, children: body }) : body }),
|
|
7742
|
+
actions && actions.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-3 flex flex-wrap gap-2", children: actions.map((action, index) => /* @__PURE__ */ jsx(
|
|
7743
|
+
Button,
|
|
7744
|
+
{
|
|
7745
|
+
type: "button",
|
|
7746
|
+
size: "sm",
|
|
7747
|
+
variant: action.variant ?? (index === 0 ? "default" : "outline"),
|
|
7748
|
+
disabled: action.disabled || action.busy,
|
|
7749
|
+
"aria-busy": action.busy || void 0,
|
|
7750
|
+
onClick: () => onAction?.(action.id),
|
|
7751
|
+
children: action.label
|
|
7752
|
+
},
|
|
7753
|
+
action.id
|
|
7754
|
+
)) })
|
|
7755
|
+
]
|
|
7756
|
+
}
|
|
7757
|
+
);
|
|
7758
|
+
}
|
|
7694
7759
|
function MessageList({
|
|
7695
7760
|
messages,
|
|
7696
7761
|
showAvatars = true,
|
|
7697
7762
|
renderMessage,
|
|
7763
|
+
onConfirmAction,
|
|
7698
7764
|
className
|
|
7699
7765
|
}) {
|
|
7700
7766
|
return /* @__PURE__ */ jsx("div", { className: cn("flex flex-col gap-4", className), children: messages.map((message) => {
|
|
@@ -7711,7 +7777,18 @@ function MessageList({
|
|
|
7711
7777
|
hasSteps && /* @__PURE__ */ jsx(MessageWithSteps, { steps: message.steps }),
|
|
7712
7778
|
message.content && /* @__PURE__ */ jsx(MessageBubble, { role: message.role, children: /* @__PURE__ */ jsx(MessageContent, { children: message.content }) }),
|
|
7713
7779
|
hasAttachments && /* @__PURE__ */ jsx(MessageWithAttachments, { attachments: message.attachments }),
|
|
7714
|
-
message.data && /* @__PURE__ */ jsx(DataPayloadView, { payload: message.data })
|
|
7780
|
+
message.data && /* @__PURE__ */ jsx(DataPayloadView, { payload: message.data }),
|
|
7781
|
+
message.confirmation && /* @__PURE__ */ jsx(
|
|
7782
|
+
ConfirmationPanel,
|
|
7783
|
+
{
|
|
7784
|
+
title: message.confirmation.title,
|
|
7785
|
+
summary: message.confirmation.summary,
|
|
7786
|
+
body: message.confirmation.body,
|
|
7787
|
+
markdown: message.confirmation.markdown,
|
|
7788
|
+
actions: message.confirmation.actions,
|
|
7789
|
+
onAction: (actionId) => onConfirmAction?.(message.id, actionId)
|
|
7790
|
+
}
|
|
7791
|
+
)
|
|
7715
7792
|
] })
|
|
7716
7793
|
] }, message.id);
|
|
7717
7794
|
}) });
|
|
@@ -7915,6 +7992,54 @@ function FullBleedSurface({
|
|
|
7915
7992
|
}
|
|
7916
7993
|
);
|
|
7917
7994
|
}
|
|
7995
|
+
function NativeSurface({
|
|
7996
|
+
children,
|
|
7997
|
+
input,
|
|
7998
|
+
title,
|
|
7999
|
+
subtitle,
|
|
8000
|
+
icon,
|
|
8001
|
+
headerActions,
|
|
8002
|
+
suggestions,
|
|
8003
|
+
footer,
|
|
8004
|
+
isLoading = false,
|
|
8005
|
+
autoScroll = true,
|
|
8006
|
+
className,
|
|
8007
|
+
contentClassName
|
|
8008
|
+
}) {
|
|
8009
|
+
const scrollRef = useRef(null);
|
|
8010
|
+
useEffect(() => {
|
|
8011
|
+
if (autoScroll && scrollRef.current) {
|
|
8012
|
+
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
8013
|
+
}
|
|
8014
|
+
}, [children, isLoading, autoScroll]);
|
|
8015
|
+
const showHeader = !!title || !!headerActions || !!icon;
|
|
8016
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex h-full min-h-0 flex-col", className), children: [
|
|
8017
|
+
showHeader && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-b px-4 py-3", children: [
|
|
8018
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
8019
|
+
icon,
|
|
8020
|
+
(title || subtitle) && /* @__PURE__ */ jsxs("div", { children: [
|
|
8021
|
+
title && /* @__PURE__ */ jsx("span", { className: "font-medium text-sm", children: title }),
|
|
8022
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground text-xs", children: subtitle })
|
|
8023
|
+
] })
|
|
8024
|
+
] }),
|
|
8025
|
+
headerActions && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2", children: headerActions })
|
|
8026
|
+
] }),
|
|
8027
|
+
/* @__PURE__ */ jsx(
|
|
8028
|
+
"div",
|
|
8029
|
+
{
|
|
8030
|
+
ref: scrollRef,
|
|
8031
|
+
className: cn("min-h-0 flex-1 overflow-y-auto", contentClassName),
|
|
8032
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 p-4", children: [
|
|
8033
|
+
children,
|
|
8034
|
+
isLoading && /* @__PURE__ */ jsx(TypingIndicator, {})
|
|
8035
|
+
] })
|
|
8036
|
+
}
|
|
8037
|
+
),
|
|
8038
|
+
suggestions && /* @__PURE__ */ jsx("div", { className: "border-t px-4 py-2", children: suggestions }),
|
|
8039
|
+
input,
|
|
8040
|
+
footer && /* @__PURE__ */ jsx("div", { className: "border-t px-4 py-1.5", children: footer })
|
|
8041
|
+
] });
|
|
8042
|
+
}
|
|
7918
8043
|
function AgentSurface({
|
|
7919
8044
|
mode,
|
|
7920
8045
|
messages,
|
|
@@ -7932,6 +8057,7 @@ function AgentSurface({
|
|
|
7932
8057
|
showAvatars = true,
|
|
7933
8058
|
renderMessage,
|
|
7934
8059
|
onFeedback,
|
|
8060
|
+
onConfirmAction,
|
|
7935
8061
|
report,
|
|
7936
8062
|
dataPanel,
|
|
7937
8063
|
isOpen = true,
|
|
@@ -7948,7 +8074,8 @@ function AgentSurface({
|
|
|
7948
8074
|
messages,
|
|
7949
8075
|
showAvatars,
|
|
7950
8076
|
renderMessage,
|
|
7951
|
-
onFeedback
|
|
8077
|
+
onFeedback,
|
|
8078
|
+
onConfirmAction
|
|
7952
8079
|
}
|
|
7953
8080
|
);
|
|
7954
8081
|
const resolvedInput = input ?? (onInputChange && onSubmit !== void 0 ? /* @__PURE__ */ jsx("div", { className: "border-t p-2", children: /* @__PURE__ */ jsx(
|
|
@@ -8036,6 +8163,21 @@ function AgentSurface({
|
|
|
8036
8163
|
children: conversation
|
|
8037
8164
|
}
|
|
8038
8165
|
);
|
|
8166
|
+
case "native":
|
|
8167
|
+
return /* @__PURE__ */ jsx(
|
|
8168
|
+
NativeSurface,
|
|
8169
|
+
{
|
|
8170
|
+
title,
|
|
8171
|
+
subtitle,
|
|
8172
|
+
icon,
|
|
8173
|
+
headerActions,
|
|
8174
|
+
input: resolvedInput,
|
|
8175
|
+
suggestions,
|
|
8176
|
+
isLoading,
|
|
8177
|
+
className,
|
|
8178
|
+
children: conversation
|
|
8179
|
+
}
|
|
8180
|
+
);
|
|
8039
8181
|
case "panel":
|
|
8040
8182
|
default:
|
|
8041
8183
|
return /* @__PURE__ */ jsx(
|
|
@@ -8054,7 +8196,337 @@ function AgentSurface({
|
|
|
8054
8196
|
);
|
|
8055
8197
|
}
|
|
8056
8198
|
}
|
|
8199
|
+
var NativeAgentContext = createContext(
|
|
8200
|
+
null
|
|
8201
|
+
);
|
|
8202
|
+
function useNativeAgent() {
|
|
8203
|
+
const ctx = useContext(NativeAgentContext);
|
|
8204
|
+
if (!ctx) {
|
|
8205
|
+
throw new Error(
|
|
8206
|
+
"useNativeAgent must be used within a <NativeAgentProvider>."
|
|
8207
|
+
);
|
|
8208
|
+
}
|
|
8209
|
+
return ctx;
|
|
8210
|
+
}
|
|
8211
|
+
function useNativeAgentOptional() {
|
|
8212
|
+
return useContext(NativeAgentContext);
|
|
8213
|
+
}
|
|
8214
|
+
var EMPTY_BLOCKS = [];
|
|
8215
|
+
var REASONING_STATUS = {
|
|
8216
|
+
active: "active",
|
|
8217
|
+
complete: "complete"
|
|
8218
|
+
};
|
|
8219
|
+
function toAgentMessage(message) {
|
|
8220
|
+
const reasoning = message.thinking ? [
|
|
8221
|
+
{
|
|
8222
|
+
id: `${message.id}__thinking`,
|
|
8223
|
+
label: "Thinking",
|
|
8224
|
+
content: message.thinking,
|
|
8225
|
+
status: message.streaming ? REASONING_STATUS.active : REASONING_STATUS.complete
|
|
8226
|
+
}
|
|
8227
|
+
] : void 0;
|
|
8228
|
+
return {
|
|
8229
|
+
id: message.id,
|
|
8230
|
+
role: message.role,
|
|
8231
|
+
content: message.content,
|
|
8232
|
+
timestamp: new Date(message.createdAt),
|
|
8233
|
+
reasoning
|
|
8234
|
+
};
|
|
8235
|
+
}
|
|
8236
|
+
function deriveStatus(connectionState) {
|
|
8237
|
+
switch (connectionState) {
|
|
8238
|
+
case "streaming":
|
|
8239
|
+
return "busy";
|
|
8240
|
+
case "ready":
|
|
8241
|
+
return "online";
|
|
8242
|
+
case "connecting":
|
|
8243
|
+
return "away";
|
|
8244
|
+
default:
|
|
8245
|
+
return "offline";
|
|
8246
|
+
}
|
|
8247
|
+
}
|
|
8248
|
+
function NativeAgentProvider({
|
|
8249
|
+
children,
|
|
8250
|
+
socketUrl,
|
|
8251
|
+
resolveSocketUrl,
|
|
8252
|
+
websiteId,
|
|
8253
|
+
pageCategoryId,
|
|
8254
|
+
pageName = "",
|
|
8255
|
+
pageSlug,
|
|
8256
|
+
blocks,
|
|
8257
|
+
contentBrief,
|
|
8258
|
+
onGeneratedBlocks,
|
|
8259
|
+
webSocketImpl,
|
|
8260
|
+
connectionStrategy = "lazy",
|
|
8261
|
+
seedWelcomeMessage = false,
|
|
8262
|
+
onError,
|
|
8263
|
+
onActivate
|
|
8264
|
+
}) {
|
|
8265
|
+
const [enabled, setEnabled] = useState(connectionStrategy === "eager");
|
|
8266
|
+
const [isActive, setIsActive] = useState(false);
|
|
8267
|
+
const [input, setInput] = useState("");
|
|
8268
|
+
const [pendingCount, setPendingCount] = useState(0);
|
|
8269
|
+
const [optimistic, setOptimistic] = useState([]);
|
|
8270
|
+
const blocksValue = blocks ?? EMPTY_BLOCKS;
|
|
8271
|
+
const {
|
|
8272
|
+
messages: builderMessages,
|
|
8273
|
+
connectionState,
|
|
8274
|
+
connectionError,
|
|
8275
|
+
statusLabel,
|
|
8276
|
+
isConnected,
|
|
8277
|
+
isStreaming,
|
|
8278
|
+
sendMessage,
|
|
8279
|
+
retry,
|
|
8280
|
+
reset: resetSession
|
|
8281
|
+
} = useSemanticBuilder({
|
|
8282
|
+
socketUrl,
|
|
8283
|
+
resolveSocketUrl,
|
|
8284
|
+
websiteId,
|
|
8285
|
+
pageCategoryId,
|
|
8286
|
+
pageName,
|
|
8287
|
+
pageSlug,
|
|
8288
|
+
blocks: blocksValue,
|
|
8289
|
+
contentBrief,
|
|
8290
|
+
enabled,
|
|
8291
|
+
onGeneratedBlocks,
|
|
8292
|
+
webSocketImpl,
|
|
8293
|
+
seedWelcomeMessage
|
|
8294
|
+
});
|
|
8295
|
+
const pendingPromptsRef = useRef([]);
|
|
8296
|
+
const optimisticSeqRef = useRef(0);
|
|
8297
|
+
const onActivateRef = useRef(onActivate);
|
|
8298
|
+
const onErrorRef = useRef(onError);
|
|
8299
|
+
useEffect(() => {
|
|
8300
|
+
onActivateRef.current = onActivate;
|
|
8301
|
+
}, [onActivate]);
|
|
8302
|
+
useEffect(() => {
|
|
8303
|
+
onErrorRef.current = onError;
|
|
8304
|
+
}, [onError]);
|
|
8305
|
+
useEffect(() => {
|
|
8306
|
+
if (connectionError) onErrorRef.current?.(connectionError);
|
|
8307
|
+
}, [connectionError]);
|
|
8308
|
+
const markActive = useCallback(() => {
|
|
8309
|
+
setIsActive((prev) => {
|
|
8310
|
+
if (!prev) onActivateRef.current?.();
|
|
8311
|
+
return true;
|
|
8312
|
+
});
|
|
8313
|
+
}, []);
|
|
8314
|
+
useEffect(() => {
|
|
8315
|
+
if (connectionState !== "ready" || pendingPromptsRef.current.length === 0) {
|
|
8316
|
+
return;
|
|
8317
|
+
}
|
|
8318
|
+
const next = pendingPromptsRef.current.shift();
|
|
8319
|
+
if (next === void 0) return;
|
|
8320
|
+
setPendingCount(pendingPromptsRef.current.length);
|
|
8321
|
+
setOptimistic((prev) => prev.slice(1));
|
|
8322
|
+
void sendMessage(next).then((ok) => {
|
|
8323
|
+
if (!ok) {
|
|
8324
|
+
pendingPromptsRef.current.unshift(next);
|
|
8325
|
+
setPendingCount(pendingPromptsRef.current.length);
|
|
8326
|
+
}
|
|
8327
|
+
});
|
|
8328
|
+
}, [connectionState, pendingCount, sendMessage]);
|
|
8329
|
+
const submit = useCallback(
|
|
8330
|
+
(content) => {
|
|
8331
|
+
const text = (content ?? input).trim();
|
|
8332
|
+
if (!text) return;
|
|
8333
|
+
markActive();
|
|
8334
|
+
setEnabled(true);
|
|
8335
|
+
setInput("");
|
|
8336
|
+
pendingPromptsRef.current.push(text);
|
|
8337
|
+
setPendingCount(pendingPromptsRef.current.length);
|
|
8338
|
+
const id = `native-pending-${optimisticSeqRef.current}`;
|
|
8339
|
+
optimisticSeqRef.current += 1;
|
|
8340
|
+
setOptimistic((prev) => [
|
|
8341
|
+
...prev,
|
|
8342
|
+
{ id, role: "user", content: text, timestamp: /* @__PURE__ */ new Date() }
|
|
8343
|
+
]);
|
|
8344
|
+
},
|
|
8345
|
+
[input, markActive]
|
|
8346
|
+
);
|
|
8347
|
+
const activate = useCallback(() => {
|
|
8348
|
+
markActive();
|
|
8349
|
+
setEnabled(true);
|
|
8350
|
+
}, [markActive]);
|
|
8351
|
+
const reset = useCallback(() => {
|
|
8352
|
+
pendingPromptsRef.current = [];
|
|
8353
|
+
setPendingCount(0);
|
|
8354
|
+
setOptimistic([]);
|
|
8355
|
+
setIsActive(false);
|
|
8356
|
+
setInput("");
|
|
8357
|
+
setEnabled(false);
|
|
8358
|
+
resetSession();
|
|
8359
|
+
}, [resetSession]);
|
|
8360
|
+
const messages = useMemo(
|
|
8361
|
+
() => [...builderMessages.map(toAgentMessage), ...optimistic],
|
|
8362
|
+
[builderMessages, optimistic]
|
|
8363
|
+
);
|
|
8364
|
+
const isResponding = isStreaming || pendingCount > 0 && !connectionError && connectionState !== "error" && connectionState !== "requires_shared_domain";
|
|
8365
|
+
const status = deriveStatus(connectionState);
|
|
8366
|
+
const value = useMemo(
|
|
8367
|
+
() => ({
|
|
8368
|
+
messages,
|
|
8369
|
+
isActive,
|
|
8370
|
+
isConnected,
|
|
8371
|
+
isResponding,
|
|
8372
|
+
isStreaming,
|
|
8373
|
+
connectionState,
|
|
8374
|
+
statusLabel,
|
|
8375
|
+
status,
|
|
8376
|
+
error: connectionError,
|
|
8377
|
+
input,
|
|
8378
|
+
setInput,
|
|
8379
|
+
submit,
|
|
8380
|
+
activate,
|
|
8381
|
+
reset,
|
|
8382
|
+
retry
|
|
8383
|
+
}),
|
|
8384
|
+
[
|
|
8385
|
+
messages,
|
|
8386
|
+
isActive,
|
|
8387
|
+
isConnected,
|
|
8388
|
+
isResponding,
|
|
8389
|
+
isStreaming,
|
|
8390
|
+
connectionState,
|
|
8391
|
+
statusLabel,
|
|
8392
|
+
status,
|
|
8393
|
+
connectionError,
|
|
8394
|
+
input,
|
|
8395
|
+
submit,
|
|
8396
|
+
activate,
|
|
8397
|
+
reset,
|
|
8398
|
+
retry
|
|
8399
|
+
]
|
|
8400
|
+
);
|
|
8401
|
+
return /* @__PURE__ */ jsx(NativeAgentContext.Provider, { value, children });
|
|
8402
|
+
}
|
|
8403
|
+
var noop = () => {
|
|
8404
|
+
};
|
|
8405
|
+
function warnDev(message) {
|
|
8406
|
+
const env = globalThis.process?.env;
|
|
8407
|
+
if (env && env.NODE_ENV !== "production") {
|
|
8408
|
+
console.warn(`[AgentComposer] ${message}`);
|
|
8409
|
+
}
|
|
8410
|
+
}
|
|
8411
|
+
function AgentComposer({
|
|
8412
|
+
value: valueProp,
|
|
8413
|
+
onChange,
|
|
8414
|
+
onSubmit,
|
|
8415
|
+
loading: loadingProp,
|
|
8416
|
+
disabled: disabledProp,
|
|
8417
|
+
placeholder = "Ask anything\u2026",
|
|
8418
|
+
variant = "default",
|
|
8419
|
+
bare = false,
|
|
8420
|
+
suggestions,
|
|
8421
|
+
footer,
|
|
8422
|
+
leftActions,
|
|
8423
|
+
rightActions,
|
|
8424
|
+
autoFocus = false,
|
|
8425
|
+
className,
|
|
8426
|
+
inputClassName
|
|
8427
|
+
}) {
|
|
8428
|
+
const ctx = useNativeAgentOptional();
|
|
8429
|
+
const [draft, setDraft] = useState("");
|
|
8430
|
+
const propsControlEditing = valueProp !== void 0 || onChange !== void 0;
|
|
8431
|
+
const value = propsControlEditing ? valueProp ?? "" : ctx ? ctx.input : draft;
|
|
8432
|
+
const handleChange = propsControlEditing ? onChange ?? noop : ctx ? ctx.setInput : setDraft;
|
|
8433
|
+
const loading = loadingProp ?? ctx?.isResponding ?? false;
|
|
8434
|
+
const disabled = disabledProp ?? false;
|
|
8435
|
+
const handleSubmit = useCallback(() => {
|
|
8436
|
+
if (onSubmit) {
|
|
8437
|
+
onSubmit(value);
|
|
8438
|
+
return;
|
|
8439
|
+
}
|
|
8440
|
+
if (!propsControlEditing && ctx) {
|
|
8441
|
+
ctx.submit();
|
|
8442
|
+
return;
|
|
8443
|
+
}
|
|
8444
|
+
warnDev(
|
|
8445
|
+
"submit was ignored: provide `onSubmit`, or render inside a <NativeAgentProvider>."
|
|
8446
|
+
);
|
|
8447
|
+
}, [onSubmit, propsControlEditing, ctx, value]);
|
|
8448
|
+
return /* @__PURE__ */ jsxs(
|
|
8449
|
+
"div",
|
|
8450
|
+
{
|
|
8451
|
+
className: cn(
|
|
8452
|
+
!bare && "rounded-2xl border bg-background shadow-sm",
|
|
8453
|
+
className
|
|
8454
|
+
),
|
|
8455
|
+
children: [
|
|
8456
|
+
suggestions && /* @__PURE__ */ jsx("div", { className: cn("px-3", bare ? "pb-2" : "pt-3"), children: suggestions }),
|
|
8457
|
+
/* @__PURE__ */ jsx(
|
|
8458
|
+
PromptInput,
|
|
8459
|
+
{
|
|
8460
|
+
value,
|
|
8461
|
+
onChange: handleChange,
|
|
8462
|
+
onSubmit: handleSubmit,
|
|
8463
|
+
placeholder,
|
|
8464
|
+
loading,
|
|
8465
|
+
disabled,
|
|
8466
|
+
variant,
|
|
8467
|
+
autoFocus,
|
|
8468
|
+
leftActions,
|
|
8469
|
+
rightActions,
|
|
8470
|
+
inputClassName
|
|
8471
|
+
}
|
|
8472
|
+
),
|
|
8473
|
+
footer && /* @__PURE__ */ jsx("div", { className: "px-4 pb-2 text-muted-foreground text-xs", children: footer })
|
|
8474
|
+
]
|
|
8475
|
+
}
|
|
8476
|
+
);
|
|
8477
|
+
}
|
|
8478
|
+
var EMPTY_MESSAGES = [];
|
|
8479
|
+
function AgentConversation({
|
|
8480
|
+
messages: messagesProp,
|
|
8481
|
+
isLoading: isLoadingProp,
|
|
8482
|
+
header,
|
|
8483
|
+
emptyState,
|
|
8484
|
+
showAvatars = true,
|
|
8485
|
+
renderMessage,
|
|
8486
|
+
onFeedback,
|
|
8487
|
+
onConfirmAction,
|
|
8488
|
+
autoScroll = true,
|
|
8489
|
+
className,
|
|
8490
|
+
contentClassName
|
|
8491
|
+
}) {
|
|
8492
|
+
const ctx = useNativeAgentOptional();
|
|
8493
|
+
const messages = useMemo(
|
|
8494
|
+
() => messagesProp ?? ctx?.messages ?? EMPTY_MESSAGES,
|
|
8495
|
+
[messagesProp, ctx?.messages]
|
|
8496
|
+
);
|
|
8497
|
+
const isLoading = isLoadingProp ?? ctx?.isResponding ?? false;
|
|
8498
|
+
const scrollRef = useRef(null);
|
|
8499
|
+
useEffect(() => {
|
|
8500
|
+
if (autoScroll && scrollRef.current) {
|
|
8501
|
+
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
8502
|
+
}
|
|
8503
|
+
}, [messages, isLoading, autoScroll]);
|
|
8504
|
+
const showEmptyState = messages.length === 0 && !isLoading && !!emptyState;
|
|
8505
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex h-full min-h-0 flex-col", className), children: [
|
|
8506
|
+
header,
|
|
8507
|
+
/* @__PURE__ */ jsx(
|
|
8508
|
+
"div",
|
|
8509
|
+
{
|
|
8510
|
+
ref: scrollRef,
|
|
8511
|
+
className: cn("min-h-0 flex-1 overflow-y-auto", contentClassName),
|
|
8512
|
+
children: showEmptyState ? /* @__PURE__ */ jsx("div", { className: "flex h-full items-center justify-center p-6", children: emptyState }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 p-4", children: [
|
|
8513
|
+
/* @__PURE__ */ jsx(
|
|
8514
|
+
MessageList,
|
|
8515
|
+
{
|
|
8516
|
+
messages,
|
|
8517
|
+
showAvatars,
|
|
8518
|
+
renderMessage,
|
|
8519
|
+
onFeedback,
|
|
8520
|
+
onConfirmAction
|
|
8521
|
+
}
|
|
8522
|
+
),
|
|
8523
|
+
isLoading && /* @__PURE__ */ jsx(TypingIndicator, {})
|
|
8524
|
+
] })
|
|
8525
|
+
}
|
|
8526
|
+
)
|
|
8527
|
+
] });
|
|
8528
|
+
}
|
|
8057
8529
|
|
|
8058
|
-
export { AgentAvatar, AgentHandoff, AgentProvider, AgentSurface, AllocationBreakdown, AnalyticsDashboard, Avatar, AvatarFallback, AvatarImage, Badge, Button, ChartContainer, ChatPanel, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, ControlGrid, ConversationAnalytics, ConversationArtifact, DataPayloadView, DataTable, DynamicRenderer, EntityCard, FileDropZone, FloatingWidget, FullBleedSurface, FullscreenDashboard, GuidedLessonFlow, ImageGenerator, InlineSuggestionsInput, Input, ListingFeed, MediaEditorCanvas, MediaGallery, MessageActions, MessageBubble, MessageList, MessageWithAttachments, MessageWithFeedback, MessageWithReasoning, MessageWithSteps, MetricsGrid, MobileShell, MultimodalInput, OnboardingWizard, OptionCards, OverlayModal, PerformanceMetrics, PersonaSelector, Progress, ProgressTracker, PromptInput, PromptLibrary, QuickReplies, QuizCard, RecommendationCards, ReportView, ScheduleTimeline, ScrollArea, ScrollBar, SemanticBuilderSocketClient, SentimentDisplay, SettingsPanel, SlotRenderer, SplitView, StatusBadge, SystemMessage, TemplateSelector, Textarea, Timestamp, Tooltip4 as Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TypingIndicator, WritingAssistant, badgeVariants, buildSocketUrl, buttonVariants, calculatePercentage, cn, componentManifest, componentMap, componentRegistry, copyToClipboard, createMockBackend, debounce, delay, findComponentsByCapability, findComponentsByCategory, findComponentsBySurface, formatBytes, formatCurrency, formatNumber, formatRelativeTime, formatTime, generateId, getInitials, getManifestEntry, getSentimentBgColor, getSentimentColor, isBrowser, isInIframe, normalizeWebsiteId, parseTextWithBold, registerAllComponents, truncate, useAgent, useAgentBackend, useAgentInput, useAgentLayout, useAgentMessages, useSemanticBuilder };
|
|
8530
|
+
export { AgentAvatar, AgentComposer, AgentConversation, AgentHandoff, AgentProvider, AgentSurface, AllocationBreakdown, AnalyticsDashboard, Avatar, AvatarFallback, AvatarImage, Badge, Button, ChartContainer, ChatPanel, Collapsible, CollapsibleContent2 as CollapsibleContent, CollapsibleTrigger2 as CollapsibleTrigger, ConfirmationPanel, ControlGrid, ConversationAnalytics, ConversationArtifact, DataPayloadView, DataTable, DynamicRenderer, EntityCard, FileDropZone, FloatingWidget, FullBleedSurface, FullscreenDashboard, GuidedLessonFlow, ImageGenerator, InlineSuggestionsInput, Input, ListingFeed, MediaEditorCanvas, MediaGallery, MessageActions, MessageBubble, MessageContainer, MessageContent, MessageList, MessageWithAttachments, MessageWithFeedback, MessageWithReasoning, MessageWithSteps, MetricsGrid, MobileShell, MultimodalInput, NativeAgentProvider, NativeSurface, OnboardingWizard, OptionCards, OverlayModal, PerformanceMetrics, PersonaSelector, Progress, ProgressTracker, PromptInput, PromptLibrary, QuickReplies, QuizCard, RecommendationCards, ReportView, ScheduleTimeline, ScrollArea, ScrollBar, SemanticBuilderSocketClient, SentimentDisplay, SettingsPanel, SlotRenderer, SplitView, StatusBadge, SystemMessage, TemplateSelector, Textarea, Timestamp, Tooltip4 as Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TypingIndicator, WritingAssistant, badgeVariants, buildSocketUrl, buttonVariants, calculatePercentage, cn, componentManifest, componentMap, componentRegistry, copyToClipboard, createMockBackend, debounce, delay, findComponentsByCapability, findComponentsByCategory, findComponentsBySurface, formatBytes, formatCurrency, formatNumber, formatRelativeTime, formatTime, generateId, getInitials, getManifestEntry, getSentimentBgColor, getSentimentColor, isBrowser, isInIframe, normalizeWebsiteId, parseTextWithBold, registerAllComponents, truncate, useAgent, useAgentBackend, useAgentInput, useAgentLayout, useAgentMessages, useNativeAgent, useNativeAgentOptional, useSemanticBuilder };
|
|
8059
8531
|
//# sourceMappingURL=index.js.map
|
|
8060
8532
|
//# sourceMappingURL=index.js.map
|