1use serde::{Deserialize, Serialize};
8
9use crate::llm::ToolCall;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12#[serde(rename_all = "lowercase")]
13pub enum Role {
14 System,
15 User,
16 Assistant,
17 Tool,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct Message {
22 pub role: Role,
23 pub content: String,
24 #[serde(default, skip_serializing_if = "Vec::is_empty")]
25 pub tool_calls: Vec<ToolCall>,
26 #[serde(default, skip_serializing_if = "Option::is_none")]
27 pub tool_call_id: Option<String>,
28}
29
30impl Message {
31 pub fn system(content: impl Into<String>) -> Self {
32 Self {
33 role: Role::System,
34 content: content.into(),
35 tool_calls: Vec::new(),
36 tool_call_id: None,
37 }
38 }
39
40 pub fn user(content: impl Into<String>) -> Self {
41 Self {
42 role: Role::User,
43 content: content.into(),
44 tool_calls: Vec::new(),
45 tool_call_id: None,
46 }
47 }
48
49 pub fn assistant(content: impl Into<String>) -> Self {
50 Self {
51 role: Role::Assistant,
52 content: content.into(),
53 tool_calls: Vec::new(),
54 tool_call_id: None,
55 }
56 }
57
58 pub fn assistant_with_tool_calls(
59 content: impl Into<String>,
60 tool_calls: Vec<ToolCall>,
61 ) -> Self {
62 Self {
63 role: Role::Assistant,
64 content: content.into(),
65 tool_calls,
66 tool_call_id: None,
67 }
68 }
69
70 pub fn tool_result(tool_call_id: impl Into<String>, content: impl Into<String>) -> Self {
71 Self {
72 role: Role::Tool,
73 content: content.into(),
74 tool_calls: Vec::new(),
75 tool_call_id: Some(tool_call_id.into()),
76 }
77 }
78}