| 395 | } |
| 396 | |
| 397 | fn parse_event(&self, hook_type: HookType, input: &[u8]) -> AgentResult<TurnEvent> { |
| 398 | if input.is_empty() { |
| 399 | return Err(AgentError::HookInputEmpty { |
| 400 | agent: self.name().to_string(), |
| 401 | hook_type: hook_type.as_str().to_string(), |
| 402 | }); |
| 403 | } |
| 404 | |
| 405 | // Preserve raw JSON for debugging and downstream use |
| 406 | let raw_json: serde_json::Value = |
| 407 | serde_json::from_slice(input).map_err(|e| AgentError::HookParseFailed { |
| 408 | agent: self.name().to_string(), |
| 409 | hook_type: hook_type.as_str().to_string(), |
| 410 | reason: e.to_string(), |
| 411 | })?; |
| 412 | |
| 413 | match hook_type { |
| 414 | HookType::SessionStart => { |
| 415 | let parsed: SessionStartInput = |
| 416 | serde_json::from_value(raw_json.clone()).map_err(|e| { |
| 417 | AgentError::HookParseFailed { |
| 418 | agent: self.name().to_string(), |
| 419 | hook_type: hook_type.as_str().to_string(), |
| 420 | reason: e.to_string(), |
| 421 | } |
| 422 | })?; |
| 423 | |
| 424 | // SessionStart: prefer session_id, fall back to conversation_id |
| 425 | let session_id = |
| 426 | Self::extract_session_id(parsed.conversation_id, parsed.session_id); |
| 427 | |
| 428 | let mut event = TurnEvent::new(session_id, hook_type).with_raw_json(raw_json); |
| 429 | |
| 430 | if let Some(transcript) = parsed.transcript_path { |
| 431 | event = event.with_transcript_path(transcript); |
| 432 | } |
| 433 | |
| 434 | // Store model, composer_mode, is_background_agent in raw_json |
| 435 | if let Some(model) = parsed.model { |
| 436 | if let Some(ref mut raw) = event.raw_json { |
| 437 | if let Some(obj) = raw.as_object_mut() { |
| 438 | obj.insert("model".to_string(), serde_json::Value::String(model)); |
| 439 | } |
| 440 | } |
| 441 | } |
| 442 | if let Some(mode) = parsed.composer_mode { |
| 443 | if let Some(ref mut raw) = event.raw_json { |
| 444 | if let Some(obj) = raw.as_object_mut() { |
| 445 | obj.insert( |
| 446 | "composer_mode".to_string(), |
| 447 | serde_json::Value::String(mode), |
| 448 | ); |
| 449 | } |
| 450 | } |
| 451 | } |
| 452 | if let Some(bg) = parsed.is_background_agent { |
| 453 | if let Some(ref mut raw) = event.raw_json { |
| 454 | if let Some(obj) = raw.as_object_mut() { |