(messages: Message[])
| 2793 | } |
| 2794 | |
| 2795 | export function filterUnresolvedToolUses(messages: Message[]): Message[] { |
| 2796 | // Collect all tool_use IDs and tool_result IDs directly from message content blocks. |
| 2797 | // This avoids calling normalizeMessages() which generates new UUIDs — if those |
| 2798 | // normalized messages were returned and later recorded to the transcript JSONL, |
| 2799 | // the UUID dedup would not catch them, causing exponential transcript growth on |
| 2800 | // every session resume. |
| 2801 | const toolUseIds = new Set<string>() |
| 2802 | const toolResultIds = new Set<string>() |
| 2803 | |
| 2804 | for (const msg of messages) { |
| 2805 | if (msg.type !== 'user' && msg.type !== 'assistant') continue |
| 2806 | const content = msg.message.content |
| 2807 | if (!Array.isArray(content)) continue |
| 2808 | for (const block of content) { |
| 2809 | if (block.type === 'tool_use') { |
| 2810 | toolUseIds.add(block.id) |
| 2811 | } |
| 2812 | if (block.type === 'tool_result') { |
| 2813 | toolResultIds.add(block.tool_use_id) |
| 2814 | } |
| 2815 | } |
| 2816 | } |
| 2817 | |
| 2818 | const unresolvedIds = new Set( |
| 2819 | [...toolUseIds].filter(id => !toolResultIds.has(id)), |
| 2820 | ) |
| 2821 | |
| 2822 | if (unresolvedIds.size === 0) { |
| 2823 | return messages |
| 2824 | } |
| 2825 | |
| 2826 | // Filter out assistant messages whose tool_use blocks are all unresolved |
| 2827 | return messages.filter(msg => { |
| 2828 | if (msg.type !== 'assistant') return true |
| 2829 | const content = msg.message.content |
| 2830 | if (!Array.isArray(content)) return true |
| 2831 | const toolUseBlockIds: string[] = [] |
| 2832 | for (const b of content) { |
| 2833 | if (b.type === 'tool_use') { |
| 2834 | toolUseBlockIds.push(b.id) |
| 2835 | } |
| 2836 | } |
| 2837 | if (toolUseBlockIds.length === 0) return true |
| 2838 | // Remove message only if ALL its tool_use blocks are unresolved |
| 2839 | return !toolUseBlockIds.every(id => unresolvedIds.has(id)) |
| 2840 | }) |
| 2841 | } |
| 2842 | |
| 2843 | export function getAssistantMessageText(message: Message): string | null { |
| 2844 | if (message.type !== 'assistant') { |
no test coverage detected