Skip to main content

vv_agent/sdk/session/run/
controls.rs

1use std::collections::BTreeMap;
2use std::sync::Arc;
3
4use serde_json::Value;
5
6use crate::sdk::types::AgentRun;
7
8use super::super::handles::{SessionCancellationHandle, SessionSteeringHandle};
9use super::super::util::normalize_session_prompt;
10use super::super::AgentSession;
11
12impl AgentSession {
13    pub fn follow_up(&mut self, prompt: impl Into<String>) -> Result<(), String> {
14        let prompt = normalize_session_prompt(prompt.into(), "follow_up prompt")?;
15        self.follow_up_queue
16            .lock()
17            .map_err(|_| "Session follow-up queue lock is poisoned.".to_string())?
18            .push_back(prompt.clone());
19        self.emit(
20            "session_follow_up_queued",
21            BTreeMap::from([("prompt".to_string(), Value::String(prompt))]),
22        );
23        Ok(())
24    }
25
26    pub fn steer(&mut self, prompt: impl Into<String>) -> Result<(), String> {
27        self.steering_handle().steer(prompt)
28    }
29
30    pub fn steering_handle(&self) -> SessionSteeringHandle {
31        SessionSteeringHandle {
32            steering_queue: Arc::clone(&self.steering_queue),
33            listeners: Arc::clone(&self.listeners),
34        }
35    }
36
37    pub fn cancellation_handle(&self) -> SessionCancellationHandle {
38        SessionCancellationHandle {
39            active_cancellation_token: Arc::clone(&self.active_cancellation_token),
40            steering_queue: Arc::clone(&self.steering_queue),
41            follow_up_queue: Arc::clone(&self.follow_up_queue),
42            listeners: Arc::clone(&self.listeners),
43        }
44    }
45
46    pub fn cancel(&self) -> bool {
47        self.cancellation_handle().cancel()
48    }
49
50    pub fn clear_queues(&mut self) {
51        if let Ok(mut queue) = self.steering_queue.lock() {
52            queue.clear();
53        }
54        if let Ok(mut queue) = self.follow_up_queue.lock() {
55            queue.clear();
56        }
57        self.emit("session_queues_cleared", BTreeMap::new());
58    }
59
60    pub fn continue_run(&mut self, prompt: Option<String>) -> Result<AgentRun, String> {
61        if let Some(prompt) = prompt {
62            let prompt = prompt.trim();
63            if !prompt.is_empty() {
64                return self.prompt_with_auto_follow_up(prompt.to_string(), false);
65            }
66        }
67
68        let queued_prompt = {
69            let mut steering_queue = self
70                .steering_queue
71                .lock()
72                .map_err(|_| "Session steering queue lock is poisoned.".to_string())?;
73            steering_queue.pop_front()
74        }
75        .or_else(|| {
76            self.follow_up_queue
77                .lock()
78                .expect("session follow-up queue lock")
79                .pop_front()
80        })
81        .ok_or_else(|| {
82            "No queued prompt available. Provide prompt or call steer()/follow_up() first."
83                .to_string()
84        })?;
85        self.prompt_with_auto_follow_up(queued_prompt, false)
86    }
87}