@webless/agent 0.2.0 → 0.2.6
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 +22 -106
- package/dist/{chunk-WLQDMWO6.js → chunk-GMG4WJNF.js} +844 -699
- package/dist/chunk-GMG4WJNF.js.map +1 -0
- package/dist/embed.cjs +598 -570
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.css +156 -148
- package/dist/embed.css.map +1 -1
- package/dist/embed.d.cts +7 -11
- package/dist/embed.d.ts +7 -11
- package/dist/embed.js +21 -130
- package/dist/embed.js.map +1 -1
- package/dist/placement-2d9GQGou.d.cts +23 -0
- package/dist/placement-2d9GQGou.d.ts +23 -0
- package/dist/react.cjs +605 -465
- package/dist/react.cjs.map +1 -1
- package/dist/react.css +156 -1
- package/dist/react.css.map +1 -1
- package/dist/react.d.cts +13 -12
- package/dist/react.d.ts +13 -12
- package/dist/react.js +8 -1
- package/dist/react.js.map +1 -1
- package/package.json +2 -2
- package/scripts/ensure-css-imports.mjs +53 -0
- package/dist/chunk-WLQDMWO6.js.map +0 -1
package/dist/react.cjs
CHANGED
|
@@ -21,482 +21,82 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var react_exports = {};
|
|
22
22
|
__export(react_exports, {
|
|
23
23
|
AgentRail: () => AgentRail,
|
|
24
|
+
AgentWidget: () => AgentWidget,
|
|
24
25
|
AssistEdgeTab: () => AssistEdgeTab,
|
|
26
|
+
DEFAULT_AGENT_PLACEMENT: () => DEFAULT_AGENT_PLACEMENT,
|
|
25
27
|
createIdleSuggestions: () => createIdleSuggestions,
|
|
26
28
|
defaultAgentRailTheme: () => defaultAgentRailTheme,
|
|
27
29
|
hasVisitorMessages: () => hasVisitorMessages,
|
|
28
30
|
isAgentBusy: () => isAgentBusy,
|
|
31
|
+
normalizeAgentPlacement: () => normalizeAgentPlacement,
|
|
29
32
|
useAgentChat: () => useAgentChat
|
|
30
33
|
});
|
|
31
34
|
module.exports = __toCommonJS(react_exports);
|
|
32
35
|
|
|
33
|
-
// src/react/components/
|
|
34
|
-
var
|
|
36
|
+
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
37
|
+
var import_react5 = require("react");
|
|
35
38
|
|
|
36
|
-
// src/react/
|
|
37
|
-
var
|
|
38
|
-
function SpinnerIcon() {
|
|
39
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { className: "agent-status__spinner", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
40
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "8", cy: "8", r: "6", stroke: "currentColor", strokeWidth: "1.5", strokeOpacity: "0.25" }),
|
|
41
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 8a6 6 0 0 0-6-6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
42
|
-
] });
|
|
43
|
-
}
|
|
44
|
-
function getCurrentStep(steps) {
|
|
45
|
-
const active = steps.find((step) => step.state === "active");
|
|
46
|
-
if (active) return active;
|
|
47
|
-
const error = steps.find((step) => step.state === "error");
|
|
48
|
-
if (error) return error;
|
|
49
|
-
const pending = steps.find((step) => step.state === "pending");
|
|
50
|
-
if (pending) return pending;
|
|
51
|
-
return steps.at(-1) ?? null;
|
|
52
|
-
}
|
|
53
|
-
function ToolTimeline({
|
|
54
|
-
steps,
|
|
55
|
-
streamingText,
|
|
56
|
-
showStreaming = false,
|
|
57
|
-
inline = false
|
|
58
|
-
}) {
|
|
59
|
-
if (steps.length === 0 && !(showStreaming && streamingText)) return null;
|
|
60
|
-
const currentStep = getCurrentStep(steps);
|
|
61
|
-
const showStatus = currentStep && currentStep.state !== "completed" && !(showStreaming && streamingText);
|
|
62
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
63
|
-
"div",
|
|
64
|
-
{
|
|
65
|
-
className: `tool-timeline${inline ? " tool-timeline--inline" : ""}`,
|
|
66
|
-
role: "status",
|
|
67
|
-
"aria-live": "polite",
|
|
68
|
-
"aria-label": "Agent progress",
|
|
69
|
-
children: [
|
|
70
|
-
showStatus ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-status", children: [
|
|
71
|
-
currentStep.state === "error" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__icon agent-status__icon--error", "aria-hidden": "true", children: "!" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SpinnerIcon, {}) }),
|
|
72
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-status__copy", children: [
|
|
73
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__label", children: currentStep.label }),
|
|
74
|
-
currentStep.detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__detail", children: currentStep.detail }) : null
|
|
75
|
-
] })
|
|
76
|
-
] }, currentStep.id) : null,
|
|
77
|
-
showStreaming && streamingText ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "tool-timeline__streaming-text", children: [
|
|
78
|
-
streamingText,
|
|
79
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tool-timeline__cursor", "aria-hidden": "true" })
|
|
80
|
-
] }) : null
|
|
81
|
-
]
|
|
82
|
-
}
|
|
83
|
-
);
|
|
84
|
-
}
|
|
39
|
+
// src/react/hooks/useAgentChat.ts
|
|
40
|
+
var import_react = require("react");
|
|
85
41
|
|
|
86
|
-
// src/
|
|
87
|
-
var
|
|
88
|
-
function AgentActivityBubble({
|
|
89
|
-
steps,
|
|
90
|
-
streamingText,
|
|
91
|
-
showStreaming = false
|
|
92
|
-
}) {
|
|
93
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("article", { className: "agent-activity-bubble", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "agent-activity-bubble__shell", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
94
|
-
ToolTimeline,
|
|
95
|
-
{
|
|
96
|
-
steps,
|
|
97
|
-
streamingText,
|
|
98
|
-
showStreaming,
|
|
99
|
-
inline: true
|
|
100
|
-
}
|
|
101
|
-
) }) });
|
|
102
|
-
}
|
|
42
|
+
// src/runtime/client.ts
|
|
43
|
+
var import_client = require("eve/client");
|
|
103
44
|
|
|
104
|
-
// src/
|
|
105
|
-
var
|
|
106
|
-
var
|
|
107
|
-
function
|
|
108
|
-
|
|
45
|
+
// src/runtime/config.ts
|
|
46
|
+
var DEFAULT_RUNTIME_ORIGIN = "https://runtime.staging.webless.ai";
|
|
47
|
+
var trimTrailingSlash = (value) => value.replace(/\/+$/, "");
|
|
48
|
+
function buildEveHost(origin, indexId) {
|
|
49
|
+
const base = trimTrailingSlash(origin);
|
|
50
|
+
return `${base}?indexId=${encodeURIComponent(indexId.trim())}`;
|
|
109
51
|
}
|
|
110
|
-
function
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
function submitCurrent() {
|
|
119
|
-
const trimmed = value.trim();
|
|
120
|
-
if (!trimmed || disabled) return;
|
|
121
|
-
onSubmit?.(trimmed);
|
|
122
|
-
setValue("");
|
|
123
|
-
inputRef.current?.focus();
|
|
124
|
-
}
|
|
125
|
-
function handleSubmit(event) {
|
|
126
|
-
event.preventDefault();
|
|
127
|
-
submitCurrent();
|
|
128
|
-
}
|
|
129
|
-
function handleKeyDown(event) {
|
|
130
|
-
if (event.key === "Enter" && !event.shiftKey) {
|
|
131
|
-
event.preventDefault();
|
|
132
|
-
submitCurrent();
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("form", { className: `composer${variant === "dock" ? " composer--dock" : ""}`, onSubmit: handleSubmit, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__field", children: [
|
|
136
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
137
|
-
"textarea",
|
|
138
|
-
{
|
|
139
|
-
ref: inputRef,
|
|
140
|
-
className: "composer__input",
|
|
141
|
-
rows: 1,
|
|
142
|
-
value,
|
|
143
|
-
placeholder,
|
|
144
|
-
disabled,
|
|
145
|
-
"aria-label": "Message",
|
|
146
|
-
onChange: (event) => setValue(event.target.value),
|
|
147
|
-
onKeyDown: handleKeyDown
|
|
148
|
-
}
|
|
149
|
-
),
|
|
150
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
151
|
-
"button",
|
|
152
|
-
{
|
|
153
|
-
type: "submit",
|
|
154
|
-
className: "composer__send",
|
|
155
|
-
disabled: disabled || !value.trim(),
|
|
156
|
-
"aria-label": "Send message",
|
|
157
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
|
|
158
|
-
}
|
|
159
|
-
)
|
|
160
|
-
] }) });
|
|
52
|
+
function resolveAgentRuntimeConfig(input) {
|
|
53
|
+
const origin = trimTrailingSlash(input.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN);
|
|
54
|
+
const resolvedIndexId = input.indexId.trim();
|
|
55
|
+
return {
|
|
56
|
+
origin,
|
|
57
|
+
indexId: resolvedIndexId,
|
|
58
|
+
host: resolvedIndexId ? buildEveHost(origin, resolvedIndexId) : origin
|
|
59
|
+
};
|
|
161
60
|
}
|
|
162
61
|
|
|
163
|
-
// src/
|
|
164
|
-
var
|
|
165
|
-
function
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if (
|
|
174
|
-
|
|
175
|
-
"button",
|
|
176
|
-
{
|
|
177
|
-
type: "button",
|
|
178
|
-
className: "followups__chip followups__chip--dock",
|
|
179
|
-
disabled,
|
|
180
|
-
onClick: () => onSelect?.(suggestion),
|
|
181
|
-
children: suggestion.label
|
|
182
|
-
},
|
|
183
|
-
suggestion.id
|
|
184
|
-
)) }) });
|
|
62
|
+
// src/runtime/session-store.ts
|
|
63
|
+
var DEFAULT_STORAGE_KEY_PREFIX = "webless:agent";
|
|
64
|
+
function normalizeRuntimeOrigin(runtimeOrigin) {
|
|
65
|
+
const trimmed = runtimeOrigin?.trim();
|
|
66
|
+
if (!trimmed) return "_";
|
|
67
|
+
return trimmed.replace(/\/+$/, "");
|
|
68
|
+
}
|
|
69
|
+
function buildAgentStorageKeyPrefix(input) {
|
|
70
|
+
const customerId = input.customerId?.trim() || "_";
|
|
71
|
+
const indexId = input.indexId.trim();
|
|
72
|
+
if (!indexId) {
|
|
73
|
+
throw new Error("indexId is required to build agent storage keys.");
|
|
185
74
|
}
|
|
186
|
-
return
|
|
187
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "followups__label", children: label }),
|
|
188
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
189
|
-
"button",
|
|
190
|
-
{
|
|
191
|
-
type: "button",
|
|
192
|
-
className: "followups__chip",
|
|
193
|
-
disabled,
|
|
194
|
-
onClick: () => onSelect?.(suggestion),
|
|
195
|
-
children: suggestion.label
|
|
196
|
-
},
|
|
197
|
-
suggestion.id
|
|
198
|
-
)) })
|
|
199
|
-
] });
|
|
75
|
+
return `${DEFAULT_STORAGE_KEY_PREFIX}:${customerId}:${indexId}:${normalizeRuntimeOrigin(input.runtimeOrigin)}`;
|
|
200
76
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
function MessageBubble({ message }) {
|
|
205
|
-
if (message.role === "visitor") {
|
|
206
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "message-bubble__text", children: message.text }) });
|
|
77
|
+
function createSessionId() {
|
|
78
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
79
|
+
return crypto.randomUUID();
|
|
207
80
|
}
|
|
208
|
-
return
|
|
209
|
-
message.text,
|
|
210
|
-
message.streaming ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "tool-timeline__cursor", "aria-hidden": "true" }) : null
|
|
211
|
-
] }) });
|
|
81
|
+
return `sess_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
|
|
212
82
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
216
|
-
function MinimizeIcon() {
|
|
217
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3.5 8h9", stroke: "currentColor", strokeWidth: "1.7", strokeLinecap: "round" }) });
|
|
83
|
+
function resolvePrefix(options) {
|
|
84
|
+
return options?.storageKeyPrefix?.trim() || DEFAULT_STORAGE_KEY_PREFIX;
|
|
218
85
|
}
|
|
219
|
-
function
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
86
|
+
function getOrCreateVisitorSessionId(options) {
|
|
87
|
+
const prefix = resolvePrefix(options);
|
|
88
|
+
const visitorKey = `${prefix}:visitorSessionId`;
|
|
89
|
+
if (typeof sessionStorage === "undefined") {
|
|
90
|
+
return createSessionId();
|
|
91
|
+
}
|
|
92
|
+
const existing = sessionStorage.getItem(visitorKey)?.trim();
|
|
93
|
+
if (existing) return existing;
|
|
94
|
+
const next = createSessionId();
|
|
95
|
+
sessionStorage.setItem(visitorKey, next);
|
|
96
|
+
return next;
|
|
230
97
|
}
|
|
231
|
-
function
|
|
232
|
-
return
|
|
233
|
-
"path",
|
|
234
|
-
{
|
|
235
|
-
d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
|
|
236
|
-
stroke: "currentColor",
|
|
237
|
-
strokeWidth: "1.5",
|
|
238
|
-
strokeLinecap: "round",
|
|
239
|
-
strokeLinejoin: "round"
|
|
240
|
-
}
|
|
241
|
-
) });
|
|
242
|
-
}
|
|
243
|
-
function AgentRail({
|
|
244
|
-
state,
|
|
245
|
-
theme,
|
|
246
|
-
brandLabel = "Webless Assist",
|
|
247
|
-
poweredByLabel = "Powered by Webless",
|
|
248
|
-
composerPlaceholder = "Ask anything\u2026",
|
|
249
|
-
mobileFullscreen = false,
|
|
250
|
-
expanded = false,
|
|
251
|
-
onCollapse,
|
|
252
|
-
onClose,
|
|
253
|
-
onExpandToggle,
|
|
254
|
-
onSubmit,
|
|
255
|
-
onFollowUpSelect
|
|
256
|
-
}) {
|
|
257
|
-
const transcriptRef = (0, import_react2.useRef)(null);
|
|
258
|
-
const railStyle = theme?.railMaxWidth ? { ["--rail-width"]: theme.railMaxWidth, ["--as-rail-max-width"]: theme.railMaxWidth } : void 0;
|
|
259
|
-
const isBusy = state.phase === "thinking" || state.phase === "running-tools" || state.phase === "streaming";
|
|
260
|
-
const showActivity = state.toolSteps.length > 0 && (state.phase === "thinking" || state.phase === "running-tools" || state.phase === "streaming");
|
|
261
|
-
const showStreamingInActivity = state.phase === "streaming" && Boolean(state.streamingText);
|
|
262
|
-
const hasVisitorMessages2 = state.messages.some((message) => message.role === "visitor");
|
|
263
|
-
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
264
|
-
const showCompleteFollowUps = state.phase === "complete" && state.followUps.length > 0 && hasVisitorMessages2;
|
|
265
|
-
const showDockFollowUps = expanded && (showIdleFollowUps || showCompleteFollowUps);
|
|
266
|
-
(0, import_react2.useEffect)(() => {
|
|
267
|
-
const node = transcriptRef.current;
|
|
268
|
-
if (!node) return;
|
|
269
|
-
node.scrollTop = node.scrollHeight;
|
|
270
|
-
}, [state.messages, state.toolSteps, state.streamingText, state.followUps, state.journey]);
|
|
271
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
272
|
-
"aside",
|
|
273
|
-
{
|
|
274
|
-
className: `agent-rail${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
|
|
275
|
-
style: railStyle,
|
|
276
|
-
"aria-label": "Agent conversation",
|
|
277
|
-
children: [
|
|
278
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("header", { className: "agent-rail__header", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__brand-row", children: [
|
|
279
|
-
onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
280
|
-
"button",
|
|
281
|
-
{
|
|
282
|
-
type: "button",
|
|
283
|
-
className: "agent-rail__collapse",
|
|
284
|
-
"aria-label": "Collapse assist",
|
|
285
|
-
onClick: onCollapse,
|
|
286
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MinimizeIcon, {})
|
|
287
|
-
}
|
|
288
|
-
) : onClose ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "agent-rail__close", "aria-label": "Close agent", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MinimizeIcon, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
|
|
289
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "agent-rail__brand-label", children: brandLabel }),
|
|
290
|
-
onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
291
|
-
"button",
|
|
292
|
-
{
|
|
293
|
-
type: "button",
|
|
294
|
-
className: "agent-rail__expand",
|
|
295
|
-
"aria-label": expanded ? "Restore assist panel" : "Expand assist panel",
|
|
296
|
-
onClick: onExpandToggle,
|
|
297
|
-
children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ExpandIcon, {})
|
|
298
|
-
}
|
|
299
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" })
|
|
300
|
-
] }) }),
|
|
301
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: [
|
|
302
|
-
state.messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MessageBubble, { message }, message.id)),
|
|
303
|
-
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
304
|
-
AgentActivityBubble,
|
|
305
|
-
{
|
|
306
|
-
steps: state.toolSteps,
|
|
307
|
-
streamingText: state.streamingText,
|
|
308
|
-
showStreaming: showStreamingInActivity
|
|
309
|
-
}
|
|
310
|
-
) : null,
|
|
311
|
-
!expanded && showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
312
|
-
FollowUpChips,
|
|
313
|
-
{
|
|
314
|
-
suggestions: state.followUps,
|
|
315
|
-
disabled: isBusy,
|
|
316
|
-
label: "Try asking",
|
|
317
|
-
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
318
|
-
}
|
|
319
|
-
) }) : null,
|
|
320
|
-
!expanded && showCompleteFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
321
|
-
FollowUpChips,
|
|
322
|
-
{
|
|
323
|
-
suggestions: state.followUps,
|
|
324
|
-
disabled: isBusy,
|
|
325
|
-
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
326
|
-
}
|
|
327
|
-
) }) : null,
|
|
328
|
-
state.error ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "alert", style: { fontSize: 13, color: "var(--as-danger)", margin: 0 }, children: state.error }) : null
|
|
329
|
-
] }),
|
|
330
|
-
expanded ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__dock-wrap", children: [
|
|
331
|
-
showDockFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__dock-followups", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
332
|
-
FollowUpChips,
|
|
333
|
-
{
|
|
334
|
-
variant: "dock",
|
|
335
|
-
suggestions: state.followUps,
|
|
336
|
-
disabled: isBusy,
|
|
337
|
-
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
338
|
-
}
|
|
339
|
-
) }) : null,
|
|
340
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__dock", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
341
|
-
Composer,
|
|
342
|
-
{
|
|
343
|
-
variant: "dock",
|
|
344
|
-
disabled: isBusy,
|
|
345
|
-
placeholder: composerPlaceholder,
|
|
346
|
-
onSubmit
|
|
347
|
-
}
|
|
348
|
-
) }),
|
|
349
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__footer", children: [
|
|
350
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
351
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
352
|
-
] })
|
|
353
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
354
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
355
|
-
Composer,
|
|
356
|
-
{
|
|
357
|
-
disabled: isBusy,
|
|
358
|
-
placeholder: composerPlaceholder,
|
|
359
|
-
onSubmit
|
|
360
|
-
}
|
|
361
|
-
),
|
|
362
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__footer", children: [
|
|
363
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
364
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
365
|
-
] })
|
|
366
|
-
] })
|
|
367
|
-
]
|
|
368
|
-
}
|
|
369
|
-
);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
|
|
373
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
374
|
-
function SparklesIcon() {
|
|
375
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { className: "assist-edge-tab__sparkles", viewBox: "0 0 18 16", fill: "none", "aria-hidden": "true", children: [
|
|
376
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M8 1.2l.95 2.7 2.85.05-2.25 1.75.8 2.75L8 6.7 5.65 8.45l.8-2.75L4.2 3.95l2.85-.05L8 1.2z", fill: "currentColor" }),
|
|
377
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M14.2 6.4l.55 1.55 1.65.03-1.3 1 .46 1.58-1.36-1-1.36 1 .46-1.58-1.3-1 1.65-.03.55-1.55z", fill: "currentColor" }),
|
|
378
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M3.1 9.1l.4 1.15 1.22.02-.96.74.34 1.17-1-.74-1 .74.34-1.17-.96-.74 1.22-.02.4-1.15z", fill: "currentColor" })
|
|
379
|
-
] });
|
|
380
|
-
}
|
|
381
|
-
function ChevronLeftIcon() {
|
|
382
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M10 4L6 8l4 4", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
383
|
-
}
|
|
384
|
-
function ChevronDownIcon() {
|
|
385
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
386
|
-
}
|
|
387
|
-
function DragDots() {
|
|
388
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("i", {}, index)) });
|
|
389
|
-
}
|
|
390
|
-
var VARIANT_COPY = {
|
|
391
|
-
outline: { label: "Assist", aria: "Open Assist" },
|
|
392
|
-
ask: { label: "Ask anything", aria: "Ask anything" },
|
|
393
|
-
fill: { label: "Assist", aria: "Open Assist" }
|
|
394
|
-
};
|
|
395
|
-
function AssistEdgeTab({
|
|
396
|
-
variant,
|
|
397
|
-
side,
|
|
398
|
-
along,
|
|
399
|
-
inset,
|
|
400
|
-
visible,
|
|
401
|
-
onOpen
|
|
402
|
-
}) {
|
|
403
|
-
const copy = VARIANT_COPY[variant];
|
|
404
|
-
const style = {
|
|
405
|
-
"--tab-along": `${along}%`,
|
|
406
|
-
"--tab-inset": `${inset}px`
|
|
407
|
-
};
|
|
408
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
409
|
-
"button",
|
|
410
|
-
{
|
|
411
|
-
type: "button",
|
|
412
|
-
className: `assist-edge-tab assist-edge-tab--${variant} assist-edge-tab--${side}${visible ? " is-visible" : ""}`,
|
|
413
|
-
style,
|
|
414
|
-
"aria-label": copy.aria,
|
|
415
|
-
"aria-hidden": !visible,
|
|
416
|
-
tabIndex: visible ? 0 : -1,
|
|
417
|
-
onClick: onOpen,
|
|
418
|
-
children: [
|
|
419
|
-
variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
420
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparklesIcon, {}),
|
|
421
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__label", children: copy.label }),
|
|
422
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronDownIcon, {})
|
|
423
|
-
] }) : null,
|
|
424
|
-
variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
425
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronLeftIcon, {}),
|
|
426
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__label", children: copy.label }),
|
|
427
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DragDots, {})
|
|
428
|
-
] }) : null,
|
|
429
|
-
variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
430
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparklesIcon, {}),
|
|
431
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__label", children: copy.label }),
|
|
432
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronLeftIcon, {})
|
|
433
|
-
] }) : null
|
|
434
|
-
]
|
|
435
|
-
}
|
|
436
|
-
);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
// src/react/hooks/useAgentChat.ts
|
|
440
|
-
var import_react3 = require("react");
|
|
441
|
-
|
|
442
|
-
// src/runtime/client.ts
|
|
443
|
-
var import_client = require("eve/client");
|
|
444
|
-
|
|
445
|
-
// src/runtime/config.ts
|
|
446
|
-
var DEFAULT_RUNTIME_ORIGIN = "https://runtime.staging.webless.ai";
|
|
447
|
-
var trimTrailingSlash = (value) => value.replace(/\/+$/, "");
|
|
448
|
-
function buildEveHost(origin, indexId) {
|
|
449
|
-
const base = trimTrailingSlash(origin);
|
|
450
|
-
return `${base}?indexId=${encodeURIComponent(indexId.trim())}`;
|
|
451
|
-
}
|
|
452
|
-
function resolveAgentRuntimeConfig(input) {
|
|
453
|
-
const origin = trimTrailingSlash(input.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN);
|
|
454
|
-
const resolvedIndexId = input.indexId.trim();
|
|
455
|
-
return {
|
|
456
|
-
origin,
|
|
457
|
-
indexId: resolvedIndexId,
|
|
458
|
-
host: resolvedIndexId ? buildEveHost(origin, resolvedIndexId) : origin
|
|
459
|
-
};
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// src/runtime/session-store.ts
|
|
463
|
-
var DEFAULT_STORAGE_KEY_PREFIX = "webless:agent";
|
|
464
|
-
function normalizeRuntimeOrigin(runtimeOrigin) {
|
|
465
|
-
const trimmed = runtimeOrigin?.trim();
|
|
466
|
-
if (!trimmed) return "_";
|
|
467
|
-
return trimmed.replace(/\/+$/, "");
|
|
468
|
-
}
|
|
469
|
-
function buildAgentStorageKeyPrefix(input) {
|
|
470
|
-
const customerId = input.customerId?.trim() || "_";
|
|
471
|
-
const indexId = input.indexId.trim();
|
|
472
|
-
if (!indexId) {
|
|
473
|
-
throw new Error("indexId is required to build agent storage keys.");
|
|
474
|
-
}
|
|
475
|
-
return `${DEFAULT_STORAGE_KEY_PREFIX}:${customerId}:${indexId}:${normalizeRuntimeOrigin(input.runtimeOrigin)}`;
|
|
476
|
-
}
|
|
477
|
-
function createSessionId() {
|
|
478
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
479
|
-
return crypto.randomUUID();
|
|
480
|
-
}
|
|
481
|
-
return `sess_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
|
|
482
|
-
}
|
|
483
|
-
function resolvePrefix(options) {
|
|
484
|
-
return options?.storageKeyPrefix?.trim() || DEFAULT_STORAGE_KEY_PREFIX;
|
|
485
|
-
}
|
|
486
|
-
function getOrCreateVisitorSessionId(options) {
|
|
487
|
-
const prefix = resolvePrefix(options);
|
|
488
|
-
const visitorKey = `${prefix}:visitorSessionId`;
|
|
489
|
-
if (typeof sessionStorage === "undefined") {
|
|
490
|
-
return createSessionId();
|
|
491
|
-
}
|
|
492
|
-
const existing = sessionStorage.getItem(visitorKey)?.trim();
|
|
493
|
-
if (existing) return existing;
|
|
494
|
-
const next = createSessionId();
|
|
495
|
-
sessionStorage.setItem(visitorKey, next);
|
|
496
|
-
return next;
|
|
497
|
-
}
|
|
498
|
-
function runtimeSessionIdKey(visitorSessionId, prefix) {
|
|
499
|
-
return `${prefix}:eve:${visitorSessionId}:sessionId`;
|
|
98
|
+
function runtimeSessionIdKey(visitorSessionId, prefix) {
|
|
99
|
+
return `${prefix}:eve:${visitorSessionId}:sessionId`;
|
|
500
100
|
}
|
|
501
101
|
function runtimeStreamIndexKey(visitorSessionId, prefix) {
|
|
502
102
|
return `${prefix}:eve:${visitorSessionId}:streamIndex`;
|
|
@@ -774,17 +374,17 @@ function useAgentChat({
|
|
|
774
374
|
visitorSessionId,
|
|
775
375
|
storageKeyPrefix
|
|
776
376
|
}) {
|
|
777
|
-
const [state, setState] = (0,
|
|
778
|
-
const runRef = (0,
|
|
779
|
-
const resolvedStorageKeyPrefix = (0,
|
|
377
|
+
const [state, setState] = (0, import_react.useState)(INITIAL_STATE);
|
|
378
|
+
const runRef = (0, import_react.useRef)(null);
|
|
379
|
+
const resolvedStorageKeyPrefix = (0, import_react.useMemo)(
|
|
780
380
|
() => storageKeyPrefix?.trim() || buildAgentStorageKeyPrefix({ customerId, indexId, runtimeOrigin }),
|
|
781
381
|
[customerId, indexId, runtimeOrigin, storageKeyPrefix]
|
|
782
382
|
);
|
|
783
|
-
const visitorId = (0,
|
|
383
|
+
const visitorId = (0, import_react.useMemo)(
|
|
784
384
|
() => visitorSessionId?.trim() || getOrCreateVisitorSessionId({ storageKeyPrefix: resolvedStorageKeyPrefix }),
|
|
785
385
|
[resolvedStorageKeyPrefix, visitorSessionId]
|
|
786
386
|
);
|
|
787
|
-
const clientRef = (0,
|
|
387
|
+
const clientRef = (0, import_react.useRef)(
|
|
788
388
|
createAgentClient({
|
|
789
389
|
customerId,
|
|
790
390
|
indexId,
|
|
@@ -793,9 +393,9 @@ function useAgentChat({
|
|
|
793
393
|
storageKeyPrefix: resolvedStorageKeyPrefix
|
|
794
394
|
})
|
|
795
395
|
);
|
|
796
|
-
const identityRef = (0,
|
|
396
|
+
const identityRef = (0, import_react.useRef)(null);
|
|
797
397
|
const identityKey = `${customerId ?? ""}|${indexId}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}`;
|
|
798
|
-
(0,
|
|
398
|
+
(0, import_react.useEffect)(() => {
|
|
799
399
|
if (identityRef.current === null) {
|
|
800
400
|
identityRef.current = identityKey;
|
|
801
401
|
return;
|
|
@@ -816,13 +416,13 @@ function useAgentChat({
|
|
|
816
416
|
});
|
|
817
417
|
setState(INITIAL_STATE);
|
|
818
418
|
}, [customerId, identityKey, indexId, runtimeOrigin, resolvedStorageKeyPrefix, visitorId]);
|
|
819
|
-
const reset = (0,
|
|
419
|
+
const reset = (0, import_react.useCallback)(() => {
|
|
820
420
|
runRef.current?.abort();
|
|
821
421
|
runRef.current = null;
|
|
822
422
|
clientRef.current.reset();
|
|
823
423
|
setState(INITIAL_STATE);
|
|
824
424
|
}, []);
|
|
825
|
-
const submit = (0,
|
|
425
|
+
const submit = (0, import_react.useCallback)(
|
|
826
426
|
async (visitorText) => {
|
|
827
427
|
runRef.current?.abort();
|
|
828
428
|
clientRef.current.cancelActive();
|
|
@@ -920,7 +520,7 @@ function useAgentChat({
|
|
|
920
520
|
},
|
|
921
521
|
[customerId, indexId, runtimeOrigin, resolvedStorageKeyPrefix, visitorId]
|
|
922
522
|
);
|
|
923
|
-
(0,
|
|
523
|
+
(0, import_react.useEffect)(() => {
|
|
924
524
|
return () => {
|
|
925
525
|
runRef.current?.abort();
|
|
926
526
|
clientRef.current.cancelActive();
|
|
@@ -948,6 +548,543 @@ function isAgentBusy(phase) {
|
|
|
948
548
|
return phase === "thinking" || phase === "running-tools" || phase === "streaming";
|
|
949
549
|
}
|
|
950
550
|
|
|
551
|
+
// src/react/hooks/useIsMobile.ts
|
|
552
|
+
var import_react2 = require("react");
|
|
553
|
+
function useIsMobile(breakpoint = 767) {
|
|
554
|
+
const [isMobile, setIsMobile] = (0, import_react2.useState)(
|
|
555
|
+
() => typeof window !== "undefined" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
|
|
556
|
+
);
|
|
557
|
+
(0, import_react2.useEffect)(() => {
|
|
558
|
+
const media = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
559
|
+
const onChange = () => setIsMobile(media.matches);
|
|
560
|
+
onChange();
|
|
561
|
+
media.addEventListener("change", onChange);
|
|
562
|
+
return () => media.removeEventListener("change", onChange);
|
|
563
|
+
}, [breakpoint]);
|
|
564
|
+
return isMobile;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// src/react/placement.ts
|
|
568
|
+
var DEFAULT_AGENT_PLACEMENT = {
|
|
569
|
+
side: "right",
|
|
570
|
+
along: 50,
|
|
571
|
+
inset: 0,
|
|
572
|
+
variant: "outline"
|
|
573
|
+
};
|
|
574
|
+
function normalizeAgentPlacement(placement) {
|
|
575
|
+
const along = placement?.along ?? DEFAULT_AGENT_PLACEMENT.along;
|
|
576
|
+
return {
|
|
577
|
+
side: placement?.side ?? DEFAULT_AGENT_PLACEMENT.side,
|
|
578
|
+
along: Math.min(100, Math.max(0, along)),
|
|
579
|
+
inset: Math.max(0, placement?.inset ?? DEFAULT_AGENT_PLACEMENT.inset),
|
|
580
|
+
variant: placement?.variant ?? DEFAULT_AGENT_PLACEMENT.variant
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// src/react/panel-controller.ts
|
|
585
|
+
var controllers = /* @__PURE__ */ new Map();
|
|
586
|
+
function registerAgentPanelController(customerId, controller) {
|
|
587
|
+
controllers.set(customerId, controller);
|
|
588
|
+
}
|
|
589
|
+
function unregisterAgentPanelController(customerId) {
|
|
590
|
+
controllers.delete(customerId);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// src/react/components/AgentRail/AgentRail.tsx
|
|
594
|
+
var import_react4 = require("react");
|
|
595
|
+
|
|
596
|
+
// src/react/components/ToolTimeline/ToolTimeline.tsx
|
|
597
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
598
|
+
function SpinnerIcon() {
|
|
599
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { className: "agent-status__spinner", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
600
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "8", cy: "8", r: "6", stroke: "currentColor", strokeWidth: "1.5", strokeOpacity: "0.25" }),
|
|
601
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 8a6 6 0 0 0-6-6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
602
|
+
] });
|
|
603
|
+
}
|
|
604
|
+
function getCurrentStep(steps) {
|
|
605
|
+
const active = steps.find((step) => step.state === "active");
|
|
606
|
+
if (active) return active;
|
|
607
|
+
const error = steps.find((step) => step.state === "error");
|
|
608
|
+
if (error) return error;
|
|
609
|
+
const pending = steps.find((step) => step.state === "pending");
|
|
610
|
+
if (pending) return pending;
|
|
611
|
+
return steps.at(-1) ?? null;
|
|
612
|
+
}
|
|
613
|
+
function ToolTimeline({
|
|
614
|
+
steps,
|
|
615
|
+
streamingText,
|
|
616
|
+
showStreaming = false,
|
|
617
|
+
inline = false
|
|
618
|
+
}) {
|
|
619
|
+
if (steps.length === 0 && !(showStreaming && streamingText)) return null;
|
|
620
|
+
const currentStep = getCurrentStep(steps);
|
|
621
|
+
const showStatus = currentStep && currentStep.state !== "completed" && !(showStreaming && streamingText);
|
|
622
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
623
|
+
"div",
|
|
624
|
+
{
|
|
625
|
+
className: `tool-timeline${inline ? " tool-timeline--inline" : ""}`,
|
|
626
|
+
role: "status",
|
|
627
|
+
"aria-live": "polite",
|
|
628
|
+
"aria-label": "Agent progress",
|
|
629
|
+
children: [
|
|
630
|
+
showStatus ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-status", children: [
|
|
631
|
+
currentStep.state === "error" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__icon agent-status__icon--error", "aria-hidden": "true", children: "!" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SpinnerIcon, {}) }),
|
|
632
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-status__copy", children: [
|
|
633
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__label", children: currentStep.label }),
|
|
634
|
+
currentStep.detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__detail", children: currentStep.detail }) : null
|
|
635
|
+
] })
|
|
636
|
+
] }, currentStep.id) : null,
|
|
637
|
+
showStreaming && streamingText ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "tool-timeline__streaming-text", children: [
|
|
638
|
+
streamingText,
|
|
639
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tool-timeline__cursor", "aria-hidden": "true" })
|
|
640
|
+
] }) : null
|
|
641
|
+
]
|
|
642
|
+
}
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
// src/react/components/AgentActivityBubble/AgentActivityBubble.tsx
|
|
647
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
648
|
+
function AgentActivityBubble({
|
|
649
|
+
steps,
|
|
650
|
+
streamingText,
|
|
651
|
+
showStreaming = false
|
|
652
|
+
}) {
|
|
653
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("article", { className: "agent-activity-bubble", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "agent-activity-bubble__shell", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
654
|
+
ToolTimeline,
|
|
655
|
+
{
|
|
656
|
+
steps,
|
|
657
|
+
streamingText,
|
|
658
|
+
showStreaming,
|
|
659
|
+
inline: true
|
|
660
|
+
}
|
|
661
|
+
) }) });
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
// src/react/components/Composer/Composer.tsx
|
|
665
|
+
var import_react3 = require("react");
|
|
666
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
667
|
+
function SendIcon() {
|
|
668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "M8 12V4M8 4l-3 3M8 4l3 3", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
669
|
+
}
|
|
670
|
+
function Composer({
|
|
671
|
+
disabled = false,
|
|
672
|
+
placeholder = "Ask anything\u2026",
|
|
673
|
+
variant = "default",
|
|
674
|
+
onSubmit
|
|
675
|
+
}) {
|
|
676
|
+
const [value, setValue] = (0, import_react3.useState)("");
|
|
677
|
+
const inputRef = (0, import_react3.useRef)(null);
|
|
678
|
+
function submitCurrent() {
|
|
679
|
+
const trimmed = value.trim();
|
|
680
|
+
if (!trimmed || disabled) return;
|
|
681
|
+
onSubmit?.(trimmed);
|
|
682
|
+
setValue("");
|
|
683
|
+
inputRef.current?.focus();
|
|
684
|
+
}
|
|
685
|
+
function handleSubmit(event) {
|
|
686
|
+
event.preventDefault();
|
|
687
|
+
submitCurrent();
|
|
688
|
+
}
|
|
689
|
+
function handleKeyDown(event) {
|
|
690
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
691
|
+
event.preventDefault();
|
|
692
|
+
submitCurrent();
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("form", { className: `composer${variant === "dock" ? " composer--dock" : ""}`, onSubmit: handleSubmit, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "composer__field", children: [
|
|
696
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
697
|
+
"textarea",
|
|
698
|
+
{
|
|
699
|
+
ref: inputRef,
|
|
700
|
+
className: "composer__input",
|
|
701
|
+
rows: 1,
|
|
702
|
+
value,
|
|
703
|
+
placeholder,
|
|
704
|
+
disabled,
|
|
705
|
+
"aria-label": "Message",
|
|
706
|
+
onChange: (event) => setValue(event.target.value),
|
|
707
|
+
onKeyDown: handleKeyDown
|
|
708
|
+
}
|
|
709
|
+
),
|
|
710
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
711
|
+
"button",
|
|
712
|
+
{
|
|
713
|
+
type: "submit",
|
|
714
|
+
className: "composer__send",
|
|
715
|
+
disabled: disabled || !value.trim(),
|
|
716
|
+
"aria-label": "Send message",
|
|
717
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
|
|
718
|
+
}
|
|
719
|
+
)
|
|
720
|
+
] }) });
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
// src/react/components/FollowUpChips/FollowUpChips.tsx
|
|
724
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
725
|
+
function FollowUpChips({
|
|
726
|
+
suggestions,
|
|
727
|
+
disabled = false,
|
|
728
|
+
label = "Follow up",
|
|
729
|
+
variant = "default",
|
|
730
|
+
onSelect
|
|
731
|
+
}) {
|
|
732
|
+
if (suggestions.length === 0) return null;
|
|
733
|
+
if (variant === "dock") {
|
|
734
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups followups--dock", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups__scroll", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
735
|
+
"button",
|
|
736
|
+
{
|
|
737
|
+
type: "button",
|
|
738
|
+
className: "followups__chip followups__chip--dock",
|
|
739
|
+
disabled,
|
|
740
|
+
onClick: () => onSelect?.(suggestion),
|
|
741
|
+
children: suggestion.label
|
|
742
|
+
},
|
|
743
|
+
suggestion.id
|
|
744
|
+
)) }) });
|
|
745
|
+
}
|
|
746
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "followups", children: [
|
|
747
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "followups__label", children: label }),
|
|
748
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
749
|
+
"button",
|
|
750
|
+
{
|
|
751
|
+
type: "button",
|
|
752
|
+
className: "followups__chip",
|
|
753
|
+
disabled,
|
|
754
|
+
onClick: () => onSelect?.(suggestion),
|
|
755
|
+
children: suggestion.label
|
|
756
|
+
},
|
|
757
|
+
suggestion.id
|
|
758
|
+
)) })
|
|
759
|
+
] });
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// src/react/components/MessageBubble/MessageBubble.tsx
|
|
763
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
764
|
+
function MessageBubble({ message }) {
|
|
765
|
+
if (message.role === "visitor") {
|
|
766
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("article", { className: "message-bubble message-bubble--visitor", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "message-bubble__text", children: message.text }) });
|
|
767
|
+
}
|
|
768
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("article", { className: "message-bubble message-bubble--agent", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "message-bubble__text", children: [
|
|
769
|
+
message.text,
|
|
770
|
+
message.streaming ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "tool-timeline__cursor", "aria-hidden": "true" }) : null
|
|
771
|
+
] }) });
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
// src/react/components/AgentRail/AgentRail.tsx
|
|
775
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
776
|
+
function MinimizeIcon() {
|
|
777
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "M3.5 8h9", stroke: "currentColor", strokeWidth: "1.7", strokeLinecap: "round" }) });
|
|
778
|
+
}
|
|
779
|
+
function ExpandIcon() {
|
|
780
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
781
|
+
"path",
|
|
782
|
+
{
|
|
783
|
+
d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
|
|
784
|
+
stroke: "currentColor",
|
|
785
|
+
strokeWidth: "1.5",
|
|
786
|
+
strokeLinecap: "round",
|
|
787
|
+
strokeLinejoin: "round"
|
|
788
|
+
}
|
|
789
|
+
) });
|
|
790
|
+
}
|
|
791
|
+
function RestoreIcon() {
|
|
792
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
793
|
+
"path",
|
|
794
|
+
{
|
|
795
|
+
d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
|
|
796
|
+
stroke: "currentColor",
|
|
797
|
+
strokeWidth: "1.5",
|
|
798
|
+
strokeLinecap: "round",
|
|
799
|
+
strokeLinejoin: "round"
|
|
800
|
+
}
|
|
801
|
+
) });
|
|
802
|
+
}
|
|
803
|
+
function AgentRail({
|
|
804
|
+
state,
|
|
805
|
+
theme,
|
|
806
|
+
brandLabel = "Webless Assist",
|
|
807
|
+
poweredByLabel = "Powered by Webless",
|
|
808
|
+
composerPlaceholder = "Ask anything\u2026",
|
|
809
|
+
mobileFullscreen = false,
|
|
810
|
+
expanded = false,
|
|
811
|
+
onCollapse,
|
|
812
|
+
onClose,
|
|
813
|
+
onExpandToggle,
|
|
814
|
+
onSubmit,
|
|
815
|
+
onFollowUpSelect
|
|
816
|
+
}) {
|
|
817
|
+
const transcriptRef = (0, import_react4.useRef)(null);
|
|
818
|
+
const railStyle = theme?.railMaxWidth ? { ["--rail-width"]: theme.railMaxWidth, ["--as-rail-max-width"]: theme.railMaxWidth } : void 0;
|
|
819
|
+
const isBusy = state.phase === "thinking" || state.phase === "running-tools" || state.phase === "streaming";
|
|
820
|
+
const showActivity = state.toolSteps.length > 0 && (state.phase === "thinking" || state.phase === "running-tools" || state.phase === "streaming");
|
|
821
|
+
const showStreamingInActivity = state.phase === "streaming" && Boolean(state.streamingText);
|
|
822
|
+
const hasVisitorMessages2 = state.messages.some((message) => message.role === "visitor");
|
|
823
|
+
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
824
|
+
const showCompleteFollowUps = state.phase === "complete" && state.followUps.length > 0 && hasVisitorMessages2;
|
|
825
|
+
const showDockFollowUps = expanded && (showIdleFollowUps || showCompleteFollowUps);
|
|
826
|
+
(0, import_react4.useEffect)(() => {
|
|
827
|
+
const node = transcriptRef.current;
|
|
828
|
+
if (!node) return;
|
|
829
|
+
node.scrollTop = node.scrollHeight;
|
|
830
|
+
}, [state.messages, state.toolSteps, state.streamingText, state.followUps, state.journey]);
|
|
831
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
832
|
+
"aside",
|
|
833
|
+
{
|
|
834
|
+
className: `agent-rail${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
|
|
835
|
+
style: railStyle,
|
|
836
|
+
"aria-label": "Agent conversation",
|
|
837
|
+
children: [
|
|
838
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("header", { className: "agent-rail__header", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__brand-row", children: [
|
|
839
|
+
onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
840
|
+
"button",
|
|
841
|
+
{
|
|
842
|
+
type: "button",
|
|
843
|
+
className: "agent-rail__collapse",
|
|
844
|
+
"aria-label": "Collapse assist",
|
|
845
|
+
onClick: onCollapse,
|
|
846
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MinimizeIcon, {})
|
|
847
|
+
}
|
|
848
|
+
) : onClose ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "agent-rail__close", "aria-label": "Close agent", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MinimizeIcon, {}) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" }),
|
|
849
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "agent-rail__brand-label", children: brandLabel }),
|
|
850
|
+
onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
851
|
+
"button",
|
|
852
|
+
{
|
|
853
|
+
type: "button",
|
|
854
|
+
className: "agent-rail__expand",
|
|
855
|
+
"aria-label": expanded ? "Restore assist panel" : "Expand assist panel",
|
|
856
|
+
onClick: onExpandToggle,
|
|
857
|
+
children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ExpandIcon, {})
|
|
858
|
+
}
|
|
859
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" })
|
|
860
|
+
] }) }),
|
|
861
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: [
|
|
862
|
+
state.messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MessageBubble, { message }, message.id)),
|
|
863
|
+
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
864
|
+
AgentActivityBubble,
|
|
865
|
+
{
|
|
866
|
+
steps: state.toolSteps,
|
|
867
|
+
streamingText: state.streamingText,
|
|
868
|
+
showStreaming: showStreamingInActivity
|
|
869
|
+
}
|
|
870
|
+
) : null,
|
|
871
|
+
!expanded && showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
872
|
+
FollowUpChips,
|
|
873
|
+
{
|
|
874
|
+
suggestions: state.followUps,
|
|
875
|
+
disabled: isBusy,
|
|
876
|
+
label: "Try asking",
|
|
877
|
+
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
878
|
+
}
|
|
879
|
+
) }) : null,
|
|
880
|
+
!expanded && showCompleteFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
881
|
+
FollowUpChips,
|
|
882
|
+
{
|
|
883
|
+
suggestions: state.followUps,
|
|
884
|
+
disabled: isBusy,
|
|
885
|
+
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
886
|
+
}
|
|
887
|
+
) }) : null,
|
|
888
|
+
state.error ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "alert", style: { fontSize: 13, color: "var(--as-danger)", margin: 0 }, children: state.error }) : null
|
|
889
|
+
] }),
|
|
890
|
+
expanded ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__dock-wrap", children: [
|
|
891
|
+
showDockFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__dock-followups", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
892
|
+
FollowUpChips,
|
|
893
|
+
{
|
|
894
|
+
variant: "dock",
|
|
895
|
+
suggestions: state.followUps,
|
|
896
|
+
disabled: isBusy,
|
|
897
|
+
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
898
|
+
}
|
|
899
|
+
) }) : null,
|
|
900
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__dock", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
901
|
+
Composer,
|
|
902
|
+
{
|
|
903
|
+
variant: "dock",
|
|
904
|
+
disabled: isBusy,
|
|
905
|
+
placeholder: composerPlaceholder,
|
|
906
|
+
onSubmit
|
|
907
|
+
}
|
|
908
|
+
) }),
|
|
909
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__footer", children: [
|
|
910
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
911
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
912
|
+
] })
|
|
913
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
914
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
915
|
+
Composer,
|
|
916
|
+
{
|
|
917
|
+
disabled: isBusy,
|
|
918
|
+
placeholder: composerPlaceholder,
|
|
919
|
+
onSubmit
|
|
920
|
+
}
|
|
921
|
+
),
|
|
922
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__footer", children: [
|
|
923
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
924
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
925
|
+
] })
|
|
926
|
+
] })
|
|
927
|
+
]
|
|
928
|
+
}
|
|
929
|
+
);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
// src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
|
|
933
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
934
|
+
function SparklesIcon() {
|
|
935
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { className: "assist-edge-tab__sparkles", viewBox: "0 0 18 16", fill: "none", "aria-hidden": "true", children: [
|
|
936
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M8 1.2l.95 2.7 2.85.05-2.25 1.75.8 2.75L8 6.7 5.65 8.45l.8-2.75L4.2 3.95l2.85-.05L8 1.2z", fill: "currentColor" }),
|
|
937
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M14.2 6.4l.55 1.55 1.65.03-1.3 1 .46 1.58-1.36-1-1.36 1 .46-1.58-1.3-1 1.65-.03.55-1.55z", fill: "currentColor" }),
|
|
938
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M3.1 9.1l.4 1.15 1.22.02-.96.74.34 1.17-1-.74-1 .74.34-1.17-.96-.74 1.22-.02.4-1.15z", fill: "currentColor" })
|
|
939
|
+
] });
|
|
940
|
+
}
|
|
941
|
+
function ChevronLeftIcon() {
|
|
942
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M10 4L6 8l4 4", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
943
|
+
}
|
|
944
|
+
function ChevronDownIcon() {
|
|
945
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("svg", { viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M4 6l4 4 4-4", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round" }) });
|
|
946
|
+
}
|
|
947
|
+
function DragDots() {
|
|
948
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__dots", "aria-hidden": "true", children: Array.from({ length: 12 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("i", {}, index)) });
|
|
949
|
+
}
|
|
950
|
+
var VARIANT_COPY = {
|
|
951
|
+
outline: { label: "Assist", aria: "Open Assist" },
|
|
952
|
+
ask: { label: "Ask anything", aria: "Ask anything" },
|
|
953
|
+
fill: { label: "Assist", aria: "Open Assist" }
|
|
954
|
+
};
|
|
955
|
+
function AssistEdgeTab({
|
|
956
|
+
variant,
|
|
957
|
+
side,
|
|
958
|
+
along,
|
|
959
|
+
inset,
|
|
960
|
+
visible,
|
|
961
|
+
onOpen
|
|
962
|
+
}) {
|
|
963
|
+
const copy = VARIANT_COPY[variant];
|
|
964
|
+
const style = {
|
|
965
|
+
"--tab-along": `${along}%`,
|
|
966
|
+
"--tab-inset": `${inset}px`
|
|
967
|
+
};
|
|
968
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
969
|
+
"button",
|
|
970
|
+
{
|
|
971
|
+
type: "button",
|
|
972
|
+
className: `assist-edge-tab assist-edge-tab--${variant} assist-edge-tab--${side}${visible ? " is-visible" : ""}`,
|
|
973
|
+
style,
|
|
974
|
+
"aria-label": copy.aria,
|
|
975
|
+
"aria-hidden": !visible,
|
|
976
|
+
tabIndex: visible ? 0 : -1,
|
|
977
|
+
onClick: onOpen,
|
|
978
|
+
children: [
|
|
979
|
+
variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
980
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparklesIcon, {}),
|
|
981
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__label", children: copy.label }),
|
|
982
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronDownIcon, {})
|
|
983
|
+
] }) : null,
|
|
984
|
+
variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
985
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronLeftIcon, {}),
|
|
986
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__label", children: copy.label }),
|
|
987
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DragDots, {})
|
|
988
|
+
] }) : null,
|
|
989
|
+
variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
990
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparklesIcon, {}),
|
|
991
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__label", children: copy.label }),
|
|
992
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronLeftIcon, {})
|
|
993
|
+
] }) : null
|
|
994
|
+
]
|
|
995
|
+
}
|
|
996
|
+
);
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
1000
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1001
|
+
function AgentWidget({
|
|
1002
|
+
indexId,
|
|
1003
|
+
customerId,
|
|
1004
|
+
runtimeOrigin,
|
|
1005
|
+
placement: placementInput,
|
|
1006
|
+
defaultCollapsed = true,
|
|
1007
|
+
registerPanelController = false
|
|
1008
|
+
}) {
|
|
1009
|
+
const isMobile = useIsMobile();
|
|
1010
|
+
const placement = normalizeAgentPlacement(placementInput);
|
|
1011
|
+
const [railCollapsed, setRailCollapsed] = (0, import_react5.useState)(defaultCollapsed);
|
|
1012
|
+
const [railExpanded, setRailExpanded] = (0, import_react5.useState)(false);
|
|
1013
|
+
const { state, submit } = useAgentChat({
|
|
1014
|
+
customerId,
|
|
1015
|
+
indexId,
|
|
1016
|
+
runtimeOrigin
|
|
1017
|
+
});
|
|
1018
|
+
const idle = state.phase === "idle" && !hasVisitorMessages(state.messages);
|
|
1019
|
+
(0, import_react5.useEffect)(() => {
|
|
1020
|
+
if (!registerPanelController) return;
|
|
1021
|
+
registerAgentPanelController(customerId, {
|
|
1022
|
+
open: () => setRailCollapsed(false),
|
|
1023
|
+
close: () => {
|
|
1024
|
+
setRailCollapsed(true);
|
|
1025
|
+
setRailExpanded(false);
|
|
1026
|
+
}
|
|
1027
|
+
});
|
|
1028
|
+
return () => unregisterAgentPanelController(customerId);
|
|
1029
|
+
}, [customerId, registerPanelController]);
|
|
1030
|
+
async function handleSubmit(message) {
|
|
1031
|
+
if (isMobile) setRailCollapsed(false);
|
|
1032
|
+
await submit(message);
|
|
1033
|
+
}
|
|
1034
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "webless-agent-root", children: [
|
|
1035
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1036
|
+
"div",
|
|
1037
|
+
{
|
|
1038
|
+
className: `webless-agent-root__shell${railCollapsed ? " webless-agent-root__shell--collapsed" : ""}${railExpanded ? " webless-agent-root__shell--expanded" : ""}`,
|
|
1039
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1040
|
+
"div",
|
|
1041
|
+
{
|
|
1042
|
+
className: "webless-agent-root__rail-slot",
|
|
1043
|
+
inert: railCollapsed || void 0,
|
|
1044
|
+
"aria-hidden": railCollapsed,
|
|
1045
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1046
|
+
AgentRail,
|
|
1047
|
+
{
|
|
1048
|
+
state: idle ? {
|
|
1049
|
+
...state,
|
|
1050
|
+
followUps: createIdleSuggestions()
|
|
1051
|
+
} : state,
|
|
1052
|
+
mobileFullscreen: isMobile && !railCollapsed,
|
|
1053
|
+
expanded: railExpanded,
|
|
1054
|
+
onCollapse: !isMobile ? () => setRailCollapsed(true) : void 0,
|
|
1055
|
+
onClose: isMobile ? () => setRailCollapsed(true) : void 0,
|
|
1056
|
+
onExpandToggle: !isMobile ? () => setRailExpanded((current) => !current) : void 0,
|
|
1057
|
+
onSubmit: handleSubmit,
|
|
1058
|
+
onFollowUpSelect: (label) => void handleSubmit(label)
|
|
1059
|
+
}
|
|
1060
|
+
)
|
|
1061
|
+
}
|
|
1062
|
+
)
|
|
1063
|
+
}
|
|
1064
|
+
),
|
|
1065
|
+
!isMobile && railExpanded && !railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1066
|
+
"button",
|
|
1067
|
+
{
|
|
1068
|
+
type: "button",
|
|
1069
|
+
className: "webless-agent-root__backdrop",
|
|
1070
|
+
"aria-label": "Close expanded assist",
|
|
1071
|
+
onClick: () => setRailExpanded(false)
|
|
1072
|
+
}
|
|
1073
|
+
) : null,
|
|
1074
|
+
railCollapsed ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1075
|
+
AssistEdgeTab,
|
|
1076
|
+
{
|
|
1077
|
+
variant: placement.variant,
|
|
1078
|
+
side: placement.side,
|
|
1079
|
+
along: placement.along,
|
|
1080
|
+
inset: placement.inset,
|
|
1081
|
+
visible: true,
|
|
1082
|
+
onOpen: () => setRailCollapsed(false)
|
|
1083
|
+
}
|
|
1084
|
+
) : null
|
|
1085
|
+
] });
|
|
1086
|
+
}
|
|
1087
|
+
|
|
951
1088
|
// src/react/types/conversation.ts
|
|
952
1089
|
var defaultAgentRailTheme = {
|
|
953
1090
|
railMaxWidth: "450px",
|
|
@@ -968,11 +1105,14 @@ var defaultAgentRailTheme = {
|
|
|
968
1105
|
// Annotate the CommonJS export names for ESM import in node:
|
|
969
1106
|
0 && (module.exports = {
|
|
970
1107
|
AgentRail,
|
|
1108
|
+
AgentWidget,
|
|
971
1109
|
AssistEdgeTab,
|
|
1110
|
+
DEFAULT_AGENT_PLACEMENT,
|
|
972
1111
|
createIdleSuggestions,
|
|
973
1112
|
defaultAgentRailTheme,
|
|
974
1113
|
hasVisitorMessages,
|
|
975
1114
|
isAgentBusy,
|
|
1115
|
+
normalizeAgentPlacement,
|
|
976
1116
|
useAgentChat
|
|
977
1117
|
});
|
|
978
1118
|
//# sourceMappingURL=react.cjs.map
|