use anyhow::Result;
use claude_agent_sdk::{
ClaudeAgentOptions, PermissionMode, SdkBeta, SystemPrompt, SystemPromptPreset, Tools, ToolsPreset, query,
};
#[tokio::main]
async fn main() -> Result<()> {
println!("=== Advanced Configuration Example ===\n");
println!("1. Beta Features:");
beta_features_example().await?;
println!("\n2. Custom System Prompts:");
custom_system_prompts().await?;
println!("\n3. Advanced Tool Configuration:");
advanced_tool_config().await?;
println!("\n4. Budget and Cost Control:");
budget_control_example().await?;
println!("\n5. Model Selection and Fallback:");
model_selection_example().await?;
println!("\n6. Session Management:");
session_management_example().await?;
println!("\n7. Environment Variables:");
env_vars_example().await?;
println!("\n8. Debug Configuration:");
debug_config_example().await?;
Ok(())
}
async fn beta_features_example() -> Result<()> {
let options = ClaudeAgentOptions::builder()
.betas(vec![
SdkBeta::Context1M, ])
.build();
println!(" Beta features configuration:");
println!(" - Context1M: Extended context window (1M tokens)");
let _messages = query("List available beta features", Some(options)).await?;
println!(" ✓ Configuration active");
Ok(())
}
async fn custom_system_prompts() -> Result<()> {
let simple_prompt = SystemPrompt::Text("You are a helpful Rust programming assistant.".to_string());
let multi_part_prompt = SystemPrompt::Text(
"You are a Rust expert.\n\
Focus on:\n\
1. Idiomatic Rust code\n\
2. Performance\n\
3. Safety\n\
4. Best practices".to_string(),
);
let preset_prompt = SystemPrompt::Preset(SystemPromptPreset {
type_: "preset".to_string(),
preset: "custom_prompt".to_string(),
append: None,
});
let options = ClaudeAgentOptions::builder()
.system_prompt(multi_part_prompt)
.build();
println!(" Configured custom system prompt");
let _messages = query("What is Rust ownership?", Some(options)).await?;
println!(" ✓ Custom prompt used");
Ok(())
}
async fn advanced_tool_config() -> Result<()> {
let all_tools = Tools::Preset(ToolsPreset::claude_code());
let coding_tools = Tools::Preset(ToolsPreset::new("coding"));
let filesystem_tools = Tools::Preset(ToolsPreset::new("filesystem"));
let custom_tools = Tools::List(vec!["Read".to_string(), "Write".to_string(), "Bash".to_string()]);
let options = ClaudeAgentOptions::builder()
.tools(coding_tools)
.allowed_tools(vec![
"Read".to_string(),
"Write".to_string(),
"Bash".to_string(),
])
.disallowed_tools(vec![
"Edit".to_string(), ])
.build();
println!(" Tool configuration:");
println!(" - Preset: coding");
println!(" - Allowed: Read, Write, Bash");
println!(" - Disallowed: Edit");
let _messages = query("List files in current directory", Some(options)).await?;
println!(" ✓ Tools configured");
Ok(())
}
async fn budget_control_example() -> Result<()> {
let options = ClaudeAgentOptions::builder()
.max_budget_usd(0.50) .max_turns(5)
.model("claude-sonnet-4-5")
.build();
println!(" Budget limit: $0.50 USD");
println!(" Max turns: 5");
println!(" Model: claude-sonnet-4-5");
match query("Explain quantum computing in detail", Some(options)).await {
Ok(messages) => {
println!(" ✓ Query completed within budget");
println!(" Received {} messages", messages.len());
},
Err(e) => {
println!(" ✗ Query failed: {}", e);
println!(" (Likely exceeded budget or max turns)");
},
}
Ok(())
}
async fn model_selection_example() -> Result<()> {
let options = ClaudeAgentOptions::builder()
.model("claude-opus-4-5")
.fallback_model("claude-sonnet-4-5".to_string())
.max_thinking_tokens(50000) .build();
println!(" Primary model: claude-opus-4-5");
println!(" Fallback model: claude-sonnet-4-5");
println!(" Max thinking tokens: 50000");
let _messages = query("Solve this complex problem", Some(options)).await?;
println!(" ✓ Model selection successful");
Ok(())
}
async fn session_management_example() -> Result<()> {
let options_fork = ClaudeAgentOptions::builder()
.fork_session(true) .build();
let options_resume = ClaudeAgentOptions::builder()
.resume("my-session-id".to_string())
.continue_conversation(true)
.build();
println!(" Session configurations:");
println!(" - Fork mode: fresh start each time");
println!(" - Resume mode: continue existing session");
let _messages = query("What is 2 + 2?", Some(options_fork)).await?;
println!(" ✓ Fork session created");
Ok(())
}
async fn env_vars_example() -> Result<()> {
use std::collections::HashMap;
let mut env = HashMap::new();
env.insert("RUST_LOG".to_string(), "debug".to_string());
env.insert("API_KEY".to_string(), "sk-xxx".to_string());
let options = ClaudeAgentOptions::builder().env(env).build();
println!(" Environment variables:");
println!(" - RUST_LOG=debug");
println!(" - API_KEY=sk-xxx");
let _messages = query("Check environment", Some(options)).await?;
println!(" ✓ Environment configured");
Ok(())
}
async fn debug_config_example() -> Result<()> {
use std::sync::Arc;
let stderr_callback = Arc::new(|msg: String| {
eprintln!("🔍 DEBUG: {}", msg);
});
let mut extra_args = std::collections::HashMap::new();
extra_args.insert("debug-to-stderr".to_string(), None);
extra_args.insert("verbose".to_string(), None);
let options = ClaudeAgentOptions::builder()
.stderr_callback(stderr_callback)
.extra_args(extra_args)
.build();
println!(" Debug mode enabled");
println!(" - Stderr callback active");
println!(" - Extra arguments: debug-to-stderr, verbose");
let _messages = query("Simple test query", Some(options)).await?;
println!(" ✓ Debug output captured");
Ok(())
}
async fn working_directory_example() -> Result<()> {
use std::path::PathBuf;
let options = ClaudeAgentOptions::builder()
.cwd(PathBuf::from("/tmp"))
.add_dirs(vec![
PathBuf::from("/home/user/projects"),
PathBuf::from("/shared"),
])
.build();
println!(" Working directory: /tmp");
println!(" Additional directories:");
println!(" - /home/user/projects");
println!(" - /shared");
let _messages = query("List files in working directory", Some(options)).await?;
println!(" ✓ Working directory configured");
Ok(())
}
async fn user_metadata_example() -> Result<()> {
let options = ClaudeAgentOptions::builder()
.user("user-12345".to_string())
.permission_prompt_tool_name("admin_approval".to_string())
.build();
println!(" User ID: user-12345");
println!(" Permission tool: admin_approval");
let _messages = query("Who am I?", Some(options)).await?;
println!(" ✓ User metadata configured");
Ok(())
}
async fn stream_config_example() -> Result<()> {
let options = ClaudeAgentOptions::builder()
.include_partial_messages(true) .max_buffer_size(1024 * 1024) .build();
println!(" Stream configuration:");
println!(" - Include partial messages: true");
println!(" - Max buffer size: 1MB");
let _messages = query("Explain streams", Some(options)).await?;
println!(" ✓ Stream configuration applied");
Ok(())
}
async fn production_config_example() -> Result<()> {
let options = ClaudeAgentOptions::builder()
.model("claude-sonnet-4-5")
.fallback_model("claude-haiku-4-5".to_string())
.max_budget_usd(1.00)
.max_turns(10)
.permission_mode(PermissionMode::AcceptEdits)
.tools(Tools::Preset(ToolsPreset::claude_code()))
.allowed_tools(vec![
"Read".to_string(),
"Write".to_string(),
"Bash".to_string(),
])
.system_prompt(SystemPrompt::Text(
"You are a production assistant focused on \
reliability and correctness.".to_string(),
))
.betas(vec![SdkBeta::Context1M])
.max_thinking_tokens(20000)
.build();
println!(" ✓ Production configuration complete");
println!(" Features:");
println!(" - Model with fallback");
println!(" - Budget limit: $1.00");
println!(" - Production tools preset");
println!(" - Beta features enabled");
println!(" - Extended thinking: 20k tokens");
let _messages = query("Production test query", Some(options)).await?;
println!(" ✓ Production-ready configuration");
Ok(())
}