async_dashscope/operation/generation/
param.rs

1use derive_builder::Builder;
2use serde::{Deserialize, Serialize};
3use thiserror::Error;
4
5use crate::operation::common::{Parameters, StreamOptions};
6use crate::operation::request::RequestTrait;
7
8#[derive(Debug, Clone, Builder, Serialize, Deserialize, PartialEq)]
9pub struct GenerationParam {
10    #[builder(setter(into, strip_option))]
11    pub model: String,
12
13    pub input: Input,
14
15    #[serde(skip_serializing_if = "Option::is_none")]
16    #[builder(setter(into, strip_option))]
17    #[builder(default=None)]
18    pub parameters: Option<Parameters>,
19
20    #[builder(setter(into, strip_option))]
21    #[builder(default=Some(false))]
22    pub stream: Option<bool>,
23
24    #[builder(setter(into, strip_option))]
25    #[builder(default=None)]
26    pub stream_options: Option<StreamOptions>,
27}
28
29#[derive(Debug, Clone, Builder, Serialize, Deserialize, PartialEq)]
30pub struct Input {
31    #[builder(setter(custom))]
32    pub messages: Vec<Message>,
33}
34impl InputBuilder {
35    pub fn messages(&mut self, value: Vec<Message>) -> &mut Self {
36        self.messages = Some(value);
37        self
38    }
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
42#[serde(untagged)]
43#[derive(Default)]
44pub enum Message {
45    #[default]
46    None,
47    System(SystemMessage),
48    User(UserMessage),
49    Assistant(AssistantMessage),
50    Tool(ToolMessage),
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
54pub struct MessageBuilder {
55    pub role: String,
56    pub content: String,
57    pub partial: Option<bool>,
58    pub tool_calls: Option<Vec<ToolCall>>,
59    pub tool_call_id: Option<String>,
60}
61
62#[derive(Debug, Error)]
63pub enum MessageBuilderError {
64    #[error("Invalid role")]
65    InvalidRole,
66}
67
68impl MessageBuilder {
69    pub fn new(role: impl Into<String>, content: impl Into<String>) -> Self {
70        Self {
71            role: role.into(),
72            content: content.into(),
73            partial: Some(false),
74            tool_calls: None,
75            tool_call_id: None,
76        }
77    }
78
79    pub fn role(&mut self, value: impl Into<String>) -> &mut Self {
80        self.role = value.into();
81        self
82    }
83    pub fn system(&mut self) -> &mut Self {
84        self.role("system")
85    }
86
87    pub fn user(&mut self) -> &mut Self {
88        self.role("user")
89    }
90    pub fn assistant(&mut self) -> &mut Self {
91        self.role("assistant")
92    }
93    pub fn tool(&mut self) -> &mut Self {
94        self.role("tool")
95    }
96
97    pub fn content(&mut self, value: impl Into<String>) -> &mut Self {
98        self.content = value.into();
99        self
100    }
101
102    pub fn partial(&mut self, value: bool) -> &mut Self {
103        self.partial = Some(value);
104        self
105    }
106
107    pub fn tool_call_id(&mut self, value: impl Into<String>) -> &mut Self {
108        self.tool_call_id = Some(value.into());
109        self
110    }
111
112    pub fn tool_calls(&mut self, value: Vec<ToolCall>) -> &mut Self {
113        self.tool_calls = Some(value);
114        self
115    }
116
117    pub fn build(&self) -> Result<Message, MessageBuilderError> {
118        match self.role.as_ref() {
119            "system" => Ok(Message::System(SystemMessage {
120                role: self.role.clone(),
121                content: self.clone().content,
122            })),
123            "user" => Ok(Message::User(UserMessage {
124                role: self.role.clone(),
125                content: self.clone().content,
126            })),
127            "assistant" => Ok(Message::Assistant(AssistantMessage {
128                role: self.role.clone(),
129                content: self.content.clone(),
130                partial: self.partial,
131                tool_calls: self.tool_calls.clone(),
132            })),
133            "tool" => Ok(Message::Tool(ToolMessage {
134                role: self.role.clone(),
135                content: self.content.clone(),
136                tool_call_id: self.tool_call_id.clone(),
137            })),
138            // 不可用的角色
139            _ => Err(MessageBuilderError::InvalidRole),
140        }
141    }
142}
143
144/// 模型的目标或角色。如果设置系统消息,请放在messages列表的第一位。
145#[derive(Debug, Clone, Builder, Serialize, Deserialize, PartialEq)]
146pub struct SystemMessage {
147    #[builder(setter(into), default = "\"system\".to_string()")]
148    pub role: String,
149    #[builder(setter(into))]
150    pub content: String,
151}
152
153impl From<SystemMessage> for Message {
154    fn from(value: SystemMessage) -> Self {
155        Self::System(value)
156    }
157}
158
159/// 用户发送给模型的消息
160#[derive(Debug, Clone, Builder, Serialize, Deserialize, PartialEq)]
161pub struct UserMessage {
162    #[builder(setter(into), default = "\"user\".to_string()")]
163    pub role: String,
164    #[builder(setter(into))]
165    pub content: String,
166}
167
168impl From<UserMessage> for Message {
169    fn from(value: UserMessage) -> Self {
170        Self::User(value)
171    }
172}
173
174/// 模型对用户消息的回复
175#[derive(Debug, Clone, Builder, Serialize, Deserialize, PartialEq)]
176pub struct AssistantMessage {
177    #[builder(setter(into), default = "\"assistant\".to_string()")]
178    pub role: String,
179    #[builder(setter(into))]
180    pub content: String,
181
182    /// 是否开启Partial Mode,参考: [前缀续写](https://help.aliyun.com/zh/model-studio/partial-mode)
183    #[builder(setter(into, strip_option))]
184    #[builder(default=Some(false))]
185    pub partial: Option<bool>,
186
187    /// 在发起 Function Calling后,模型回复的要调用的工具和调用工具时需要的参数。包含一个或多个对象。由上一轮模型响应的tool_calls字段获得。
188    #[builder(setter(into, strip_option))]
189    pub tool_calls: Option<Vec<ToolCall>>,
190}
191
192impl From<AssistantMessage> for Message {
193    fn from(value: AssistantMessage) -> Self {
194        Self::Assistant(value)
195    }
196}
197
198#[derive(Debug, Clone, Builder, Serialize, Deserialize, PartialEq)]
199pub struct ToolCall {
200    /// 本次工具响应的ID。
201    #[builder(setter(into))]
202    pub id: String,
203    /// 工具的类型,当前只支持function。
204    #[builder(setter(into))]
205    #[serde(rename = "type")]
206    pub type_: String,
207
208    /// 需要被调用的函数。
209    pub function: Function,
210
211    /// 工具信息在tool_calls列表中的索引。
212    pub index: i32,
213}
214
215#[derive(Debug, Clone, Builder, Serialize, Deserialize, PartialEq)]
216pub struct Function {
217    /// 需要被调用的函数名。
218    #[builder(setter(into))]
219    pub name: String,
220    /// 需要输入到工具中的参数,为JSON字符串。
221    #[builder(setter(into))]
222    pub arguments: String,
223}
224
225#[derive(Debug, Clone, Builder, Serialize, Deserialize, PartialEq)]
226pub struct ToolMessage {
227    #[builder(setter(into), default = "\"tool\".to_string()")]
228    pub role: String,
229    #[builder(setter(into))]
230    pub content: String,
231    #[builder(setter(into))]
232    pub tool_call_id: Option<String>,
233}
234
235impl From<ToolMessage> for Message {
236    fn from(value: ToolMessage) -> Self {
237        Self::Tool(value)
238    }
239}
240
241impl RequestTrait for GenerationParam {
242    type P = Parameters;
243    fn model(&self) -> &str {
244        &self.model
245    }
246
247    fn parameters(&self) -> Option<&Self::P> {
248        self.parameters.as_ref()
249    }
250}