Skip to main content

Python SDK

Current Version: v0.1.11

Overview

The iFlow SDK is an SDK for programmatic interaction with iFlow CLI. It can be quickly integrated into your business system, combining with workflow and other intelligent agent extensions to enable developers to build AI-driven applications with conversation, tool execution, and task planning capabilities, giving business systems AI capabilities. Currently supports Python, Java, TypeScript, and Android versions.

✨ Core Feature: SDK automatically manages iFlow processes - no manual configuration needed!

System Requirements

  • Python: 3.8 or higher
  • iFlow CLI: 0.2.24 or higher
  • Operating System: Windows, macOS, Linux

Installation

pip install iflow-cli-sdk

Quick Start

Basic Example

The SDK automatically detects and starts iFlow processes without manual configuration:

import asyncio
from iflow_sdk import IFlowClient, AssistantMessage, TaskFinishMessage

async def main():
# SDK automatically handles:
# 1. Detect if iFlow is installed
# 2. Start iFlow process (if not running)
# 3. Find available port and establish connection
# 4. Automatically clean up resources on exit
async with IFlowClient() as client:
await client.send_message("Hello, iFlow!")

async for message in client.receive_messages():
if isinstance(message, AssistantMessage):
print(message.chunk.text, end="\n", flush=True)
elif isinstance(message, TaskFinishMessage):
break

asyncio.run(main())

Simple Query

The simplest way to use it is through the query function:

from iflow_sdk import query
import asyncio

async def main():
response = await query("What is the capital of France?")
print(response) # Output: The capital of France is Paris.

asyncio.run(main())

Core Concepts

IFlowClient

IFlowClient is the main interface for interacting with iFlow CLI, managing the WebSocket connection lifecycle:

from iflow_sdk import IFlowClient, IFlowOptions

# Use default configuration (auto-manage process)
async with IFlowClient() as client:
await client.send_message("Your question")
async for message in client.receive_messages():
# Handle messages
pass

# Use custom configuration
options = IFlowOptions(
url="ws://localhost:8090/acp", # WebSocket URL
auto_start_process=True, # Auto-start iFlow
timeout=30.0 # Timeout (seconds)
)
async with IFlowClient(options) as client:
await client.send_message("Your question")
async for message in client.receive_messages():
# Handle messages
pass

Message Types

The SDK supports various message types corresponding to different iFlow protocol responses:

AssistantMessage - AI Assistant Response

Includes AgentInfo support to get detailed agent information:

import asyncio
from iflow_sdk import IFlowClient, AssistantMessage, TaskFinishMessage, AgentInfo

async def handle_assistant_message():
async with IFlowClient() as client:
await client.send_message("Please introduce Python")

async for message in client.receive_messages():
if isinstance(message, AssistantMessage):
print(message.chunk.text, end="\n", flush=True)

# Access agent information (if available)
if message.agent_info:
print(f"Agent ID: {message.agent_info.agent_id}")
if message.agent_info.task_id:
print(f"Task ID: {message.agent_info.task_id}")
if message.agent_info.agent_index is not None:
print(f"Agent Index: {message.agent_info.agent_index}")

elif isinstance(message, TaskFinishMessage):
break

if __name__ == "__main__":
asyncio.run(handle_assistant_message())

ToolCallMessage - Tool Calls

Tool call messages now also include AgentInfo information and tool names:

import asyncio
from iflow_sdk import IFlowClient, ToolCallMessage, ToolCallStatus, TaskFinishMessage

async def handle_tool_calls():
async with IFlowClient() as client:
# Note: This example shows how to view tool call messages
# iFlow will require full path and content to create files
await client.send_message("List files in the current directory")

async for message in client.receive_messages():
if isinstance(message, ToolCallMessage):
print(f"Status: {message.status}")

# New: Tool name
if message.tool_name:
print(f"Tool Name: {message.tool_name}")

# Access agent information
if message.agent_info:
print(f"Agent ID: {message.agent_info.agent_id}")

elif isinstance(message, TaskFinishMessage):
break

if __name__ == "__main__":
asyncio.run(handle_tool_calls())

PlanMessage - Task Planning

import asyncio
from iflow_sdk import IFlowClient, PlanMessage, TaskFinishMessage

async def show_plan():
async with IFlowClient() as client:
await client.send_message("Help me create a Python project structure")

async for message in client.receive_messages():
if isinstance(message, PlanMessage):
print("Execution Plan:")
for entry in message.entries:
status_icon = "✅" if entry.status == "completed" else "⏳"
print(f"{status_icon} [{entry.priority}] {entry.content}")
elif isinstance(message, TaskFinishMessage):
break

