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: {}