export type AgentInputSubmitResult = "noop" | "queued" | "submitted" | "failed"; export interface AgentInputSubmitActionInput { message: string; attachments: TAttachment[]; hasExternalContent?: boolean; allowEmptySubmit?: boolean; submitBehavior?: "clear" | "preserve-and-lock"; forceSend?: boolean; isAgentRunning: boolean; canSubmit: boolean; queueMessage: (input: { message: string; attachments: TAttachment[] }) => void; submitMessage: (input: { message: string; attachments: TAttachment[] }) => Promise; clearDraft: (lifecycle: "sent" | "abandoned") => void; setUserInput: (text: string) => void; setAttachments: (attachments: TAttachment[]) => void; setSendError: (message: string | null) => void; setIsProcessing: (isProcessing: boolean) => void; onSubmitError?: (error: unknown) => void; } export async function submitAgentInput( input: AgentInputSubmitActionInput, ): Promise { const trimmedMessage = input.message.trim(); const attachments = input.attachments; const shouldClearOnSubmit = input.submitBehavior !== "preserve-and-lock"; if ( !trimmedMessage && attachments.length === 0 && !input.hasExternalContent && !input.allowEmptySubmit ) { return "noop"; } if (!input.canSubmit) { return "noop"; } if (input.isAgentRunning && !input.forceSend) { input.queueMessage({ message: trimmedMessage, attachments }); if (shouldClearOnSubmit) { input.setUserInput(""); input.setAttachments([]); } return "queued"; } // Clear immediately so optimistic stream updates and composer state stay in sync. if (shouldClearOnSubmit) { input.setUserInput(""); input.setAttachments([]); } input.setSendError(null); input.setIsProcessing(true); try { await input.submitMessage({ message: trimmedMessage, attachments }); input.clearDraft("sent"); input.setIsProcessing(false); return "submitted"; } catch (error) { input.onSubmitError?.(error); if (shouldClearOnSubmit) { input.setUserInput(trimmedMessage); input.setAttachments(attachments); } input.setSendError(error instanceof Error ? error.message : "Failed to send message"); input.setIsProcessing(false); return "failed"; } }