use futures::stream::StreamExt;
use iflow_cli_sdk_rust::{IFlowClient, IFlowOptions, Message};
use iflow_cli_sdk_rust::error::IFlowError;
use std::io::Write;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.init();
println!("🚀 Starting iFlow client example...");
let local = tokio::task::LocalSet::new();
local
.run_until(async {
let options = IFlowOptions::new()
.with_process_config(
iflow_cli_sdk_rust::types::ProcessConfig::new()
.enable_auto_start()
.stdio_mode(),
)
.with_logging_config(iflow_cli_sdk_rust::types::LoggingConfig {
enabled: true,
level: "INFO".to_string(),
logger_config: iflow_cli_sdk_rust::logger::LoggerConfig {
enabled: true,
log_file: "logs/iflow_client.log".into(),
max_file_size: 10 * 1024 * 1024, max_files: 5,
},
});
let mut client = IFlowClient::new(Some(options));
println!("🔗 Connecting to iFlow...");
client.connect().await?;
println!("✅ Connected to iFlow");
println!("📥 Receiving responses...");
let mut message_stream = client.messages();
let message_task = tokio::task::spawn_local(async move {
let mut stdout = std::io::stdout();
while let Some(message) = message_stream.next().await {
match message {
Message::Assistant { content } => {
print!("{}", content);
stdout
.flush()
.map_err(|err| -> Box<dyn std::error::Error> { Box::new(err) })?;
}
Message::ToolCall { id, name, status } => {
println!("\n🔧 Tool call: {} ({}): {}", id, name, status);
}
Message::Plan { entries } => {
println!("\n📋 Plan update received: {:?}", entries);
}
Message::TaskFinish { .. } => {
println!("\n✅ Task completed");
break;
}
Message::Error {
code,
message: msg,
details: _,
} => {
eprintln!("\n❌ Error {}: {}", code, msg);
break;
}
Message::User { content } => {
println!("\n👤 User message: {}", content);
}
}
}
Ok::<(), Box<dyn std::error::Error>>(())
});
let prompt = "Create a plan to introduce this project.";
println!("📤 Sending: {}", prompt);
match client.send_message(prompt, None).await {
Ok(()) => {
println!("✅ Message sent successfully");
}
Err(IFlowError::Timeout(msg)) => {
eprintln!("⏰ Timeout error occurred: {}", msg);
eprintln!("This may be due to processing delays.");
eprintln!("Consider increasing the timeout or checking the iFlow process.");
}
Err(e) => {
eprintln!("❌ Error sending message: {}", e);
return Err(e.into());
}
}
match message_task.await {
Ok(Ok(())) => {}
Ok(Err(err)) => return Err(err),
Err(err) => return Err(Box::new(err)),
}
println!("\n🔌 Disconnecting...");
client.disconnect().await?;
println!("👋 Disconnected from iFlow");
Ok::<(), Box<dyn std::error::Error>>(())
})
.await
}