#![allow(clippy::pedantic, clippy::nursery, missing_docs)]
use std::sync::Arc;
use async_trait::async_trait;
use polyc_agent::{ToolDecision, ToolExecutor};
use polyc_llm::ToolSpec;
use polyc_tools::CompositeRegistry;
const OWNED: &str = "owned_tool";
#[derive(Debug)]
struct OpinionatedSource;
#[async_trait]
impl ToolExecutor for OpinionatedSource {
fn specs(&self) -> Vec<ToolSpec> {
vec![ToolSpec::new(OWNED, "owned", serde_json::json!({}))]
}
fn needs_approval(&self, name: &str) -> bool {
name == OWNED
}
fn pre_dispatch(&self, _name: &str, args_json: &str) -> ToolDecision {
if args_json.contains("\"forbidden\"") {
ToolDecision::Deny("the owning source refuses these arguments".to_owned())
} else {
ToolDecision::RequireApproval
}
}
fn post_dispatch(&self, _name: &str, _args_json: &str, _result_json: &str) -> Option<String> {
Some("[redacted by the owning source]".to_owned())
}
fn recover_unadvertised(&self, _name: &str, _args_json: &str) -> Vec<ToolSpec> {
vec![ToolSpec::new(
"recovered_tool",
"recovered",
serde_json::json!({}),
)]
}
async fn execute(&self, _name: &str, _args_json: &str) -> String {
String::new()
}
}
fn composed() -> CompositeRegistry {
CompositeRegistry::new().with(Arc::new(OpinionatedSource))
}
#[test]
fn pre_dispatch_carries_an_owners_argument_aware_deny() {
let decision = composed().pre_dispatch(OWNED, r#"{"forbidden":true}"#);
assert!(
matches!(decision, ToolDecision::Deny(_)),
"composition flattened the owner's Deny into {decision:?}"
);
}
#[test]
fn pre_dispatch_carries_the_owners_ordinary_decision_too() {
let decision = composed().pre_dispatch(OWNED, r#"{"fine":true}"#);
assert!(
matches!(decision, ToolDecision::RequireApproval),
"expected the owner's gated decision, got {decision:?}"
);
}
#[test]
fn pre_dispatch_allows_a_name_no_source_owns() {
let decision = composed().pre_dispatch("nobody_owns_this", "{}");
assert!(
matches!(decision, ToolDecision::Allow),
"an unowned name must stay allowed, got {decision:?}"
);
}
#[test]
fn post_dispatch_carries_an_owners_redaction() {
assert_eq!(
composed().post_dispatch(OWNED, "{}", "the raw secret"),
Some("[redacted by the owning source]".to_owned()),
"composition dropped the owner's result rewrite"
);
}
#[test]
fn post_dispatch_rewrites_nothing_for_an_unowned_name() {
assert_eq!(
composed().post_dispatch("nobody_owns_this", "{}", "raw"),
None
);
}
#[test]
fn recover_unadvertised_fans_out_across_sources() {
let recovered = composed().recover_unadvertised("hallucinated_name", "{}");
assert_eq!(
recovered
.iter()
.map(|s| s.name.as_str())
.collect::<Vec<_>>(),
vec!["recovered_tool"],
"composition swallowed the source's recovery hatch"
);
}