grok_api 0.1.6

Rust client library for the Grok AI API (xAI)
Documentation
//! Conversation example — multi-turn chat with message history.
//!
//! Shows how to maintain context across turns and inspect token usage,
//! including cached prompt tokens (reduces cost on repeated prompts).
//!
//! Run with:
//!   cargo run --example conversation

use grok_api::{ChatMessage, GrokClient, Result};

const MODEL: &str = "grok-4-1-fast-reasoning";

#[tokio::main]
async fn main() -> Result<()> {
    tracing_subscriber::fmt::init();

    let api_key = std::env::var("GROK_API_KEY").expect("GROK_API_KEY environment variable not set");

    let client = GrokClient::new(&api_key)?;

    println!("🤖 Grok API — Multi-Turn Conversation\n");
    println!("Model: {MODEL}\n");

    let mut messages = vec![
        ChatMessage::system(
            "You are a concise Rust programming assistant. \
             Keep answers short and include a code snippet where relevant.",
        ),
        ChatMessage::user("What is ownership in Rust?"),
    ];

    // ── Turn 1 ────────────────────────────────────────────────────────────────
    println!("👤 User: {}\n", messages[1].content.as_ref().unwrap());

    let response = client
        .chat_with_history(&messages)
        .model(MODEL)
        .max_tokens(400)
        .send()
        .await?;

    let reply = response.content().unwrap_or("").to_string();
    println!("🤖 Grok:\n{}\n", reply);
    print_usage(&response.usage);

    messages.push(ChatMessage::assistant(&*reply));

    // ── Turn 2 ────────────────────────────────────────────────────────────────
    let q2 = "How does the borrow checker enforce ownership?";
    messages.push(ChatMessage::user(q2));
    println!("👤 User: {q2}\n");

    let response = client
        .chat_with_history(&messages)
        .model(MODEL)
        .max_tokens(400)
        .send()
        .await?;

    let reply = response.content().unwrap_or("").to_string();
    println!("🤖 Grok:\n{}\n", reply);
    print_usage(&response.usage);

    messages.push(ChatMessage::assistant(&*reply));

    // ── Turn 3 ────────────────────────────────────────────────────────────────
    let q3 = "Show me a compile error caused by a borrow violation and how to fix it.";
    messages.push(ChatMessage::user(q3));
    println!("👤 User: {q3}\n");

    let response = client
        .chat_with_history(&messages)
        .model(MODEL)
        .max_tokens(600)
        .send()
        .await?;

    let reply = response.content().unwrap_or("").to_string();
    println!("🤖 Grok:\n{}\n", reply);
    print_usage(&response.usage);

    println!(
        "✨ Conversation complete — {} messages exchanged.",
        messages.len() + 1
    );

    Ok(())
}

fn print_usage(usage: &grok_api::Usage) {
    print!(
        "   📊 tokens — prompt: {}, completion: {}, total: {}",
        usage.prompt_tokens, usage.completion_tokens, usage.total_tokens
    );
    if let Some(cached) = usage.cached_prompt_tokens {
        print!(", cached: {cached} 💰");
    }
    if let Some(reasoning) = usage.reasoning_tokens {
        print!(", reasoning: {reasoning} 🧠");
    }
    println!();
}