Skip to main content

vtcode_core/core/interfaces/
session.rs

1use anyhow::Result;
2use async_trait::async_trait;
3
4use crate::config::loader::VTCodeConfig;
5use crate::config::types::AgentConfig as CoreAgentConfig;
6use crate::core::agent::steering::SteeringMessage;
7
8/// High-level mode for an interactive agent session.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
10pub enum SessionMode {
11    Ask,
12    Architect,
13    #[default]
14    Code,
15}
16
17impl SessionMode {
18    pub const fn as_str(self) -> &'static str {
19        match self {
20            Self::Ask => "ask",
21            Self::Architect => "architect",
22            Self::Code => "code",
23        }
24    }
25
26    pub fn parse(value: &str) -> Option<Self> {
27        match value {
28            "ask" => Some(Self::Ask),
29            "architect" => Some(Self::Architect),
30            "code" => Some(Self::Code),
31            _ => None,
32        }
33    }
34}
35
36/// Source that triggered plan mode entry.
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
38pub enum PlanModeEntrySource {
39    #[default]
40    None,
41    CliFlag,
42    ConfigDefault,
43    UserRequest,
44}
45
46impl PlanModeEntrySource {
47    pub const fn should_auto_enter(self) -> bool {
48        matches!(self, Self::CliFlag)
49    }
50
51    pub const fn requires_startup_prompt(self) -> bool {
52        matches!(self, Self::ConfigDefault)
53    }
54}
55
56/// Parameters passed to a [`SessionRuntime`] implementation for executing an interactive session.
57#[derive(Debug)]
58pub struct SessionRuntimeParams<'a, Resume> {
59    pub agent_config: &'a CoreAgentConfig,
60    pub vt_config: Option<VTCodeConfig>,
61    pub skip_confirmations: bool,
62    pub full_auto: bool,
63    pub plan_mode_entry_source: PlanModeEntrySource,
64    pub resume: Option<Resume>,
65    pub steering_receiver: &'a mut Option<tokio::sync::mpsc::UnboundedReceiver<SteeringMessage>>,
66}
67
68impl<'a, Resume> SessionRuntimeParams<'a, Resume> {
69    #[expect(clippy::too_many_arguments)]
70    pub fn new(
71        agent_config: &'a CoreAgentConfig,
72        vt_config: Option<VTCodeConfig>,
73        skip_confirmations: bool,
74        full_auto: bool,
75        plan_mode_entry_source: PlanModeEntrySource,
76        resume: Option<Resume>,
77        steering_receiver: &'a mut Option<tokio::sync::mpsc::UnboundedReceiver<SteeringMessage>>,
78    ) -> Self {
79        Self {
80            agent_config,
81            vt_config,
82            skip_confirmations,
83            full_auto,
84            plan_mode_entry_source,
85            resume,
86            steering_receiver,
87        }
88    }
89}
90
91/// Abstraction over an interactive session runtime used by the CLI and adapters.
92#[async_trait]
93pub trait SessionRuntime<Resume>: Send + Sync {
94    async fn run_session(&self, params: SessionRuntimeParams<'_, Resume>) -> Result<()>;
95}
96
97#[cfg(test)]
98mod tests {
99    use super::SessionMode;
100
101    #[test]
102    fn session_mode_round_trip() {
103        assert_eq!(
104            SessionMode::parse(SessionMode::Ask.as_str()),
105            Some(SessionMode::Ask)
106        );
107        assert_eq!(
108            SessionMode::parse(SessionMode::Architect.as_str()),
109            Some(SessionMode::Architect)
110        );
111        assert_eq!(
112            SessionMode::parse(SessionMode::Code.as_str()),
113            Some(SessionMode::Code)
114        );
115        assert_eq!(SessionMode::parse("unknown"), None);
116    }
117}