1use std::fmt;
2use std::path::PathBuf;
3
4use serde::Serialize;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
7pub enum ProviderKind {
8 Amp,
9 Copilot,
10 Codex,
11 Claude,
12 Cursor,
13 Gemini,
14 Kimi,
15 Pi,
16 Opencode,
17}
18
19impl fmt::Display for ProviderKind {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 match self {
22 Self::Amp => write!(f, "amp"),
23 Self::Copilot => write!(f, "copilot"),
24 Self::Codex => write!(f, "codex"),
25 Self::Claude => write!(f, "claude"),
26 Self::Cursor => write!(f, "cursor"),
27 Self::Gemini => write!(f, "gemini"),
28 Self::Kimi => write!(f, "kimi"),
29 Self::Pi => write!(f, "pi"),
30 Self::Opencode => write!(f, "opencode"),
31 }
32 }
33}
34
35#[derive(Debug, Clone, Default, PartialEq, Eq)]
36pub struct ResolutionMeta {
37 pub source: String,
38 pub candidate_count: usize,
39 pub warnings: Vec<String>,
40}
41
42#[derive(Debug, Clone, PartialEq, Eq)]
43pub struct ResolvedThread {
44 pub provider: ProviderKind,
45 pub session_id: String,
46 pub path: PathBuf,
47 pub metadata: ResolutionMeta,
48}
49
50#[derive(Debug, Clone, PartialEq, Eq)]
51pub struct WriteRequest {
52 pub prompt: String,
53 pub session_id: Option<String>,
54 pub options: WriteOptions,
55}
56
57#[derive(Debug, Clone, PartialEq, Eq)]
58pub struct WriteResult {
59 pub provider: ProviderKind,
60 pub session_id: String,
61 pub final_text: Option<String>,
62 pub warnings: Vec<String>,
63}
64
65#[derive(Debug, Clone, Default, PartialEq, Eq)]
66pub struct WriteOptions {
67 pub params: Vec<(String, Option<String>)>,
68 pub role: Option<String>,
69}
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
72pub enum MessageRole {
73 User,
74 Assistant,
75}
76
77impl fmt::Display for MessageRole {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 match self {
80 Self::User => write!(f, "user"),
81 Self::Assistant => write!(f, "assistant"),
82 }
83 }
84}
85
86#[derive(Debug, Clone, PartialEq, Eq)]
87pub struct ThreadMessage {
88 pub role: MessageRole,
89 pub text: String,
90}
91
92#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
93pub struct SubagentQuery {
94 pub provider: String,
95 pub main_thread_id: String,
96 pub agent_id: Option<String>,
97 pub list: bool,
98}
99
100#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize)]
101pub struct SubagentRelation {
102 pub validated: bool,
103 pub evidence: Vec<String>,
104}
105
106#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
107pub struct SubagentLifecycleEvent {
108 pub timestamp: Option<String>,
109 pub event: String,
110 pub detail: String,
111}
112
113#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
114pub struct SubagentExcerptMessage {
115 pub role: MessageRole,
116 pub text: String,
117}
118
119#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
120pub struct SubagentThreadRef {
121 pub thread_id: String,
122 pub path: Option<String>,
123 pub last_updated_at: Option<String>,
124}
125
126#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
127pub struct SubagentDetailView {
128 pub query: SubagentQuery,
129 pub relation: SubagentRelation,
130 pub lifecycle: Vec<SubagentLifecycleEvent>,
131 pub status: String,
132 pub status_source: String,
133 pub child_thread: Option<SubagentThreadRef>,
134 pub excerpt: Vec<SubagentExcerptMessage>,
135 #[serde(skip_serializing)]
136 pub warnings: Vec<String>,
137}
138
139#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
140pub struct SubagentListItem {
141 pub agent_id: String,
142 pub status: String,
143 pub status_source: String,
144 pub last_update: Option<String>,
145 pub relation: SubagentRelation,
146 pub child_thread: Option<SubagentThreadRef>,
147}
148
149#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
150pub struct SubagentListView {
151 pub query: SubagentQuery,
152 pub agents: Vec<SubagentListItem>,
153 #[serde(skip_serializing)]
154 pub warnings: Vec<String>,
155}
156
157#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
158#[serde(tag = "kind", rename_all = "snake_case")]
159pub enum SubagentView {
160 List(SubagentListView),
161 Detail(SubagentDetailView),
162}
163
164#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
165pub struct PiEntryQuery {
166 pub provider: String,
167 pub session_id: String,
168 pub list: bool,
169}
170
171#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
172pub struct PiEntryListItem {
173 pub entry_id: String,
174 pub entry_type: String,
175 pub parent_id: Option<String>,
176 pub timestamp: Option<String>,
177 pub is_leaf: bool,
178 pub preview: Option<String>,
179}
180
181#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
182pub struct PiEntryListView {
183 pub query: PiEntryQuery,
184 pub entries: Vec<PiEntryListItem>,
185 #[serde(skip_serializing)]
186 pub warnings: Vec<String>,
187}
188
189#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
190pub struct ThreadQuery {
191 pub uri: String,
192 pub provider: ProviderKind,
193 pub role: Option<String>,
194 pub q: Option<String>,
195 pub limit: usize,
196 pub ignored_params: Vec<String>,
197}
198
199#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
200pub struct PathThreadQuery {
201 pub uri: String,
202 pub scope_path: String,
203 pub providers: Option<Vec<ProviderKind>>,
204 pub q: Option<String>,
205 pub limit: usize,
206 pub ignored_params: Vec<String>,
207}
208
209#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
210pub struct ThreadQueryItem {
211 pub provider: ProviderKind,
212 pub thread_id: String,
213 pub uri: String,
214 pub thread_source: String,
215 pub updated_at: Option<String>,
216 pub matched_preview: Option<String>,
217 #[serde(skip_serializing_if = "Option::is_none")]
218 pub thread_metadata: Option<Vec<String>>,
219}
220
221#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
222pub struct ThreadQueryResult {
223 pub query: ThreadQuery,
224 pub items: Vec<ThreadQueryItem>,
225 #[serde(skip_serializing)]
226 pub warnings: Vec<String>,
227}
228
229#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
230pub struct PathThreadQueryResult {
231 pub query: PathThreadQuery,
232 pub items: Vec<ThreadQueryItem>,
233 #[serde(skip_serializing)]
234 pub warnings: Vec<String>,
235}