Files
codex/codex-rs/app-server-protocol/schema/json/v2/HooksListResponse.json
Abhinav eee3e60db3 Add SubagentStop hook (#22873)
# What

<img width="1792" height="1024" alt="image"
src="https://github.com/user-attachments/assets/8f81d232-5813-4994-a61d-e42a05a93a3e"
/>

`SubagentStop` runs when a thread-spawned subagent turn is about to
finish. Thread-spawned subagents use `SubagentStop` instead of the
normal root-agent `Stop` hook.

Configured handlers match on `agent_type`. Hook input includes the
normal stop fields plus:

- `agent_id`: the child thread id.
- `agent_type`: the resolved subagent type.
- `agent_transcript_path`: the child subagent transcript path.
- `transcript_path`: the parent thread transcript path.
- `last_assistant_message`: the final assistant message from the child
turn, when available.
- `stop_hook_active`: `true` when the child is already continuing
because an earlier stop-like hook blocked completion.

`SubagentStop` shares the same completion-control semantics as `Stop`,
scoped to the child turn:

- No decision allows the child turn to finish.
- `decision: "block"` with a non-empty `reason` records that reason as
hook feedback and continues the child with that prompt.
- `continue: false` stops the child turn. If `stopReason` is present,
Codex surfaces it as the stop reason.

# Lifecycle Scope

Only thread-spawned subagents run `SubagentStop`.

Internal/system subagents such as Review, Compact, MemoryConsolidation,
and Other do not run normal `Stop` hooks and do not run `SubagentStop`.
This avoids exposing synthetic matcher labels for internal
implementation paths.

# Stack

1. #22782: add `SubagentStart`.
2. This PR: add `SubagentStop`.
3. #22882: add subagent identity to normal hook inputs.
2026-05-20 14:59:41 -07:00

194 lines
4.1 KiB
JSON
Generated

{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"AbsolutePathBuf": {
"description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.",
"type": "string"
},
"HookErrorInfo": {
"properties": {
"message": {
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"message",
"path"
],
"type": "object"
},
"HookEventName": {
"enum": [
"preToolUse",
"permissionRequest",
"postToolUse",
"preCompact",
"postCompact",
"sessionStart",
"userPromptSubmit",
"subagentStart",
"subagentStop",
"stop"
],
"type": "string"
},
"HookHandlerType": {
"enum": [
"command",
"prompt",
"agent"
],
"type": "string"
},
"HookMetadata": {
"properties": {
"command": {
"type": [
"string",
"null"
]
},
"currentHash": {
"type": "string"
},
"displayOrder": {
"format": "int64",
"type": "integer"
},
"enabled": {
"type": "boolean"
},
"eventName": {
"$ref": "#/definitions/HookEventName"
},
"handlerType": {
"$ref": "#/definitions/HookHandlerType"
},
"isManaged": {
"type": "boolean"
},
"key": {
"type": "string"
},
"matcher": {
"type": [
"string",
"null"
]
},
"pluginId": {
"type": [
"string",
"null"
]
},
"source": {
"$ref": "#/definitions/HookSource"
},
"sourcePath": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"statusMessage": {
"type": [
"string",
"null"
]
},
"timeoutSec": {
"format": "uint64",
"minimum": 0.0,
"type": "integer"
},
"trustStatus": {
"$ref": "#/definitions/HookTrustStatus"
}
},
"required": [
"currentHash",
"displayOrder",
"enabled",
"eventName",
"handlerType",
"isManaged",
"key",
"source",
"sourcePath",
"timeoutSec",
"trustStatus"
],
"type": "object"
},
"HookSource": {
"enum": [
"system",
"user",
"project",
"mdm",
"sessionFlags",
"plugin",
"cloudRequirements",
"legacyManagedConfigFile",
"legacyManagedConfigMdm",
"unknown"
],
"type": "string"
},
"HookTrustStatus": {
"enum": [
"managed",
"untrusted",
"trusted",
"modified"
],
"type": "string"
},
"HooksListEntry": {
"properties": {
"cwd": {
"type": "string"
},
"errors": {
"items": {
"$ref": "#/definitions/HookErrorInfo"
},
"type": "array"
},
"hooks": {
"items": {
"$ref": "#/definitions/HookMetadata"
},
"type": "array"
},
"warnings": {
"items": {
"type": "string"
},
"type": "array"
}
},
"required": [
"cwd",
"errors",
"hooks",
"warnings"
],
"type": "object"
}
},
"properties": {
"data": {
"items": {
"$ref": "#/definitions/HooksListEntry"
},
"type": "array"
}
},
"required": [
"data"
],
"title": "HooksListResponse",
"type": "object"
}