Skip to main content

ds_api/raw/request/
message.rs

1use serde::{Deserialize, Serialize};
2
3// Unified message struct
4// This struct is used both for the `messages` array in requests and the `message` field in responses.
5// All fields are optional to cover different roles and scenarios.
6#[derive(Debug, Serialize, Deserialize, Default, Clone)]
7pub struct Message {
8    /// default role is User
9    pub role: Role,
10
11    /// The content may be null for assistant messages (only when `tool_calls` are present)
12    #[serde(skip_serializing_if = "Option::is_none")]
13    pub content: Option<String>,
14
15    /// Optional name to identify a user or function
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub name: Option<String>,
18
19    /// Required when role = "tool"; links to the previous tool call ID
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub tool_call_id: Option<String>,
22
23    /// Present when role = "assistant" and the model requested tool calls
24    #[serde(skip_serializing_if = "Option::is_none")]
25    pub tool_calls: Option<Vec<ToolCall>>,
26
27    /// Reasoning content produced by the model (may appear only in responses)
28    #[serde(skip_serializing_if = "Option::is_none")]
29    pub reasoning_content: Option<String>,
30
31    /// Beta: if true, forces the model to begin its reply with the prefix content provided in this assistant message
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub prefix: Option<bool>,
34}
35
36/// The `name` value written by built-in summarizers to mark a system message
37/// as an auto-generated summary that may be replaced on the next summarization
38/// pass.  Any `Role::System` message **without** this tag is treated as a
39/// permanent user-provided system prompt and is never removed.
40pub const AUTO_SUMMARY_TAG: &str = "[auto-summary]";
41
42impl Message {
43    pub fn new(role: Role, message: &str) -> Self {
44        Self {
45            role,
46            content: Some(message.to_string()),
47            name: None,
48            tool_call_id: None,
49            tool_calls: None,
50            reasoning_content: None,
51            prefix: None,
52        }
53    }
54
55    pub fn user(message: &str) -> Self {
56        Self::new(Role::User, message)
57    }
58
59    pub fn assistant(message: &str) -> Self {
60        Self::new(Role::Assistant, message)
61    }
62
63    pub fn system(message: &str) -> Self {
64        Self::new(Role::System, message)
65    }
66
67    /// Returns `true` if this is an auto-generated summary message produced by
68    /// a built-in [`Summarizer`](crate::conversation::Summarizer) implementation.
69    ///
70    /// Auto-summary messages are `Role::System` messages whose `name` field is
71    /// set to [`AUTO_SUMMARY_TAG`].  They may be replaced on subsequent
72    /// summarization passes.  All other `Role::System` messages are permanent
73    /// user-provided prompts and must never be removed by a summarizer.
74    #[inline]
75    pub fn is_auto_summary(&self) -> bool {
76        matches!(self.role, Role::System) && self.name.as_deref() == Some(AUTO_SUMMARY_TAG)
77    }
78
79    /// Create an auto-summary system message wrapping the given text.
80    pub(crate) fn auto_summary(text: impl Into<String>) -> Self {
81        let mut msg = Self::new(Role::System, &text.into());
82        msg.name = Some(AUTO_SUMMARY_TAG.to_string());
83        msg
84    }
85}
86
87// Role enum (includes Tool variant)
88#[derive(Debug, Serialize, Deserialize, Clone, Default)]
89#[serde(rename_all = "lowercase")]
90pub enum Role {
91    System,
92    #[default]
93    User,
94    Assistant,
95    Tool,
96}
97
98// Tool call struct (reused in requests and responses)
99#[derive(Debug, Serialize, Deserialize, Clone)]
100pub struct ToolCall {
101    pub id: String,
102    pub r#type: ToolType,
103    pub function: FunctionCall,
104}
105
106#[derive(Debug, Serialize, Deserialize, Clone)]
107#[serde(rename_all = "lowercase")]
108pub enum ToolType {
109    Function,
110}
111
112#[derive(Debug, Serialize, Deserialize, Clone)]
113pub struct FunctionCall {
114    pub name: String,
115    pub arguments: String, // JSON string
116}