@hivegpt/hiveai-angular 0.0.611 → 0.0.613
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/esm2020/lib/components/chat-drawer/chat-drawer.component.mjs +47 -17
- package/fesm2015/hivegpt-hiveai-angular.mjs +50 -19
- package/fesm2015/hivegpt-hiveai-angular.mjs.map +1 -1
- package/fesm2020/hivegpt-hiveai-angular.mjs +46 -16
- package/fesm2020/hivegpt-hiveai-angular.mjs.map +1 -1
- package/lib/components/chat-drawer/chat-drawer.component.d.ts +9 -1
- package/lib/components/chat-drawer/chat-drawer.component.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1644,6 +1644,8 @@ class ChatDrawerComponent {
|
|
|
1644
1644
|
/** Guards against our own programmatic scrolls triggering the userHasScrolled detection. */
|
|
1645
1645
|
this.isProgrammaticScroll = false;
|
|
1646
1646
|
this.scrollListenerTimer = null;
|
|
1647
|
+
/** Throttle timer for streaming chunk scroll — prevents firing on every chunk. */
|
|
1648
|
+
this.chunkScrollRAF = null;
|
|
1647
1649
|
/** Connections list from host (e.g. from store selectConnectionsList). Each item has userId. When set, used for Connect/Request Sent/Disconnect button state. */
|
|
1648
1650
|
this.connectionsList = [];
|
|
1649
1651
|
/** Pending sent request user IDs from host (e.g. from store selectPendingConnectionsSentList). When set, used for Request Sent state. */
|
|
@@ -3426,7 +3428,8 @@ class ChatDrawerComponent {
|
|
|
3426
3428
|
var _a, _b, _c, _d;
|
|
3427
3429
|
const lastItem = this.chatLog[this.chatLog.length - 1];
|
|
3428
3430
|
if (done) {
|
|
3429
|
-
|
|
3431
|
+
// Final pass with the complete raw text (aiResponse) for a clean render
|
|
3432
|
+
lastItem.message = this.processMessageForDisplay(this.aiResponse);
|
|
3430
3433
|
this.chatLog.pop();
|
|
3431
3434
|
this.chatLog.push(lastItem);
|
|
3432
3435
|
if (allSuggestions === null || allSuggestions === void 0 ? void 0 : allSuggestions.length) {
|
|
@@ -3455,7 +3458,7 @@ class ChatDrawerComponent {
|
|
|
3455
3458
|
allSuggestions.push(match === null || match === void 0 ? void 0 : match.replace(/<\/?sug>/g, ''));
|
|
3456
3459
|
});
|
|
3457
3460
|
}
|
|
3458
|
-
lastItem.message = this.aiResponse;
|
|
3461
|
+
lastItem.message = this.processMessageForDisplay(this.aiResponse);
|
|
3459
3462
|
this.cdr.markForCheck();
|
|
3460
3463
|
}
|
|
3461
3464
|
else {
|
|
@@ -3743,7 +3746,7 @@ class ChatDrawerComponent {
|
|
|
3743
3746
|
}
|
|
3744
3747
|
this.cdr.detectChanges();
|
|
3745
3748
|
}
|
|
3746
|
-
scrollToBottom(force = false
|
|
3749
|
+
scrollToBottom(force = false) {
|
|
3747
3750
|
var _a;
|
|
3748
3751
|
if (!force && !this.autoScrollOnNewMessage) {
|
|
3749
3752
|
return;
|
|
@@ -3757,10 +3760,37 @@ class ChatDrawerComponent {
|
|
|
3757
3760
|
this.isProgrammaticScroll = true;
|
|
3758
3761
|
el.scrollTo({
|
|
3759
3762
|
top: el.scrollHeight,
|
|
3760
|
-
behavior:
|
|
3763
|
+
behavior: 'smooth',
|
|
3764
|
+
});
|
|
3765
|
+
setTimeout(() => { this.isProgrammaticScroll = false; }, 400);
|
|
3766
|
+
}
|
|
3767
|
+
/**
|
|
3768
|
+
* Lightweight scroll-to-bottom used during streaming chunks.
|
|
3769
|
+
* Coalesces via requestAnimationFrame so we get at most one smooth
|
|
3770
|
+
* nudge per paint frame, no matter how fast chunks arrive.
|
|
3771
|
+
*/
|
|
3772
|
+
scrollToBottomStreaming() {
|
|
3773
|
+
if (this.userHasScrolled)
|
|
3774
|
+
return;
|
|
3775
|
+
if (this.chunkScrollRAF !== null)
|
|
3776
|
+
return; // already queued
|
|
3777
|
+
this.chunkScrollRAF = requestAnimationFrame(() => {
|
|
3778
|
+
var _a;
|
|
3779
|
+
this.chunkScrollRAF = null;
|
|
3780
|
+
if (this.userHasScrolled)
|
|
3781
|
+
return;
|
|
3782
|
+
const el = (_a = this.chatMain) === null || _a === void 0 ? void 0 : _a.nativeElement;
|
|
3783
|
+
if (!el)
|
|
3784
|
+
return;
|
|
3785
|
+
// Small gap check: only scroll if we're within a reasonable distance from the bottom
|
|
3786
|
+
const gap = el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
3787
|
+
if (gap <= 0)
|
|
3788
|
+
return; // already at bottom
|
|
3789
|
+
this.isProgrammaticScroll = true;
|
|
3790
|
+
// Use a quick smooth nudge rather than instant jump
|
|
3791
|
+
el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' });
|
|
3792
|
+
setTimeout(() => { this.isProgrammaticScroll = false; }, 300);
|
|
3761
3793
|
});
|
|
3762
|
-
// Release the guard after the smooth scroll settles
|
|
3763
|
-
setTimeout(() => { this.isProgrammaticScroll = false; }, smooth ? 400 : 50);
|
|
3764
3794
|
}
|
|
3765
3795
|
/** Scrolls the chat container so the top of the AI message with the given id is visible. */
|
|
3766
3796
|
scrollToAiMessage(messageId) {
|
|
@@ -4650,7 +4680,7 @@ class ChatDrawerComponent {
|
|
|
4650
4680
|
return false;
|
|
4651
4681
|
}
|
|
4652
4682
|
handleAskWebSocketMessage(rawMessage) {
|
|
4653
|
-
var _a, _b, _c, _d, _e;
|
|
4683
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4654
4684
|
if (!rawMessage)
|
|
4655
4685
|
return;
|
|
4656
4686
|
let parsed = null;
|
|
@@ -4672,7 +4702,9 @@ class ChatDrawerComponent {
|
|
|
4672
4702
|
return;
|
|
4673
4703
|
const isNewAiMessage = !this.chatLog.find((p) => p._id == messageId);
|
|
4674
4704
|
const currentChatMessage = this.upsertAiChatMessage(messageId);
|
|
4675
|
-
|
|
4705
|
+
// Accumulate raw text and render markdown in real-time
|
|
4706
|
+
currentChatMessage.rawMessage = `${currentChatMessage.rawMessage || ''}${(payload === null || payload === void 0 ? void 0 : payload.text) || ''}`;
|
|
4707
|
+
currentChatMessage.message = this.processMessageForDisplay(currentChatMessage.rawMessage);
|
|
4676
4708
|
if (isNewAiMessage) {
|
|
4677
4709
|
// First chunk: hide Thinking indicator and scroll to the message start
|
|
4678
4710
|
this.isChatingWithAi = false;
|
|
@@ -4681,7 +4713,7 @@ class ChatDrawerComponent {
|
|
|
4681
4713
|
}
|
|
4682
4714
|
else {
|
|
4683
4715
|
this.cdr.markForCheck();
|
|
4684
|
-
|
|
4716
|
+
this.scrollToBottomStreaming();
|
|
4685
4717
|
}
|
|
4686
4718
|
break;
|
|
4687
4719
|
}
|
|
@@ -4692,19 +4724,21 @@ class ChatDrawerComponent {
|
|
|
4692
4724
|
break;
|
|
4693
4725
|
}
|
|
4694
4726
|
const currentChatMessage = this.upsertAiChatMessage(messageId);
|
|
4695
|
-
const finalAnswer = (_c = (_b = payload === null || payload === void 0 ? void 0 : payload.text) !== null && _b !== void 0 ? _b : currentChatMessage.
|
|
4727
|
+
const finalAnswer = (_d = (_c = (_b = payload === null || payload === void 0 ? void 0 : payload.text) !== null && _b !== void 0 ? _b : currentChatMessage.rawMessage) !== null && _c !== void 0 ? _c : currentChatMessage.message) !== null && _d !== void 0 ? _d : '';
|
|
4696
4728
|
const hasCardResponse = this.applyToolResultCardMessage(currentChatMessage, messageId, finalAnswer, payload === null || payload === void 0 ? void 0 : payload.tool_results);
|
|
4697
4729
|
if (!hasCardResponse) {
|
|
4698
4730
|
currentChatMessage.type = 'ai';
|
|
4699
4731
|
currentChatMessage.message = this.processMessageForDisplay(finalAnswer);
|
|
4700
4732
|
}
|
|
4733
|
+
// Clean up raw accumulator
|
|
4734
|
+
delete currentChatMessage.rawMessage;
|
|
4701
4735
|
if (Array.isArray(payload === null || payload === void 0 ? void 0 : payload.suggestions)) {
|
|
4702
4736
|
currentChatMessage.relatedListItems = payload.suggestions;
|
|
4703
4737
|
}
|
|
4704
4738
|
if (Array.isArray(payload === null || payload === void 0 ? void 0 : payload.web_results)) {
|
|
4705
4739
|
currentChatMessage.sourcesList = payload.web_results;
|
|
4706
|
-
currentChatMessage.displayedSources = (
|
|
4707
|
-
currentChatMessage.remainingSources = (
|
|
4740
|
+
currentChatMessage.displayedSources = (_e = payload.web_results) === null || _e === void 0 ? void 0 : _e.slice(0, 3);
|
|
4741
|
+
currentChatMessage.remainingSources = (_f = payload.web_results) === null || _f === void 0 ? void 0 : _f.slice(3);
|
|
4708
4742
|
}
|
|
4709
4743
|
if (payload === null || payload === void 0 ? void 0 : payload.tool_results) {
|
|
4710
4744
|
currentChatMessage.toolResults = payload.tool_results;
|
|
@@ -4712,13 +4746,10 @@ class ChatDrawerComponent {
|
|
|
4712
4746
|
this.showFeedBackIconsIndex = this.chatLog.length - 1;
|
|
4713
4747
|
this.activeAskMessageId = '';
|
|
4714
4748
|
this.isChatingWithAi = false;
|
|
4715
|
-
// For card responses (tool results), scroll
|
|
4716
|
-
//
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
setTimeout(() => this.scrollToAiMessage(messageId), 30);
|
|
4720
|
-
}
|
|
4721
|
-
else {
|
|
4749
|
+
// For card responses (tool results), don't scroll at all —
|
|
4750
|
+
// user is already viewing the AI text from the streaming phase,
|
|
4751
|
+
// cards render below and the user can scroll down to see them.
|
|
4752
|
+
if (!hasCardResponse) {
|
|
4722
4753
|
this.scrollToBottom();
|
|
4723
4754
|
}
|
|
4724
4755
|
this.focusOnTextarea();
|