if __name__ == "__main__":
asyncio.run(show_plan())

TaskFinishMessage - Task Completion

import asyncio
from iflow_sdk import IFlowClient, AssistantMessage, TaskFinishMessage, StopReason

async def check_completion():
async with IFlowClient() as client:
await client.send_message("Calculate 1+1")

async for message in client.receive_messages():
if isinstance(message, AssistantMessage):
print(message.chunk.text, end="", flush=True)
elif isinstance(message, TaskFinishMessage):
print() # New line
if message.stop_reason == StopReason.END_TURN:
print("Task completed successfully")
elif message.stop_reason == StopReason.MAX_TOKENS:
print("Maximum token limit reached")
break # TaskFinishMessage indicates end of conversation

if __name__ == "__main__":
asyncio.run(check_completion())

Common Use Cases

Interactive Chatbot

#!/usr/bin/env python3
import asyncio
from iflow_sdk import IFlowClient, AssistantMessage, TaskFinishMessage

async def chatbot():
print("iFlow Chatbot (type 'quit' to exit)")
print("-" * 50)

async with IFlowClient() as client:
while True:
user_input = input("\nYou: ")

if user_input.lower() in ['quit', 'exit', 'q']:
print("Goodbye!")
break

await client.send_message(user_input)

print("iFlow: ", end="", flush=True)
async for message in client.receive_messages():
if isinstance(message, AssistantMessage):
print(message.chunk.text, end="", flush=True)
elif isinstance(message, TaskFinishMessage):
print() # New line
break

if __name__ == "__main__":
asyncio.run(chatbot())

Advanced Configuration

Manual Process Management

If you need to manually manage iFlow processes:

import asyncio
from iflow_sdk import IFlowClient, IFlowOptions, AssistantMessage, TaskFinishMessage

async def manual_process_example():
# Disable automatic process management
options = IFlowOptions(
auto_start_process=False,
url="ws://localhost:8090/acp" # Connect to existing iFlow
)

async with IFlowClient(options) as client:
await client.send_message("Your question")
async for message in client.receive_messages():
if isinstance(message, AssistantMessage):
print(message.chunk.text, end="", flush=True)
elif isinstance(message, TaskFinishMessage):
break

if __name__ == "__main__":
asyncio.run(manual_process_example())

Note Manual mode requires you to start iFlow separately:

iflow --experimental-acp --port 8090

Error Handling

The SDK provides detailed error handling mechanisms:

import asyncio
from iflow_sdk import IFlowClient, ConnectionError, TimeoutError, AssistantMessage, TaskFinishMessage

async def error_handling_example():
try:
async with IFlowClient() as client:
await client.send_message("Test")
async for message in client.receive_messages():
if isinstance(message, AssistantMessage):
print(message.chunk.text, end="", flush=True)
elif isinstance(message, TaskFinishMessage):
break
except ConnectionError as e:
print(f"Connection error: {e}")
except TimeoutError as e:
print(f"Timeout error: {e}")
except Exception as e:
print(f"Unknown error: {e}")

if __name__ == "__main__":
asyncio.run(error_handling_example())

Synchronous Calls

For scenarios requiring synchronous calls:

from iflow_sdk import query_sync, IFlowOptions

# Synchronous call with timeout control
options = IFlowOptions(timeout=30.0)
response = query_sync("Your question", options=options)
print(response)

API Reference

Core Classes

Class NameDescription
IFlowClientMain client class for managing connections to iFlow
IFlowOptionsConfiguration options class
RawDataClientClient for accessing raw protocol data

IFlowOptions Parameters

The IFlowOptions class is used to configure the behavior of the iFlow client:

