Skip to main content

vv_agent/sdk/session/
handles.rs

1use std::collections::{BTreeMap, VecDeque};
2use std::sync::{Arc, Mutex};
3
4use serde_json::Value;
5
6use crate::runtime::CancellationToken;
7
8use super::events::emit_session_event;
9use super::state::{SessionEventHandler, SessionListenerId};
10use super::util::normalize_session_prompt;
11
12#[derive(Clone)]
13pub struct SessionSteeringHandle {
14    pub(super) steering_queue: Arc<Mutex<VecDeque<String>>>,
15    pub(super) listeners: Arc<Mutex<BTreeMap<SessionListenerId, SessionEventHandler>>>,
16}
17
18impl SessionSteeringHandle {
19    pub fn steer(&self, prompt: impl Into<String>) -> Result<(), String> {
20        let prompt = normalize_session_prompt(prompt.into(), "steer prompt")?;
21        {
22            let mut queue = self
23                .steering_queue
24                .lock()
25                .map_err(|_| "Session steering queue lock is poisoned.".to_string())?;
26            queue.push_back(prompt.clone());
27        }
28        emit_session_event(
29            &self.listeners,
30            "session_steer_queued",
31            BTreeMap::from([("prompt".to_string(), Value::String(prompt))]),
32        );
33        Ok(())
34    }
35}
36
37#[derive(Clone)]
38pub struct SessionCancellationHandle {
39    pub(super) active_cancellation_token: Arc<Mutex<Option<CancellationToken>>>,
40    pub(super) steering_queue: Arc<Mutex<VecDeque<String>>>,
41    pub(super) follow_up_queue: Arc<Mutex<VecDeque<String>>>,
42    pub(super) listeners: Arc<Mutex<BTreeMap<SessionListenerId, SessionEventHandler>>>,
43}
44
45impl SessionCancellationHandle {
46    pub fn cancel(&self) -> bool {
47        let token = {
48            self.active_cancellation_token
49                .lock()
50                .expect("session cancellation token lock")
51                .clone()
52        };
53        let Some(token) = token else {
54            return false;
55        };
56        token.cancel();
57        if let Ok(mut queue) = self.steering_queue.lock() {
58            queue.clear();
59        }
60        if let Ok(mut queue) = self.follow_up_queue.lock() {
61            queue.clear();
62        }
63        emit_session_event(&self.listeners, "session_cancel_requested", BTreeMap::new());
64        true
65    }
66}