@webless/agent 0.7.2 → 0.7.4
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/{chunk-HZUPH5Z7.js → chunk-GS65OJFL.js} +197 -126
- package/dist/chunk-GS65OJFL.js.map +1 -0
- package/dist/embed.cjs +188 -117
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.css +105 -8
- package/dist/embed.css.map +1 -1
- package/dist/embed.js +1 -1
- package/dist/react.cjs +188 -117
- package/dist/react.cjs.map +1 -1
- package/dist/react.css +105 -8
- package/dist/react.css.map +1 -1
- package/dist/react.js +1 -1
- package/package.json +2 -1
- package/dist/chunk-HZUPH5Z7.js.map +0 -1
package/dist/embed.cjs
CHANGED
|
@@ -3804,42 +3804,72 @@ function emptyValues(form) {
|
|
|
3804
3804
|
for (const field of form?.fields ?? []) values[field.id] = "";
|
|
3805
3805
|
return values;
|
|
3806
3806
|
}
|
|
3807
|
+
function createDraft(form) {
|
|
3808
|
+
return {
|
|
3809
|
+
form,
|
|
3810
|
+
values: emptyValues(form),
|
|
3811
|
+
expanded: Boolean(form),
|
|
3812
|
+
submitted: false,
|
|
3813
|
+
dismissalSent: false,
|
|
3814
|
+
attempted: false
|
|
3815
|
+
};
|
|
3816
|
+
}
|
|
3807
3817
|
function Composer({
|
|
3808
3818
|
disabled = false,
|
|
3809
3819
|
placeholder = "Ask anything\u2026",
|
|
3810
3820
|
variant = "default",
|
|
3811
3821
|
form = null,
|
|
3822
|
+
allowFormResume = true,
|
|
3812
3823
|
onSubmit
|
|
3813
3824
|
}) {
|
|
3814
3825
|
const [value, setValue] = (0, import_react8.useState)("");
|
|
3815
|
-
const [
|
|
3816
|
-
() => emptyValues(form)
|
|
3817
|
-
);
|
|
3818
|
-
const [blurred, setBlurred] = (0, import_react8.useState)({});
|
|
3826
|
+
const [draft, setDraft] = (0, import_react8.useState)(() => createDraft(form));
|
|
3819
3827
|
const inputRef = (0, import_react8.useRef)(null);
|
|
3820
3828
|
const firstFieldRef = (0, import_react8.useRef)(null);
|
|
3829
|
+
const formRef = (0, import_react8.useRef)(null);
|
|
3821
3830
|
const formId = (0, import_react8.useId)();
|
|
3822
|
-
|
|
3823
|
-
const
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
setBlurred({});
|
|
3827
|
-
}, [form?.id]);
|
|
3831
|
+
if (form && form.id !== draft.form?.id) setDraft(createDraft(form));
|
|
3832
|
+
const savedForm = allowFormResume && !draft.submitted ? draft.form : null;
|
|
3833
|
+
const activeForm = !disabled && draft.expanded ? savedForm : null;
|
|
3834
|
+
const hasDraft = Object.values(draft.values).some((value2) => value2.trim());
|
|
3828
3835
|
(0, import_react8.useEffect)(() => {
|
|
3829
3836
|
if (activeForm) firstFieldRef.current?.focus();
|
|
3830
|
-
|
|
3837
|
+
else if ((savedForm || draft.submitted) && !disabled)
|
|
3838
|
+
inputRef.current?.focus();
|
|
3839
|
+
}, [activeForm?.id, disabled, savedForm?.id, draft.submitted]);
|
|
3831
3840
|
function submitChat() {
|
|
3832
3841
|
const trimmed = value.trim();
|
|
3833
3842
|
if (!trimmed || disabled) return;
|
|
3834
|
-
|
|
3843
|
+
const shareDismissal = savedForm && !draft.dismissalSent;
|
|
3844
|
+
onSubmit?.(
|
|
3845
|
+
shareDismissal ? `I'd like to keep chatting without sharing the requested details for now. Please don't ask for them again unless I choose to proceed with something that needs them.
|
|
3846
|
+
|
|
3847
|
+
${trimmed}` : trimmed
|
|
3848
|
+
);
|
|
3849
|
+
if (shareDismissal)
|
|
3850
|
+
setDraft((current) => ({ ...current, dismissalSent: true }));
|
|
3835
3851
|
setValue("");
|
|
3836
3852
|
inputRef.current?.focus();
|
|
3837
3853
|
}
|
|
3838
3854
|
function submitForm() {
|
|
3839
|
-
if (!activeForm || disabled
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3855
|
+
if (!activeForm || disabled) return;
|
|
3856
|
+
if (!isComposerFormComplete(activeForm, draft.values)) {
|
|
3857
|
+
setDraft((current) => ({ ...current, attempted: true }));
|
|
3858
|
+
const invalidField = activeForm.fields.find(
|
|
3859
|
+
(field) => !isValidComposerFieldValue(field, draft.values[field.id] ?? "")
|
|
3860
|
+
);
|
|
3861
|
+
const control = invalidField && formRef.current?.elements.namedItem(invalidField.id);
|
|
3862
|
+
if (control instanceof HTMLElement) control.focus();
|
|
3863
|
+
return;
|
|
3864
|
+
}
|
|
3865
|
+
onSubmit?.(formatComposerFormMessage(activeForm, draft.values));
|
|
3866
|
+
setDraft((current) => ({
|
|
3867
|
+
...current,
|
|
3868
|
+
values: emptyValues(activeForm),
|
|
3869
|
+
expanded: false,
|
|
3870
|
+
submitted: true,
|
|
3871
|
+
attempted: false
|
|
3872
|
+
}));
|
|
3843
3873
|
}
|
|
3844
3874
|
function handleSubmit(event) {
|
|
3845
3875
|
event.preventDefault();
|
|
@@ -3863,112 +3893,151 @@ function Composer({
|
|
|
3863
3893
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3864
3894
|
"form",
|
|
3865
3895
|
{
|
|
3896
|
+
ref: formRef,
|
|
3897
|
+
noValidate: true,
|
|
3866
3898
|
className: [
|
|
3867
3899
|
"composer",
|
|
3868
3900
|
variant === "dock" ? "composer--dock" : "",
|
|
3869
3901
|
activeForm ? "composer--form" : ""
|
|
3870
3902
|
].filter(Boolean).join(" "),
|
|
3871
3903
|
onSubmit: handleSubmit,
|
|
3872
|
-
children: activeForm ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
|
|
3882
|
-
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3904
|
+
children: activeForm ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
3905
|
+
"div",
|
|
3906
|
+
{
|
|
3907
|
+
className: "composer__sheet",
|
|
3908
|
+
role: "group",
|
|
3909
|
+
"aria-label": "Contact details",
|
|
3910
|
+
children: [
|
|
3911
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__form-heading", children: [
|
|
3912
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("strong", { children: "Share your details" }),
|
|
3913
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Optional" }),
|
|
3914
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: "You can also keep chatting." })
|
|
3915
|
+
] }),
|
|
3916
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "composer__fields", children: activeForm.fields.map((field, index) => {
|
|
3917
|
+
const fieldId = `${formId}-${field.id}`;
|
|
3918
|
+
const invalid = draft.attempted && !isValidComposerFieldValue(field, draft.values[field.id] ?? "");
|
|
3919
|
+
const controlProps = {
|
|
3920
|
+
id: fieldId,
|
|
3921
|
+
name: field.id,
|
|
3922
|
+
disabled,
|
|
3923
|
+
required: field.required,
|
|
3924
|
+
autoComplete: field.autocomplete,
|
|
3925
|
+
placeholder: field.placeholder,
|
|
3926
|
+
spellCheck: false,
|
|
3927
|
+
value: draft.values[field.id] ?? "",
|
|
3928
|
+
"aria-invalid": invalid || void 0,
|
|
3929
|
+
"aria-describedby": invalid ? `${fieldId}-error` : void 0,
|
|
3930
|
+
onChange: (event) => {
|
|
3931
|
+
const next = readComposerControlValue(event);
|
|
3932
|
+
setDraft((current) => ({
|
|
3933
|
+
...current,
|
|
3934
|
+
values: { ...current.values, [field.id]: next }
|
|
3935
|
+
}));
|
|
3936
|
+
},
|
|
3937
|
+
onKeyDown: handleFormKeyDown
|
|
3938
|
+
};
|
|
3939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
3940
|
+
"div",
|
|
3941
|
+
{
|
|
3942
|
+
className: [
|
|
3943
|
+
"composer__row",
|
|
3944
|
+
field.kind === "textarea" ? "composer__row--grow" : ""
|
|
3945
|
+
].filter(Boolean).join(" "),
|
|
3946
|
+
children: [
|
|
3947
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { className: "composer__label", htmlFor: fieldId, children: [
|
|
3948
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "composer__field-label", children: field.label }),
|
|
3949
|
+
field.kind === "textarea" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3950
|
+
"textarea",
|
|
3951
|
+
{
|
|
3952
|
+
...controlProps,
|
|
3953
|
+
ref: index === 0 ? (node) => {
|
|
3954
|
+
firstFieldRef.current = node;
|
|
3955
|
+
} : void 0,
|
|
3956
|
+
className: "composer__control composer__control--area",
|
|
3957
|
+
rows: 3
|
|
3958
|
+
}
|
|
3959
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3960
|
+
"input",
|
|
3961
|
+
{
|
|
3962
|
+
...controlProps,
|
|
3963
|
+
ref: index === 0 ? (node) => {
|
|
3964
|
+
firstFieldRef.current = node;
|
|
3965
|
+
} : void 0,
|
|
3966
|
+
className: "composer__control",
|
|
3967
|
+
type: field.kind,
|
|
3968
|
+
inputMode: field.kind === "tel" ? "tel" : void 0
|
|
3969
|
+
}
|
|
3970
|
+
)
|
|
3971
|
+
] }),
|
|
3972
|
+
invalid ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "composer__error", id: `${fieldId}-error`, children: field.kind === "email" ? "Enter a valid email to share your details." : `Add your ${field.label.toLowerCase()} to share your details.` }) : null
|
|
3973
|
+
]
|
|
3974
|
+
},
|
|
3975
|
+
field.id
|
|
3976
|
+
);
|
|
3977
|
+
}) }),
|
|
3978
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__toolbar", children: [
|
|
3979
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3980
|
+
"button",
|
|
3981
|
+
{
|
|
3982
|
+
type: "submit",
|
|
3983
|
+
className: "composer__action composer__action--primary",
|
|
3984
|
+
disabled,
|
|
3985
|
+
children: "Share details"
|
|
3986
|
+
}
|
|
3987
|
+
),
|
|
3988
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3989
|
+
"button",
|
|
3990
|
+
{
|
|
3991
|
+
type: "button",
|
|
3992
|
+
className: "composer__action",
|
|
3993
|
+
disabled,
|
|
3994
|
+
onClick: () => setDraft((current) => ({ ...current, expanded: false })),
|
|
3995
|
+
children: "Keep chatting"
|
|
3996
|
+
}
|
|
3997
|
+
)
|
|
3998
|
+
] })
|
|
3999
|
+
]
|
|
4000
|
+
}
|
|
4001
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
4002
|
+
savedForm ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__resume", children: [
|
|
4003
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: hasDraft ? "Your details aren\u2019t shared yet" : "Contact details are optional" }),
|
|
4004
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
4005
|
+
"button",
|
|
3899
4006
|
{
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
|
|
3905
|
-
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
);
|
|
3935
|
-
}),
|
|
3936
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "composer__toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3937
|
-
"button",
|
|
3938
|
-
{
|
|
3939
|
-
type: "submit",
|
|
3940
|
-
className: "composer__send",
|
|
3941
|
-
disabled: disabled || !canSendForm,
|
|
3942
|
-
"aria-label": "Send details",
|
|
3943
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
|
|
3944
|
-
}
|
|
3945
|
-
) })
|
|
3946
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__field", children: [
|
|
3947
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3948
|
-
"textarea",
|
|
3949
|
-
{
|
|
3950
|
-
ref: inputRef,
|
|
3951
|
-
className: "composer__input",
|
|
3952
|
-
rows: 1,
|
|
3953
|
-
value,
|
|
3954
|
-
placeholder,
|
|
3955
|
-
disabled,
|
|
3956
|
-
spellCheck: false,
|
|
3957
|
-
"aria-label": "Message",
|
|
3958
|
-
onChange: (event) => setValue(event.target.value),
|
|
3959
|
-
onKeyDown: handleChatKeyDown
|
|
3960
|
-
}
|
|
3961
|
-
),
|
|
3962
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
3963
|
-
"button",
|
|
3964
|
-
{
|
|
3965
|
-
type: "submit",
|
|
3966
|
-
className: "composer__send",
|
|
3967
|
-
disabled: disabled || !value.trim(),
|
|
3968
|
-
"aria-label": "Send message",
|
|
3969
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
|
|
3970
|
-
}
|
|
3971
|
-
)
|
|
4007
|
+
type: "button",
|
|
4008
|
+
disabled,
|
|
4009
|
+
onClick: () => setDraft((current) => ({ ...current, expanded: true })),
|
|
4010
|
+
children: hasDraft ? "Resume details" : "Add details"
|
|
4011
|
+
}
|
|
4012
|
+
)
|
|
4013
|
+
] }) : null,
|
|
4014
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__field", children: [
|
|
4015
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
4016
|
+
"textarea",
|
|
4017
|
+
{
|
|
4018
|
+
ref: inputRef,
|
|
4019
|
+
className: "composer__input",
|
|
4020
|
+
rows: 1,
|
|
4021
|
+
value,
|
|
4022
|
+
placeholder,
|
|
4023
|
+
disabled,
|
|
4024
|
+
spellCheck: false,
|
|
4025
|
+
"aria-label": "Message",
|
|
4026
|
+
onChange: (event) => setValue(event.target.value),
|
|
4027
|
+
onKeyDown: handleChatKeyDown
|
|
4028
|
+
}
|
|
4029
|
+
),
|
|
4030
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
4031
|
+
"button",
|
|
4032
|
+
{
|
|
4033
|
+
type: "submit",
|
|
4034
|
+
className: "composer__send",
|
|
4035
|
+
disabled: disabled || !value.trim(),
|
|
4036
|
+
"aria-label": "Send message",
|
|
4037
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
|
|
4038
|
+
}
|
|
4039
|
+
)
|
|
4040
|
+
] })
|
|
3972
4041
|
] })
|
|
3973
4042
|
}
|
|
3974
4043
|
);
|
|
@@ -6339,10 +6408,12 @@ function AgentRail({
|
|
|
6339
6408
|
{
|
|
6340
6409
|
variant: expanded || mobileFullscreen ? "dock" : "default",
|
|
6341
6410
|
disabled: isBusy,
|
|
6342
|
-
form: composerForm,
|
|
6411
|
+
form: composerForm && lastMessage ? { ...composerForm, id: `${lastMessage.id}:${composerForm.id}` } : null,
|
|
6412
|
+
allowFormResume: !state.pendingOffer && !waitingForBooking && !hasPendingConfirmation,
|
|
6343
6413
|
placeholder: composerPlaceholder,
|
|
6344
6414
|
onSubmit: handleSubmit
|
|
6345
|
-
}
|
|
6415
|
+
},
|
|
6416
|
+
state.messages.find((message) => message.role === "visitor")?.id ?? "empty"
|
|
6346
6417
|
),
|
|
6347
6418
|
poweredByLabel ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "agent-rail__footer", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: poweredByLabel }) }) }) : null
|
|
6348
6419
|
] })
|