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