mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Add SubagentStart hook (#22782)
# What `SubagentStart` runs once when Codex creates a thread-spawned subagent, before that child sends its first model request. Thread-spawned subagents use `SubagentStart` instead of the normal root-agent `SessionStart` hook. Configured handlers match on the subagent `agent_type`, using the same value passed to `spawn_agent`. When no agent type is specified, Codex uses the default agent type. Hook input includes the normal session-start fields plus: - `agent_id`: the child thread id. - `agent_type`: the resolved subagent type. `SubagentStart` may return `hookSpecificOutput.additionalContext`. That context is added to the child conversation before the first model request. # Lifecycle Scope Only thread-spawned subagents run `SubagentStart`. Internal/system subagents such as Review, Compact, MemoryConsolidation, and Other do not run normal `SessionStart` hooks and do not run `SubagentStart`. This avoids exposing synthetic matcher labels for internal implementation paths. Also the `SessionStart` hook no longer fires for subagents, this matches behavior with other coding agents' implementation # Stack 1. This PR: add `SubagentStart`. 2. #22873: add `SubagentStop`. 3. #22882: add subagent identity to normal hook inputs.
This commit is contained in:
@@ -45,6 +45,8 @@ pub struct HookEventsToml {
|
||||
pub session_start: Vec<MatcherGroup>,
|
||||
#[serde(rename = "UserPromptSubmit", default)]
|
||||
pub user_prompt_submit: Vec<MatcherGroup>,
|
||||
#[serde(rename = "SubagentStart", default)]
|
||||
pub subagent_start: Vec<MatcherGroup>,
|
||||
#[serde(rename = "Stop", default)]
|
||||
pub stop: Vec<MatcherGroup>,
|
||||
}
|
||||
@@ -59,6 +61,7 @@ impl HookEventsToml {
|
||||
post_compact,
|
||||
session_start,
|
||||
user_prompt_submit,
|
||||
subagent_start,
|
||||
stop,
|
||||
} = self;
|
||||
pre_tool_use.is_empty()
|
||||
@@ -68,6 +71,7 @@ impl HookEventsToml {
|
||||
&& post_compact.is_empty()
|
||||
&& session_start.is_empty()
|
||||
&& user_prompt_submit.is_empty()
|
||||
&& subagent_start.is_empty()
|
||||
&& stop.is_empty()
|
||||
}
|
||||
|
||||
@@ -80,6 +84,7 @@ impl HookEventsToml {
|
||||
post_compact,
|
||||
session_start,
|
||||
user_prompt_submit,
|
||||
subagent_start,
|
||||
stop,
|
||||
} = self;
|
||||
[
|
||||
@@ -90,6 +95,7 @@ impl HookEventsToml {
|
||||
post_compact,
|
||||
session_start,
|
||||
user_prompt_submit,
|
||||
subagent_start,
|
||||
stop,
|
||||
]
|
||||
.into_iter()
|
||||
@@ -98,7 +104,7 @@ impl HookEventsToml {
|
||||
.sum()
|
||||
}
|
||||
|
||||
pub fn into_matcher_groups(self) -> [(HookEventName, Vec<MatcherGroup>); 8] {
|
||||
pub fn into_matcher_groups(self) -> [(HookEventName, Vec<MatcherGroup>); 9] {
|
||||
[
|
||||
(HookEventName::PreToolUse, self.pre_tool_use),
|
||||
(HookEventName::PermissionRequest, self.permission_request),
|
||||
@@ -107,6 +113,7 @@ impl HookEventsToml {
|
||||
(HookEventName::PostCompact, self.post_compact),
|
||||
(HookEventName::SessionStart, self.session_start),
|
||||
(HookEventName::UserPromptSubmit, self.user_prompt_submit),
|
||||
(HookEventName::SubagentStart, self.subagent_start),
|
||||
(HookEventName::Stop, self.stop),
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user