( usage: TokenUsage, )
| 24 | * set and have no agreed convention yet. |
| 25 | */ |
| 26 | export function usageAttributes( |
| 27 | usage: TokenUsage, |
| 28 | ): Record<string, AttributeValue> { |
| 29 | const attrs: Record<string, AttributeValue> = { |
| 30 | 'gen_ai.usage.input_tokens': usage.promptTokens, |
| 31 | 'gen_ai.usage.output_tokens': usage.completionTokens, |
| 32 | } |
| 33 | const optional: Array<[key: string, value: unknown]> = [ |
| 34 | ['gen_ai.usage.total_tokens', usage.totalTokens], |
| 35 | ['gen_ai.usage.cost', usage.cost], |
| 36 | [ |
| 37 | 'gen_ai.usage.cache_read.input_tokens', |
| 38 | usage.promptTokensDetails?.cachedTokens, |
| 39 | ], |
| 40 | [ |
| 41 | 'gen_ai.usage.cache_creation.input_tokens', |
| 42 | usage.promptTokensDetails?.cacheWriteTokens, |
| 43 | ], |
| 44 | [ |
| 45 | 'gen_ai.usage.reasoning.output_tokens', |
| 46 | usage.completionTokensDetails?.reasoningTokens, |
| 47 | ], |
| 48 | ['tanstack.ai.usage.duration_seconds', usage.durationSeconds], |
| 49 | ['tanstack.ai.usage.units_billed', usage.unitsBilled], |
| 50 | ['tanstack.ai.usage.upstream_cost', usage.costDetails?.upstreamCost], |
| 51 | [ |
| 52 | 'tanstack.ai.usage.upstream_input_cost', |
| 53 | usage.costDetails?.upstreamInputCost, |
| 54 | ], |
| 55 | [ |
| 56 | 'tanstack.ai.usage.upstream_output_cost', |
| 57 | usage.costDetails?.upstreamOutputCost, |
| 58 | ], |
| 59 | ] |
| 60 | for (const [key, value] of optional) { |
| 61 | const num = firstNumber(value) |
| 62 | if (num !== undefined) attrs[key] = num |
| 63 | } |
| 64 | return attrs |
| 65 | } |
no test coverage detected