Skip to main content

vtcode_desktop_protocol/
session.rs

1//! Session lifecycle, history paging, and idle-session option DTOs.
2
3use serde::{Deserialize, Serialize};
4
5/// Session execution and command confirmation policy.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "camelCase")]
8pub enum PermissionMode {
9    /// Preserve interactive confirmation for protected commands.
10    Ask,
11    /// Use the CLI's skip-confirmations behavior for commands.
12    AutoApproveCommands,
13    /// Run without the process sandbox or interactive approval prompts.
14    FullAccess,
15}
16
17/// Runtime options exposed without credentials or complete configuration documents.
18#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
19#[serde(rename_all = "camelCase")]
20pub struct SessionOptionsSnapshot {
21    /// Effective command confirmation policy.
22    pub permission_mode: PermissionMode,
23    /// Selected primary agent, such as build or plan.
24    pub mode: String,
25    /// Primary agents discovered by the CLI for this workspace.
26    #[serde(default)]
27    pub available_modes: Vec<AgentModeInfo>,
28    /// CLI reasoning effort identifier.
29    pub reasoning_effort: String,
30    /// Efforts supported by this exact provider/model route.
31    pub supported_efforts: Vec<String>,
32    /// Effective provider speed badge, when supported by this route.
33    pub speed: Option<String>,
34    /// Whether this exact provider/model route supports the CLI's fast setting.
35    #[serde(default)]
36    pub fast_mode_supported: bool,
37    /// Whether fast processing is currently enabled for this route.
38    #[serde(default)]
39    pub fast_mode_enabled: bool,
40    /// Label used by the CLI for the selected fast tier on this route.
41    #[serde(default, skip_serializing_if = "Option::is_none")]
42    pub fast_mode_label: Option<String>,
43}
44
45/// Non-secret metadata for a selectable CLI primary agent.
46#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
47#[serde(rename_all = "camelCase")]
48pub struct AgentModeInfo {
49    /// Canonical CLI primary-agent name.
50    pub name: String,
51    /// CLI display name.
52    pub display_name: String,
53    /// Short description of the agent's role.
54    pub description: String,
55}
56
57/// An explicit idle-session option change. Omitted values preserve existing choices.
58#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
59#[serde(rename_all = "camelCase", deny_unknown_fields)]
60pub struct SessionOptionsSelectParams {
61    /// Change command confirmations, retaining sandbox and tool authorization.
62    pub permission_mode: Option<PermissionMode>,
63    /// Select a built-in build or plan agent.
64    pub mode: Option<String>,
65    /// Select a capability-validated reasoning effort.
66    pub reasoning_effort: Option<String>,
67    /// Select the CLI's fast processing tier for a compatible route.
68    pub fast_mode: Option<bool>,
69    /// One-shot attestation that the user completed the Full access
70    /// confirmation dialog (risk disclosure + explicit acknowledge) for this
71    /// request. Required when `permission_mode` is `FullAccess`; never
72    /// persisted, never merged into stored session options.
73    pub full_access_confirmed: Option<bool>,
74}
75
76/// Persist a built-in CLI theme selected in Desktop.
77#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
78#[serde(rename_all = "camelCase", deny_unknown_fields)]
79pub struct ThemePreferenceSelectParams {
80    /// Built-in VT Code theme identifier.
81    pub theme: String,
82}
83
84/// A persisted session available for reload.
85#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
86#[serde(rename_all = "camelCase")]
87pub struct SessionSummary {
88    /// Stable durable session identifier.
89    pub session_id: String,
90    /// Human-readable title when known.
91    pub title: Option<String>,
92    /// Session workspace path.
93    pub workspace: String,
94    /// Whether the last observed state was terminal.
95    pub completed: bool,
96    /// Whether this session can be continued using existing archive data.
97    pub resumable: bool,
98    /// Archive size in bytes, zero when unknown.
99    #[serde(default)]
100    pub size_bytes: u64,
101    /// Snapshot end time as unix seconds, absent when unknown.
102    #[serde(default, skip_serializing_if = "Option::is_none")]
103    pub updated_at: Option<u64>,
104}
105
106/// Text restored from the durable message snapshot for a loaded session.
107#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
108#[serde(rename_all = "camelCase")]
109pub struct SessionHistoryMessage {
110    /// Model-only context retained for archive indexing but hidden from the transcript.
111    #[serde(default)]
112    pub hidden: bool,
113    /// Stable zero-based index in the archived session snapshot.
114    #[serde(default, skip_serializing_if = "Option::is_none")]
115    pub archive_index: Option<usize>,
116    /// Message role such as `user`, `assistant`, or `tool`.
117    pub role: String,
118    /// Text projection of the persisted message content.
119    pub text: String,
120}
121
122/// Loaded durable session metadata and its bounded transcript projection.
123#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
124#[serde(rename_all = "camelCase")]
125pub struct SessionLoadResult {
126    /// Selected session metadata.
127    pub session: SessionSummary,
128    /// Recent messages restored from the archive snapshot.
129    pub messages: Vec<SessionHistoryMessage>,
130    /// Index of the earliest restored message in the archive snapshot.
131    #[serde(default)]
132    pub history_start_index: usize,
133    /// Whether earlier archived messages can be requested.
134    #[serde(default)]
135    pub history_has_earlier: bool,
136    /// Recent file-change snapshots from canonical history, in persisted order.
137    #[serde(default, skip_serializing_if = "Vec::is_empty")]
138    pub review_items: Vec<vtcode_exec_events::ThreadItem>,
139    /// Whether bounded history projection omitted review evidence.
140    #[serde(default)]
141    pub review_history_incomplete: bool,
142    /// Recent canonical tool, command, and supporting activity snapshots.
143    #[serde(default, skip_serializing_if = "Vec::is_empty")]
144    pub activity_items: Vec<vtcode_exec_events::ThreadItem>,
145    /// Bounded cursors for archived tool output that can be loaded on demand.
146    #[serde(default, skip_serializing_if = "Vec::is_empty")]
147    pub activity_output_cursors: Vec<SessionOutputCursor>,
148    /// Whether bounded history projection omitted activity or output evidence.
149    #[serde(default)]
150    pub activity_history_incomplete: bool,
151}
152
153/// Request an earlier bounded page of the selected archived conversation.
154#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
155#[serde(rename_all = "camelCase")]
156pub struct SessionHistoryParams {
157    /// Durable session identifier.
158    pub session_id: String,
159    /// Request identity echoed by the service to reject stale pages.
160    pub request_id: String,
161    /// Exclusive end index for the page; use the earliest loaded archive index.
162    pub before_index: usize,
163    /// Number of messages requested, capped by [`MAX_SESSION_HISTORY_PAGE_MESSAGES`].
164    pub limit: usize,
165}
166
167/// One bounded earlier page from a durable conversation.
168#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
169#[serde(rename_all = "camelCase")]
170pub struct SessionHistoryPage {
171    /// Durable session identifier that owns the page.
172    pub session_id: String,
173    /// Request identity echoed from [`SessionHistoryParams`].
174    pub request_id: String,
175    /// Index of the earliest message included in this page.
176    pub start_index: usize,
177    /// Messages in chronological order.
178    pub messages: Vec<SessionHistoryMessage>,
179    /// Whether the archive contains messages before this page.
180    pub has_earlier: bool,
181}
182
183/// Cursor for reading more of a restored tool-output capture.
184#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
185#[serde(rename_all = "camelCase")]
186pub struct SessionOutputCursor {
187    /// Stable canonical activity item identity.
188    pub item_id: String,
189    /// Byte offset to request next; always a UTF-8 boundary for text output.
190    pub next_offset: u64,
191    /// Captured spool size observed during session restore.
192    pub total_bytes: u64,
193}
194
195/// Request one bounded page from a restored tool-output capture.
196#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
197#[serde(rename_all = "camelCase")]
198pub struct SessionOutputReadParams {
199    /// Durable session that owns the output item.
200    pub session_id: String,
201    /// Request identity echoed by the service to reject stale pages.
202    pub request_id: String,
203    /// Stable canonical activity item identity.
204    pub item_id: String,
205    /// UTF-8 byte offset supplied by the current cursor.
206    pub offset: u64,
207}
208
209/// One bounded page from an archived tool-output capture.
210#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
211#[serde(rename_all = "camelCase")]
212pub struct SessionOutputPage {
213    /// Durable session that owns the output item.
214    pub session_id: String,
215    /// Request identity echoed from [`SessionOutputReadParams`].
216    pub request_id: String,
217    /// Stable canonical activity item identity.
218    pub item_id: String,
219    /// Requested starting offset.
220    pub offset: u64,
221    /// Next UTF-8 boundary after the returned text.
222    pub next_offset: u64,
223    /// Captured spool size observed during this read.
224    pub total_bytes: u64,
225    /// Text captured in this page.
226    pub text: String,
227    /// Whether more captured bytes remain.
228    pub has_more: bool,
229}
230
231/// Parameters for creating an empty session.
232#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
233#[serde(rename_all = "camelCase")]
234pub struct SessionCreateParams {
235    /// Optional title shown in history.
236    pub title: Option<String>,
237}
238
239/// Parameters for loading a durable session.
240#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
241#[serde(rename_all = "camelCase")]
242pub struct SessionIdParams {
243    /// Durable session identifier.
244    pub session_id: String,
245}
246
247/// Maximum message count accepted by one desktop archive-history page request.
248pub const MAX_SESSION_HISTORY_PAGE_MESSAGES: usize = 160;
249
250/// Maximum captured output returned by one on-demand desktop page.
251pub const MAX_SESSION_OUTPUT_PAGE_BYTES: usize = 32 * 1024;
252
253/// Marker appended while more archived tool output is available.
254pub const RESTORED_OUTPUT_TRUNCATION_SUFFIX: &str = "\n[Output truncated in restored history.]";