feat(gateway): GET /api/tools with capability metadata

This commit is contained in:
xiaoxixi 2026-07-26 21:18:51 +08:00
parent fa58e4d2f6
commit 119df57b49
2 changed files with 25 additions and 0 deletions

View File

@ -820,6 +820,30 @@ pub async fn get_status(State(state): State<Arc<GatewayState>>) -> Result<Json<V
})))
}
pub async fn get_tools(State(state): State<Arc<GatewayState>>) -> Result<Json<Value>, ApiError> {
let metrics = crate::observability::metrics::global_metrics();
let registry = state.session_manager.tools();
let mut entries = registry.iter();
entries.sort_by(|(a, _), (b, _)| a.cmp(b));
let tools: Vec<Value> = entries
.into_iter()
.map(|(name, tool)| {
let source = if name.contains("__") { "mcp" } else { "builtin" };
json!({
"name": name,
"description": tool.description(),
"parameters_schema": tool.parameters_schema(),
"source": source,
"read_only": tool.read_only(),
"exclusive": tool.exclusive(),
"concurrency_safe": tool.concurrency_safe(),
"call_count": metrics.tool_call_count(&name),
})
})
.collect();
Ok(Json(json!({ "tools": tools })))
}
pub async fn get_tasks(
State(state): State<Arc<GatewayState>>,
Query(query): Query<LimitQuery>,

View File

@ -594,6 +594,7 @@ fn build_router(state: Arc<GatewayState>) -> Router {
.route("/api/logs", routing::get(http::get_logs))
.route("/api/tasks", routing::get(http::get_tasks))
.route("/api/status", routing::get(http::get_status))
.route("/api/tools", routing::get(http::get_tools))
.route("/api/jobs", routing::get(http::get_jobs))
.route("/api/jobs/{id}/runs", routing::get(http::get_job_runs))
.route("/api/memories", routing::get(http::get_memories))