feat: add permission field to the list tools response (#2080)
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
use utoipa::OpenApi;
|
||||
|
||||
use goose::agents::extension::Envs;
|
||||
use goose::agents::extension::ToolInfo;
|
||||
use goose::agents::ExtensionConfig;
|
||||
use goose::config::permission::PermissionLevel;
|
||||
use goose::config::ExtensionEntry;
|
||||
use goose::providers::base::ConfigKey;
|
||||
use goose::providers::base::ProviderMetadata;
|
||||
use mcp_core::tool::{Tool, ToolAnnotations};
|
||||
use utoipa::OpenApi;
|
||||
|
||||
#[allow(dead_code)] // Used by utoipa for OpenAPI generation
|
||||
#[derive(OpenApi)]
|
||||
@@ -36,6 +37,8 @@ use mcp_core::tool::{Tool, ToolAnnotations};
|
||||
Envs,
|
||||
Tool,
|
||||
ToolAnnotations,
|
||||
ToolInfo,
|
||||
PermissionLevel,
|
||||
))
|
||||
)]
|
||||
pub struct ApiDoc;
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
use crate::state::AppState;
|
||||
use axum::{
|
||||
extract::State,
|
||||
extract::{Query, State},
|
||||
http::{HeaderMap, StatusCode},
|
||||
routing::{get, post},
|
||||
Json, Router,
|
||||
};
|
||||
use goose::config::Config;
|
||||
use goose::{agents::AgentFactory, model::ModelConfig, providers};
|
||||
use mcp_core::Tool;
|
||||
use goose::{agents::AgentFactory, config::PermissionManager, model::ModelConfig, providers};
|
||||
use goose::{
|
||||
agents::{capabilities::get_parameter_names, extension::ToolInfo},
|
||||
config::Config,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
@@ -62,6 +64,11 @@ struct ProviderList {
|
||||
details: ProviderDetails,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct GetToolsQuery {
|
||||
extension_name: Option<String>,
|
||||
}
|
||||
|
||||
async fn get_versions() -> Json<VersionsResponse> {
|
||||
let versions = AgentFactory::available_versions();
|
||||
let default_version = AgentFactory::default_version().to_string();
|
||||
@@ -167,6 +174,9 @@ async fn list_providers() -> Json<Vec<ProviderList>> {
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/agent/tools",
|
||||
params(
|
||||
("extension_name" = Option<String>, Query, description = "Optional extension name to filter tools")
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Tools retrieved successfully", body = Vec<Tool>),
|
||||
(status = 401, description = "Unauthorized - invalid secret key"),
|
||||
@@ -177,7 +187,8 @@ async fn list_providers() -> Json<Vec<ProviderList>> {
|
||||
async fn get_tools(
|
||||
State(state): State<AppState>,
|
||||
headers: HeaderMap,
|
||||
) -> Result<Json<Vec<Tool>>, StatusCode> {
|
||||
Query(query): Query<GetToolsQuery>,
|
||||
) -> Result<Json<Vec<ToolInfo>>, StatusCode> {
|
||||
let secret_key = headers
|
||||
.get("X-Secret-Key")
|
||||
.and_then(|value| value.to_str().ok())
|
||||
@@ -189,11 +200,30 @@ async fn get_tools(
|
||||
|
||||
let mut agent = state.agent.write().await;
|
||||
let agent = agent.as_mut().ok_or(StatusCode::PRECONDITION_REQUIRED)?;
|
||||
let permission_manager = PermissionManager::default();
|
||||
|
||||
// Since list_tools() now returns Vec<Tool> directly, not a Result
|
||||
let tools = agent.list_tools().await;
|
||||
let tools = agent
|
||||
.list_tools()
|
||||
.await
|
||||
.into_iter()
|
||||
.filter(|tool| {
|
||||
// Apply the filter only if the extension name is present in the query
|
||||
if let Some(extension_name) = &query.extension_name {
|
||||
tool.name.starts_with(extension_name)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
})
|
||||
.map(|tool| {
|
||||
ToolInfo::new(
|
||||
&tool.name,
|
||||
&tool.description,
|
||||
get_parameter_names(&tool),
|
||||
permission_manager.get_user_permission(&tool.name),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Return the tools directly
|
||||
Ok(Json(tools))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user