use mirror::{
builder::{LLMBackend, LLMBuilder, FunctionBuilder, ParamBuilder},
chat::{ChatMessage, ChatRole, MessageType, StructuredOutputFormat}
};
use serde_json::Value;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let provider = LLMBuilder::default()
.backend(LLMBackend::Mistral)
.api_key(std::env::var("MISTRAL_API_KEY")?)
.model("mistral-small-latest") .temperature(0.7)
.max_tokens(1000)
.build()?;
println!("=== Simple Chat Example ===");
let messages = vec![
ChatMessage {
role: ChatRole::Assistant,
message_type: MessageType::Text,
content: "You are a helpful assistant.".to_string(),
},
ChatMessage {
role: ChatRole::User,
message_type: MessageType::Text,
content: "What is the capital of France?".to_string(),
},
];
let response = provider.chat(&messages).await?;
println!("Response: {}", response.text().unwrap_or_default());
println!("\n=== Streaming Chat Example ===");
let streaming_provider = LLMBuilder::default()
.backend(LLMBackend::Mistral)
.api_key(std::env::var("MISTRAL_API_KEY")?)
.model("mistral-small-latest")
.stream(true)
.build()?;
let messages = vec![ChatMessage {
role: ChatRole::User,
message_type: MessageType::Text,
content: "Tell me a short story about a robot.".to_string(),
}];
println!("Streaming response:");
let mut stream = streaming_provider.chat_stream(&messages).await?;
use futures::StreamExt;
while let Some(chunk) = stream.next().await {
match chunk {
Ok(response) => print!("{}", response),
Err(e) => eprintln!("Stream error: {}", e),
}
}
println!();
println!("\n=== Embeddings Example ===");
let embedding_provider = LLMBuilder::default()
.backend(LLMBackend::Mistral)
.api_key(std::env::var("MISTRAL_API_KEY")?)
.model("mistral-embed") .build()?;
let texts = vec![
"The quick brown fox jumps over the lazy dog.".to_string(),
"Machine learning is transforming technology.".to_string(),
];
let embeddings = embedding_provider.embed(texts).await?;
println!("Generated {} embeddings", embeddings.len());
println!("First embedding dimension: {}", embeddings[0].len());
println!("\n=== Available Models ===");
let models = provider.list_models(None).await?;
println!("Available Mistral models:");
for model_id in models.get_models() {
println!(" - {}", model_id);
}
println!("\n=== Function Calling Example ===");
let weather_function = FunctionBuilder::new("get_weather")
.description("Get the current weather for a location")
.param(
ParamBuilder::new("location")
.type_of("string")
.description("The city and state, e.g. San Francisco, CA")
)
.param(
ParamBuilder::new("unit")
.type_of("string")
.description("The temperature unit (celsius or fahrenheit)")
)
.required(vec!["location".to_string()]);
let tool_provider = LLMBuilder::default()
.backend(LLMBackend::Mistral)
.api_key(std::env::var("MISTRAL_API_KEY")?)
.model("mistral-large-latest") .function(weather_function)
.build()?;
let messages = vec![ChatMessage {
role: ChatRole::User,
message_type: MessageType::Text,
content: "What's the weather like in Paris, France?".to_string(),
}];
let response = tool_provider.chat(&messages).await?;
println!("Response: {}", response.text().unwrap_or_default());
if let Some(tool_calls) = response.tool_calls() {
println!("Tool calls requested:");
for tool_call in tool_calls {
println!(" - Function: {}", tool_call.function.name);
println!(" Arguments: {}", tool_call.function.arguments);
}
}
println!("\n=== Structured Output Example ===");
let schema_json = r#"{
"name": "Recipe",
"description": "A cooking recipe",
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of the recipe"
},
"ingredients": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": { "type": "string" },
"amount": { "type": "string" }
},
"required": ["name", "amount"]
}
},
"instructions": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["name", "ingredients", "instructions"]
}
}"#;
let schema: StructuredOutputFormat = serde_json::from_str(schema_json)?;
let structured_provider = LLMBuilder::default()
.backend(LLMBackend::Mistral)
.api_key(std::env::var("MISTRAL_API_KEY")?)
.model("mistral-large-latest")
.schema(schema)
.build()?;
let messages = vec![ChatMessage {
role: ChatRole::User,
message_type: MessageType::Text,
content: "Give me a simple recipe for chocolate chip cookies.".to_string(),
}];
println!("Generating structured recipe response...");
let response = structured_provider.chat(&messages).await?;
let response_text = response.text().unwrap_or_default();
let recipe: Value = serde_json::from_str(&response_text)?;
println!("Recipe JSON:");
println!("{}", serde_json::to_string_pretty(&recipe)?);
Ok(())
}