(messages: Message[])
| 1773 | * - Any assistant message |
| 1774 | */ |
| 1775 | export function reorderAttachmentsForAPI(messages: Message[]): Message[] { |
| 1776 | // We build `result` backwards (push) and reverse once at the end — O(N). |
| 1777 | // Using unshift inside the loop would be O(N²). |
| 1778 | const result: Message[] = [] |
| 1779 | // Attachments are pushed as we encounter them scanning bottom-up, so |
| 1780 | // this buffer holds them in reverse order (relative to the input array). |
| 1781 | const pendingAttachments: AttachmentMessage[] = [] |
| 1782 | |
| 1783 | // Scan from the bottom up |
| 1784 | for (let i = messages.length - 1; i >= 0; i--) { |
| 1785 | const message = messages[i]! |
| 1786 | |
| 1787 | if (message.type === 'attachment') { |
| 1788 | // Collect attachment to bubble up |
| 1789 | pendingAttachments.push(message as AttachmentMessage) |
| 1790 | } else { |
| 1791 | // Check if this is a stopping point |
| 1792 | const isStoppingPoint = |
| 1793 | message.type === 'assistant' || |
| 1794 | (message.type === 'user' && |
| 1795 | Array.isArray(message.message?.content) && |
| 1796 | (message.message?.content as Array<{ type: string }>)[0]?.type === |
| 1797 | 'tool_result') |
| 1798 | |
| 1799 | if (isStoppingPoint && pendingAttachments.length > 0) { |
| 1800 | // Hit a stopping point — attachments stop here (go after the stopping point). |
| 1801 | // pendingAttachments is already reversed; after the final result.reverse() |
| 1802 | // they will appear in original order right after `message`. |
| 1803 | for (let j = 0; j < pendingAttachments.length; j++) { |
| 1804 | result.push(pendingAttachments[j]!) |
| 1805 | } |
| 1806 | result.push(message) |
| 1807 | pendingAttachments.length = 0 |
| 1808 | } else { |
| 1809 | // Regular message |
| 1810 | result.push(message) |
| 1811 | } |
| 1812 | } |
| 1813 | } |
| 1814 | |
| 1815 | // Any remaining attachments bubble all the way to the top. |
| 1816 | for (let j = 0; j < pendingAttachments.length; j++) { |
| 1817 | result.push(pendingAttachments[j]!) |
| 1818 | } |
| 1819 | |
| 1820 | result.reverse() |
| 1821 | return result |
| 1822 | } |
| 1823 | |
| 1824 | export function isSystemLocalCommandMessage( |
| 1825 | message: Message, |
no test coverage detected