@@ -5,6 +5,8 @@ import { shouldHideAgent } from '../utils/constants'
55import { formatTimestamp } from '../utils/helpers'
66import { loadAgentDefinitions } from '../utils/load-agent-definitions'
77import { logger } from '../utils/logger'
8+ import { getLoadedAgentsData } from '../utils/local-agent-registry'
9+ import { createValidationErrorBlocks } from '../utils/create-validation-error-blocks'
810
911import type { ChatMessage , ContentBlock } from '../chat'
1012import type { AgentDefinition , ToolName } from '@codebuff/sdk'
@@ -97,8 +99,9 @@ interface UseSendMessageOptions {
9799 setCanProcessQueue : ( can : boolean ) => void
98100 abortControllerRef : React . MutableRefObject < AbortController | null >
99101 agentId ?: string
100- onBeforeMessageSend ?: ( ) => Promise < boolean >
102+ onBeforeMessageSend ?: ( ) => Promise < { success : boolean ; errors : Array < { id : string ; message : string } > } >
101103 setMainAgentStreamStartTime : ( time : number | null ) => void
104+ scrollToLatest : ( ) => void
102105}
103106
104107export const useSendMessage = ( {
@@ -121,6 +124,7 @@ export const useSendMessage = ({
121124 agentId,
122125 onBeforeMessageSend,
123126 setMainAgentStreamStartTime,
127+ scrollToLatest,
124128} : UseSendMessageOptions ) => {
125129 const previousRunStateRef = useRef < any > ( null )
126130 const spawnAgentsMapRef = useRef <
@@ -247,19 +251,49 @@ export const useSendMessage = ({
247251
248252 const sendMessage = useCallback (
249253 async ( content : string , params : { agentMode : 'FAST' | 'MAX' } ) => {
254+ const { agentMode } = params
255+ const timestamp = formatTimestamp ( )
256+
257+ // Add user message to UI first
258+ const userMessage : ChatMessage = {
259+ id : `user-${ Date . now ( ) } ` ,
260+ variant : 'user' ,
261+ content,
262+ timestamp,
263+ }
264+
265+ applyMessageUpdate ( ( prev ) => {
266+ const newMessages = [ ...prev , userMessage ]
267+ if ( newMessages . length > 100 ) {
268+ return newMessages . slice ( - 100 )
269+ }
270+ return newMessages
271+ } )
272+ await yieldToEventLoop ( )
273+
274+ // Scroll to bottom after user message appears
275+ setTimeout ( ( ) => scrollToLatest ( ) , 0 )
276+
250277 // Validate agents before sending message (blocking)
251278 if ( onBeforeMessageSend ) {
252279 try {
253- const validationPassed = await onBeforeMessageSend ( )
280+ const validationResult = await onBeforeMessageSend ( )
254281
255- if ( ! validationPassed ) {
282+ if ( ! validationResult . success ) {
256283 logger . warn ( 'Message send blocked due to agent validation errors' )
257284
258- // Add an error message to the chat
285+ // Create validation error blocks with clickable file paths
286+ const loadedAgentsData = getLoadedAgentsData ( )
287+ const errorBlocks = createValidationErrorBlocks ( {
288+ errors : validationResult . errors ,
289+ loadedAgentsData,
290+ } )
291+
259292 const errorMessage : ChatMessage = {
260293 id : `error-${ Date . now ( ) } ` ,
261294 variant : 'error' ,
262- content : 'Cannot send message: Please fix agent validation errors first. Check the validation errors displayed above.' ,
295+ content : '' ,
296+ blocks : errorBlocks ,
263297 timestamp : formatTimestamp ( ) ,
264298 }
265299
@@ -271,11 +305,10 @@ export const useSendMessage = ({
271305 } catch ( error ) {
272306 logger . error ( { error } , 'Validation before message send failed with exception' )
273307
274- // Add an error message to the chat
275308 const errorMessage : ChatMessage = {
276309 id : `error-${ Date . now ( ) } ` ,
277310 variant : 'error' ,
278- content : 'Cannot send message: Agent validation failed unexpectedly.' ,
311+ content : '⚠️ Agent validation failed unexpectedly. Please try again .' ,
279312 timestamp : formatTimestamp ( ) ,
280313 }
281314
@@ -286,24 +319,6 @@ export const useSendMessage = ({
286319 }
287320 }
288321
289- const { agentMode } = params
290- const timestamp = formatTimestamp ( )
291- const userMessage : ChatMessage = {
292- id : `user-${ Date . now ( ) } ` ,
293- variant : 'user' ,
294- content,
295- timestamp,
296- }
297-
298- applyMessageUpdate ( ( prev ) => {
299- const newMessages = [ ...prev , userMessage ]
300- if ( newMessages . length > 100 ) {
301- return newMessages . slice ( - 100 )
302- }
303- return newMessages
304- } )
305- await yieldToEventLoop ( )
306-
307322 setFocusedAgentId ( null )
308323 setInputFocused ( true )
309324 inputRef . current ?. focus ( )
@@ -1414,6 +1429,7 @@ export const useSendMessage = ({
14141429 removeActiveSubagent ,
14151430 onBeforeMessageSend ,
14161431 setMainAgentStreamStartTime ,
1432+ scrollToLatest ,
14171433 ] ,
14181434 )
14191435
0 commit comments