refactor: derive GooseMode string conversions with strum (#7706)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
This commit is contained in:
Generated
+2
@@ -4337,6 +4337,7 @@ dependencies = [
|
|||||||
"sha2",
|
"sha2",
|
||||||
"shellexpand",
|
"shellexpand",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
|
"strum",
|
||||||
"symphonia",
|
"symphonia",
|
||||||
"sys-info",
|
"sys-info",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
@@ -4455,6 +4456,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"shlex",
|
"shlex",
|
||||||
|
"strum",
|
||||||
"tar",
|
"tar",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"test-case",
|
"test-case",
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ serde = { version = "1.0", features = ["derive"] }
|
|||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_yaml = "0.9"
|
serde_yaml = "0.9"
|
||||||
shellexpand = "3.1"
|
shellexpand = "3.1"
|
||||||
|
strum = { version = "0.27", features = ["derive"] }
|
||||||
tempfile = "3"
|
tempfile = "3"
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
tokio = { version = "1.49", features = ["full"] }
|
tokio = { version = "1.49", features = ["full"] }
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ tokio = { workspace = true }
|
|||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_yaml = { workspace = true }
|
serde_yaml = { workspace = true }
|
||||||
|
strum = { workspace = true }
|
||||||
tempfile = { workspace = true }
|
tempfile = { workspace = true }
|
||||||
etcetera = { workspace = true }
|
etcetera = { workspace = true }
|
||||||
rand = { workspace = true }
|
rand = { workspace = true }
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use goose::config::GooseMode;
|
||||||
use rustyline::completion::{Completer, FilenameCompleter, Pair};
|
use rustyline::completion::{Completer, FilenameCompleter, Pair};
|
||||||
use rustyline::highlight::{CmdKind, Highlighter};
|
use rustyline::highlight::{CmdKind, Highlighter};
|
||||||
use rustyline::hint::Hinter;
|
use rustyline::hint::Hinter;
|
||||||
@@ -5,6 +6,7 @@ use rustyline::validate::Validator;
|
|||||||
use rustyline::{Context, Helper, Result};
|
use rustyline::{Context, Helper, Result};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use strum::VariantNames;
|
||||||
|
|
||||||
use super::{CompletionCache, HintStatus};
|
use super::{CompletionCache, HintStatus};
|
||||||
|
|
||||||
@@ -81,7 +83,7 @@ impl GooseCompleter {
|
|||||||
|
|
||||||
/// Complete flags for the /mode command
|
/// Complete flags for the /mode command
|
||||||
fn complete_mode_flags(&self, line: &str) -> Result<(usize, Vec<Pair>)> {
|
fn complete_mode_flags(&self, line: &str) -> Result<(usize, Vec<Pair>)> {
|
||||||
let modes = ["auto", "approve", "smart_approve", "chat"];
|
let modes = GooseMode::VARIANTS;
|
||||||
|
|
||||||
let parts: Vec<&str> = line.split_whitespace().collect();
|
let parts: Vec<&str> = line.split_whitespace().collect();
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
use super::completion::GooseCompleter;
|
use super::completion::GooseCompleter;
|
||||||
use super::{CompletionCache, HintStatus};
|
use super::{CompletionCache, HintStatus};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use goose::config::Config;
|
use goose::config::{Config, GooseMode};
|
||||||
use rustyline::Editor;
|
use rustyline::Editor;
|
||||||
use shlex;
|
use shlex;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use strum::VariantNames;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum InputResult {
|
pub enum InputResult {
|
||||||
@@ -409,6 +410,7 @@ fn get_input_prompt_string() -> String {
|
|||||||
|
|
||||||
fn print_help() {
|
fn print_help() {
|
||||||
let newline_key = get_newline_key().to_ascii_uppercase();
|
let newline_key = get_newline_key().to_ascii_uppercase();
|
||||||
|
let modes = GooseMode::VARIANTS.join(", ");
|
||||||
println!(
|
println!(
|
||||||
"Available commands:
|
"Available commands:
|
||||||
/exit or /quit - Exit the session
|
/exit or /quit - Exit the session
|
||||||
@@ -419,7 +421,7 @@ fn print_help() {
|
|||||||
/builtin <names> - Add builtin extensions by name (comma-separated)
|
/builtin <names> - Add builtin extensions by name (comma-separated)
|
||||||
/prompts [--extension <name>] - List all available prompts, optionally filtered by extension
|
/prompts [--extension <name>] - List all available prompts, optionally filtered by extension
|
||||||
/prompt <n> [--info] [key=value...] - Get prompt info or execute a prompt
|
/prompt <n> [--info] [key=value...] - Get prompt info or execute a prompt
|
||||||
/mode <name> - Set the goose mode to use ('auto', 'approve', 'chat', 'smart_approve')
|
/mode <name> - Set the goose mode to use ({modes})
|
||||||
/plan <message_text> - Enters 'plan' mode with optional message. Create a plan based on the current messages and asks user if they want to act on it.
|
/plan <message_text> - Enters 'plan' mode with optional message. Create a plan based on the current messages and asks user if they want to act on it.
|
||||||
If user acts on the plan, goose mode is set to 'auto' and returns to 'normal' goose mode.
|
If user acts on the plan, goose mode is set to 'auto' and returns to 'normal' goose mode.
|
||||||
To warm up goose before using '/plan', we recommend setting '/mode approve' & putting appropriate context into goose.
|
To warm up goose before using '/plan', we recommend setting '/mode approve' & putting appropriate context into goose.
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ use input::InputResult;
|
|||||||
use rmcp::model::PromptMessage;
|
use rmcp::model::PromptMessage;
|
||||||
use rmcp::model::ServerNotification;
|
use rmcp::model::ServerNotification;
|
||||||
use rmcp::model::{ErrorCode, ErrorData};
|
use rmcp::model::{ErrorCode, ErrorData};
|
||||||
|
use strum::VariantNames;
|
||||||
|
|
||||||
use goose::config::paths::Paths;
|
use goose::config::paths::Paths;
|
||||||
use goose::conversation::message::{ActionRequiredData, Message, MessageContent};
|
use goose::conversation::message::{ActionRequiredData, Message, MessageContent};
|
||||||
@@ -717,14 +718,14 @@ impl CliSession {
|
|||||||
Ok(mode) => mode,
|
Ok(mode) => mode,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
output::render_error(&format!(
|
output::render_error(&format!(
|
||||||
"Invalid mode '{}'. Mode must be one of: auto, approve, chat, smart_approve",
|
"Invalid mode '{mode}'. Mode must be one of: {}",
|
||||||
mode
|
GooseMode::VARIANTS.join(", ")
|
||||||
));
|
));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
config.set_goose_mode(mode)?;
|
config.set_goose_mode(mode)?;
|
||||||
output::goose_mode_message(&format!("Goose mode set to '{:?}'", mode));
|
output::goose_mode_message(&format!("Goose mode set to '{mode}'"));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ keyring = { version = "3.6.2", features = [
|
|||||||
"vendored",
|
"vendored",
|
||||||
] }
|
] }
|
||||||
serde_yaml = { workspace = true }
|
serde_yaml = { workspace = true }
|
||||||
|
strum = { workspace = true }
|
||||||
once_cell = { workspace = true }
|
once_cell = { workspace = true }
|
||||||
etcetera = { workspace = true }
|
etcetera = { workspace = true }
|
||||||
rand = { workspace = true }
|
rand = { workspace = true }
|
||||||
|
|||||||
@@ -1,26 +1,24 @@
|
|||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use strum::{Display, EnumString, IntoStaticStr, VariantNames};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
|
#[derive(
|
||||||
|
Copy,
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
Eq,
|
||||||
|
PartialEq,
|
||||||
|
Serialize,
|
||||||
|
Deserialize,
|
||||||
|
Display,
|
||||||
|
EnumString,
|
||||||
|
IntoStaticStr,
|
||||||
|
VariantNames,
|
||||||
|
)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
|
#[strum(serialize_all = "snake_case")]
|
||||||
pub enum GooseMode {
|
pub enum GooseMode {
|
||||||
Auto,
|
Auto,
|
||||||
Approve,
|
Approve,
|
||||||
SmartApprove,
|
SmartApprove,
|
||||||
Chat,
|
Chat,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for GooseMode {
|
|
||||||
type Err = String;
|
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
||||||
match s {
|
|
||||||
"auto" => Ok(GooseMode::Auto),
|
|
||||||
"approve" => Ok(GooseMode::Approve),
|
|
||||||
"smart_approve" => Ok(GooseMode::SmartApprove),
|
|
||||||
"chat" => Ok(GooseMode::Chat),
|
|
||||||
_ => Err(format!("invalid mode: {}", s)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -424,14 +424,8 @@ impl ProviderTester {
|
|||||||
message: &str,
|
message: &str,
|
||||||
label: &str,
|
label: &str,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let mode_str = match mode {
|
|
||||||
GooseMode::Approve => "approve",
|
|
||||||
GooseMode::SmartApprove => "smart_approve",
|
|
||||||
GooseMode::Auto => "auto",
|
|
||||||
GooseMode::Chat => "chat",
|
|
||||||
};
|
|
||||||
// Guard must live through agent.reply() — providers read GOOSE_MODE at spawn time.
|
// Guard must live through agent.reply() — providers read GOOSE_MODE at spawn time.
|
||||||
let _guard = env_lock::lock_env([("GOOSE_MODE", Some(mode_str))]);
|
let _guard = env_lock::lock_env([("GOOSE_MODE", Some(<&str>::from(mode)))]);
|
||||||
let provider = if self.is_cli_provider {
|
let provider = if self.is_cli_provider {
|
||||||
create_with_named_model(
|
create_with_named_model(
|
||||||
&self.name.to_lowercase(),
|
&self.name.to_lowercase(),
|
||||||
|
|||||||
Reference in New Issue
Block a user