Skip to main content

Android SDK

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.

Currently provides Android SDK with support for simple queries and full bidirectional client for complex interactions.

System Requirements​

  • Android API: 21+ (Android 5.0 Lollipop or higher)
  • Kotlin: 1.8 or higher
  • iFlow CLI:0.2.24 or higher

Dependencies​

Add to your build.gradle:

dependencies {
// For connecting to iFlow CLI, communication and such
implementation 'cn.iflow:iflow-cli-sdk-android:1.0.0'

// OkHttp for WebSocket
implementation 'com.squareup.okhttp3:okhttp:4.12.0'

// Gson for JSON
implementation 'com.google.code.gson:gson:2.10.1'

// Coroutines
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3'
}

Quick Start​

Basic Example​

Use IFlowClient for basic conversational interaction:

import com.iflow.sdk.IFlowClient
import com.iflow.sdk.IFlowOptions
import com.iflow.sdk.models.*

val options = IFlowOptions()

IFlowClient(options).use { client ->
client.connect()
client.sendMessage("Hello, iFlow!")

client.receiveMessages { message ->
when (message) {
is AssistantMessage -> {
println(message.chunk.text)
}
is TaskFinishMessage -> {
return@receiveMessages // Completed
}
}
}
}

Simple Query​

The simplest way to use is through the IFlowQuery.query function:

import com.iflow.sdk.query.IFlowQuery

// Simple one-click query
val result = IFlowQuery.query("What is 2 + 2?")
println(result) // "2 + 2 equals 4."

Core Concepts​

IFlowClient​

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

import com.iflow.sdk.IFlowClient
import com.iflow.sdk.IFlowOptions

// Using default configuration
val options = IFlowOptions()
IFlowClient(options).use { client ->
client.connect()
client.sendMessage("Your question")

client.receiveMessages { message ->
// Handle messages
}
}

// Using custom configuration
val options = IFlowOptions(
url = "ws://localhost:8090/acp?peer=iflow",
timeout = 300_000L, // 5 minutes
permissionMode = PermissionMode.AUTO
)
IFlowClient(options).use { client ->
client.connect()
client.sendMessage("Your question")

client.receiveMessages { message ->
// Handle messages
}
}

Message Types​

The SDK supports multiple message types corresponding to different responses from the iFlow protocol:

AssistantMessage - AI Assistant Response​

import com.iflow.sdk.IFlowClient
import com.iflow.sdk.IFlowOptions
import com.iflow.sdk.models.*

fun handleAssistantMessage() {
val options = IFlowOptions()

IFlowClient(options).use { client ->
client.connect()
client.sendMessage("Please introduce Kotlin")

client.receiveMessages { message ->
when (message) {
is AssistantMessage -> {
println(message.chunk.text)
}
is TaskFinishMessage -> {
return@receiveMessages
}
}
}
}
}

ToolCallMessage - Tool Calls​

import com.iflow.sdk.IFlowClient
import com.iflow.sdk.IFlowOptions
import com.iflow.sdk.models.*

fun handleToolCalls() {
val options = IFlowOptions(
permissionMode = PermissionMode.MANUAL
)

IFlowClient(options).use { client ->
client.connect()
client.sendMessage("List files in current directory")

client.receiveMessages { message ->
when (message) {
is ToolCallMessage -> {
println("Tool call: ${message.label}")
println("Status: ${message.status}")

// Handle tool confirmation
if (message.confirmation?.required == true) {
client.approveToolCall(message.id)
}
}
is TaskFinishMessage -> {
return@receiveMessages
}
}
}
}
}

PlanMessage - Task Plans​

import com.iflow.sdk.IFlowClient
import com.iflow.sdk.IFlowOptions
import com.iflow.sdk.models.*

fun showPlan() {
val options = IFlowOptions()

IFlowClient(options).use { client ->
client.connect()
client.sendMessage("Help me create an Android project structure")

client.receiveMessages { message ->
when (message) {
is PlanMessage -> {
println("Execution plan:")
message.entries.forEach { entry ->
val statusIcon = if (entry.status == "completed") "✅" else "⏳"
println("$statusIcon [${entry.priority}] ${entry.content}")
}
}
is TaskFinishMessage -> {
return@receiveMessages
}
}
}
}
}

TaskFinishMessage - Task Completion​

import com.iflow.sdk.IFlowClient
import com.iflow.sdk.IFlowOptions
import com.iflow.sdk.models.*

fun checkCompletion() {
val options = IFlowOptions()

IFlowClient(options).use { client ->
client.connect()
client.sendMessage("Calculate 1+1")

client.receiveMessages { message ->
when (message) {
is AssistantMessage -> {
print(message.chunk.text)
}
is TaskFinishMessage -> {
println() // New line
println("Task completed: ${message.stopReason}")
return@receiveMessages
}
}
}
}
}

Common Use Cases​

Interactive Chatbot​

import com.iflow.sdk.IFlowClient
import com.iflow.sdk.IFlowOptions
import com.iflow.sdk.models.*

fun chatbot() {
println("iFlow Chatbot (type 'quit' to exit)")
println("-".repeat(50))

val options = IFlowOptions()

IFlowClient(options).use { client ->
client.connect()

while (true) {
print("\nYou: ")
val userInput = readLine() ?: break

if (userInput.lowercase() in listOf("quit", "exit", "q")) {
println("Goodbye!")
break
}

client.sendMessage(userInput)

print("iFlow: ")
client.receiveMessages { message ->
when (message) {
is AssistantMessage -> {
print(message.chunk.text)
}
is TaskFinishMessage -> {
println() // New line
return@receiveMessages
}
}
}
}
}
}

