* Check if a progress message is a search/read/REPL operation (tool use or result). * Returns { isSearch, isRead, isREPL } if it's a collapsible operation, null otherwise. * * For tool_result messages, uses the provided `toolUseByID` map to find the * corresponding tool_use block instead of rely
(progressMessage: ProgressMessage<Progress>, tools: Tools, toolUseByID: Map<string, ToolUseBlockParam>)
| 53 | * corresponding tool_use block instead of relying on `normalizedMessages`. |
| 54 | */ |
| 55 | function getSearchOrReadInfo(progressMessage: ProgressMessage<Progress>, tools: Tools, toolUseByID: Map<string, ToolUseBlockParam>): { |
| 56 | isSearch: boolean; |
| 57 | isRead: boolean; |
| 58 | isREPL: boolean; |
| 59 | } | null { |
| 60 | if (!hasProgressMessage(progressMessage.data)) { |
| 61 | return null; |
| 62 | } |
| 63 | const message = progressMessage.data.message; |
| 64 | |
| 65 | // Check tool_use (assistant message) |
| 66 | if (message.type === 'assistant') { |
| 67 | return getSearchOrReadFromContent(message.message.content[0], tools); |
| 68 | } |
| 69 | |
| 70 | // Check tool_result (user message) - find corresponding tool use from the map |
| 71 | if (message.type === 'user') { |
| 72 | const content = message.message.content[0]; |
| 73 | if (content?.type === 'tool_result') { |
| 74 | const toolUse = toolUseByID.get(content.tool_use_id); |
| 75 | if (toolUse) { |
| 76 | return getSearchOrReadFromContent(toolUse, tools); |
| 77 | } |
| 78 | } |
| 79 | } |
| 80 | return null; |
| 81 | } |
| 82 | type SummaryMessage = { |
| 83 | type: 'summary'; |
| 84 | searchCount: number; |
no test coverage detected