Skip to main content

ras_llm/domain/
message.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4#[serde(tag = "role", rename_all = "lowercase")]
5pub enum ChatMessage {
6    System(SystemMessage),
7    User(UserMessage),
8    Assistant(AssistantMessage),
9    Tool(ToolResultMessage),
10}
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct SystemMessage {
14    pub content: String,
15    #[serde(default)]
16    pub cache: bool,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct UserMessage {
21    pub content: Vec<ContentPart>,
22    #[serde(default)]
23    pub cache: bool,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct AssistantMessage {
28    pub content: Option<String>,
29    #[serde(default)]
30    pub tool_calls: Vec<ToolCall>,
31    #[serde(default)]
32    pub cache: bool,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct ToolResultMessage {
37    pub tool_call_id: String,
38    pub content: String,
39    #[serde(default)]
40    pub is_error: bool,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
44#[serde(tag = "type", rename_all = "snake_case")]
45pub enum ContentPart {
46    Text { text: String },
47    ImageBase64 { media_type: String, data: String },
48    ImageUrl { url: String },
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct ToolCall {
53    pub id: String,
54    pub name: String,
55    pub arguments: serde_json::Value,
56}
57
58impl ChatMessage {
59    #[must_use]
60    pub fn system(content: impl Into<String>) -> Self {
61        Self::System(SystemMessage {
62            content: content.into(),
63            cache: false,
64        })
65    }
66
67    #[must_use]
68    pub fn user_text(text: impl Into<String>) -> Self {
69        Self::User(UserMessage {
70            content: vec![ContentPart::Text { text: text.into() }],
71            cache: false,
72        })
73    }
74
75    #[must_use]
76    pub fn assistant_text(text: impl Into<String>) -> Self {
77        Self::Assistant(AssistantMessage {
78            content: Some(text.into()),
79            tool_calls: Vec::new(),
80            cache: false,
81        })
82    }
83}