@xapp/chat-widget 1.98.4 → 1.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.d.ts +0 -0
- package/dist/config/index.d.ts +0 -0
- package/dist/config/isRenderableConfig.d.ts +0 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +0 -0
- package/dist/index.es.js +79 -26
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +79 -26
- package/dist/index.js.map +1 -1
- package/dist/xapp/MCPChat.d.ts +0 -0
- package/dist/xapp-chat-widget.css +1 -1
- package/dist/xapp-chat-widget.js +5 -5
- package/dist/xapp-chat-widget.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -4491,23 +4491,48 @@ var MCPChat = /** @class */ (function () {
|
|
|
4491
4491
|
log("SERVER: account_status: ".concat(JSON.stringify(status)));
|
|
4492
4492
|
this.dispatch(setAccountStatus(status));
|
|
4493
4493
|
};
|
|
4494
|
-
|
|
4494
|
+
/**
|
|
4495
|
+
* The paths this mode hangs off its base URL: [stream, close].
|
|
4496
|
+
*/
|
|
4497
|
+
MCPChat.prototype.getEndpointPaths = function () {
|
|
4498
|
+
return (this.config.mode || "homeowner") === "business_owner"
|
|
4499
|
+
? [BUSINESS_OWNER_ENDPOINT_PATH, BUSINESS_OWNER_CLOSE_ENDPOINT_PATH]
|
|
4500
|
+
: [HOMEOWNER_ENDPOINT_PATH, HOMEOWNER_CLOSE_ENDPOINT_PATH];
|
|
4501
|
+
};
|
|
4502
|
+
/**
|
|
4503
|
+
* The base the endpoint paths are built from.
|
|
4504
|
+
*
|
|
4505
|
+
* A configured `serverUrl` arrives in either of two shapes: the base
|
|
4506
|
+
* (`https://agentic.xapp.ai/<appId>`), which is what this class was written for, or the
|
|
4507
|
+
* full stream endpoint (`https://agentic.xapp.ai/<appId>/chat/stream`), which is the form
|
|
4508
|
+
* issue #1403 documents as the Dev and Prod defaults. Appending unconditionally turns the
|
|
4509
|
+
* second into `.../chat/stream/chat/stream`.
|
|
4510
|
+
*
|
|
4511
|
+
* Taking `serverUrl` verbatim instead is not the fix: `/chat/close` has to be derived
|
|
4512
|
+
* from something, and a widget configured with the full stream URL would then send every
|
|
4513
|
+
* close request to the stream endpoint. So normalise back to the base and build both
|
|
4514
|
+
* paths from it, which leaves either configured form working.
|
|
4515
|
+
*
|
|
4516
|
+
* Only the paths belonging to the CONFIGURED mode come off. A homeowner URL handed to a
|
|
4517
|
+
* business_owner widget is a misconfiguration, not something to quietly reinterpret, and
|
|
4518
|
+
* an appId that merely ends in `/stream` is not an endpoint path.
|
|
4519
|
+
*/
|
|
4520
|
+
MCPChat.prototype.getBaseUrl = function () {
|
|
4495
4521
|
// Normalize serverUrl to remove trailing slashes
|
|
4496
4522
|
var serverUrl = this.config.serverUrl.replace(/\/+$/, "");
|
|
4497
|
-
var
|
|
4498
|
-
|
|
4499
|
-
|
|
4523
|
+
for (var _i = 0, _a = this.getEndpointPaths(); _i < _a.length; _i++) {
|
|
4524
|
+
var path = _a[_i];
|
|
4525
|
+
if (serverUrl.endsWith(path)) {
|
|
4526
|
+
return serverUrl.slice(0, -path.length);
|
|
4527
|
+
}
|
|
4500
4528
|
}
|
|
4501
|
-
|
|
4502
|
-
|
|
4529
|
+
return serverUrl;
|
|
4530
|
+
};
|
|
4531
|
+
MCPChat.prototype.getEndpoint = function () {
|
|
4532
|
+
return "".concat(this.getBaseUrl()).concat(this.getEndpointPaths()[0]);
|
|
4503
4533
|
};
|
|
4504
4534
|
MCPChat.prototype.getCloseEndpoint = function () {
|
|
4505
|
-
|
|
4506
|
-
var mode = this.config.mode || "homeowner";
|
|
4507
|
-
if (mode === "business_owner") {
|
|
4508
|
-
return "".concat(serverUrl).concat(BUSINESS_OWNER_CLOSE_ENDPOINT_PATH);
|
|
4509
|
-
}
|
|
4510
|
-
return "".concat(serverUrl).concat(HOMEOWNER_CLOSE_ENDPOINT_PATH);
|
|
4535
|
+
return "".concat(this.getBaseUrl()).concat(this.getEndpointPaths()[1]);
|
|
4511
4536
|
};
|
|
4512
4537
|
MCPChat.prototype.sendNewMessage = function (msg, user) {
|
|
4513
4538
|
log("SERVER: new message: ".concat(JSON.stringify(msg)));
|
|
@@ -12953,7 +12978,7 @@ var ChatMessage = function (props) {
|
|
|
12953
12978
|
return (require$$0.jsxs(require$$0.Fragment, { children: [showToolProgressWithAvatar && (require$$0.jsx(ChatMessagePart, { showAvatar: true, user: user, avatarPosition: (_g = (_f = (_e = chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.env) === null || _e === void 0 ? void 0 : _e.theme) === null || _f === void 0 ? void 0 : _f.messages) === null || _g === void 0 ? void 0 : _g.avatarPosition, hideUserInfo: hideUserInfo, isStreaming: true, children: require$$0.jsx("div", { className: "chat-msg", children: require$$0.jsx(ToolCallDisplay, { toolCalls: toolCalls, debugMode: debugMode }) }) })), msg.text && (require$$0.jsx(ChatMessagePart, { showAvatar: avaKey === "text", user: user, avatarPosition: (_k = (_j = (_h = chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.env) === null || _h === void 0 ? void 0 : _h.theme) === null || _j === void 0 ? void 0 : _j.messages) === null || _k === void 0 ? void 0 : _k.avatarPosition, hideUserInfo: hideUserInfo, isStreaming: isStreaming_1 || wasStreamed, children: require$$0.jsx(ChatTextMessage, { message: props.message, sibling: props.sibling, user: user, toolCalls: hasToolCalls ? toolCalls : undefined, debugMode: debugMode }) })), msg.html &&
|
|
12954
12979
|
require$$0.jsx(ChatMessagePart, { showAvatar: avaKey === "html", user: user, avatarPosition: (_o = (_m = (_l = chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.env) === null || _l === void 0 ? void 0 : _l.theme) === null || _m === void 0 ? void 0 : _m.messages) === null || _o === void 0 ? void 0 : _o.avatarPosition, hideUserInfo: hideUserInfo, children: require$$0.jsx(ChatMarkdownMessage, { message: props.message, sibling: props.sibling, onOpenUrl: (_p = props.middlewareContext) === null || _p === void 0 ? void 0 : _p.openUrl }) }), msg.displays && middleware && msg.displays.map(function (display, index) {
|
|
12955
12980
|
if (display.type === "ScheduleButton") {
|
|
12956
|
-
return (require$$0.jsx(ChatScheduleWidget, { minimizeOnClick: props.minimizeOnClick, display: display }));
|
|
12981
|
+
return (require$$0.jsx(ChatScheduleWidget, { minimizeOnClick: props.minimizeOnClick, display: display }, index));
|
|
12957
12982
|
}
|
|
12958
12983
|
var Middleware = middleware;
|
|
12959
12984
|
return (require$$0.jsx(Middleware, { msg: display, ctx: props.middlewareContext }, index));
|
|
@@ -13451,11 +13476,14 @@ var Suggestions = function (props) {
|
|
|
13451
13476
|
var actions = React.useMemo(function () { return createActions(onItemUse); }, [onItemUse]);
|
|
13452
13477
|
var transformContent = function (content) {
|
|
13453
13478
|
var lines = content.split('\n');
|
|
13454
|
-
|
|
13479
|
+
// Keyed by position: the lines have no id of their own, and a blank line between
|
|
13480
|
+
// paragraphs is not distinguishable by content either. `<></>` cannot carry a key,
|
|
13481
|
+
// hence the explicit Fragment.
|
|
13482
|
+
return lines.map(function (line, index) {
|
|
13455
13483
|
if (line) {
|
|
13456
|
-
return require$$0.jsx(MarkdownBuilder, { text: line });
|
|
13484
|
+
return require$$0.jsx(MarkdownBuilder, { text: line }, "line-".concat(index));
|
|
13457
13485
|
}
|
|
13458
|
-
return require$$0.jsx(
|
|
13486
|
+
return require$$0.jsx(React.Fragment, {}, "line-".concat(index));
|
|
13459
13487
|
});
|
|
13460
13488
|
};
|
|
13461
13489
|
var containerClass = "xappw-suggestions ".concat(props.className || "", " ").concat(props.hasWsButton ? "xappw-suggestions--with-ws-button" : "").trim();
|
|
@@ -35435,12 +35463,37 @@ var MessageList = function (_a) {
|
|
|
35435
35463
|
var _a = containerRef.current, scrollTop = _a.scrollTop, scrollHeight = _a.scrollHeight, clientHeight = _a.clientHeight;
|
|
35436
35464
|
return Math.abs(scrollHeight - clientHeight - scrollTop) < 10;
|
|
35437
35465
|
}, []);
|
|
35438
|
-
|
|
35466
|
+
/**
|
|
35467
|
+
* Pin the list to its newest message.
|
|
35468
|
+
*
|
|
35469
|
+
* Scrolls THIS container, deliberately - not `messagesEndRef.scrollIntoView()`.
|
|
35470
|
+
* scrollIntoView walks every scrollable ancestor, and its default `block: "start"` puts
|
|
35471
|
+
* the target at the top of each one. On first open the greeting and its chips arrive,
|
|
35472
|
+
* this effect fires, and the whole chat panel was smoothly dragged upward until the end
|
|
35473
|
+
* marker reached the top - leaving only the suggestion chips and the input on screen
|
|
35474
|
+
* until the user scrolled back by hand. Device, 2026-09-10.
|
|
35475
|
+
*
|
|
35476
|
+
* A container scroll cannot touch an ancestor, which is the entire point.
|
|
35477
|
+
*
|
|
35478
|
+
* `scrollTo` is feature-detected rather than assumed. It is absent in jsdom, so every
|
|
35479
|
+
* test that mounts this component through a passive effect throws on it -- but the
|
|
35480
|
+
* reason to guard is not the test runner: this widget renders on whatever browser a
|
|
35481
|
+
* customer's visitor brought, and a missing `Element.prototype.scrollTo` would throw
|
|
35482
|
+
* inside a passive effect and take the message list down with it. Assigning
|
|
35483
|
+
* `scrollTop` is the universally supported equivalent; it loses the smooth animation
|
|
35484
|
+
* and nothing else.
|
|
35485
|
+
*/
|
|
35439
35486
|
var scrollToBottom = React.useCallback(function (behavior) {
|
|
35440
35487
|
if (behavior === void 0) { behavior = "smooth"; }
|
|
35441
|
-
|
|
35442
|
-
|
|
35488
|
+
var container = containerRef.current;
|
|
35489
|
+
if (!container) {
|
|
35490
|
+
return;
|
|
35491
|
+
}
|
|
35492
|
+
if (typeof container.scrollTo === "function") {
|
|
35493
|
+
container.scrollTo({ top: container.scrollHeight, behavior: behavior });
|
|
35494
|
+
return;
|
|
35443
35495
|
}
|
|
35496
|
+
container.scrollTop = container.scrollHeight;
|
|
35444
35497
|
}, []);
|
|
35445
35498
|
// Always scroll to bottom when messages change (unless disabled)
|
|
35446
35499
|
React.useEffect(function () {
|
|
@@ -35472,16 +35525,16 @@ var MessageList = function (_a) {
|
|
|
35472
35525
|
}, [hasWsButton, isAtBottom, scrollToBottom, disableAutoScroll]);
|
|
35473
35526
|
var handleSend = React.useCallback(function (msg) {
|
|
35474
35527
|
onSend(msg);
|
|
35475
|
-
if (!disableAutoScroll
|
|
35476
|
-
|
|
35528
|
+
if (!disableAutoScroll) {
|
|
35529
|
+
scrollToBottom("smooth");
|
|
35477
35530
|
}
|
|
35478
|
-
}, [onSend, disableAutoScroll]);
|
|
35531
|
+
}, [onSend, disableAutoScroll, scrollToBottom]);
|
|
35479
35532
|
var handleWrite = React.useCallback(function (msg) {
|
|
35480
35533
|
onWrite(msg);
|
|
35481
|
-
if (!disableAutoScroll
|
|
35482
|
-
|
|
35534
|
+
if (!disableAutoScroll) {
|
|
35535
|
+
scrollToBottom("smooth");
|
|
35483
35536
|
}
|
|
35484
|
-
}, [onWrite, disableAutoScroll]);
|
|
35537
|
+
}, [onWrite, disableAutoScroll, scrollToBottom]);
|
|
35485
35538
|
var ctxCache = React.useMemo(function () {
|
|
35486
35539
|
return new MiddlewareContextFactory({
|
|
35487
35540
|
send: handleSend,
|
|
@@ -35531,7 +35584,7 @@ var MessageList = function (_a) {
|
|
|
35531
35584
|
case "chat.prechat":
|
|
35532
35585
|
return require$$0.jsx(PrechatFormContainer, { time: time }, "prechat");
|
|
35533
35586
|
default:
|
|
35534
|
-
return (require$$0.jsxs("span", { children: [require$$0.jsx("span", { className: "message-sr-only", children: "at " + time + " system message" }), require$$0.jsxs("div", { children: ["Unhandled message: ", JSON.stringify(msg)] }, "uhm-".concat(
|
|
35587
|
+
return (require$$0.jsxs("span", { children: [require$$0.jsx("span", { className: "message-sr-only", children: "at " + time + " system message" }), require$$0.jsxs("div", { "data-testid": "unhandled-message", children: ["Unhandled message: ", JSON.stringify(msg)] }, "uhm-".concat(msg.timestamp))] }, "default-".concat(msg.timestamp)));
|
|
35535
35588
|
}
|
|
35536
35589
|
}
|
|
35537
35590
|
/**
|