From 19fc20173b488b5695e60b58a351b924b595ac6d Mon Sep 17 00:00:00 2001
From: Abdul Rahman <81605929+abdulrahmancodes@users.noreply.github.com>
Date: Mon, 1 Dec 2025 20:01:20 +0530
Subject: [PATCH] fix: lagging issue in ask AI during message streaming
(#16201)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## Changes
### 1. Fixed streaming lag with throttle parameter
**Problem:** The AI chat was experiencing lag during message streaming
because the messages array was being updated too frequently, causing all
messages to re-render too quickly.
**Solution:** Added the `experimental_throttle: 100` parameter to the
`useChat` hook configuration. This throttles message updates during
streaming to prevent excessive re-renders and improve performance.
### 2. Cleaned up useAgentChat hook return values
**Context:** The `useAgentChat` hook primarily returns values from the
underlying `useChat` hook, so there wasn't significant room for
improvement regarding the "umbrella hook" pattern. However, some
unnecessary values were being returned that weren't needed.
**Solution:**
- Removed `input` and `handleInputChange` from the `useAgentChat` hook
return. These weren't needed since input state is already managed
directly via Recoil state (`agentChatInputState`) in components.
---
> [!NOTE]
> Throttle message streaming updates and switch AI chat input management
from context to Recoil; minor scroll behavior tweak.
>
> - **AI Chat performance**:
> - Add `experimental_throttle: 100` to `useChat` in `useAgentChat` to
reduce re-render frequency during streaming.
> - **State management**:
> - Migrate input handling to Recoil via `agentChatInputState`; remove
`input` and `handleInputChange` from `AgentChatContext` and
`useAgentChat` returns.
> - Update `AIChatTab` and `SendMessageButton` to read/write input from
Recoil and adjust hotkeys/disabled state accordingly.
> - **UX behavior**:
> - Remove smooth scroll behavior in `useAgentChatScrollToBottom`.
>
> Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
911b341ea1f7c63a4e1e27667da119d9a2960b78. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).
---------
Co-authored-by: Félix Malfait
---
.../src/modules/ai/components/AIChatTab.tsx | 11 ++++++++---
.../ai/components/internal/SendMessageButton.tsx | 11 +++++++----
.../src/modules/ai/contexts/AgentChatContext.ts | 3 ---
.../twenty-front/src/modules/ai/hooks/useAgentChat.ts | 3 +--
.../modules/ai/hooks/useAgentChatScrollToBottom.ts | 1 -
5 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/packages/twenty-front/src/modules/ai/components/AIChatTab.tsx b/packages/twenty-front/src/modules/ai/components/AIChatTab.tsx
index df76d907b1..c45a668cdd 100644
--- a/packages/twenty-front/src/modules/ai/components/AIChatTab.tsx
+++ b/packages/twenty-front/src/modules/ai/components/AIChatTab.tsx
@@ -19,10 +19,12 @@ import { AI_CHAT_INPUT_ID } from '@/ai/constants/AiChatInputId';
import { AI_CHAT_SCROLL_WRAPPER_ID } from '@/ai/constants/AiChatScrollWrapperId';
import { useAIChatFileUpload } from '@/ai/hooks/useAIChatFileUpload';
import { useAgentChatContextOrThrow } from '@/ai/hooks/useAgentChatContextOrThrow';
+import { agentChatInputState } from '@/ai/states/agentChatInputState';
import { contextStoreCurrentObjectMetadataItemIdComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemIdComponentState';
import { useRecoilComponentValue } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValue';
import { t } from '@lingui/core/macro';
import { useState } from 'react';
+import { useRecoilState } from 'recoil';
import { Button } from 'twenty-ui/input';
const StyledContainer = styled.div<{ isDraggingFile: boolean }>`
@@ -63,9 +65,12 @@ const StyledButtonsContainer = styled.div`
export const AIChatTab = () => {
const [isDraggingFile, setIsDraggingFile] = useState(false);
- const { isLoading, input, handleInputChange, messages, isStreaming, error } =
+ const { isLoading, messages, isStreaming, error } =
useAgentChatContextOrThrow();
+ const [agentChatInput, setAgentChatInput] =
+ useRecoilState(agentChatInputState);
+
const contextStoreCurrentObjectMetadataItemId = useRecoilComponentValue(
contextStoreCurrentObjectMetadataItemIdComponentState,
);
@@ -115,8 +120,8 @@ export const AIChatTab = () => {