vv_agent/sdk/session/
handles.rs1use 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}