Skip to main content

vv_agent/app_server/protocol/
thread.rs

1use std::collections::BTreeMap;
2use std::path::PathBuf;
3
4use schemars::JsonSchema;
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7use ts_rs::TS;
8
9use super::item::AppItem;
10use super::turn::AppTurn;
11
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, TS)]
13#[serde(rename_all = "camelCase")]
14pub struct ThreadStartParams {
15    #[serde(default = "default_agent_key")]
16    pub agent_key: String,
17    #[serde(default, skip_serializing_if = "Option::is_none")]
18    pub cwd: Option<PathBuf>,
19    #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
20    pub metadata: BTreeMap<String, Value>,
21}
22
23impl Default for ThreadStartParams {
24    fn default() -> Self {
25        Self {
26            agent_key: default_agent_key(),
27            cwd: None,
28            metadata: BTreeMap::new(),
29        }
30    }
31}
32
33#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
34#[serde(rename_all = "camelCase")]
35pub struct ThreadResumeParams {
36    pub thread_id: String,
37    #[serde(default = "default_subscribe")]
38    pub subscribe: bool,
39}
40
41#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
42#[serde(rename_all = "camelCase")]
43pub struct ThreadReadParams {
44    pub thread_id: String,
45    #[serde(default, skip_serializing_if = "Option::is_none")]
46    pub after_item_id: Option<String>,
47}
48
49#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
50#[serde(rename_all = "camelCase")]
51pub struct ThreadListParams {
52    #[serde(default)]
53    pub include_archived: bool,
54    #[serde(default, skip_serializing_if = "Option::is_none")]
55    pub archived: Option<bool>,
56    #[serde(default, skip_serializing_if = "Option::is_none")]
57    pub offset: Option<usize>,
58    #[serde(default, skip_serializing_if = "Option::is_none")]
59    pub limit: Option<usize>,
60}
61
62#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
63#[serde(rename_all = "camelCase")]
64pub struct ThreadArchiveParams {
65    pub thread_id: String,
66}
67
68#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
69#[serde(rename_all = "camelCase")]
70pub struct ThreadUnsubscribeParams {
71    pub thread_id: String,
72}
73
74#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, TS)]
75#[serde(rename_all = "camelCase")]
76pub struct ThreadStartResponse {
77    pub thread_id: String,
78    pub agent_key: String,
79    #[serde(default)]
80    pub cwd: Option<PathBuf>,
81    pub status: ThreadStatus,
82}
83
84impl ThreadStartResponse {
85    pub fn from_thread(thread: &AppThread) -> Self {
86        Self {
87            thread_id: thread.thread_id.clone(),
88            agent_key: thread.agent_key.clone(),
89            cwd: thread.cwd.clone(),
90            status: thread.status,
91        }
92    }
93}
94
95pub type ThreadStartedParams = ThreadStartResponse;
96
97#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, TS)]
98#[serde(rename_all = "camelCase")]
99pub struct ThreadResumeResponse {
100    pub thread: AppThread,
101    pub turns: Vec<AppTurn>,
102    pub items: Vec<AppItem>,
103}
104
105pub type ThreadReadResponse = ThreadResumeResponse;
106
107#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, TS)]
108#[serde(rename_all = "camelCase")]
109pub struct ThreadListResponse {
110    pub threads: Vec<AppThread>,
111}
112
113#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
114#[serde(rename_all = "camelCase")]
115pub struct ThreadArchiveResponse {
116    pub thread_id: String,
117    pub archived: bool,
118}
119
120#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
121#[serde(rename_all = "camelCase")]
122pub struct ThreadUnsubscribeResponse {
123    pub thread_id: String,
124    pub subscribed: bool,
125    pub closed: bool,
126}
127
128pub type ThreadArchivedParams = ThreadArchiveResponse;
129
130#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
131#[serde(rename_all = "camelCase")]
132pub struct ThreadClosedParams {
133    pub thread_id: String,
134}
135
136#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
137#[serde(rename_all = "camelCase")]
138pub struct ThreadStatusChangedParams {
139    pub thread_id: String,
140    pub status: ThreadStatus,
141}
142
143#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, TS)]
144#[serde(rename_all = "camelCase")]
145pub struct AppThread {
146    pub thread_id: String,
147    pub agent_key: String,
148    #[serde(default)]
149    pub cwd: Option<PathBuf>,
150    pub created_at: f64,
151    pub updated_at: f64,
152    #[serde(default)]
153    pub archived_at: Option<f64>,
154    pub status: ThreadStatus,
155    #[serde(default)]
156    pub metadata: BTreeMap<String, Value>,
157}
158
159#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
160#[serde(rename_all = "camelCase")]
161pub enum ThreadStatus {
162    Idle,
163    Running,
164    Archived,
165    Closed,
166}
167
168fn default_agent_key() -> String {
169    "default".to_string()
170}
171
172fn default_subscribe() -> bool {
173    true
174}