* Extracts token usage from an event, tolerating the field names Pi and common * provider payloads use (`input`/`output`, `inputTokens`/`outputTokens`, * `prompt_tokens`/`completion_tokens`), checked on the event and on a nested * `message`/`usage` object.
( ev: Record<string, unknown> )
| 90 | * `message`/`usage` object. |
| 91 | */ |
| 92 | function extractUsage( |
| 93 | ev: Record<string, unknown> |
| 94 | ): { inputTokens: number; outputTokens: number } | null { |
| 95 | const candidates: Array<Record<string, unknown>> = [] |
| 96 | const direct = asRecord(ev.usage) |
| 97 | if (direct) candidates.push(direct) |
| 98 | const message = asRecord(ev.message) |
| 99 | if (message) { |
| 100 | const messageUsage = asRecord(message.usage) |
| 101 | if (messageUsage) candidates.push(messageUsage) |
| 102 | } |
| 103 | |
| 104 | for (const usage of candidates) { |
| 105 | const input = |
| 106 | asNumber(usage.input) || asNumber(usage.inputTokens) || asNumber(usage.prompt_tokens) |
| 107 | const output = |
| 108 | asNumber(usage.output) || asNumber(usage.outputTokens) || asNumber(usage.completion_tokens) |
| 109 | if (input > 0 || output > 0) { |
| 110 | return { inputTokens: input, outputTokens: output } |
| 111 | } |
| 112 | } |
| 113 | |
| 114 | return null |
| 115 | } |
| 116 | |
| 117 | /** Normalizes a raw Pi/SDK event object into a {@link PiEvent}. */ |
| 118 | export function normalizePiEvent(raw: unknown): PiEvent | null { |
no test coverage detected