@webless/agent 0.2.0 → 0.2.7
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-4QGS7UZY.js} +899 -736
- package/dist/chunk-4QGS7UZY.js.map +1 -0
- package/dist/embed.cjs +709 -612
- 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 +23 -13
- package/dist/embed.d.ts +23 -13
- package/dist/embed.js +72 -131
- package/dist/embed.js.map +1 -1
- package/dist/index.cjs +19 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +19 -6
- package/dist/index.js.map +1 -1
- package/dist/placement-CXW_83AF.d.cts +25 -0
- package/dist/placement-CXW_83AF.d.ts +25 -0
- package/dist/react.cjs +876 -718
- 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 +16 -13
- package/dist/react.d.ts +16 -13
- package/dist/react.js +8 -1
- package/dist/react.js.map +1 -1
- package/package.json +5 -5
- package/scripts/build-agent-manifest-bundle-impl.mjs +32 -32
- package/scripts/ensure-css-imports.mjs +53 -0
- package/dist/chunk-WLQDMWO6.js.map +0 -1
package/dist/embed.cjs
CHANGED
|
@@ -22,6 +22,7 @@ var embed_exports = {};
|
|
|
22
22
|
__export(embed_exports, {
|
|
23
23
|
DEFAULT_AGENT_PLACEMENT: () => DEFAULT_AGENT_PLACEMENT,
|
|
24
24
|
bootstrapAgent: () => bootstrapAgent,
|
|
25
|
+
createWeblessAgentPublicApi: () => createWeblessAgentPublicApi,
|
|
25
26
|
getMountedAgent: () => getMountedAgent,
|
|
26
27
|
mountAgent: () => mountAgent,
|
|
27
28
|
normalizeAgentPlacement: () => normalizeAgentPlacement,
|
|
@@ -33,7 +34,7 @@ module.exports = __toCommonJS(embed_exports);
|
|
|
33
34
|
// src/embed/mount.tsx
|
|
34
35
|
var import_client4 = require("react-dom/client");
|
|
35
36
|
|
|
36
|
-
// src/
|
|
37
|
+
// src/react/panel-controller.ts
|
|
37
38
|
var controllers = /* @__PURE__ */ new Map();
|
|
38
39
|
function registerAgentPanelController(customerId, controller) {
|
|
39
40
|
controllers.set(customerId, controller);
|
|
@@ -48,527 +49,130 @@ function closeAgentPanel(customerId) {
|
|
|
48
49
|
controllers.get(customerId)?.close();
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
// src/
|
|
52
|
-
var
|
|
52
|
+
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
53
|
+
var import_react5 = require("react");
|
|
53
54
|
|
|
54
|
-
// src/react/
|
|
55
|
-
var
|
|
55
|
+
// src/react/hooks/useAgentChat.ts
|
|
56
|
+
var import_react = require("react");
|
|
56
57
|
|
|
57
|
-
// src/
|
|
58
|
-
var
|
|
59
|
-
function SpinnerIcon() {
|
|
60
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { className: "agent-status__spinner", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
61
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "8", cy: "8", r: "6", stroke: "currentColor", strokeWidth: "1.5", strokeOpacity: "0.25" }),
|
|
62
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 8a6 6 0 0 0-6-6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
63
|
-
] });
|
|
64
|
-
}
|
|
65
|
-
function getCurrentStep(steps) {
|
|
66
|
-
const active = steps.find((step) => step.state === "active");
|
|
67
|
-
if (active) return active;
|
|
68
|
-
const error = steps.find((step) => step.state === "error");
|
|
69
|
-
if (error) return error;
|
|
70
|
-
const pending = steps.find((step) => step.state === "pending");
|
|
71
|
-
if (pending) return pending;
|
|
72
|
-
return steps.at(-1) ?? null;
|
|
73
|
-
}
|
|
74
|
-
function ToolTimeline({
|
|
75
|
-
steps,
|
|
76
|
-
streamingText,
|
|
77
|
-
showStreaming = false,
|
|
78
|
-
inline = false
|
|
79
|
-
}) {
|
|
80
|
-
if (steps.length === 0 && !(showStreaming && streamingText)) return null;
|
|
81
|
-
const currentStep = getCurrentStep(steps);
|
|
82
|
-
const showStatus = currentStep && currentStep.state !== "completed" && !(showStreaming && streamingText);
|
|
83
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
84
|
-
"div",
|
|
85
|
-
{
|
|
86
|
-
className: `tool-timeline${inline ? " tool-timeline--inline" : ""}`,
|
|
87
|
-
role: "status",
|
|
88
|
-
"aria-live": "polite",
|
|
89
|
-
"aria-label": "Agent progress",
|
|
90
|
-
children: [
|
|
91
|
-
showStatus ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-status", children: [
|
|
92
|
-
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, {}) }),
|
|
93
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-status__copy", children: [
|
|
94
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__label", children: currentStep.label }),
|
|
95
|
-
currentStep.detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__detail", children: currentStep.detail }) : null
|
|
96
|
-
] })
|
|
97
|
-
] }, currentStep.id) : null,
|
|
98
|
-
showStreaming && streamingText ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "tool-timeline__streaming-text", children: [
|
|
99
|
-
streamingText,
|
|
100
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tool-timeline__cursor", "aria-hidden": "true" })
|
|
101
|
-
] }) : null
|
|
102
|
-
]
|
|
103
|
-
}
|
|
104
|
-
);
|
|
105
|
-
}
|
|
58
|
+
// src/runtime/client.ts
|
|
59
|
+
var import_client = require("eve/client");
|
|
106
60
|
|
|
107
|
-
// src/
|
|
108
|
-
var
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
61
|
+
// src/runtime/config.ts
|
|
62
|
+
var DEFAULT_RUNTIME_ORIGIN = "https://runtime.staging.webless.ai";
|
|
63
|
+
var trimTrailingSlash = (value) => value.replace(/\/+$/, "");
|
|
64
|
+
function buildEveHost(origin, indexId, version = "published") {
|
|
65
|
+
const base = trimTrailingSlash(origin);
|
|
66
|
+
const searchParams = new URLSearchParams({ indexId: indexId.trim() });
|
|
67
|
+
if (version === "unpublished") {
|
|
68
|
+
searchParams.set("version", version);
|
|
69
|
+
}
|
|
70
|
+
return `${base}?${searchParams.toString()}`;
|
|
71
|
+
}
|
|
72
|
+
function resolveAgentRuntimeConfig(input) {
|
|
73
|
+
const origin = trimTrailingSlash(input.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN);
|
|
74
|
+
const resolvedIndexId = input.indexId.trim();
|
|
75
|
+
const version = input.version ?? "published";
|
|
76
|
+
return {
|
|
77
|
+
origin,
|
|
78
|
+
indexId: resolvedIndexId,
|
|
79
|
+
version,
|
|
80
|
+
host: resolvedIndexId ? buildEveHost(origin, resolvedIndexId, version) : origin
|
|
81
|
+
};
|
|
123
82
|
}
|
|
124
83
|
|
|
125
|
-
// src/
|
|
126
|
-
var
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
84
|
+
// src/runtime/session-store.ts
|
|
85
|
+
var DEFAULT_STORAGE_KEY_PREFIX = "webless:agent";
|
|
86
|
+
function normalizeRuntimeOrigin(runtimeOrigin) {
|
|
87
|
+
const trimmed = runtimeOrigin?.trim();
|
|
88
|
+
if (!trimmed) return "_";
|
|
89
|
+
return trimmed.replace(/\/+$/, "");
|
|
130
90
|
}
|
|
131
|
-
function
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}) {
|
|
137
|
-
const [value, setValue] = (0, import_react.useState)("");
|
|
138
|
-
const inputRef = (0, import_react.useRef)(null);
|
|
139
|
-
function submitCurrent() {
|
|
140
|
-
const trimmed = value.trim();
|
|
141
|
-
if (!trimmed || disabled) return;
|
|
142
|
-
onSubmit?.(trimmed);
|
|
143
|
-
setValue("");
|
|
144
|
-
inputRef.current?.focus();
|
|
145
|
-
}
|
|
146
|
-
function handleSubmit(event) {
|
|
147
|
-
event.preventDefault();
|
|
148
|
-
submitCurrent();
|
|
149
|
-
}
|
|
150
|
-
function handleKeyDown(event) {
|
|
151
|
-
if (event.key === "Enter" && !event.shiftKey) {
|
|
152
|
-
event.preventDefault();
|
|
153
|
-
submitCurrent();
|
|
154
|
-
}
|
|
91
|
+
function buildAgentStorageKeyPrefix(input) {
|
|
92
|
+
const customerId = input.customerId?.trim() || "_";
|
|
93
|
+
const indexId = input.indexId.trim();
|
|
94
|
+
if (!indexId) {
|
|
95
|
+
throw new Error("indexId is required to build agent storage keys.");
|
|
155
96
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
"textarea",
|
|
159
|
-
{
|
|
160
|
-
ref: inputRef,
|
|
161
|
-
className: "composer__input",
|
|
162
|
-
rows: 1,
|
|
163
|
-
value,
|
|
164
|
-
placeholder,
|
|
165
|
-
disabled,
|
|
166
|
-
"aria-label": "Message",
|
|
167
|
-
onChange: (event) => setValue(event.target.value),
|
|
168
|
-
onKeyDown: handleKeyDown
|
|
169
|
-
}
|
|
170
|
-
),
|
|
171
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
172
|
-
"button",
|
|
173
|
-
{
|
|
174
|
-
type: "submit",
|
|
175
|
-
className: "composer__send",
|
|
176
|
-
disabled: disabled || !value.trim(),
|
|
177
|
-
"aria-label": "Send message",
|
|
178
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
|
|
179
|
-
}
|
|
180
|
-
)
|
|
181
|
-
] }) });
|
|
97
|
+
const versionSuffix = input.version === "unpublished" ? ":unpublished" : "";
|
|
98
|
+
return `${DEFAULT_STORAGE_KEY_PREFIX}:${customerId}:${indexId}${versionSuffix}:${normalizeRuntimeOrigin(input.runtimeOrigin)}`;
|
|
182
99
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
function FollowUpChips({
|
|
187
|
-
suggestions,
|
|
188
|
-
disabled = false,
|
|
189
|
-
label = "Follow up",
|
|
190
|
-
variant = "default",
|
|
191
|
-
onSelect
|
|
192
|
-
}) {
|
|
193
|
-
if (suggestions.length === 0) return null;
|
|
194
|
-
if (variant === "dock") {
|
|
195
|
-
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)(
|
|
196
|
-
"button",
|
|
197
|
-
{
|
|
198
|
-
type: "button",
|
|
199
|
-
className: "followups__chip followups__chip--dock",
|
|
200
|
-
disabled,
|
|
201
|
-
onClick: () => onSelect?.(suggestion),
|
|
202
|
-
children: suggestion.label
|
|
203
|
-
},
|
|
204
|
-
suggestion.id
|
|
205
|
-
)) }) });
|
|
100
|
+
function createSessionId() {
|
|
101
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
102
|
+
return crypto.randomUUID();
|
|
206
103
|
}
|
|
207
|
-
return
|
|
208
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "followups__label", children: label }),
|
|
209
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
210
|
-
"button",
|
|
211
|
-
{
|
|
212
|
-
type: "button",
|
|
213
|
-
className: "followups__chip",
|
|
214
|
-
disabled,
|
|
215
|
-
onClick: () => onSelect?.(suggestion),
|
|
216
|
-
children: suggestion.label
|
|
217
|
-
},
|
|
218
|
-
suggestion.id
|
|
219
|
-
)) })
|
|
220
|
-
] });
|
|
104
|
+
return `sess_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
|
|
221
105
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
function
|
|
226
|
-
|
|
227
|
-
|
|
106
|
+
function resolvePrefix(options) {
|
|
107
|
+
return options?.storageKeyPrefix?.trim() || DEFAULT_STORAGE_KEY_PREFIX;
|
|
108
|
+
}
|
|
109
|
+
function getOrCreateVisitorSessionId(options) {
|
|
110
|
+
const prefix = resolvePrefix(options);
|
|
111
|
+
const visitorKey = `${prefix}:visitorSessionId`;
|
|
112
|
+
if (typeof sessionStorage === "undefined") {
|
|
113
|
+
return createSessionId();
|
|
228
114
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
115
|
+
const existing = sessionStorage.getItem(visitorKey)?.trim();
|
|
116
|
+
if (existing) return existing;
|
|
117
|
+
const next = createSessionId();
|
|
118
|
+
sessionStorage.setItem(visitorKey, next);
|
|
119
|
+
return next;
|
|
233
120
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
237
|
-
function MinimizeIcon() {
|
|
238
|
-
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" }) });
|
|
121
|
+
function runtimeSessionIdKey(visitorSessionId, prefix) {
|
|
122
|
+
return `${prefix}:eve:${visitorSessionId}:sessionId`;
|
|
239
123
|
}
|
|
240
|
-
function
|
|
241
|
-
return
|
|
242
|
-
"path",
|
|
243
|
-
{
|
|
244
|
-
d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
|
|
245
|
-
stroke: "currentColor",
|
|
246
|
-
strokeWidth: "1.5",
|
|
247
|
-
strokeLinecap: "round",
|
|
248
|
-
strokeLinejoin: "round"
|
|
249
|
-
}
|
|
250
|
-
) });
|
|
124
|
+
function runtimeStreamIndexKey(visitorSessionId, prefix) {
|
|
125
|
+
return `${prefix}:eve:${visitorSessionId}:streamIndex`;
|
|
251
126
|
}
|
|
252
|
-
function
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
127
|
+
function loadPersistedAgentSession(visitorSessionId, options) {
|
|
128
|
+
if (typeof sessionStorage === "undefined" || !visitorSessionId.trim()) return null;
|
|
129
|
+
const prefix = resolvePrefix(options);
|
|
130
|
+
const sessionId = sessionStorage.getItem(runtimeSessionIdKey(visitorSessionId, prefix))?.trim();
|
|
131
|
+
if (!sessionId) return null;
|
|
132
|
+
const rawIndex = sessionStorage.getItem(runtimeStreamIndexKey(visitorSessionId, prefix));
|
|
133
|
+
const streamIndex = rawIndex ? Number.parseInt(rawIndex, 10) : 0;
|
|
134
|
+
return {
|
|
135
|
+
sessionId,
|
|
136
|
+
streamIndex: Number.isFinite(streamIndex) && streamIndex >= 0 ? streamIndex : 0
|
|
137
|
+
};
|
|
263
138
|
}
|
|
264
|
-
function
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
onClose,
|
|
274
|
-
onExpandToggle,
|
|
275
|
-
onSubmit,
|
|
276
|
-
onFollowUpSelect
|
|
277
|
-
}) {
|
|
278
|
-
const transcriptRef = (0, import_react2.useRef)(null);
|
|
279
|
-
const railStyle = theme?.railMaxWidth ? { ["--rail-width"]: theme.railMaxWidth, ["--as-rail-max-width"]: theme.railMaxWidth } : void 0;
|
|
280
|
-
const isBusy = state.phase === "thinking" || state.phase === "running-tools" || state.phase === "streaming";
|
|
281
|
-
const showActivity = state.toolSteps.length > 0 && (state.phase === "thinking" || state.phase === "running-tools" || state.phase === "streaming");
|
|
282
|
-
const showStreamingInActivity = state.phase === "streaming" && Boolean(state.streamingText);
|
|
283
|
-
const hasVisitorMessages2 = state.messages.some((message) => message.role === "visitor");
|
|
284
|
-
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
285
|
-
const showCompleteFollowUps = state.phase === "complete" && state.followUps.length > 0 && hasVisitorMessages2;
|
|
286
|
-
const showDockFollowUps = expanded && (showIdleFollowUps || showCompleteFollowUps);
|
|
287
|
-
(0, import_react2.useEffect)(() => {
|
|
288
|
-
const node = transcriptRef.current;
|
|
289
|
-
if (!node) return;
|
|
290
|
-
node.scrollTop = node.scrollHeight;
|
|
291
|
-
}, [state.messages, state.toolSteps, state.streamingText, state.followUps, state.journey]);
|
|
292
|
-
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
293
|
-
"aside",
|
|
294
|
-
{
|
|
295
|
-
className: `agent-rail${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
|
|
296
|
-
style: railStyle,
|
|
297
|
-
"aria-label": "Agent conversation",
|
|
298
|
-
children: [
|
|
299
|
-
/* @__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: [
|
|
300
|
-
onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
301
|
-
"button",
|
|
302
|
-
{
|
|
303
|
-
type: "button",
|
|
304
|
-
className: "agent-rail__collapse",
|
|
305
|
-
"aria-label": "Collapse assist",
|
|
306
|
-
onClick: onCollapse,
|
|
307
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MinimizeIcon, {})
|
|
308
|
-
}
|
|
309
|
-
) : 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" }),
|
|
310
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "agent-rail__brand-label", children: brandLabel }),
|
|
311
|
-
onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
312
|
-
"button",
|
|
313
|
-
{
|
|
314
|
-
type: "button",
|
|
315
|
-
className: "agent-rail__expand",
|
|
316
|
-
"aria-label": expanded ? "Restore assist panel" : "Expand assist panel",
|
|
317
|
-
onClick: onExpandToggle,
|
|
318
|
-
children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ExpandIcon, {})
|
|
319
|
-
}
|
|
320
|
-
) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" })
|
|
321
|
-
] }) }),
|
|
322
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: [
|
|
323
|
-
state.messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MessageBubble, { message }, message.id)),
|
|
324
|
-
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
325
|
-
AgentActivityBubble,
|
|
326
|
-
{
|
|
327
|
-
steps: state.toolSteps,
|
|
328
|
-
streamingText: state.streamingText,
|
|
329
|
-
showStreaming: showStreamingInActivity
|
|
330
|
-
}
|
|
331
|
-
) : null,
|
|
332
|
-
!expanded && showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
333
|
-
FollowUpChips,
|
|
334
|
-
{
|
|
335
|
-
suggestions: state.followUps,
|
|
336
|
-
disabled: isBusy,
|
|
337
|
-
label: "Try asking",
|
|
338
|
-
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
339
|
-
}
|
|
340
|
-
) }) : null,
|
|
341
|
-
!expanded && showCompleteFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
342
|
-
FollowUpChips,
|
|
343
|
-
{
|
|
344
|
-
suggestions: state.followUps,
|
|
345
|
-
disabled: isBusy,
|
|
346
|
-
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
347
|
-
}
|
|
348
|
-
) }) : null,
|
|
349
|
-
state.error ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "alert", style: { fontSize: 13, color: "var(--as-danger)", margin: 0 }, children: state.error }) : null
|
|
350
|
-
] }),
|
|
351
|
-
expanded ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__dock-wrap", children: [
|
|
352
|
-
showDockFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__dock-followups", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
353
|
-
FollowUpChips,
|
|
354
|
-
{
|
|
355
|
-
variant: "dock",
|
|
356
|
-
suggestions: state.followUps,
|
|
357
|
-
disabled: isBusy,
|
|
358
|
-
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
359
|
-
}
|
|
360
|
-
) }) : null,
|
|
361
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__dock", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
362
|
-
Composer,
|
|
363
|
-
{
|
|
364
|
-
variant: "dock",
|
|
365
|
-
disabled: isBusy,
|
|
366
|
-
placeholder: composerPlaceholder,
|
|
367
|
-
onSubmit
|
|
368
|
-
}
|
|
369
|
-
) }),
|
|
370
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__footer", children: [
|
|
371
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
372
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
373
|
-
] })
|
|
374
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
375
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
376
|
-
Composer,
|
|
377
|
-
{
|
|
378
|
-
disabled: isBusy,
|
|
379
|
-
placeholder: composerPlaceholder,
|
|
380
|
-
onSubmit
|
|
381
|
-
}
|
|
382
|
-
),
|
|
383
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__footer", children: [
|
|
384
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
385
|
-
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
386
|
-
] })
|
|
387
|
-
] })
|
|
388
|
-
]
|
|
389
|
-
}
|
|
139
|
+
function savePersistedAgentSession(visitorSessionId, sessionId, streamIndex, options) {
|
|
140
|
+
if (typeof sessionStorage === "undefined" || !visitorSessionId.trim() || !sessionId.trim()) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const prefix = resolvePrefix(options);
|
|
144
|
+
sessionStorage.setItem(runtimeSessionIdKey(visitorSessionId, prefix), sessionId);
|
|
145
|
+
sessionStorage.setItem(
|
|
146
|
+
runtimeStreamIndexKey(visitorSessionId, prefix),
|
|
147
|
+
String(Math.max(0, streamIndex))
|
|
390
148
|
);
|
|
391
149
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
/* @__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" }),
|
|
398
|
-
/* @__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" }),
|
|
399
|
-
/* @__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" })
|
|
400
|
-
] });
|
|
401
|
-
}
|
|
402
|
-
function ChevronLeftIcon() {
|
|
403
|
-
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" }) });
|
|
404
|
-
}
|
|
405
|
-
function ChevronDownIcon() {
|
|
406
|
-
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" }) });
|
|
407
|
-
}
|
|
408
|
-
function DragDots() {
|
|
409
|
-
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)) });
|
|
410
|
-
}
|
|
411
|
-
var VARIANT_COPY = {
|
|
412
|
-
outline: { label: "Assist", aria: "Open Assist" },
|
|
413
|
-
ask: { label: "Ask anything", aria: "Ask anything" },
|
|
414
|
-
fill: { label: "Assist", aria: "Open Assist" }
|
|
415
|
-
};
|
|
416
|
-
function AssistEdgeTab({
|
|
417
|
-
variant,
|
|
418
|
-
side,
|
|
419
|
-
along,
|
|
420
|
-
inset,
|
|
421
|
-
visible,
|
|
422
|
-
onOpen
|
|
423
|
-
}) {
|
|
424
|
-
const copy = VARIANT_COPY[variant];
|
|
425
|
-
const style = {
|
|
426
|
-
"--tab-along": `${along}%`,
|
|
427
|
-
"--tab-inset": `${inset}px`
|
|
428
|
-
};
|
|
429
|
-
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
430
|
-
"button",
|
|
431
|
-
{
|
|
432
|
-
type: "button",
|
|
433
|
-
className: `assist-edge-tab assist-edge-tab--${variant} assist-edge-tab--${side}${visible ? " is-visible" : ""}`,
|
|
434
|
-
style,
|
|
435
|
-
"aria-label": copy.aria,
|
|
436
|
-
"aria-hidden": !visible,
|
|
437
|
-
tabIndex: visible ? 0 : -1,
|
|
438
|
-
onClick: onOpen,
|
|
439
|
-
children: [
|
|
440
|
-
variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
441
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparklesIcon, {}),
|
|
442
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__label", children: copy.label }),
|
|
443
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronDownIcon, {})
|
|
444
|
-
] }) : null,
|
|
445
|
-
variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
446
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronLeftIcon, {}),
|
|
447
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__label", children: copy.label }),
|
|
448
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DragDots, {})
|
|
449
|
-
] }) : null,
|
|
450
|
-
variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
451
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparklesIcon, {}),
|
|
452
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__label", children: copy.label }),
|
|
453
|
-
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronLeftIcon, {})
|
|
454
|
-
] }) : null
|
|
455
|
-
]
|
|
456
|
-
}
|
|
457
|
-
);
|
|
150
|
+
function clearPersistedAgentSession(visitorSessionId, options) {
|
|
151
|
+
if (typeof sessionStorage === "undefined" || !visitorSessionId.trim()) return;
|
|
152
|
+
const prefix = resolvePrefix(options);
|
|
153
|
+
sessionStorage.removeItem(runtimeSessionIdKey(visitorSessionId, prefix));
|
|
154
|
+
sessionStorage.removeItem(runtimeStreamIndexKey(visitorSessionId, prefix));
|
|
458
155
|
}
|
|
459
156
|
|
|
460
|
-
// src/react/hooks/useAgentChat.ts
|
|
461
|
-
var import_react3 = require("react");
|
|
462
|
-
|
|
463
157
|
// src/runtime/client.ts
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
var DEFAULT_RUNTIME_ORIGIN = "https://runtime.staging.webless.ai";
|
|
468
|
-
var trimTrailingSlash = (value) => value.replace(/\/+$/, "");
|
|
469
|
-
function buildEveHost(origin, indexId) {
|
|
470
|
-
const base = trimTrailingSlash(origin);
|
|
471
|
-
return `${base}?indexId=${encodeURIComponent(indexId.trim())}`;
|
|
472
|
-
}
|
|
473
|
-
function resolveAgentRuntimeConfig(input) {
|
|
474
|
-
const origin = trimTrailingSlash(input.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN);
|
|
475
|
-
const resolvedIndexId = input.indexId.trim();
|
|
158
|
+
function mapStepLabel(event) {
|
|
159
|
+
if (event.type !== "step.started") return null;
|
|
160
|
+
const stepIndex = event.data.stepIndex;
|
|
476
161
|
return {
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
host: resolvedIndexId ? buildEveHost(origin, resolvedIndexId) : origin
|
|
162
|
+
label: "Model step running",
|
|
163
|
+
detail: typeof stepIndex === "number" ? `Step ${stepIndex + 1}` : void 0
|
|
480
164
|
};
|
|
481
165
|
}
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
}
|
|
490
|
-
function buildAgentStorageKeyPrefix(input) {
|
|
491
|
-
const customerId = input.customerId?.trim() || "_";
|
|
492
|
-
const indexId = input.indexId.trim();
|
|
493
|
-
if (!indexId) {
|
|
494
|
-
throw new Error("indexId is required to build agent storage keys.");
|
|
495
|
-
}
|
|
496
|
-
return `${DEFAULT_STORAGE_KEY_PREFIX}:${customerId}:${indexId}:${normalizeRuntimeOrigin(input.runtimeOrigin)}`;
|
|
497
|
-
}
|
|
498
|
-
function createSessionId() {
|
|
499
|
-
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
500
|
-
return crypto.randomUUID();
|
|
501
|
-
}
|
|
502
|
-
return `sess_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
|
|
503
|
-
}
|
|
504
|
-
function resolvePrefix(options) {
|
|
505
|
-
return options?.storageKeyPrefix?.trim() || DEFAULT_STORAGE_KEY_PREFIX;
|
|
506
|
-
}
|
|
507
|
-
function getOrCreateVisitorSessionId(options) {
|
|
508
|
-
const prefix = resolvePrefix(options);
|
|
509
|
-
const visitorKey = `${prefix}:visitorSessionId`;
|
|
510
|
-
if (typeof sessionStorage === "undefined") {
|
|
511
|
-
return createSessionId();
|
|
512
|
-
}
|
|
513
|
-
const existing = sessionStorage.getItem(visitorKey)?.trim();
|
|
514
|
-
if (existing) return existing;
|
|
515
|
-
const next = createSessionId();
|
|
516
|
-
sessionStorage.setItem(visitorKey, next);
|
|
517
|
-
return next;
|
|
518
|
-
}
|
|
519
|
-
function runtimeSessionIdKey(visitorSessionId, prefix) {
|
|
520
|
-
return `${prefix}:eve:${visitorSessionId}:sessionId`;
|
|
521
|
-
}
|
|
522
|
-
function runtimeStreamIndexKey(visitorSessionId, prefix) {
|
|
523
|
-
return `${prefix}:eve:${visitorSessionId}:streamIndex`;
|
|
524
|
-
}
|
|
525
|
-
function loadPersistedAgentSession(visitorSessionId, options) {
|
|
526
|
-
if (typeof sessionStorage === "undefined" || !visitorSessionId.trim()) return null;
|
|
527
|
-
const prefix = resolvePrefix(options);
|
|
528
|
-
const sessionId = sessionStorage.getItem(runtimeSessionIdKey(visitorSessionId, prefix))?.trim();
|
|
529
|
-
if (!sessionId) return null;
|
|
530
|
-
const rawIndex = sessionStorage.getItem(runtimeStreamIndexKey(visitorSessionId, prefix));
|
|
531
|
-
const streamIndex = rawIndex ? Number.parseInt(rawIndex, 10) : 0;
|
|
532
|
-
return {
|
|
533
|
-
sessionId,
|
|
534
|
-
streamIndex: Number.isFinite(streamIndex) && streamIndex >= 0 ? streamIndex : 0
|
|
535
|
-
};
|
|
536
|
-
}
|
|
537
|
-
function savePersistedAgentSession(visitorSessionId, sessionId, streamIndex, options) {
|
|
538
|
-
if (typeof sessionStorage === "undefined" || !visitorSessionId.trim() || !sessionId.trim()) {
|
|
539
|
-
return;
|
|
540
|
-
}
|
|
541
|
-
const prefix = resolvePrefix(options);
|
|
542
|
-
sessionStorage.setItem(runtimeSessionIdKey(visitorSessionId, prefix), sessionId);
|
|
543
|
-
sessionStorage.setItem(
|
|
544
|
-
runtimeStreamIndexKey(visitorSessionId, prefix),
|
|
545
|
-
String(Math.max(0, streamIndex))
|
|
546
|
-
);
|
|
547
|
-
}
|
|
548
|
-
function clearPersistedAgentSession(visitorSessionId, options) {
|
|
549
|
-
if (typeof sessionStorage === "undefined" || !visitorSessionId.trim()) return;
|
|
550
|
-
const prefix = resolvePrefix(options);
|
|
551
|
-
sessionStorage.removeItem(runtimeSessionIdKey(visitorSessionId, prefix));
|
|
552
|
-
sessionStorage.removeItem(runtimeStreamIndexKey(visitorSessionId, prefix));
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
// src/runtime/client.ts
|
|
556
|
-
function mapStepLabel(event) {
|
|
557
|
-
if (event.type !== "step.started") return null;
|
|
558
|
-
const stepIndex = event.data.stepIndex;
|
|
559
|
-
return {
|
|
560
|
-
label: "Model step running",
|
|
561
|
-
detail: typeof stepIndex === "number" ? `Step ${stepIndex + 1}` : void 0
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
var AgentSession = class {
|
|
565
|
-
constructor(indexId, runtimeOrigin, visitorSessionId, storeOptions) {
|
|
566
|
-
this.indexId = indexId;
|
|
567
|
-
this.runtimeOrigin = runtimeOrigin;
|
|
568
|
-
this.visitorSessionId = visitorSessionId;
|
|
569
|
-
this.storeOptions = storeOptions;
|
|
166
|
+
var AgentSession = class {
|
|
167
|
+
constructor(indexId, version, runtimeOrigin, visitorSessionId, storeOptions) {
|
|
168
|
+
this.indexId = indexId;
|
|
169
|
+
this.version = version;
|
|
170
|
+
this.runtimeOrigin = runtimeOrigin;
|
|
171
|
+
this.visitorSessionId = visitorSessionId;
|
|
172
|
+
this.storeOptions = storeOptions;
|
|
570
173
|
}
|
|
571
174
|
indexId;
|
|
175
|
+
version;
|
|
572
176
|
runtimeOrigin;
|
|
573
177
|
visitorSessionId;
|
|
574
178
|
storeOptions;
|
|
@@ -599,6 +203,7 @@ var AgentSession = class {
|
|
|
599
203
|
ensureClient() {
|
|
600
204
|
const config = resolveAgentRuntimeConfig({
|
|
601
205
|
indexId: this.indexId,
|
|
206
|
+
version: this.version,
|
|
602
207
|
runtimeOrigin: this.runtimeOrigin
|
|
603
208
|
});
|
|
604
209
|
if (!config.indexId) {
|
|
@@ -698,17 +303,20 @@ function createAgentClient(options) {
|
|
|
698
303
|
throw new Error("indexId is required.");
|
|
699
304
|
}
|
|
700
305
|
const runtimeOrigin = options.runtimeOrigin?.trim() || resolveAgentRuntimeConfig({ indexId }).origin;
|
|
306
|
+
const version = options.version ?? "published";
|
|
701
307
|
const storeOptions = {
|
|
702
308
|
storageKeyPrefix: options.storageKeyPrefix?.trim() || buildAgentStorageKeyPrefix({
|
|
703
309
|
customerId: options.customerId,
|
|
704
310
|
indexId,
|
|
311
|
+
version,
|
|
705
312
|
runtimeOrigin
|
|
706
313
|
})
|
|
707
314
|
};
|
|
708
315
|
const visitorSessionId = options.visitorSessionId?.trim() || getOrCreateVisitorSessionId(storeOptions);
|
|
709
|
-
const session = new AgentSession(indexId, runtimeOrigin, visitorSessionId, storeOptions);
|
|
316
|
+
const session = new AgentSession(indexId, version, runtimeOrigin, visitorSessionId, storeOptions);
|
|
710
317
|
return {
|
|
711
318
|
indexId,
|
|
319
|
+
version,
|
|
712
320
|
runtimeOrigin,
|
|
713
321
|
visitorSessionId,
|
|
714
322
|
sendTurn: (message, sendOptions) => session.sendTurn(
|
|
@@ -791,32 +399,34 @@ async function runStatusSequence(signal, onStep) {
|
|
|
791
399
|
function useAgentChat({
|
|
792
400
|
customerId,
|
|
793
401
|
indexId,
|
|
402
|
+
version,
|
|
794
403
|
runtimeOrigin,
|
|
795
404
|
visitorSessionId,
|
|
796
405
|
storageKeyPrefix
|
|
797
406
|
}) {
|
|
798
|
-
const [state, setState] = (0,
|
|
799
|
-
const runRef = (0,
|
|
800
|
-
const resolvedStorageKeyPrefix = (0,
|
|
801
|
-
() => storageKeyPrefix?.trim() || buildAgentStorageKeyPrefix({ customerId, indexId, runtimeOrigin }),
|
|
802
|
-
[customerId, indexId, runtimeOrigin, storageKeyPrefix]
|
|
407
|
+
const [state, setState] = (0, import_react.useState)(INITIAL_STATE);
|
|
408
|
+
const runRef = (0, import_react.useRef)(null);
|
|
409
|
+
const resolvedStorageKeyPrefix = (0, import_react.useMemo)(
|
|
410
|
+
() => storageKeyPrefix?.trim() || buildAgentStorageKeyPrefix({ customerId, indexId, version, runtimeOrigin }),
|
|
411
|
+
[customerId, indexId, runtimeOrigin, storageKeyPrefix, version]
|
|
803
412
|
);
|
|
804
|
-
const visitorId = (0,
|
|
413
|
+
const visitorId = (0, import_react.useMemo)(
|
|
805
414
|
() => visitorSessionId?.trim() || getOrCreateVisitorSessionId({ storageKeyPrefix: resolvedStorageKeyPrefix }),
|
|
806
415
|
[resolvedStorageKeyPrefix, visitorSessionId]
|
|
807
416
|
);
|
|
808
|
-
const clientRef = (0,
|
|
417
|
+
const clientRef = (0, import_react.useRef)(
|
|
809
418
|
createAgentClient({
|
|
810
419
|
customerId,
|
|
811
420
|
indexId,
|
|
421
|
+
version,
|
|
812
422
|
runtimeOrigin,
|
|
813
423
|
visitorSessionId: visitorId,
|
|
814
424
|
storageKeyPrefix: resolvedStorageKeyPrefix
|
|
815
425
|
})
|
|
816
426
|
);
|
|
817
|
-
const identityRef = (0,
|
|
818
|
-
const identityKey = `${customerId ?? ""}|${indexId}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}`;
|
|
819
|
-
(0,
|
|
427
|
+
const identityRef = (0, import_react.useRef)(null);
|
|
428
|
+
const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}`;
|
|
429
|
+
(0, import_react.useEffect)(() => {
|
|
820
430
|
if (identityRef.current === null) {
|
|
821
431
|
identityRef.current = identityKey;
|
|
822
432
|
return;
|
|
@@ -831,19 +441,20 @@ function useAgentChat({
|
|
|
831
441
|
clientRef.current = createAgentClient({
|
|
832
442
|
customerId,
|
|
833
443
|
indexId,
|
|
444
|
+
version,
|
|
834
445
|
runtimeOrigin,
|
|
835
446
|
visitorSessionId: visitorId,
|
|
836
447
|
storageKeyPrefix: resolvedStorageKeyPrefix
|
|
837
448
|
});
|
|
838
449
|
setState(INITIAL_STATE);
|
|
839
|
-
}, [customerId, identityKey, indexId, runtimeOrigin, resolvedStorageKeyPrefix, visitorId]);
|
|
840
|
-
const reset = (0,
|
|
450
|
+
}, [customerId, identityKey, indexId, runtimeOrigin, resolvedStorageKeyPrefix, version, visitorId]);
|
|
451
|
+
const reset = (0, import_react.useCallback)(() => {
|
|
841
452
|
runRef.current?.abort();
|
|
842
453
|
runRef.current = null;
|
|
843
454
|
clientRef.current.reset();
|
|
844
455
|
setState(INITIAL_STATE);
|
|
845
456
|
}, []);
|
|
846
|
-
const submit = (0,
|
|
457
|
+
const submit = (0, import_react.useCallback)(
|
|
847
458
|
async (visitorText) => {
|
|
848
459
|
runRef.current?.abort();
|
|
849
460
|
clientRef.current.cancelActive();
|
|
@@ -905,108 +516,544 @@ function useAgentChat({
|
|
|
905
516
|
if (!isActiveRun()) return;
|
|
906
517
|
streamStarted = true;
|
|
907
518
|
}
|
|
908
|
-
}
|
|
909
|
-
});
|
|
910
|
-
await planningPromise.catch(() => {
|
|
911
|
-
});
|
|
912
|
-
if (!isActiveRun()) return;
|
|
913
|
-
const agentMessage = {
|
|
914
|
-
id: `agent-${Date.now()}`,
|
|
915
|
-
role: "agent",
|
|
916
|
-
text: finalText,
|
|
917
|
-
createdAt: Date.now()
|
|
918
|
-
};
|
|
919
|
-
setState((prev) => ({
|
|
920
|
-
...prev,
|
|
921
|
-
phase: "complete",
|
|
922
|
-
messages: [...prev.messages, agentMessage],
|
|
923
|
-
toolSteps: [],
|
|
924
|
-
streamingText: "",
|
|
925
|
-
followUps: DEFAULT_FOLLOW_UPS,
|
|
926
|
-
journey: null
|
|
927
|
-
}));
|
|
928
|
-
} catch (error) {
|
|
929
|
-
if (error instanceof DOMException && error.name === "AbortError") return;
|
|
930
|
-
if (!isActiveRun()) return;
|
|
931
|
-
const message = formatAgentError(error);
|
|
932
|
-
if (!message) return;
|
|
933
|
-
setState((prev) => ({
|
|
934
|
-
...prev,
|
|
935
|
-
phase: "complete",
|
|
936
|
-
toolSteps: [],
|
|
937
|
-
streamingText: "",
|
|
938
|
-
error: message
|
|
939
|
-
}));
|
|
940
|
-
}
|
|
941
|
-
},
|
|
942
|
-
[customerId, indexId, runtimeOrigin, resolvedStorageKeyPrefix, visitorId]
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
await planningPromise.catch(() => {
|
|
522
|
+
});
|
|
523
|
+
if (!isActiveRun()) return;
|
|
524
|
+
const agentMessage = {
|
|
525
|
+
id: `agent-${Date.now()}`,
|
|
526
|
+
role: "agent",
|
|
527
|
+
text: finalText,
|
|
528
|
+
createdAt: Date.now()
|
|
529
|
+
};
|
|
530
|
+
setState((prev) => ({
|
|
531
|
+
...prev,
|
|
532
|
+
phase: "complete",
|
|
533
|
+
messages: [...prev.messages, agentMessage],
|
|
534
|
+
toolSteps: [],
|
|
535
|
+
streamingText: "",
|
|
536
|
+
followUps: DEFAULT_FOLLOW_UPS,
|
|
537
|
+
journey: null
|
|
538
|
+
}));
|
|
539
|
+
} catch (error) {
|
|
540
|
+
if (error instanceof DOMException && error.name === "AbortError") return;
|
|
541
|
+
if (!isActiveRun()) return;
|
|
542
|
+
const message = formatAgentError(error);
|
|
543
|
+
if (!message) return;
|
|
544
|
+
setState((prev) => ({
|
|
545
|
+
...prev,
|
|
546
|
+
phase: "complete",
|
|
547
|
+
toolSteps: [],
|
|
548
|
+
streamingText: "",
|
|
549
|
+
error: message
|
|
550
|
+
}));
|
|
551
|
+
}
|
|
552
|
+
},
|
|
553
|
+
[customerId, indexId, runtimeOrigin, resolvedStorageKeyPrefix, version, visitorId]
|
|
554
|
+
);
|
|
555
|
+
(0, import_react.useEffect)(() => {
|
|
556
|
+
return () => {
|
|
557
|
+
runRef.current?.abort();
|
|
558
|
+
clientRef.current.cancelActive();
|
|
559
|
+
};
|
|
560
|
+
}, []);
|
|
561
|
+
return {
|
|
562
|
+
state,
|
|
563
|
+
reset,
|
|
564
|
+
submit,
|
|
565
|
+
visitorSessionId: visitorId,
|
|
566
|
+
sessionId: clientRef.current.getActiveSessionId()
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
function hasVisitorMessages(messages) {
|
|
570
|
+
return messages.some((message) => message.role === "visitor");
|
|
571
|
+
}
|
|
572
|
+
function createIdleSuggestions() {
|
|
573
|
+
return [
|
|
574
|
+
{ id: "idle-1", label: "Hello \u2014 what can you do?" },
|
|
575
|
+
{ id: "idle-2", label: "Help me evaluate this product" },
|
|
576
|
+
{ id: "idle-3", label: "What should I ask you?" }
|
|
577
|
+
];
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// src/react/hooks/useIsMobile.ts
|
|
581
|
+
var import_react2 = require("react");
|
|
582
|
+
function useIsMobile(breakpoint = 767) {
|
|
583
|
+
const [isMobile, setIsMobile] = (0, import_react2.useState)(
|
|
584
|
+
() => typeof window !== "undefined" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
|
|
585
|
+
);
|
|
586
|
+
(0, import_react2.useEffect)(() => {
|
|
587
|
+
const media = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
588
|
+
const onChange = () => setIsMobile(media.matches);
|
|
589
|
+
onChange();
|
|
590
|
+
media.addEventListener("change", onChange);
|
|
591
|
+
return () => media.removeEventListener("change", onChange);
|
|
592
|
+
}, [breakpoint]);
|
|
593
|
+
return isMobile;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
// src/react/placement.ts
|
|
597
|
+
var DEFAULT_AGENT_PLACEMENT = {
|
|
598
|
+
side: "right",
|
|
599
|
+
along: 50,
|
|
600
|
+
inset: 0,
|
|
601
|
+
variant: "outline"
|
|
602
|
+
};
|
|
603
|
+
function normalizeAgentPlacement(placement) {
|
|
604
|
+
const along = placement?.along ?? DEFAULT_AGENT_PLACEMENT.along;
|
|
605
|
+
return {
|
|
606
|
+
side: placement?.side ?? DEFAULT_AGENT_PLACEMENT.side,
|
|
607
|
+
along: Math.min(100, Math.max(0, along)),
|
|
608
|
+
inset: Math.max(0, placement?.inset ?? DEFAULT_AGENT_PLACEMENT.inset),
|
|
609
|
+
variant: placement?.variant ?? DEFAULT_AGENT_PLACEMENT.variant
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// src/react/components/AgentRail/AgentRail.tsx
|
|
614
|
+
var import_react4 = require("react");
|
|
615
|
+
|
|
616
|
+
// src/react/components/ToolTimeline/ToolTimeline.tsx
|
|
617
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
618
|
+
function SpinnerIcon() {
|
|
619
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { className: "agent-status__spinner", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
|
|
620
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "8", cy: "8", r: "6", stroke: "currentColor", strokeWidth: "1.5", strokeOpacity: "0.25" }),
|
|
621
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14 8a6 6 0 0 0-6-6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
|
|
622
|
+
] });
|
|
623
|
+
}
|
|
624
|
+
function getCurrentStep(steps) {
|
|
625
|
+
const active = steps.find((step) => step.state === "active");
|
|
626
|
+
if (active) return active;
|
|
627
|
+
const error = steps.find((step) => step.state === "error");
|
|
628
|
+
if (error) return error;
|
|
629
|
+
const pending = steps.find((step) => step.state === "pending");
|
|
630
|
+
if (pending) return pending;
|
|
631
|
+
return steps.at(-1) ?? null;
|
|
632
|
+
}
|
|
633
|
+
function ToolTimeline({
|
|
634
|
+
steps,
|
|
635
|
+
streamingText,
|
|
636
|
+
showStreaming = false,
|
|
637
|
+
inline = false
|
|
638
|
+
}) {
|
|
639
|
+
if (steps.length === 0 && !(showStreaming && streamingText)) return null;
|
|
640
|
+
const currentStep = getCurrentStep(steps);
|
|
641
|
+
const showStatus = currentStep && currentStep.state !== "completed" && !(showStreaming && streamingText);
|
|
642
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
643
|
+
"div",
|
|
644
|
+
{
|
|
645
|
+
className: `tool-timeline${inline ? " tool-timeline--inline" : ""}`,
|
|
646
|
+
role: "status",
|
|
647
|
+
"aria-live": "polite",
|
|
648
|
+
"aria-label": "Agent progress",
|
|
649
|
+
children: [
|
|
650
|
+
showStatus ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-status", children: [
|
|
651
|
+
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, {}) }),
|
|
652
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "agent-status__copy", children: [
|
|
653
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__label", children: currentStep.label }),
|
|
654
|
+
currentStep.detail ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "agent-status__detail", children: currentStep.detail }) : null
|
|
655
|
+
] })
|
|
656
|
+
] }, currentStep.id) : null,
|
|
657
|
+
showStreaming && streamingText ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "tool-timeline__streaming-text", children: [
|
|
658
|
+
streamingText,
|
|
659
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "tool-timeline__cursor", "aria-hidden": "true" })
|
|
660
|
+
] }) : null
|
|
661
|
+
]
|
|
662
|
+
}
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// src/react/components/AgentActivityBubble/AgentActivityBubble.tsx
|
|
667
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
668
|
+
function AgentActivityBubble({
|
|
669
|
+
steps,
|
|
670
|
+
streamingText,
|
|
671
|
+
showStreaming = false
|
|
672
|
+
}) {
|
|
673
|
+
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)(
|
|
674
|
+
ToolTimeline,
|
|
675
|
+
{
|
|
676
|
+
steps,
|
|
677
|
+
streamingText,
|
|
678
|
+
showStreaming,
|
|
679
|
+
inline: true
|
|
680
|
+
}
|
|
681
|
+
) }) });
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// src/react/components/Composer/Composer.tsx
|
|
685
|
+
var import_react3 = require("react");
|
|
686
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
687
|
+
function SendIcon() {
|
|
688
|
+
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" }) });
|
|
689
|
+
}
|
|
690
|
+
function Composer({
|
|
691
|
+
disabled = false,
|
|
692
|
+
placeholder = "Ask anything\u2026",
|
|
693
|
+
variant = "default",
|
|
694
|
+
onSubmit
|
|
695
|
+
}) {
|
|
696
|
+
const [value, setValue] = (0, import_react3.useState)("");
|
|
697
|
+
const inputRef = (0, import_react3.useRef)(null);
|
|
698
|
+
function submitCurrent() {
|
|
699
|
+
const trimmed = value.trim();
|
|
700
|
+
if (!trimmed || disabled) return;
|
|
701
|
+
onSubmit?.(trimmed);
|
|
702
|
+
setValue("");
|
|
703
|
+
inputRef.current?.focus();
|
|
704
|
+
}
|
|
705
|
+
function handleSubmit(event) {
|
|
706
|
+
event.preventDefault();
|
|
707
|
+
submitCurrent();
|
|
708
|
+
}
|
|
709
|
+
function handleKeyDown(event) {
|
|
710
|
+
if (event.key === "Enter" && !event.shiftKey) {
|
|
711
|
+
event.preventDefault();
|
|
712
|
+
submitCurrent();
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
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: [
|
|
716
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
717
|
+
"textarea",
|
|
718
|
+
{
|
|
719
|
+
ref: inputRef,
|
|
720
|
+
className: "composer__input",
|
|
721
|
+
rows: 1,
|
|
722
|
+
value,
|
|
723
|
+
placeholder,
|
|
724
|
+
disabled,
|
|
725
|
+
"aria-label": "Message",
|
|
726
|
+
onChange: (event) => setValue(event.target.value),
|
|
727
|
+
onKeyDown: handleKeyDown
|
|
728
|
+
}
|
|
729
|
+
),
|
|
730
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
731
|
+
"button",
|
|
732
|
+
{
|
|
733
|
+
type: "submit",
|
|
734
|
+
className: "composer__send",
|
|
735
|
+
disabled: disabled || !value.trim(),
|
|
736
|
+
"aria-label": "Send message",
|
|
737
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SendIcon, {})
|
|
738
|
+
}
|
|
739
|
+
)
|
|
740
|
+
] }) });
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
// src/react/components/FollowUpChips/FollowUpChips.tsx
|
|
744
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
745
|
+
function FollowUpChips({
|
|
746
|
+
suggestions,
|
|
747
|
+
disabled = false,
|
|
748
|
+
label = "Follow up",
|
|
749
|
+
variant = "default",
|
|
750
|
+
onSelect
|
|
751
|
+
}) {
|
|
752
|
+
if (suggestions.length === 0) return null;
|
|
753
|
+
if (variant === "dock") {
|
|
754
|
+
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)(
|
|
755
|
+
"button",
|
|
756
|
+
{
|
|
757
|
+
type: "button",
|
|
758
|
+
className: "followups__chip followups__chip--dock",
|
|
759
|
+
disabled,
|
|
760
|
+
onClick: () => onSelect?.(suggestion),
|
|
761
|
+
children: suggestion.label
|
|
762
|
+
},
|
|
763
|
+
suggestion.id
|
|
764
|
+
)) }) });
|
|
765
|
+
}
|
|
766
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "followups", children: [
|
|
767
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "followups__label", children: label }),
|
|
768
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "followups__list", children: suggestions.map((suggestion) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
769
|
+
"button",
|
|
770
|
+
{
|
|
771
|
+
type: "button",
|
|
772
|
+
className: "followups__chip",
|
|
773
|
+
disabled,
|
|
774
|
+
onClick: () => onSelect?.(suggestion),
|
|
775
|
+
children: suggestion.label
|
|
776
|
+
},
|
|
777
|
+
suggestion.id
|
|
778
|
+
)) })
|
|
779
|
+
] });
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
// src/react/components/MessageBubble/MessageBubble.tsx
|
|
783
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
784
|
+
function MessageBubble({ message }) {
|
|
785
|
+
if (message.role === "visitor") {
|
|
786
|
+
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 }) });
|
|
787
|
+
}
|
|
788
|
+
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: [
|
|
789
|
+
message.text,
|
|
790
|
+
message.streaming ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "tool-timeline__cursor", "aria-hidden": "true" }) : null
|
|
791
|
+
] }) });
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// src/react/components/AgentRail/AgentRail.tsx
|
|
795
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
796
|
+
function MinimizeIcon() {
|
|
797
|
+
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" }) });
|
|
798
|
+
}
|
|
799
|
+
function ExpandIcon() {
|
|
800
|
+
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)(
|
|
801
|
+
"path",
|
|
802
|
+
{
|
|
803
|
+
d: "M6 3.5H3.5V6M10 3.5h2.5V6M10 12.5h2.5V10M6 12.5H3.5V10",
|
|
804
|
+
stroke: "currentColor",
|
|
805
|
+
strokeWidth: "1.5",
|
|
806
|
+
strokeLinecap: "round",
|
|
807
|
+
strokeLinejoin: "round"
|
|
808
|
+
}
|
|
809
|
+
) });
|
|
810
|
+
}
|
|
811
|
+
function RestoreIcon() {
|
|
812
|
+
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)(
|
|
813
|
+
"path",
|
|
814
|
+
{
|
|
815
|
+
d: "M5.5 5.5H3.5V7.5M10.5 5.5h2V7.5M10.5 10.5h2V8.5M5.5 10.5H3.5V8.5",
|
|
816
|
+
stroke: "currentColor",
|
|
817
|
+
strokeWidth: "1.5",
|
|
818
|
+
strokeLinecap: "round",
|
|
819
|
+
strokeLinejoin: "round"
|
|
820
|
+
}
|
|
821
|
+
) });
|
|
822
|
+
}
|
|
823
|
+
function AgentRail({
|
|
824
|
+
state,
|
|
825
|
+
theme,
|
|
826
|
+
brandLabel = "Webless Assist",
|
|
827
|
+
poweredByLabel = "Powered by Webless",
|
|
828
|
+
composerPlaceholder = "Ask anything\u2026",
|
|
829
|
+
mobileFullscreen = false,
|
|
830
|
+
expanded = false,
|
|
831
|
+
onCollapse,
|
|
832
|
+
onClose,
|
|
833
|
+
onExpandToggle,
|
|
834
|
+
onSubmit,
|
|
835
|
+
onFollowUpSelect
|
|
836
|
+
}) {
|
|
837
|
+
const transcriptRef = (0, import_react4.useRef)(null);
|
|
838
|
+
const railStyle = theme?.railMaxWidth ? { ["--rail-width"]: theme.railMaxWidth, ["--as-rail-max-width"]: theme.railMaxWidth } : void 0;
|
|
839
|
+
const isBusy = state.phase === "thinking" || state.phase === "running-tools" || state.phase === "streaming";
|
|
840
|
+
const showActivity = state.toolSteps.length > 0 && (state.phase === "thinking" || state.phase === "running-tools" || state.phase === "streaming");
|
|
841
|
+
const showStreamingInActivity = state.phase === "streaming" && Boolean(state.streamingText);
|
|
842
|
+
const hasVisitorMessages2 = state.messages.some((message) => message.role === "visitor");
|
|
843
|
+
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
844
|
+
const showCompleteFollowUps = state.phase === "complete" && state.followUps.length > 0 && hasVisitorMessages2;
|
|
845
|
+
const showDockFollowUps = expanded && (showIdleFollowUps || showCompleteFollowUps);
|
|
846
|
+
(0, import_react4.useEffect)(() => {
|
|
847
|
+
const node = transcriptRef.current;
|
|
848
|
+
if (!node) return;
|
|
849
|
+
node.scrollTop = node.scrollHeight;
|
|
850
|
+
}, [state.messages, state.toolSteps, state.streamingText, state.followUps, state.journey]);
|
|
851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
852
|
+
"aside",
|
|
853
|
+
{
|
|
854
|
+
className: `agent-rail${mobileFullscreen ? " agent-rail--mobile-fullscreen" : ""}${expanded ? " agent-rail--expanded" : ""}`,
|
|
855
|
+
style: railStyle,
|
|
856
|
+
"aria-label": "Agent conversation",
|
|
857
|
+
children: [
|
|
858
|
+
/* @__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: [
|
|
859
|
+
onCollapse ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
860
|
+
"button",
|
|
861
|
+
{
|
|
862
|
+
type: "button",
|
|
863
|
+
className: "agent-rail__collapse",
|
|
864
|
+
"aria-label": "Collapse assist",
|
|
865
|
+
onClick: onCollapse,
|
|
866
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MinimizeIcon, {})
|
|
867
|
+
}
|
|
868
|
+
) : 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" }),
|
|
869
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "agent-rail__brand-label", children: brandLabel }),
|
|
870
|
+
onExpandToggle ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
871
|
+
"button",
|
|
872
|
+
{
|
|
873
|
+
type: "button",
|
|
874
|
+
className: "agent-rail__expand",
|
|
875
|
+
"aria-label": expanded ? "Restore assist panel" : "Expand assist panel",
|
|
876
|
+
onClick: onExpandToggle,
|
|
877
|
+
children: expanded ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RestoreIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ExpandIcon, {})
|
|
878
|
+
}
|
|
879
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "agent-rail__brand-spacer", "aria-hidden": "true" })
|
|
880
|
+
] }) }),
|
|
881
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: [
|
|
882
|
+
state.messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MessageBubble, { message }, message.id)),
|
|
883
|
+
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
884
|
+
AgentActivityBubble,
|
|
885
|
+
{
|
|
886
|
+
steps: state.toolSteps,
|
|
887
|
+
streamingText: state.streamingText,
|
|
888
|
+
showStreaming: showStreamingInActivity
|
|
889
|
+
}
|
|
890
|
+
) : null,
|
|
891
|
+
!expanded && showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
892
|
+
FollowUpChips,
|
|
893
|
+
{
|
|
894
|
+
suggestions: state.followUps,
|
|
895
|
+
disabled: isBusy,
|
|
896
|
+
label: "Try asking",
|
|
897
|
+
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
898
|
+
}
|
|
899
|
+
) }) : null,
|
|
900
|
+
!expanded && showCompleteFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
901
|
+
FollowUpChips,
|
|
902
|
+
{
|
|
903
|
+
suggestions: state.followUps,
|
|
904
|
+
disabled: isBusy,
|
|
905
|
+
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
906
|
+
}
|
|
907
|
+
) }) : null,
|
|
908
|
+
state.error ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "alert", style: { fontSize: 13, color: "var(--as-danger)", margin: 0 }, children: state.error }) : null
|
|
909
|
+
] }),
|
|
910
|
+
expanded ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__dock-wrap", children: [
|
|
911
|
+
showDockFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__dock-followups", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
912
|
+
FollowUpChips,
|
|
913
|
+
{
|
|
914
|
+
variant: "dock",
|
|
915
|
+
suggestions: state.followUps,
|
|
916
|
+
disabled: isBusy,
|
|
917
|
+
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
918
|
+
}
|
|
919
|
+
) }) : null,
|
|
920
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__dock", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
921
|
+
Composer,
|
|
922
|
+
{
|
|
923
|
+
variant: "dock",
|
|
924
|
+
disabled: isBusy,
|
|
925
|
+
placeholder: composerPlaceholder,
|
|
926
|
+
onSubmit
|
|
927
|
+
}
|
|
928
|
+
) }),
|
|
929
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__footer", children: [
|
|
930
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
931
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
932
|
+
] })
|
|
933
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__composer-wrap", children: [
|
|
934
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
935
|
+
Composer,
|
|
936
|
+
{
|
|
937
|
+
disabled: isBusy,
|
|
938
|
+
placeholder: composerPlaceholder,
|
|
939
|
+
onSubmit
|
|
940
|
+
}
|
|
941
|
+
),
|
|
942
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__footer", children: [
|
|
943
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-disclaimer", children: "AI can make mistakes. Check important info." }),
|
|
944
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "agent-rail__footer-note", children: poweredByLabel })
|
|
945
|
+
] })
|
|
946
|
+
] })
|
|
947
|
+
]
|
|
948
|
+
}
|
|
943
949
|
);
|
|
944
|
-
(0, import_react3.useEffect)(() => {
|
|
945
|
-
return () => {
|
|
946
|
-
runRef.current?.abort();
|
|
947
|
-
clientRef.current.cancelActive();
|
|
948
|
-
};
|
|
949
|
-
}, []);
|
|
950
|
-
return {
|
|
951
|
-
state,
|
|
952
|
-
reset,
|
|
953
|
-
submit,
|
|
954
|
-
visitorSessionId: visitorId,
|
|
955
|
-
sessionId: clientRef.current.getActiveSessionId()
|
|
956
|
-
};
|
|
957
950
|
}
|
|
958
|
-
|
|
959
|
-
|
|
951
|
+
|
|
952
|
+
// src/react/components/AssistEdgeTab/AssistEdgeTab.tsx
|
|
953
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
954
|
+
function SparklesIcon() {
|
|
955
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { className: "assist-edge-tab__sparkles", viewBox: "0 0 18 16", fill: "none", "aria-hidden": "true", children: [
|
|
956
|
+
/* @__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" }),
|
|
957
|
+
/* @__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" }),
|
|
958
|
+
/* @__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" })
|
|
959
|
+
] });
|
|
960
960
|
}
|
|
961
|
-
function
|
|
962
|
-
return
|
|
963
|
-
{ id: "idle-1", label: "Hello \u2014 what can you do?" },
|
|
964
|
-
{ id: "idle-2", label: "Help me evaluate this product" },
|
|
965
|
-
{ id: "idle-3", label: "What should I ask you?" }
|
|
966
|
-
];
|
|
961
|
+
function ChevronLeftIcon() {
|
|
962
|
+
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" }) });
|
|
967
963
|
}
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
function
|
|
972
|
-
|
|
973
|
-
|
|
964
|
+
function ChevronDownIcon() {
|
|
965
|
+
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" }) });
|
|
966
|
+
}
|
|
967
|
+
function DragDots() {
|
|
968
|
+
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)) });
|
|
969
|
+
}
|
|
970
|
+
var VARIANT_COPY = {
|
|
971
|
+
outline: { label: "Assist", aria: "Open Assist" },
|
|
972
|
+
ask: { label: "Ask anything", aria: "Ask anything" },
|
|
973
|
+
fill: { label: "Assist", aria: "Open Assist" }
|
|
974
|
+
};
|
|
975
|
+
function AssistEdgeTab({
|
|
976
|
+
variant,
|
|
977
|
+
side,
|
|
978
|
+
along,
|
|
979
|
+
inset,
|
|
980
|
+
visible,
|
|
981
|
+
onOpen
|
|
982
|
+
}) {
|
|
983
|
+
const copy = VARIANT_COPY[variant];
|
|
984
|
+
const style = {
|
|
985
|
+
"--tab-along": `${along}%`,
|
|
986
|
+
"--tab-inset": `${inset}px`
|
|
987
|
+
};
|
|
988
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
989
|
+
"button",
|
|
990
|
+
{
|
|
991
|
+
type: "button",
|
|
992
|
+
className: `assist-edge-tab assist-edge-tab--${variant} assist-edge-tab--${side}${visible ? " is-visible" : ""}`,
|
|
993
|
+
style,
|
|
994
|
+
"aria-label": copy.aria,
|
|
995
|
+
"aria-hidden": !visible,
|
|
996
|
+
tabIndex: visible ? 0 : -1,
|
|
997
|
+
onClick: onOpen,
|
|
998
|
+
children: [
|
|
999
|
+
variant === "outline" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1000
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparklesIcon, {}),
|
|
1001
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__label", children: copy.label }),
|
|
1002
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronDownIcon, {})
|
|
1003
|
+
] }) : null,
|
|
1004
|
+
variant === "ask" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1005
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronLeftIcon, {}),
|
|
1006
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__label", children: copy.label }),
|
|
1007
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(DragDots, {})
|
|
1008
|
+
] }) : null,
|
|
1009
|
+
variant === "fill" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
|
|
1010
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SparklesIcon, {}),
|
|
1011
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "assist-edge-tab__label", children: copy.label }),
|
|
1012
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ChevronLeftIcon, {})
|
|
1013
|
+
] }) : null
|
|
1014
|
+
]
|
|
1015
|
+
}
|
|
974
1016
|
);
|
|
975
|
-
(0, import_react4.useEffect)(() => {
|
|
976
|
-
const media = window.matchMedia(`(max-width: ${breakpoint}px)`);
|
|
977
|
-
const onChange = () => setIsMobile(media.matches);
|
|
978
|
-
onChange();
|
|
979
|
-
media.addEventListener("change", onChange);
|
|
980
|
-
return () => media.removeEventListener("change", onChange);
|
|
981
|
-
}, [breakpoint]);
|
|
982
|
-
return isMobile;
|
|
983
1017
|
}
|
|
984
|
-
|
|
1018
|
+
|
|
1019
|
+
// src/react/components/AgentWidget/AgentWidget.tsx
|
|
1020
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1021
|
+
function AgentWidget({
|
|
1022
|
+
indexId,
|
|
1023
|
+
customerId,
|
|
1024
|
+
version,
|
|
1025
|
+
runtimeOrigin,
|
|
1026
|
+
placement: placementInput,
|
|
1027
|
+
defaultCollapsed = true,
|
|
1028
|
+
registerPanelController = false
|
|
1029
|
+
}) {
|
|
985
1030
|
const isMobile = useIsMobile();
|
|
986
|
-
const
|
|
987
|
-
const [
|
|
1031
|
+
const placement = normalizeAgentPlacement(placementInput);
|
|
1032
|
+
const [railCollapsed, setRailCollapsed] = (0, import_react5.useState)(defaultCollapsed);
|
|
1033
|
+
const [railExpanded, setRailExpanded] = (0, import_react5.useState)(false);
|
|
988
1034
|
const { state, submit } = useAgentChat({
|
|
989
|
-
customerId
|
|
990
|
-
indexId
|
|
991
|
-
|
|
1035
|
+
customerId,
|
|
1036
|
+
indexId,
|
|
1037
|
+
version,
|
|
1038
|
+
runtimeOrigin
|
|
992
1039
|
});
|
|
993
1040
|
const idle = state.phase === "idle" && !hasVisitorMessages(state.messages);
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
registerAgentPanelController(
|
|
1041
|
+
(0, import_react5.useEffect)(() => {
|
|
1042
|
+
if (!registerPanelController) return;
|
|
1043
|
+
registerAgentPanelController(customerId, {
|
|
997
1044
|
open: () => setRailCollapsed(false),
|
|
998
1045
|
close: () => {
|
|
999
1046
|
setRailCollapsed(true);
|
|
1000
1047
|
setRailExpanded(false);
|
|
1001
1048
|
}
|
|
1002
1049
|
});
|
|
1003
|
-
return () => unregisterAgentPanelController(
|
|
1004
|
-
}, [
|
|
1050
|
+
return () => unregisterAgentPanelController(customerId);
|
|
1051
|
+
}, [customerId, registerPanelController]);
|
|
1005
1052
|
async function handleSubmit(message) {
|
|
1006
1053
|
if (isMobile) setRailCollapsed(false);
|
|
1007
1054
|
await submit(message);
|
|
1008
1055
|
}
|
|
1009
|
-
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1056
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "webless-agent-root", children: [
|
|
1010
1057
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1011
1058
|
"div",
|
|
1012
1059
|
{
|
|
@@ -1060,22 +1107,24 @@ function AgentWidget({ manifest }) {
|
|
|
1060
1107
|
] });
|
|
1061
1108
|
}
|
|
1062
1109
|
|
|
1063
|
-
// src/embed/
|
|
1064
|
-
var
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1110
|
+
// src/embed/AgentWidget.tsx
|
|
1111
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1112
|
+
function AgentWidget2({ manifest }) {
|
|
1113
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1114
|
+
AgentWidget,
|
|
1115
|
+
{
|
|
1116
|
+
indexId: manifest.indexId,
|
|
1117
|
+
customerId: manifest.customerId,
|
|
1118
|
+
version: manifest.version,
|
|
1119
|
+
runtimeOrigin: manifest.runtimeOrigin,
|
|
1120
|
+
placement: manifest.placement,
|
|
1121
|
+
defaultCollapsed: true,
|
|
1122
|
+
registerPanelController: true
|
|
1123
|
+
}
|
|
1124
|
+
);
|
|
1078
1125
|
}
|
|
1126
|
+
|
|
1127
|
+
// src/embed/manifest.ts
|
|
1079
1128
|
function normalizeAgentTagManifest(manifest) {
|
|
1080
1129
|
const indexId = manifest.indexId.trim();
|
|
1081
1130
|
if (!indexId) {
|
|
@@ -1085,15 +1134,20 @@ function normalizeAgentTagManifest(manifest) {
|
|
|
1085
1134
|
if (!customerId) {
|
|
1086
1135
|
throw new Error("Agent manifest requires customerId.");
|
|
1087
1136
|
}
|
|
1137
|
+
const version = manifest.version ?? "published";
|
|
1138
|
+
if (version !== "published" && version !== "unpublished") {
|
|
1139
|
+
throw new Error("Agent manifest version must be published or unpublished.");
|
|
1140
|
+
}
|
|
1088
1141
|
const runtime = resolveAgentRuntimeConfig({
|
|
1089
1142
|
indexId,
|
|
1143
|
+
version,
|
|
1090
1144
|
runtimeOrigin: manifest.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN
|
|
1091
1145
|
});
|
|
1092
1146
|
return {
|
|
1093
1147
|
customerId,
|
|
1094
1148
|
indexId,
|
|
1095
1149
|
runtimeOrigin: runtime.origin,
|
|
1096
|
-
version
|
|
1150
|
+
version,
|
|
1097
1151
|
mount: {
|
|
1098
1152
|
selector: manifest.mount?.selector?.trim(),
|
|
1099
1153
|
strategy: manifest.mount?.strategy ?? "body"
|
|
@@ -1103,7 +1157,7 @@ function normalizeAgentTagManifest(manifest) {
|
|
|
1103
1157
|
}
|
|
1104
1158
|
|
|
1105
1159
|
// src/embed/mount.tsx
|
|
1106
|
-
var
|
|
1160
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1107
1161
|
var mountedHandles = /* @__PURE__ */ new Map();
|
|
1108
1162
|
var latestCustomerId = null;
|
|
1109
1163
|
function resolveMountHost(manifest, script) {
|
|
@@ -1119,7 +1173,6 @@ function resolveMountHost(manifest, script) {
|
|
|
1119
1173
|
}
|
|
1120
1174
|
function createHost(customerId) {
|
|
1121
1175
|
const host = document.createElement("div");
|
|
1122
|
-
host.className = "webless-agent-root";
|
|
1123
1176
|
host.dataset.weblessAgentCustomerId = customerId;
|
|
1124
1177
|
host.setAttribute("data-webless-agent", customerId);
|
|
1125
1178
|
return host;
|
|
@@ -1134,7 +1187,7 @@ function mountAgent(input) {
|
|
|
1134
1187
|
const host = createHost(manifest.customerId);
|
|
1135
1188
|
mountTarget.append(host);
|
|
1136
1189
|
const root = (0, import_client4.createRoot)(host);
|
|
1137
|
-
root.render(/* @__PURE__ */ (0,
|
|
1190
|
+
root.render(/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(AgentWidget2, { manifest }));
|
|
1138
1191
|
const handle = {
|
|
1139
1192
|
customerId: manifest.customerId,
|
|
1140
1193
|
manifest,
|
|
@@ -1175,10 +1228,54 @@ function getMountedAgent(customerId) {
|
|
|
1175
1228
|
function bootstrapAgent(manifest, script) {
|
|
1176
1229
|
return mountAgent({ manifest, script });
|
|
1177
1230
|
}
|
|
1231
|
+
|
|
1232
|
+
// src/embed/iife-bootstrap.ts
|
|
1233
|
+
function createWeblessAgentPublicApi(manifest) {
|
|
1234
|
+
const script = document.currentScript instanceof HTMLScriptElement ? document.currentScript : null;
|
|
1235
|
+
function mount(options = {}) {
|
|
1236
|
+
return mountAgent({
|
|
1237
|
+
manifest: {
|
|
1238
|
+
...manifest,
|
|
1239
|
+
...options,
|
|
1240
|
+
customerId: manifest.customerId
|
|
1241
|
+
},
|
|
1242
|
+
script
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
function unmount(customerId) {
|
|
1246
|
+
return unmountAgent(customerId ?? manifest.customerId);
|
|
1247
|
+
}
|
|
1248
|
+
function open(customerId) {
|
|
1249
|
+
getMountedAgent(customerId ?? manifest.customerId)?.open();
|
|
1250
|
+
}
|
|
1251
|
+
function close(customerId) {
|
|
1252
|
+
getMountedAgent(customerId ?? manifest.customerId)?.close();
|
|
1253
|
+
}
|
|
1254
|
+
function get(customerId) {
|
|
1255
|
+
return getMountedAgent(customerId ?? manifest.customerId);
|
|
1256
|
+
}
|
|
1257
|
+
const api = {
|
|
1258
|
+
mount,
|
|
1259
|
+
unmount,
|
|
1260
|
+
open,
|
|
1261
|
+
close,
|
|
1262
|
+
get
|
|
1263
|
+
};
|
|
1264
|
+
window.WeblessAgent = api;
|
|
1265
|
+
void (async () => {
|
|
1266
|
+
try {
|
|
1267
|
+
mount();
|
|
1268
|
+
} catch (error) {
|
|
1269
|
+
console.error("[Webless] Agent mount failed", error);
|
|
1270
|
+
}
|
|
1271
|
+
})();
|
|
1272
|
+
return api;
|
|
1273
|
+
}
|
|
1178
1274
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1179
1275
|
0 && (module.exports = {
|
|
1180
1276
|
DEFAULT_AGENT_PLACEMENT,
|
|
1181
1277
|
bootstrapAgent,
|
|
1278
|
+
createWeblessAgentPublicApi,
|
|
1182
1279
|
getMountedAgent,
|
|
1183
1280
|
mountAgent,
|
|
1184
1281
|
normalizeAgentPlacement,
|