aggregateTokenMetadata sums all numeric values from the metadata JSONB across the given token usage rows by key. Nested objects are flattened using dot-notation (e.g. {"cache": {"read_tokens": 10}} becomes "cache.read_tokens"). Non-numeric leaves (strings, booleans, arrays, nulls) are silently skipp
(tokens []database.AIBridgeTokenUsage)
| 1455 | // becomes "cache.read_tokens"). Non-numeric leaves (strings, |
| 1456 | // booleans, arrays, nulls) are silently skipped. |
| 1457 | func aggregateTokenMetadata(tokens []database.AIBridgeTokenUsage) map[string]any { |
| 1458 | sums := make(map[string]int64) |
| 1459 | for _, tu := range tokens { |
| 1460 | if !tu.Metadata.Valid || len(tu.Metadata.RawMessage) == 0 { |
| 1461 | continue |
| 1462 | } |
| 1463 | var m map[string]json.RawMessage |
| 1464 | if err := json.Unmarshal(tu.Metadata.RawMessage, &m); err != nil { |
| 1465 | continue |
| 1466 | } |
| 1467 | flattenAndSum(sums, "", m) |
| 1468 | } |
| 1469 | result := make(map[string]any, len(sums)) |
| 1470 | for k, v := range sums { |
| 1471 | result[k] = v |
| 1472 | } |
| 1473 | return result |
| 1474 | } |
| 1475 | |
| 1476 | // flattenAndSum recursively walks a JSON object and sums all numeric |
| 1477 | // leaf values into sums, using dot-separated keys for nested objects. |