Core Connection Parameters
ParameterTypeDefaultDescription
urlstr"ws://localhost:8090/acp"WebSocket connection URL
auto_start_processboolTrueWhether to automatically start the iFlow process. Set to False to manually start iFlow
process_start_portint8090Starting port number to use when automatically starting the iFlow process
timeoutfloat30.0Connection and operation timeout time (seconds)
log_levelstr"INFO"Log level, possible values: "DEBUG", "INFO", "WARNING", "ERROR"
cwdstrCurrent working directoryWorking directory for CLI operations
session_idOptional[str]NoneSession ID, used to restore existing sessions
Authentication Parameters
ParameterTypeDefaultDescription
auth_method_idOptional[str]NoneAuthentication method ID (e.g.: "use_iflow_ak")
auth_method_infoOptional[Union[Dict, AuthMethodInfo]]NoneAuthentication method information (containing api_key, base_url, model_name, etc.)
Tool Execution Control Parameters
ParameterTypeDefaultDescription
approval_modeApprovalModeApprovalMode.YOLOTool execution permission mode: DEFAULT(needs confirmation), AUTO_EDIT(auto execute), YOLO(auto execute+auto rollback), PLAN(read-only mode)
auto_approve_typesList[str]["edit", "fetch"]List of tool types to automatically approve (old version, not recommended to use)
File System Access Parameters
ParameterTypeDefaultDescription
file_accessboolFalseWhether to enable file system access (disabled by default for security)
file_allowed_dirsOptional[List[str]]NoneList of directories allowed for iFlow access. None means current directory only
file_read_onlyboolFalseWhether to allow read-only operations only (write operations are prohibited when enabled)
file_max_sizeint10485760Maximum file size allowed for read operations (bytes), default 10MB
Advanced Configuration Parameters
ParameterTypeDefaultDescription
mcp_serversList[Union[Dict, McpServer]][]List of MCP server configurations
hooksOptional[Dict[HookEventType, List[HookEventConfig]]]NoneHook configurations for various lifecycle events
commandsOptional[List[CommandConfig]]NoneList of command configurations
agentsOptional[List[CreateAgentConfig]]NoneList of agent configurations
session_settingsOptional[SessionSettings]NoneSession-specific settings (including allowed_tools, system_prompt, etc.)
metadataDict[str, Any]{}Additional metadata to send with requests

Example Usage:

from iflow_sdk import IFlowClient, IFlowOptions, ApprovalMode

# Basic configuration
options = IFlowOptions(
url="ws://localhost:8090/acp",
auto_start_process=True,
timeout=60.0,
log_level="DEBUG"
)

# Complete configuration example
options = IFlowOptions(
# Connection settings
url="ws://localhost:8090/acp",
auto_start_process=True,
process_start_port=8090,
timeout=300.0,
log_level="DEBUG",
cwd="/path/to/project",

# Tool execution control
approval_mode=ApprovalMode.DEFAULT, # Requires user confirmation

# File system access
file_access=True,
file_allowed_dirs=["/path/to/project"],
file_read_only=False,
file_max_size=10 * 1024 * 1024, # 10MB

# Authentication
auth_method_id="use_iflow_ak",
auth_method_info={
"api_key": "your-api-key",
"base_url": "https://api.example.com",
"model_name": "your-model"
}
)

async with IFlowClient(options) as client:
await client.send_message("Your question")
async for message in client.receive_messages():
# Handle messages
pass

Message Types

Message TypeDescriptionMain Attributes
AssistantMessageAI assistant text responseschunk.text, agent_id, agent_info
ToolCallMessageTool execution requests and statuslabel, status, tool_name, agent_info
PlanMessageStructured task plansentries (containing content, priority, status)
TaskFinishMessageTask completion signalsstop_reason

AgentInfo - Agent Information

The new AgentInfo class provides detailed information parsed from iFlow agent IDs:

AttributeTypeDescription
agent_idstrComplete agent ID
agent_indexOptional[int]Agent index within the task
task_idOptional[str]Task or instance ID
timestampOptional[int]Creation timestamp

AgentInfo Usage Example

from iflow_sdk import AgentInfo

# Parse information from agent ID
agent_id = "subagent-task-abc123-2-1735123456789"
agent_info = AgentInfo.from_agent_id_only(agent_id)

if agent_info:
print(f"Agent ID: {agent_info.agent_id}")
print(f"Task ID: {agent_info.task_id}")
print(f"Agent Index: {agent_info.agent_index}")
print(f"Timestamp: {agent_info.timestamp}")

Troubleshooting

Connection Issues

If you encounter connection errors, check:

  1. Is iFlow installed

    iflow --version
  2. Is the port occupied

    # Linux/Mac
    lsof -i :8090

    # Windows
    netstat -an | findstr :8090
  3. Manual connection testing

    iflow --experimental-acp --port 8090

Timeout Issues

For long-running tasks, you can increase the timeout:

from iflow_sdk import IFlowClient, IFlowOptions

options = IFlowOptions(timeout=600.0) # 10-minute timeout
client = IFlowClient(options)

Debug Logging

Enable verbose logging for debugging:

import logging
from iflow_sdk import IFlowClient, IFlowOptions

# Set logging level
logging.basicConfig(level=logging.DEBUG)

options = IFlowOptions(log_level="DEBUG")
client = IFlowClient(options)