@page-speed/agent-everywhere 0.1.0 → 0.3.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/dist/index.cjs +102 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -1
- package/dist/index.d.ts +20 -1
- package/dist/index.js +103 -58
- package/dist/index.js.map +1 -1
- package/package.json +6 -1
package/dist/index.d.cts
CHANGED
|
@@ -1091,8 +1091,27 @@ interface PromptInputProps {
|
|
|
1091
1091
|
inputClassName?: string;
|
|
1092
1092
|
/** Variant styling */
|
|
1093
1093
|
variant?: 'default' | 'minimal' | 'bordered';
|
|
1094
|
+
/**
|
|
1095
|
+
* Minimum number of visible text rows. Default 1 (grows as the user types).
|
|
1096
|
+
*/
|
|
1097
|
+
minRows?: number;
|
|
1098
|
+
/**
|
|
1099
|
+
* Maximum number of visible text rows before the textarea scrolls internally
|
|
1100
|
+
* instead of growing further. Default 6.
|
|
1101
|
+
*/
|
|
1102
|
+
maxRows?: number;
|
|
1094
1103
|
}
|
|
1095
|
-
|
|
1104
|
+
/**
|
|
1105
|
+
* Conversational prompt input.
|
|
1106
|
+
*
|
|
1107
|
+
* Behaves like a standard AI chat input: it is a multi-line, auto-growing
|
|
1108
|
+
* textarea where **Enter submits** and **Shift+Enter inserts a newline**. The
|
|
1109
|
+
* textarea grows with content up to `maxRows`, then scrolls internally.
|
|
1110
|
+
*
|
|
1111
|
+
* (Previously this was a single-line `<input>`, which made Shift+Enter a no-op
|
|
1112
|
+
* and prevented multi-line messages entirely.)
|
|
1113
|
+
*/
|
|
1114
|
+
declare const PromptInput: react.ForwardRefExoticComponent<PromptInputProps & react.RefAttributes<HTMLTextAreaElement>>;
|
|
1096
1115
|
|
|
1097
1116
|
interface MultimodalInputProps {
|
|
1098
1117
|
/** Current input value */
|
package/dist/index.d.ts
CHANGED
|
@@ -1091,8 +1091,27 @@ interface PromptInputProps {
|
|
|
1091
1091
|
inputClassName?: string;
|
|
1092
1092
|
/** Variant styling */
|
|
1093
1093
|
variant?: 'default' | 'minimal' | 'bordered';
|
|
1094
|
+
/**
|
|
1095
|
+
* Minimum number of visible text rows. Default 1 (grows as the user types).
|
|
1096
|
+
*/
|
|
1097
|
+
minRows?: number;
|
|
1098
|
+
/**
|
|
1099
|
+
* Maximum number of visible text rows before the textarea scrolls internally
|
|
1100
|
+
* instead of growing further. Default 6.
|
|
1101
|
+
*/
|
|
1102
|
+
maxRows?: number;
|
|
1094
1103
|
}
|
|
1095
|
-
|
|
1104
|
+
/**
|
|
1105
|
+
* Conversational prompt input.
|
|
1106
|
+
*
|
|
1107
|
+
* Behaves like a standard AI chat input: it is a multi-line, auto-growing
|
|
1108
|
+
* textarea where **Enter submits** and **Shift+Enter inserts a newline**. The
|
|
1109
|
+
* textarea grows with content up to `maxRows`, then scrolls internally.
|
|
1110
|
+
*
|
|
1111
|
+
* (Previously this was a single-line `<input>`, which made Shift+Enter a no-op
|
|
1112
|
+
* and prevented multi-line messages entirely.)
|
|
1113
|
+
*/
|
|
1114
|
+
declare const PromptInput: react.ForwardRefExoticComponent<PromptInputProps & react.RefAttributes<HTMLTextAreaElement>>;
|
|
1096
1115
|
|
|
1097
1116
|
interface MultimodalInputProps {
|
|
1098
1117
|
/** Current input value */
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
3
|
import { twMerge } from 'tailwind-merge';
|
|
4
4
|
import * as React4 from 'react';
|
|
5
|
-
import { createContext, forwardRef, useCallback,
|
|
5
|
+
import { createContext, forwardRef, useRef, useImperativeHandle, useCallback, useLayoutEffect, useState, useEffect, useReducer, useMemo, useContext } from 'react';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
7
|
import { AnimatePresence, motion } from 'motion/react';
|
|
8
|
+
import { Markdown } from '@page-speed/markdown-to-jsx';
|
|
8
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
10
|
import { Slot } from '@radix-ui/react-slot';
|
|
10
11
|
import { cva } from 'class-variance-authority';
|
|
@@ -980,7 +981,32 @@ function MessageBubble({ role, children, className, unstyled }) {
|
|
|
980
981
|
}
|
|
981
982
|
);
|
|
982
983
|
}
|
|
983
|
-
|
|
984
|
+
var PROSE_CLASSES = cn(
|
|
985
|
+
"text-sm leading-relaxed",
|
|
986
|
+
"[&_p]:my-1.5 first:[&_p]:mt-0 last:[&_p]:mb-0",
|
|
987
|
+
"[&_ul]:my-1.5 [&_ul]:list-disc [&_ul]:pl-5",
|
|
988
|
+
"[&_ol]:my-1.5 [&_ol]:list-decimal [&_ol]:pl-5",
|
|
989
|
+
"[&_li]:my-0.5",
|
|
990
|
+
"[&_h1]:mt-2 [&_h1]:mb-1 [&_h1]:text-base [&_h1]:font-semibold",
|
|
991
|
+
"[&_h2]:mt-2 [&_h2]:mb-1 [&_h2]:text-sm [&_h2]:font-semibold",
|
|
992
|
+
"[&_h3]:mt-2 [&_h3]:mb-1 [&_h3]:text-sm [&_h3]:font-semibold",
|
|
993
|
+
"[&_strong]:font-semibold",
|
|
994
|
+
"[&_a]:underline [&_a]:underline-offset-2",
|
|
995
|
+
"[&_code]:rounded [&_code]:bg-black/10 [&_code]:px-1 [&_code]:py-0.5 [&_code]:text-[0.85em]",
|
|
996
|
+
"[&_pre]:my-1.5 [&_pre]:overflow-x-auto [&_pre]:rounded-md [&_pre]:bg-black/10 [&_pre]:p-2 [&_pre]:text-xs",
|
|
997
|
+
"[&_pre_code]:bg-transparent [&_pre_code]:p-0",
|
|
998
|
+
"[&_blockquote]:border-l-2 [&_blockquote]:border-current/30 [&_blockquote]:pl-3 [&_blockquote]:opacity-90",
|
|
999
|
+
"[&_hr]:my-2 [&_hr]:border-current/20",
|
|
1000
|
+
"whitespace-normal"
|
|
1001
|
+
);
|
|
1002
|
+
function MessageContent({
|
|
1003
|
+
children,
|
|
1004
|
+
className,
|
|
1005
|
+
markdown = true
|
|
1006
|
+
}) {
|
|
1007
|
+
if (markdown && typeof children === "string") {
|
|
1008
|
+
return /* @__PURE__ */ jsx(Markdown, { className: cn(PROSE_CLASSES, className), children });
|
|
1009
|
+
}
|
|
984
1010
|
return /* @__PURE__ */ jsx("div", { className: cn("text-sm leading-relaxed whitespace-pre-wrap", className), children });
|
|
985
1011
|
}
|
|
986
1012
|
function MessageContainer({ role, children, className }) {
|
|
@@ -1056,23 +1082,6 @@ function StatusBadge({
|
|
|
1056
1082
|
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-[10px]", children: displayLabel })
|
|
1057
1083
|
] });
|
|
1058
1084
|
}
|
|
1059
|
-
var Input = React4.forwardRef(
|
|
1060
|
-
({ className, type, ...props }, ref) => {
|
|
1061
|
-
return /* @__PURE__ */ jsx(
|
|
1062
|
-
"input",
|
|
1063
|
-
{
|
|
1064
|
-
type,
|
|
1065
|
-
className: cn(
|
|
1066
|
-
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
1067
|
-
className
|
|
1068
|
-
),
|
|
1069
|
-
ref,
|
|
1070
|
-
...props
|
|
1071
|
-
}
|
|
1072
|
-
);
|
|
1073
|
-
}
|
|
1074
|
-
);
|
|
1075
|
-
Input.displayName = "Input";
|
|
1076
1085
|
var buttonVariants = cva(
|
|
1077
1086
|
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
1078
1087
|
{
|
|
@@ -1112,6 +1121,8 @@ var Button = React4.forwardRef(
|
|
|
1112
1121
|
}
|
|
1113
1122
|
);
|
|
1114
1123
|
Button.displayName = "Button";
|
|
1124
|
+
var LINE_HEIGHT_PX = 20;
|
|
1125
|
+
var VERTICAL_PADDING_PX = 8;
|
|
1115
1126
|
var PromptInput = forwardRef(
|
|
1116
1127
|
({
|
|
1117
1128
|
value,
|
|
@@ -1127,11 +1138,28 @@ var PromptInput = forwardRef(
|
|
|
1127
1138
|
rightActions,
|
|
1128
1139
|
className,
|
|
1129
1140
|
inputClassName,
|
|
1130
|
-
variant = "default"
|
|
1141
|
+
variant = "default",
|
|
1142
|
+
minRows = 1,
|
|
1143
|
+
maxRows = 6
|
|
1131
1144
|
}, ref) => {
|
|
1145
|
+
const textareaRef = useRef(null);
|
|
1146
|
+
useImperativeHandle(ref, () => textareaRef.current);
|
|
1147
|
+
const resize = useCallback(() => {
|
|
1148
|
+
const el = textareaRef.current;
|
|
1149
|
+
if (!el) return;
|
|
1150
|
+
el.style.height = "auto";
|
|
1151
|
+
const maxHeight = maxRows * LINE_HEIGHT_PX + VERTICAL_PADDING_PX;
|
|
1152
|
+
const minHeight = minRows * LINE_HEIGHT_PX + VERTICAL_PADDING_PX;
|
|
1153
|
+
const next = Math.min(Math.max(el.scrollHeight, minHeight), maxHeight);
|
|
1154
|
+
el.style.height = `${next}px`;
|
|
1155
|
+
el.style.overflowY = el.scrollHeight > maxHeight ? "auto" : "hidden";
|
|
1156
|
+
}, [maxRows, minRows]);
|
|
1157
|
+
useLayoutEffect(() => {
|
|
1158
|
+
resize();
|
|
1159
|
+
}, [value, resize]);
|
|
1132
1160
|
const handleSubmit = useCallback(
|
|
1133
1161
|
(e) => {
|
|
1134
|
-
e
|
|
1162
|
+
e?.preventDefault();
|
|
1135
1163
|
if (!value.trim() || disabled || loading) return;
|
|
1136
1164
|
onSubmit();
|
|
1137
1165
|
},
|
|
@@ -1141,7 +1169,7 @@ var PromptInput = forwardRef(
|
|
|
1141
1169
|
(e) => {
|
|
1142
1170
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
1143
1171
|
e.preventDefault();
|
|
1144
|
-
handleSubmit(
|
|
1172
|
+
handleSubmit();
|
|
1145
1173
|
}
|
|
1146
1174
|
},
|
|
1147
1175
|
[handleSubmit]
|
|
@@ -1152,48 +1180,65 @@ var PromptInput = forwardRef(
|
|
|
1152
1180
|
bordered: "border rounded-lg px-3 py-2.5"
|
|
1153
1181
|
};
|
|
1154
1182
|
const inputVariantStyles = {
|
|
1155
|
-
default: "
|
|
1156
|
-
minimal: "
|
|
1157
|
-
bordered: "
|
|
1183
|
+
default: "bg-transparent",
|
|
1184
|
+
minimal: "bg-transparent px-0",
|
|
1185
|
+
bordered: "bg-muted/50"
|
|
1158
1186
|
};
|
|
1187
|
+
return /* @__PURE__ */ jsx("form", { onSubmit: handleSubmit, className: cn(variantStyles[variant], className), children: /* @__PURE__ */ jsxs("div", { className: "flex items-end gap-2", children: [
|
|
1188
|
+
leftActions,
|
|
1189
|
+
/* @__PURE__ */ jsx(
|
|
1190
|
+
"textarea",
|
|
1191
|
+
{
|
|
1192
|
+
ref: textareaRef,
|
|
1193
|
+
value,
|
|
1194
|
+
onChange: (e) => onChange(e.target.value),
|
|
1195
|
+
onKeyDown: handleKeyDown,
|
|
1196
|
+
placeholder,
|
|
1197
|
+
disabled: disabled || loading,
|
|
1198
|
+
autoFocus,
|
|
1199
|
+
rows: minRows,
|
|
1200
|
+
className: cn(
|
|
1201
|
+
"flex-1 resize-none border-0 px-0 py-1 text-sm leading-5 shadow-none",
|
|
1202
|
+
"placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0",
|
|
1203
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
1204
|
+
inputVariantStyles[variant],
|
|
1205
|
+
inputClassName
|
|
1206
|
+
)
|
|
1207
|
+
}
|
|
1208
|
+
),
|
|
1209
|
+
rightActions,
|
|
1210
|
+
showSendButton && /* @__PURE__ */ jsx(
|
|
1211
|
+
Button,
|
|
1212
|
+
{
|
|
1213
|
+
type: "submit",
|
|
1214
|
+
size: "sm",
|
|
1215
|
+
variant: variant === "minimal" ? "ghost" : "outline",
|
|
1216
|
+
disabled: !value.trim() || disabled || loading,
|
|
1217
|
+
className: "size-8 shrink-0 p-0",
|
|
1218
|
+
children: sendButtonContent || /* @__PURE__ */ jsx(SendIcon, { className: "size-4" })
|
|
1219
|
+
}
|
|
1220
|
+
)
|
|
1221
|
+
] }) });
|
|
1222
|
+
}
|
|
1223
|
+
);
|
|
1224
|
+
PromptInput.displayName = "PromptInput";
|
|
1225
|
+
var Input = React4.forwardRef(
|
|
1226
|
+
({ className, type, ...props }, ref) => {
|
|
1159
1227
|
return /* @__PURE__ */ jsx(
|
|
1160
|
-
"
|
|
1228
|
+
"input",
|
|
1161
1229
|
{
|
|
1162
|
-
|
|
1163
|
-
className: cn(
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
ref,
|
|
1170
|
-
value,
|
|
1171
|
-
onChange: (e) => onChange(e.target.value),
|
|
1172
|
-
onKeyDown: handleKeyDown,
|
|
1173
|
-
placeholder,
|
|
1174
|
-
disabled: disabled || loading,
|
|
1175
|
-
autoFocus,
|
|
1176
|
-
className: cn("flex-1 text-sm", inputVariantStyles[variant], inputClassName)
|
|
1177
|
-
}
|
|
1178
|
-
),
|
|
1179
|
-
rightActions,
|
|
1180
|
-
showSendButton && /* @__PURE__ */ jsx(
|
|
1181
|
-
Button,
|
|
1182
|
-
{
|
|
1183
|
-
type: "submit",
|
|
1184
|
-
size: "sm",
|
|
1185
|
-
variant: variant === "minimal" ? "ghost" : "outline",
|
|
1186
|
-
disabled: !value.trim() || disabled || loading,
|
|
1187
|
-
className: "size-8 shrink-0 p-0",
|
|
1188
|
-
children: sendButtonContent || /* @__PURE__ */ jsx(SendIcon, { className: "size-4" })
|
|
1189
|
-
}
|
|
1190
|
-
)
|
|
1191
|
-
] })
|
|
1230
|
+
type,
|
|
1231
|
+
className: cn(
|
|
1232
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
1233
|
+
className
|
|
1234
|
+
),
|
|
1235
|
+
ref,
|
|
1236
|
+
...props
|
|
1192
1237
|
}
|
|
1193
1238
|
);
|
|
1194
1239
|
}
|
|
1195
1240
|
);
|
|
1196
|
-
|
|
1241
|
+
Input.displayName = "Input";
|
|
1197
1242
|
var attachmentIcons = {
|
|
1198
1243
|
image: ImageIcon,
|
|
1199
1244
|
audio: MicIcon,
|
|
@@ -6227,7 +6272,7 @@ function FloatingWidget({
|
|
|
6227
6272
|
children,
|
|
6228
6273
|
isLoading && /* @__PURE__ */ jsx(TypingIndicator, { size: "sm" })
|
|
6229
6274
|
] }) }),
|
|
6230
|
-
quickReplies && /* @__PURE__ */ jsx("div", { className: "
|
|
6275
|
+
quickReplies && /* @__PURE__ */ jsx("div", { className: "max-h-[40%] shrink-0 overflow-y-auto border-t bg-muted/30 px-4 py-2", children: quickReplies }),
|
|
6231
6276
|
input,
|
|
6232
6277
|
footer && /* @__PURE__ */ jsx("div", { className: "border-t px-4 py-1.5", children: /* @__PURE__ */ jsx("p", { className: "text-center text-[10px] text-muted-foreground", children: footer }) })
|
|
6233
6278
|
]
|