use langfuse::{Langfuse, LangfuseConfig, observe, with_generation, with_span};
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let config = LangfuseConfig::from_env()?;
let langfuse = Langfuse::new(config)?;
println!("=== Example 1: Manual span creation ===");
example_manual_span(&langfuse).await;
println!("\n=== Example 2: Closure-based API ===");
example_closure_api().await;
println!("\n=== Example 3: Decorated function ===");
example_decorated_function().await;
println!("\nAll examples completed successfully!");
Ok(())
}
async fn example_manual_span(_langfuse: &Langfuse) {
let span = langfuse::LangfuseSpan::start("my-pipeline");
span.set_input(&json!({"query": "What is Rust?"}));
span.set_trace_user_id("user-123");
span.set_trace_session_id("session-456");
span.set_metadata(&json!({"environment": "example"}));
let r#gen = span.start_generation("llm-call");
r#gen.set_model("gpt-4o");
r#gen.set_input(&json!({
"messages": [
{"role": "user", "content": "What is Rust?"}
]
}));
r#gen.set_output(&json!({
"content": "Rust is a systems programming language focused on safety, speed, and concurrency."
}));
r#gen.set_usage(&langfuse::UsageDetails {
input: Some(15),
output: Some(50),
total: Some(65),
});
r#gen.end();
span.set_output(&json!({
"answer": "Rust is a systems programming language focused on safety, speed, and concurrency."
}));
span.end();
println!("Manual span created with trace_id: {}", span.trace_id());
}
async fn example_closure_api() {
let result = with_span("closure-example", |span| async move {
span.set_input(&json!({"input": "hello"}));
let answer = with_generation("nested-gen", |r#gen| async move {
r#gen.set_model("gpt-4o-mini");
r#gen.set_input(&json!({"prompt": "Say hello"}));
"Hello, world!"
})
.await;
span.set_output(&json!({"result": answer}));
answer
})
.await;
println!("Closure-based result: {}", result);
}
#[observe(as_type = "generation", name = "process-request")]
async fn example_decorated_function() {
let query = "What is Rust?";
let answer = process_request(query).await;
println!("Decorated function result: {}", answer);
}
#[observe(as_type = "generation", name = "llm-call")]
async fn process_request(query: &str) -> String {
format!("Answer to: {}", query)
}