@xapp/chat-widget 1.100.0 → 1.101.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/index.css +1 -1
- package/dist/index.es.js +81 -30
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +81 -30
- package/dist/index.js.map +1 -1
- package/dist/store/ChatAction.d.ts +0 -0
- package/dist/xapp/MCPChat.d.ts +0 -0
- package/dist/xapp-chat-widget.css +1 -1
- package/dist/xapp-chat-widget.js +3 -3
- package/dist/xapp-chat-widget.js.map +1 -1
- package/package.json +1 -1
package/dist/index.es.js
CHANGED
|
@@ -4643,8 +4643,8 @@ var MCPChat = /** @class */ (function () {
|
|
|
4643
4643
|
// Generic fallback
|
|
4644
4644
|
return "Something went wrong. Please try again.";
|
|
4645
4645
|
};
|
|
4646
|
-
MCPChat.prototype.dispatchStreamStart = function (messageId) {
|
|
4647
|
-
var bot = this.getBot(
|
|
4646
|
+
MCPChat.prototype.dispatchStreamStart = function (messageId, user) {
|
|
4647
|
+
var bot = this.getBot(user);
|
|
4648
4648
|
var streamTimestamp = +new Date();
|
|
4649
4649
|
log("[dispatchStreamStart] Stream started: ".concat(messageId, ", timestamp: ").concat(streamTimestamp));
|
|
4650
4650
|
this.dispatch({
|
|
@@ -4657,30 +4657,25 @@ var MCPChat = /** @class */ (function () {
|
|
|
4657
4657
|
},
|
|
4658
4658
|
});
|
|
4659
4659
|
};
|
|
4660
|
-
MCPChat.prototype.dispatchStreamChunk = function (messageId, text) {
|
|
4660
|
+
MCPChat.prototype.dispatchStreamChunk = function (messageId, text, user) {
|
|
4661
4661
|
this.dispatch({
|
|
4662
4662
|
type: "chat",
|
|
4663
4663
|
detail: {
|
|
4664
4664
|
type: "chat.stream.chunk",
|
|
4665
|
-
user: this.getBot(
|
|
4665
|
+
user: this.getBot(user),
|
|
4666
4666
|
messageId: messageId,
|
|
4667
4667
|
text: text,
|
|
4668
4668
|
timestamp: +new Date(),
|
|
4669
4669
|
},
|
|
4670
4670
|
});
|
|
4671
4671
|
};
|
|
4672
|
-
MCPChat.prototype.dispatchStreamEnd = function (messageId, fullMessage,
|
|
4672
|
+
MCPChat.prototype.dispatchStreamEnd = function (messageId, fullMessage, options) {
|
|
4673
|
+
if (options === void 0) { options = {}; }
|
|
4674
|
+
var toolCalls = options.toolCalls, user = options.user, preserveChips = options.preserveChips;
|
|
4673
4675
|
log("Stream ended: ".concat(messageId));
|
|
4674
4676
|
this.dispatch({
|
|
4675
4677
|
type: "chat",
|
|
4676
|
-
detail: {
|
|
4677
|
-
type: "chat.stream.end",
|
|
4678
|
-
user: this.getBot(undefined),
|
|
4679
|
-
messageId: messageId,
|
|
4680
|
-
msg: fullMessage,
|
|
4681
|
-
toolCalls: toolCalls,
|
|
4682
|
-
timestamp: +new Date(),
|
|
4683
|
-
},
|
|
4678
|
+
detail: __assign$1(__assign$1({ type: "chat.stream.end", user: this.getBot(user), messageId: messageId, msg: fullMessage, toolCalls: toolCalls }, (preserveChips && { preserveChips: preserveChips })), { timestamp: +new Date() }),
|
|
4684
4679
|
});
|
|
4685
4680
|
};
|
|
4686
4681
|
MCPChat.prototype.dispatchStreamAbort = function (messageId) {
|
|
@@ -4790,6 +4785,19 @@ var MCPChat = /** @class */ (function () {
|
|
|
4790
4785
|
MCPChat.prototype.bufferStreamText = function (text) {
|
|
4791
4786
|
this.streamBuffer += text;
|
|
4792
4787
|
};
|
|
4788
|
+
/**
|
|
4789
|
+
* Dispatches whatever is buffered right now, without waiting on the throttle timer.
|
|
4790
|
+
*
|
|
4791
|
+
* Used when a bubble has to be closed mid-turn (`message_start`): the split has to be
|
|
4792
|
+
* synchronous, because frames arrive in order on one `onmessage` callback and deferring it
|
|
4793
|
+
* to a microtask would let the next `text` frame land in the bubble we are closing.
|
|
4794
|
+
*/
|
|
4795
|
+
MCPChat.prototype.flushStreamBufferSync = function () {
|
|
4796
|
+
if (this.streamBuffer.length > 0 && this.streamingMessageIdForThrottle) {
|
|
4797
|
+
this.dispatchStreamChunk(this.streamingMessageIdForThrottle, this.streamBuffer);
|
|
4798
|
+
this.streamBuffer = "";
|
|
4799
|
+
}
|
|
4800
|
+
};
|
|
4793
4801
|
/**
|
|
4794
4802
|
* Flushes any remaining buffered text and stops the throttle timer.
|
|
4795
4803
|
* Returns a promise that resolves when all buffered text has been dispatched.
|
|
@@ -5070,7 +5078,7 @@ var MCPChat = /** @class */ (function () {
|
|
|
5070
5078
|
*/
|
|
5071
5079
|
MCPChat.prototype.performSSERequest = function (body) {
|
|
5072
5080
|
return __awaiter$1(this, void 0, void 0, function () {
|
|
5073
|
-
var endpoint, messageId,
|
|
5081
|
+
var endpoint, messageId, bubbleId, bubbleUser, bubbleChunks, hasError, httpStatusCode, sseError;
|
|
5074
5082
|
var _this = this;
|
|
5075
5083
|
return __generator$1(this, function (_a) {
|
|
5076
5084
|
endpoint = this.getEndpoint();
|
|
@@ -5083,7 +5091,8 @@ var MCPChat = /** @class */ (function () {
|
|
|
5083
5091
|
this.abortController = new AbortController();
|
|
5084
5092
|
messageId = uuid_1();
|
|
5085
5093
|
this.currentMessageId = messageId;
|
|
5086
|
-
|
|
5094
|
+
bubbleId = messageId;
|
|
5095
|
+
bubbleChunks = [];
|
|
5087
5096
|
hasError = false;
|
|
5088
5097
|
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
5089
5098
|
// WARNING: Do not log headers object - it contains sensitive auth tokens
|
|
@@ -5114,6 +5123,7 @@ var MCPChat = /** @class */ (function () {
|
|
|
5114
5123
|
});
|
|
5115
5124
|
}); },
|
|
5116
5125
|
onmessage: function (event) {
|
|
5126
|
+
var _a;
|
|
5117
5127
|
// Guard: ignore events from stale/aborted requests
|
|
5118
5128
|
if (_this.currentMessageId !== messageId) {
|
|
5119
5129
|
log("[SSE] Ignoring stale event for messageId: ".concat(messageId, ", current: ").concat(_this.currentMessageId));
|
|
@@ -5144,6 +5154,10 @@ var MCPChat = /** @class */ (function () {
|
|
|
5144
5154
|
if (data.isReplay) {
|
|
5145
5155
|
_this.isReplaying = true;
|
|
5146
5156
|
}
|
|
5157
|
+
// A server may name the participant up front.
|
|
5158
|
+
if (data.user) {
|
|
5159
|
+
bubbleUser = data.user;
|
|
5160
|
+
}
|
|
5147
5161
|
// Store identity from server response
|
|
5148
5162
|
if (data.userId || data.sessionId) {
|
|
5149
5163
|
if (data.userId) {
|
|
@@ -5163,13 +5177,13 @@ var MCPChat = /** @class */ (function () {
|
|
|
5163
5177
|
if (data.isReplay) {
|
|
5164
5178
|
// Replay connection — resume into the existing partial
|
|
5165
5179
|
// message instead of creating a duplicate placeholder
|
|
5166
|
-
_this.dispatchStreamResume(
|
|
5180
|
+
_this.dispatchStreamResume(bubbleId);
|
|
5167
5181
|
}
|
|
5168
5182
|
else {
|
|
5169
5183
|
// Normal connection — create new streaming placeholder
|
|
5170
|
-
_this.dispatchStreamStart(
|
|
5184
|
+
_this.dispatchStreamStart(bubbleId, bubbleUser);
|
|
5171
5185
|
}
|
|
5172
|
-
_this.startStreamThrottle(
|
|
5186
|
+
_this.startStreamThrottle(bubbleId);
|
|
5173
5187
|
break;
|
|
5174
5188
|
case "session_expired":
|
|
5175
5189
|
// Session no longer exists on server - need to start fresh
|
|
@@ -5187,14 +5201,40 @@ var MCPChat = /** @class */ (function () {
|
|
|
5187
5201
|
_this.initializeNewSession();
|
|
5188
5202
|
resolve();
|
|
5189
5203
|
break;
|
|
5204
|
+
case "message_start": {
|
|
5205
|
+
// Close the bubble being streamed and open a new one, optionally
|
|
5206
|
+
// under a different participant. This is the only way a turn can
|
|
5207
|
+
// render as more than one message: the reducer creates a fresh
|
|
5208
|
+
// bubble per `chat.stream.start` and finalizes any still-streaming
|
|
5209
|
+
// one, so a server can make a handoff look like someone joining.
|
|
5210
|
+
// Servers that never send this are unaffected.
|
|
5211
|
+
log("[SSE] message_start \u2014 splitting bubble, user: ".concat((_a = data.user) === null || _a === void 0 ? void 0 : _a.displayName));
|
|
5212
|
+
_this.flushStreamBufferSync();
|
|
5213
|
+
_this.dispatchStreamEnd(bubbleId, { text: bubbleChunks.join("") }, {
|
|
5214
|
+
// Same debug-mode capture as `done`, scoped to this bubble:
|
|
5215
|
+
// stream.end replaces a bubble's toolCalls wholesale, so any
|
|
5216
|
+
// left in currentToolCalls would reappear on the next one.
|
|
5217
|
+
toolCalls: (_this.config.debugMode || _this._debugMode) ? __spreadArray$1([], _this.currentToolCalls, true) : undefined,
|
|
5218
|
+
user: bubbleUser,
|
|
5219
|
+
// Chips belong to the turn; its final end sets them.
|
|
5220
|
+
preserveChips: true,
|
|
5221
|
+
});
|
|
5222
|
+
_this.currentToolCalls = [];
|
|
5223
|
+
bubbleId = uuid_1();
|
|
5224
|
+
bubbleChunks = [];
|
|
5225
|
+
bubbleUser = data.user;
|
|
5226
|
+
_this.dispatchStreamStart(bubbleId, bubbleUser);
|
|
5227
|
+
_this.startStreamThrottle(bubbleId);
|
|
5228
|
+
break;
|
|
5229
|
+
}
|
|
5190
5230
|
case "text":
|
|
5191
5231
|
if (data.text) {
|
|
5192
|
-
log("[SSE] Text chunk received (".concat(data.text.length, " chars),
|
|
5193
|
-
|
|
5232
|
+
log("[SSE] Text chunk received (".concat(data.text.length, " chars), chunks in this bubble: ").concat(bubbleChunks.length + 1, ", isReplay: ").concat(data.isReplay));
|
|
5233
|
+
bubbleChunks.push(data.text);
|
|
5194
5234
|
if (data.isReplay || _this.isSleeping) {
|
|
5195
5235
|
// Replayed text or tab hidden — dispatch immediately
|
|
5196
5236
|
// (no throttle timer running in either case)
|
|
5197
|
-
_this.dispatchStreamChunk(
|
|
5237
|
+
_this.dispatchStreamChunk(bubbleId, data.text, bubbleUser);
|
|
5198
5238
|
}
|
|
5199
5239
|
else {
|
|
5200
5240
|
// Live text — buffer for throttled dispatch
|
|
@@ -5218,7 +5258,7 @@ var MCPChat = /** @class */ (function () {
|
|
|
5218
5258
|
_this.currentToolCalls.push(toolCall);
|
|
5219
5259
|
// Always dispatch tool start for user-friendly progress display
|
|
5220
5260
|
_this.dispatchToolStart({
|
|
5221
|
-
messageId:
|
|
5261
|
+
messageId: bubbleId,
|
|
5222
5262
|
toolName: data.toolName,
|
|
5223
5263
|
toolCallId: data.toolCallId,
|
|
5224
5264
|
displayName: data.displayName,
|
|
@@ -5259,7 +5299,7 @@ var MCPChat = /** @class */ (function () {
|
|
|
5259
5299
|
}
|
|
5260
5300
|
// Always dispatch tool end for user-friendly progress display
|
|
5261
5301
|
_this.dispatchToolEnd({
|
|
5262
|
-
messageId:
|
|
5302
|
+
messageId: bubbleId,
|
|
5263
5303
|
toolName: data.toolName,
|
|
5264
5304
|
toolCallId: data.toolCallId,
|
|
5265
5305
|
displayName: data.displayName,
|
|
@@ -5281,8 +5321,10 @@ var MCPChat = /** @class */ (function () {
|
|
|
5281
5321
|
storeIdentity(undefined, data.response.sessionId);
|
|
5282
5322
|
}
|
|
5283
5323
|
// Wait for buffer to flush, then finalize
|
|
5284
|
-
|
|
5285
|
-
|
|
5324
|
+
// The bubble's own text, not the whole turn's — a turn split by
|
|
5325
|
+
// `message_start` has already committed its earlier bubbles.
|
|
5326
|
+
var accumulatedText = bubbleChunks.join("");
|
|
5327
|
+
log("[SSE] Done event received. Chunks in this bubble: ".concat(bubbleChunks.length, ", accumulated text length: ").concat(accumulatedText.length));
|
|
5286
5328
|
log("[SSE] First 100 chars of accumulated: ".concat(accumulatedText.substring(0, 100)));
|
|
5287
5329
|
// Map suggestions to options (chips) format
|
|
5288
5330
|
var suggestions = data.response.suggestions;
|
|
@@ -5298,8 +5340,14 @@ var MCPChat = /** @class */ (function () {
|
|
|
5298
5340
|
if (sources === null || sources === void 0 ? void 0 : sources.length) {
|
|
5299
5341
|
log("[SSE] Sources: ".concat(sources.length, " items"));
|
|
5300
5342
|
}
|
|
5343
|
+
// `response.response` is request-scoped. For an unsplit turn it is
|
|
5344
|
+
// the whole answer, and the fallback serves servers that deliver it
|
|
5345
|
+
// only via `done`. Once `message_start` has fired it would copy every
|
|
5346
|
+
// earlier bubble's text into this one, so a split turn's bubbles
|
|
5347
|
+
// must stream their text as `text` frames.
|
|
5348
|
+
var isSplitTurn = bubbleId !== messageId;
|
|
5301
5349
|
var finalMessage_1 = {
|
|
5302
|
-
text: accumulatedText || data.response.response || "",
|
|
5350
|
+
text: accumulatedText || (isSplitTurn ? "" : data.response.response) || "",
|
|
5303
5351
|
options: options,
|
|
5304
5352
|
sources: sources,
|
|
5305
5353
|
displays: data.response.displays,
|
|
@@ -5307,7 +5355,7 @@ var MCPChat = /** @class */ (function () {
|
|
|
5307
5355
|
// Capture tool calls before flushing (debug mode — config or runtime toggle)
|
|
5308
5356
|
var toolCalls_1 = (_this.config.debugMode || _this._debugMode) ? __spreadArray$1([], _this.currentToolCalls, true) : undefined;
|
|
5309
5357
|
_this.flushStreamBuffer().then(function () {
|
|
5310
|
-
_this.dispatchStreamEnd(
|
|
5358
|
+
_this.dispatchStreamEnd(bubbleId, finalMessage_1, { toolCalls: toolCalls_1, user: bubbleUser });
|
|
5311
5359
|
_this.currentToolCalls = []; // Clear after dispatch
|
|
5312
5360
|
resolve();
|
|
5313
5361
|
});
|
|
@@ -5347,7 +5395,7 @@ var MCPChat = /** @class */ (function () {
|
|
|
5347
5395
|
log("[MCPChat] SSE error during sleep - will request replay on wakeup");
|
|
5348
5396
|
_this.needsReplayOnWakeup = true;
|
|
5349
5397
|
if (_this.streamingMessageIdForThrottle) {
|
|
5350
|
-
_this.dispatchStreamAbort(
|
|
5398
|
+
_this.dispatchStreamAbort(bubbleId);
|
|
5351
5399
|
}
|
|
5352
5400
|
_this.stopStreamThrottle();
|
|
5353
5401
|
}
|
|
@@ -37947,8 +37995,11 @@ function update(state, action) {
|
|
|
37947
37995
|
var finalMsg_1 = endDetail.msg;
|
|
37948
37996
|
// Preserve tool calls from either the action or the existing message
|
|
37949
37997
|
var toolCalls_1 = endDetail.toolCalls || endStreamingChat.toolCalls;
|
|
37950
|
-
// Update chips from message options (same as chat.msg handler)
|
|
37951
|
-
|
|
37998
|
+
// Update chips from message options (same as chat.msg handler) — unless this closes
|
|
37999
|
+
// an intermediate bubble of a split turn, whose chips arrive with the final end.
|
|
38000
|
+
var chips = endDetail.preserveChips
|
|
38001
|
+
? state.chips
|
|
38002
|
+
: ((_w = finalMsg_1 === null || finalMsg_1 === void 0 ? void 0 : finalMsg_1.options) === null || _w === void 0 ? void 0 : _w.length) ? finalMsg_1.options : [];
|
|
37952
38003
|
return __assign$1(__assign$1({}, state), { lastTimestamp: endDetail === null || endDetail === void 0 ? void 0 : endDetail.timestamp, streamingMessageId: undefined, chips: chips, chats: state.chats.map(function (chat, index) {
|
|
37953
38004
|
if (index === streamingIndex_4 && isChatMsgDetail(chat)) {
|
|
37954
38005
|
return __assign$1(__assign$1({}, chat), { msg: finalMsg_1, isStreaming: false, wasStreamed: true, toolCalls: toolCalls_1 });
|