use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SDKControlRequest {
#[serde(rename = "type")]
pub msg_type: String,
pub request_id: String,
pub request: ControlRequest,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SDKControlResponse {
#[serde(rename = "type")]
pub msg_type: String,
pub response: ControlResponseData,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ControlResponseData {
Success(ControlResponseSuccess),
Error(ControlResponseError),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ControlResponseSuccess {
pub subtype: String,
pub request_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub response: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ControlResponseError {
pub subtype: String,
pub request_id: String,
pub error: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct HookMatcherConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub matcher: Option<String>,
pub hook_callback_ids: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "subtype", rename_all = "snake_case")]
pub enum ControlRequest {
Initialize {
#[serde(skip_serializing_if = "Option::is_none")]
hooks: Option<serde_json::Value>,
},
Interrupt,
SetPermissionMode { mode: String },
SetModel { model: Option<String> },
CanUseTool {
tool_name: String,
input: serde_json::Value,
#[serde(skip_serializing_if = "Option::is_none")]
permission_suggestions: Option<Vec<serde_json::Value>>,
#[serde(skip_serializing_if = "Option::is_none")]
blocked_path: Option<String>,
},
HookCallback {
callback_id: String,
input: serde_json::Value,
#[serde(skip_serializing_if = "Option::is_none")]
tool_use_id: Option<String>,
},
McpMessage {
server_name: String,
message: serde_json::Value,
},
RewindFiles { user_message_id: String },
McpStatus,
}