Skip to main content

ds_api/api/
request.rs

1//! ApiRequest builder module.
2//!
3//! Provides a safe, chainable request builder that wraps the internal
4//! `crate::raw::ChatCompletionRequest`.
5
6use crate::raw::{ChatCompletionRequest, Message, ResponseFormat, ResponseFormatType, Tool};
7
8/// A safe, chainable request builder that wraps `ChatCompletionRequest`.
9///
10/// It intentionally avoids exposing raw configuration enums (like `Model`) to
11/// callers. Use the provided helpers to pick models.
12#[derive(Debug)]
13pub struct ApiRequest {
14    raw: ChatCompletionRequest,
15}
16
17impl ApiRequest {
18    /// Start a new builder with default values.
19    pub fn builder() -> Self {
20        Self {
21            raw: ChatCompletionRequest::default(),
22        }
23    }
24
25    pub fn model(mut self, model: crate::raw::Model) -> Self {
26        self.raw.model = model;
27        self
28    }
29
30    /// Convenience constructor: deepseek-chat + messages
31    pub fn deepseek_chat(messages: Vec<Message>) -> Self {
32        let mut r = Self::builder();
33        r.raw.messages = messages;
34        r.raw.model = crate::raw::Model::DeepseekChat;
35        r
36    }
37
38    /// Convenience constructor: deepseek-reasoner + messages
39    pub fn deepseek_reasoner(messages: Vec<Message>) -> Self {
40        let mut r = Self::builder();
41        r.raw.messages = messages;
42        r.raw.model = crate::raw::Model::DeepseekReasoner;
43        r
44    }
45
46    /// Add a message to the request.
47    pub fn add_message(mut self, msg: Message) -> Self {
48        self.raw.messages.push(msg);
49        self
50    }
51
52    /// Replace messages.
53    pub fn messages(mut self, msgs: Vec<Message>) -> Self {
54        self.raw.messages = msgs;
55        self
56    }
57
58    /// Request response as JSON object.
59    pub fn json(mut self) -> Self {
60        self.raw.response_format = Some(ResponseFormat {
61            r#type: ResponseFormatType::JsonObject,
62        });
63        self
64    }
65
66    /// Request response as plain text.
67    pub fn text(mut self) -> Self {
68        self.raw.response_format = Some(ResponseFormat {
69            r#type: ResponseFormatType::Text,
70        });
71        self
72    }
73
74    /// Set temperature.
75    pub fn temperature(mut self, t: f32) -> Self {
76        self.raw.temperature = Some(t);
77        self
78    }
79
80    /// Set max tokens.
81    pub fn max_tokens(mut self, n: u32) -> Self {
82        self.raw.max_tokens = Some(n);
83        self
84    }
85
86    /// Add a raw tool definition (from `crate::raw::Tool`).
87    pub fn add_tool(mut self, tool: Tool) -> Self {
88        if let Some(ref mut v) = self.raw.tools {
89            v.push(tool);
90        } else {
91            self.raw.tools = Some(vec![tool]);
92        }
93        self
94    }
95
96    /// Set tool choice to Auto.
97    pub fn tool_choice_auto(mut self) -> Self {
98        use crate::raw::request::tool_choice::{ToolChoice, ToolChoiceType};
99        self.raw.tool_choice = Some(ToolChoice::String(ToolChoiceType::Auto));
100        self
101    }
102
103    /// Enable/disable streaming (stream: true).
104    pub fn stream(mut self, enabled: bool) -> Self {
105        self.raw.stream = Some(enabled);
106        self
107    }
108
109    /// Build and return the internal raw request (crate-internal use).
110    pub(crate) fn into_raw(self) -> ChatCompletionRequest {
111        self.raw
112    }
113}