feature: provider & model config (#8515)
This commit is contained in:
@@ -50,6 +50,11 @@
|
||||
"requestType": "GetProviderDetailsRequest",
|
||||
"responseType": "GetProviderDetailsResponse"
|
||||
},
|
||||
{
|
||||
"method": "_goose/providers/models",
|
||||
"requestType": "GetProviderModelsRequest",
|
||||
"responseType": "GetProviderModelsResponse"
|
||||
},
|
||||
{
|
||||
"method": "_goose/config/read",
|
||||
"requestType": "ReadConfigRequest",
|
||||
|
||||
@@ -317,6 +317,13 @@
|
||||
"type": "string"
|
||||
},
|
||||
"default": []
|
||||
},
|
||||
"knownModels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/ModelEntry"
|
||||
},
|
||||
"default": []
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -367,6 +374,53 @@
|
||||
"secret"
|
||||
]
|
||||
},
|
||||
"ModelEntry": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"contextLimit": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"name",
|
||||
"contextLimit"
|
||||
]
|
||||
},
|
||||
"GetProviderModelsRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"providerName": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"providerName"
|
||||
],
|
||||
"description": "Fetch the full list of models available for a specific provider.",
|
||||
"x-side": "agent",
|
||||
"x-method": "_goose/providers/models"
|
||||
},
|
||||
"GetProviderModelsResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"models": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"models"
|
||||
],
|
||||
"description": "Provider models response.",
|
||||
"x-side": "agent",
|
||||
"x-method": "_goose/providers/models"
|
||||
},
|
||||
"ReadConfigRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -683,6 +737,15 @@
|
||||
"description": "Params for _goose/providers/details",
|
||||
"title": "GetProviderDetailsRequest"
|
||||
},
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/GetProviderModelsRequest"
|
||||
}
|
||||
],
|
||||
"description": "Params for _goose/providers/models",
|
||||
"title": "GetProviderModelsRequest"
|
||||
},
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
@@ -859,6 +922,14 @@
|
||||
],
|
||||
"title": "GetProviderDetailsResponse"
|
||||
},
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/$defs/GetProviderModelsResponse"
|
||||
}
|
||||
],
|
||||
"title": "GetProviderModelsResponse"
|
||||
},
|
||||
{
|
||||
"allOf": [
|
||||
{
|
||||
|
||||
@@ -2369,12 +2369,74 @@ impl GooseAcpAgent {
|
||||
})
|
||||
.collect(),
|
||||
setup_steps: metadata.setup_steps.clone(),
|
||||
known_models: metadata
|
||||
.known_models
|
||||
.iter()
|
||||
.map(|m| ModelEntry {
|
||||
name: m.name.clone(),
|
||||
context_limit: m.context_limit,
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
Ok(GetProviderDetailsResponse { providers: entries })
|
||||
}
|
||||
|
||||
#[custom_method(GetProviderModelsRequest)]
|
||||
async fn on_get_provider_models(
|
||||
&self,
|
||||
req: GetProviderModelsRequest,
|
||||
) -> Result<GetProviderModelsResponse, sacp::Error> {
|
||||
let config = self.load_config().ok();
|
||||
let all = goose::providers::providers().await;
|
||||
|
||||
let Some((metadata, _provider_type)) =
|
||||
all.into_iter().find(|(m, _)| m.name == req.provider_name)
|
||||
else {
|
||||
return Err(sacp::Error::invalid_params()
|
||||
.data(format!("Unknown provider: {}", req.provider_name)));
|
||||
};
|
||||
|
||||
let is_configured = config
|
||||
.as_ref()
|
||||
.map(|c| {
|
||||
metadata.config_keys.iter().all(|k| {
|
||||
if !k.required {
|
||||
return true;
|
||||
}
|
||||
if k.secret {
|
||||
c.get_secret::<String>(&k.name).is_ok()
|
||||
} else {
|
||||
c.get_param::<String>(&k.name).is_ok()
|
||||
}
|
||||
})
|
||||
})
|
||||
.unwrap_or(false);
|
||||
|
||||
if !is_configured {
|
||||
return Err(sacp::Error::invalid_params().data(format!(
|
||||
"Provider '{}' is not configured",
|
||||
req.provider_name
|
||||
)));
|
||||
}
|
||||
|
||||
let model_config = goose::model::ModelConfig::new(&metadata.default_model)
|
||||
.map_err(|e| sacp::Error::internal_error().data(e.to_string()))?
|
||||
.with_canonical_limits(&req.provider_name);
|
||||
|
||||
let provider = (self.provider_factory)(req.provider_name.clone(), model_config, Vec::new())
|
||||
.await
|
||||
.map_err(|e| sacp::Error::internal_error().data(e.to_string()))?;
|
||||
|
||||
let models = provider
|
||||
.fetch_recommended_models()
|
||||
.await
|
||||
.map_err(|e| sacp::Error::internal_error().data(e.to_string()))?;
|
||||
|
||||
Ok(GetProviderModelsResponse { models })
|
||||
}
|
||||
|
||||
#[custom_method(ReadConfigRequest)]
|
||||
async fn on_read_config(
|
||||
&self,
|
||||
|
||||
@@ -265,6 +265,20 @@ pub struct GetProviderDetailsResponse {
|
||||
pub providers: Vec<ProviderDetailEntry>,
|
||||
}
|
||||
|
||||
/// Fetch the full list of models available for a specific provider.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcRequest)]
|
||||
#[request(method = "_goose/providers/models", response = GetProviderModelsResponse)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct GetProviderModelsRequest {
|
||||
pub provider_name: String,
|
||||
}
|
||||
|
||||
/// Provider models response.
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema, JsonRpcResponse)]
|
||||
pub struct GetProviderModelsResponse {
|
||||
pub models: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ProviderDetailEntry {
|
||||
@@ -277,6 +291,15 @@ pub struct ProviderDetailEntry {
|
||||
pub config_keys: Vec<ProviderConfigKey>,
|
||||
#[serde(default)]
|
||||
pub setup_steps: Vec<String>,
|
||||
#[serde(default)]
|
||||
pub known_models: Vec<ModelEntry>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ModelEntry {
|
||||
pub name: String,
|
||||
pub context_limit: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, JsonSchema)]
|
||||
|
||||
Reference in New Issue
Block a user