Restore permission request attempt context

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Abhinav Vedmala
2026-04-13 14:18:16 -07:00
parent 20e0ffabef
commit 2563661366
5 changed files with 65 additions and 1 deletions

View File

@@ -447,7 +447,13 @@ async fn execve_permission_request_hook_short_circuits_prompt() -> anyhow::Resul
hook_inputs[0]["tool_input"]["command"],
expected_hook_command
);
assert!(hook_inputs[0]["approval_context"]["attempt"].is_null());
assert_eq!(
hook_inputs[0]["approval_context"]["attempt"],
serde_json::json!({
"stage": "initial",
"retryReason": null,
})
);
Ok(())
}

View File

@@ -1174,6 +1174,10 @@ async fn permission_request_hook_allows_shell_command_without_user_approval() ->
assert_eq!(
hook_inputs[0]["approval_context"],
serde_json::json!({
"attempt": {
"stage": "initial",
"retryReason": null,
},
"policy": {
"sandboxPermissions": "use_default",
"additionalPermissions": null,
@@ -1277,6 +1281,10 @@ async fn permission_request_hook_sees_raw_exec_command_input() -> Result<()> {
assert_eq!(
hook_inputs[0]["approval_context"],
serde_json::json!({
"attempt": {
"stage": "initial",
"retryReason": null,
},
"policy": {
"sandboxPermissions": "use_default",
"additionalPermissions": null,
@@ -1445,6 +1453,10 @@ allow_local_binding = true
assert_eq!(
hook_inputs[0]["approval_context"],
serde_json::json!({
"attempt": {
"stage": "initial",
"retryReason": null,
},
"policy": {
"sandboxPermissions": "use_default",
"additionalPermissions": null,
@@ -1540,6 +1552,10 @@ async fn permission_request_hook_sees_retry_context_after_sandbox_denial() -> Re
assert_eq!(
hook_inputs[0]["approval_context"],
serde_json::json!({
"attempt": {
"stage": "retry",
"retryReason": "command failed; retry without sandbox?",
},
"policy": {
"sandboxPermissions": "use_default",
"additionalPermissions": null,

View File

@@ -57,9 +57,19 @@
},
"type": "object"
},
"PermissionRequestApprovalAttempt": {
"enum": [
"initial",
"retry"
],
"type": "string"
},
"PermissionRequestApprovalContext": {
"additionalProperties": false,
"properties": {
"attempt": {
"$ref": "#/definitions/PermissionRequestAttemptContext"
},
"justification": {
"type": "string"
},
@@ -71,11 +81,27 @@
}
},
"required": [
"attempt",
"policy",
"resource"
],
"type": "object"
},
"PermissionRequestAttemptContext": {
"additionalProperties": false,
"properties": {
"retryReason": {
"type": "string"
},
"stage": {
"$ref": "#/definitions/PermissionRequestApprovalAttempt"
}
},
"required": [
"stage"
],
"type": "object"
},
"PermissionRequestPolicyContext": {
"additionalProperties": false,
"properties": {

View File

@@ -36,6 +36,7 @@ use crate::engine::command_runner::CommandRunResult;
use crate::engine::dispatcher;
use crate::engine::output_parser;
use crate::schema::PermissionRequestApprovalContext;
use crate::schema::PermissionRequestAttemptContext;
use crate::schema::PermissionRequestCommandInput;
use crate::schema::PermissionRequestPolicyContext;
use crate::schema::PermissionRequestResourceContext;
@@ -215,6 +216,10 @@ fn build_command_input(request: &PermissionRequestRequest) -> PermissionRequestC
command: request.command.clone(),
},
approval_context: PermissionRequestApprovalContext {
attempt: PermissionRequestAttemptContext {
stage: request.approval_attempt,
retry_reason: request.retry_reason.clone(),
},
policy: PermissionRequestPolicyContext {
sandbox_permissions: request.sandbox_permissions,
additional_permissions: request.additional_permissions.clone(),

View File

@@ -16,6 +16,8 @@ use codex_protocol::approvals::NetworkApprovalProtocol;
use codex_protocol::models::PermissionProfile;
use codex_protocol::models::SandboxPermissions;
use crate::events::permission_request::PermissionRequestApprovalAttempt;
const GENERATED_DIR: &str = "generated";
const POST_TOOL_USE_INPUT_FIXTURE: &str = "post-tool-use.command.input.schema.json";
const POST_TOOL_USE_OUTPUT_FIXTURE: &str = "post-tool-use.command.output.schema.json";
@@ -248,6 +250,14 @@ pub(crate) struct PermissionRequestToolInput {
pub command: String,
}
#[derive(Debug, Clone, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
pub(crate) struct PermissionRequestAttemptContext {
pub stage: PermissionRequestApprovalAttempt,
pub retry_reason: Option<String>,
}
#[derive(Debug, Clone, Serialize, JsonSchema)]
#[serde(rename_all = "camelCase")]
#[serde(deny_unknown_fields)]
@@ -269,6 +279,7 @@ pub(crate) struct PermissionRequestResourceContext {
#[derive(Debug, Clone, Serialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub(crate) struct PermissionRequestApprovalContext {
pub attempt: PermissionRequestAttemptContext,
pub policy: PermissionRequestPolicyContext,
pub justification: Option<String>,
pub resource: PermissionRequestResourceContext,