1use serde::{Deserialize, Serialize};
7use serde_json::Value;
8
9#[derive(Debug, Deserialize)]
11pub struct JsonRpcRequest {
12 pub jsonrpc: String,
13 pub id: Option<Value>,
14 pub method: String,
15 #[serde(default)]
16 pub params: Option<Value>,
17}
18
19#[derive(Debug, Serialize)]
21pub struct JsonRpcResponse {
22 pub jsonrpc: String,
23 #[serde(skip_serializing_if = "Option::is_none")]
24 pub id: Option<Value>,
25 #[serde(skip_serializing_if = "Option::is_none")]
26 pub result: Option<Value>,
27 #[serde(skip_serializing_if = "Option::is_none")]
28 pub error: Option<JsonRpcError>,
29}
30
31impl JsonRpcResponse {
32 pub fn success(id: Option<Value>, result: Value) -> Self {
34 Self {
35 jsonrpc: "2.0".to_string(),
36 id,
37 result: Some(result),
38 error: None,
39 }
40 }
41
42 pub fn error(id: Option<Value>, code: i32, message: &str) -> Self {
44 Self {
45 jsonrpc: "2.0".to_string(),
46 id,
47 result: None,
48 error: Some(JsonRpcError {
49 code,
50 message: message.to_string(),
51 data: None,
52 }),
53 }
54 }
55}
56
57#[derive(Debug, Serialize)]
59pub struct JsonRpcError {
60 pub code: i32,
61 pub message: String,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 pub data: Option<Value>,
64}
65
66pub const PARSE_ERROR: i32 = -32700;
68pub const INVALID_REQUEST: i32 = -32600;
69pub const METHOD_NOT_FOUND: i32 = -32601;
70pub const INVALID_PARAMS: i32 = -32602;
71pub const INTERNAL_ERROR: i32 = -32603;
72
73#[derive(Debug, Deserialize)]
75#[serde(rename_all = "camelCase")]
76pub struct InitializeParams {
77 pub protocol_version: String,
78 pub capabilities: ClientCapabilities,
79 pub client_info: ClientInfo,
80}
81
82#[derive(Debug, Deserialize, Default)]
84pub struct ClientCapabilities {
85 #[serde(default)]
86 pub roots: Option<RootsCapability>,
87 #[serde(default)]
88 pub sampling: Option<Value>,
89}
90
91#[derive(Debug, Deserialize)]
93#[serde(rename_all = "camelCase")]
94pub struct RootsCapability {
95 #[serde(default)]
96 pub list_changed: bool,
97}
98
99#[derive(Debug, Deserialize)]
101pub struct ClientInfo {
102 pub name: String,
103 pub version: String,
104}
105
106#[derive(Debug, Serialize)]
108#[serde(rename_all = "camelCase")]
109pub struct InitializeResult {
110 pub protocol_version: String,
111 pub capabilities: ServerCapabilities,
112 pub server_info: ServerInfo,
113}
114
115#[derive(Debug, Serialize)]
117pub struct ServerCapabilities {
118 pub tools: ToolsCapability,
119}
120
121#[derive(Debug, Serialize)]
123#[serde(rename_all = "camelCase")]
124pub struct ToolsCapability {
125 pub list_changed: bool,
126}
127
128#[derive(Debug, Serialize)]
130pub struct ServerInfo {
131 pub name: String,
132 pub version: String,
133}
134
135#[derive(Debug, Serialize, Clone)]
137#[serde(rename_all = "camelCase")]
138pub struct ToolDefinition {
139 pub name: String,
140 pub description: String,
141 pub input_schema: Value,
142}
143
144#[derive(Debug, Serialize)]
146pub struct ToolsListResult {
147 pub tools: Vec<ToolDefinition>,
148}
149
150#[derive(Debug, Deserialize)]
152pub struct ToolCallParams {
153 pub name: String,
154 #[serde(default)]
155 pub arguments: Option<Value>,
156}
157
158#[derive(Debug, Serialize)]
160pub struct ToolCallResult {
161 pub content: Vec<ToolContent>,
162 #[serde(rename = "isError", skip_serializing_if = "Option::is_none")]
163 pub is_error: Option<bool>,
164}
165
166#[derive(Debug, Serialize)]
168#[serde(tag = "type")]
169pub enum ToolContent {
170 #[serde(rename = "text")]
171 Text { text: String },
172}
173
174impl ToolCallResult {
175 pub fn text(content: &str) -> Self {
177 Self {
178 content: vec![ToolContent::Text {
179 text: content.to_string(),
180 }],
181 is_error: None,
182 }
183 }
184
185 pub fn error(message: &str) -> Self {
187 Self {
188 content: vec![ToolContent::Text {
189 text: message.to_string(),
190 }],
191 is_error: Some(true),
192 }
193 }
194}
195
196#[derive(Debug, Clone, Deserialize)]
201pub struct LocationInput {
202 pub file: String,
204 #[serde(default)]
206 pub start_line: Option<u32>,
207 #[serde(default)]
209 pub end_line: Option<u32>,
210}
211
212#[derive(Debug, Deserialize)]
214pub struct LogEntry {
215 pub role: String,
216 pub category: String,
217 pub content: String,
218 #[serde(default)]
221 pub locations: Option<Vec<LocationInput>>,
222 #[serde(default)]
225 pub file_path: Option<String>,
226 #[serde(default)]
228 pub line_number: Option<u32>,
229}
230
231#[derive(Debug, Deserialize)]
235pub struct LogStepParams {
236 #[serde(default)]
238 pub role: Option<String>,
239 #[serde(default)]
241 pub category: Option<String>,
242 #[serde(default)]
244 pub content: Option<String>,
245 #[serde(default)]
247 pub locations: Option<Vec<LocationInput>>,
248 #[serde(default)]
251 pub file_path: Option<String>,
252 #[serde(default)]
254 pub line_number: Option<u32>,
255 #[serde(default)]
257 pub batch: Option<Vec<LogEntry>>,
258}
259
260#[derive(Debug, Deserialize)]
262pub struct GetContextParams {
263 pub git_hash: String,
264}
265
266#[derive(Debug, Deserialize)]
268pub struct GetRecentSummariesParams {
269 pub count: Option<usize>,
271}