Files
tkmind_go/crates/goose/tests/tool_inspection_manager_tests.rs
T
Adrian Cole b4546f62d9 fix: restore smart-approve mode (#7690)
Signed-off-by: Adrian Cole <adrian@tetrate.io>
2026-03-06 15:45:23 +00:00

122 lines
3.4 KiB
Rust

use anyhow::{anyhow, Result};
use async_trait::async_trait;
use goose::config::GooseMode;
use goose::conversation::message::{Message, ToolRequest};
use goose::tool_inspection::{
InspectionAction, InspectionResult, ToolInspectionManager, ToolInspector,
};
struct MockInspectorOk {
name: &'static str,
results: Vec<InspectionResult>,
}
struct MockInspectorErr {
name: &'static str,
}
#[async_trait]
impl ToolInspector for MockInspectorOk {
fn name(&self) -> &'static str {
self.name
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
async fn inspect(
&self,
_session_id: &str,
_tool_requests: &[ToolRequest],
_messages: &[Message],
_goose_mode: GooseMode,
) -> Result<Vec<InspectionResult>> {
Ok(self.results.clone())
}
}
#[async_trait]
impl ToolInspector for MockInspectorErr {
fn name(&self) -> &'static str {
self.name
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
async fn inspect(
&self,
_session_id: &str,
_tool_requests: &[ToolRequest],
_messages: &[Message],
_goose_mode: GooseMode,
) -> Result<Vec<InspectionResult>> {
Err(anyhow!("simulated failure"))
}
}
#[tokio::test]
async fn test_inspect_tools_aggregates_and_handles_errors() {
// Arrange: create a manager with one successful and one failing inspector
let ok_results = vec![
InspectionResult {
tool_request_id: "req_1".to_string(),
action: InspectionAction::Allow,
reason: "looks safe".to_string(),
confidence: 0.95,
inspector_name: "ok".to_string(),
finding_id: None,
},
InspectionResult {
tool_request_id: "req_2".to_string(),
action: InspectionAction::RequireApproval(Some("double check".to_string())),
reason: "needs user confirmation".to_string(),
confidence: 0.7,
inspector_name: "ok".to_string(),
finding_id: Some("FND-123".to_string()),
},
];
let mut manager = ToolInspectionManager::new();
manager.add_inspector(Box::new(MockInspectorOk {
name: "ok",
results: ok_results.clone(),
}));
manager.add_inspector(Box::new(MockInspectorErr { name: "err" }));
// No specific input is required for this aggregation behavior
let tool_requests: Vec<ToolRequest> = vec![];
let messages: Vec<Message> = vec![];
// Act
let results = manager
.inspect_tools(
goose_test_support::TEST_SESSION_ID,
&tool_requests,
&messages,
GooseMode::Approve,
)
.await
.expect("inspect_tools should not fail when one inspector errors");
// Assert: results from the successful inspector are returned; failing inspector is ignored
assert_eq!(
results.len(),
2,
"Should aggregate results from successful inspectors only"
);
// Also verify inspector_names() order/presence
let names = manager.inspector_names();
assert_eq!(
names,
vec!["ok", "err"],
"Inspector names should reflect registration order"
);
// Verify that specific actions are preserved
assert!(results
.iter()
.any(|r| matches!(r.action, InspectionAction::Allow)));
assert!(results
.iter()
.any(|r| matches!(r.action, InspectionAction::RequireApproval(_))));
}