Allow zero-config models - use provider default
Users can now omit the models section entirely from agent config.
The agent will automatically use the default model from an available provider.
Changes:
- Agent.get_model(): Falls back to provider name ("ollama" or "openai")
- ProviderRegistry.resolve_provider(): Handles bare provider names
- OpenAiProvider.parse_model(): Uses default_model when spec is "openai"
- OllamaProvider.parse_model(): Uses default_model when spec is "ollama"
Example minimal config (no models needed):
[[providers.ollama]]
base_url = "http://localhost:11434"
default_model = "llama3"
[agents.default]
description = "Default agent"
system_prompt = "You are helpful."
tools = ["file", "shell", "git"]
# No [agents.default.models] needed!
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@@ -80,19 +80,20 @@ impl Agent {
|
||||
if let Some(model) = self.config.get_model_for_task(task_type) {
|
||||
return Ok(model);
|
||||
}
|
||||
|
||||
// Fallback: use a reasonable default based on available providers
|
||||
// Prefer ollama for local-first, then openai
|
||||
match task_type {
|
||||
TaskType::Code | TaskType::Planning | TaskType::ToolUse => {
|
||||
// For complex tasks, try openai first
|
||||
Ok("openai/gpt-4o".to_string())
|
||||
}
|
||||
TaskType::Chat | TaskType::Default => {
|
||||
// For chat and default, use ollama
|
||||
Ok("ollama/llama3".to_string())
|
||||
}
|
||||
|
||||
// Fallback: use the default model from any available provider
|
||||
// Prefer ollama for local-first usage
|
||||
if self.provider_registry.get("ollama").is_some() {
|
||||
return Ok("ollama".to_string());
|
||||
}
|
||||
if self.provider_registry.get("openai").is_some() {
|
||||
return Ok("openai".to_string());
|
||||
}
|
||||
|
||||
// No providers available
|
||||
Err(AgentError::ConfigError(
|
||||
"No model configured and no providers available".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
/// Get available tools as provider Tool definitions
|
||||
|
||||
@@ -46,7 +46,11 @@ impl OllamaProvider {
|
||||
// Handle "ollama/model-name" format
|
||||
if let Some(stripped) = model_spec.strip_prefix("ollama/") {
|
||||
stripped.to_string()
|
||||
} else if model_spec == "ollama" {
|
||||
// Just provider name - use default model
|
||||
self.default_model.clone()
|
||||
} else {
|
||||
// Use as-is (could be a model name)
|
||||
model_spec.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,11 @@ impl OpenAiProvider {
|
||||
// Handle "openai/model-name" format
|
||||
if let Some(stripped) = model_spec.strip_prefix("openai/") {
|
||||
stripped.to_string()
|
||||
} else if model_spec == "openai" {
|
||||
// Just provider name - use default model
|
||||
self.default_model.clone()
|
||||
} else {
|
||||
// Use as-is (could be a model name)
|
||||
model_spec.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,12 +103,21 @@ impl ProviderRegistry {
|
||||
}
|
||||
|
||||
/// Resolve a model specification to a provider
|
||||
/// Format: "provider/model-name" or just "model-name" (uses default)
|
||||
/// Format:
|
||||
/// - "provider/model-name" - use specific model
|
||||
/// - "provider" - use provider's default model
|
||||
/// - "model-name" - try to find provider with this model as default
|
||||
pub fn resolve_provider(&self, model_spec: &str) -> Result<(Arc<dyn Provider>, String)> {
|
||||
if let Some((provider_name, model_name)) = model_spec.split_once('/') {
|
||||
let provider = self.get_or_error(provider_name)?;
|
||||
Ok((provider, model_name.to_string()))
|
||||
} else {
|
||||
// Check if it's just a provider name (no model specified)
|
||||
// In this case, use the provider's default model
|
||||
if let Some(provider) = self.get(model_spec) {
|
||||
return Ok((provider, model_spec.to_string()));
|
||||
}
|
||||
|
||||
// Try to find a provider that has this model as default
|
||||
// Prefer Ollama for local-first
|
||||
if let Some(provider) = self.get("ollama") {
|
||||
|
||||
Reference in New Issue
Block a user