fun main() {
chatbot()
}

Advanced Configuration​

Permission Mode Configuration​

Configure permission management for tool calls:

import com.iflow.sdk.IFlowClient
import com.iflow.sdk.IFlowOptions
import com.iflow.sdk.models.*

// Auto-approve all tools
val autoOptions = IFlowOptions(
permissionMode = PermissionMode.AUTO
)

// Ask for confirmation every time
val manualOptions = IFlowOptions(
permissionMode = PermissionMode.MANUAL
)

// Selective approval
val selectiveOptions = IFlowOptions(
permissionMode = PermissionMode.SELECTIVE
)

Session Configuration​

import com.iflow.sdk.IFlowClient
import com.iflow.sdk.IFlowOptions
import com.iflow.sdk.models.*

val options = IFlowOptions(
url = "ws://localhost:8090/acp?peer=iflow",
timeout = 300_000L, // 5 minutes
permissionMode = PermissionMode.AUTO,
fileAccess = true,
fileReadOnly = true,
authMethodId = "iflow",
sessionSettings = SessionSettings(
workingDirectory = "/workspace"
)
)

File Attachment Support​

The SDK supports multiple file types:

  • Images: PNG, JPG, GIF, WebP, SVG (base64 encoded)
  • Audio: MP3, WAV, M4A, OGG, FLAC (base64 encoded)
  • Documents: PDF, TXT, code files (resource links)
client.sendMessage(
text = "Analyze these files",
files = listOf(
"/path/to/image.png",
"/path/to/audio.mp3",
"/path/to/document.pdf"
)
)

Error Handling​

The SDK provides specific exception types:

import com.iflow.sdk.query.IFlowQuery
import com.iflow.sdk.exceptions.*

try {
val result = IFlowQuery.query("Hello")
println(result)
} catch (e: ConnectionException) {
println("Connection failed: ${e.message}")
} catch (e: AuthenticationException) {
println("Authentication failed: ${e.message}")
} catch (e: TimeoutException) {
println("Operation timed out: ${e.message}")
} catch (e: IFlowException) {
println("iFlow error: ${e.message}")
}

API Reference​

Core Classes​

ClassDescription
IFlowClientMain client class, manages connection to iFlow
IFlowOptionsConfiguration options class
IFlowQuerySimple query utility class

IFlowQuery Methods​

MethodDescription
query(text, files, options)Send query and return complete response
querySync(text, files, options)Synchronous version of query (blocks current thread)
queryBatch(queries, options)Send multiple queries in parallel
queryWithFile(text, filePath, options)Query with single file attachment
queryCode(prompt, language, options)Generate code with language hints
queryAnalyze(filePath, question, options)Analyze files

IFlowClient Methods​

MethodDescription
connect()Establish connection to iFlow
sendMessage(text, files)Send message with optional files
receiveMessages(callback)Receive streaming responses
getMessageChannel()Get message channel for receiving messages
interrupt()Cancel current generation
approveToolCall(id, outcome)Approve tool call
rejectToolCall(id)Reject tool call
disconnect()Gracefully close connection

Message Types​

Message TypeDescriptionMain Properties
AssistantMessageText response from AI assistantchunk.text
ToolCallMessageTool execution request and statuslabel, status, confirmation
PlanMessageStructured task planentries (contains content, priority, status)
TaskFinishMessageTask completion signalstopReason
ErrorMessageError informationmessage

Configuration Options​

OptionTypeDescription
urlStringWebSocket URL (default: ws://localhost:8090/acp?peer=iflow)
timeoutLongTimeout duration (milliseconds, default: 300000 i.e. 5 minutes)
permissionModePermissionModeTool call permission mode
fileAccessBooleanWhether to allow file access
fileReadOnlyBooleanWhether file access is read-only
authMethodIdStringAuthentication method ID
sessionSettingsSessionSettingsSession configuration

Permission Modes​

ModeDescription
PermissionMode.AUTOAuto-approve all tools
PermissionMode.MANUALAsk for confirmation every time
PermissionMode.SELECTIVEAuto-approve certain types

Architecture​

The SDK structure is as follows:

com.iflow.sdk/
├── IFlowClient.kt // Main client class
├── IFlowOptions.kt // Configuration
├── models/ // Data classes and enums
├── transport/ // WebSocket transport (OkHttp)
├── protocol/ // ACP protocol implementation
├── query/ // Simple query tools
├── exceptions/ // Custom exceptions
└── utils/ // JSON and logging utilities

Troubleshooting​

Connection Issues​

If you encounter connection errors, please check:

  1. Whether iFlow is installed

    iflow --version
  2. Whether the port is occupied

    # Linux/Mac
    lsof -i :8090

    # Windows
    netstat -an | findstr :8090
  3. Test connection manually

    iflow --experimental-acp --port 8090
  4. Whether WebSocket URL is correct

    • Default: ws://localhost:8090/acp?peer=iflow
    • Ensure URL format is correct and IP address and port are accessible

Timeout Issues​

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

val options = IFlowOptions(
timeout = 600_000L // 10 minute timeout
)