ai_lib/types/
request.rs

1use crate::types::Message;
2use crate::types::{FunctionCallPolicy, Tool};
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct ChatCompletionRequest {
7    pub model: String,
8    pub messages: Vec<Message>,
9    pub temperature: Option<f32>,
10    pub max_tokens: Option<u32>,
11    pub stream: Option<bool>,
12    pub top_p: Option<f32>,
13    pub frequency_penalty: Option<f32>,
14    pub presence_penalty: Option<f32>,
15    /// Optional function/tool definitions for Function Calling
16    pub functions: Option<Vec<Tool>>,
17    /// Function call policy: "auto"/"none"/specific name
18    pub function_call: Option<FunctionCallPolicy>,
19}
20
21impl ChatCompletionRequest {
22    pub fn new(model: String, messages: Vec<Message>) -> Self {
23        Self {
24            model,
25            messages,
26            temperature: None,
27            max_tokens: None,
28            stream: None,
29            top_p: None,
30            frequency_penalty: None,
31            presence_penalty: None,
32            functions: None,
33            function_call: None,
34        }
35    }
36
37    pub fn with_temperature(mut self, temperature: f32) -> Self {
38        self.temperature = Some(temperature);
39        self
40    }
41
42    pub fn with_max_tokens(mut self, max_tokens: u32) -> Self {
43        self.max_tokens = Some(max_tokens);
44        self
45    }
46
47    pub fn with_functions(mut self, functions: Vec<Tool>) -> Self {
48        self.functions = Some(functions);
49        self
50    }
51
52    pub fn with_function_call(mut self, function_call: FunctionCallPolicy) -> Self {
53        self.function_call = Some(function_call);
54        self
55    }
56
57    pub fn with_provider_specific(self, _key: &str, _value: serde_json::Value) -> Self {
58        // This needs to add provider_specific field to ChatCompletionRequest
59        // For now, just return self, actual implementation requires modifying the struct
60        self
61    }
62
63    /// Drop previous conversational messages while keeping system messages and the last non-system message.
64    /// Useful to reset context while preserving system instructions.
65    pub fn ignore_previous(mut self) -> Self {
66        use crate::types::Role;
67        let mut new_msgs: Vec<Message> = self
68            .messages
69            .iter()
70            .filter(|m| matches!(m.role, Role::System))
71            .cloned()
72            .collect();
73        if let Some(last) = self
74            .messages
75            .iter()
76            .rev()
77            .find(|m| !matches!(m.role, Role::System))
78        {
79            new_msgs.push(last.clone());
80        }
81        self.messages = new_msgs;
82        self
83    }
84}