Extract TUI approval request payloads into structs (#33684)

## What changed

Give command, permissions, patch, and MCP elicitation approvals dedicated
request structs, and update TUI routing and rendering to use the wrapped
payloads.

GitOrigin-RevId: ffee4058dd27505be2a11de3758ac12bb707b6b8
This commit is contained in:
Adam Perry @ OpenAI authored and copyberry committed 2026-07-16 20:44:28 +00:00
1 parent 693b8c2ba4
commit d3fc1950a9
8 files changed
+231 -267

No files matched your search

+167 -196
View File
@@ -71,86 +71,97 @@ use ratatui::widgets::Wrap;
/// Request coming from the agent that needs user approval.
#[derive(Clone, Debug)]
pub(crate) enum ApprovalRequest {
Exec {
thread_id: ThreadId,
thread_label: Option<String>,
id: String,
environment_id: Option<String>,
command: Vec<String>,
reason: Option<String>,
available_decisions: Vec<CommandExecutionApprovalDecision>,
network_approval_context: Option<NetworkApprovalContext>,
additional_permissions: Option<AdditionalPermissionProfile>,
},
Permissions {
thread_id: ThreadId,
thread_label: Option<String>,
call_id: String,
environment_id: Option<String>,
reason: Option<String>,
permissions: RequestPermissionProfile,
},
ApplyPatch {
thread_id: ThreadId,
thread_label: Option<String>,
id: String,
reason: Option<String>,
cwd: AbsolutePathBuf,
changes: HashMap<PathBuf, FileChange>,
},
McpElicitation {
thread_id: ThreadId,
thread_label: Option<String>,
server_name: String,
request_id: RequestId,
message: String,
},
Exec(ExecApprovalRequest),
Permissions(PermissionsApprovalRequest),
ApplyPatch(ApplyPatchApprovalRequest),
McpElicitation(McpElicitationApprovalRequest),
}
#[derive(Clone, Debug)]
pub(crate) struct ExecApprovalRequest {
pub thread_id: ThreadId,
pub thread_label: Option<String>,
pub id: String,
pub environment_id: Option<String>,
pub command: Vec<String>,
pub reason: Option<String>,
pub available_decisions: Vec<CommandExecutionApprovalDecision>,
pub network_approval_context: Option<NetworkApprovalContext>,
pub additional_permissions: Option<AdditionalPermissionProfile>,
}
#[derive(Clone, Debug)]
pub(crate) struct PermissionsApprovalRequest {
pub thread_id: ThreadId,
pub thread_label: Option<String>,
pub call_id: String,
pub environment_id: Option<String>,
pub reason: Option<String>,
pub permissions: RequestPermissionProfile,
}
#[derive(Clone, Debug)]
pub(crate) struct ApplyPatchApprovalRequest {
pub thread_id: ThreadId,
pub thread_label: Option<String>,
pub id: String,
pub reason: Option<String>,
pub cwd: AbsolutePathBuf,
pub changes: HashMap<PathBuf, FileChange>,
}
#[derive(Clone, Debug)]
pub(crate) struct McpElicitationApprovalRequest {
pub thread_id: ThreadId,
pub thread_label: Option<String>,
pub server_name: String,
pub request_id: RequestId,
pub message: String,
}
impl ApprovalRequest {
fn thread_id(&self) -> ThreadId {
match self {
ApprovalRequest::Exec { thread_id, .. }
| ApprovalRequest::Permissions { thread_id, .. }
| ApprovalRequest::ApplyPatch { thread_id, .. }
| ApprovalRequest::McpElicitation { thread_id, .. } => *thread_id,
ApprovalRequest::Exec(request) => request.thread_id,
ApprovalRequest::Permissions(request) => request.thread_id,
ApprovalRequest::ApplyPatch(request) => request.thread_id,
ApprovalRequest::McpElicitation(request) => request.thread_id,
}
}
fn thread_label(&self) -> Option<&str> {
match self {
ApprovalRequest::Exec { thread_label, .. }
| ApprovalRequest::Permissions { thread_label, .. }
| ApprovalRequest::ApplyPatch { thread_label, .. }
| ApprovalRequest::McpElicitation { thread_label, .. } => thread_label.as_deref(),
ApprovalRequest::Exec(request) => request.thread_label.as_deref(),
ApprovalRequest::Permissions(request) => request.thread_label.as_deref(),
ApprovalRequest::ApplyPatch(request) => request.thread_label.as_deref(),
ApprovalRequest::McpElicitation(request) => request.thread_label.as_deref(),
}
}
pub(super) fn matches_resolved_request(&self, request: &ResolvedAppServerRequest) -> bool {
match (self, request) {
(
ApprovalRequest::Exec { id, .. },
ApprovalRequest::Exec(request),
ResolvedAppServerRequest::ExecApproval { id: resolved_id },
) => id == resolved_id,
) => request.id == *resolved_id,
(
ApprovalRequest::Permissions { call_id, .. },
ApprovalRequest::Permissions(request),
ResolvedAppServerRequest::PermissionsApproval { id },
) => call_id == id,
) => request.call_id == *id,
(
ApprovalRequest::ApplyPatch { id, .. },
ApprovalRequest::ApplyPatch(request),
ResolvedAppServerRequest::FileChangeApproval { id: resolved_id },
) => id == resolved_id,
) => request.id == *resolved_id,
(
ApprovalRequest::McpElicitation {
server_name,
request_id,
..
},
ApprovalRequest::McpElicitation(request),
ResolvedAppServerRequest::McpElicitation {
server_name: resolved_server_name,
request_id: resolved_request_id,
},
) => server_name == resolved_server_name && request_id == resolved_request_id,
) => {
request.server_name == *resolved_server_name
&& request.request_id == *resolved_request_id
}
_ => false,
}
}
@@ -239,19 +250,14 @@ impl ApprovalOverlay {
list_keymap: &ListKeymap,
) -> (Vec<ApprovalOption>, SelectionViewParams) {
let (options, title) = match request {
ApprovalRequest::Exec {
available_decisions,
network_approval_context,
additional_permissions,
..
} => (
ApprovalRequest::Exec(request) => (
exec_options(
available_decisions,
network_approval_context.as_ref(),
additional_permissions.as_ref(),
&request.available_decisions,
request.network_approval_context.as_ref(),
request.additional_permissions.as_ref(),
approval_keymap,
),
network_approval_context.as_ref().map_or_else(
request.network_approval_context.as_ref().map_or_else(
|| "Would you like to run the following command?".to_string(),
|network_approval_context| {
format!(
@@ -261,17 +267,17 @@ impl ApprovalOverlay {
},
),
),
ApprovalRequest::Permissions { .. } => (
ApprovalRequest::Permissions(_) => (
permissions_options(approval_keymap),
"Would you like to grant these permissions?".to_string(),
),
ApprovalRequest::ApplyPatch { .. } => (
ApprovalRequest::ApplyPatch(_) => (
patch_options(approval_keymap),
"Would you like to make the following edits?".to_string(),
),
ApprovalRequest::McpElicitation { server_name, .. } => (
ApprovalRequest::McpElicitation(request) => (
elicitation_options(approval_keymap),
format!("{server_name} needs your approval."),
format!("{} needs your approval.", request.server_name),
),
};
@@ -310,35 +316,31 @@ impl ApprovalOverlay {
};
if let Some(request) = self.current_request.as_ref() {
match (request, &option.decision) {
(
ApprovalRequest::Exec { id, command, .. },
ApprovalDecision::Command(decision),
) => {
self.handle_exec_decision(id, command, decision.clone());
(ApprovalRequest::Exec(request), ApprovalDecision::Command(decision)) => {
self.handle_exec_decision(&request.id, &request.command, decision.clone());
}
(
ApprovalRequest::Permissions {
call_id,
permissions,
..
},
ApprovalRequest::Permissions(request),
ApprovalDecision::Permissions(decision),
) => self.handle_permissions_decision(call_id, permissions, *decision),
(
ApprovalRequest::ApplyPatch { id, .. },
ApprovalDecision::FileChange(decision),
) => {
self.handle_patch_decision(id, decision.clone());
self.handle_permissions_decision(
&request.call_id,
&request.permissions,
*decision,
);
}
(ApprovalRequest::ApplyPatch(request), ApprovalDecision::FileChange(decision)) => {
self.handle_patch_decision(&request.id, decision.clone());
}
(
ApprovalRequest::McpElicitation {
server_name,
request_id,
..
},
ApprovalRequest::McpElicitation(request),
ApprovalDecision::McpElicitation(decision),
) => {
self.handle_elicitation_decision(server_name, request_id, *decision);
self.handle_elicitation_decision(
&request.server_name,
&request.request_id,
*decision,
);
}
_ => {}
}
@@ -358,22 +360,22 @@ impl ApprovalOverlay {
return;
};
if request.thread_label().is_none() {
let subject = match request {
ApprovalRequest::Exec {
network_approval_context: Some(network_approval_context),
..
} => history_cell::ApprovalDecisionSubject::NetworkAccess {
let network_approval_context = match request {
ApprovalRequest::Exec(request) => request.network_approval_context.as_ref(),
ApprovalRequest::Permissions(_)
| ApprovalRequest::ApplyPatch(_)
| ApprovalRequest::McpElicitation(_) => None,
};
let subject = if let Some(network_approval_context) = network_approval_context {
history_cell::ApprovalDecisionSubject::NetworkAccess {
target: network_approval_target(network_approval_context, command),
},
_ => {
if let Some(target) = network_approval_command_target(command) {
history_cell::ApprovalDecisionSubject::NetworkAccess {
target: target.to_string(),
}
} else {
history_cell::ApprovalDecisionSubject::Command(command.to_vec())
}
}
} else if let Some(target) = network_approval_command_target(command) {
history_cell::ApprovalDecisionSubject::NetworkAccess {
target: target.to_string(),
}
} else {
history_cell::ApprovalDecisionSubject::Command(command.to_vec())
};
let cell = history_cell::new_approval_decision_cell(
subject,
@@ -488,35 +490,27 @@ impl ApprovalOverlay {
&& let Some(request) = self.current_request.as_ref()
{
match request {
ApprovalRequest::Exec { id, command, .. } => {
ApprovalRequest::Exec(request) => {
self.handle_exec_decision(
id,
command,
&request.id,
&request.command,
CommandExecutionApprovalDecision::Cancel,
);
}
ApprovalRequest::Permissions {
call_id,
permissions,
..
} => {
ApprovalRequest::Permissions(request) => {
self.handle_permissions_decision(
call_id,
permissions,
&request.call_id,
&request.permissions,
PermissionsDecision::Deny,
);
}
ApprovalRequest::ApplyPatch { id, .. } => {
self.handle_patch_decision(id, FileChangeApprovalDecision::Cancel);
ApprovalRequest::ApplyPatch(request) => {
self.handle_patch_decision(&request.id, FileChangeApprovalDecision::Cancel);
}
ApprovalRequest::McpElicitation {
server_name,
request_id,
..
} => {
ApprovalRequest::McpElicitation(request) => {
self.handle_elicitation_decision(
server_name,
request_id,
&request.server_name,
&request.request_id,
McpServerElicitationAction::Cancel,
);
}
@@ -675,35 +669,27 @@ fn network_approval_command_target(command: &[String]) -> Option<&str> {
fn build_header(request: &ApprovalRequest) -> Box<dyn Renderable> {
match request {
ApprovalRequest::Exec {
thread_label,
environment_id,
reason,
command,
network_approval_context,
additional_permissions,
..
} => {
ApprovalRequest::Exec(request) => {
let mut header: Vec<Line<'static>> = Vec::new();
if let Some(thread_label) = thread_label {
if let Some(thread_label) = &request.thread_label {
header.push(Line::from(vec![
"Thread: ".into(),
thread_label.clone().bold(),
]));
header.push(Line::from(""));
}
if let Some(environment_id) = environment_id {
if let Some(environment_id) = &request.environment_id {
header.push(Line::from(vec![
"Environment: ".into(),
environment_id.clone().bold(),
]));
header.push(Line::from(""));
}
if let Some(reason) = reason {
if let Some(reason) = &request.reason {
header.push(Line::from(vec!["Reason: ".into(), reason.clone().italic()]));
header.push(Line::from(""));
}
if let Some(additional_permissions) = additional_permissions
if let Some(additional_permissions) = &request.additional_permissions
&& let Some(rule_line) = format_additional_permissions_rule(additional_permissions)
{
header.push(Line::from(vec![
@@ -712,43 +698,37 @@ fn build_header(request: &ApprovalRequest) -> Box<dyn Renderable> {
]));
header.push(Line::from(""));
}
let full_cmd = strip_bash_lc_and_escape(command);
let full_cmd = strip_bash_lc_and_escape(&request.command);
let mut full_cmd_lines = highlight_bash_to_lines(&full_cmd);
if let Some(first) = full_cmd_lines.first_mut() {
first.spans.insert(0, Span::from("$ "));
}
if network_approval_context.is_none() {
if request.network_approval_context.is_none() {
header.extend(full_cmd_lines);
}
Box::new(Paragraph::new(header).wrap(Wrap { trim: false }))
}
ApprovalRequest::Permissions {
thread_label,
environment_id,
reason,
permissions,
..
} => {
ApprovalRequest::Permissions(request) => {
let mut header: Vec<Line<'static>> = Vec::new();
if let Some(thread_label) = thread_label {
if let Some(thread_label) = &request.thread_label {
header.push(Line::from(vec![
"Thread: ".into(),
thread_label.clone().bold(),
]));
header.push(Line::from(""));
}
if let Some(environment_id) = environment_id {
if let Some(environment_id) = &request.environment_id {
header.push(Line::from(vec![
"Environment: ".into(),
environment_id.clone().bold(),
]));
header.push(Line::from(""));
}
if let Some(reason) = reason {
if let Some(reason) = &request.reason {
header.push(Line::from(vec!["Reason: ".into(), reason.clone().italic()]));
header.push(Line::from(""));
}
if let Some(rule_line) = format_requested_permissions_rule(permissions) {
if let Some(rule_line) = format_requested_permissions_rule(&request.permissions) {
header.push(Line::from(vec![
"Permission rule: ".into(),
rule_line.cyan(),
@@ -756,19 +736,15 @@ fn build_header(request: &ApprovalRequest) -> Box<dyn Renderable> {
}
Box::new(Paragraph::new(header).wrap(Wrap { trim: false }))
}
ApprovalRequest::ApplyPatch {
thread_label,
reason,
..
} => {
ApprovalRequest::ApplyPatch(request) => {
let mut header: Vec<Box<dyn Renderable>> = Vec::new();
if let Some(thread_label) = thread_label {
if let Some(thread_label) = &request.thread_label {
header.push(Box::new(Line::from(vec![
"Thread: ".into(),
thread_label.clone().bold(),
])));
}
if let Some(reason) = reason
if let Some(reason) = &request.reason
&& !reason.is_empty()
{
if !header.is_empty() {
@@ -784,14 +760,9 @@ fn build_header(request: &ApprovalRequest) -> Box<dyn Renderable> {
}
Box::new(ColumnRenderable::with(header))
}
ApprovalRequest::McpElicitation {
thread_label,
server_name,
message,
..
} => {
ApprovalRequest::McpElicitation(request) => {
let mut lines = Vec::new();
if let Some(thread_label) = thread_label {
if let Some(thread_label) = &request.thread_label {
lines.push(Line::from(vec![
"Thread: ".into(),
thread_label.clone().bold(),
@@ -799,9 +770,9 @@ fn build_header(request: &ApprovalRequest) -> Box<dyn Renderable> {
lines.push(Line::from(""));
}
lines.extend([
Line::from(vec!["Server: ".into(), server_name.clone().bold()]),
Line::from(vec!["Server: ".into(), request.server_name.clone().bold()]),
Line::from(""),
Line::from(message.clone()),
Line::from(request.message.clone()),
]);
let header = Paragraph::new(lines).wrap(Wrap { trim: false });
Box::new(header)
@@ -1226,7 +1197,7 @@ mod tests {
}
fn make_exec_request() -> ApprovalRequest {
ApprovalRequest::Exec {
ApprovalRequest::Exec(ExecApprovalRequest {
thread_id: ThreadId::new(),
thread_label: None,
id: "test".to_string(),
@@ -1239,11 +1210,11 @@ mod tests {
],
network_approval_context: None,
additional_permissions: None,
}
})
}
fn make_permissions_request() -> ApprovalRequest {
ApprovalRequest::Permissions {
ApprovalRequest::Permissions(PermissionsApprovalRequest {
thread_id: ThreadId::new(),
thread_label: None,
call_id: "test".to_string(),
@@ -1258,17 +1229,17 @@ mod tests {
Some(vec![absolute_path("/tmp/out.txt")]),
)),
},
}
})
}
fn make_elicitation_request() -> ApprovalRequest {
ApprovalRequest::McpElicitation {
ApprovalRequest::McpElicitation(McpElicitationApprovalRequest {
thread_id: ThreadId::new(),
thread_label: None,
server_name: "test-server".to_string(),
request_id: RequestId::String("request-1".to_string()),
message: "Need more information".to_string(),
}
})
}
#[test]
@@ -1367,7 +1338,7 @@ mod tests {
let (tx, mut rx) = unbounded_channel::<AppEvent>();
let tx = AppEventSender::new(tx);
let mut view = make_overlay(
ApprovalRequest::Exec {
ApprovalRequest::Exec(ExecApprovalRequest {
thread_id: ThreadId::new(),
thread_label: None,
id: "test".to_string(),
@@ -1380,7 +1351,7 @@ mod tests {
],
network_approval_context: None,
additional_permissions: None,
},
}),
tx,
Features::with_defaults(),
);
@@ -1411,7 +1382,7 @@ mod tests {
action: NetworkPolicyRuleAction::Deny,
};
let mut view = make_overlay(
ApprovalRequest::Exec {
ApprovalRequest::Exec(ExecApprovalRequest {
thread_id: ThreadId::new(),
thread_label: None,
id: "test".to_string(),
@@ -1429,7 +1400,7 @@ mod tests {
protocol: NetworkApprovalProtocol::Https,
}),
additional_permissions: None,
},
}),
tx,
Features::with_defaults(),
);
@@ -1486,7 +1457,7 @@ mod tests {
let tx = AppEventSender::new(tx);
let thread_id = ThreadId::new();
let mut view = make_overlay(
ApprovalRequest::Exec {
ApprovalRequest::Exec(ExecApprovalRequest {
thread_id,
thread_label: Some("Robie [explorer]".to_string()),
id: "test".to_string(),
@@ -1499,7 +1470,7 @@ mod tests {
],
network_approval_context: None,
additional_permissions: None,
},
}),
tx,
Features::with_defaults(),
);
@@ -1521,7 +1492,7 @@ mod tests {
let mut keymap = crate::keymap::RuntimeKeymap::defaults();
keymap.approval.open_thread = vec![key_hint::plain(KeyCode::Char('x'))];
let mut view = make_overlay_with_keymap(
ApprovalRequest::Exec {
ApprovalRequest::Exec(ExecApprovalRequest {
thread_id,
thread_label: Some("Robie [explorer]".to_string()),
id: "test".to_string(),
@@ -1534,7 +1505,7 @@ mod tests {
],
network_approval_context: None,
additional_permissions: None,
},
}),
tx,
Features::with_defaults(),
keymap.approval,
@@ -1560,7 +1531,7 @@ mod tests {
let (tx, _rx) = unbounded_channel::<AppEvent>();
let tx = AppEventSender::new(tx);
let view = make_overlay(
ApprovalRequest::Exec {
ApprovalRequest::Exec(ExecApprovalRequest {
thread_id: ThreadId::new(),
thread_label: Some("Robie [explorer]".to_string()),
id: "test".to_string(),
@@ -1573,7 +1544,7 @@ mod tests {
],
network_approval_context: None,
additional_permissions: None,
},
}),
tx,
Features::with_defaults(),
);
@@ -1589,7 +1560,7 @@ mod tests {
let (tx, mut rx) = unbounded_channel::<AppEvent>();
let tx = AppEventSender::new(tx);
let mut view = make_overlay(
ApprovalRequest::Exec {
ApprovalRequest::Exec(ExecApprovalRequest {
thread_id: ThreadId::new(),
thread_label: None,
id: "test".to_string(),
@@ -1607,7 +1578,7 @@ mod tests {
],
network_approval_context: None,
additional_permissions: None,
},
}),
tx,
Features::with_defaults(),
);
@@ -1642,7 +1613,7 @@ mod tests {
let (tx, mut rx) = unbounded_channel::<AppEvent>();
let tx = AppEventSender::new(tx);
let mut view = make_overlay(
ApprovalRequest::Exec {
ApprovalRequest::Exec(ExecApprovalRequest {
thread_id: ThreadId::new(),
thread_label: None,
id: "test".to_string(),
@@ -1665,7 +1636,7 @@ mod tests {
protocol: NetworkApprovalProtocol::Https,
}),
additional_permissions: None,
},
}),
tx,
Features::with_defaults(),
);
@@ -1682,7 +1653,7 @@ mod tests {
let (tx, _rx) = unbounded_channel::<AppEvent>();
let tx = AppEventSender::new(tx);
let command = vec!["echo".into(), "hello".into(), "world".into()];
let exec_request = ApprovalRequest::Exec {
let exec_request = ApprovalRequest::Exec(ExecApprovalRequest {
thread_id: ThreadId::new(),
thread_label: None,
id: "test".into(),
@@ -1695,7 +1666,7 @@ mod tests {
],
network_approval_context: None,
additional_permissions: None,
};
});
let view = make_overlay(exec_request, tx, Features::with_defaults());
let mut buf = Buffer::empty(Rect::new(0, 0, 80, view.desired_height(/*width*/ 80)));
@@ -1983,7 +1954,7 @@ mod tests {
fn additional_permissions_prompt_shows_permission_rule_line() {
let (tx, _rx) = unbounded_channel::<AppEvent>();
let tx = AppEventSender::new(tx);
let exec_request = ApprovalRequest::Exec {
let exec_request = ApprovalRequest::Exec(ExecApprovalRequest {
thread_id: ThreadId::new(),
thread_label: None,
id: "test".into(),
@@ -2007,7 +1978,7 @@ mod tests {
.into(),
),
}),
};
});
let view = make_overlay(exec_request, tx, Features::with_defaults());
let mut buf = Buffer::empty(Rect::new(0, 0, 100, view.desired_height(/*width*/ 100)));
@@ -2040,7 +2011,7 @@ mod tests {
fn additional_permissions_prompt_snapshot() {
let (tx, _rx) = unbounded_channel::<AppEvent>();
let tx = AppEventSender::new(tx);
let exec_request = ApprovalRequest::Exec {
let exec_request = ApprovalRequest::Exec(ExecApprovalRequest {
thread_id: ThreadId::new(),
thread_label: None,
id: "test".into(),
@@ -2064,7 +2035,7 @@ mod tests {
.into(),
),
}),
};
});
let view = make_overlay(exec_request, tx, Features::with_defaults());
assert_snapshot!(
@@ -2095,14 +2066,14 @@ mod tests {
content: "one\ntwo\nthree\n".to_string(),
},
);
let request = ApprovalRequest::ApplyPatch {
let request = ApprovalRequest::ApplyPatch(ApplyPatchApprovalRequest {
thread_id: ThreadId::new(),
thread_label: Some("Banach [worker]".to_string()),
id: "test".to_string(),
reason: None,
cwd: absolute_path("/tmp"),
changes,
};
});
let keymap = crate::keymap::RuntimeKeymap::defaults();
let view = ApprovalOverlay::new(
request,
@@ -2121,7 +2092,7 @@ mod tests {
fn network_exec_prompt_title_includes_host() {
let (tx, _rx) = unbounded_channel::<AppEvent>();
let tx = AppEventSender::new(tx);
let exec_request = ApprovalRequest::Exec {
let exec_request = ApprovalRequest::Exec(ExecApprovalRequest {
thread_id: ThreadId::new(),
thread_label: None,
id: "test".into(),
@@ -2144,7 +2115,7 @@ mod tests {
protocol: NetworkApprovalProtocol::Https,
}),
additional_permissions: None,
};
});
let view = make_overlay(exec_request, tx, Features::with_defaults());
let mut buf = Buffer::empty(Rect::new(0, 0, 100, view.desired_height(/*width*/ 100)));
@@ -2258,7 +2229,7 @@ mod tests {
let (tx_raw, mut rx) = unbounded_channel::<AppEvent>();
let tx = AppEventSender::new(tx_raw);
let mut view = make_overlay(
ApprovalRequest::Exec {
ApprovalRequest::Exec(ExecApprovalRequest {
thread_id: ThreadId::new(),
thread_label: None,
id: "test".into(),
@@ -2274,7 +2245,7 @@ mod tests {
],
network_approval_context: None,
additional_permissions: None,
},
}),
tx,
Features::with_defaults(),
);
+6 -2
View File
@@ -66,8 +66,12 @@ pub(crate) use app_link_view::AppLinkElicitationTarget;
pub(crate) use app_link_view::AppLinkSuggestionType;
pub(crate) use app_link_view::AppLinkView;
pub(crate) use app_link_view::AppLinkViewParams;
pub(crate) use approval_overlay::ApplyPatchApprovalRequest;
pub(crate) use approval_overlay::ApprovalOverlay;
pub(crate) use approval_overlay::ApprovalRequest;
pub(crate) use approval_overlay::ExecApprovalRequest;
pub(crate) use approval_overlay::McpElicitationApprovalRequest;
pub(crate) use approval_overlay::PermissionsApprovalRequest;
pub(crate) use approval_overlay::format_requested_permissions_rule;
pub(crate) use mcp_server_elicitation::McpServerElicitationFormRequest;
pub(crate) use mcp_server_elicitation::McpServerElicitationOverlay;
@@ -1906,7 +1910,7 @@ mod tests {
}
fn exec_request() -> ApprovalRequest {
ApprovalRequest::Exec {
ApprovalRequest::Exec(ExecApprovalRequest {
thread_id: codex_protocol::ThreadId::new(),
thread_label: None,
id: "1".to_string(),
@@ -1919,7 +1923,7 @@ mod tests {
],
network_approval_context: None,
additional_permissions: None,
}
})
}
#[derive(Default)]