Records a Codex `SubagentStart` and returns the session-local count.
(event_json: &str)
| 269 | |
| 270 | /// Records a Codex `SubagentStart` and returns the session-local count. |
| 271 | pub fn record_codex_subagent_start(event_json: &str) -> Option<u64> { |
| 272 | let parsed: Value = serde_json::from_str(event_json).ok()?; |
| 273 | let root = codex_project_root_from_parsed_event(&parsed)?; |
| 274 | let layout = crate::storage::resolve_layout_for_current_profile(&root).ok()?; |
| 275 | let path = layout.data_root.join("codex_subagent_starts.json"); |
| 276 | let analytics_session_id = event_session_id(&parsed); |
| 277 | let session_id = analytics_session_id |
| 278 | .clone() |
| 279 | .unwrap_or_else(|| "unknown-codex-session".to_string()); |
| 280 | let mut counts = read_codex_subagent_start_counts(&path); |
| 281 | let count = counts.entry(session_id).or_insert(0); |
| 282 | *count = count.saturating_add(1); |
| 283 | let next = *count; |
| 284 | if let Some(parent) = path.parent() { |
| 285 | let _ = std::fs::create_dir_all(parent); |
| 286 | } |
| 287 | if let Ok(json) = serde_json::to_string_pretty(&counts) { |
| 288 | let _ = std::fs::write(path, format!("{json}\n")); |
| 289 | } |
| 290 | let agent_type = parsed |
| 291 | .get("agent_type") |
| 292 | .or_else(|| parsed.get("subagent_type")) |
| 293 | .and_then(Value::as_str) |
| 294 | .filter(|value| !value.is_empty()) |
| 295 | .unwrap_or("unknown"); |
| 296 | record_hook_analytics( |
| 297 | Some(&root), |
| 298 | "codex_subagent_start", |
| 299 | serde_json::json!({ |
| 300 | "agent": HintAgent::Codex.as_key(), |
| 301 | "session_id": analytics_session_id.as_deref(), |
| 302 | "agent_type": agent_type, |
| 303 | "count": next, |
| 304 | }), |
| 305 | ); |
| 306 | Some(next) |
| 307 | } |
| 308 | |
| 309 | pub fn codex_subagent_start_log_line( |
| 310 | event_json: &str, |
no test coverage detected