From e7762cda978e8b06f00c7af2c48003d23ef1f9c8 Mon Sep 17 00:00:00 2001
From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com>
Date: Fri, 12 Jun 2026 02:42:16 +0530
Subject: [PATCH 1/2] feat(chat): enhance thread component with active thread
handling and improve message loading logic
---
.../new-chat/[[...chat_id]]/page.tsx | 6 +++++-
surfsense_web/components/assistant-ui/thread.tsx | 14 +++++++++-----
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx
index 75cfa4184..5c8d0c3f5 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx
@@ -758,6 +758,9 @@ export default function NewChatPage() {
const loadedMessages = reconcileInterruptedAssistantMessages(messagesResponse.messages).map(
convertToThreadMessage
);
+ if (messages.length > 0 && loadedMessages.length < messages.length) {
+ return;
+ }
setMessages(loadedMessages);
tokenUsageStore.clear();
@@ -778,6 +781,7 @@ export default function NewChatPage() {
}, [
activeThreadId,
isRunning,
+ messages.length,
setMessageDocumentsMap,
threadMessagesQuery.data,
tokenUsageStore,
@@ -2569,7 +2573,7 @@ export default function NewChatPage() {
>
-
+
{isThreadMessagesLoading ? (
diff --git a/surfsense_web/components/assistant-ui/thread.tsx b/surfsense_web/components/assistant-ui/thread.tsx
index 5796109f0..95f118835 100644
--- a/surfsense_web/components/assistant-ui/thread.tsx
+++ b/surfsense_web/components/assistant-ui/thread.tsx
@@ -144,11 +144,15 @@ function getComposerSuggestionAnchorPoint(
};
}
-export const Thread: FC = () => {
- return
;
+interface ThreadProps {
+ hasActiveThread?: boolean;
+}
+
+export const Thread: FC
= ({ hasActiveThread = false }) => {
+ return ;
};
-const ThreadContent: FC = () => {
+const ThreadContent: FC = ({ hasActiveThread = false }) => {
return (
{
>
!thread.isEmpty}>
+ hasActiveThread || !thread.isEmpty}>
}
>
- thread.isEmpty}>
+ !hasActiveThread && thread.isEmpty}>
From e4803d4ed38a2dc30288a6be2e3ba2608b82a415 Mon Sep 17 00:00:00 2001
From: Anish Sarkar <104695310+AnishSarkar22@users.noreply.github.com>
Date: Fri, 12 Jun 2026 03:00:48 +0530
Subject: [PATCH 2/2] chore(dependencies): update @assistant-ui/react and
@assistant-ui/react-markdown to latest versions, adjust peer dependencies,
and modify chat viewport auto-scroll settings
---
.../components/assistant-ui/chat-viewport.tsx | 4 +-
surfsense_web/package.json | 4 +-
surfsense_web/pnpm-lock.yaml | 148 ++++++++++++------
3 files changed, 104 insertions(+), 52 deletions(-)
diff --git a/surfsense_web/components/assistant-ui/chat-viewport.tsx b/surfsense_web/components/assistant-ui/chat-viewport.tsx
index 83308b642..dedada7a5 100644
--- a/surfsense_web/components/assistant-ui/chat-viewport.tsx
+++ b/surfsense_web/components/assistant-ui/chat-viewport.tsx
@@ -27,8 +27,8 @@ export interface ChatViewportProps {
export const ChatViewport: FC = ({ children, footer }) => (
= 0.4'}
- assistant-cloud@0.1.22:
- resolution: {integrity: sha512-AEE9shV+oFrGDv/MRTRERctNKpIYS0n34UpAQXXICiOkSWD6QZnS1ljLqruFko7fJoT5CIWq8dNeJWdzQLTBLg==}
+ assistant-cloud@0.1.31:
+ resolution: {integrity: sha512-YBLc79w2EFD/6YjvcZrperpZ+B3TQ9LZ39AbjfcnbIJiSXYAs8cDH+mgy1GrfJBq47nhGaTVEf7ajv+hk084eA==}
- assistant-stream@0.3.6:
- resolution: {integrity: sha512-NdtSRrQfWCDA/aqQ1xhobf/xnhuMZkhFAw9xzAt5iAoL3ouxVXOowSRN87OL4MYBQEvqtcjw9/CE6YcsXoBtuw==}
+ assistant-stream@0.3.20:
+ resolution: {integrity: sha512-CniC84epmE9JrMSDzlZVWJ13O5rYbjoqEzh0jT+QfsrR07LBls42DMJ60XNxKXm8Hrn6MHSZcxqBUqwXRtoutA==}
+ peerDependencies:
+ ioredis: ^5.10.1
+ redis: ^5.12.1
+ peerDependenciesMeta:
+ ioredis:
+ optional: true
+ redis:
+ optional: true
ast-types-flow@0.0.8:
resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==}
@@ -8122,6 +8130,9 @@ packages:
safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+ safe-content-frame@0.0.20:
+ resolution: {integrity: sha512-saE3fBeGWOsi04PzTUaRi6RsBIjDYrZX4KzgIZUjbq3xQeOKYMcW1DeTb573Zyx1ggCDVJKoD/THchblISwjiQ==}
+
safe-push-apply@1.0.0:
resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==}
engines: {node: '>= 0.4'}
@@ -8894,6 +8905,9 @@ packages:
zod@4.3.6:
resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==}
+ zod@4.4.3:
+ resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==}
+
zustand-x@6.2.1:
resolution: {integrity: sha512-y3nQMQNx3BORY95vpuodJvh/8AqQu++S3q6mJYBSo1J0Q168Sy+FatqER658YESDqv2bwviXcIT3bgl/Ip6M5g==}
peerDependencies:
@@ -8917,6 +8931,24 @@ packages:
use-sync-external-store:
optional: true
+ zustand@5.0.14:
+ resolution: {integrity: sha512-/8tAspM5LMPr28b3fwLYrtdj77ECpfZviaP75CMTnwO8ISyaE4GDIG/9rDDYq/cH9D2Xw2A2RXglLInmVBQB/g==}
+ engines: {node: '>=12.20.0'}
+ peerDependencies:
+ '@types/react': '>=18.0.0'
+ immer: '>=9.0.6'
+ react: '>=18.0.0'
+ use-sync-external-store: '>=1.2.0'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ immer:
+ optional: true
+ react:
+ optional: true
+ use-sync-external-store:
+ optional: true
+
zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
@@ -8968,21 +9000,24 @@ snapshots:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
- '@assistant-ui/core@0.1.7(@assistant-ui/store@0.2.3(@assistant-ui/tap@0.5.3(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4))(@assistant-ui/tap@0.5.3(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(assistant-cloud@0.1.22)(react@19.2.4)(zustand@5.0.11(@types/react@19.2.14)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)))':
+ '@assistant-ui/core@0.2.10(@assistant-ui/store@0.2.13(@assistant-ui/tap@0.5.14(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4))(@assistant-ui/tap@0.5.14(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(assistant-cloud@0.1.31)(react@19.2.4)(zustand@5.0.14(@types/react@19.2.14)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)))':
dependencies:
- '@assistant-ui/store': 0.2.3(@assistant-ui/tap@0.5.3(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4)
- '@assistant-ui/tap': 0.5.3(@types/react@19.2.14)(react@19.2.4)
- assistant-stream: 0.3.6
- nanoid: 5.1.7
+ '@assistant-ui/store': 0.2.13(@assistant-ui/tap@0.5.14(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4)
+ '@assistant-ui/tap': 0.5.14(@types/react@19.2.14)(react@19.2.4)
+ assistant-stream: 0.3.20
+ nanoid: 5.1.11
optionalDependencies:
'@types/react': 19.2.14
- assistant-cloud: 0.1.22
+ assistant-cloud: 0.1.31
react: 19.2.4
- zustand: 5.0.11(@types/react@19.2.14)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))
+ zustand: 5.0.14(@types/react@19.2.14)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))
+ transitivePeerDependencies:
+ - ioredis
+ - redis
- '@assistant-ui/react-markdown@0.12.6(@assistant-ui/react@0.12.19(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(immer@10.2.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
+ '@assistant-ui/react-markdown@0.14.1(@assistant-ui/react@0.14.14(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(immer@10.2.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)':
dependencies:
- '@assistant-ui/react': 0.12.19(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(immer@10.2.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))
+ '@assistant-ui/react': 0.14.14(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(immer@10.2.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))
'@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4)
classnames: 2.5.1
@@ -8995,42 +9030,45 @@ snapshots:
- react-dom
- supports-color
- '@assistant-ui/react@0.12.19(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(immer@10.2.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))':
+ '@assistant-ui/react@0.14.14(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(immer@10.2.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))':
dependencies:
- '@assistant-ui/core': 0.1.7(@assistant-ui/store@0.2.3(@assistant-ui/tap@0.5.3(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4))(@assistant-ui/tap@0.5.3(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(assistant-cloud@0.1.22)(react@19.2.4)(zustand@5.0.11(@types/react@19.2.14)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)))
- '@assistant-ui/store': 0.2.3(@assistant-ui/tap@0.5.3(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4)
- '@assistant-ui/tap': 0.5.3(@types/react@19.2.14)(react@19.2.4)
+ '@assistant-ui/core': 0.2.10(@assistant-ui/store@0.2.13(@assistant-ui/tap@0.5.14(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4))(@assistant-ui/tap@0.5.14(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(assistant-cloud@0.1.31)(react@19.2.4)(zustand@5.0.14(@types/react@19.2.14)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)))
+ '@assistant-ui/store': 0.2.13(@assistant-ui/tap@0.5.14(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4)
+ '@assistant-ui/tap': 0.5.14(@types/react@19.2.14)(react@19.2.4)
'@radix-ui/primitive': 1.1.3
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.4)
'@radix-ui/react-context': 1.1.3(@types/react@19.2.14)(react@19.2.4)
'@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
'@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.4)
'@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.14)(react@19.2.4)
- assistant-cloud: 0.1.22
- assistant-stream: 0.3.6
- nanoid: 5.1.7
+ assistant-cloud: 0.1.31
+ assistant-stream: 0.3.20
+ nanoid: 5.1.11
radix-ui: 1.4.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
react-textarea-autosize: 8.5.9(@types/react@19.2.14)(react@19.2.4)
- zod: 4.3.6
- zustand: 5.0.11(@types/react@19.2.14)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))
+ safe-content-frame: 0.0.20
+ zod: 4.4.3
+ zustand: 5.0.14(@types/react@19.2.14)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))
optionalDependencies:
'@types/react': 19.2.14
'@types/react-dom': 19.2.3(@types/react@19.2.14)
transitivePeerDependencies:
- immer
+ - ioredis
+ - redis
- use-sync-external-store
- '@assistant-ui/store@0.2.3(@assistant-ui/tap@0.5.3(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4)':
+ '@assistant-ui/store@0.2.13(@assistant-ui/tap@0.5.14(@types/react@19.2.14)(react@19.2.4))(@types/react@19.2.14)(react@19.2.4)':
dependencies:
- '@assistant-ui/tap': 0.5.3(@types/react@19.2.14)(react@19.2.4)
+ '@assistant-ui/tap': 0.5.14(@types/react@19.2.14)(react@19.2.4)
react: 19.2.4
use-effect-event: 2.0.3(react@19.2.4)
optionalDependencies:
'@types/react': 19.2.14
- '@assistant-ui/tap@0.5.3(@types/react@19.2.14)(react@19.2.4)':
+ '@assistant-ui/tap@0.5.14(@types/react@19.2.14)(react@19.2.4)':
optionalDependencies:
'@types/react': 19.2.14
react: 19.2.4
@@ -13791,14 +13829,17 @@ snapshots:
get-intrinsic: 1.3.0
is-array-buffer: 3.0.5
- assistant-cloud@0.1.22:
+ assistant-cloud@0.1.31:
dependencies:
- assistant-stream: 0.3.6
+ assistant-stream: 0.3.20
+ transitivePeerDependencies:
+ - ioredis
+ - redis
- assistant-stream@0.3.6:
+ assistant-stream@0.3.20:
dependencies:
'@standard-schema/spec': 1.1.0
- nanoid: 5.1.7
+ nanoid: 5.1.11
secure-json-parse: 4.1.0
ast-types-flow@0.0.8: {}
@@ -17453,6 +17494,8 @@ snapshots:
safe-buffer@5.2.1: {}
+ safe-content-frame@0.0.20: {}
+
safe-push-apply@1.0.0:
dependencies:
es-errors: 1.3.0
@@ -18319,6 +18362,8 @@ snapshots:
zod@4.3.6: {}
+ zod@4.4.3: {}
+
zustand-x@6.2.1(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(scheduler@0.27.0)(zustand@5.0.11(@types/react@19.2.14)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4))):
dependencies:
immer: 10.2.0
@@ -18340,4 +18385,11 @@ snapshots:
react: 19.2.4
use-sync-external-store: 1.6.0(react@19.2.4)
+ zustand@5.0.14(@types/react@19.2.14)(immer@10.2.0)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)):
+ optionalDependencies:
+ '@types/react': 19.2.14
+ immer: 10.2.0
+ react: 19.2.4
+ use-sync-external-store: 1.6.0(react@19.2.4)
+
zwitch@2.0.4: {}