| 1 | import type { QueuedThreadMessage } from "./thread-outbox-model"; |
| 2 | import { scopedThreadKey } from "../lib/scopedEntities"; |
| 3 | import { restoredNewTaskDraftKey } from "./new-task-draft-key"; |
| 4 | import { |
| 5 | appendComposerDraftAttachments, |
| 6 | clearComposerDraftContent, |
| 7 | flushComposerDrafts, |
| 8 | getComposerDraftSnapshot, |
| 9 | mergeComposerDraftContent, |
| 10 | } from "./use-composer-drafts"; |
| 11 | |
| 12 | /** Move unsent setup edits into the restored task before reopening its editor. */ |
| 13 | export async function recoverFailedThreadDraft(message: QueuedThreadMessage): Promise<void> { |
| 14 | const sourceKey = scopedThreadKey(message.environmentId, message.threadId); |
| 15 | const targetKey = restoredNewTaskDraftKey(message.messageId); |
| 16 | const source = getComposerDraftSnapshot(sourceKey); |
| 17 | if (source.text.length === 0 && source.attachments.length === 0) return; |
| 18 | |
| 19 | await mergeComposerDraftContent(targetKey, { |
| 20 | text: source.text, |
| 21 | context: source.context, |
| 22 | attachments: [], |
| 23 | }); |
| 24 | const existingIds = new Set( |
| 25 | getComposerDraftSnapshot(targetKey).attachments.map((attachment) => attachment.id), |
| 26 | ); |
| 27 | appendComposerDraftAttachments( |
| 28 | targetKey, |
| 29 | source.attachments.filter((attachment) => !existingIds.has(attachment.id)), |
| 30 | { allowOverflow: true }, |
| 31 | ); |
| 32 | // Recovery may exceed the send cap. Preserve every file and let the editor |
| 33 | // ask the user to remove extras; never discard them during a failed send. |
| 34 | await flushComposerDrafts(); |
| 35 | clearComposerDraftContent(sourceKey); |
| 36 | } |