(
block: ContentBlockParam | ContentBlock | BetaContentBlock,
message: UserMessage | AssistantMessage,
stats: TokenStats,
toolIds: Map<string, string>,
readToolPaths: Map<string, string>,
fileReads: Map<string, { count: number; totalTokens: number }>,
)
| 97 | } |
| 98 | |
| 99 | function processBlock( |
| 100 | block: ContentBlockParam | ContentBlock | BetaContentBlock, |
| 101 | message: UserMessage | AssistantMessage, |
| 102 | stats: TokenStats, |
| 103 | toolIds: Map<string, string>, |
| 104 | readToolPaths: Map<string, string>, |
| 105 | fileReads: Map<string, { count: number; totalTokens: number }>, |
| 106 | ): void { |
| 107 | const tokens = countTokens(jsonStringify(block)) |
| 108 | stats.total += tokens |
| 109 | |
| 110 | switch (block.type) { |
| 111 | case 'text': |
| 112 | // Check if this is a local command output |
| 113 | if ( |
| 114 | message.type === 'user' && |
| 115 | 'text' in block && |
| 116 | block.text.includes('local-command-stdout') |
| 117 | ) { |
| 118 | stats.localCommandOutputs += tokens |
| 119 | } else { |
| 120 | stats[ |
| 121 | message.type === 'user' ? 'humanMessages' : 'assistantMessages' |
| 122 | ] += tokens |
| 123 | } |
| 124 | break |
| 125 | |
| 126 | case 'tool_use': { |
| 127 | if ('name' in block && 'id' in block) { |
| 128 | const toolName = block.name || 'unknown' |
| 129 | increment(stats.toolRequests, toolName, tokens) |
| 130 | toolIds.set(block.id, toolName) |
| 131 | |
| 132 | // Track Read tool file paths |
| 133 | if ( |
| 134 | toolName === 'Read' && |
| 135 | 'input' in block && |
| 136 | block.input && |
| 137 | typeof block.input === 'object' && |
| 138 | 'file_path' in block.input |
| 139 | ) { |
| 140 | const path = String( |
| 141 | (block.input as Record<string, unknown>).file_path, |
| 142 | ) |
| 143 | readToolPaths.set(block.id, path) |
| 144 | } |
| 145 | } |
| 146 | break |
| 147 | } |
| 148 | |
| 149 | case 'tool_result': { |
| 150 | if ('tool_use_id' in block) { |
| 151 | const toolName = toolIds.get(block.tool_use_id) || 'unknown' |
| 152 | increment(stats.toolResults, toolName, tokens) |
| 153 | |
| 154 | // Track file read tokens |
| 155 | if (toolName === 'Read') { |
| 156 | const path = readToolPaths.get(block.tool_use_id) |
no test coverage detected