Add PermissionRequest hooks support#17563
Conversation
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Replace stringly approval-attempt plumbing with a shared enum, centralize approval decision handling in the orchestrator, and document plus test the reserved PermissionRequest output fields. Co-authored-by: Codex <noreply@openai.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1bf5222fbb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Keep PermissionRequest hook payloads focused on tool identity and the actionable command details. For Bash and exec_command hooks, plumb request justification into tool_input.description when present. For NetworkAccess hooks, pass the originating command and a network-access <domain> description instead of the old approval context envelope. Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Remove the approval-attempt enum and let callers provide the final permission-request hook run id suffix directly. This keeps retry hook runs unique without carrying an extra cross-crate type.\n\nCo-authored-by: Codex <noreply@openai.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7e4869308c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if decision.updated_input.is_some() { | ||
| Some("PermissionRequest hook returned unsupported updatedInput".to_string()) | ||
| } else if decision.updated_permissions.is_some() { | ||
| Some("PermissionRequest hook returned unsupported updatedPermissions".to_string()) |
There was a problem hiding this comment.
Treat null reserved fields as invalid in PermissionRequest
unsupported_permission_request_hook_specific_output only checks is_some() on updated_input/updated_permissions. With Serde, explicitly sending "updatedInput": null (or updatedPermissions) deserializes to None, so the hook output is accepted instead of failing closed. This contradicts the documented intent that these reserved fields are unsupported when present.
Useful? React with 👍 / 👎.
eternal-openai
left a comment
There was a problem hiding this comment.
Codex notes: "PermissionRequest universal hook controls are handled incorrectly. The Claude hooks contract applies fields like continue and stopReason across hook events, but this implementation rejects them for PermissionRequest and falls back to normal approval instead of honoring the hook’s stop behavior."
Still reading otherwise
eternal-openai
left a comment
There was a problem hiding this comment.
Looks good aside from that note above! Will approve after that's resolved
1542947 to
7c38bb4
Compare
# Conflicts: # codex-rs/core/src/codex.rs
7c38bb4 to
6cb8d62
Compare
implemented but ended up backing the changes out so this PR is easier to review
here's the current draft, need to tie in |
Co-authored-by: Codex <noreply@openai.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Bravo. ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Keep the PermissionRequest approval helper focused on hook-or-prompt selection while leaving approval decision handling in the existing approval branches. Co-authored-by: Codex <noreply@openai.com>
Why
We need
PermissionRequesthook support!Also addresses:
decisionobject from output or just have the script exit 0 and print nothingReviewer Note
There's a lot of plumbing for the new hook, key files to review are:
codex-rs/hooks/src/events/permission_request.rscodex-rs/core/src/tools/network_approval.rscodex-rs/core/src/tools/orchestrator.rscodex-rs/core/src/tools/runtimes/shell/unix_escalation.rsWhat
PermissionRequesthook flow.tool_input.descriptionfor user-facing context when it helps:exec_command: the request justification, when presentnetwork-access <domain>tool_name: Bashfor shell, unified exec, and network approval permission-request hooks.tool_input.commandwhen there is a single owning call; otherwise falls back to the syntheticnetwork-access ...command.Example `PermissionRequest` hook input for a shell approval
{ "session_id": "<session-id>", "turn_id": "<turn-id>", "transcript_path": "/path/to/transcript.jsonl", "cwd": "/path/to/cwd", "hook_event_name": "PermissionRequest", "model": "gpt-5", "permission_mode": "default", "tool_name": "Bash", "tool_input": { "command": "rm -f /tmp/example" } }Example `PermissionRequest` hook input for an escalated `exec_command` request
{ "session_id": "<session-id>", "turn_id": "<turn-id>", "transcript_path": "/path/to/transcript.jsonl", "cwd": "/path/to/cwd", "hook_event_name": "PermissionRequest", "model": "gpt-5", "permission_mode": "default", "tool_name": "Bash", "tool_input": { "command": "cp /tmp/source.json /Users/alice/export/source.json", "description": "Need to copy a generated file outside the workspace" } }Example `PermissionRequest` hook input for a network approval
{ "session_id": "<session-id>", "turn_id": "<turn-id>", "transcript_path": "/path/to/transcript.jsonl", "cwd": "/path/to/cwd", "hook_event_name": "PermissionRequest", "model": "gpt-5", "permission_mode": "default", "tool_name": "Bash", "tool_input": { "command": "curl http://codex-network-test.invalid", "description": "network-access http://codex-network-test.invalid" } }Follow-ups
PermissionRequestsemantics forupdatedInput,updatedPermissions,interrupt, and suggestions /permission_suggestionsPermissionRequestsupport for therequest_permissionstool path