mirror of
https://github.com/aljazceru/goose.git
synced 2025-12-23 17:14:22 +01:00
feat: allow user to turn off smart approve (#1407)
This commit is contained in:
@@ -622,24 +622,19 @@ pub fn remove_extension_dialog() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn configure_settings_dialog() -> Result<(), Box<dyn Error>> {
|
pub fn configure_settings_dialog() -> Result<(), Box<dyn Error>> {
|
||||||
let mut setting_select_builder = cliclack::select("What setting would you like to configure?")
|
let setting_type = cliclack::select("What setting would you like to configure?")
|
||||||
.item("goose_mode", "Goose Mode", "Configure Goose mode")
|
.item("goose_mode", "Goose Mode", "Configure Goose mode")
|
||||||
.item(
|
.item(
|
||||||
"tool_output",
|
"tool_output",
|
||||||
"Tool Output",
|
"Tool Output",
|
||||||
"Show more or less tool output",
|
"Show more or less tool output",
|
||||||
);
|
)
|
||||||
|
.item(
|
||||||
// Conditionally add the "Toggle Experiment" option
|
|
||||||
if ExperimentManager::is_enabled("EXPERIMENT_CONFIG")? {
|
|
||||||
setting_select_builder = setting_select_builder.item(
|
|
||||||
"experiment",
|
"experiment",
|
||||||
"Toggle Experiment",
|
"Toggle Experiment",
|
||||||
"Enable or disable an experiment feature",
|
"Enable or disable an experiment feature",
|
||||||
);
|
)
|
||||||
}
|
.interact()?;
|
||||||
|
|
||||||
let setting_type = setting_select_builder.interact()?;
|
|
||||||
|
|
||||||
match setting_type {
|
match setting_type {
|
||||||
"goose_mode" => {
|
"goose_mode" => {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use super::Agent;
|
|||||||
use crate::agents::capabilities::Capabilities;
|
use crate::agents::capabilities::Capabilities;
|
||||||
use crate::agents::extension::{ExtensionConfig, ExtensionResult};
|
use crate::agents::extension::{ExtensionConfig, ExtensionResult};
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
|
use crate::config::ExperimentManager;
|
||||||
use crate::message::{Message, ToolRequest};
|
use crate::message::{Message, ToolRequest};
|
||||||
use crate::providers::base::Provider;
|
use crate::providers::base::Provider;
|
||||||
use crate::providers::base::ProviderUsage;
|
use crate::providers::base::ProviderUsage;
|
||||||
@@ -244,8 +245,11 @@ impl Agent for TruncateAgent {
|
|||||||
let mode = goose_mode.clone();
|
let mode = goose_mode.clone();
|
||||||
match mode.as_str() {
|
match mode.as_str() {
|
||||||
"approve" => {
|
"approve" => {
|
||||||
|
let mut read_only_tools = Vec::new();
|
||||||
// Process each tool request sequentially with confirmation
|
// Process each tool request sequentially with confirmation
|
||||||
let read_only_tools = detect_read_only_tools(&capabilities, tool_requests.clone()).await;
|
if ExperimentManager::is_enabled("GOOSE_SMART_APPROVE")? {
|
||||||
|
read_only_tools = detect_read_only_tools(&capabilities, tool_requests.clone()).await;
|
||||||
|
}
|
||||||
for request in &tool_requests {
|
for request in &tool_requests {
|
||||||
if let Ok(tool_call) = request.tool_call.clone() {
|
if let Ok(tool_call) = request.tool_call.clone() {
|
||||||
// Skip confirmation if the tool_call.name is in the read_only_tools list
|
// Skip confirmation if the tool_call.name is in the read_only_tools list
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use std::collections::HashMap;
|
|||||||
/// It is the ground truth for init experiments. The experiment names in users' experiment list but not
|
/// It is the ground truth for init experiments. The experiment names in users' experiment list but not
|
||||||
/// in the list will be remove from user list; The experiment names in the ground-truth list but not
|
/// in the list will be remove from user list; The experiment names in the ground-truth list but not
|
||||||
/// in users' experiment list will be added to user list with default value false;
|
/// in users' experiment list will be added to user list with default value false;
|
||||||
const ALL_EXPERIMENTS: &[(&str, bool)] = &[("EXPERIMENT_CONFIG", false)];
|
const ALL_EXPERIMENTS: &[(&str, bool)] = &[("GOOSE_SMART_APPROVE", true)];
|
||||||
|
|
||||||
/// Experiment configuration management
|
/// Experiment configuration management
|
||||||
pub struct ExperimentManager;
|
pub struct ExperimentManager;
|
||||||
@@ -19,14 +19,7 @@ impl ExperimentManager {
|
|||||||
pub fn get_all() -> Result<Vec<(String, bool)>> {
|
pub fn get_all() -> Result<Vec<(String, bool)>> {
|
||||||
let config = Config::global();
|
let config = Config::global();
|
||||||
let mut experiments: HashMap<String, bool> = config.get("experiments").unwrap_or_default();
|
let mut experiments: HashMap<String, bool> = config.get("experiments").unwrap_or_default();
|
||||||
|
Self::refresh_experiments(&mut experiments);
|
||||||
// Synchronize the user's experiments with the ground truth (`ALL_EXPERIMENTS`)
|
|
||||||
for &(key, default_value) in ALL_EXPERIMENTS {
|
|
||||||
experiments.entry(key.to_string()).or_insert(default_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove experiments not in `ALL_EXPERIMENTS`
|
|
||||||
experiments.retain(|key, _| ALL_EXPERIMENTS.iter().any(|(k, _)| k == key));
|
|
||||||
|
|
||||||
Ok(experiments.into_iter().collect())
|
Ok(experiments.into_iter().collect())
|
||||||
}
|
}
|
||||||
@@ -34,28 +27,29 @@ impl ExperimentManager {
|
|||||||
/// Enable or disable an experiment
|
/// Enable or disable an experiment
|
||||||
pub fn set_enabled(name: &str, enabled: bool) -> Result<()> {
|
pub fn set_enabled(name: &str, enabled: bool) -> Result<()> {
|
||||||
let config = Config::global();
|
let config = Config::global();
|
||||||
|
|
||||||
// Load existing experiments or initialize a new map
|
|
||||||
let mut experiments: HashMap<String, bool> =
|
let mut experiments: HashMap<String, bool> =
|
||||||
config.get("experiments").unwrap_or_else(|_| HashMap::new());
|
config.get("experiments").unwrap_or_else(|_| HashMap::new());
|
||||||
|
Self::refresh_experiments(&mut experiments);
|
||||||
// Update the status of the experiment
|
|
||||||
experiments.insert(name.to_string(), enabled);
|
experiments.insert(name.to_string(), enabled);
|
||||||
|
|
||||||
// Save the updated experiments map
|
|
||||||
config.set("experiments", serde_json::to_value(experiments)?)?;
|
config.set("experiments", serde_json::to_value(experiments)?)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if an experiment is enabled
|
/// Check if an experiment is enabled
|
||||||
pub fn is_enabled(name: &str) -> Result<bool> {
|
pub fn is_enabled(name: &str) -> Result<bool> {
|
||||||
let config = Config::global();
|
let experiments = Self::get_all()?;
|
||||||
|
let experiments_map: HashMap<String, bool> = experiments.into_iter().collect();
|
||||||
|
Ok(*experiments_map.get(name).unwrap_or(&false))
|
||||||
|
}
|
||||||
|
|
||||||
// Load existing experiments or initialize a new map
|
fn refresh_experiments(experiments: &mut HashMap<String, bool>) {
|
||||||
let experiments: HashMap<String, bool> =
|
// Add missing experiments from `ALL_EXPERIMENTS`
|
||||||
config.get("experiments").unwrap_or_else(|_| HashMap::new());
|
for &(key, default_value) in ALL_EXPERIMENTS {
|
||||||
|
experiments.entry(key.to_string()).or_insert(default_value);
|
||||||
|
}
|
||||||
|
|
||||||
// Return whether the experiment is enabled, defaulting to false
|
// Remove experiments not present in `ALL_EXPERIMENTS`
|
||||||
Ok(*experiments.get(name).unwrap_or(&false))
|
experiments.retain(|key, _| ALL_EXPERIMENTS.iter().any(|(k, _)| k == key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user