1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
mod private
{
use crate::error::Result;
use crate::environment::XaiEnvironment;
use crate::client::Client;
use crate::components::chat::{ ChatCompletionRequest, ChatCompletionResponse };
#[ cfg( feature = "streaming" ) ]
use crate::components::chat::ChatCompletionChunk;
#[ cfg( feature = "streaming" ) ]
use futures_core::Stream;
#[ cfg( feature = "streaming" ) ]
use std::pin::Pin;
/// Chat completions API accessor.
///
/// Provides methods for creating chat completions using the XAI API.
///
/// # Examples
///
/// ```no_run
/// use api_xai::{ Client, XaiEnvironmentImpl, Secret, ChatCompletionRequest, Message, ClientApiAccessors };
///
/// # async fn example() -> Result< (), Box< dyn std::error::Error > > {
/// let secret = Secret::load_with_fallbacks( "XAI_API_KEY" )?;
/// let env = XaiEnvironmentImpl::new( secret )?;
/// let client = Client::build( env )?;
///
/// let request = ChatCompletionRequest::former()
/// .model( "grok-2-1212".to_string() )
/// .messages( vec![ Message::user( "Hello!" ) ] )
/// .form();
///
/// let response = client.chat().create( request ).await?;
/// println!( "Response : {:?}", response.choices[ 0 ].message.content );
/// # Ok( () )
/// # }
/// ```
#[ derive( Debug ) ]
pub struct Chat< 'a, E >
where
E : XaiEnvironment + Send + Sync + 'static,
{
client : &'a Client< E >,
}
impl< 'a, E > Chat< 'a, E >
where
E : XaiEnvironment + Send + Sync + 'static,
{
/// Creates a new Chat API accessor.
///
/// Typically not called directly - use `client.chat()` instead.
///
/// # Arguments
///
/// * `client` - Reference to the client
pub fn new( client : &'a Client< E > ) -> Self
{
Self { client }
}
/// Creates a chat completion.
///
/// Sends a conversation to the model and receives a completion.
///
/// # Arguments
///
/// * `request` - Chat completion request with model and messages
///
/// # Errors
///
/// Returns errors for network failures, API errors, or invalid requests.
///
/// # Examples
///
/// ```no_run
/// # use api_xai::{ Client, XaiEnvironmentImpl, Secret, ChatCompletionRequest, Message, ClientApiAccessors };
/// # async fn example() -> Result< (), Box< dyn std::error::Error > > {
/// # let secret = Secret::load_with_fallbacks( "XAI_API_KEY" )?;
/// # let env = XaiEnvironmentImpl::new( secret )?;
/// # let client = Client::build( env )?;
/// let request = ChatCompletionRequest::former()
/// .model( "grok-2-1212".to_string() )
/// .messages( vec![
/// Message::system( "You are a helpful assistant" ),
/// Message::user( "What is 2 + 2?" ),
/// ] )
/// .temperature( 0.7 )
/// .max_tokens( 100u32 )
/// .form();
///
/// let response = client.chat().create( request ).await?;
///
/// for choice in response.choices {
/// if let Some( content ) = choice.message.content {
/// println!( "Assistant : {}", content );
/// }
/// }
/// # Ok( () )
/// # }
/// ```
pub async fn create(
&self,
request : ChatCompletionRequest
) -> Result< ChatCompletionResponse >
{
self.client.post( "chat/completions", &request ).await
}
/// Creates a streaming chat completion.
///
/// Returns a stream of completion chunks via Server-Sent Events (SSE).
/// The request is automatically modified to enable streaming.
///
/// # Feature Gate
///
/// This method requires the `streaming` feature to be enabled.
///
/// # Arguments
///
/// * `request` - Chat completion request (stream flag is set automatically)
///
/// # Returns
///
/// A pinned stream of `Result< ChatCompletionChunk >` events.
///
/// # Errors
///
/// Returns errors for network failures, API errors, or SSE parsing failures.
///
/// # Examples
///
/// ```no_run
/// # #[ cfg( feature = "streaming" ) ]
/// # {
/// use api_xai::{ Client, XaiEnvironmentImpl, Secret, ChatCompletionRequest, Message, ClientApiAccessors };
/// use futures_util::StreamExt;
///
/// # async fn example() -> Result< (), Box< dyn std::error::Error > > {
/// # let secret = Secret::load_with_fallbacks( "XAI_API_KEY" )?;
/// # let env = XaiEnvironmentImpl::new( secret )?;
/// # let client = Client::build( env )?;
/// let request = ChatCompletionRequest::former()
/// .model( "grok-2-1212".to_string() )
/// .messages( vec![ Message::user( "Count to 5" ) ] )
/// .form();
///
/// let chat = client.chat();
/// let mut stream = chat.create_stream( request ).await?;
///
/// while let Some( chunk_result ) = stream.next().await {
/// let chunk = chunk_result?;
/// if let Some( delta ) = chunk.choices.first().map( |c| &c.delta ) {
/// if let Some( content ) = &delta.content {
/// print!( "{}", content );
/// }
/// }
/// }
/// # Ok( () )
/// # }
/// # }
/// ```
#[ cfg( feature = "streaming" ) ]
pub async fn create_stream(
&self,
mut request : ChatCompletionRequest
) -> Result< Pin< Box< dyn Stream< Item = Result< ChatCompletionChunk > > + Send + 'static > > >
{
// Enable streaming
request.stream = Some( true );
self.client.post_stream( "chat/completions", &request ).await
}
}
}
crate::mod_interface!
{
exposed use
{
Chat,
};
}