1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4#[derive(Debug, Serialize, Deserialize, Clone)]
5pub struct Message {
6 pub role: String,
7 #[serde(skip_serializing_if = "Option::is_none")]
8 pub content: Option<String>,
9 #[serde(skip_serializing_if = "Option::is_none")]
10 pub reasoning_content: Option<String>,
11 #[serde(skip_serializing_if = "Option::is_none")]
12 pub tool_calls: Option<Vec<ToolCall>>,
13 #[serde(skip_serializing_if = "Option::is_none")]
14 pub tool_call_id: Option<String>,
15}
16
17#[derive(Debug, Serialize, Deserialize, Clone)]
18pub struct ToolCall {
19 pub id: String,
20 pub r#type: String,
21 pub function: FunctionCall,
22}
23
24#[derive(Debug, Serialize, Deserialize, Clone)]
25pub struct FunctionCall {
26 pub name: String,
27 pub arguments: String,
28}
29
30#[derive(Debug, Serialize, Deserialize, Clone)]
31pub struct ThinkingConfig {
32 pub r#type: String,
33}
34
35#[derive(Debug, Serialize, Deserialize, Clone)]
36pub struct ResponseFormat {
37 pub r#type: String,
38}
39
40#[derive(Debug, Serialize, Deserialize, Clone)]
41pub struct ChatRequest {
42 pub model: String,
43 pub messages: Vec<Message>,
44 pub stream: bool,
45 #[serde(skip_serializing_if = "Option::is_none")]
46 pub tools: Option<Vec<Tool>>,
47 #[serde(skip_serializing_if = "Option::is_none")]
48 pub tool_choice: Option<String>,
49 pub temperature: f32,
50 pub top_p: f32,
51 pub presence_penalty: f32,
52 pub frequency_penalty: f32,
53 #[serde(skip_serializing_if = "Option::is_none")]
54 pub max_tokens: Option<u32>,
55 #[serde(skip_serializing_if = "Option::is_none")]
56 pub thinking: Option<ThinkingConfig>,
57 #[serde(skip_serializing_if = "Option::is_none")]
58 pub reasoning_effort: Option<String>,
59 #[serde(skip_serializing_if = "Option::is_none")]
60 pub response_format: Option<ResponseFormat>,
61 #[serde(skip_serializing_if = "Option::is_none")]
62 pub stop: Option<Vec<String>>,
63}
64
65#[derive(Debug, Serialize, Deserialize, Clone)]
66pub struct Tool {
67 pub r#type: String,
68 pub function: FunctionDefinition,
69}
70
71#[derive(Debug, Serialize, Deserialize, Clone)]
72pub struct FunctionDefinition {
73 pub name: String,
74 pub description: String,
75 pub parameters: Value,
76}
77
78#[derive(Debug, Deserialize)]
79pub struct ChatResponseChunk {
80 pub choices: Vec<ChatChoiceChunk>,
81 pub usage: Option<TokenUsage>,
82}
83
84#[derive(Debug, Deserialize)]
85pub struct ChatChoiceChunk {
86 pub delta: DeltaMessage,
87 #[allow(dead_code)]
88 pub finish_reason: Option<String>,
89}
90
91#[derive(Debug, Deserialize)]
92pub struct DeltaMessage {
93 pub content: Option<String>,
94 pub reasoning_content: Option<String>,
95 pub tool_calls: Option<Vec<DeltaToolCall>>,
96}
97
98#[derive(Debug, Deserialize)]
99pub struct DeltaToolCall {
100 pub index: usize,
101 pub id: Option<String>,
102 pub function: Option<DeltaFunctionCall>,
103}
104
105#[derive(Debug, Deserialize)]
106pub struct DeltaFunctionCall {
107 pub name: Option<String>,
108 pub arguments: Option<String>,
109}
110
111#[derive(Debug, Clone)]
112pub struct ChatOptions {
113 pub temperature: f32,
114 pub top_p: f32,
115 pub presence_penalty: f32,
116 pub frequency_penalty: f32,
117 pub max_tokens: Option<u32>,
118 pub thinking_enabled: bool,
119 pub reasoning_effort: Option<String>,
120 pub json_mode: bool,
121}
122
123impl Default for ChatOptions {
124 fn default() -> Self {
125 Self {
126 temperature: 0.0,
127 top_p: 1.0,
128 presence_penalty: 0.0,
129 frequency_penalty: 0.0,
130 max_tokens: Some(16_384),
131 thinking_enabled: true,
132 reasoning_effort: Some("high".to_string()),
133 json_mode: false,
134 }
135 }
136}
137
138#[derive(Debug, Deserialize, Clone, Default)]
139pub struct TokenUsage {
140 pub prompt_tokens: u64,
141 pub completion_tokens: u64,
142 #[serde(default)]
143 pub prompt_cache_hit_tokens: u64,
144 #[serde(default)]
145 pub prompt_cache_miss_tokens: u64,
146}