vv-agent 0.1.3

VectorVein agent runtime, SDK, CLI, tools, and workspace backends
Documentation
use std::collections::{BTreeMap, VecDeque};
use std::sync::{Arc, Mutex};

use serde_json::Value;

use crate::runtime::CancellationToken;

use super::events::emit_session_event;
use super::state::{SessionEventHandler, SessionListenerId};
use super::util::normalize_session_prompt;

#[derive(Clone)]
pub struct SessionSteeringHandle {
    pub(super) steering_queue: Arc<Mutex<VecDeque<String>>>,
    pub(super) listeners: Arc<Mutex<BTreeMap<SessionListenerId, SessionEventHandler>>>,
}

impl SessionSteeringHandle {
    pub fn steer(&self, prompt: impl Into<String>) -> Result<(), String> {
        let prompt = normalize_session_prompt(prompt.into(), "steer prompt")?;
        {
            let mut queue = self
                .steering_queue
                .lock()
                .map_err(|_| "Session steering queue lock is poisoned.".to_string())?;
            queue.push_back(prompt.clone());
        }
        emit_session_event(
            &self.listeners,
            "session_steer_queued",
            BTreeMap::from([("prompt".to_string(), Value::String(prompt))]),
        );
        Ok(())
    }
}

#[derive(Clone)]
pub struct SessionCancellationHandle {
    pub(super) active_cancellation_token: Arc<Mutex<Option<CancellationToken>>>,
    pub(super) steering_queue: Arc<Mutex<VecDeque<String>>>,
    pub(super) follow_up_queue: Arc<Mutex<VecDeque<String>>>,
    pub(super) listeners: Arc<Mutex<BTreeMap<SessionListenerId, SessionEventHandler>>>,
}

impl SessionCancellationHandle {
    pub fn cancel(&self) -> bool {
        let token = {
            self.active_cancellation_token
                .lock()
                .expect("session cancellation token lock")
                .clone()
        };
        let Some(token) = token else {
            return false;
        };
        token.cancel();
        if let Ok(mut queue) = self.steering_queue.lock() {
            queue.clear();
        }
        if let Ok(mut queue) = self.follow_up_queue.lock() {
            queue.clear();
        }
        emit_session_event(&self.listeners, "session_cancel_requested", BTreeMap::new());
        true
    }
}