Skip to content

Commit 1013a8a

Browse files
committed
refactor(cli): remove message update batching, use setMessages directly
Remove the 48ms batching mechanism and rely on React 18's automatic batching. Simplify setupStreamingContext and createMessageUpdater APIs.
1 parent 7678809 commit 1013a8a

File tree

1 file changed

+15
-69
lines changed

1 file changed

+15
-69
lines changed

cli/src/hooks/use-send-message.ts

Lines changed: 15 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ import type { SendMessageFn } from '../types/contracts/send-message'
4444
import type { AgentMode } from '../utils/constants'
4545
import type { SendMessageTimerEvent } from '../utils/send-message-timer'
4646
import type { AgentDefinition, MessageContent, RunState } from '@codebuff/sdk'
47-
import type { SetStateAction } from 'react'
4847

4948
// Main chat send hook: orchestrates prep, streaming, and completion.
5049
const yieldToEventLoop = () =>
@@ -205,61 +204,6 @@ export const useSendMessage = ({
205204
[updateActiveSubagents],
206205
)
207206

208-
const pendingMessageUpdatesRef = useRef<
209-
((messages: ChatMessage[]) => ChatMessage[])[]
210-
>([])
211-
const flushTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null)
212-
213-
const flushPendingUpdates = useCallback(() => {
214-
if (flushTimeoutRef.current) {
215-
clearTimeout(flushTimeoutRef.current)
216-
flushTimeoutRef.current = null
217-
}
218-
if (pendingMessageUpdatesRef.current.length === 0) {
219-
return
220-
}
221-
const queuedUpdates = pendingMessageUpdatesRef.current.slice()
222-
pendingMessageUpdatesRef.current = []
223-
224-
setMessages((prev) => {
225-
let next = prev
226-
for (const updater of queuedUpdates) {
227-
next = updater(next)
228-
}
229-
return next
230-
})
231-
}, [setMessages])
232-
233-
const queueMessageUpdate = useCallback(
234-
(updater: (messages: ChatMessage[]) => ChatMessage[]) => {
235-
pendingMessageUpdatesRef.current.push(updater)
236-
if (!flushTimeoutRef.current) {
237-
flushTimeoutRef.current = setTimeout(() => {
238-
flushTimeoutRef.current = null
239-
flushPendingUpdates()
240-
}, 48)
241-
}
242-
},
243-
[flushPendingUpdates],
244-
)
245-
246-
const applyMessageUpdate = useCallback(
247-
(update: SetStateAction<ChatMessage[]>) => {
248-
flushPendingUpdates()
249-
setMessages(update)
250-
},
251-
[flushPendingUpdates, setMessages],
252-
)
253-
254-
useEffect(() => {
255-
return () => {
256-
if (flushTimeoutRef.current) {
257-
clearTimeout(flushTimeoutRef.current)
258-
flushTimeoutRef.current = null
259-
}
260-
flushPendingUpdates()
261-
}
262-
}, [flushPendingUpdates])
263207

264208
function clearMessages() {
265209
previousRunStateRef.current = null
@@ -275,7 +219,7 @@ export const useSendMessage = ({
275219
return prepareUserMessageHelper({
276220
...params,
277221
deps: {
278-
applyMessageUpdate,
222+
setMessages,
279223
lastMessageMode,
280224
setLastMessageMode,
281225
scrollToLatest,
@@ -284,7 +228,7 @@ export const useSendMessage = ({
284228
})
285229
},
286230
[
287-
applyMessageUpdate,
231+
setMessages,
288232
lastMessageMode,
289233
scrollToLatest,
290234
setLastMessageMode,
@@ -298,13 +242,15 @@ export const useSendMessage = ({
298242
setHasReceivedPlanResponse(false)
299243
}
300244

245+
// Initialize timer for elapsed time tracking
301246
const timerController = createSendMessageTimerController({
302247
mainAgentTimer,
303248
onTimerEvent,
304249
agentId,
305250
})
306251
setIsRetrying(false)
307252

253+
// Prepare user message (bash context, images, mode divider)
308254
const { userMessageId, messageContent, bashContextForPrompt } =
309255
await prepareUserMessage({
310256
content,
@@ -313,6 +259,7 @@ export const useSendMessage = ({
313259
attachedImages,
314260
})
315261

262+
// Validate before sending (e.g., agent config checks)
316263
try {
317264
const validationResult = await onBeforeMessageSend()
318265

@@ -347,7 +294,7 @@ export const useSendMessage = ({
347294
'Validation before message send failed with exception',
348295
)
349296

350-
applyMessageUpdate((prev) => [
297+
setMessages((prev) => [
351298
...prev,
352299
createErrorChatMessage(
353300
'⚠️ Agent validation failed unexpectedly. Please try again.',
@@ -359,10 +306,12 @@ export const useSendMessage = ({
359306
return
360307
}
361308

309+
// Reset UI focus state
362310
setFocusedAgentId(null)
363311
setInputFocused(true)
364312
inputRef.current?.focus()
365313

314+
// Get SDK client
366315
const client = await getCodebuffClient()
367316

368317
if (!client) {
@@ -373,19 +322,17 @@ export const useSendMessage = ({
373322
return
374323
}
375324

325+
// Create AI message shell and setup streaming context
376326
const aiMessageId = generateAiMessageId()
377327
const aiMessage = createAiMessageShell(aiMessageId)
378328

379-
applyMessageUpdate((prev) =>
380-
autoCollapsePreviousMessages(prev, aiMessageId),
381-
)
329+
setMessages((prev) => autoCollapsePreviousMessages(prev, aiMessageId))
382330

383331
const { updater, hasReceivedContentRef, abortController } =
384332
setupStreamingContext({
385333
aiMessageId,
386334
timerController,
387-
queueMessageUpdate,
388-
flushPendingUpdates,
335+
setMessages,
389336
streamRefs,
390337
abortControllerRef,
391338
setStreamStatus,
@@ -395,11 +342,12 @@ export const useSendMessage = ({
395342
setIsRetrying,
396343
})
397344
setStreamStatus('waiting')
398-
applyMessageUpdate((prev) => [...prev, aiMessage])
345+
setMessages((prev) => [...prev, aiMessage])
399346
setCanProcessQueue(false)
400347
updateChainInProgress(true)
401348
let actualCredits: number | undefined
402349

350+
// Execute SDK run with streaming handlers
403351
try {
404352
const agentDefinitions = loadAgentDefinitions()
405353
const resolvedAgent = resolveAgent(agentMode, agentId, agentDefinitions)
@@ -471,11 +419,12 @@ export const useSendMessage = ({
471419
handleEvent: createEventHandler(eventContext),
472420
})
473421

422+
// Finalize: persist state and mark complete
474423
previousRunStateRef.current = runState
475424
setRunState(runState)
476425
setIsRetrying(false)
477426

478-
applyMessageUpdate((currentMessages) => {
427+
setMessages((currentMessages) => {
479428
saveChatState(runState, currentMessages)
480429
return currentMessages
481430
})
@@ -512,15 +461,12 @@ export const useSendMessage = ({
512461
addActiveSubagent,
513462
addSessionCredits,
514463
agentId,
515-
applyMessageUpdate,
516-
flushPendingUpdates,
517464
inputRef,
518465
isQueuePausedRef,
519466
mainAgentTimer,
520467
onTimerEvent,
521468
onBeforeMessageSend,
522469
prepareUserMessage,
523-
queueMessageUpdate,
524470
queryClient,
525471
removeActiveSubagent,
526472
resumeQueue,

0 commit comments

Comments
 (0)