mirror of
https://github.com/openai/codex.git
synced 2026-04-26 23:55:25 +00:00
start of hooks engine (#13276)
(Experimental) This PR adds a first MVP for hooks, with SessionStart and Stop The core design is: - hooks live in a dedicated engine under codex-rs/hooks - each hook type has its own event-specific file - hook execution is synchronous and blocks normal turn progression while running - matching hooks run in parallel, then their results are aggregated into a normalized HookRunSummary On the AppServer side, hooks are exposed as operational metadata rather than transcript-native items: - new live notifications: hook/started, hook/completed - persisted/replayed hook results live on Turn.hookRuns - we intentionally did not add hook-specific ThreadItem variants Hooks messages are not persisted, they remain ephemeral. The context changes they add are (they get appended to the user's prompt)
This commit is contained in:
@@ -1234,6 +1234,8 @@ pub enum EventMsg {
|
||||
|
||||
ItemStarted(ItemStartedEvent),
|
||||
ItemCompleted(ItemCompletedEvent),
|
||||
HookStarted(HookStartedEvent),
|
||||
HookCompleted(HookCompletedEvent),
|
||||
|
||||
AgentMessageContentDelta(AgentMessageContentDeltaEvent),
|
||||
PlanDelta(PlanDeltaEvent),
|
||||
@@ -1262,6 +1264,97 @@ pub enum EventMsg {
|
||||
CollabResumeEnd(CollabResumeEndEvent),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum HookEventName {
|
||||
SessionStart,
|
||||
Stop,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum HookHandlerType {
|
||||
Command,
|
||||
Prompt,
|
||||
Agent,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum HookExecutionMode {
|
||||
Sync,
|
||||
Async,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum HookScope {
|
||||
Thread,
|
||||
Turn,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum HookRunStatus {
|
||||
Running,
|
||||
Completed,
|
||||
Failed,
|
||||
Blocked,
|
||||
Stopped,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum HookOutputEntryKind {
|
||||
Warning,
|
||||
Stop,
|
||||
Feedback,
|
||||
Context,
|
||||
Error,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct HookOutputEntry {
|
||||
pub kind: HookOutputEntryKind,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct HookRunSummary {
|
||||
pub id: String,
|
||||
pub event_name: HookEventName,
|
||||
pub handler_type: HookHandlerType,
|
||||
pub execution_mode: HookExecutionMode,
|
||||
pub scope: HookScope,
|
||||
pub source_path: PathBuf,
|
||||
pub display_order: i64,
|
||||
pub status: HookRunStatus,
|
||||
pub status_message: Option<String>,
|
||||
#[ts(type = "number")]
|
||||
pub started_at: i64,
|
||||
#[ts(type = "number | null")]
|
||||
pub completed_at: Option<i64>,
|
||||
#[ts(type = "number | null")]
|
||||
pub duration_ms: Option<i64>,
|
||||
pub entries: Vec<HookOutputEntry>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct HookStartedEvent {
|
||||
pub turn_id: Option<String>,
|
||||
pub run: HookRunSummary,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct HookCompletedEvent {
|
||||
pub turn_id: Option<String>,
|
||||
pub run: HookRunSummary,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, JsonSchema, TS)]
|
||||
pub struct RealtimeConversationStartedEvent {
|
||||
pub session_id: Option<String>,
|
||||
|
||||
Reference in New Issue
Block a user