Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/goose-cli/src/commands/acp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ impl GooseAcpAgent {
toolshim_model: None,
fast_model: None,
};
let provider = create(&provider_name, model_config)?;
let provider = create(&provider_name, model_config).await?;

// Create a shared agent instance
let agent = Agent::new();
Expand Down
14 changes: 7 additions & 7 deletions crates/goose-cli/src/commands/configure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ async fn handle_oauth_configuration(

// Create a temporary provider instance to handle OAuth
let temp_model = ModelConfig::new("temp")?;
match create(provider_name, temp_model) {
match create(provider_name, temp_model).await {
Ok(provider) => match provider.configure_oauth().await {
Ok(_) => {
let _ = cliclack::log::success("OAuth authentication completed successfully!");
Expand Down Expand Up @@ -420,7 +420,7 @@ pub async fn configure_provider_dialog() -> Result<bool, Box<dyn Error>> {
let config = Config::global();

// Get all available providers and their metadata
let available_providers = providers();
let available_providers = providers().await;

// Create selection items from provider metadata
let provider_items: Vec<(&String, &str, &str)> = available_providers
Expand Down Expand Up @@ -550,7 +550,7 @@ pub async fn configure_provider_dialog() -> Result<bool, Box<dyn Error>> {
spin.start("Attempting to fetch supported models...");
let models_res = {
let temp_model_config = ModelConfig::new(&provider_meta.default_model)?;
let temp_provider = create(provider_name, temp_model_config)?;
let temp_provider = create(provider_name, temp_model_config).await?;
temp_provider.fetch_supported_models().await
};
spin.stop(style("Model fetch complete").green());
Expand Down Expand Up @@ -586,7 +586,7 @@ pub async fn configure_provider_dialog() -> Result<bool, Box<dyn Error>> {
.with_toolshim(toolshim_enabled)
.with_toolshim_model(std::env::var("GOOSE_TOOLSHIM_OLLAMA_MODEL").ok());

let provider = create(provider_name, model_config)?;
let provider = create(provider_name, model_config).await?;

let messages =
vec![Message::user().with_text("What is the weather like in San Francisco today?")];
Expand Down Expand Up @@ -1419,7 +1419,7 @@ pub async fn configure_tool_permissions_dialog() -> Result<(), Box<dyn Error>> {

// Create the agent
let agent = Agent::new();
let new_provider = create(&provider_name, model_config)?;
let new_provider = create(&provider_name, model_config).await?;
agent.update_provider(new_provider).await?;
if let Some(config) = get_extension_by_name(&selected_extension_name) {
agent
Expand Down Expand Up @@ -1688,7 +1688,7 @@ pub async fn handle_openrouter_auth() -> Result<(), Box<dyn Error>> {
}
};

match create("openrouter", model_config) {
match create("openrouter", model_config).await {
Ok(provider) => {
// Simple test request
let test_result = provider
Expand Down Expand Up @@ -1787,7 +1787,7 @@ pub async fn handle_tetrate_auth() -> Result<(), Box<dyn Error>> {
}
};

match create("tetrate", model_config) {
match create("tetrate", model_config).await {
Ok(provider) => {
// Simple test request
let test_result = provider
Expand Down
3 changes: 1 addition & 2 deletions crates/goose-cli/src/commands/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ pub async fn handle_web(
// Setup logging
crate::logging::setup_logging(Some("goose-web"), None)?;

// Load config and create agent just like the CLI does
let config = goose::config::Config::global();

let provider_name: String = match config.get_param("GOOSE_PROVIDER") {
Expand All @@ -160,7 +159,7 @@ pub async fn handle_web(

// Create the agent
let agent = Agent::new();
let provider = goose::providers::create(&provider_name, model_config)?;
let provider = goose::providers::create(&provider_name, model_config).await?;
agent.update_provider(provider).await?;

// Load and enable extensions from config
Expand Down
2 changes: 1 addition & 1 deletion crates/goose-cli/src/scenario_tests/scenario_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ where

let original_env = setup_environment(config)?;

let inner_provider = create(&factory_name, ModelConfig::new(config.model_name)?)?;
let inner_provider = create(&factory_name, ModelConfig::new(config.model_name)?).await?;

let test_provider = Arc::new(TestProvider::new_recording(inner_provider, &file_path));
(
Expand Down
2 changes: 1 addition & 1 deletion crates/goose-cli/src/session/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ pub async fn build_session(session_config: SessionBuilderConfig) -> CliSession {
agent.add_final_output_tool(final_output_response).await;
}

let new_provider = match create(&provider_name, model_config) {
let new_provider = match create(&provider_name, model_config).await {
Ok(provider) => provider,
Err(e) => {
output::render_error(&format!(
Expand Down
8 changes: 4 additions & 4 deletions crates/goose-cli/src/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ impl CliSession {
RunMode::Plan => {
let mut plan_messages = self.messages.clone();
plan_messages.push(Message::user().with_text(&content));
let reasoner = get_reasoner()?;
let reasoner = get_reasoner().await?;
self.plan_with_reasoner_model(plan_messages, reasoner)
.await?;
}
Expand Down Expand Up @@ -581,7 +581,7 @@ impl CliSession {
let mut plan_messages = self.messages.clone();
plan_messages.push(Message::user().with_text(&message_text));

let reasoner = get_reasoner()?;
let reasoner = get_reasoner().await?;
self.plan_with_reasoner_model(plan_messages, reasoner)
.await?;
}
Expand Down Expand Up @@ -1632,7 +1632,7 @@ impl CliSession {
}
}

fn get_reasoner() -> Result<Arc<dyn Provider>, anyhow::Error> {
async fn get_reasoner() -> Result<Arc<dyn Provider>, anyhow::Error> {
use goose::model::ModelConfig;
use goose::providers::create;

Expand Down Expand Up @@ -1660,7 +1660,7 @@ fn get_reasoner() -> Result<Arc<dyn Provider>, anyhow::Error> {

let model_config =
ModelConfig::new_with_context_env(model, Some("GOOSE_PLANNER_CONTEXT_LIMIT"))?;
let reasoner = create(&provider, model_config)?;
let reasoner = create(&provider, model_config).await?;

Ok(reasoner)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/goose-server/src/routes/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ async fn update_agent_provider(
StatusCode::BAD_REQUEST
})?;

let new_provider = create(&payload.provider, model_config).map_err(|e| {
let new_provider = create(&payload.provider, model_config).await.map_err(|e| {
tracing::error!("Failed to create provider: {}", e);
StatusCode::BAD_REQUEST
})?;
Expand Down
11 changes: 6 additions & 5 deletions crates/goose-server/src/routes/config_management.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ pub async fn read_all_config() -> Result<Json<ConfigResponse>, StatusCode> {
)
)]
pub async fn providers() -> Result<Json<Vec<ProviderDetails>>, StatusCode> {
let mut providers_metadata = get_providers();
let mut providers_metadata = get_providers().await;

let custom_providers_dir = goose::config::custom_providers::custom_providers_dir();

Expand Down Expand Up @@ -347,7 +347,7 @@ pub async fn providers() -> Result<Json<Vec<ProviderDetails>>, StatusCode> {
pub async fn get_provider_models(
Path(name): Path<String>,
) -> Result<Json<Vec<String>>, StatusCode> {
let all = get_providers();
let all = get_providers().await;
let Some(metadata) = all.into_iter().find(|m| m.name == name) else {
return Err(StatusCode::BAD_REQUEST);
};
Expand All @@ -358,6 +358,7 @@ pub async fn get_provider_models(
let model_config =
ModelConfig::new(&metadata.default_model).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
let provider = goose::providers::create(&name, model_config)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

match provider.fetch_supported_models().await {
Expand Down Expand Up @@ -449,7 +450,7 @@ pub async fn get_pricing(
}
} else {
// Get only configured providers' pricing
let providers_metadata = get_providers();
let providers_metadata = get_providers().await;

for metadata in providers_metadata {
// Skip unconfigured providers if filtering
Expand Down Expand Up @@ -684,7 +685,7 @@ pub async fn create_custom_provider(
)
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

if let Err(e) = goose::providers::refresh_custom_providers() {
if let Err(e) = goose::providers::refresh_custom_providers().await {
tracing::warn!("Failed to refresh custom providers after creation: {}", e);
}

Expand All @@ -706,7 +707,7 @@ pub async fn remove_custom_provider(
goose::config::custom_providers::CustomProviderConfig::remove(&id)
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

if let Err(e) = goose::providers::refresh_custom_providers() {
if let Err(e) = goose::providers::refresh_custom_providers().await {
tracing::warn!("Failed to refresh custom providers after deletion: {}", e);
}

Expand Down
11 changes: 5 additions & 6 deletions crates/goose/examples/agent.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
use std::sync::Arc;

use dotenvy::dotenv;
use futures::StreamExt;
use goose::agents::{Agent, AgentEvent, ExtensionConfig};
use goose::config::{DEFAULT_EXTENSION_DESCRIPTION, DEFAULT_EXTENSION_TIMEOUT};
use goose::conversation::message::Message;
use goose::conversation::Conversation;
use goose::providers::databricks::DatabricksProvider;
use goose::providers::create_with_named_model;
use goose::providers::databricks::DATABRICKS_DEFAULT_MODEL;

#[tokio::main]
async fn main() {
// Setup a model provider from env vars
let _ = dotenv();

let provider = Arc::new(DatabricksProvider::default());
let provider = create_with_named_model("databricks", DATABRICKS_DEFAULT_MODEL)
.await
.expect("Couldn't create provider");

// Setup an agent with the developer extension
let agent = Agent::new();
let _ = agent.update_provider(provider).await;

Expand Down
9 changes: 3 additions & 6 deletions crates/goose/examples/databricks_oauth.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
use anyhow::Result;
use dotenvy::dotenv;
use goose::conversation::message::Message;
use goose::providers::{
base::{Provider, Usage},
databricks::DatabricksProvider,
};
use goose::providers::databricks::DATABRICKS_DEFAULT_MODEL;
use goose::providers::{base::Usage, create_with_named_model};
use tokio_stream::StreamExt;

#[tokio::main]
async fn main() -> Result<()> {
// Load environment variables from .env file
dotenv().ok();

// Clear any token to force OAuth
std::env::remove_var("DATABRICKS_TOKEN");

// Create the provider
let provider = DatabricksProvider::default();
let provider = create_with_named_model("databricks", DATABRICKS_DEFAULT_MODEL).await?;

// Create a simple message
let message = Message::user().with_text("Tell me a short joke about programming.");
Expand Down
17 changes: 9 additions & 8 deletions crates/goose/examples/image_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@ use anyhow::Result;
use base64::{engine::general_purpose::STANDARD as BASE64, Engine as _};
use dotenvy::dotenv;
use goose::conversation::message::Message;
use goose::providers::{
bedrock::BedrockProvider, databricks::DatabricksProvider, openai::OpenAiProvider,
};
use goose::providers::anthropic::ANTHROPIC_DEFAULT_MODEL;
use goose::providers::create_with_named_model;
use goose::providers::databricks::DATABRICKS_DEFAULT_MODEL;
use goose::providers::openai::OPEN_AI_DEFAULT_MODEL;
use rmcp::model::{CallToolRequestParam, Content, Tool};
use rmcp::object;
use std::fs;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<()> {
// Load environment variables from .env file
dotenv().ok();

// Create providers
let providers: Vec<Box<dyn goose::providers::base::Provider + Send + Sync>> = vec![
Box::new(DatabricksProvider::default()),
Box::new(OpenAiProvider::default()),
Box::new(BedrockProvider::default()),
let providers: Vec<Arc<dyn goose::providers::base::Provider>> = vec![
create_with_named_model("databricks", DATABRICKS_DEFAULT_MODEL).await?,
create_with_named_model("openai", OPEN_AI_DEFAULT_MODEL).await?,
create_with_named_model("anthropic", ANTHROPIC_DEFAULT_MODEL).await?,
];

for provider in providers {
// Read and encode test image
let image_data = fs::read("crates/goose/examples/test_assets/test_image.png")?;
Expand Down
2 changes: 1 addition & 1 deletion crates/goose/src/agents/model_selector/autopilot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ impl AutoPilot {
self.current_role = Some(best_model.role.clone());

let model = crate::model::ModelConfig::new_or_fail(&best_model.model);
let new_provider = providers::create(&best_model.provider, model)?;
let new_provider = providers::create(&best_model.provider, model).await?;

return Ok(Some((
new_provider,
Expand Down
7 changes: 4 additions & 3 deletions crates/goose/src/agents/subagent_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ use crate::{
session::SessionManager,
};
use anyhow::{anyhow, Result};
use futures::future::BoxFuture;
use futures::StreamExt;
use rmcp::model::{ErrorCode, ErrorData};
use std::future::Future;
use std::pin::Pin;
use tracing::debug;

/// Standalone function to run a complete subagent task with output options
Expand Down Expand Up @@ -93,7 +94,7 @@ pub async fn run_complete_subagent_task(
fn get_agent_messages(
text_instruction: String,
task_config: TaskConfig,
) -> BoxFuture<'static, Result<Conversation>> {
) -> Pin<Box<dyn Future<Output = Result<Conversation>> + Send>> {
Box::pin(async move {
let agent_manager = AgentManager::instance()
.await
Expand Down Expand Up @@ -148,7 +149,7 @@ fn get_agent_messages(
Ok(AgentEvent::Message(msg)) => session_messages.push(msg),
Ok(AgentEvent::McpNotification(_))
| Ok(AgentEvent::ModelChange { .. })
| Ok(AgentEvent::HistoryReplaced(_)) => {} // Handle informational events
| Ok(AgentEvent::HistoryReplaced(_)) => {}
Err(e) => {
tracing::error!("Error receiving message from subagent: {}", e);
break;
Expand Down
2 changes: 1 addition & 1 deletion crates/goose/src/execution/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl AgentManager {

if let (Some(provider_name), Some(model_name)) = (provider_name, model_name) {
match ModelConfig::new(&model_name) {
Ok(model_config) => match create(&provider_name, model_config) {
Ok(model_config) => match create(&provider_name, model_config).await {
Ok(provider) => {
self.set_default_provider(provider).await;
info!(
Expand Down
2 changes: 0 additions & 2 deletions crates/goose/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,3 @@ pub mod utils;

#[cfg(test)]
mod cron_test;
#[macro_use]
mod macros;
19 changes: 0 additions & 19 deletions crates/goose/src/macros.rs

This file was deleted.

7 changes: 2 additions & 5 deletions crates/goose/src/providers/anthropic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ use super::formats::anthropic::{
use super::utils::{emit_debug_trace, get_model, map_http_error_to_provider_error};
use crate::config::custom_providers::CustomProviderConfig;
use crate::conversation::message::Message;
use crate::impl_provider_default;
use crate::model::ModelConfig;
use crate::providers::retry::ProviderRetry;
use rmcp::model::Tool;

const ANTHROPIC_DEFAULT_MODEL: &str = "claude-sonnet-4-0";
pub const ANTHROPIC_DEFAULT_MODEL: &str = "claude-sonnet-4-0";
const ANTHROPIC_DEFAULT_FAST_MODEL: &str = "claude-3-7-sonnet-latest";
const ANTHROPIC_KNOWN_MODELS: &[&str] = &[
"claude-sonnet-4-0",
Expand All @@ -45,10 +44,8 @@ pub struct AnthropicProvider {
supports_streaming: bool,
}

impl_provider_default!(AnthropicProvider);

impl AnthropicProvider {
pub fn from_env(model: ModelConfig) -> Result<Self> {
pub async fn from_env(model: ModelConfig) -> Result<Self> {
let model = model.with_fast(ANTHROPIC_DEFAULT_FAST_MODEL.to_string());

let config = crate::config::Config::global();
Expand Down
Loading
Loading