use serde::{Deserialize, Serialize};
use crate::json::JsonValue;
use crate::shared::{FileData, ProviderOptions};
pub type Prompt = Vec<Message>;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "role", rename_all = "lowercase")]
pub enum Message {
System {
content: String,
#[serde(
default,
rename = "providerOptions",
skip_serializing_if = "Option::is_none"
)]
provider_options: Option<ProviderOptions>,
},
User {
content: Vec<UserPart>,
#[serde(
default,
rename = "providerOptions",
skip_serializing_if = "Option::is_none"
)]
provider_options: Option<ProviderOptions>,
},
Assistant {
content: Vec<AssistantPart>,
#[serde(
default,
rename = "providerOptions",
skip_serializing_if = "Option::is_none"
)]
provider_options: Option<ProviderOptions>,
},
Tool {
content: Vec<ToolMessagePart>,
#[serde(
default,
rename = "providerOptions",
skip_serializing_if = "Option::is_none"
)]
provider_options: Option<ProviderOptions>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "type", rename_all = "kebab-case")]
pub enum UserPart {
Text(TextPart),
File(FilePart),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "type", rename_all = "kebab-case")]
pub enum AssistantPart {
Text(TextPart),
File(FilePart),
Reasoning {
text: String,
#[serde(
default,
rename = "providerOptions",
skip_serializing_if = "Option::is_none"
)]
provider_options: Option<ProviderOptions>,
},
ReasoningFile {
data: FileData,
#[serde(rename = "mediaType")]
media_type: String,
#[serde(
default,
rename = "providerOptions",
skip_serializing_if = "Option::is_none"
)]
provider_options: Option<ProviderOptions>,
},
Custom {
kind: String,
#[serde(
default,
rename = "providerOptions",
skip_serializing_if = "Option::is_none"
)]
provider_options: Option<ProviderOptions>,
},
ToolCall(ToolCallPart),
ToolResult(ToolResultPart),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(tag = "type", rename_all = "kebab-case")]
pub enum ToolMessagePart {
ToolResult(ToolResultPart),
ToolApprovalResponse(ToolApprovalResponsePart),
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct TextPart {
pub text: String,
#[serde(
default,
rename = "providerOptions",
skip_serializing_if = "Option::is_none"
)]
pub provider_options: Option<ProviderOptions>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct FilePart {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub filename: Option<String>,
pub data: FileData,
#[serde(rename = "mediaType")]
pub media_type: String,
#[serde(
default,
rename = "providerOptions",
skip_serializing_if = "Option::is_none"
)]
pub provider_options: Option<ProviderOptions>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ToolCallPart {
#[serde(rename = "toolCallId")]
pub tool_call_id: String,
#[serde(rename = "toolName")]
pub tool_name: String,
pub input: JsonValue,
#[serde(
default,
rename = "providerExecuted",
skip_serializing_if = "Option::is_none"
)]
pub provider_executed: Option<bool>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub dynamic: Option<bool>,
#[serde(
default,
rename = "providerOptions",
skip_serializing_if = "Option::is_none"
)]
pub provider_options: Option<ProviderOptions>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ToolResultPart {
#[serde(rename = "toolCallId")]
pub tool_call_id: String,
#[serde(rename = "toolName")]
pub tool_name: String,
pub output: super::content::ToolResultOutput,
#[serde(
default,
rename = "providerOptions",
skip_serializing_if = "Option::is_none"
)]
pub provider_options: Option<ProviderOptions>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct ToolApprovalResponsePart {
#[serde(rename = "approvalId")]
pub approval_id: String,
pub approved: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub reason: Option<String>,
#[serde(
default,
rename = "providerOptions",
skip_serializing_if = "Option::is_none"
)]
pub provider_options: Option<ProviderOptions>,
}