bxcore, brokerd, loopd: an invalid-arguments denial says why

Co-Authored-By: ornith-1.5-35b-a3b <agent@wntrmute.dev>
This commit is contained in:
2026-09-27 19:08:42 -07:00
co-authored by ornith-1.5-35b-a3b
parent 89a50bc3c6
commit de60c9e13a
21 changed files with 520 additions and 33 deletions
+14
View File
@@ -378,6 +378,19 @@ pub fn denial_text(reason: bxcore::DenyReason) -> &'static str {
}
}
/// What a denial reaches the model as: the reason's sentence, and the broker's detail, if it sent
/// one, after a colon (`Denied: the arguments are not valid for this tool: <detail>.`).
pub fn denial_message(reason: bxcore::DenyReason, detail: Option<&str>) -> String {
let sentence = denial_text(reason);
match detail {
None => sentence.to_string(),
Some(detail) => {
let stem = sentence.strip_suffix('.').unwrap_or(sentence);
format!("{stem}: {detail}.")
}
}
}
pub struct FakeTools {
calls: Mutex<Vec<bxcore::ToolRequest>>,
}
@@ -432,6 +445,7 @@ impl ToolPort for FakeTools {
},
_ => bxcore::ToolResponse::Denied {
reason: bxcore::DenyReason::NoGrant,
detail: None,
},
}
}
+7 -3
View File
@@ -7,7 +7,7 @@ use crate::config::Config;
use crate::llama::info::{CacheOutcome, cache_outcome};
use crate::llama::{ChatEvent, ChatRequest, Client, InferError};
use crate::session::{Session, SessionError};
use crate::tools::{Registry, ToolPort, cap_result, denial_text, dispatch};
use crate::tools::{Registry, ToolPort, cap_result, denial_message, dispatch};
use bxcore::{
CallId, DataClass, LogRecord, Timestamp, ToolRequest, ToolResponse, TurnEvent, Usage,
};
@@ -292,12 +292,16 @@ fn run_call(
DataClass::Public,
false,
),
ToolResponse::Denied { reason } => {
ToolResponse::Denied { reason, detail } => {
on_event(&TurnEvent::ToolDenied {
name: request.tool.clone(),
reason,
});
(denial_text(reason).to_string(), DataClass::Public, false)
(
denial_message(reason, detail.as_deref()),
DataClass::Public,
false,
)
}
ToolResponse::PendingApproval { .. } => (
"The tool failed: the tool broker gave no final answer".to_string(),