story-kit: merge 91_bug_permissions_dialog_never_triggers_in_web_ui
This commit is contained in:
@@ -10,7 +10,7 @@ use poem::web::websocket::{Message as WsMessage, WebSocket};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::{mpsc, oneshot};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
@@ -155,11 +155,11 @@ pub async fn ws_handler(ws: WebSocket, ctx: Data<&Arc<AppContext>>) -> impl poem
|
||||
}
|
||||
});
|
||||
|
||||
// Channel for permission requests flowing from the PTY thread to this handler.
|
||||
let (perm_req_tx, mut perm_req_rx) =
|
||||
mpsc::unbounded_channel::<crate::llm::providers::claude_code::PermissionReqMsg>();
|
||||
// Map of pending permission request_id → one-shot responder.
|
||||
let mut pending_perms: HashMap<String, std::sync::mpsc::SyncSender<bool>> = HashMap::new();
|
||||
// Map of pending permission request_id → oneshot responder.
|
||||
// Permission requests arrive from the MCP `prompt_permission` tool via
|
||||
// `ctx.perm_rx` and are forwarded to the client as `PermissionRequest`.
|
||||
// When the client responds, we resolve the corresponding oneshot.
|
||||
let mut pending_perms: HashMap<String, oneshot::Sender<bool>> = HashMap::new();
|
||||
|
||||
loop {
|
||||
// Outer loop: wait for the next WebSocket message.
|
||||
@@ -174,7 +174,6 @@ pub async fn ws_handler(ws: WebSocket, ctx: Data<&Arc<AppContext>>) -> impl poem
|
||||
let tx_tokens = tx.clone();
|
||||
let tx_activity = tx.clone();
|
||||
let ctx_clone = ctx.clone();
|
||||
let perm_tx = perm_req_tx.clone();
|
||||
|
||||
// Build the chat future without driving it yet so we can
|
||||
// interleave it with permission-request forwarding.
|
||||
@@ -198,26 +197,29 @@ pub async fn ws_handler(ws: WebSocket, ctx: Data<&Arc<AppContext>>) -> impl poem
|
||||
tool_name: tool_name.to_string(),
|
||||
});
|
||||
},
|
||||
Some(perm_tx),
|
||||
);
|
||||
tokio::pin!(chat_fut);
|
||||
|
||||
// Lock the permission receiver for the duration of this chat
|
||||
// session. Permission requests from the MCP tool arrive here.
|
||||
let mut perm_rx = ctx.perm_rx.lock().await;
|
||||
|
||||
// Inner loop: drive the chat while concurrently handling
|
||||
// permission requests and WebSocket messages.
|
||||
// permission requests (from MCP) and WebSocket messages.
|
||||
let chat_result = loop {
|
||||
tokio::select! {
|
||||
result = &mut chat_fut => break result,
|
||||
|
||||
// Forward permission requests from PTY to the client.
|
||||
Some(perm_req) = perm_req_rx.recv() => {
|
||||
// Forward permission requests from MCP tool to the client.
|
||||
Some(perm_fwd) = perm_rx.recv() => {
|
||||
let _ = tx.send(WsResponse::PermissionRequest {
|
||||
request_id: perm_req.request_id.clone(),
|
||||
tool_name: perm_req.tool_name.clone(),
|
||||
tool_input: perm_req.tool_input.clone(),
|
||||
request_id: perm_fwd.request_id.clone(),
|
||||
tool_name: perm_fwd.tool_name.clone(),
|
||||
tool_input: perm_fwd.tool_input.clone(),
|
||||
});
|
||||
pending_perms.insert(
|
||||
perm_req.request_id,
|
||||
perm_req.response_tx,
|
||||
perm_fwd.request_id,
|
||||
perm_fwd.response_tx,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user