refactor: remove agent flavours, move provider to Agent (#2091)
This commit is contained in:
@@ -3,7 +3,6 @@ use clap::{Args, Parser, Subcommand};
|
||||
|
||||
use goose::config::Config;
|
||||
|
||||
use crate::commands::agent_version::AgentCommand;
|
||||
use crate::commands::bench::agent_generator;
|
||||
use crate::commands::configure::handle_configure;
|
||||
use crate::commands::info::handle_info;
|
||||
@@ -279,9 +278,6 @@ enum Command {
|
||||
builtin: Vec<String>,
|
||||
},
|
||||
|
||||
/// List available agent versions
|
||||
Agents(AgentCommand),
|
||||
|
||||
/// Update the Goose CLI version
|
||||
#[command(about = "Update the goose CLI version")]
|
||||
Update {
|
||||
@@ -417,10 +413,6 @@ pub async fn cli() -> Result<()> {
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
Some(Command::Agents(cmd)) => {
|
||||
cmd.run()?;
|
||||
return Ok(());
|
||||
}
|
||||
Some(Command::Update {
|
||||
canary,
|
||||
reconfigure,
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
use anyhow::Result;
|
||||
use clap::Args;
|
||||
use goose::agents::AgentFactory;
|
||||
use std::fmt::Write;
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct AgentCommand {}
|
||||
|
||||
impl AgentCommand {
|
||||
pub fn run(&self) -> Result<()> {
|
||||
let mut output = String::new();
|
||||
writeln!(output, "Available agent versions:")?;
|
||||
|
||||
let versions = AgentFactory::available_versions();
|
||||
let default_version = AgentFactory::default_version();
|
||||
let configured_version = AgentFactory::configured_version();
|
||||
|
||||
for version in versions {
|
||||
if version == default_version && version == configured_version {
|
||||
writeln!(output, "* {} (default)", version)?;
|
||||
} else if version == default_version {
|
||||
writeln!(output, " {} (default)", version)?;
|
||||
} else if version == configured_version {
|
||||
writeln!(output, "* {}", version)?;
|
||||
} else {
|
||||
writeln!(output, " {}", version)?;
|
||||
}
|
||||
}
|
||||
|
||||
print!("{}", output);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,8 @@ use console::style;
|
||||
use goose::agents::{extension::Envs, ExtensionConfig};
|
||||
use goose::config::extensions::name_to_key;
|
||||
use goose::config::{
|
||||
Config, ConfigError, ExperimentManager, ExtensionEntry, ExtensionManager, PermissionManager,
|
||||
Config, ConfigError, ExperimentManager, ExtensionConfigManager, ExtensionEntry,
|
||||
PermissionManager,
|
||||
};
|
||||
use goose::message::Message;
|
||||
use goose::providers::{create, providers};
|
||||
@@ -63,7 +64,7 @@ pub async fn handle_configure() -> Result<(), Box<dyn Error>> {
|
||||
);
|
||||
// Since we are setting up for the first time, we'll also enable the developer system
|
||||
// This operation is best-effort and errors are ignored
|
||||
ExtensionManager::set(ExtensionEntry {
|
||||
ExtensionConfigManager::set(ExtensionEntry {
|
||||
enabled: true,
|
||||
config: ExtensionConfig::Builtin {
|
||||
name: "developer".to_string(),
|
||||
@@ -392,7 +393,7 @@ pub async fn configure_provider_dialog() -> Result<bool, Box<dyn Error>> {
|
||||
/// Configure extensions that can be used with goose
|
||||
/// Dialog for toggling which extensions are enabled/disabled
|
||||
pub fn toggle_extensions_dialog() -> Result<(), Box<dyn Error>> {
|
||||
let extensions = ExtensionManager::get_all()?;
|
||||
let extensions = ExtensionConfigManager::get_all()?;
|
||||
|
||||
if extensions.is_empty() {
|
||||
cliclack::outro(
|
||||
@@ -430,7 +431,7 @@ pub fn toggle_extensions_dialog() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
// Update enabled status for each extension
|
||||
for name in extension_status.iter().map(|(name, _)| name) {
|
||||
ExtensionManager::set_enabled(
|
||||
ExtensionConfigManager::set_enabled(
|
||||
&name_to_key(name),
|
||||
selected.iter().any(|s| s.as_str() == name),
|
||||
)?;
|
||||
@@ -502,7 +503,7 @@ pub fn configure_extensions_dialog() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
let display_name = get_display_name(&extension);
|
||||
|
||||
ExtensionManager::set(ExtensionEntry {
|
||||
ExtensionConfigManager::set(ExtensionEntry {
|
||||
enabled: true,
|
||||
config: ExtensionConfig::Builtin {
|
||||
name: extension.clone(),
|
||||
@@ -514,7 +515,7 @@ pub fn configure_extensions_dialog() -> Result<(), Box<dyn Error>> {
|
||||
cliclack::outro(format!("Enabled {} extension", style(extension).green()))?;
|
||||
}
|
||||
"stdio" => {
|
||||
let extensions = ExtensionManager::get_all_names()?;
|
||||
let extensions = ExtensionConfigManager::get_all_names()?;
|
||||
let name: String = cliclack::input("What would you like to call this extension?")
|
||||
.placeholder("my-extension")
|
||||
.validate(move |input: &String| {
|
||||
@@ -590,7 +591,7 @@ pub fn configure_extensions_dialog() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
}
|
||||
|
||||
ExtensionManager::set(ExtensionEntry {
|
||||
ExtensionConfigManager::set(ExtensionEntry {
|
||||
enabled: true,
|
||||
config: ExtensionConfig::Stdio {
|
||||
name: name.clone(),
|
||||
@@ -605,7 +606,7 @@ pub fn configure_extensions_dialog() -> Result<(), Box<dyn Error>> {
|
||||
cliclack::outro(format!("Added {} extension", style(name).green()))?;
|
||||
}
|
||||
"sse" => {
|
||||
let extensions = ExtensionManager::get_all_names()?;
|
||||
let extensions = ExtensionConfigManager::get_all_names()?;
|
||||
let name: String = cliclack::input("What would you like to call this extension?")
|
||||
.placeholder("my-remote-extension")
|
||||
.validate(move |input: &String| {
|
||||
@@ -677,7 +678,7 @@ pub fn configure_extensions_dialog() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
}
|
||||
|
||||
ExtensionManager::set(ExtensionEntry {
|
||||
ExtensionConfigManager::set(ExtensionEntry {
|
||||
enabled: true,
|
||||
config: ExtensionConfig::Sse {
|
||||
name: name.clone(),
|
||||
@@ -697,7 +698,7 @@ pub fn configure_extensions_dialog() -> Result<(), Box<dyn Error>> {
|
||||
}
|
||||
|
||||
pub fn remove_extension_dialog() -> Result<(), Box<dyn Error>> {
|
||||
let extensions = ExtensionManager::get_all()?;
|
||||
let extensions = ExtensionConfigManager::get_all()?;
|
||||
|
||||
// Create a list of extension names and their enabled status
|
||||
let extension_status: Vec<(String, bool)> = extensions
|
||||
@@ -739,7 +740,7 @@ pub fn remove_extension_dialog() -> Result<(), Box<dyn Error>> {
|
||||
.interact()?;
|
||||
|
||||
for name in selected {
|
||||
ExtensionManager::remove(&name_to_key(name))?;
|
||||
ExtensionConfigManager::remove(&name_to_key(name))?;
|
||||
let mut permission_manager = PermissionManager::default();
|
||||
permission_manager.remove_extension(&name_to_key(name));
|
||||
cliclack::outro(format!("Removed {} extension", style(name).green()))?;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
pub mod agent_version;
|
||||
pub mod bench;
|
||||
pub mod configure;
|
||||
pub mod info;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use console::style;
|
||||
use goose::agents::extension::ExtensionError;
|
||||
use goose::agents::AgentFactory;
|
||||
use goose::config::{Config, ExtensionManager};
|
||||
use goose::agents::Agent;
|
||||
use goose::config::{Config, ExtensionConfigManager};
|
||||
use goose::session;
|
||||
use goose::session::Identifier;
|
||||
use mcp_client::transport::Error as McpClientError;
|
||||
@@ -33,8 +33,7 @@ pub async fn build_session(
|
||||
goose::providers::create(&provider_name, model_config).expect("Failed to create provider");
|
||||
|
||||
// Create the agent
|
||||
let mut agent = AgentFactory::create(&AgentFactory::configured_version(), provider)
|
||||
.expect("Failed to create agent");
|
||||
let mut agent = Agent::new(provider);
|
||||
|
||||
// Handle session file resolution and resuming
|
||||
let session_file = if resume {
|
||||
@@ -93,7 +92,7 @@ pub async fn build_session(
|
||||
|
||||
// Setup extensions for the agent
|
||||
// Extensions need to be added after the session is created because we change directory when resuming a session
|
||||
for extension in ExtensionManager::get_all().expect("should load extensions") {
|
||||
for extension in ExtensionConfigManager::get_all().expect("should load extensions") {
|
||||
if extension.enabled {
|
||||
let config = extension.config.clone();
|
||||
agent
|
||||
|
||||
@@ -38,7 +38,7 @@ pub enum RunMode {
|
||||
}
|
||||
|
||||
pub struct Session {
|
||||
agent: Box<dyn Agent>,
|
||||
agent: Agent,
|
||||
messages: Vec<Message>,
|
||||
session_file: PathBuf,
|
||||
// Cache for completion data - using std::sync for thread safety without async
|
||||
@@ -76,7 +76,7 @@ pub enum PlannerResponseType {
|
||||
/// question.
|
||||
pub async fn classify_planner_response(
|
||||
message_text: String,
|
||||
provider: Arc<Box<dyn Provider>>,
|
||||
provider: Arc<dyn Provider>,
|
||||
) -> Result<PlannerResponseType> {
|
||||
let prompt = format!("The text below is the output from an AI model which can either provide a plan or list of clarifying questions. Based on the text below, decide if the output is a \"plan\" or \"clarifying questions\".\n---\n{message_text}");
|
||||
|
||||
@@ -101,7 +101,7 @@ pub async fn classify_planner_response(
|
||||
}
|
||||
|
||||
impl Session {
|
||||
pub fn new(agent: Box<dyn Agent>, session_file: PathBuf, debug: bool) -> Self {
|
||||
pub fn new(agent: Agent, session_file: PathBuf, debug: bool) -> Self {
|
||||
let messages = match session::read_messages(&session_file) {
|
||||
Ok(msgs) => msgs,
|
||||
Err(e) => {
|
||||
@@ -278,7 +278,7 @@ impl Session {
|
||||
async fn process_message(&mut self, message: String) -> Result<()> {
|
||||
self.messages.push(Message::user().with_text(&message));
|
||||
// Get the provider from the agent for description generation
|
||||
let provider = self.agent.provider().await;
|
||||
let provider = self.agent.provider();
|
||||
|
||||
// Persist messages with provider for automatic description generation
|
||||
session::persist_messages(&self.session_file, &self.messages, Some(provider)).await?;
|
||||
@@ -350,7 +350,7 @@ impl Session {
|
||||
self.messages.push(Message::user().with_text(&content));
|
||||
|
||||
// Get the provider from the agent for description generation
|
||||
let provider = self.agent.provider().await;
|
||||
let provider = self.agent.provider();
|
||||
|
||||
// Persist messages with provider for automatic description generation
|
||||
session::persist_messages(
|
||||
@@ -535,7 +535,7 @@ impl Session {
|
||||
async fn plan_with_reasoner_model(
|
||||
&mut self,
|
||||
plan_messages: Vec<Message>,
|
||||
reasoner: Box<dyn Provider + Send + Sync>,
|
||||
reasoner: Arc<dyn Provider>,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
let plan_prompt = self.agent.get_plan_prompt().await?;
|
||||
output::show_thinking();
|
||||
@@ -543,7 +543,7 @@ impl Session {
|
||||
output::render_message(&plan_response, self.debug);
|
||||
output::hide_thinking();
|
||||
let planner_response_type =
|
||||
classify_planner_response(plan_response.as_concat_text(), self.agent.provider().await)
|
||||
classify_planner_response(plan_response.as_concat_text(), self.agent.provider())
|
||||
.await?;
|
||||
|
||||
match planner_response_type {
|
||||
@@ -857,7 +857,7 @@ impl Session {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_reasoner() -> Result<Box<dyn Provider + Send + Sync>, anyhow::Error> {
|
||||
fn get_reasoner() -> Result<Arc<dyn Provider>, anyhow::Error> {
|
||||
use goose::model::ModelConfig;
|
||||
use goose::providers::create;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user