Add codex_hook_run analytics event (#17996)

# Why
Add product analytics for hook handler executions so we can understand
which hooks are running, where they came from, and whether they
completed, failed, stopped, or blocked work.

# What
- add the new `codex_hook_run` analytics event and payload plumbing in
`codex-rs/analytics`
- emit hook-run analytics from the shared hook completion path in
`codex-rs/core`
- classify hook source from the loaded hook path as `system`, `user`,
`project`, or `unknown`

```
{
  "event_type": "codex_hook_run",
  "event_params": {
    "thread_id": "string",
    "turn_id": "string",
    "model_slug": "string",
    "hook_name": "string, // any HookEventName
    "hook_source": "system | user | project | unknown",
    "status": "completed | failed | stopped | blocked"
  }
}
```

---------

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Abhinav
2026-04-16 12:43:16 -07:00
committed by GitHub
parent 62847e7554
commit 8720b7bdce
32 changed files with 682 additions and 114 deletions

View File

@@ -65,6 +65,7 @@ use codex_protocol::protocol::HookOutputEntryKind as CoreHookOutputEntryKind;
use codex_protocol::protocol::HookRunStatus as CoreHookRunStatus;
use codex_protocol::protocol::HookRunSummary as CoreHookRunSummary;
use codex_protocol::protocol::HookScope as CoreHookScope;
use codex_protocol::protocol::HookSource as CoreHookSource;
use codex_protocol::protocol::ModelRerouteReason as CoreModelRerouteReason;
use codex_protocol::protocol::NetworkAccess as CoreNetworkAccess;
use codex_protocol::protocol::NonSteerableTurnKind as CoreNonSteerableTurnKind;
@@ -402,6 +403,23 @@ v2_enum_from_core!(
}
);
v2_enum_from_core!(
pub enum HookSource from CoreHookSource {
System,
User,
Project,
Mdm,
SessionFlags,
LegacyManagedConfigFile,
LegacyManagedConfigMdm,
Unknown,
}
);
fn default_hook_source() -> HookSource {
HookSource::Unknown
}
v2_enum_from_core!(
pub enum HookRunStatus from CoreHookRunStatus {
Running, Completed, Failed, Blocked, Stopped
@@ -449,6 +467,8 @@ pub struct HookRunSummary {
pub execution_mode: HookExecutionMode,
pub scope: HookScope,
pub source_path: AbsolutePathBuf,
#[serde(default = "default_hook_source")]
pub source: HookSource,
pub display_order: i64,
pub status: HookRunStatus,
pub status_message: Option<String>,
@@ -467,6 +487,7 @@ impl From<CoreHookRunSummary> for HookRunSummary {
execution_mode: value.execution_mode.into(),
scope: value.scope.into(),
source_path: value.source_path,
source: value.source.into(),
display_order: value.display_order,
status: value.status.into(),
status_message: value.status_message,