Organize composer into its own module
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
export type AgentInputSubmitResult = "noop" | "queued" | "submitted" | "failed";
|
||||
|
||||
export interface AgentInputSubmitActionInput<TAttachment> {
|
||||
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<void>;
|
||||
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<TAttachment>(
|
||||
input: AgentInputSubmitActionInput<TAttachment>,
|
||||
): Promise<AgentInputSubmitResult> {
|
||||
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";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user