Skip to content

Commit 4a20876

Browse files
committed
fix: improve tool call 'Ask' permission handling with proper logging and error handling
1 parent 2878d46 commit 4a20876

File tree

1 file changed

+40
-11
lines changed

1 file changed

+40
-11
lines changed

src/cortex-engine/src/agent/handler.rs

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,24 @@ impl MessageHandler {
6868

6969
/// Validates and handles tool execution based on agent profile permissions.
7070
///
71-
/// If a tool is 'deny', returns an error immediately.
72-
/// If 'ask', triggers a protocol 'ExecApprovalRequest' via the event sender.
73-
/// Returns Ok(true) if execution should proceed, Ok(false) if waiting for approval.
71+
/// This method checks the permission level for a tool call and determines
72+
/// whether execution should proceed immediately, wait for user approval,
73+
/// or be denied entirely.
74+
///
75+
/// # Return Value Semantics
76+
///
77+
/// - `Ok(true)` - The tool has 'Allow' permission; caller should proceed with execution
78+
/// - `Ok(false)` - The tool has 'Ask' permission; caller should NOT proceed immediately.
79+
/// A `ToolCallPending` event has been emitted, and the session handler will convert
80+
/// this to a protocol `ExecApprovalRequest`. The caller should wait for user approval
81+
/// before retrying execution.
82+
/// - `Err(_)` - The tool has 'Deny' permission; execution is forbidden for this profile
83+
///
84+
/// # Errors
85+
///
86+
/// Returns `CortexError::Internal` if:
87+
/// - The tool is explicitly denied by the profile
88+
/// - Failed to send the approval request event (for 'Ask' permission)
7489
pub async fn handle_tool_execution(
7590
&self,
7691
profile: &AgentProfile,
@@ -95,15 +110,29 @@ impl MessageHandler {
95110
Err(CortexError::Internal(error_msg))
96111
}
97112
ToolPermission::Ask => {
98-
// Trigger protocol ExecApprovalRequest by emitting ToolCallPending event
99-
// This will be picked up by the session handler and converted to a protocol event
100-
let _ = event_tx.send(AgentEvent::ToolCallPending {
101-
id: tool_call.id.clone(),
102-
name: tool_call.function.name.clone(),
103-
arguments: tool_call.function.arguments.clone(),
104-
risk_level: RiskLevel::Medium, // Tools marked as 'ask' are considered medium risk by default
105-
});
113+
// The 'Ask' permission requires user approval before execution.
114+
// We emit a ToolCallPending event and return Ok(false) to indicate
115+
// that the caller should NOT proceed with execution immediately.
116+
// The session handler will convert this to a protocol ExecApprovalRequest
117+
// and wait for user approval before retrying.
118+
tracing::debug!(
119+
tool = %tool_call.function.name,
120+
id = %tool_call.id,
121+
"Tool execution requires user approval"
122+
);
123+
124+
event_tx
125+
.send(AgentEvent::ToolCallPending {
126+
id: tool_call.id.clone(),
127+
name: tool_call.function.name.clone(),
128+
arguments: tool_call.function.arguments.clone(),
129+
risk_level: RiskLevel::Medium, // Tools marked as 'ask' are considered medium risk by default
130+
})
131+
.map_err(|e| {
132+
CortexError::Internal(format!("Failed to send approval request: {}", e))
133+
})?;
106134

135+
// Return false to indicate caller should wait for approval
107136
Ok(false)
108137
}
109138
}

0 commit comments

Comments
 (0)