The Rust SDK is currently in alpha. The API is stable, but some features and interfaces may change based on user feedback.
Basic Usage
Copy
use valyu::ValyuClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = ValyuClient::new("your-api-key");
// Simple answer with defaults
let response = client.ask("What are the latest developments in quantum computing?").await?;
if response.success {
if let Some(contents) = &response.contents {
println!("Answer: {}", contents);
}
if let Some(metadata) = &response.search_metadata {
println!("Sources used: {:?}", metadata);
}
}
Ok(())
}
Advanced Usage with Builder Pattern
UseAnswerRequest for full control over answer generation:
Copy
use valyu::{ValyuClient, AnswerRequest};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = ValyuClient::new("your-api-key");
let request = AnswerRequest::new("What are the latest developments in quantum computing?")
.with_search_type("web")
.with_system_instructions("Focus on breakthroughs from 2024")
.with_fast_mode(true);
let response = client.answer(&request).await?;
if let Some(contents) = &response.contents {
println!("Answer: {}", contents);
}
if let Some(sources) = &response.search_results {
println!("\nSources ({}):", sources.len());
for source in sources {
println!(" - {}", source.title.as_deref().unwrap_or("Untitled"));
}
}
Ok(())
}
Parameters
Query (Required)
| Parameter | Type | Description |
|---|---|---|
query | impl Into<String> | The question or query to answer |
Builder Methods (Optional)
| Method | Type | Description | Default |
|---|---|---|---|
with_structured_output() | serde_json::Value | JSON schema for structured response format | None |
with_system_instructions() | impl Into<String> | Custom AI instructions (max 2000 chars) | None |
with_search_type() | "web" | "proprietary" | "all" | Search type before generating answer | "all" |
with_data_max_price() | f64 | Maximum cost in USD for data retrieval | 1.0 |
with_country_code() | impl Into<String> | 2-letter ISO country code to bias results | None |
with_included_sources() | Vec<String> | Sources to search within | None |
with_excluded_sources() | Vec<String> | Sources to exclude | None |
with_date_range() | (start, end) | Date range filter (YYYY-MM-DD) | None |
with_fast_mode() | bool | Enable fast mode for reduced latency | false |
Response Format
Copy
pub struct AnswerResponse {
pub success: bool,
pub error: Option<String>,
pub tx_id: Option<String>,
pub original_query: Option<String>,
pub contents: Option<serde_json::Value>, // String or structured object
pub data_type: Option<String>, // "unstructured" | "structured"
pub search_results: Option<Vec<AnswerSearchResult>>,
pub search_metadata: Option<AnswerSearchMetadata>,
pub ai_usage: Option<AiUsage>,
pub cost: Option<AnswerCost>,
}
pub struct AnswerSearchResult {
pub title: Option<String>,
pub url: Option<String>,
pub content: Option<String>,
pub source: Option<String>,
pub relevance_score: Option<f64>,
}
pub struct AiUsage {
pub input_tokens: Option<i32>,
pub output_tokens: Option<i32>,
}
pub struct AnswerCost {
pub search_cost: Option<f64>,
pub ai_cost: Option<f64>,
pub total_deduction_dollars: Option<f64>,
}
Parameter Examples
Basic Question Answering
Get a comprehensive answer to any question:Copy
let response = client.ask("How do neural networks learn?").await?;
if response.success {
if let Some(contents) = &response.contents {
println!("{}", contents);
}
}
System Instructions
Customize the AI’s response style and focus:Copy
let request = AnswerRequest::new("Explain quantum computing")
.with_system_instructions(
"You are a computer science professor. Explain concepts clearly \
with practical examples and avoid overly technical jargon."
);
let response = client.answer(&request).await?;
Structured Output Response
Get answers in a specific JSON format:Copy
use serde_json::json;
let schema = json!({
"type": "object",
"properties": {
"summary": {
"type": "string",
"description": "Brief summary of AI's impact"
},
"key_impacts": {
"type": "array",
"items": {"type": "string"},
"description": "List of key impacts"
},
"benefits": {
"type": "array",
"items": {"type": "string"},
"maxItems": 5
},
"challenges": {
"type": "array",
"items": {"type": "string"},
"maxItems": 5
},
"future_outlook": {
"type": "string",
"description": "Future implications and trends"
}
},
"required": ["summary", "key_impacts", "future_outlook"]
});
let request = AnswerRequest::new("What is the impact of AI on software development?")
.with_structured_output(schema);
let response = client.answer(&request).await?;
if response.success {
if let Some(data_type) = &response.data_type {
if data_type == "structured" {
if let Some(contents) = &response.contents {
println!("Structured answer: {}", serde_json::to_string_pretty(contents)?);
}
}
}
}
Source Filtering
Get answers from specific, authoritative sources:Copy
let request = AnswerRequest::new("What are the best practices for React performance optimization?")
.with_search_type("web")
.with_included_sources(vec![
"react.dev".to_string(),
"developer.mozilla.org".to_string(),
"web.dev".to_string(),
])
.with_system_instructions("Focus on official recommendations and proven techniques");
let response = client.answer(&request).await?;
Geographic and Date Filtering
Get location-specific and recent information:Copy
let request = AnswerRequest::new("What are the current renewable energy policies and incentives?")
.with_country_code("US")
.with_date_range("2024-01-01", "2024-12-31")
.with_system_instructions("Focus on federal and state-level policies with specific program details");
let response = client.answer(&request).await?;
Fast Mode
For time-sensitive applications:Copy
let request = AnswerRequest::new("What's the current status of the stock market?")
.with_fast_mode(true);
let response = client.answer(&request).await?;
Use Case Examples
Financial Analysis
Build an AI-powered financial research assistant:Copy
use serde_json::json;
use valyu::{ValyuClient, AnswerRequest};
async fn financial_analysis(
client: &ValyuClient,
query: &str,
) -> Result<(), Box<dyn std::error::Error>> {
let schema = json!({
"type": "object",
"properties": {
"company_analysis": {
"type": "object",
"properties": {
"performance_summary": {"type": "string"},
"key_metrics": {
"type": "array",
"items": {"type": "string"}
},
"key_events": {
"type": "array",
"items": {"type": "string"}
}
}
},
"competitor_comparison": {
"type": "array",
"items": {
"type": "object",
"properties": {
"company": {"type": "string"},
"relative_performance": {"type": "string"}
}
}
},
"market_analysis": {"type": "string"}
}
});
let request = AnswerRequest::new(query)
.with_search_type("proprietary")
.with_included_sources(vec!["valyu/valyu-stocks".to_string()])
.with_structured_output(schema)
.with_system_instructions(
"Provide detailed financial analysis with specific metrics, \
key events, and market context."
);
let response = client.answer(&request).await?;
if response.success {
if let Some(contents) = &response.contents {
println!("Financial Analysis:");
println!("{}", serde_json::to_string_pretty(contents)?);
}
if let Some(cost) = &response.cost {
println!("\nCost: ${:.4}", cost.total_deduction_dollars.unwrap_or(0.0));
}
}
Ok(())
}
Technical Documentation Assistant
Create an AI assistant that provides comprehensive technical guidance:Copy
use serde_json::json;
async fn get_technical_guide(
client: &ValyuClient,
topic: &str,
) -> Result<Option<serde_json::Value>, Box<dyn std::error::Error>> {
let schema = json!({
"type": "object",
"properties": {
"overview": {
"type": "string",
"description": "Brief overview of the implementation"
},
"prerequisites": {
"type": "array",
"items": {"type": "string"},
"description": "Required dependencies and setup"
},
"implementation_steps": {
"type": "array",
"items": {
"type": "object",
"properties": {
"step": {"type": "string"},
"description": {"type": "string"},
"code_example": {"type": "string"}
}
}
},
"security_considerations": {
"type": "array",
"items": {"type": "string"}
},
"common_pitfalls": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["overview", "implementation_steps", "security_considerations"]
});
let request = AnswerRequest::new(format!(
"How do I implement {} in a Rust application?",
topic
))
.with_system_instructions(
"Provide step-by-step implementation guidance with code examples, \
security best practices, and common pitfalls to avoid."
)
.with_included_sources(vec![
"docs.rs".to_string(),
"rust-lang.org".to_string(),
"github.com".to_string(),
])
.with_structured_output(schema);
let response = client.answer(&request).await?;
if response.success {
if let Some(contents) = &response.contents {
println!("=== Technical Implementation Guide ===");
println!("{}", serde_json::to_string_pretty(contents)?);
return Ok(Some(contents.clone()));
}
}
Ok(None)
}
// Usage
let guide = get_technical_guide(&client, "JWT authentication").await?;
Comparative Analysis Tool
Build a decision-making assistant:Copy
use serde_json::json;
async fn compare_options(
client: &ValyuClient,
topic: &str,
options: &[&str],
) -> Result<(), Box<dyn std::error::Error>> {
let schema = json!({
"type": "object",
"properties": {
"comparison_summary": {
"type": "string",
"description": "Brief overview of the comparison"
},
"options": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"pros": {
"type": "array",
"items": {"type": "string"}
},
"cons": {
"type": "array",
"items": {"type": "string"}
},
"best_for": {"type": "string"},
"learning_curve": {"type": "string"}
}
}
},
"recommendation": {
"type": "string",
"description": "Final recommendation with reasoning"
}
},
"required": ["comparison_summary", "options", "recommendation"]
});
let query = format!(
"Compare the pros and cons of {} for {}",
options.join(", "),
topic
);
let request = AnswerRequest::new(query)
.with_system_instructions(
"Provide a comprehensive comparison with objective analysis. \
Include specific examples and real-world considerations."
)
.with_structured_output(schema);
let response = client.answer(&request).await?;
if response.success {
if let Some(contents) = &response.contents {
println!("=== Comparative Analysis ===");
println!("{}", serde_json::to_string_pretty(contents)?);
}
}
Ok(())
}
// Usage
compare_options(
&client,
"web backend development",
&["Actix Web", "Axum", "Rocket"]
).await?;
Error Handling
Copy
use valyu::{ValyuClient, AnswerRequest, ValyuError};
let request = AnswerRequest::new("test query");
match client.answer(&request).await {
Ok(response) => {
if !response.success {
eprintln!("Answer generation failed: {:?}", response.error);
// Handle specific error cases
if let Some(err) = &response.error {
if err.contains("insufficient credits") {
eprintln!("Please add more credits to your account");
} else if err.contains("invalid") {
eprintln!("Check your query and options");
}
}
return;
}
// Process successful response
println!("Transaction ID: {:?}", response.tx_id);
println!("Data type: {:?}", response.data_type);
if let Some(metadata) = &response.search_metadata {
println!("Sources processed: {:?}", metadata);
}
if let Some(contents) = &response.contents {
println!("Answer: {}", contents);
}
}
Err(ValyuError::InvalidApiKey) => eprintln!("Invalid API key"),
Err(ValyuError::RateLimitExceeded) => eprintln!("Rate limit exceeded"),
Err(e) => eprintln!("Error: {}", e),
}
Best Practices
Improve Answer Quality
Copy
let request = AnswerRequest::new(query)
.with_system_instructions("Provide detailed, evidence-based answers with specific examples")
.with_search_type("proprietary") // Use high-quality academic/professional sources
.with_included_sources(vec!["authoritative-domain.com".to_string()])
.with_date_range("2024-01-01", "2024-12-31"); // Focus on recent information
Handle Structured Responses
Copy
let request = AnswerRequest::new(query)
.with_structured_output(schema);
let response = client.answer(&request).await?;
if response.success {
match response.data_type.as_deref() {
Some("structured") => {
// Process as structured data
if let Some(data) = &response.contents {
let parsed: MyStruct = serde_json::from_value(data.clone())?;
// Use parsed struct
}
}
_ => {
// Process as text
if let Some(text) = &response.contents {
println!("{}", text);
}
}
}
}

