huskies: merge 1163 story Replace perm_rx lock-as-presence-signal with a permission router
This commit is contained in:
@@ -81,14 +81,14 @@ pub(super) async fn handle_llm_message(
|
||||
);
|
||||
tokio::pin!(chat_fut);
|
||||
|
||||
// Lock the permission receiver for the duration of this chat session.
|
||||
let mut perm_rx_guard = ctx.services.perm_rx.lock().await;
|
||||
// Register as a permission responder for the duration of this chat turn.
|
||||
let (_perm_guard, mut perm_rx) = ctx.services.permission_registry.register();
|
||||
|
||||
let result = loop {
|
||||
tokio::select! {
|
||||
r = &mut chat_fut => break r,
|
||||
|
||||
Some(perm_fwd) = perm_rx_guard.recv() => {
|
||||
Some(perm_fwd) = perm_rx.recv() => {
|
||||
let prompt_msg = format!(
|
||||
"*Permission Request*\n\nTool: `{}`\n```json\n{}\n```\n\nReply *yes* to approve or *no* to deny.",
|
||||
perm_fwd.tool_name,
|
||||
@@ -101,20 +101,22 @@ pub(super) async fn handle_llm_message(
|
||||
}
|
||||
|
||||
// Store the response sender so the incoming message handler
|
||||
// can resolve it when the user replies yes/no.
|
||||
// can resolve it when the user replies yes/no. Keyed by
|
||||
// request_id (not just sender) so a second concurrent
|
||||
// request doesn't drop the first's sender.
|
||||
ctx.services.pending_perm_replies
|
||||
.lock()
|
||||
.await
|
||||
.insert(sender.to_string(), perm_fwd.response_tx);
|
||||
.insert(sender.to_string(), perm_fwd.request_id.clone(), perm_fwd.response_tx)
|
||||
.await;
|
||||
|
||||
// Spawn a timeout task: auto-deny if the user does not respond.
|
||||
let pending = Arc::clone(&ctx.services.pending_perm_replies);
|
||||
let timeout_sender = sender.to_string();
|
||||
let timeout_request_id = perm_fwd.request_id.clone();
|
||||
let timeout_transport = Arc::clone(&ctx.transport);
|
||||
let timeout_secs = ctx.services.permission_timeout_secs;
|
||||
tokio::spawn(async move {
|
||||
tokio::time::sleep(std::time::Duration::from_secs(timeout_secs)).await;
|
||||
if let Some(tx) = pending.lock().await.remove(&timeout_sender) {
|
||||
if let Some(tx) = pending.remove_by_request_id(&timeout_sender, &timeout_request_id).await {
|
||||
let _ = tx.send(PermissionDecision::Deny);
|
||||
let msg = "Permission request timed out — denied (fail-closed).";
|
||||
let _ = timeout_transport.send_message(&timeout_sender, msg, "").await;
|
||||
@@ -123,7 +125,6 @@ pub(super) async fn handle_llm_message(
|
||||
}
|
||||
}
|
||||
};
|
||||
drop(perm_rx_guard);
|
||||
|
||||
// Flush remaining text.
|
||||
let remaining = buffer.lock().unwrap().trim().to_string();
|
||||
|
||||
Reference in New Issue
Block a user