just-deepseek 0.2.0

DeepSeek API client and wire-level types
Documentation
//! Streaming chat completion via [`DeepSeekClient`].
//!
//! ```bash
//! JUST_LLM_DEEPSEEK_API_KEY=your-key JUST_LLM_DEEPSEEK_MODEL=deepseek-chat \
//!   cargo run -p just-deepseek --example streaming_chat_completion
//! ```

use futures_util::StreamExt;
use just_deepseek::types::chat::{ChatCompletionRequest, ChatMessage, StreamOptions};
use just_deepseek::{DeepSeekClient, Error};

#[tokio::main]
async fn main() -> Result<(), Error> {
    dotenvy::dotenv().ok();

    let api_key =
        std::env::var("JUST_LLM_DEEPSEEK_API_KEY").expect("JUST_LLM_DEEPSEEK_API_KEY must be set");
    let base_url = std::env::var("JUST_LLM_DEEPSEEK_BASE_URL").ok();
    let model =
        std::env::var("JUST_LLM_DEEPSEEK_MODEL").expect("JUST_LLM_DEEPSEEK_MODEL must be set");
    let prompt = "Explain Rust ownership in two sentences.";

    let mut builder = DeepSeekClient::builder().api_key(&api_key);
    if let Some(url) = base_url {
        builder = builder.base_url(&url);
    }
    let client = builder.build()?;

    let mut request = ChatCompletionRequest::new(
        model,
        vec![
            ChatMessage::system("You are a concise assistant."),
            ChatMessage::user(prompt),
        ],
    );
    request.stream_options = Some(StreamOptions {
        include_usage: Some(true),
    });

    println!("--- request ---");
    println!("  [system] You are a concise assistant.");
    println!("  [user] {prompt}");

    // stream_chat_completion forces stream=true internally.
    let mut stream = client.stream_chat_completion(request).await?;

    println!("\n--- response (streaming) ---");
    while let Some(result) = stream.next().await {
        let chunk = result?;
        for choice in &chunk.choices {
            if let Some(reasoning) = &choice.delta.reasoning_content {
                print!("{reasoning}");
            }
            if let Some(content) = &choice.delta.content {
                print!("{content}");
            }
        }
        if let Some(usage) = &chunk.usage {
            println!(
                "\n  [usage] prompt={} completion={} total={}",
                usage.prompt_tokens, usage.completion_tokens, usage.total_tokens
            );
        }
    }
    println!();

    Ok(())
}