* Extract a display string from forked agent messages. * * IMPORTANT: claude.ts yields one AssistantMessage PER CONTENT BLOCK, not one * per API response. With adaptive thinking enabled (inherited from the main * thread to preserve the cache key), a thinking response arrives as: * messages[0]
(messages: Message[])
| 123 | * interruption, no assistant message at all. |
| 124 | */ |
| 125 | function extractSideQuestionResponse(messages: Message[]): string | null { |
| 126 | // Flatten all assistant content blocks across the per-block messages. |
| 127 | const assistantBlocks = messages.flatMap(m => |
| 128 | m.type === 'assistant' |
| 129 | ? (m.message!.content as unknown as Array<{ |
| 130 | type: string |
| 131 | [key: string]: unknown |
| 132 | }>) |
| 133 | : [], |
| 134 | ) |
| 135 | |
| 136 | if (assistantBlocks.length > 0) { |
| 137 | // Concatenate all text blocks (there's normally at most one, but be safe). |
| 138 | const text = extractTextContent(assistantBlocks, '\n\n').trim() |
| 139 | if (text) return text |
| 140 | |
| 141 | // No text — check if the model tried to call a tool despite instructions. |
| 142 | const toolUse = assistantBlocks.find(b => b.type === 'tool_use') |
| 143 | if (toolUse) { |
| 144 | const toolName = |
| 145 | 'name' in toolUse |
| 146 | ? (toolUse as unknown as { name: string }).name |
| 147 | : 'a tool' |
| 148 | return `(The model tried to call ${toolName} instead of answering directly. Try rephrasing or ask in the main conversation.)` |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | // No assistant content — likely API error exhausted retries. Surface the |
| 153 | // first system api_error message so the user sees what happened. |
| 154 | const apiErr = messages.find( |
| 155 | (m): m is SystemAPIErrorMessage => |
| 156 | m.type === 'system' && 'subtype' in m && m.subtype === 'api_error', |
| 157 | ) |
| 158 | if (apiErr) { |
| 159 | return `(API error: ${formatAPIError(apiErr.error as Parameters<typeof formatAPIError>[0])})` |
| 160 | } |
| 161 | |
| 162 | return null |
| 163 | } |
no test coverage detected