diff --git a/crates/goose/src/agents/reply_parts.rs b/crates/goose/src/agents/reply_parts.rs index 7d54e60fb045..1d8fdaea06b4 100644 --- a/crates/goose/src/agents/reply_parts.rs +++ b/crates/goose/src/agents/reply_parts.rs @@ -309,6 +309,10 @@ mod tests { crate::providers::base::ProviderMetadata::empty() } + fn get_name(&self) -> &str { + "mock" + } + fn get_model_config(&self) -> ModelConfig { self.model_config.clone() } diff --git a/crates/goose/src/providers/anthropic.rs b/crates/goose/src/providers/anthropic.rs index 0558e3fe985b..06dbd8fecfad 100644 --- a/crates/goose/src/providers/anthropic.rs +++ b/crates/goose/src/providers/anthropic.rs @@ -43,6 +43,7 @@ pub struct AnthropicProvider { api_client: ApiClient, model: ModelConfig, supports_streaming: bool, + name: String, } impl AnthropicProvider { @@ -67,6 +68,7 @@ impl AnthropicProvider { api_client, model, supports_streaming: true, + name: Self::metadata().name, }) } @@ -91,6 +93,7 @@ impl AnthropicProvider { api_client, model, supports_streaming: config.supports_streaming.unwrap_or(true), + name: config.name.clone(), }) } @@ -176,6 +179,10 @@ impl Provider for AnthropicProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/providers/azure.rs b/crates/goose/src/providers/azure.rs index cd7f51a42af6..d519a82c7345 100644 --- a/crates/goose/src/providers/azure.rs +++ b/crates/goose/src/providers/azure.rs @@ -27,6 +27,7 @@ pub struct AzureProvider { deployment_name: String, api_version: String, model: ModelConfig, + name: String, } impl Serialize for AzureProvider { @@ -94,6 +95,7 @@ impl AzureProvider { deployment_name, api_version, model, + name: Self::metadata().name, }) } @@ -128,6 +130,10 @@ impl Provider for AzureProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/providers/base.rs b/crates/goose/src/providers/base.rs index f8dfadee3757..0067af9fc8f8 100644 --- a/crates/goose/src/providers/base.rs +++ b/crates/goose/src/providers/base.rs @@ -325,6 +325,9 @@ pub trait Provider: Send + Sync { where Self: Sized; + /// Get the name of this provider instance + fn get_name(&self) -> &str; + // Internal implementation of complete, used by complete_fast and complete // Providers should override this to implement their actual completion logic async fn complete_with_model( diff --git a/crates/goose/src/providers/bedrock.rs b/crates/goose/src/providers/bedrock.rs index b5f720692a0a..ff5300484316 100644 --- a/crates/goose/src/providers/bedrock.rs +++ b/crates/goose/src/providers/bedrock.rs @@ -42,6 +42,8 @@ pub struct BedrockProvider { model: ModelConfig, #[serde(skip)] retry_config: RetryConfig, + #[serde(skip)] + name: String, } impl BedrockProvider { @@ -78,6 +80,7 @@ impl BedrockProvider { client, model, retry_config, + name: Self::metadata().name, }) } @@ -184,6 +187,10 @@ impl Provider for BedrockProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn retry_config(&self) -> RetryConfig { self.retry_config.clone() } diff --git a/crates/goose/src/providers/claude_code.rs b/crates/goose/src/providers/claude_code.rs index d27be5ce273f..9683c2ee03d4 100644 --- a/crates/goose/src/providers/claude_code.rs +++ b/crates/goose/src/providers/claude_code.rs @@ -24,6 +24,8 @@ pub const CLAUDE_CODE_DOC_URL: &str = "https://claude.ai/cli"; pub struct ClaudeCodeProvider { command: String, model: ModelConfig, + #[serde(skip)] + name: String, } impl ClaudeCodeProvider { @@ -42,6 +44,7 @@ impl ClaudeCodeProvider { Ok(Self { command: resolved_command, model, + name: Self::metadata().name, }) } @@ -463,6 +466,10 @@ impl Provider for ClaudeCodeProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { // Return the model config with appropriate context limit for Claude models self.model.clone() diff --git a/crates/goose/src/providers/cursor_agent.rs b/crates/goose/src/providers/cursor_agent.rs index b5f4e0b98552..31b185f3ddae 100644 --- a/crates/goose/src/providers/cursor_agent.rs +++ b/crates/goose/src/providers/cursor_agent.rs @@ -23,6 +23,8 @@ pub const CURSOR_AGENT_DOC_URL: &str = "https://docs.cursor.com/en/cli/overview" pub struct CursorAgentProvider { command: String, model: ModelConfig, + #[serde(skip)] + name: String, } impl CursorAgentProvider { @@ -41,6 +43,7 @@ impl CursorAgentProvider { Ok(Self { command: resolved_command, model, + name: Self::metadata().name, }) } @@ -395,6 +398,10 @@ impl Provider for CursorAgentProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { // Return the model config with appropriate context limit for Cursor models self.model.clone() diff --git a/crates/goose/src/providers/databricks.rs b/crates/goose/src/providers/databricks.rs index 44dc59971dd7..b36b07f1484e 100644 --- a/crates/goose/src/providers/databricks.rs +++ b/crates/goose/src/providers/databricks.rs @@ -106,6 +106,8 @@ pub struct DatabricksProvider { image_format: ImageFormat, #[serde(skip)] retry_config: RetryConfig, + #[serde(skip)] + name: String, } impl DatabricksProvider { @@ -146,6 +148,7 @@ impl DatabricksProvider { model: model.clone(), image_format: ImageFormat::OpenAi, retry_config, + name: Self::metadata().name, }; // Check if the default fast model exists in the workspace @@ -222,6 +225,7 @@ impl DatabricksProvider { model, image_format: ImageFormat::OpenAi, retry_config: RetryConfig::default(), + name: Self::metadata().name, }) } @@ -260,6 +264,10 @@ impl Provider for DatabricksProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn retry_config(&self) -> RetryConfig { self.retry_config.clone() } diff --git a/crates/goose/src/providers/gcpvertexai.rs b/crates/goose/src/providers/gcpvertexai.rs index e2ac26a31af3..62cf82289a86 100644 --- a/crates/goose/src/providers/gcpvertexai.rs +++ b/crates/goose/src/providers/gcpvertexai.rs @@ -76,6 +76,8 @@ pub struct GcpVertexAIProvider { /// Retry configuration for handling rate limit errors #[serde(skip)] retry_config: RetryConfig, + #[serde(skip)] + name: String, } impl GcpVertexAIProvider { @@ -109,6 +111,7 @@ impl GcpVertexAIProvider { location, model, retry_config, + name: Self::metadata().name, }) } @@ -494,6 +497,10 @@ impl Provider for GcpVertexAIProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + /// Completes a model interaction by sending a request and processing the response. /// /// # Arguments diff --git a/crates/goose/src/providers/gemini_cli.rs b/crates/goose/src/providers/gemini_cli.rs index 417774a70002..e13610e7dd09 100644 --- a/crates/goose/src/providers/gemini_cli.rs +++ b/crates/goose/src/providers/gemini_cli.rs @@ -24,6 +24,8 @@ pub const GEMINI_CLI_DOC_URL: &str = "https://ai.google.dev/gemini-api/docs"; pub struct GeminiCliProvider { command: String, model: ModelConfig, + #[serde(skip)] + name: String, } impl GeminiCliProvider { @@ -42,6 +44,7 @@ impl GeminiCliProvider { Ok(Self { command: resolved_command, model, + name: Self::metadata().name, }) } @@ -311,6 +314,10 @@ impl Provider for GeminiCliProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { // Return the model config with appropriate context limit for Gemini models self.model.clone() diff --git a/crates/goose/src/providers/githubcopilot.rs b/crates/goose/src/providers/githubcopilot.rs index 4a822ee7abbe..08a7074c48ba 100644 --- a/crates/goose/src/providers/githubcopilot.rs +++ b/crates/goose/src/providers/githubcopilot.rs @@ -113,6 +113,8 @@ pub struct GithubCopilotProvider { #[serde(skip)] mu: tokio::sync::Mutex>>, model: ModelConfig, + #[serde(skip)] + name: String, } impl GithubCopilotProvider { @@ -127,6 +129,7 @@ impl GithubCopilotProvider { cache, mu, model, + name: Self::metadata().name, }) } @@ -392,6 +395,10 @@ impl Provider for GithubCopilotProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/providers/google.rs b/crates/goose/src/providers/google.rs index d6d7b30dd2ac..6f73268aa5e2 100644 --- a/crates/goose/src/providers/google.rs +++ b/crates/goose/src/providers/google.rs @@ -39,6 +39,8 @@ pub struct GoogleProvider { #[serde(skip)] api_client: ApiClient, model: ModelConfig, + #[serde(skip)] + name: String, } impl GoogleProvider { @@ -59,7 +61,11 @@ impl GoogleProvider { let api_client = ApiClient::new(host, auth)?.with_header("Content-Type", "application/json")?; - Ok(Self { api_client, model }) + Ok(Self { + api_client, + model, + name: Self::metadata().name, + }) } async fn post(&self, model_name: &str, payload: &Value) -> Result { @@ -86,6 +92,10 @@ impl Provider for GoogleProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/providers/lead_worker.rs b/crates/goose/src/providers/lead_worker.rs index bb2d457b5a4a..1dc8fe7a8b7c 100644 --- a/crates/goose/src/providers/lead_worker.rs +++ b/crates/goose/src/providers/lead_worker.rs @@ -320,6 +320,11 @@ impl Provider for LeadWorkerProvider { ) } + fn get_name(&self) -> &str { + // Return the lead provider's name as the default + self.lead_provider.get_name() + } + fn get_model_config(&self) -> ModelConfig { // Return the lead provider's model config as the default // In practice, this might need to be more sophisticated @@ -472,6 +477,10 @@ mod tests { ProviderMetadata::empty() } + fn get_name(&self) -> &str { + "mock-lead" + } + fn get_model_config(&self) -> ModelConfig { self.model_config.clone() } @@ -634,6 +643,10 @@ mod tests { ProviderMetadata::empty() } + fn get_name(&self) -> &str { + "mock-lead" + } + fn get_model_config(&self) -> ModelConfig { self.model_config.clone() } diff --git a/crates/goose/src/providers/litellm.rs b/crates/goose/src/providers/litellm.rs index a0839724e8fc..65bebce57504 100644 --- a/crates/goose/src/providers/litellm.rs +++ b/crates/goose/src/providers/litellm.rs @@ -23,6 +23,8 @@ pub struct LiteLLMProvider { api_client: ApiClient, base_path: String, model: ModelConfig, + #[serde(skip)] + name: String, } impl LiteLLMProvider { @@ -67,6 +69,7 @@ impl LiteLLMProvider { api_client, base_path, model, + name: Self::metadata().name, }) } @@ -154,6 +157,10 @@ impl Provider for LiteLLMProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/providers/ollama.rs b/crates/goose/src/providers/ollama.rs index b355b6f244d6..3a180084634b 100644 --- a/crates/goose/src/providers/ollama.rs +++ b/crates/goose/src/providers/ollama.rs @@ -47,6 +47,7 @@ pub struct OllamaProvider { api_client: ApiClient, model: ModelConfig, supports_streaming: bool, + name: String, } impl OllamaProvider { @@ -92,6 +93,7 @@ impl OllamaProvider { api_client, model, supports_streaming: true, + name: Self::metadata().name, }) } @@ -131,6 +133,7 @@ impl OllamaProvider { api_client, model, supports_streaming: config.supports_streaming.unwrap_or(true), + name: config.name.clone(), }) } @@ -176,6 +179,10 @@ impl Provider for OllamaProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/providers/openai.rs b/crates/goose/src/providers/openai.rs index c00d8e6a5ed5..720cebce136a 100644 --- a/crates/goose/src/providers/openai.rs +++ b/crates/goose/src/providers/openai.rs @@ -54,6 +54,7 @@ pub struct OpenAiProvider { model: ModelConfig, custom_headers: Option>, supports_streaming: bool, + name: String, } impl OpenAiProvider { @@ -107,6 +108,7 @@ impl OpenAiProvider { model, custom_headers, supports_streaming: true, + name: Self::metadata().name, }) } @@ -163,6 +165,7 @@ impl OpenAiProvider { model, custom_headers: config.headers, supports_streaming: config.supports_streaming.unwrap_or(true), + name: config.name.clone(), }) } @@ -201,6 +204,10 @@ impl Provider for OpenAiProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/providers/openrouter.rs b/crates/goose/src/providers/openrouter.rs index f9acb72152f6..e87fb3741e44 100644 --- a/crates/goose/src/providers/openrouter.rs +++ b/crates/goose/src/providers/openrouter.rs @@ -40,6 +40,8 @@ pub struct OpenRouterProvider { #[serde(skip)] api_client: ApiClient, model: ModelConfig, + #[serde(skip)] + name: String, } impl OpenRouterProvider { @@ -57,7 +59,11 @@ impl OpenRouterProvider { .with_header("HTTP-Referer", "https://block.github.io/goose")? .with_header("X-Title", "goose")?; - Ok(Self { api_client, model }) + Ok(Self { + api_client, + model, + name: Self::metadata().name, + }) } async fn post(&self, payload: &Value) -> Result { @@ -242,6 +248,10 @@ impl Provider for OpenRouterProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/providers/sagemaker_tgi.rs b/crates/goose/src/providers/sagemaker_tgi.rs index 9c804147cbd1..5861b09cdd59 100644 --- a/crates/goose/src/providers/sagemaker_tgi.rs +++ b/crates/goose/src/providers/sagemaker_tgi.rs @@ -30,6 +30,8 @@ pub struct SageMakerTgiProvider { sagemaker_client: SageMakerClient, endpoint_name: String, model: ModelConfig, + #[serde(skip)] + name: String, } impl SageMakerTgiProvider { @@ -79,6 +81,7 @@ impl SageMakerTgiProvider { sagemaker_client, endpoint_name, model, + name: Self::metadata().name, }) } @@ -272,6 +275,10 @@ impl Provider for SageMakerTgiProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/providers/snowflake.rs b/crates/goose/src/providers/snowflake.rs index 7138625aaaea..7176d59d2055 100644 --- a/crates/goose/src/providers/snowflake.rs +++ b/crates/goose/src/providers/snowflake.rs @@ -48,6 +48,8 @@ pub struct SnowflakeProvider { api_client: ApiClient, model: ModelConfig, image_format: ImageFormat, + #[serde(skip)] + name: String, } impl SnowflakeProvider { @@ -101,6 +103,7 @@ impl SnowflakeProvider { api_client, model, image_format: ImageFormat::OpenAi, + name: Self::metadata().name, }) } @@ -302,6 +305,10 @@ impl Provider for SnowflakeProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/providers/testprovider.rs b/crates/goose/src/providers/testprovider.rs index e15cd4a0fc9e..c9e455bd69d3 100644 --- a/crates/goose/src/providers/testprovider.rs +++ b/crates/goose/src/providers/testprovider.rs @@ -36,6 +36,7 @@ pub struct TestProvider { inner: Option>, records: Arc>>, file_path: String, + name: String, } impl TestProvider { @@ -44,6 +45,7 @@ impl TestProvider { inner: Some(inner), records: Arc::new(Mutex::new(HashMap::new())), file_path: file_path.into(), + name: Self::metadata().name, } } @@ -55,6 +57,7 @@ impl TestProvider { inner: None, records: Arc::new(Mutex::new(records)), file_path, + name: Self::metadata().name, }) } @@ -112,6 +115,10 @@ impl Provider for TestProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + async fn complete_with_model( &self, _model_config: &ModelConfig, @@ -189,6 +196,10 @@ mod tests { ) } + fn get_name(&self) -> &str { + "mock-testprovider" + } + async fn complete_with_model( &self, _model_config: &ModelConfig, diff --git a/crates/goose/src/providers/tetrate.rs b/crates/goose/src/providers/tetrate.rs index e771d4916019..235f7b3198a7 100644 --- a/crates/goose/src/providers/tetrate.rs +++ b/crates/goose/src/providers/tetrate.rs @@ -46,6 +46,8 @@ pub struct TetrateProvider { api_client: ApiClient, model: ModelConfig, supports_streaming: bool, + #[serde(skip)] + name: String, } impl TetrateProvider { @@ -66,6 +68,7 @@ impl TetrateProvider { api_client, model, supports_streaming: true, + name: Self::metadata().name, }) } @@ -150,6 +153,10 @@ impl Provider for TetrateProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/providers/venice.rs b/crates/goose/src/providers/venice.rs index 701af251be4e..4a699222d4a5 100644 --- a/crates/goose/src/providers/venice.rs +++ b/crates/goose/src/providers/venice.rs @@ -78,6 +78,8 @@ pub struct VeniceProvider { base_path: String, models_path: String, model: ModelConfig, + #[serde(skip)] + name: String, } impl VeniceProvider { @@ -105,6 +107,7 @@ impl VeniceProvider { base_path, models_path, model, + name: Self::metadata().name, }; Ok(instance) @@ -210,6 +213,10 @@ impl Provider for VeniceProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/providers/xai.rs b/crates/goose/src/providers/xai.rs index ab75680acd64..0078d9894e97 100644 --- a/crates/goose/src/providers/xai.rs +++ b/crates/goose/src/providers/xai.rs @@ -42,6 +42,8 @@ pub struct XaiProvider { #[serde(skip)] api_client: ApiClient, model: ModelConfig, + #[serde(skip)] + name: String, } impl XaiProvider { @@ -55,7 +57,11 @@ impl XaiProvider { let auth = AuthMethod::BearerToken(api_key); let api_client = ApiClient::new(host, auth)?; - Ok(Self { api_client, model }) + Ok(Self { + api_client, + model, + name: Self::metadata().name, + }) } async fn post(&self, payload: Value) -> Result { @@ -87,6 +93,10 @@ impl Provider for XaiProvider { ) } + fn get_name(&self) -> &str { + &self.name + } + fn get_model_config(&self) -> ModelConfig { self.model.clone() } diff --git a/crates/goose/src/scheduler.rs b/crates/goose/src/scheduler.rs index e62ed05e49f5..85269ae2fa37 100644 --- a/crates/goose/src/scheduler.rs +++ b/crates/goose/src/scheduler.rs @@ -1361,6 +1361,10 @@ mod tests { ) } + fn get_name(&self) -> &str { + "mock-scheduler" + } + fn get_model_config(&self) -> ModelConfig { self.model_config.clone() } diff --git a/crates/goose/tests/agent.rs b/crates/goose/tests/agent.rs index e97f0bfb53c8..77e7359f6987 100644 --- a/crates/goose/tests/agent.rs +++ b/crates/goose/tests/agent.rs @@ -557,6 +557,10 @@ mod final_output_tool_tests { goose::providers::base::ProviderMetadata::empty() } + fn get_name(&self) -> &str { + "mock-test" + } + fn get_model_config(&self) -> ModelConfig { self.model_config.clone() } @@ -672,6 +676,10 @@ mod final_output_tool_tests { goose::providers::base::ProviderMetadata::empty() } + fn get_name(&self) -> &str { + "mock-test" + } + fn get_model_config(&self) -> ModelConfig { self.model_config.clone() } @@ -858,6 +866,10 @@ mod retry_tests { goose::providers::base::ProviderMetadata::empty() } + fn get_name(&self) -> &str { + "mock-test" + } + fn get_model_config(&self) -> ModelConfig { self.model_config.clone() } @@ -1080,6 +1092,10 @@ mod max_turns_tests { config_keys: vec![], } } + + fn get_name(&self) -> &str { + "mock-test" + } } #[tokio::test]