@xapp/chat-widget 1.98.3 → 1.99.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 +65 -22
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +65 -22
- 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)));
|
|
@@ -35435,11 +35460,23 @@ var MessageList = function (_a) {
|
|
|
35435
35460
|
var _a = containerRef.current, scrollTop = _a.scrollTop, scrollHeight = _a.scrollHeight, clientHeight = _a.clientHeight;
|
|
35436
35461
|
return Math.abs(scrollHeight - clientHeight - scrollTop) < 10;
|
|
35437
35462
|
}, []);
|
|
35438
|
-
|
|
35463
|
+
/**
|
|
35464
|
+
* Pin the list to its newest message.
|
|
35465
|
+
*
|
|
35466
|
+
* Scrolls THIS container, deliberately - not `messagesEndRef.scrollIntoView()`.
|
|
35467
|
+
* scrollIntoView walks every scrollable ancestor, and its default `block: "start"` puts
|
|
35468
|
+
* the target at the top of each one. On first open the greeting and its chips arrive,
|
|
35469
|
+
* this effect fires, and the whole chat panel was smoothly dragged upward until the end
|
|
35470
|
+
* marker reached the top - leaving only the suggestion chips and the input on screen
|
|
35471
|
+
* until the user scrolled back by hand. Device, 2026-09-10.
|
|
35472
|
+
*
|
|
35473
|
+
* A container scroll cannot touch an ancestor, which is the entire point.
|
|
35474
|
+
*/
|
|
35439
35475
|
var scrollToBottom = React.useCallback(function (behavior) {
|
|
35440
35476
|
if (behavior === void 0) { behavior = "smooth"; }
|
|
35441
|
-
|
|
35442
|
-
|
|
35477
|
+
var container = containerRef.current;
|
|
35478
|
+
if (container) {
|
|
35479
|
+
container.scrollTo({ top: container.scrollHeight, behavior: behavior });
|
|
35443
35480
|
}
|
|
35444
35481
|
}, []);
|
|
35445
35482
|
// Always scroll to bottom when messages change (unless disabled)
|
|
@@ -35472,16 +35509,16 @@ var MessageList = function (_a) {
|
|
|
35472
35509
|
}, [hasWsButton, isAtBottom, scrollToBottom, disableAutoScroll]);
|
|
35473
35510
|
var handleSend = React.useCallback(function (msg) {
|
|
35474
35511
|
onSend(msg);
|
|
35475
|
-
if (!disableAutoScroll
|
|
35476
|
-
|
|
35512
|
+
if (!disableAutoScroll) {
|
|
35513
|
+
scrollToBottom("smooth");
|
|
35477
35514
|
}
|
|
35478
|
-
}, [onSend, disableAutoScroll]);
|
|
35515
|
+
}, [onSend, disableAutoScroll, scrollToBottom]);
|
|
35479
35516
|
var handleWrite = React.useCallback(function (msg) {
|
|
35480
35517
|
onWrite(msg);
|
|
35481
|
-
if (!disableAutoScroll
|
|
35482
|
-
|
|
35518
|
+
if (!disableAutoScroll) {
|
|
35519
|
+
scrollToBottom("smooth");
|
|
35483
35520
|
}
|
|
35484
|
-
}, [onWrite, disableAutoScroll]);
|
|
35521
|
+
}, [onWrite, disableAutoScroll, scrollToBottom]);
|
|
35485
35522
|
var ctxCache = React.useMemo(function () {
|
|
35486
35523
|
return new MiddlewareContextFactory({
|
|
35487
35524
|
send: handleSend,
|
|
@@ -37280,7 +37317,13 @@ var ChatWidgetUI = function (props) {
|
|
|
37280
37317
|
}));
|
|
37281
37318
|
setVisible(true);
|
|
37282
37319
|
setTimeout(function () {
|
|
37283
|
-
|
|
37320
|
+
var _a;
|
|
37321
|
+
// preventScroll, because this lands 100ms into the 0.3s widget-show translateY.
|
|
37322
|
+
// A plain focus() lets the browser scroll the input into view against a panel
|
|
37323
|
+
// that is still moving; it settles on an offset nobody asked for and the input
|
|
37324
|
+
// sits far up the screen until the user scrolls by hand. Nothing needs scrolling
|
|
37325
|
+
// here anyway - the panel is already full-screen on mobile. Device, 2026-09-09.
|
|
37326
|
+
(_a = document.getElementById("chatWidgetInput")) === null || _a === void 0 ? void 0 : _a.focus({ preventScroll: true });
|
|
37284
37327
|
}, 100);
|
|
37285
37328
|
}
|
|
37286
37329
|
function handleCtaDismiss() {
|