From 73ad49a3a144f0d61ddcd75f4bce5c6ed73d4d19 Mon Sep 17 00:00:00 2001 From: jaberjaber23 Date: Mon, 2 Mar 2026 03:31:59 +0300 Subject: [PATCH] batch fixes --- Cargo.lock | 28 +++--- Cargo.toml | 2 +- crates/openfang-api/src/routes.rs | 86 ++++++++++++++++++ crates/openfang-api/src/server.rs | 4 + crates/openfang-api/static/index_body.html | 71 +++++++++++++-- crates/openfang-api/static/js/pages/agents.js | 91 +++++++++++++++++++ crates/openfang-api/static/js/pages/chat.js | 38 +++++++- crates/openfang-cli/src/tui/event.rs | 8 +- crates/openfang-kernel/src/kernel.rs | 65 +++++++++---- crates/openfang-kernel/src/registry.rs | 23 +++++ crates/openfang-kernel/src/wizard.rs | 2 + crates/openfang-runtime/src/prompt_builder.rs | 32 ++++++- crates/openfang-types/src/agent.rs | 10 ++ 13 files changed, 417 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 82fc83ff..dfbb3da9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3866,7 +3866,7 @@ dependencies = [ [[package]] name = "openfang-api" -version = "0.2.4" +version = "0.2.5" dependencies = [ "async-trait", "axum", @@ -3902,7 +3902,7 @@ dependencies = [ [[package]] name = "openfang-channels" -version = "0.2.4" +version = "0.2.5" dependencies = [ "async-trait", "axum", @@ -3933,7 +3933,7 @@ dependencies = [ [[package]] name = "openfang-cli" -version = "0.2.4" +version = "0.2.5" dependencies = [ "clap", "clap_complete", @@ -3960,7 +3960,7 @@ dependencies = [ [[package]] name = "openfang-desktop" -version = "0.2.4" +version = "0.2.5" dependencies = [ "axum", "open", @@ -3986,7 +3986,7 @@ dependencies = [ [[package]] name = "openfang-extensions" -version = "0.2.4" +version = "0.2.5" dependencies = [ "aes-gcm", "argon2", @@ -4014,7 +4014,7 @@ dependencies = [ [[package]] name = "openfang-hands" -version = "0.2.4" +version = "0.2.5" dependencies = [ "chrono", "dashmap", @@ -4031,7 +4031,7 @@ dependencies = [ [[package]] name = "openfang-kernel" -version = "0.2.4" +version = "0.2.5" dependencies = [ "async-trait", "chrono", @@ -4067,7 +4067,7 @@ dependencies = [ [[package]] name = "openfang-memory" -version = "0.2.4" +version = "0.2.5" dependencies = [ "async-trait", "chrono", @@ -4086,7 +4086,7 @@ dependencies = [ [[package]] name = "openfang-migrate" -version = "0.2.4" +version = "0.2.5" dependencies = [ "chrono", "dirs 6.0.0", @@ -4105,7 +4105,7 @@ dependencies = [ [[package]] name = "openfang-runtime" -version = "0.2.4" +version = "0.2.5" dependencies = [ "anyhow", "async-trait", @@ -4136,7 +4136,7 @@ dependencies = [ [[package]] name = "openfang-skills" -version = "0.2.4" +version = "0.2.5" dependencies = [ "chrono", "hex", @@ -4158,7 +4158,7 @@ dependencies = [ [[package]] name = "openfang-types" -version = "0.2.4" +version = "0.2.5" dependencies = [ "async-trait", "chrono", @@ -4177,7 +4177,7 @@ dependencies = [ [[package]] name = "openfang-wire" -version = "0.2.4" +version = "0.2.5" dependencies = [ "async-trait", "chrono", @@ -8789,7 +8789,7 @@ checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] name = "xtask" -version = "0.2.4" +version = "0.2.5" [[package]] name = "yoke" diff --git a/Cargo.toml b/Cargo.toml index ca8bc193..7da1cfcd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ members = [ ] [workspace.package] -version = "0.2.5" +version = "0.2.6" edition = "2021" license = "Apache-2.0 OR MIT" repository = "https://github.com/RightNow-AI/openfang" diff --git a/crates/openfang-api/src/routes.rs b/crates/openfang-api/src/routes.rs index e9b189f9..0565a50f 100644 --- a/crates/openfang-api/src/routes.rs +++ b/crates/openfang-api/src/routes.rs @@ -5799,6 +5799,92 @@ pub async fn set_model( } } +/// GET /api/agents/{id}/tools — Get an agent's tool allowlist/blocklist. +pub async fn get_agent_tools( + State(state): State>, + Path(id): Path, +) -> impl IntoResponse { + let agent_id: AgentId = match id.parse() { + Ok(id) => id, + Err(_) => { + return ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!({"error": "Invalid agent ID"})), + ) + } + }; + let entry = match state.kernel.registry.get(agent_id) { + Some(e) => e, + None => { + return ( + StatusCode::NOT_FOUND, + Json(serde_json::json!({"error": "Agent not found"})), + ) + } + }; + ( + StatusCode::OK, + Json(serde_json::json!({ + "tool_allowlist": entry.manifest.tool_allowlist, + "tool_blocklist": entry.manifest.tool_blocklist, + })), + ) +} + +/// PUT /api/agents/{id}/tools — Update an agent's tool allowlist/blocklist. +pub async fn set_agent_tools( + State(state): State>, + Path(id): Path, + Json(body): Json, +) -> impl IntoResponse { + let agent_id: AgentId = match id.parse() { + Ok(id) => id, + Err(_) => { + return ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!({"error": "Invalid agent ID"})), + ) + } + }; + let allowlist = body + .get("tool_allowlist") + .and_then(|v| v.as_array()) + .map(|arr| { + arr.iter() + .filter_map(|v| v.as_str().map(String::from)) + .collect::>() + }); + let blocklist = body + .get("tool_blocklist") + .and_then(|v| v.as_array()) + .map(|arr| { + arr.iter() + .filter_map(|v| v.as_str().map(String::from)) + .collect::>() + }); + + if allowlist.is_none() && blocklist.is_none() { + return ( + StatusCode::BAD_REQUEST, + Json(serde_json::json!({"error": "Provide 'tool_allowlist' and/or 'tool_blocklist'"})), + ); + } + + match state + .kernel + .set_agent_tool_filters(agent_id, allowlist, blocklist) + { + Ok(()) => ( + StatusCode::OK, + Json(serde_json::json!({"status": "ok"})), + ), + Err(e) => ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(serde_json::json!({"error": format!("{e}")})), + ), + } +} + // ── Per-Agent Skill & MCP Endpoints ──────────────────────────────────── /// GET /api/agents/{id}/skills — Get an agent's skill assignment info. diff --git a/crates/openfang-api/src/server.rs b/crates/openfang-api/src/server.rs index aa5bced2..3df41cbf 100644 --- a/crates/openfang-api/src/server.rs +++ b/crates/openfang-api/src/server.rs @@ -172,6 +172,10 @@ pub async fn build_router( "/api/agents/{id}/model", axum::routing::put(routes::set_model), ) + .route( + "/api/agents/{id}/tools", + axum::routing::get(routes::get_agent_tools).put(routes::set_agent_tools), + ) .route( "/api/agents/{id}/skills", axum::routing::get(routes::get_agent_skills).put(routes::set_agent_skills), diff --git a/crates/openfang-api/static/index_body.html b/crates/openfang-api/static/index_body.html index 60d918e9..77404e69 100644 --- a/crates/openfang-api/static/index_body.html +++ b/crates/openfang-api/static/index_body.html @@ -696,6 +696,16 @@ + +
+
Available models — pick one or keep typing
+ +
@@ -811,7 +821,7 @@
Info
Files
-
Config
+
Config
@@ -826,12 +836,29 @@
Profile
Provider
-
Model
+
Model + + +
Created
+
@@ -890,6 +917,36 @@ + + +
+

Tool Filters

+

Allowlist: only these tools available (empty = all). Blocklist: these tools excluded.

+
+ +
+ +
+
+ + +
+
+
+ +
+ +
+
+ + +
+
+
@@ -2995,7 +3052,7 @@ args = ["-y", "@modelcontextprotocol/server-filesystem", "/path"]