iflow-cli-sdk-rust 0.1.1

Rust SDK for iFlow CLI using Agent Communication Protocol
Documentation

iFlow CLI SDK for Rust

A powerful Rust SDK for interacting with iFlow using the Agent Communication Protocol (ACP). This SDK provides both simple query functions and full bidirectional client for complex interactions.

codecov Crates.io Version DeepWiki

Features

  • 🚀 Automatic Process Management - SDK automatically starts and manages iFlow process
  • 🔌 Stdio Communication - Communicate with iFlow via stdio
  • 🔌 WebSocket Communication - Communicate with iFlow via WebSocket for better performance and reliability
  • 🔄 Bidirectional Communication - Real-time streaming messages and responses
  • 🛠️ Tool Call Management - Fine-grained permission control for tool execution
  • 📋 Task Planning - Receive and process structured task plans
  • 🔍 Raw Data Access - Debug and inspect protocol-level messages
  • Async/Await Support - Modern async Rust with full type safety

TODO

  • 🤖 Sub-agent Support - Track and manage multiple AI agents via agent_id

ROADMAP.md

Installation

Add this to your Cargo.toml:

[dependencies]
iflow-cli-sdk-rust = "0.1.0"

Or install directly from the repository:

cargo add --git https://github.com/vibe-ideas/iflow-cli-sdk-rust

Quick Start

Simple Query

use iflow_cli_sdk_rust::query;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let response = query("What is 2 + 2?").await?;
    println!("{}", response); // "4"
    Ok(())
}

MCP Server Configuration

The SDK supports configuring MCP (Modular Command Protocol) servers for extended capabilities such as filesystem access, command execution, and more. You can configure MCP servers using the McpServer type:

use iflow_cli_sdk_rust::{IFlowClient, IFlowOptions, McpServer, EnvVariable};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Configure MCP servers for extended capabilities
    let mcp_servers = vec![
        McpServer {
            name: "filesystem".to_string(),
            command: "mcp-server-filesystem".to_string(),
            args: vec!["--allowed-dirs".to_string(), "/workspace".to_string()],
            env: vec![
                EnvVariable {
                    name: "DEBUG".to_string(),
                    value: "1".to_string(),
                }
            ],
        }
    ];
    
    // Create options with MCP server configuration
    let options = IFlowOptions::new()
        .with_mcp_servers(mcp_servers);
    
    // Create client with options
    let mut client = IFlowClient::new(Some(options));
    
    // Connect and use the client as usual
    client.connect().await?;
    // ...
    Ok(())
}

Simple Query with Custom Configuration

use iflow_cli_sdk_rust::{query_with_config, IFlowOptions};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let options = IFlowOptions::new()
        .with_timeout(60.0);  // 60 second timeout
        
    let response = query_with_config("What is 2 + 2?", options).await?;
    println!("{}", response); // "4"
    Ok(())
}

Interactive Session

use iflow_cli_sdk_rust::{IFlowClient, IFlowOptions, Message};
use futures::stream::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let options = IFlowOptions::new()
        .with_auto_start_process(true);
    
    let mut client = IFlowClient::new(Some(options));
    client.connect().await?;
    
    client.send_message("Hello, iFlow!", None).await?;
    
    let mut message_stream = client.messages();
    while let Some(message) = message_stream.next().await {
        match message {
            Message::Assistant { content } => {
                print!("{}", content);
                std::io::stdout().flush()?;
            }
            Message::TaskFinish { .. } => {
                break;
            }
            _ => {
                // Handle other message types
            }
        }
    }
    
    client.disconnect().await?;
    Ok(())
}

Streaming Responses

use iflow_cli_sdk_rust::query_stream;
use futures::stream::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut stream = query_stream("Tell me a story").await?;
    
    while let Some(chunk) = stream.next().await {
        print!("{}", chunk);
        std::io::stdout().flush()?;
    }
    
    Ok(())
}

Streaming Responses with Custom Configuration

use iflow_cli_sdk_rust::{query_stream_with_config, IFlowOptions};
use futures::stream::StreamExt;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let options = IFlowOptions::new()
        .with_timeout(60.0);  // 60 second timeout
        
    let mut stream = query_stream_with_config("Tell me a story", options).await?;
    
    while let Some(chunk) = stream.next().await {
        print!("{}", chunk);
        std::io::stdout().flush()?;
    }
    
    Ok(())
}

Configuration

Client Options

use iflow_cli_sdk_rust::IFlowOptions;

let options = IFlowOptions::new()
    .with_timeout(60.0)
    .with_file_access(true)
    .with_auto_start_process(true);

WebSocket Communication

The SDK supports WebSocket communication with iFlow for better performance and reliability. To use WebSocket, specify the WebSocket configuration in the options:

use iflow_cli_sdk_rust::{IFlowOptions, types::WebSocketConfig};

// Simple configuration with default reconnect settings
let options = IFlowOptions::new()
    .with_websocket_config(WebSocketConfig::new("ws://localhost:8090/acp?peer=iflow".to_string()));

// Or use the default configuration
let options = IFlowOptions::new()
    .with_websocket_config(WebSocketConfig::default());

// Or configure with custom reconnect settings
let options = IFlowOptions::new()
    .with_websocket_config(WebSocketConfig::with_reconnect_settings(
        "ws://localhost:8090/acp?peer=iflow".to_string(),
        5,  // reconnect attempts
        std::time::Duration::from_secs(10)  // reconnect interval
    ));

// In auto-start mode, you can omit the URL entirely
let options = IFlowOptions::new()
    .with_websocket_config(WebSocketConfig::auto_start());

// Or configure auto-start mode with custom reconnect settings
let options = IFlowOptions::new()
    .with_websocket_config(WebSocketConfig::auto_start_with_reconnect_settings(
        5,  // reconnect attempts
        std::time::Duration::from_secs(10)  // reconnect interval
    ));

If you enable auto-start process with a WebSocket URL pointing to localhost, the SDK will automatically start the iFlow process if it's not already running. In auto-start mode, you can omit the URL entirely and let the SDK generate it automatically.

Message Types

The SDK handles various message types from iFlow:

  • Message::Assistant { content } - AI assistant responses
  • Message::ToolCall { id, name, status } - Tool execution requests
  • Message::Plan { entries } - Structured task plans
  • Message::TaskFinish { reason } - Task completion signals
  • Message::Error { code, message } - Error notifications
  • Message::User { content } - User message echoes

Examples

Run the examples:

# Simple query example
cargo run --example query

# Interactive client example
cargo run --example basic_client

# Test response handling
cargo run --example test_response

# Explore API capabilities
cargo run --example explore_api

# Logging example
cargo run --example logging_example

Architecture

The SDK is organized into several modules:

  • client - Main IFlowClient implementation with stdio communication
  • types - Type definitions and message structures
  • process_manager - iFlow process lifecycle management
  • query - Convenience functions for simple queries
  • error - Error types and handling
  • logger - Message logging functionality

Requirements

  • Rust 1.70+
  • iFlow CLI installed with --experimental-acp support (or use auto-start feature)

Development

Building

cargo build

Testing

cargo test

# Run specific test suites
cargo test --test websocket_config_tests
cargo test --test websocket_integration_tests

# e2e tests
cargo test --test e2e_tests -- --nocapture

Running with logging

RUST_LOG=debug cargo run --example basic_client

License

MIT License - see LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.