use std::env;
use std::sync::Arc;
use clap::{Parser, Subcommand};
use anyhow::Result;
use tracing::{info, error, warn};
use alou::agent::{
Agent, Adapter, AgentConfig, DeepSeekConfig, BehaviorConfig,
WorkspaceConfig, ToolStrategy
};
use alou::connection_pool::ConnectionPool;
#[derive(Parser)]
#[command(name = "test-adapter")]
#[command(about = "测试Claude Agent适配器")]
struct Cli {
#[arg(short, long)]
quiet: bool,
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Test {
#[arg(short, long, default_value = "你好,请介绍一下你的功能")]
message: String,
#[arg(short, long, default_value = "agent_config.json")]
config: String,
},
Init {
#[arg(short, long, default_value = "agent_config.json")]
output: String,
},
}
fn get_default_config() -> AgentConfig {
AgentConfig {
deepseek: DeepSeekConfig {
base_url: env::var("DEEPSEEK_BASE_URL")
.unwrap_or_else(|_| "https://api.deepseek.com".to_string()),
api_key: env::var("DEEPSEEK_API_KEY")
.unwrap_or_else(|_| {
warn!("未设置DEEPSEEK_API_KEY环境变量,请设置正确的API密钥");
"your-api-key-here".to_string()
}),
model: env::var("DEEPSEEK_MODEL")
.unwrap_or_else(|_| "deepseek-chat".to_string()),
max_tokens: 2000,
temperature: 0.7,
},
behavior: BehaviorConfig {
max_retries: 3,
timeout_seconds: 30,
verbose_logging: true,
tool_strategy: ToolStrategy::Auto,
},
workspace: WorkspaceConfig {
directories: vec![".".to_string()],
smart_detection: true,
exclude_patterns: vec!["target".to_string(), "node_modules".to_string()],
},
}
}
fn load_config(config_path: &str) -> Result<AgentConfig> {
let mut config = if std::path::Path::new(config_path).exists() {
let content = std::fs::read_to_string(config_path)?;
let config: AgentConfig = serde_json::from_str(&content)?;
config
} else {
warn!("配置文件 {} 不存在,使用默认配置", config_path);
get_default_config()
};
if let Ok(api_key) = env::var("DEEPSEEK_API_KEY") {
if !api_key.is_empty() && api_key != "your-api-key-here" {
config.deepseek.api_key = api_key;
info!("使用环境变量中的DeepSeek API密钥");
}
}
if config.deepseek.api_key == "your-api-key-here" || config.deepseek.api_key.is_empty() {
error!("DeepSeek API密钥未设置或无效!");
error!("请设置环境变量 DEEPSEEK_API_KEY 或编辑配置文件 {}", config_path);
return Err(anyhow::anyhow!("API密钥未设置"));
}
Ok(config)
}
fn save_config(config: &AgentConfig, config_path: &str) -> Result<()> {
let content = serde_json::to_string_pretty(config)?;
std::fs::write(config_path, content)?;
info!("配置文件已保存到: {}", config_path);
Ok(())
}
async fn init_connection_pool() -> Result<ConnectionPool> {
let pool = ConnectionPool::new();
Ok(pool)
}
async fn test_adapter(config_path: &str, message: &str) -> Result<()> {
let config = load_config(config_path)?;
let connection_pool = Arc::new(init_connection_pool().await?);
let mut adapter = Adapter::with_connection_pool(config, connection_pool.clone()).await?;
adapter.initialize().await?;
info!("测试消息: {}", message);
let result = adapter.process_input(message).await;
match result {
Ok(response) => {
println!("适配器响应: {}", response);
}
Err(e) => {
error!("测试失败: {}", e);
return Err(e.into());
}
}
Ok(())
}
fn init_config(output_path: &str) -> Result<()> {
let config = get_default_config();
save_config(&config, output_path)?;
println!("配置文件已创建: {}", output_path);
println!("请编辑配置文件,设置正确的DeepSeek API密钥和其他参数");
Ok(())
}
#[tokio::main]
async fn main() -> Result<()> {
if let Err(e) = dotenv::dotenv() {
warn!("无法加载 .env 文件: {}", e);
}
let cli = Cli::parse();
if cli.quiet {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::ERROR)
.with_target(false)
.with_ansi(false)
.init();
} else {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::INFO)
.with_target(false)
.with_ansi(true)
.with_thread_ids(false)
.with_thread_names(false)
.with_file(false)
.with_line_number(false)
.init();
}
match cli.command {
Commands::Test { message, config } => {
test_adapter(&config, &message).await?;
}
Commands::Init { output } => {
init_config(&output)?;
}
}
Ok(())
}