@page-speed/agent-everywhere 0.3.0 → 0.4.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 +36 -1
- package/dist/index.cjs +164 -56
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +115 -7
- package/dist/index.d.ts +115 -7
- package/dist/index.js +163 -58
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,6 +71,41 @@ import { AgentSurface } from '@page-speed/agent-everywhere';
|
|
|
71
71
|
/>;
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
+
### Inline confirmation / proposed-plan panels
|
|
75
|
+
|
|
76
|
+
Confirmation and proposed-plan panels flow **inline in the transcript** — attach
|
|
77
|
+
one to a message via `message.confirmation` and it renders after that message's
|
|
78
|
+
content, never pinned over the response. The plan body reuses the same markdown
|
|
79
|
+
rendering and spacing as assistant messages, so long multi-paragraph / bulleted
|
|
80
|
+
plans stay readable. Wire `onConfirmAction` (or use `ConfirmationPanel`
|
|
81
|
+
directly) to handle the action buttons.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
const messages = [
|
|
85
|
+
{
|
|
86
|
+
id: 'm1',
|
|
87
|
+
role: 'assistant',
|
|
88
|
+
content: 'Here is the response and the plan.',
|
|
89
|
+
timestamp: new Date(),
|
|
90
|
+
confirmation: {
|
|
91
|
+
title: 'Proposed plan',
|
|
92
|
+
summary: '3 pages to change',
|
|
93
|
+
body: '## What changes\n\n- Rebuild the platform page\n- Refresh OG images',
|
|
94
|
+
actions: [
|
|
95
|
+
{ id: 'apply', label: 'Apply changes' },
|
|
96
|
+
{ id: 'cancel', label: 'Cancel', variant: 'outline' },
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
<AgentSurface
|
|
103
|
+
mode="widget"
|
|
104
|
+
messages={messages}
|
|
105
|
+
onConfirmAction={(messageId, actionId) => apply(messageId, actionId)}
|
|
106
|
+
/>;
|
|
107
|
+
```
|
|
108
|
+
|
|
74
109
|
## Artifacts
|
|
75
110
|
|
|
76
111
|
Components an agent can render inside responses, grouped by category. All are
|
|
@@ -81,7 +116,7 @@ prop-driven and individually importable:
|
|
|
81
116
|
`AnalyticsDashboard`, `ReportView`.
|
|
82
117
|
- **Interactive** — `EntityCard`, `OptionCards`, `ListingFeed`, `ControlGrid`,
|
|
83
118
|
`RecommendationCards`, `ScheduleTimeline`, `SettingsPanel`, `AgentHandoff`,
|
|
84
|
-
`PersonaSelector`.
|
|
119
|
+
`ConfirmationPanel`, `PersonaSelector`.
|
|
85
120
|
- **Messages** — `MessageList`, `MessageWithReasoning`, `MessageWithSteps`,
|
|
86
121
|
`MessageWithFeedback`, `MessageWithAttachments`, `ConversationArtifact`.
|
|
87
122
|
- **Input** — `PromptInput`, `MultimodalInput`, `QuickReplies`,
|
package/dist/index.cjs
CHANGED
|
@@ -1007,33 +1007,70 @@ function MessageBubble({ role, children, className, unstyled }) {
|
|
|
1007
1007
|
}
|
|
1008
1008
|
);
|
|
1009
1009
|
}
|
|
1010
|
-
var
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
"
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
"[&_a]:underline [&_a]:underline-offset-2",
|
|
1021
|
-
"[&_code]:rounded [&_code]:bg-black/10 [&_code]:px-1 [&_code]:py-0.5 [&_code]:text-[0.85em]",
|
|
1022
|
-
"[&_pre]:my-1.5 [&_pre]:overflow-x-auto [&_pre]:rounded-md [&_pre]:bg-black/10 [&_pre]:p-2 [&_pre]:text-xs",
|
|
1023
|
-
"[&_pre_code]:bg-transparent [&_pre_code]:p-0",
|
|
1024
|
-
"[&_blockquote]:border-l-2 [&_blockquote]:border-current/30 [&_blockquote]:pl-3 [&_blockquote]:opacity-90",
|
|
1025
|
-
"[&_hr]:my-2 [&_hr]:border-current/20",
|
|
1026
|
-
"whitespace-normal"
|
|
1010
|
+
var SPACE = "0.5rem";
|
|
1011
|
+
var mdStyle = { lineHeight: 1.6 };
|
|
1012
|
+
var MdP = ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: `${SPACE} 0` }, children });
|
|
1013
|
+
var MdUl = ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: `${SPACE} 0`, paddingLeft: "1.25rem", listStyle: "disc" }, children });
|
|
1014
|
+
var MdOl = ({ children }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1015
|
+
"ol",
|
|
1016
|
+
{
|
|
1017
|
+
style: { margin: `${SPACE} 0`, paddingLeft: "1.25rem", listStyle: "decimal" },
|
|
1018
|
+
children
|
|
1019
|
+
}
|
|
1027
1020
|
);
|
|
1021
|
+
var MdLi = ({ children }) => /* @__PURE__ */ jsxRuntime.jsx("li", { style: { margin: "0.2rem 0" }, children });
|
|
1022
|
+
var mkHeading = (level, fontSize) => ({ children }) => {
|
|
1023
|
+
const Tag = `h${level}`;
|
|
1024
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Tag, { style: { margin: `${SPACE} 0 0.25rem`, fontSize, fontWeight: 600 }, children });
|
|
1025
|
+
};
|
|
1026
|
+
var MdBlockquote = ({ children }) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1027
|
+
"blockquote",
|
|
1028
|
+
{
|
|
1029
|
+
style: {
|
|
1030
|
+
margin: `${SPACE} 0`,
|
|
1031
|
+
paddingLeft: "0.75rem",
|
|
1032
|
+
borderLeft: "2px solid currentColor",
|
|
1033
|
+
opacity: 0.85
|
|
1034
|
+
},
|
|
1035
|
+
children
|
|
1036
|
+
}
|
|
1037
|
+
);
|
|
1038
|
+
var MARKDOWN_OVERRIDES = {
|
|
1039
|
+
p: MdP,
|
|
1040
|
+
ul: MdUl,
|
|
1041
|
+
ol: MdOl,
|
|
1042
|
+
li: MdLi,
|
|
1043
|
+
h1: mkHeading(1, "1rem"),
|
|
1044
|
+
h2: mkHeading(2, "0.95rem"),
|
|
1045
|
+
h3: mkHeading(3, "0.9rem"),
|
|
1046
|
+
blockquote: MdBlockquote
|
|
1047
|
+
};
|
|
1028
1048
|
function MessageContent({
|
|
1029
1049
|
children,
|
|
1030
1050
|
className,
|
|
1031
1051
|
markdown = true
|
|
1032
1052
|
}) {
|
|
1033
1053
|
if (markdown && typeof children === "string") {
|
|
1034
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1054
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1055
|
+
markdownToJsx.Markdown,
|
|
1056
|
+
{
|
|
1057
|
+
className: cn(
|
|
1058
|
+
"text-sm [&>*:first-child]:mt-0 [&>*:last-child]:mb-0",
|
|
1059
|
+
className
|
|
1060
|
+
),
|
|
1061
|
+
overrides: MARKDOWN_OVERRIDES,
|
|
1062
|
+
children
|
|
1063
|
+
}
|
|
1064
|
+
);
|
|
1035
1065
|
}
|
|
1036
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1066
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1067
|
+
"div",
|
|
1068
|
+
{
|
|
1069
|
+
className: cn("text-sm leading-relaxed whitespace-pre-wrap", className),
|
|
1070
|
+
style: mdStyle,
|
|
1071
|
+
children
|
|
1072
|
+
}
|
|
1073
|
+
);
|
|
1037
1074
|
}
|
|
1038
1075
|
function MessageContainer({ role, children, className }) {
|
|
1039
1076
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1201,7 +1238,7 @@ var PromptInput = React4.forwardRef(
|
|
|
1201
1238
|
[handleSubmit]
|
|
1202
1239
|
);
|
|
1203
1240
|
const variantStyles = {
|
|
1204
|
-
default: "
|
|
1241
|
+
default: "px-3 py-2.5",
|
|
1205
1242
|
minimal: "px-3 py-2",
|
|
1206
1243
|
bordered: "border rounded-lg px-3 py-2.5"
|
|
1207
1244
|
};
|
|
@@ -1210,41 +1247,48 @@ var PromptInput = React4.forwardRef(
|
|
|
1210
1247
|
minimal: "bg-transparent px-0",
|
|
1211
1248
|
bordered: "bg-muted/50"
|
|
1212
1249
|
};
|
|
1213
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1250
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1251
|
+
"form",
|
|
1252
|
+
{
|
|
1253
|
+
onSubmit: handleSubmit,
|
|
1254
|
+
className: cn(variantStyles[variant], className),
|
|
1255
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-end gap-2", children: [
|
|
1256
|
+
leftActions,
|
|
1257
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1258
|
+
"textarea",
|
|
1259
|
+
{
|
|
1260
|
+
ref: textareaRef,
|
|
1261
|
+
value,
|
|
1262
|
+
onChange: (e) => onChange(e.target.value),
|
|
1263
|
+
onKeyDown: handleKeyDown,
|
|
1264
|
+
placeholder,
|
|
1265
|
+
disabled: disabled || loading,
|
|
1266
|
+
autoFocus,
|
|
1267
|
+
rows: minRows,
|
|
1268
|
+
className: cn(
|
|
1269
|
+
"flex-1 resize-none border-0 px-0 py-1 text-sm leading-5 shadow-none",
|
|
1270
|
+
"placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-0",
|
|
1271
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
1272
|
+
inputVariantStyles[variant],
|
|
1273
|
+
inputClassName
|
|
1274
|
+
)
|
|
1275
|
+
}
|
|
1276
|
+
),
|
|
1277
|
+
rightActions,
|
|
1278
|
+
showSendButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1279
|
+
Button,
|
|
1280
|
+
{
|
|
1281
|
+
type: "submit",
|
|
1282
|
+
size: "sm",
|
|
1283
|
+
variant: variant === "minimal" ? "ghost" : "outline",
|
|
1284
|
+
disabled: !value.trim() || disabled || loading,
|
|
1285
|
+
className: "size-8 shrink-0 p-0",
|
|
1286
|
+
children: sendButtonContent || /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SendIcon, { className: "size-4" })
|
|
1287
|
+
}
|
|
1232
1288
|
)
|
|
1233
|
-
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
showSendButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1237
|
-
Button,
|
|
1238
|
-
{
|
|
1239
|
-
type: "submit",
|
|
1240
|
-
size: "sm",
|
|
1241
|
-
variant: variant === "minimal" ? "ghost" : "outline",
|
|
1242
|
-
disabled: !value.trim() || disabled || loading,
|
|
1243
|
-
className: "size-8 shrink-0 p-0",
|
|
1244
|
-
children: sendButtonContent || /* @__PURE__ */ jsxRuntime.jsx(lucideReact.SendIcon, { className: "size-4" })
|
|
1245
|
-
}
|
|
1246
|
-
)
|
|
1247
|
-
] }) });
|
|
1289
|
+
] })
|
|
1290
|
+
}
|
|
1291
|
+
);
|
|
1248
1292
|
}
|
|
1249
1293
|
);
|
|
1250
1294
|
PromptInput.displayName = "PromptInput";
|
|
@@ -7680,10 +7724,58 @@ function ReportView({ report, className }) {
|
|
|
7680
7724
|
))
|
|
7681
7725
|
] });
|
|
7682
7726
|
}
|
|
7727
|
+
function ConfirmationPanel({
|
|
7728
|
+
title = "Proposed plan",
|
|
7729
|
+
summary,
|
|
7730
|
+
body,
|
|
7731
|
+
markdown = true,
|
|
7732
|
+
icon,
|
|
7733
|
+
actions,
|
|
7734
|
+
onAction,
|
|
7735
|
+
ariaLabel,
|
|
7736
|
+
className
|
|
7737
|
+
}) {
|
|
7738
|
+
const hasBody = body !== void 0 && body !== null && body !== "";
|
|
7739
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
7740
|
+
react.motion.section,
|
|
7741
|
+
{
|
|
7742
|
+
initial: { opacity: 0, y: 6 },
|
|
7743
|
+
animate: { opacity: 1, y: 0 },
|
|
7744
|
+
transition: { duration: 0.2 },
|
|
7745
|
+
"aria-label": ariaLabel ?? title,
|
|
7746
|
+
className: cn(
|
|
7747
|
+
"flex w-full min-w-0 flex-col rounded-lg border bg-card p-4",
|
|
7748
|
+
className
|
|
7749
|
+
),
|
|
7750
|
+
children: [
|
|
7751
|
+
/* @__PURE__ */ jsxRuntime.jsxs("header", { className: "flex items-center gap-2", children: [
|
|
7752
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-6 shrink-0 items-center justify-center rounded-md bg-muted/60 text-muted-foreground", children: icon ?? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ClipboardListIcon, { className: "size-3.5" }) }),
|
|
7753
|
+
/* @__PURE__ */ jsxRuntime.jsx("h4", { className: "min-w-0 flex-1 truncate font-medium text-sm", children: title }),
|
|
7754
|
+
summary && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "secondary", className: "shrink-0 text-[10px] font-normal", children: summary })
|
|
7755
|
+
] }),
|
|
7756
|
+
hasBody && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 min-w-0", children: typeof body === "string" ? /* @__PURE__ */ jsxRuntime.jsx(MessageContent, { markdown, children: body }) : body }),
|
|
7757
|
+
actions && actions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 flex flex-wrap gap-2", children: actions.map((action, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
7758
|
+
Button,
|
|
7759
|
+
{
|
|
7760
|
+
type: "button",
|
|
7761
|
+
size: "sm",
|
|
7762
|
+
variant: action.variant ?? (index === 0 ? "default" : "outline"),
|
|
7763
|
+
disabled: action.disabled || action.busy,
|
|
7764
|
+
"aria-busy": action.busy || void 0,
|
|
7765
|
+
onClick: () => onAction?.(action.id),
|
|
7766
|
+
children: action.label
|
|
7767
|
+
},
|
|
7768
|
+
action.id
|
|
7769
|
+
)) })
|
|
7770
|
+
]
|
|
7771
|
+
}
|
|
7772
|
+
);
|
|
7773
|
+
}
|
|
7683
7774
|
function MessageList({
|
|
7684
7775
|
messages,
|
|
7685
7776
|
showAvatars = true,
|
|
7686
7777
|
renderMessage,
|
|
7778
|
+
onConfirmAction,
|
|
7687
7779
|
className
|
|
7688
7780
|
}) {
|
|
7689
7781
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-col gap-4", className), children: messages.map((message) => {
|
|
@@ -7700,7 +7792,18 @@ function MessageList({
|
|
|
7700
7792
|
hasSteps && /* @__PURE__ */ jsxRuntime.jsx(MessageWithSteps, { steps: message.steps }),
|
|
7701
7793
|
message.content && /* @__PURE__ */ jsxRuntime.jsx(MessageBubble, { role: message.role, children: /* @__PURE__ */ jsxRuntime.jsx(MessageContent, { children: message.content }) }),
|
|
7702
7794
|
hasAttachments && /* @__PURE__ */ jsxRuntime.jsx(MessageWithAttachments, { attachments: message.attachments }),
|
|
7703
|
-
message.data && /* @__PURE__ */ jsxRuntime.jsx(DataPayloadView, { payload: message.data })
|
|
7795
|
+
message.data && /* @__PURE__ */ jsxRuntime.jsx(DataPayloadView, { payload: message.data }),
|
|
7796
|
+
message.confirmation && /* @__PURE__ */ jsxRuntime.jsx(
|
|
7797
|
+
ConfirmationPanel,
|
|
7798
|
+
{
|
|
7799
|
+
title: message.confirmation.title,
|
|
7800
|
+
summary: message.confirmation.summary,
|
|
7801
|
+
body: message.confirmation.body,
|
|
7802
|
+
markdown: message.confirmation.markdown,
|
|
7803
|
+
actions: message.confirmation.actions,
|
|
7804
|
+
onAction: (actionId) => onConfirmAction?.(message.id, actionId)
|
|
7805
|
+
}
|
|
7806
|
+
)
|
|
7704
7807
|
] })
|
|
7705
7808
|
] }, message.id);
|
|
7706
7809
|
}) });
|
|
@@ -7921,6 +8024,7 @@ function AgentSurface({
|
|
|
7921
8024
|
showAvatars = true,
|
|
7922
8025
|
renderMessage,
|
|
7923
8026
|
onFeedback,
|
|
8027
|
+
onConfirmAction,
|
|
7924
8028
|
report,
|
|
7925
8029
|
dataPanel,
|
|
7926
8030
|
isOpen = true,
|
|
@@ -7937,7 +8041,8 @@ function AgentSurface({
|
|
|
7937
8041
|
messages,
|
|
7938
8042
|
showAvatars,
|
|
7939
8043
|
renderMessage,
|
|
7940
|
-
onFeedback
|
|
8044
|
+
onFeedback,
|
|
8045
|
+
onConfirmAction
|
|
7941
8046
|
}
|
|
7942
8047
|
);
|
|
7943
8048
|
const resolvedInput = input ?? (onInputChange && onSubmit !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t p-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -8060,6 +8165,7 @@ exports.ChatPanel = ChatPanel;
|
|
|
8060
8165
|
exports.Collapsible = Collapsible;
|
|
8061
8166
|
exports.CollapsibleContent = CollapsibleContent2;
|
|
8062
8167
|
exports.CollapsibleTrigger = CollapsibleTrigger2;
|
|
8168
|
+
exports.ConfirmationPanel = ConfirmationPanel;
|
|
8063
8169
|
exports.ControlGrid = ControlGrid;
|
|
8064
8170
|
exports.ConversationAnalytics = ConversationAnalytics;
|
|
8065
8171
|
exports.ConversationArtifact = ConversationArtifact;
|
|
@@ -8080,6 +8186,8 @@ exports.MediaEditorCanvas = MediaEditorCanvas;
|
|
|
8080
8186
|
exports.MediaGallery = MediaGallery;
|
|
8081
8187
|
exports.MessageActions = MessageActions;
|
|
8082
8188
|
exports.MessageBubble = MessageBubble;
|
|
8189
|
+
exports.MessageContainer = MessageContainer;
|
|
8190
|
+
exports.MessageContent = MessageContent;
|
|
8083
8191
|
exports.MessageList = MessageList;
|
|
8084
8192
|
exports.MessageWithAttachments = MessageWithAttachments;
|
|
8085
8193
|
exports.MessageWithFeedback = MessageWithFeedback;
|