Simplified custom model flow with canonical models (#6934)
This commit is contained in:
@@ -354,6 +354,8 @@ derive_utoipa!(Icon as IconSchema);
|
||||
super::routes::config_management::get_custom_provider,
|
||||
super::routes::config_management::update_custom_provider,
|
||||
super::routes::config_management::remove_custom_provider,
|
||||
super::routes::config_management::get_provider_catalog,
|
||||
super::routes::config_management::get_provider_catalog_template,
|
||||
super::routes::config_management::check_provider,
|
||||
super::routes::config_management::set_config_provider,
|
||||
super::routes::config_management::configure_provider_oauth,
|
||||
@@ -450,6 +452,10 @@ derive_utoipa!(Icon as IconSchema);
|
||||
super::routes::config_management::ToolPermission,
|
||||
super::routes::config_management::UpsertPermissionsQuery,
|
||||
super::routes::config_management::UpdateCustomProviderRequest,
|
||||
goose::providers::catalog::ProviderCatalogEntry,
|
||||
goose::providers::catalog::ProviderTemplate,
|
||||
goose::providers::catalog::ModelTemplate,
|
||||
goose::providers::catalog::ModelCapabilities,
|
||||
super::routes::config_management::CheckProviderRequest,
|
||||
super::routes::config_management::SetProviderRequest,
|
||||
super::routes::config_management::ModelInfoQuery,
|
||||
|
||||
@@ -15,6 +15,10 @@ use goose::model::ModelConfig;
|
||||
use goose::providers::auto_detect::detect_provider_from_api_key;
|
||||
use goose::providers::base::{ProviderMetadata, ProviderType};
|
||||
use goose::providers::canonical::maybe_get_canonical_model;
|
||||
use goose::providers::catalog::{
|
||||
get_provider_template, get_providers_by_format, ProviderCatalogEntry, ProviderFormat,
|
||||
ProviderTemplate,
|
||||
};
|
||||
use goose::providers::create_with_default_model;
|
||||
use goose::providers::providers as get_providers;
|
||||
use goose::{
|
||||
@@ -94,6 +98,8 @@ pub struct UpdateCustomProviderRequest {
|
||||
pub headers: Option<std::collections::HashMap<String, String>>,
|
||||
#[serde(default = "default_requires_auth")]
|
||||
pub requires_auth: bool,
|
||||
#[serde(default)]
|
||||
pub catalog_provider_id: Option<String>,
|
||||
}
|
||||
|
||||
fn default_requires_auth() -> bool {
|
||||
@@ -648,6 +654,7 @@ pub async fn create_custom_provider(
|
||||
supports_streaming: request.supports_streaming,
|
||||
headers: request.headers,
|
||||
requires_auth: request.requires_auth,
|
||||
catalog_provider_id: request.catalog_provider_id,
|
||||
},
|
||||
)?;
|
||||
|
||||
@@ -718,6 +725,7 @@ pub async fn update_custom_provider(
|
||||
supports_streaming: request.supports_streaming,
|
||||
headers: request.headers,
|
||||
requires_auth: request.requires_auth,
|
||||
catalog_provider_id: request.catalog_provider_id,
|
||||
},
|
||||
)?;
|
||||
|
||||
@@ -770,6 +778,54 @@ pub async fn set_config_provider(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/config/provider-catalog",
|
||||
params(
|
||||
("format" = Option<String>, Query, description = "Filter by provider format (openai, anthropic, ollama)")
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Provider catalog retrieved successfully", body = [ProviderCatalogEntry]),
|
||||
(status = 400, description = "Invalid format parameter")
|
||||
)
|
||||
)]
|
||||
pub async fn get_provider_catalog(
|
||||
axum::extract::Query(params): axum::extract::Query<HashMap<String, String>>,
|
||||
) -> Result<Json<Vec<ProviderCatalogEntry>>, ErrorResponse> {
|
||||
let format_str = params.get("format").map(|s| s.as_str()).unwrap_or("openai");
|
||||
|
||||
let format = format_str.parse::<ProviderFormat>().map_err(|_| {
|
||||
ErrorResponse::bad_request(format!(
|
||||
"Invalid format '{}'. Must be one of: openai, anthropic, ollama",
|
||||
format_str
|
||||
))
|
||||
})?;
|
||||
|
||||
let providers = get_providers_by_format(format).await;
|
||||
Ok(Json(providers))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/config/provider-catalog/{id}",
|
||||
params(
|
||||
("id" = String, Path, description = "Provider ID from models.dev")
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Provider template retrieved successfully", body = ProviderTemplate),
|
||||
(status = 404, description = "Provider not found in catalog")
|
||||
)
|
||||
)]
|
||||
pub async fn get_provider_catalog_template(
|
||||
Path(id): Path<String>,
|
||||
) -> Result<Json<ProviderTemplate>, ErrorResponse> {
|
||||
let template = get_provider_template(&id).ok_or_else(|| {
|
||||
ErrorResponse::not_found(format!("Provider '{}' not found in catalog", id))
|
||||
})?;
|
||||
|
||||
Ok(Json(template))
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
post,
|
||||
path = "/config/providers/{name}/oauth",
|
||||
@@ -836,6 +892,11 @@ pub fn routes(state: Arc<AppState>) -> Router {
|
||||
.route("/config/extensions/{name}", delete(remove_extension))
|
||||
.route("/config/providers", get(providers))
|
||||
.route("/config/providers/{name}/models", get(get_provider_models))
|
||||
.route("/config/provider-catalog", get(get_provider_catalog))
|
||||
.route(
|
||||
"/config/provider-catalog/{id}",
|
||||
get(get_provider_catalog_template),
|
||||
)
|
||||
.route("/config/detect-provider", post(detect_provider))
|
||||
.route("/config/slash_commands", get(get_slash_commands))
|
||||
.route(
|
||||
|
||||
Reference in New Issue
Block a user