feat(tui2) /personality

This commit is contained in:
Dylan Hurd
2026-01-20 14:48:09 -08:00
parent 24ab98ed85
commit 4d98928c00
13 changed files with 111 additions and 28 deletions

View File

@@ -2020,6 +2020,9 @@ impl ChatWidget {
SlashCommand::Approvals => {
self.open_approvals_popup();
}
SlashCommand::Permissions => {
self.open_permissions_popup();
}
SlashCommand::ElevateSandbox => {
#[cfg(target_os = "windows")]
{
@@ -3225,6 +3228,52 @@ impl ChatWidget {
/// Open a popup to choose the approvals mode (ask for approval policy + sandbox policy).
pub(crate) fn open_approvals_popup(&mut self) {
self.open_approval_mode_popup(
"Update Model Permissions",
true,
false,
|preset, is_windows_degraded| {
if preset.id == "auto" && is_windows_degraded {
"Agent (non-elevated sandbox)".to_string()
} else {
preset.label.to_string()
}
},
|preset| preset.description.to_string(),
);
}
/// Open a popup to choose the permissions mode (approval policy + sandbox policy).
pub(crate) fn open_permissions_popup(&mut self) {
let include_read_only = cfg!(target_os = "windows");
self.open_approval_mode_popup(
"Update Model Permissions",
include_read_only,
true,
|preset, _| match preset.id {
"read-only" => "Read Only".to_string(),
"auto" => "Default".to_string(),
"full-access" => "Full Access".to_string(),
_ => preset.label.to_string(),
},
|preset| match preset.id {
"auto" => format!("{} Identical to Agent approvals.", preset.description),
_ => preset.description.to_string(),
},
);
}
fn open_approval_mode_popup<F, D>(
&mut self,
title: &str,
include_read_only: bool,
return_to_permissions: bool,
label_for_preset: F,
description_for_preset: D,
) where
F: Fn(&ApprovalPreset, bool) -> String,
D: Fn(&ApprovalPreset) -> String,
{
let current_approval = self.config.approval_policy.value();
let current_sandbox = self.config.sandbox_policy.get();
let mut items: Vec<SelectionItem> = Vec::new();
@@ -3241,15 +3290,13 @@ impl ChatWidget {
&& presets.iter().any(|preset| preset.id == "auto");
for preset in presets.into_iter() {
if !include_read_only && preset.id == "read-only" {
continue;
}
let is_current =
Self::preset_matches_current(current_approval, current_sandbox, &preset);
let name = if preset.id == "auto" && windows_degraded_sandbox_enabled {
"Agent (non-elevated sandbox)".to_string()
} else {
preset.label.to_string()
};
let description_text = preset.description;
let description = Some(description_text.to_string());
let name = label_for_preset(&preset, windows_degraded_sandbox_enabled);
let description = Some(description_for_preset(&preset));
let requires_confirmation = preset.id == "full-access"
&& !self
.config
@@ -3261,6 +3308,7 @@ impl ChatWidget {
vec![Box::new(move |tx| {
tx.send(AppEvent::OpenFullAccessConfirmation {
preset: preset_clone.clone(),
return_to_permissions,
});
})]
} else if preset.id == "auto" {
@@ -3329,7 +3377,7 @@ impl ChatWidget {
});
self.bottom_pane.show_selection_view(SelectionViewParams {
title: Some("Select Approval Mode".to_string()),
title: Some(title.to_string()),
footer_note,
footer_hint: Some(standard_popup_hint_line()),
items,
@@ -3410,7 +3458,11 @@ impl ChatWidget {
None
}
pub(crate) fn open_full_access_confirmation(&mut self, preset: ApprovalPreset) {
pub(crate) fn open_full_access_confirmation(
&mut self,
preset: ApprovalPreset,
return_to_permissions: bool,
) {
let approval = preset.approval;
let sandbox = preset.sandbox;
let mut header_children: Vec<Box<dyn Renderable>> = Vec::new();
@@ -3438,8 +3490,12 @@ impl ChatWidget {
tx.send(AppEvent::PersistFullAccessWarningAcknowledged);
}));
let deny_actions: Vec<SelectionAction> = vec![Box::new(|tx| {
tx.send(AppEvent::OpenApprovalsPopup);
let deny_actions: Vec<SelectionAction> = vec![Box::new(move |tx| {
if return_to_permissions {
tx.send(AppEvent::OpenPermissionsPopup);
} else {
tx.send(AppEvent::OpenApprovalsPopup);
}
})];
let items = vec![