use serde::{Deserialize, Serialize};
use serde_json::Value;
macro_rules! opaque_struct {
($name:ident) => {
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct $name {
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
};
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientInfo {
pub name: String,
pub title: String,
pub version: String,
}
impl ClientInfo {
pub fn new(
name: impl Into<String>,
title: impl Into<String>,
version: impl Into<String>,
) -> Self {
Self {
name: name.into(),
title: title.into(),
version: version.into(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct InitializeCapabilities {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub experimental_api: Option<bool>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct InitializeParams {
pub client_info: ClientInfo,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub capabilities: Option<InitializeCapabilities>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
impl InitializeParams {
pub fn new(client_info: ClientInfo) -> Self {
Self {
client_info,
capabilities: None,
extra: serde_json::Map::new(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct PaginationParams {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cursor: Option<String>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct ThreadStartParams {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model_provider: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cwd: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub approval_policy: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub sandbox: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub sandbox_policy: Option<Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub effort: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub summary: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub personality: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ephemeral: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub base_instructions: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub developer_instructions: Option<String>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct ThreadResumeParams {
pub thread_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub history: Option<Vec<Value>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub path: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model_provider: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cwd: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub approval_policy: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub sandbox: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub config: Option<serde_json::Map<String, Value>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub base_instructions: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub developer_instructions: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub personality: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub persist_extended_history: Option<bool>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ThreadIdParams {
pub thread_id: String,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
impl ThreadResumeParams {
pub fn from_thread_id(thread_id: impl Into<String>) -> Self {
Self {
thread_id: thread_id.into(),
..Self::default()
}
}
}
impl From<ThreadIdParams> for ThreadResumeParams {
fn from(value: ThreadIdParams) -> Self {
Self {
thread_id: value.thread_id,
extra: value.extra,
..Self::default()
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ThreadForkParams {
pub thread_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub from_turn_id: Option<String>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ThreadSetNameParams {
pub thread_id: String,
pub name: String,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ThreadRollbackParams {
pub thread_id: String,
pub count: u32,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ThreadBackgroundTerminalsCleanParams {
pub thread_id: String,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct ThreadListParams {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub limit: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cursor: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub archived: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source_kinds: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model_providers: Option<Vec<String>>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ThreadReadParams {
pub thread_id: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub include_turns: Option<bool>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum TurnInputItem {
Text {
text: String,
},
Image {
url: String,
},
LocalImage {
path: String,
},
Skill {
name: String,
path: String,
},
#[serde(other)]
Unknown,
}
impl TurnInputItem {
pub fn text(text: impl Into<String>) -> Self {
Self::Text { text: text.into() }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TurnStartParams {
pub thread_id: String,
pub input: Vec<TurnInputItem>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cwd: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub model_provider: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub effort: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub summary: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub personality: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub output_schema: Option<Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub approval_policy: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub sandbox_policy: Option<Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub collaboration_mode: Option<String>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
impl TurnStartParams {
pub fn text(thread_id: impl Into<String>, text: impl Into<String>) -> Self {
Self {
thread_id: thread_id.into(),
input: vec![TurnInputItem::text(text)],
cwd: None,
model: None,
model_provider: None,
effort: None,
summary: None,
personality: None,
output_schema: None,
approval_policy: None,
sandbox_policy: None,
collaboration_mode: None,
extra: serde_json::Map::new(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TurnSteerParams {
pub thread_id: String,
pub input: Vec<TurnInputItem>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub expected_turn_id: Option<String>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct TurnInterruptParams {
pub thread_id: String,
pub turn_id: String,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct SkillsListParams {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cwd: Option<Vec<String>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub force_reload: Option<bool>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
opaque_struct!(SkillsRemoteReadParams);
opaque_struct!(SkillsRemoteWriteParams);
opaque_struct!(SkillsConfigWriteParams);
opaque_struct!(AppsListParams);
opaque_struct!(ReviewStartParams);
opaque_struct!(ModelListParams);
opaque_struct!(ExperimentalFeatureListParams);
opaque_struct!(CollaborationModeListParams);
opaque_struct!(MockExperimentalMethodParams);
opaque_struct!(McpServerOauthLoginParams);
opaque_struct!(ListMcpServerStatusParams);
opaque_struct!(WindowsSandboxSetupStartParams);
opaque_struct!(FeedbackUploadParams);
opaque_struct!(CommandExecParams);
opaque_struct!(ConfigReadParams);
opaque_struct!(ConfigValueWriteParams);
opaque_struct!(ConfigBatchWriteParams);
opaque_struct!(FuzzyFileSearchSessionStartParams);
opaque_struct!(FuzzyFileSearchSessionUpdateParams);
opaque_struct!(FuzzyFileSearchSessionStopParams);
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct LoginAccountParams {
#[serde(rename = "type")]
pub login_type: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub api_key: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub id_token: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub access_token: Option<String>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
impl LoginAccountParams {
pub fn api_key(key: impl Into<String>) -> Self {
Self {
login_type: "apiKey".to_string(),
api_key: Some(key.into()),
id_token: None,
access_token: None,
extra: serde_json::Map::new(),
}
}
pub fn chatgpt(id_token: impl Into<String>, access_token: impl Into<String>) -> Self {
Self {
login_type: "chatgpt".to_string(),
api_key: None,
id_token: Some(id_token.into()),
access_token: Some(access_token.into()),
extra: serde_json::Map::new(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CancelLoginAccountParams {
pub login_id: String,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct GetAccountParams {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub refresh_token: Option<bool>,
#[serde(flatten)]
pub extra: serde_json::Map<String, Value>,
}
pub type ThreadArchiveParams = ThreadIdParams;
pub type ThreadUnarchiveParams = ThreadIdParams;
pub type ThreadCompactStartParams = ThreadIdParams;
pub type ThreadLoadedListParams = PaginationParams;