TypeScript 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.
✨ Core Feature: SDK automatically manages iFlow processes - no manual configuration needed!
System Requirements
- Node.js: 22.0 or higher
- TypeScript: 4.5 or higher (optional, but recommended)
- iFlow CLI: 0.2.24 or higher
- Operating System: Windows, macOS, Linux
Installation
npm install --save @iflow-ai/iflow-cli-sdk
Quick Start
Basic Example
The SDK automatically detects and starts iFlow processes without manual configuration:
import { IFlowClient, MessageType } from "@iflow-ai/iflow-cli-sdk";
async function main() {
const client = new IFlowClient();
try {
// SDK automatically handles:
// 1. Detect if iFlow is installed
// 2. Start iFlow process (if not running)
// 3. Find available port and establish connection
await client.connect();
await client.sendMessage("Hello, iFlow!");
for await (const message of client.receiveMessages()) {
if (message.type === MessageType.ASSISTANT && message.chunk.text) {
console.log(message.chunk.text);
} else if (message.type === MessageType.TASK_FINISH) {
break;
}
}
} finally {
await client.disconnect();
}
}
main().catch(console.error);
Simple Query
The simplest way to use the SDK is through the query function:
import { query } from "@iflow-ai/iflow-cli-sdk";
async function main() {
const response = await query("What is the capital of France?");
console.log(response); // Output: The capital of France is Paris.
}
main().catch(console.error);
Core Concepts
IFlowClient
IFlowClient is the main interface for interacting with iFlow CLI, managing the WebSocket connection lifecycle:
import { IFlowClient, IFlowOptions } from "@iflow-ai/iflow-cli-sdk";
async function main() {
// Using default configuration (automatic process management)
const client = new IFlowClient();
try {
await client.connect();
await client.sendMessage("Your question");
for await (const message of client.receiveMessages()) {
// Process messages
}
} finally {
await client.disconnect();
}
// Using custom configuration
const customOptions: IFlowOptions = {
url: "ws://localhost:8090/acp", // WebSocket URL
autoStartProcess: true, // Auto-start iFlow
timeout: 30000, // Timeout in milliseconds
};
const customClient = new IFlowClient(customOptions);
try {
await customClient.connect();
await customClient.sendMessage("Your question");
for await (const message of customClient.receiveMessages()) {
// Process messages
}
} catch {
await customClient.disconnect();
}
}
main().catch(console.error);
Message Types
The SDK supports multiple message types corresponding to different iFlow protocol responses:
AssistantMessage - AI Assistant Response
Includes AgentInfo support for accessing detailed agent information:
import { IFlowClient, MessageType, AgentInfo } from "@iflow-ai/iflow-cli-sdk";
async function handleAssistantMessage() {
const client = new IFlowClient();
try {
await client.connect();
await client.sendMessage("Please introduce TypeScript");
for await (const message of client.receiveMessages()) {
if (message.type === MessageType.ASSISTANT && message.chunk.text) {
console.log(message.chunk.text);
// Access agent info (if available)
if (message.agentInfo) {
console.log(`Agent ID: ${message.agentInfo.agentId}`);
if (message.agentInfo.taskId) {
console.log(`Task ID: ${message.agentInfo.taskId}`);
}
if (message.agentInfo.agentIndex) {
console.log(`Agent Index: ${message.agentInfo.agentIndex}`);
}
}
} else if (message.type === MessageType.TASK_FINISH) {
break;
}
}
} finally {
await client.disconnect();
}
}
handleAssistantMessage().catch(console.error);
ToolCallMessage - Tool Execution
Tool call messages now include AgentInfo and tool name:
import { IFlowClient, MessageType, ToolCallStatus } from "@iflow-ai/iflow-cli-sdk";
async function handleToolCalls() {
const client = new IFlowClient();
try {
await client.connect();
// Note: This example demonstrates how to view tool call messages
// iFlow will request full path and content to create files
await client.sendMessage("List files in current directory");
for await (const message of client.receiveMessages()) {
if (message.type === MessageType.TOOL_CALL) {
console.log(`Status: ${message.status}`);
// New: Tool name
if (message.toolName) {
console.log(`Tool Name: ${message.toolName}`);
}
// Access agent info
if (message.agentInfo) {
console.log(`Agent ID: ${message.agentInfo.agentId}`);
}
} else if (message.type === MessageType.TASK_FINISH) {
break;
}
}
} finally {
await client.disconnect();
}
}
handleToolCalls().catch(console.error);
PlanMessage - Task Planning
import { IFlowClient, MessageType } from "@iflow-ai/iflow-cli-sdk";
async function showPlan() {
const client = new IFlowClient();
try {
await client.connect();
await client.sendMessage("Help me create a TypeScript project structure");
for await (const message of client.receiveMessages()) {
if (message.type === MessageType.PLAN) {
console.log("Execution plan:");
for (const entry of message.entries) {
const statusIcon = entry.status === "completed" ? "✅" : "⏳";
console.log(`${statusIcon} [${entry.priority}] ${entry.content}`);
}
} else if (message.type === MessageType.TASK_FINISH) {
break;
}
}
} finally {
await client.disconnect();
}
}
showPlan().catch(console.error);
TaskFinishMessage - Task Completion
import { IFlowClient, MessageType, StopReason } from "@iflow-ai/iflow-cli-sdk";
async function checkCompletion() {
const client = new IFlowClient();
try {
await client.connect();
await client.sendMessage("Calculate 1+1");
for await (const message of client.receiveMessages()) {
if (message.type === MessageType.ASSISTANT && message.chunk.text) {
process.stdout.write(message.chunk.text);
} else if (message.type === MessageType.TASK_FINISH) {
console.log(); // New line
if (message.stopReason === StopReason.END_TURN) {
console.log("Task completed normally");
} else if (message.stopReason === StopReason.MAX_TOKENS) {
console.log("Reached maximum token limit");
}
break; // TaskFinishMessage indicates conversation end
}
}
} finally {
await client.disconnect();
}
}
checkCompletion().catch(console.error);
Common Use Cases
Interactive Chatbot
import * as readline from "readline";
import { IFlowClient, MessageType } from "@iflow-ai/iflow-cli-sdk";
async function chatbot() {
console.log("iFlow Chatbot (type 'quit' to exit)");
console.log("-".repeat(50));
const client = new IFlowClient();
try {
await client.connect();
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
while (true) {
const userInput = await new Promise<string>((resolve) => {
rl.question("\nYou: ", resolve);
});
if (userInput.toLowerCase() === "quit" || userInput.toLowerCase() === "exit" || userInput.toLowerCase() === "q") {
console.log("Goodbye!");
break;
}
await client.sendMessage(userInput);
process.stdout.write("iFlow: ");
for await (const message of client.receiveMessages()) {
if (message.type === MessageType.ASSISTANT && message.chunk.text) {
process.stdout.write(message.chunk.text);
} else if (message.type === MessageType.TASK_FINISH) {
console.log(); // New line
break;
}
}
}
rl.close();
} finally {
await client.disconnect();
}
}
chatbot().catch(console.error);
Advanced Configuration
Manual Process Management
If you need to manually manage the iFlow process:
import { IFlowClient, MessageType } from "@iflow-ai/iflow-cli-sdk";
async function manualProcessExample() {
const client = new IFlowClient({
autoStartProcess: false, // Disable automatic process management
url: "ws://localhost:8090/acp", // Connect to existing iFlow
});
try {
await client.connect();
await client.sendMessage("Your question");
for await (const message of client.receiveMessages()) {
if (message.type === MessageType.ASSISTANT && message.chunk.text) {
process.stdout.write(message.chunk.text);
} else if (message.type === MessageType.TASK_FINISH) {
break;
}
}
} finally {
await client.disconnect();
}
}
manualProcessExample().catch(console.error);
Note Manual mode requires you to start iFlow separately:
iflow --experimental-acp --port 8090
Error Handling
The SDK provides detailed error handling mechanisms:
import { IFlowClient, ConnectionError, TimeoutError, MessageType } from "@iflow-ai/iflow-cli-sdk";
async function errorHandlingExample() {
const client = new IFlowClient();
try {
await client.connect();
await client.sendMessage("Test");
for await (const message of client.receiveMessages()) {
if (message.type === MessageType.ASSISTANT && message.chunk.text) {
console.log(message.chunk.text);
} else if (message.type === MessageType.TASK_FINISH) {
break;
}
}
} catch (error) {
if (error instanceof ConnectionError) {
console.error(`Connection error: ${error.message}`);
} else if (error instanceof TimeoutError) {
console.error(`Timeout error: ${error.message}`);
} else {
console.error(`Unknown error: ${error}`);
}
} finally {
await client.disconnect();
}
}
errorHandlingExample().catch(console.error);
API Reference
Core Classes
| Class Name | Description |
|---|---|
IFlowClient | Main client class for managing iFlow connections |
RawDataClient | Client for accessing raw protocol data |
Message Types
| Message Type | Description | Main Properties |
|---|---|---|
AssistantMessage | AI assistant text response | chunk.text, agentId, agentInfo |
ToolCallMessage | Tool execution request and status | label, status, toolName, agentInfo |
PlanMessage | Structured task plan | entries (containing content, priority, status) |
TaskFinishMessage | Task completion signal | stopReason |
UserMessage | User message | chunks |
ErrorMessage | Error message | code, message |
AgentInfo - Agent Information
The AgentInfo type shows detailed information parsed from iFlow agent IDs:
interface AgentInfo {
agentId: string; // Complete agent ID
agentIndex?: number; // Agent index in task
taskId?: string; // Task or instance ID
timestamp?: number; // Creation timestamp
}
Configuration Options
The IFlowOptions interface provides rich configuration options:
interface IFlowOptions {
url?: string; // WebSocket URL
cwd?: string; // Working directory
timeout?: number; // Timeout in milliseconds
logLevel?: "DEBUG" | "INFO" | "WARN" | "ERROR"; // Log level
processStartPort?: number; // Process start port
autoStartProcess?: boolean; // Auto-start process
authMethodId?: string; // Authentication method ID
authMethodInfo?: AuthMethodInfo; // Authentication info
mcpServers?: MCPServerConfig[]; // MCP server configuration
hooks?: HookConfigs; // Hook configuration
commands?: CommandConfig[]; // Command configuration
agents?: SubAgentConfig[]; // Sub-agent configuration
sessionSettings?: SessionSettings; // Session settings
permissionMode?: "auto" | "manual" | "selective"; // Permission mode
autoApproveTypes?: string[]; // Auto-approve types
fileAccess?: boolean; // File access permission
fileMaxSize?: number; // Maximum file size
fileReadOnly?: boolean; // Read-only mode
fileAllowedDirs?: string[]; // Allowed directories
}
interface AuthMethodInfo {
apiKey?: string;
baseUrl?: string;
modelName?: string;
}
interface MCPServerConfig {
name: string;
command: string;
args: string[];
env: { name: string; value: string }[];
}
interface CommandConfig {
name: string;
content: string;
}
interface SubAgentConfig {
agentType: string;
whenToUse: string;
allowedTools: string[];
systemPrompt: string;
name?: string;
description?: string;
allowedMcps?: string[];
proactive?: boolean;
location?: "global" | "project";
model?: string;
isInheritTools?: boolean;
isInheritMcps?: boolean;
}
interface SessionSettings {
system_prompt?: string;
append_system_prompt?: string;
allowed_tools?: string[];
disallowed_tools?: string[];
permission_mode?: "default" | "autoEdit" | "yolo" | "plan";
max_turns?: number;
add_dirs?: string[];
}
Troubleshooting
Connection Issues
If you encounter connection errors, check:
-
Is iFlow installed
iflow --version -
Is the port occupied
# Linux/Mac
lsof -i :8090
# Windows
netstat -an | findstr :8090 -
Manually test connection
iflow --experimental-acp --port 8090
Timeout Issues
For long-running tasks, increase the timeout:
import { IFlowClient, IFlowOptions } from "@iflow-ai/iflow-cli-sdk";
const options: IFlowOptions = {
timeout: 600000, // 10 minute timeout
};
const client = new IFlowClient(options);
Debug Logging
Enable detailed logging for debugging:
import { IFlowClient, IFlowOptions } from "@iflow-ai/iflow-cli-sdk";
const options: IFlowOptions = {
logLevel: "DEBUG",
};
const client = new IFlowClient(options);