use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AgentId {
GeneralTranslation,
SlidesGlmAgent,
AiDrawingAgent,
ReceiptRecognitionAgent,
ClothesRecognitionAgent,
IntelligentEducationSolveAgent,
ViduTemplateAgent,
}
impl AgentId {
pub const fn as_str(self) -> &'static str {
match self {
Self::GeneralTranslation => "general_translation",
Self::SlidesGlmAgent => "slides_glm_agent",
Self::AiDrawingAgent => "ai_drawing_agent",
Self::ReceiptRecognitionAgent => "receipt_recognition_agent",
Self::ClothesRecognitionAgent => "clothes_recognition_agent",
Self::IntelligentEducationSolveAgent => "intelligent_education_solve_agent",
Self::ViduTemplateAgent => "vidu_template_agent",
}
}
}
impl std::fmt::Display for AgentId {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter.write_str(self.as_str())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum AgentRole {
System,
User,
Assistant,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AgentRequestContentType {
Text,
FileId,
FileUrl,
ImageUrl,
}
#[derive(Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct AgentRequestContentPart {
#[serde(rename = "type")]
type_: AgentRequestContentType,
#[serde(skip_serializing_if = "Option::is_none")]
text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
file_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
file_url: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
image_url: Option<String>,
}
impl std::fmt::Debug for AgentRequestContentPart {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter
.debug_struct("AgentRequestContentPart")
.field("type", &self.type_)
.field("value", &"[REDACTED]")
.finish()
}
}
impl AgentRequestContentPart {
fn with_value(type_: AgentRequestContentType, value: String) -> Self {
let mut part = Self {
type_,
text: None,
file_id: None,
file_url: None,
image_url: None,
};
match type_ {
AgentRequestContentType::Text => part.text = Some(value),
AgentRequestContentType::FileId => part.file_id = Some(value),
AgentRequestContentType::FileUrl => part.file_url = Some(value),
AgentRequestContentType::ImageUrl => part.image_url = Some(value),
}
part
}
pub fn text(value: impl Into<String>) -> Self {
Self::with_value(AgentRequestContentType::Text, value.into())
}
pub fn file_id(value: impl Into<String>) -> Self {
Self::with_value(AgentRequestContentType::FileId, value.into())
}
pub fn file_url(value: impl Into<String>) -> Self {
Self::with_value(AgentRequestContentType::FileUrl, value.into())
}
pub fn image_url(value: impl Into<String>) -> Self {
Self::with_value(AgentRequestContentType::ImageUrl, value.into())
}
pub const fn type_(&self) -> AgentRequestContentType {
self.type_
}
}
#[derive(Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum AgentContent {
Text(String),
Part(AgentRequestContentPart),
Parts(Vec<AgentRequestContentPart>),
}
impl std::fmt::Debug for AgentContent {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Text(_) => formatter.write_str("AgentContent::Text([REDACTED])"),
Self::Part(part) => formatter
.debug_tuple("AgentContent::Part")
.field(part)
.finish(),
Self::Parts(parts) => formatter
.debug_struct("AgentContent::Parts")
.field("count", &parts.len())
.finish(),
}
}
}
impl From<String> for AgentContent {
fn from(value: String) -> Self {
Self::Text(value)
}
}
impl From<&str> for AgentContent {
fn from(value: &str) -> Self {
Self::Text(value.to_owned())
}
}
impl From<AgentRequestContentPart> for AgentContent {
fn from(value: AgentRequestContentPart) -> Self {
Self::Part(value)
}
}
impl From<Vec<AgentRequestContentPart>> for AgentContent {
fn from(value: Vec<AgentRequestContentPart>) -> Self {
Self::Parts(value)
}
}
#[derive(Clone, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct AgentMessage {
role: AgentRole,
content: AgentContent,
}
impl std::fmt::Debug for AgentMessage {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
formatter
.debug_struct("AgentMessage")
.field("role", &self.role)
.field("content", &"[REDACTED]")
.finish()
}
}
impl AgentMessage {
pub fn new(role: AgentRole, content: impl Into<AgentContent>) -> Self {
Self {
role,
content: content.into(),
}
}
pub fn user(content: impl Into<AgentContent>) -> Self {
Self::new(AgentRole::User, content)
}
pub fn system(content: impl Into<AgentContent>) -> Self {
Self::new(AgentRole::System, content)
}
pub fn assistant(content: impl Into<AgentContent>) -> Self {
Self::new(AgentRole::Assistant, content)
}
pub const fn role(&self) -> AgentRole {
self.role
}
pub const fn content(&self) -> &AgentContent {
&self.content
}
}