@@ -138,7 +138,6 @@ import { reusedRequestId, useMothershipQueueStore } from '@/stores/mothership-qu
138138import type {
139139 QueuedMothershipMessage ,
140140 QueuedSendHandoffSeed ,
141- ScheduledRetry ,
142141} from '@/stores/mothership-queue/types'
143142import type { ChatContext } from '@/stores/panel'
144143import { useTableViewPinStore } from '@/stores/table/view-pin/store'
@@ -153,6 +152,7 @@ import type {
153152 MothershipResource ,
154153 MothershipResourceType ,
155154 QueuedMessage ,
155+ SendPayload ,
156156 ToolCallInfo ,
157157} from '../types'
158158import {
@@ -178,6 +178,7 @@ import {
178178} from './send-handoff'
179179import {
180180 requeuedFields ,
181+ sendPayload ,
181182 sendRetry ,
182183 type WithdrawalReason ,
183184 withoutRequeueFields ,
@@ -277,14 +278,8 @@ interface PendingChatAdmission {
277278}
278279
279280/** A send an unmount cleanup withdrew, as handed to the next chat surface. */
280- interface WithdrawnSend {
281- content : string
282- fileAttachments ?: FileAttachmentForApi [ ]
283- contexts ?: ChatContext [ ]
281+ interface WithdrawnSend extends SendPayload {
284282 userMessageId : string
285- requestMode ?: ChatRequestMode
286- assistantSearch ?: WorkspaceSearchFilters
287- assistantSearchLevel ?: AssistantSearchLevel
288283}
289284
290285export interface UseChatReturn {
@@ -3391,15 +3386,7 @@ export function useChat(
33913386 )
33923387
33933388 const createQueuedMessage = useCallback (
3394- (
3395- message : string ,
3396- fileAttachments ?: FileAttachmentForApi [ ] ,
3397- contexts ?: ChatContext [ ] ,
3398- resumeUserMessageId ?: string ,
3399- requestMode ?: ChatRequestMode ,
3400- assistantSearch ?: WorkspaceSearchFilters ,
3401- assistantSearchLevel ?: AssistantSearchLevel
3402- ) : QueuedMothershipMessage => {
3389+ ( payload : SendPayload , resumeUserMessageId ?: string ) : QueuedMothershipMessage => {
34033390 const id = generateId ( )
34043391 const handoffChatId = selectedChatIdRef . current ?? chatIdRef . current
34053392 const cachedActiveStreamId = handoffChatId
@@ -3415,13 +3402,8 @@ export function useChat(
34153402
34163403 return {
34173404 id,
3418- content : message ,
3419- fileAttachments,
3420- contexts,
3405+ ...sendPayload ( payload ) ,
34213406 ...( resumeUserMessageId ? { resumeUserMessageId } : { } ) ,
3422- ...( requestMode ? { requestMode } : { } ) ,
3423- ...( assistantSearch ? { assistantSearch } : { } ) ,
3424- ...( assistantSearchLevel !== undefined ? { assistantSearchLevel } : { } ) ,
34253407 ...( supersededStreamId || handoffChatId
34263408 ? {
34273409 queuedSendHandoff : {
@@ -3610,9 +3592,18 @@ export function useChat(
36103592 if ( ! admittedThisSend || latestChoice !== effortChoice )
36113593 saveMothershipChatEffort ( queryClient , chatId , latestChoice )
36123594 }
3595+ const payload = sendPayload ( {
3596+ content : message ,
3597+ fileAttachments,
3598+ contexts,
3599+ requestMode : options ?. requestMode ,
3600+ assistantSearch : options ?. assistantSearch ,
3601+ assistantSearchLevel : options ?. assistantSearchLevel ,
3602+ } )
36133603 const writeQueuedSendHandoff = ( chatId ?: string ) => {
36143604 if ( ! queuedSendHandoff ) return
36153605 if ( ! chatId && ! queuedSendHandoff . supersededStreamId ) return
3606+ const { content, ...payloadFields } = payload
36163607 writeQueuedSendHandoffState ( {
36173608 id : queuedSendHandoff . id ,
36183609 ...( chatId ? { chatId } : { } ) ,
@@ -3622,14 +3613,8 @@ export function useChat(
36223613 ...( queuedSendHandoff . stopRequired ? { stopRequired : true } : { } ) ,
36233614 admissionUnknown,
36243615 userMessageId,
3625- message,
3626- ...( fileAttachments ? { fileAttachments } : { } ) ,
3627- ...( contexts ? { contexts } : { } ) ,
3628- ...( options ?. requestMode ? { requestMode : options . requestMode } : { } ) ,
3629- ...( options ?. assistantSearch ? { assistantSearch : options . assistantSearch } : { } ) ,
3630- ...( options ?. assistantSearchLevel !== undefined
3631- ? { assistantSearchLevel : options ?. assistantSearchLevel }
3632- : { } ) ,
3616+ message : content ,
3617+ ...payloadFields ,
36333618 requestedAt : Date . now ( ) ,
36343619 } )
36353620 }
@@ -3802,17 +3787,7 @@ export function useChat(
38023787 settled : new Promise ( ( resolve ) => {
38033788 resolveAdmission = resolve
38043789 } ) ,
3805- send : {
3806- content : message ,
3807- userMessageId,
3808- ...( fileAttachments ? { fileAttachments } : { } ) ,
3809- ...( contexts ? { contexts } : { } ) ,
3810- ...( options ?. requestMode ? { requestMode : options . requestMode } : { } ) ,
3811- ...( options ?. assistantSearch ? { assistantSearch : options . assistantSearch } : { } ) ,
3812- ...( options ?. assistantSearchLevel !== undefined
3813- ? { assistantSearchLevel : options . assistantSearchLevel }
3814- : { } ) ,
3815- } ,
3790+ send : { ...payload , userMessageId } ,
38163791 }
38173792 pendingChatAdmissionRef . current = admission
38183793 }
@@ -4297,31 +4272,11 @@ export function useChat(
42974272 ( send : WithdrawnSend ) => {
42984273 /** The unmount already queued it ahead of its follow-ups; see the unmount cleanup. */
42994274 if ( withdrawnHeldAtUnmountRef . current ?. delete ( send . userMessageId ) ) return
4300- if (
4301- sendMothershipMessage (
4302- send . content ,
4303- send . contexts ,
4304- send . fileAttachments ,
4305- send . userMessageId ,
4306- send . requestMode ,
4307- send . assistantSearch ,
4308- send . assistantSearchLevel
4309- )
4310- ) {
4311- return
4312- }
4275+ const payload = sendPayload ( send )
4276+ if ( sendMothershipMessage ( payload , send . userMessageId ) ) return
4277+ const { content, ...payloadFields } = payload
43134278 MothershipHandoffStorage . store (
4314- {
4315- message : send . content ,
4316- ...( send . contexts ?. length ? { contexts : send . contexts } : { } ) ,
4317- ...( send . fileAttachments ?. length ? { fileAttachments : send . fileAttachments } : { } ) ,
4318- resumeUserMessageId : send . userMessageId ,
4319- ...( send . requestMode ? { requestMode : send . requestMode } : { } ) ,
4320- ...( send . assistantSearch ? { assistantSearch : send . assistantSearch } : { } ) ,
4321- ...( send . assistantSearchLevel !== undefined
4322- ? { assistantSearchLevel : send . assistantSearchLevel }
4323- : { } ) ,
4324- } ,
4279+ { message : content , ...payloadFields , resumeUserMessageId : send . userMessageId } ,
43254280 organizationId ? { organizationId } : workspaceId !
43264281 )
43274282 } ,
@@ -4365,6 +4320,14 @@ export function useChat(
43654320 }
43664321
43674322 options = { ...options , requestMode : options ?. requestMode ?? requestModeRef . current }
4323+ const payload = sendPayload ( {
4324+ content : message ,
4325+ fileAttachments,
4326+ contexts,
4327+ requestMode : options . requestMode ,
4328+ assistantSearch : options . assistantSearch ,
4329+ assistantSearchLevel : options . assistantSearchLevel ,
4330+ } )
43684331
43694332 // An in-flight send drains the queue from `finalize`; a pending stop kicks
43704333 // the dispatcher itself, since nothing else will once the stop settles.
@@ -4380,18 +4343,7 @@ export function useChat(
43804343 queuedAheadCount
43814344 )
43824345 ) {
4383- queueStore . enqueue (
4384- activeChatKey ,
4385- createQueuedMessage (
4386- message ,
4387- fileAttachments ,
4388- contexts ,
4389- options ?. resumeUserMessageId ,
4390- options ?. requestMode ,
4391- options ?. assistantSearch ,
4392- options ?. assistantSearchLevel
4393- )
4394- )
4346+ queueStore . enqueue ( activeChatKey , createQueuedMessage ( payload , options . resumeUserMessageId ) )
43954347 if ( pendingStopPromiseRef . current || ( queuedAheadCount > 0 && ! sendingRef . current ) ) {
43964348 void enqueueQueueDispatchRef . current ( { type : 'send_head' } )
43974349 }
@@ -4407,34 +4359,17 @@ export function useChat(
44074359 whichever one they opened next. Only a send an unmount withdrew from a
44084360 chatless surface, whose key dies with the mount, goes to the
44094361 cross-surface lanes. */
4410- const withdrawn = {
4411- content : message ,
4412- fileAttachments,
4413- contexts,
4414- userMessageId : result . userMessageId ,
4415- ...( options ?. requestMode ? { requestMode : options . requestMode } : { } ) ,
4416- ...( options ?. assistantSearch ? { assistantSearch : options . assistantSearch } : { } ) ,
4417- ...( options ?. assistantSearchLevel !== undefined
4418- ? { assistantSearchLevel : options ?. assistantSearchLevel }
4419- : { } ) ,
4420- }
44214362 const chatless = activeChatKey . startsWith ( PENDING_CHAT_KEY_PREFIX )
44224363 if ( result . reason === 'withdrawn' && chatless ) {
4423- handOffWithdrawnSend ( withdrawn )
4364+ handOffWithdrawnSend ( { ... payload , userMessageId : result . userMessageId } )
44244365 return
44254366 }
44264367 /* Back at the head: a direct send only goes out with nothing queued ahead of
4427- it, so anything queued while its POST was out was written after it. */
4368+ it, so anything queued while its POST was out was written after it. The one
4369+ exception is a held send adopted from a dead mount of this surface in that
4370+ window, which can be older; it lands behind this one. */
44284371 useMothershipQueueStore . getState ( ) . insertAt ( activeChatKey , 0 , {
4429- ...createQueuedMessage (
4430- message ,
4431- fileAttachments ,
4432- contexts ,
4433- result . userMessageId ,
4434- options ?. requestMode ,
4435- options ?. assistantSearch ,
4436- options ?. assistantSearchLevel
4437- ) ,
4372+ ...createQueuedMessage ( payload , result . userMessageId ) ,
44384373 ...requeuedFields ( result . reason , 0 , chatless ? heldSendSurface : undefined ) ,
44394374 admissionUnknown : result . admissionUnknown ,
44404375 } )
@@ -4634,14 +4569,7 @@ export function useChat(
46344569 /** Recovered sends join the queue so dispatch, failure and retry have one owner. */
46354570 useMothershipQueueStore . getState ( ) . insertAt ( chatHistory . id , 0 , {
46364571 id : handoff . id ,
4637- content : handoff . message ,
4638- fileAttachments : handoff . fileAttachments ,
4639- contexts : handoff . contexts ,
4640- ...( handoff . requestMode ? { requestMode : handoff . requestMode } : { } ) ,
4641- ...( handoff . assistantSearch ? { assistantSearch : handoff . assistantSearch } : { } ) ,
4642- ...( handoff . assistantSearchLevel !== undefined
4643- ? { assistantSearchLevel : handoff . assistantSearchLevel }
4644- : { } ) ,
4572+ ...sendPayload ( { ...handoff , content : handoff . message } ) ,
46454573 queuedSendHandoff : {
46464574 id : handoff . id ,
46474575 chatId : handoff . chatId ,
@@ -5037,14 +4965,7 @@ export function useChat(
50374965 if ( withdrawn ?. reason === 'withdrawn' && chatless ) {
50384966 clearQueuedSendHandoffState ( msg . id )
50394967 handOffWithdrawnSend ( {
5040- content : dispatched . content ,
5041- fileAttachments : dispatched . fileAttachments ,
5042- contexts : dispatched . contexts ,
5043- ...( dispatched . requestMode ? { requestMode : dispatched . requestMode } : { } ) ,
5044- ...( dispatched . assistantSearch ? { assistantSearch : dispatched . assistantSearch } : { } ) ,
5045- ...( dispatched . assistantSearchLevel !== undefined
5046- ? { assistantSearchLevel : dispatched . assistantSearchLevel }
5047- : { } ) ,
4968+ ...sendPayload ( dispatched ) ,
50484969 userMessageId : withdrawn . userMessageId ,
50494970 } )
50504971 return
@@ -5083,27 +5004,19 @@ export function useChat(
50835004 dispatched = liveMsg
50845005 activeQueuedSendHandoff = options . queuedSendHandoff ?? liveMsg . queuedSendHandoff
50855006
5086- const sendResult = await startSendMessage (
5087- liveMsg . content ,
5088- liveMsg . fileAttachments ,
5089- liveMsg . contexts ,
5090- {
5091- pendingStop : options . pendingStop ,
5092- onOptimisticSendApplied : removeQueuedMessage ,
5093- queuedSendHandoff : activeQueuedSendHandoff ,
5094- ...( liveMsg . resumeUserMessageId
5095- ? { resumeUserMessageId : liveMsg . resumeUserMessageId }
5096- : { } ) ,
5097- ...( liveMsg . admissionUnknown !== undefined
5098- ? { admissionUnknown : liveMsg . admissionUnknown }
5099- : { } ) ,
5100- ...( liveMsg . requestMode ? { requestMode : liveMsg . requestMode } : { } ) ,
5101- ...( liveMsg . assistantSearch ? { assistantSearch : liveMsg . assistantSearch } : { } ) ,
5102- ...( liveMsg . assistantSearchLevel !== undefined
5103- ? { assistantSearchLevel : liveMsg . assistantSearchLevel }
5104- : { } ) ,
5105- }
5106- )
5007+ const { content, fileAttachments, contexts, ...sendOptions } = sendPayload ( liveMsg )
5008+ const sendResult = await startSendMessage ( content , fileAttachments , contexts , {
5009+ ...sendOptions ,
5010+ pendingStop : options . pendingStop ,
5011+ onOptimisticSendApplied : removeQueuedMessage ,
5012+ queuedSendHandoff : activeQueuedSendHandoff ,
5013+ ...( liveMsg . resumeUserMessageId
5014+ ? { resumeUserMessageId : liveMsg . resumeUserMessageId }
5015+ : { } ) ,
5016+ ...( liveMsg . admissionUnknown !== undefined
5017+ ? { admissionUnknown : liveMsg . admissionUnknown }
5018+ : { } ) ,
5019+ } )
51075020
51085021 if ( sendResult !== true ) {
51095022 restoreQueuedMessage (
@@ -5400,16 +5313,9 @@ export function useChat(
54005313 const { send } = withdrawing
54015314 queueStore . insertAt ( deadKey , 0 , {
54025315 id : generateId ( ) ,
5403- content : send . content ,
5316+ ... sendPayload ( send ) ,
54045317 resumeUserMessageId : send . userMessageId ,
54055318 admissionUnknown : true ,
5406- ...( send . fileAttachments ? { fileAttachments : send . fileAttachments } : { } ) ,
5407- ...( send . contexts ? { contexts : send . contexts } : { } ) ,
5408- ...( send . requestMode ? { requestMode : send . requestMode } : { } ) ,
5409- ...( send . assistantSearch ? { assistantSearch : send . assistantSearch } : { } ) ,
5410- ...( send . assistantSearchLevel !== undefined
5411- ? { assistantSearchLevel : send . assistantSearchLevel }
5412- : { } ) ,
54135319 } )
54145320 withdrawnHeldAtUnmountRef . current ??= new Set ( )
54155321 withdrawnHeldAtUnmountRef . current . add ( send . userMessageId )
0 commit comments