Skip to main content

basic_usage/
basic_usage.rs

1use orchestra_rs::{
2    error::Result, llm::LLM, messages::Message, model::ModelConfig,
3    providers::types::ProviderSource,
4};
5
6/// This example demonstrates basic usage of Orchestra-rs (single crate) with the Gemini provider.
7///
8/// To run this example:
9/// 1. Set your Gemini API key: export GEMINI_API_KEY="your-api-key-here"
10/// 2. Run: cargo run --example basic_usage
11#[tokio::main]
12async fn main() -> Result<()> {
13    // Initialize logging (optional)
14    env_logger::init();
15
16    println!("šŸŽ¼ Orchestra-rs Basic Usage Example\n");
17
18    // Example 1: Simple prompt
19    simple_prompt().await?;
20
21    // Example 2: Chat with history
22    chat_with_history().await?;
23
24    // Example 3: Custom configuration
25    custom_configuration().await?;
26
27    // Example 4: Using presets
28    using_presets().await?;
29
30    println!("\nāœ… All examples completed successfully!");
31    Ok(())
32}
33
34/// Example 1: Simple prompt
35async fn simple_prompt() -> Result<()> {
36    println!("šŸ“ Example 1: Simple Prompt");
37    println!("===============================================================================");
38
39    // Create an LLM instance with Gemini
40    let llm = LLM::gemini("gemini-2.5-flash");
41
42    // Send a simple prompt.
43    let response = llm
44        .prompt("Hello! Can you tell me a fun fact about Rust programming language?")
45        .await?;
46
47    println!("šŸ¤– Response: {}\n", response.text);
48    Ok(())
49}
50
51/// Example 2: Chat with conversation history
52async fn chat_with_history() -> Result<()> {
53    println!("šŸ’¬ Example 2: Chat with History");
54    println!("===============================================================================");
55
56    let llm = LLM::gemini("gemini-2.5-flash");
57
58    // Build conversation history
59    let history = vec![
60        Message::human("Hi! I'm learning Rust and I'm confused about ownership."),
61        Message::assistant(
62            "Hello! I'd be happy to help you understand Rust ownership. It's one of Rust's most important concepts. What specific aspect of ownership would you like me to explain?",
63        ),
64        Message::human("What's the difference between moving and borrowing?"),
65        Message::assistant(
66            "Great question! Moving transfers ownership of a value, while borrowing allows temporary access without taking ownership. When you move a value, the original variable can no longer be used. When you borrow, you get a reference that allows you to use the value without owning it.",
67        ),
68    ];
69
70    // Continue the conversation
71    let response = llm
72        .chat(
73            Message::human("Can you give me a simple code example of both?"),
74            history,
75        )
76        .await?;
77
78    println!("šŸ¤– Response: {}\n", response.text);
79    Ok(())
80}
81
82/// Example 3: Custom configuration
83async fn custom_configuration() -> Result<()> {
84    println!("āš™ļø  Example 3: Custom Configuration");
85    println!("===============================================================================");
86
87    // Create a custom model configuration
88    let config = ModelConfig::new("gemini-2.5-flash")
89        .with_system_instruction("You are a helpful Rust programming tutor. Always provide practical examples and explain concepts clearly.")
90        .with_temperature(0.7)?
91        .with_top_p(0.9)?;
92
93    // Create LLM with custom configuration
94    let llm =
95        LLM::new(ProviderSource::Gemini, "gemini-2.5-flash".to_string()).with_custom_config(config);
96
97    let response = llm
98        .prompt("Explain Rust's Result type and how to use it")
99        .await?;
100    println!("šŸ¤– Response: {}\n", response.text);
101    Ok(())
102}
103
104/// Example 4: Using configuration presets
105async fn using_presets() -> Result<()> {
106    println!("šŸŽÆ Example 4: Using Presets");
107    println!("===============================================================================");
108
109    // Conservative settings (lower temperature, more focused)
110    println!("šŸ”’ Conservative preset (focused, deterministic):");
111    let conservative_llm =
112        LLM::conservative(ProviderSource::Gemini, "gemini-2.5-flash".to_string());
113    let conservative_response = conservative_llm
114        .prompt("Write a one-sentence summary of what Rust is.")
115        .await?;
116    println!("Response: {}\n", conservative_response.text);
117
118    // Creative settings (higher temperature, more diverse)
119    println!("šŸŽØ Creative preset (diverse, imaginative):");
120    let creative_llm = LLM::creative(ProviderSource::Gemini, "gemini-2.5-flash".to_string());
121    let creative_response = creative_llm
122        .prompt("Write a creative analogy to explain Rust's ownership system.")
123        .await?;
124    println!("Response: {}\n", creative_response.text);
125
126    // Balanced settings (moderate temperature)
127    println!("āš–ļø  Balanced preset (moderate creativity):");
128    let balanced_llm = LLM::balanced(ProviderSource::Gemini, "gemini-2.5-flash".to_string());
129    let balanced_response = balanced_llm
130        .prompt("Explain the benefits of using Rust for systems programming.")
131        .await?;
132    println!("Response: {}\n", balanced_response.text);
133
134    Ok(())
135}
136
137/// Helper function to demonstrate provider capabilities
138#[allow(dead_code)]
139async fn provider_capabilities() -> Result<()> {
140    println!("šŸ” Provider Capabilities");
141    println!("===============================================================================");
142
143    let llm = LLM::gemini("gemini-2.5-flash");
144
145    println!("Provider name: {}", llm.provider_name());
146    println!("Supports streaming: {}", llm.supports_streaming());
147    println!("Supports tools: {}", llm.supports_tools());
148    println!("Model name: {}", llm.get_model_name());
149
150    Ok(())
151}