mod private
{
pub trait AsCurl
{
fn as_curl( &self ) -> String;
fn as_curl_with_options( &self, options : &CurlOptions ) -> String;
}
use crate::components::inference_shared::ChatCompletionRequest;
#[ derive( Debug, Clone ) ]
pub struct CurlOptions
{
pub pretty_json : bool,
pub include_auth_header : bool,
pub multiline_format : bool,
pub api_key : Option< String >,
}
impl CurlOptions
{
#[ inline ]
#[ must_use ]
pub fn new() -> Self
{
Self
{
pretty_json : false,
include_auth_header : true,
multiline_format : false,
api_key : None,
}
}
#[ inline ]
#[ must_use ]
pub fn pretty() -> Self
{
Self
{
pretty_json : true,
include_auth_header : true,
multiline_format : true,
api_key : None,
}
}
#[ inline ]
pub fn with_api_key< S : Into< String > >( api_key : S ) -> Self
{
Self
{
pretty_json : false,
include_auth_header : true,
multiline_format : false,
api_key : Some( api_key.into() ),
}
}
#[ inline ]
#[ must_use ]
pub fn pretty_json( mut self ) -> Self
{
self.pretty_json = true;
self
}
#[ inline ]
#[ must_use ]
pub fn multiline( mut self ) -> Self
{
self.multiline_format = true;
self
}
}
impl Default for CurlOptions
{
#[ inline ]
fn default() -> Self
{
Self::new()
}
}
mod curl_helpers
{
use super::*;
pub fn generate_curl_command(
url : &str,
json_body : &str,
options : &CurlOptions,
) -> String
{
let formatted_json = if options.pretty_json
{
match serde_json::from_str::< serde_json::Value >( json_body )
{
Ok( value ) => serde_json::to_string_pretty( &value )
.unwrap_or_else( |_| json_body.to_string() ),
Err( _ ) => json_body.to_string(),
}
}
else
{
json_body.to_string()
};
let auth_header = if let Some( ref api_key ) = options.api_key
{
format!( "Authorization : Bearer {api_key}" )
}
else if options.include_auth_header
{
"Authorization : Bearer YOUR_API_KEY_HERE".to_string()
}
else
{
String::new()
};
if options.multiline_format
{
let json_escaped = formatted_json.replace( '"', "\\\"" );
if options.include_auth_header || options.api_key.is_some()
{
format!(
"curl -X POST \\\n \"{url}\" \\\n -H \"{auth_header}\" \\\n -H \"Content-Type : application/json\" \\\n -d \"{json_escaped}\""
)
}
else
{
format!(
"curl -X POST \\\n \"{url}\" \\\n -H \"Content-Type : application/json\" \\\n -d \"{json_escaped}\""
)
}
}
else
{
let json_escaped = formatted_json.replace( '\'', "'\"'\"'" );
if options.include_auth_header || options.api_key.is_some()
{
format!(
"curl -X POST \"{url}\" -H \"{auth_header}\" -H \"Content-Type : application/json\" -d '{json_escaped}'"
)
}
else
{
format!(
"curl -X POST \"{url}\" -H \"Content-Type : application/json\" -d '{json_escaped}'"
)
}
}
}
pub fn safe_json_serialize< T : serde::Serialize >( value : &T ) -> String
{
serde_json::to_string( value ).unwrap_or_else( |err| {
format!( "{{\"error\": \"Failed to serialize request : {err}\"}}" )
})
}
}
impl AsCurl for ChatCompletionRequest
{
#[ inline ]
fn as_curl( &self ) -> String
{
self.as_curl_with_options( &CurlOptions::default() )
}
#[ inline ]
fn as_curl_with_options( &self, options : &CurlOptions ) -> String
{
let url = "https://router.huggingface.co/v1/chat/completions";
let json_body = curl_helpers::safe_json_serialize( self );
curl_helpers::generate_curl_command( url, &json_body, options )
}
}
pub mod debug_helpers
{
use super::*;
use crate::components::inference_shared::ChatMessage;
#[ inline ]
#[ must_use ]
pub fn simple_chat_curl( message : &str, options : Option< &CurlOptions > ) -> String
{
let request = ChatCompletionRequest
{
messages : vec![ ChatMessage
{
role : "user".to_string(),
content : message.to_string(),
tool_calls : None,
tool_call_id : None,
} ],
model : "moonshotai/Kimi-K2-Instruct-0905:groq".to_string(),
temperature : Some( 0.7 ),
max_tokens : Some( 150 ),
top_p : Some( 0.9 ),
stream : Some( false ),
tools : None,
tool_choice : None,
};
match options
{
Some( opts ) => request.as_curl_with_options( opts ),
None => request.as_curl(),
}
}
#[ inline ]
#[ must_use ]
pub fn chat_with_system_curl(
system_message : &str,
user_message : &str,
options : Option< &CurlOptions >
) -> String
{
let request = ChatCompletionRequest
{
messages : vec![
ChatMessage
{
role : "system".to_string(),
content : system_message.to_string(),
tool_calls : None,
tool_call_id : None,
},
ChatMessage
{
role : "user".to_string(),
content : user_message.to_string(),
tool_calls : None,
tool_call_id : None,
}
],
model : "moonshotai/Kimi-K2-Instruct-0905:groq".to_string(),
temperature : Some( 0.7 ),
max_tokens : Some( 150 ),
top_p : Some( 0.9 ),
stream : Some( false ),
tools : None,
tool_choice : None,
};
match options
{
Some( opts ) => request.as_curl_with_options( opts ),
None => request.as_curl(),
}
}
}
}
crate::mod_interface!
{
exposed use private::
{
AsCurl,
CurlOptions,
debug_helpers,
};
}