Flattened `model` / `usage_*` column values for an assistant transcript record, extracted from `message.model` and `message.usage.*`. Returns only pairs whose source value exists and is non-null. Empty for non-assistant records.
(json: &serde_json::Value)
| 119 | /// Returns only pairs whose source value exists and is non-null. Empty for |
| 120 | /// non-assistant records. |
| 121 | pub fn flattened_usage_fields(json: &serde_json::Value) -> Vec<(&'static str, &serde_json::Value)> { |
| 122 | let mut fields = Vec::new(); |
| 123 | if json.get("type").and_then(|t| t.as_str()) != Some("assistant") { |
| 124 | return fields; |
| 125 | } |
| 126 | let Some(message) = json.get("message") else { |
| 127 | return fields; |
| 128 | }; |
| 129 | |
| 130 | fn put<'a>( |
| 131 | fields: &mut Vec<(&'static str, &'a serde_json::Value)>, |
| 132 | key: &'static str, |
| 133 | value: Option<&'a serde_json::Value>, |
| 134 | ) { |
| 135 | if let Some(value) = value { |
| 136 | if !value.is_null() { |
| 137 | fields.push((key, value)); |
| 138 | } |
| 139 | } |
| 140 | } |
| 141 | |
| 142 | put(&mut fields, "model", message.get("model")); |
| 143 | |
| 144 | let usage = message.get("usage"); |
| 145 | let get = |path: &str| usage.and_then(|u| u.get(path)); |
| 146 | put(&mut fields, "usage_input_tokens", get("input_tokens")); |
| 147 | put(&mut fields, "usage_output_tokens", get("output_tokens")); |
| 148 | put( |
| 149 | &mut fields, |
| 150 | "usage_cache_read_input_tokens", |
| 151 | get("cache_read_input_tokens"), |
| 152 | ); |
| 153 | put( |
| 154 | &mut fields, |
| 155 | "usage_cache_creation_input_tokens", |
| 156 | get("cache_creation_input_tokens"), |
| 157 | ); |
| 158 | put(&mut fields, "usage_service_tier", get("service_tier")); |
| 159 | |
| 160 | let cache_creation = usage.and_then(|u| u.get("cache_creation")); |
| 161 | put( |
| 162 | &mut fields, |
| 163 | "usage_ephemeral_5m_input_tokens", |
| 164 | cache_creation.and_then(|c| c.get("ephemeral_5m_input_tokens")), |
| 165 | ); |
| 166 | put( |
| 167 | &mut fields, |
| 168 | "usage_ephemeral_1h_input_tokens", |
| 169 | cache_creation.and_then(|c| c.get("ephemeral_1h_input_tokens")), |
| 170 | ); |
| 171 | |
| 172 | fields |
| 173 | } |
| 174 | |
| 175 | /// Per-session aggregation over a session's transcript records, used to build |
| 176 | /// the `sessions` virtual table (and reused by the devsql binary). |
no test coverage detected